Adding signatures and documentation for openConnection and closeConnection

This commit is contained in:
Rodrigo Alfonso
2024-08-18 10:14:21 -03:00
parent f994270ee0
commit 855accae1c
2 changed files with 173 additions and 56 deletions

View File

@@ -437,8 +437,6 @@ You can also change these compile-time constants:
- On fatal errors, the library will transition to a `NEEDS_RESET` state. In that case, you can call `getError()` to know more details on what happened, and then `activate()` to restart.
- When calling `deactivate()`, the adapter automatically turns itself off after `3` seconds of inactivity. However, to gracefully turn it off, it's recommended to call `shutdown()` first, wait until the state is `SHUTDOWN`, and then `deactivate()`.
// TODO: Add ISP methods
Name | Return type | Description
--- | --- | ---
`isActive()` | **bool** | Returns whether the library is active or not.
@@ -448,7 +446,9 @@ Name | Return type | Description
`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`).
`callISP(password, loginId)` | **bool** | 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`. After some time, the state will be `ISP_ACTIVE`. If `loginId` is empty and the adapter has been configured, it will use the one stored in the configuration. Both parameters are null-terminated strings (max `32` characters).
`dnsQuery(domainName, result)` | **bool** | Looks up the IPv4 address for a `domainName` (a null-terminated string, max `253` characters). The `result` is a pointer to a `LinkMobile::DNSQuery` struct that will be filled with the result. When the request is completed, the `completed` field will be `true`. If an IP address was found, the `success` field will be `true` and the `ipv4` field can be read as a 4-byte address.
`transfer(dataToSend, result)` | **bool** | Requests a data transfer (up to `254` bytes) within a P2P connection and responds the received data. The `result` is a pointer to a `LinkMobile::DataTransfer` struct that will be filled with the received data. It can also point to `dataToSend` to reuse the struct. When the transfer is completed, the `completed` field will be `true`.
`openConnection(ip, port, type, result)` | **bool** | Opens a TCP/UDP (`type`) connection at the given `ip` (4-byte address) on the given `port`. The `result` is a pointer to a `LinkMobile::OpenConn` struct that will be filled with the result. When the request is completed, the `completed` field will be `true`. If the connection was successful, the `success` field will be `true` and the `connectionId` field can be used when calling the `transfer(...)` method. Only `2` connections can be opened at the same time.
`closeConnection(connectionId, type, result)` | **bool** | Closes an active TCP/UDP (`type`) connection. The `result` is a pointer to a `LinkMobile::CloseConn` struct that will be filled with the result. When the request is completed, the `completed` field will be `true`. If the connection was closed correctly, the `success` field will be `true`.
`transfer(dataToSend, result, [connectionId])` | **bool** | Requests a data transfer (up to `254` bytes) and responds the received data. The transfer can be done with the other node in a P2P connection, or with any open TCP/UDP connection if an ISP session is active. In the case of a TCP/UDP connection, the `connectionId` must be provided. The `result` is a pointer to a `LinkMobile::DataTransfer` struct that will be filled with the received data. It can also point to `dataToSend` to reuse the struct. When the request is completed, the `completed` field will be `true`. If the transfer was successful, the `success` field will be `true`.
`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`).

View File

@@ -35,7 +35,18 @@
// linkMobile->dnsQuery("something.com", &dnsQuery);
// // (do something until `dnsQuery.completed` is `true`)
// // (use `dnsQuery.success` and `dnsQuery.ipv4`)
// - 7) Turn off the adapter:
// - 9) Open connections:
// auto type = LinkMobile::ConnectionType::TCP;
// LinkMobile::OpenConn openConn;
// linkMobile->openConnection(dnsQuery.ipv4, type, openConn);
// // (do something until `openConn.completed` is `true`)
// // (use `openConn.connectionId` as last argument of `transfer(...)`)
// - 10) Close connections:
// auto type = LinkMobile::ConnectionType::TCP;
// LinkMobile::CloseConn closeConn;
// linkMobile->closeConnection(openConn.connectionId, type, closeConn);
// // (do something until `openConn.completed` is `true`)
// - 11) Turn off the adapter:
// linkMobile->shutdown();
// --------------------------------------------------------------------------
// (*) libtonc's interrupt handler sometimes ignores interrupts due to a bug.
@@ -158,41 +169,8 @@ class LinkMobile {
SHUTDOWN
};
enum CommandResult {
PENDING,
SUCCESS,
NOT_WAITING,
INVALID_DEVICE_ID,
INVALID_COMMAND_ACK,
INVALID_MAGIC_BYTES,
WEIRD_DATA_SIZE,
WRONG_CHECKSUM,
ERROR_CODE,
WEIRD_ERROR_CODE
};
enum Role { NO_P2P_CONNECTION, CALLER, RECEIVER };
struct Error {
enum Type {
NONE,
ADAPTER_NOT_CONNECTED,
ISP_LOGIN_FAILED,
COMMAND_FAILED,
WEIRD_RESPONSE,
TIMEOUT,
WTF
};
Error::Type type = Error::Type::NONE;
State state = State::NEEDS_RESET;
u8 cmdId = 0;
CommandResult cmdResult = CommandResult::PENDING;
u8 cmdErrorCode = 0;
bool cmdIsSending = false;
int reqType = -1;
};
struct ConfigurationData {
char magic[2];
u8 registrationState;
@@ -215,16 +193,63 @@ class LinkMobile {
char _ispNumber1[16 + 1]; // (parsed from `configurationSlot1`)
} __attribute__((packed));
struct DataTransfer {
u8 data[LINK_MOBILE_MAX_USER_TRANSFER_LENGTH] = {};
u8 size = 0;
bool completed = false;
};
struct DNSQuery {
u8 ipv4[4] = {};
bool completed = false;
bool success = false;
u8 ipv4[4] = {};
};
enum ConnectionType { TCP, UDP };
struct OpenConn {
bool completed = false;
bool success = false;
u8 connectionId = 0;
};
struct CloseConn {
bool completed = false;
bool success = false;
};
struct DataTransfer {
bool completed = false;
bool success = false;
u8 data[LINK_MOBILE_MAX_USER_TRANSFER_LENGTH] = {};
u8 size = 0;
};
enum CommandResult {
PENDING,
SUCCESS,
NOT_WAITING,
INVALID_DEVICE_ID,
INVALID_COMMAND_ACK,
INVALID_MAGIC_BYTES,
WEIRD_DATA_SIZE,
WRONG_CHECKSUM,
ERROR_CODE,
WEIRD_ERROR_CODE
};
struct Error {
enum Type {
NONE,
ADAPTER_NOT_CONNECTED,
ISP_LOGIN_FAILED,
COMMAND_FAILED,
WEIRD_RESPONSE,
TIMEOUT,
WTF
};
Error::Type type = Error::Type::NONE;
State state = State::NEEDS_RESET;
u8 cmdId = 0;
CommandResult cmdResult = CommandResult::PENDING;
u8 cmdErrorCode = 0;
bool cmdIsSending = false;
int reqType = -1;
};
/**
@@ -368,8 +393,8 @@ class LinkMobile {
size = LINK_MOBILE_MAX_DOMAIN_NAME_LENGTH;
auto request = UserRequest{.type = UserRequest::Type::DNS_QUERY,
.send = {.data = {}},
.dns = result,
.send = {.data = {}},
.commandSent = false};
for (u32 i = 0; i < size; i++)
request.send.data[i] = domainName[i];
@@ -380,22 +405,98 @@ class LinkMobile {
}
/**
* @brief Requests a data transfer within a P2P connection and responds the
* received data.
* @brief Opens a TCP/UDP (`type`) connection at the given `ip` (4-byte
* address) on the given `port`.
* @param ip The 4-byte address.
* @param port The port.
* @param type One of the enum values from `LinkMobile::ConnectionType`.
* @param result A pointer to a `LinkMobile::OpenConn` struct that
* will be filled with the result. When the request is completed, the
* `completed` field will be `true`. If the connection was successful, the
* `success` field will be `true` and the `connectionId` field can be used
* when calling the `transfer(...)` method.
* \warning Only `2` connections can be opened at the same time.
* \warning Non-blocking. Returns `true` immediately, or `false` if there's no
* active ISP session, no available request slots.
*/
bool openConnection(const u8* ip,
u16 port,
ConnectionType type,
OpenConn* result) {
if (state != ISP_ACTIVE || userRequests.isFull())
return false;
result->completed = false;
result->success = false;
auto request = UserRequest{.type = UserRequest::Type::OPEN_CONNECTION,
.open = result,
.connectionType = type,
.commandSent = false};
for (u32 i = 0; i < 4; i++)
request.ip[i] = ip[i];
request.port = port;
pushRequest(request);
return true;
}
// TODO: IMPLEMENT SOCKET METHODS
/**
* @brief Closes an active TCP/UDP (`type`) connection.
* @param connectionId The ID of the connection.
* @param type One of the enum values from `LinkMobile::ConnectionType`.
* @param result A pointer to a `LinkMobile::CloseConn` struct that
* will be filled with the result. When the request is completed, the
* `completed` field will be `true`. If the connection was closed correctly,
* the `success` field will be `true`.
* \warning Non-blocking. Returns `true` immediately, or `false` if there's no
* active ISP session, no available request slots.
*/
bool closeConnection(u8 connectionId,
ConnectionType type,
CloseConn* result) {
if (state != ISP_ACTIVE || userRequests.isFull())
return false;
result->completed = false;
result->success = false;
auto request = UserRequest{.type = UserRequest::Type::CLOSE_CONNECTION,
.close = result,
.connectionType = type,
.commandSent = false};
request.connectionId = connectionId;
pushRequest(request);
return true;
}
/**
* @brief Requests a data transfer and responds the received data. The
* transfer can be done with the other node in a P2P connection, or with any
* open TCP/UDP connection if an ISP session is active. In the case of a
* TCP/UDP connection, the `connectionId` must be provided.
* @param dataToSend The data to send, up to 254 bytes.
* @param result A pointer to a `LinkMobile::DataTransfer` struct that
* will be filled with the received data. It can also point to `dataToSend` to
* reuse the struct. When the transfer is completed, the `completed` field
* will be `true`.
* \warning Non-blocking. Returns `true` immediately, or `false` if there's no
* active call or available request slots.
* will be `true`. If the transfer was successful, the `success` field will be
* `true`.
* \warning Non-blocking. Returns `true` immediately, or `false` if
* there's no active call or available request slots.
*/
bool transfer(DataTransfer dataToSend, DataTransfer* result) {
if (state != CALL_ESTABLISHED || userRequests.isFull())
bool transfer(DataTransfer dataToSend,
DataTransfer* result,
u8 connectionId = 0xff) {
if ((state != CALL_ESTABLISHED && state != ISP_ACTIVE) ||
userRequests.isFull())
return false;
result->completed = false;
result->success = false;
auto request = UserRequest{.type = UserRequest::Type::TRANSFER,
.connectionId = connectionId,
.send = {.data = {}, .size = dataToSend.size},
.receive = result,
.commandSent = false};
@@ -591,15 +692,30 @@ class LinkMobile {
enum AdapterType { BLUE, YELLOW, GREEN, RED, UNKNOWN };
struct UserRequest {
enum Type { CALL, ISP_LOGIN, DNS_QUERY, TRANSFER, HANG_UP, SHUTDOWN };
enum Type {
CALL,
ISP_LOGIN,
DNS_QUERY,
OPEN_CONNECTION,
CLOSE_CONNECTION,
TRANSFER,
HANG_UP,
SHUTDOWN
};
Type type;
char phoneNumber[LINK_MOBILE_MAX_PHONE_NUMBER_LENGTH + 1];
DataTransfer send;
DataTransfer* receive;
DNSQuery* dns;
char loginId[LINK_MOBILE_MAX_LOGIN_ID_LENGTH + 1];
char password[LINK_MOBILE_MAX_PASSWORD_LENGTH + 1];
DNSQuery* dns;
OpenConn* open;
CloseConn* close;
u8 ip[4];
u16 port;
ConnectionType connectionType;
u8 connectionId;
DataTransfer send;
DataTransfer* receive;
bool commandSent;
u32 timeout;
bool finished;
@@ -1022,6 +1138,7 @@ class LinkMobile {
request->receive->data[i] = asyncCommand.cmd.data.bytes[1 + i];
request->receive->size = size;
request->receive->completed = true;
request->receive->success = true;
request->finished = true;
}
case ISP_CALLING: {