ISP calling and login completed

This commit is contained in:
Rodrigo Alfonso 2024-08-18 05:43:59 -03:00
parent 0f2d09229f
commit c1f01cd5af
3 changed files with 121 additions and 15 deletions

View File

@ -445,12 +445,13 @@ Name | Return type | Description
`shutdown()` | **bool** | Gracefully shuts down the adapter, closing all connections. After some time, the state will be changed to `SHUTDOWN`, and only then it's safe to call `deactivate()`.
`call(phoneNumber)` | **bool** | Initiates a P2P connection with a `phoneNumber`. After some time, the state will be `CALL_ESTABLISHED`, or `ACTIVE_SESSION` if the connection fails or ends. In REON/libmobile the phone number can be a number assigned by the relay server, or a 12-digit IPv4 address (for example, `"127000000001"` would be `127.0.0.1`).
`transfer(dataToSend, receivedData)` | **bool** | Requests a data transfer (up to `254` bytes) within a P2P connection and responds the received data. The `receivedData` is a pointer to a `LinkWireless::DataTransfer` struct that will be filled with data. It can point to `dataToSend`. When the transfer is completed, the `completed` field will be `true`.
`hangUp()` | **bool** | Hangs up the current P2P call.
`hangUp()` | **bool** | Hangs up the current P2P or ISP call. Closes all connections.
`readConfiguration(configurationData)` | **bool** | Retrieves the adapter configuration, and puts it in the `configurationData` struct. If the adapter has an active session, the data is already loaded, so it's instantaneous.
`getState()` | **LinkMobile::State** | Returns the current state (one of `LinkMobile::State::NEEDS_RESET`, `LinkMobile::State::PINGING`, `LinkMobile::State::WAITING_TO_START`, `LinkMobile::State::STARTING_SESSION`, `LinkMobile::State::ACTIVATING_SIO32`, `LinkMobile::State::WAITING_32BIT_SWITCH`, `LinkMobile::State::READING_CONFIGURATION`, `LinkMobile::State::SESSION_ACTIVE`, `LinkMobile::State::CALL_REQUESTED`, `LinkMobile::State::CALLING`, `LinkMobile::State::CALL_ESTABLISHED`, `LinkMobile::State::ISP_CALL_REQUESTED`, `LinkMobile::State::ISP_CALLING`, `LinkMobile::State::ISP_LOGIN`, `LinkMobile::State::ISP_ACTIVE`, `LinkMobile::State::SHUTDOWN_REQUESTED`, `LinkMobile::State::ENDING_SESSION`, `LinkMobile::State::WAITING_8BIT_SWITCH`, or `LinkMobile::State::SHUTDOWN`).
`getRole()` | **LinkMobile::Role** | Returns the current role in the P2P connection (one of `LinkMobile::Role::NO_P2P_CONNECTION`, `LinkMobile::Role::CALLER`, or `LinkMobile::Role::RECEIVER`).
`isConfigurationValid()` | **int** | Returns whether the adapter has been configured or not. Returns `1` = yes, `0` = no, `-1` = unknown (no session active).
`isP2PConnected()` | **bool** | Returns `true` if a P2P call is established (the state is `CALL_ESTABLISHED`).
`isConnectedP2P()` | **bool** | Returns `true` if a P2P call is established (the state is `CALL_ESTABLISHED`).
`isConnectedISP()` | **bool** | Returns `true` if an ISP call is active (the state is `ISP_ACTIVE`).
`isSessionActive()` | **bool** | Returns `true` if the session is active.
`canShutdown()` | **bool** | Returns `true` if there's an active session and there's no previous shutdown requests.
`getDataSize()` | **LinkSPI::DataSize** | Returns the current operation mode (`LinkSPI::DataSize`).

View File

@ -89,14 +89,16 @@ start:
output += "\nSTART = Call the ISP";
output += "\n (A = ok)\n (SELECT = stop)";
} else {
if (linkMobile->isP2PConnected()) {
if (linkMobile->isConnectedP2P()) {
output += "\n (A = send)";
output += "\n (L = hang up)";
} else if (linkMobile->isConnectedISP()) {
output += "\n (L = hang up)";
}
output += "\n (SELECT = stop)";
}
if (linkMobile->isP2PConnected()) {
if (linkMobile->isConnectedP2P()) {
if (!isConnected) {
isConnected = true;
outgoingData = linkMobile->getRole() == LinkMobile::Role::CALLER
@ -181,9 +183,15 @@ start:
linkMobile->call(number.c_str());
}
}
// START = Call the ISP
if (didPress(KEY_START, start)) {
linkMobile->callISP("asdasd");
}
break;
}
case LinkMobile::State::CALL_ESTABLISHED: {
case LinkMobile::State::CALL_ESTABLISHED:
case LinkMobile::State::ISP_ACTIVE: {
// L = hang up
if (didPress(KEY_L, l)) {
// (6) Hang up
@ -368,12 +376,16 @@ std::string getErrorTypeString(LinkMobile::Error::Type errorType) {
switch (errorType) {
case LinkMobile::Error::Type::ADAPTER_NOT_CONNECTED:
return "ADAPTER_NOT_CONNECTED";
case LinkMobile::Error::Type::ISP_LOGIN_FAILED:
return "ISP_LOGIN_FAILED";
case LinkMobile::Error::Type::COMMAND_FAILED:
return "COMMAND_FAILED";
case LinkMobile::Error::Type::WEIRD_RESPONSE:
return "WEIRD_RESPONSE";
case LinkMobile::Error::Type::TIMEOUT:
return "TIMEOUT";
case LinkMobile::Error::Type::WTF:
return "WTF";
default:
return "?";
}

View File

@ -18,7 +18,7 @@
// // (do something until `linkMobile->isSessionActive()` returns `true`)
// - 4) Call someone:
// linkMobile->call("127000000001");
// // (do something until `linkMobile->isP2PConnected()` returns `true`)
// // (do something until `linkMobile->isConnectedP2P()` returns `true`)
// - 5) Send/receive data:
// LinkMobile::DataTransfer dataTransfer = { .size = 5 };
// for (u32 i = 0; i < 5; i++)
@ -30,6 +30,7 @@
// linkMobile->hangUp();
// - 7) Turn off the adapter:
// linkMobile->shutdown();
// TODO: DOCUMENT ISP METHODS
// --------------------------------------------------------------------------
// (*) libtonc's interrupt handler sometimes ignores interrupts due to a bug.
// That causes packet loss. You REALLY want to use libugba's instead.
@ -169,9 +170,11 @@ class LinkMobile {
enum Type {
NONE,
ADAPTER_NOT_CONNECTED,
ISP_LOGIN_FAILED,
COMMAND_FAILED,
WEIRD_RESPONSE,
TIMEOUT
TIMEOUT,
WTF
};
Error::Type type = Error::Type::NONE;
@ -356,12 +359,13 @@ class LinkMobile {
}
/**
* @brief Hangs up the current P2P call.
* @brief Hangs up the current P2P or ISP call. Closes all connections.
* \warning Non-blocking. Returns `true` immediately, or `false` if there's no
* active call or available request slots.
*/
bool hangUp() {
if (state != CALL_ESTABLISHED || userRequests.isFull())
if ((state != CALL_ESTABLISHED && state != ISP_ACTIVE) ||
userRequests.isFull())
return false;
pushRequest(UserRequest{.type = UserRequest::Type::HANG_UP});
@ -411,7 +415,13 @@ class LinkMobile {
* @brief Returns `true` if a P2P call is established (the state is
* `CALL_ESTABLISHED`).
*/
[[nodiscard]] bool isP2PConnected() { return state == CALL_ESTABLISHED; }
[[nodiscard]] bool isConnectedP2P() { return state == CALL_ESTABLISHED; }
/**
* @brief Returns `true` if an ISP call is active (the state is
* `ISP_ACTIVE`).
*/
[[nodiscard]] bool isConnectedISP() { return state == ISP_ACTIVE; }
/**
* @brief Returns `true` if the session is active.
@ -544,6 +554,7 @@ class LinkMobile {
char password[LINK_MOBILE_MAX_PASSWORD_LENGTH + 1];
bool commandSent;
u32 timeout;
bool finished;
};
union AdapterConfiguration {
@ -696,6 +707,11 @@ class LinkMobile {
return;
}
if (userRequests.peek().finished)
userRequests.pop();
if (userRequests.isEmpty())
return;
auto request = userRequests.peek();
request.timeout++;
if (shouldAbortOnRequestTimeout() && request.timeout >= config.timeout)
@ -717,6 +733,23 @@ class LinkMobile {
}
break;
}
case UserRequest::Type::ISP_LOGIN: {
if (state != SESSION_ACTIVE && state != ISP_CALL_REQUESTED &&
state != ISP_CALLING) {
userRequests.pop();
return;
}
if (state == SESSION_ACTIVE)
setState(ISP_CALL_REQUESTED);
if (!asyncCommand.isActive && state == ISP_CALL_REQUESTED) {
setState(ISP_CALLING);
cmdDialTelephone(adapterConfiguration.isValid()
? adapterConfiguration.fields._ispNumber1
: FALLBACK_ISP_NUMBER);
}
break;
}
case UserRequest::Type::TRANSFER: {
if (state != CALL_ESTABLISHED) {
userRequests.pop();
@ -729,7 +762,7 @@ class LinkMobile {
break;
}
case UserRequest::Type::HANG_UP: {
if (state != CALL_ESTABLISHED) {
if (state != CALL_ESTABLISHED && state != ISP_ACTIVE) {
userRequests.pop();
return;
}
@ -913,9 +946,10 @@ class LinkMobile {
setState(SESSION_ACTIVE);
return;
}
if (!asyncCommand.respondsTo(COMMAND_TRANSFER_DATA))
return;
if (userRequests.isEmpty())
return abort(Error::Type::WTF);
auto request = userRequests.peek();
@ -929,12 +963,50 @@ class LinkMobile {
request.receive->data[i] = asyncCommand.cmd.data.bytes[1 + i];
request.receive->size = size;
request.receive->completed = true;
userRequests.pop();
}
request.finished = true;
} else
return abort(Error::Type::WTF);
} else {
setState(SESSION_ACTIVE);
}
}
case ISP_CALLING: {
if (!asyncCommand.respondsTo(COMMAND_DIAL_TELEPHONE))
return;
if (userRequests.isEmpty())
return abort(Error::Type::WTF);
auto request = userRequests.peek();
if (request.type == UserRequest::ISP_LOGIN) {
if (asyncCommand.result == CommandResult::SUCCESS) {
setState(ISP_LOGIN);
cmdISPLogin(request.loginId, request.password);
}
request.finished = true;
} else
return abort(Error::Type::WTF);
break;
}
case ISP_LOGIN: {
if (!asyncCommand.respondsTo(COMMAND_ISP_LOGIN))
return;
if (asyncCommand.result != CommandResult::SUCCESS)
return abort(Error::Type::ISP_LOGIN_FAILED);
setState(ISP_ACTIVE);
break;
}
case ISP_ACTIVE: {
if (asyncCommand.respondsTo(COMMAND_HANG_UP_TELEPHONE)) {
setState(SESSION_ACTIVE);
return;
}
// TODO: IMPLEMENT
break;
}
case ENDING_SESSION: {
if (!asyncCommand.respondsTo(COMMAND_END_SESSION))
return;
@ -968,7 +1040,7 @@ class LinkMobile {
void cmdEndSession() { sendCommandAsync(buildCommand(COMMAND_END_SESSION)); }
void cmdDialTelephone(char* phoneNumber) {
void cmdDialTelephone(const char* phoneNumber) {
addData(DIAL_PHONE_FIRST_BYTE[adapterType], true);
for (u32 i = 0; i < std::strlen(phoneNumber); i++)
addData(phoneNumber[i]);
@ -1005,6 +1077,26 @@ class LinkMobile {
sendCommandAsync(buildCommand(COMMAND_READ_CONFIGURATION_DATA, true));
}
void cmdISPLogin(const char* loginId, const char* password) {
u32 loginIdLength = std::strlen(loginId);
addData(loginIdLength, true);
for (u32 i = 0; i < loginIdLength; i++)
addData(loginId[i]);
u32 passwordLength = std::strlen(password);
addData(passwordLength);
for (u32 i = 0; i < passwordLength; i++)
addData(password[i]);
bool isConfigured = isConfigurationValid();
for (u32 i = 0; i < 4; i++)
addData(isConfigured ? adapterConfiguration.fields.primaryDNS[i] : 0);
for (u32 i = 0; i < 4; i++)
addData(isConfigured ? adapterConfiguration.fields.secondaryDNS[i] : 0);
sendCommandAsync(buildCommand(COMMAND_ISP_LOGIN, true));
}
void setISPNumber() {
static const char BCD[16] = "0123456789#*cde";
@ -1017,6 +1109,7 @@ class LinkMobile {
void pushRequest(UserRequest request) {
request.timeout = 0;
request.finished = false;
userRequests.syncPush(request);
}