mirror of
https://github.com/afska/gba-link-connection.git
synced 2026-10-01 21:36:53 -05:00
Starting ISP connection
This commit is contained in:
@@ -447,7 +447,7 @@ Name | Return type | Description
|
||||
`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.
|
||||
`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::SESSION_ACTIVE_ISP`, `LinkMobile::State::SHUTDOWN_REQUESTED`, `LinkMobile::State::ENDING_SESSION`, `LinkMobile::State::WAITING_8BIT_SWITCH`, or `LinkMobile::State::SHUTDOWN`).
|
||||
`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`).
|
||||
|
||||
@@ -85,7 +85,8 @@ start:
|
||||
output += "\n (SELECT = stop)";
|
||||
} else if (linkMobile->getState() == LinkMobile::State::SESSION_ACTIVE) {
|
||||
output += "\nL = Read Configuration";
|
||||
output += "\nR = Call someone\n";
|
||||
output += "\nR = Call someone";
|
||||
output += "\nSTART = Call the ISP";
|
||||
output += "\n (A = ok)\n (SELECT = stop)";
|
||||
} else {
|
||||
if (linkMobile->isP2PConnected()) {
|
||||
@@ -217,23 +218,24 @@ std::string readConfiguration() {
|
||||
if (!linkMobile->readConfiguration(data))
|
||||
return "Read failed :(";
|
||||
|
||||
return ("Magic:\n " + toStr(data.magic, 2) + "\nRegistered:\n $" +
|
||||
toHex(data.registrationState) + "\nPrimary DNS:\n " +
|
||||
std::to_string(data.primaryDNS[0]) + "." +
|
||||
std::to_string(data.primaryDNS[1]) + "." +
|
||||
std::to_string(data.primaryDNS[2]) + "." +
|
||||
std::to_string(data.primaryDNS[3]) + "\nSecondary DNS:\n " +
|
||||
std::to_string(data.secondaryDNS[0]) + "." +
|
||||
std::to_string(data.secondaryDNS[1]) + "." +
|
||||
std::to_string(data.secondaryDNS[2]) + "." +
|
||||
std::to_string(data.secondaryDNS[3]) + "\nLoginID:\n " +
|
||||
toStr(data.loginID, 10) + "\nEmail:\n " + toStr(data.email, 24) +
|
||||
"\nSMTP Server:\n " + toStr(data.smtpServer, 20) +
|
||||
"\nPOP Server:\n " + toStr(data.popServer, 19) + "\nIs Valid:\n " +
|
||||
std::to_string(linkMobile->isConfigurationValid()) + "\n\nMode: " +
|
||||
(linkMobile->getDataSize() == LinkSPI::DataSize::SIZE_32BIT
|
||||
? "SIO32"
|
||||
: "SIO8"));
|
||||
return (
|
||||
"Magic:\n " + toStr(data.magic, 2) + ", $" +
|
||||
toHex(data.registrationState) + "\nPrimary DNS:\n " +
|
||||
std::to_string(data.primaryDNS[0]) + "." +
|
||||
std::to_string(data.primaryDNS[1]) + "." +
|
||||
std::to_string(data.primaryDNS[2]) + "." +
|
||||
std::to_string(data.primaryDNS[3]) + "\nSecondary DNS:\n " +
|
||||
std::to_string(data.secondaryDNS[0]) + "." +
|
||||
std::to_string(data.secondaryDNS[1]) + "." +
|
||||
std::to_string(data.secondaryDNS[2]) + "." +
|
||||
std::to_string(data.secondaryDNS[3]) + "\nLoginID:\n " +
|
||||
toStr(data.loginId, 10) + "\nEmail:\n " + toStr(data.email, 24) +
|
||||
"\nSMTP Server:\n " + toStr(data.smtpServer, 20) + "\nPOP Server:\n " +
|
||||
toStr(data.popServer, 19) + "\nISP Number #1:\n " +
|
||||
std::string(data._ispNumber1) + "\n\nIs Valid: " +
|
||||
std::to_string(linkMobile->isConfigurationValid()) + "\nMode: " +
|
||||
(linkMobile->getDataSize() == LinkSPI::DataSize::SIZE_32BIT ? "SIO32"
|
||||
: "SIO8"));
|
||||
}
|
||||
|
||||
std::string getNumberInput() {
|
||||
@@ -278,7 +280,7 @@ std::string getNumberInput() {
|
||||
return "";
|
||||
}
|
||||
if (didPress(KEY_A, a)) {
|
||||
if (selectedNumber.size() < LINK_MOBILE_MAX_PHONE_NUMBER_SIZE)
|
||||
if (selectedNumber.size() < LINK_MOBILE_MAX_PHONE_NUMBER_LENGTH)
|
||||
selectedNumber += rows[selectedY][selectedX];
|
||||
}
|
||||
if (didPress(KEY_SELECT, select))
|
||||
@@ -329,6 +331,14 @@ std::string getStateString(LinkMobile::State state) {
|
||||
return "CALLING";
|
||||
case LinkMobile::State::CALL_ESTABLISHED:
|
||||
return "CALL_ESTABLISHED";
|
||||
case LinkMobile::State::ISP_CALL_REQUESTED:
|
||||
return "ISP_CALL_REQUESTED";
|
||||
case LinkMobile::State::ISP_CALLING:
|
||||
return "ISP_CALLING";
|
||||
case LinkMobile::State::ISP_LOGIN:
|
||||
return "ISP_LOGIN";
|
||||
case LinkMobile::State::ISP_ACTIVE:
|
||||
return "ISP_ACTIVE";
|
||||
case LinkMobile::State::SHUTDOWN_REQUESTED:
|
||||
return "SHUTDOWN_REQUESTED";
|
||||
case LinkMobile::State::ENDING_SESSION:
|
||||
|
||||
@@ -54,7 +54,9 @@ static volatile char LINK_MOBILE_VERSION[] = "LinkMobile/v7.0.0";
|
||||
|
||||
#define LINK_MOBILE_MAX_USER_TRANSFER_LENGTH 254
|
||||
#define LINK_MOBILE_MAX_COMMAND_TRANSFER_LENGTH 255
|
||||
#define LINK_MOBILE_MAX_PHONE_NUMBER_SIZE 32
|
||||
#define LINK_MOBILE_MAX_PHONE_NUMBER_LENGTH 32
|
||||
#define LINK_MOBILE_MAX_LOGIN_ID_LENGTH 32
|
||||
#define LINK_MOBILE_MAX_PASSWORD_LENGTH 32
|
||||
#define LINK_MOBILE_COMMAND_TRANSFER_BUFFER \
|
||||
(LINK_MOBILE_MAX_COMMAND_TRANSFER_LENGTH + 4)
|
||||
#define LINK_MOBILE_DEFAULT_TIMEOUT (60 * 3)
|
||||
@@ -96,6 +98,7 @@ class LinkMobile {
|
||||
static constexpr int ACK_SENDER = 0;
|
||||
static constexpr int CONFIGURATION_DATA_SIZE = 192;
|
||||
static constexpr int CONFIGURATION_DATA_CHUNK = CONFIGURATION_DATA_SIZE / 2;
|
||||
static constexpr const char* FALLBACK_ISP_NUMBER = "#9677";
|
||||
static constexpr int COMMAND_BEGIN_SESSION = 0x10;
|
||||
static constexpr int COMMAND_END_SESSION = 0x11;
|
||||
static constexpr int COMMAND_DIAL_TELEPHONE = 0x12;
|
||||
@@ -137,7 +140,10 @@ class LinkMobile {
|
||||
CALL_REQUESTED,
|
||||
CALLING,
|
||||
CALL_ESTABLISHED,
|
||||
SESSION_ACTIVE_ISP,
|
||||
ISP_CALL_REQUESTED,
|
||||
ISP_CALLING,
|
||||
ISP_LOGIN,
|
||||
ISP_ACTIVE,
|
||||
SHUTDOWN_REQUESTED,
|
||||
ENDING_SESSION,
|
||||
WAITING_8BIT_SWITCH,
|
||||
@@ -183,7 +189,7 @@ class LinkMobile {
|
||||
u8 _unused1_;
|
||||
u8 primaryDNS[4];
|
||||
u8 secondaryDNS[4];
|
||||
char loginID[10];
|
||||
char loginId[10];
|
||||
u8 _unused2_[22];
|
||||
char email[24];
|
||||
u8 _unused3_[6];
|
||||
@@ -195,6 +201,8 @@ class LinkMobile {
|
||||
u8 configurationSlot3[24];
|
||||
u8 checksumHigh;
|
||||
u8 checksumLow;
|
||||
|
||||
char _ispNumber1[16 + 1]; // (parsed from `configurationSlot1`)
|
||||
} __attribute__((packed));
|
||||
|
||||
struct DataTransfer {
|
||||
@@ -285,7 +293,39 @@ class LinkMobile {
|
||||
|
||||
auto request = UserRequest{.type = UserRequest::Type::CALL};
|
||||
copyString(request.phoneNumber, phoneNumber,
|
||||
LINK_MOBILE_MAX_PHONE_NUMBER_SIZE);
|
||||
LINK_MOBILE_MAX_PHONE_NUMBER_LENGTH);
|
||||
pushRequest(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls the ISP number registered in the adapter configuration, or a
|
||||
* default number if the adapter hasn't been configured. Then, performs a
|
||||
* login operation using the provided `password` and `loginId`. If `loginId`
|
||||
* is empty and the adapter has been configured, it will use the one stored in
|
||||
* the configuration.
|
||||
* @param password The password, as a null-terminated string (max `32`
|
||||
* characters).
|
||||
* @param loginId The login ID, as a null-terminated string (max `32`
|
||||
* characters). It can be empty if it's already stored in the configuration.
|
||||
* \warning Non-blocking. Returns `true` immediately, or `false`
|
||||
* if there's no active session, no available request slots, or no login ID.
|
||||
*/
|
||||
bool callISP(const char* password, const char* loginId = "") {
|
||||
if (state != SESSION_ACTIVE || userRequests.isFull())
|
||||
return false;
|
||||
|
||||
auto request = UserRequest{.type = UserRequest::Type::ISP_LOGIN};
|
||||
copyString(request.password, password, LINK_MOBILE_MAX_PASSWORD_LENGTH);
|
||||
|
||||
if (std::strlen(loginId) > 0)
|
||||
copyString(request.loginId, loginId, LINK_MOBILE_MAX_LOGIN_ID_LENGTH);
|
||||
else if (adapterConfiguration.isValid())
|
||||
copyString(request.loginId, adapterConfiguration.fields._ispNumber1,
|
||||
LINK_MOBILE_MAX_LOGIN_ID_LENGTH);
|
||||
else
|
||||
return false;
|
||||
|
||||
pushRequest(request);
|
||||
return true;
|
||||
}
|
||||
@@ -494,12 +534,14 @@ class LinkMobile {
|
||||
enum AdapterType { BLUE, YELLOW, GREEN, RED, UNKNOWN };
|
||||
|
||||
struct UserRequest {
|
||||
enum Type { CALL, TRANSFER, HANG_UP, SHUTDOWN };
|
||||
enum Type { CALL, ISP_LOGIN, TRANSFER, HANG_UP, SHUTDOWN };
|
||||
|
||||
Type type;
|
||||
char phoneNumber[LINK_MOBILE_MAX_PHONE_NUMBER_SIZE + 1];
|
||||
char phoneNumber[LINK_MOBILE_MAX_PHONE_NUMBER_LENGTH + 1];
|
||||
DataTransfer send;
|
||||
DataTransfer* receive;
|
||||
char loginId[LINK_MOBILE_MAX_LOGIN_ID_LENGTH + 1];
|
||||
char password[LINK_MOBILE_MAX_PASSWORD_LENGTH + 1];
|
||||
bool commandSent;
|
||||
u32 timeout;
|
||||
};
|
||||
@@ -833,11 +875,13 @@ class LinkMobile {
|
||||
adapterConfiguration.bytes[offset + i] =
|
||||
asyncCommand.cmd.data.bytes[1 + i];
|
||||
|
||||
if (offset == 0)
|
||||
if (offset == 0) {
|
||||
cmdReadConfigurationData(CONFIGURATION_DATA_CHUNK,
|
||||
CONFIGURATION_DATA_CHUNK);
|
||||
else
|
||||
} else {
|
||||
setISPNumber();
|
||||
setState(SESSION_ACTIVE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SESSION_ACTIVE: {
|
||||
@@ -961,6 +1005,16 @@ class LinkMobile {
|
||||
sendCommandAsync(buildCommand(COMMAND_READ_CONFIGURATION_DATA, true));
|
||||
}
|
||||
|
||||
void setISPNumber() {
|
||||
static const char BCD[16] = "0123456789#*cde";
|
||||
|
||||
for (u32 i = 0; i < 8; i++) {
|
||||
u8 b = adapterConfiguration.fields.configurationSlot1[i];
|
||||
adapterConfiguration.fields._ispNumber1[i * 2] = BCD[b >> 4];
|
||||
adapterConfiguration.fields._ispNumber1[i * 2 + 1] = BCD[b & 0xF];
|
||||
}
|
||||
}
|
||||
|
||||
void pushRequest(UserRequest request) {
|
||||
request.timeout = 0;
|
||||
userRequests.syncPush(request);
|
||||
|
||||
Reference in New Issue
Block a user