mirror of
https://github.com/afska/gba-link-connection.git
synced 2026-03-21 17:44:21 -05:00
ISP calling and login completed
This commit is contained in:
parent
0f2d09229f
commit
c1f01cd5af
|
|
@ -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`).
|
||||
|
|
|
|||
|
|
@ -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 "?";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user