Starting ISP connection

This commit is contained in:
Rodrigo Alfonso
2024-08-18 04:09:43 -03:00
parent a0221f2971
commit 0f2d09229f
3 changed files with 92 additions and 28 deletions

View File

@@ -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`).

View File

@@ -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:

View File

@@ -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);