Refactoring and trying out multiple clients

This commit is contained in:
Rodrigo Alfonso
2023-01-29 05:25:25 -03:00
parent 91ab5a70fb
commit c8e639ff8f
2 changed files with 219 additions and 164 deletions

View File

@@ -4,7 +4,14 @@
// (0) Include the header
#include "../../_lib/LinkWireless.h"
void activate();
void host();
void connect();
void messageLoop(bool acceptNewClients);
void log(std::string text);
void waitFor(u16 key);
void vBlankWait();
void hang();
// (1) Create a LinkWireless instance
LinkWireless* linkWireless = new LinkWireless();
@@ -14,9 +21,6 @@ void init() {
REG_DISPCNT = DCNT_MODE0 | DCNT_BG0;
tte_init_se_default(0, BG_CBB(0) | BG_SBB(31));
// (2) Initialize the library
// linkWireless->activate(); // TODO: RECOVER
}
int main() {
@@ -27,164 +31,200 @@ int main() {
bool connecting = false;
while (true) {
// std::string output = "";
u16 keys = ~REG_KEYS & KEY_ANY;
if ((keys & KEY_START) && !activating) {
log("Trying...");
activating = true;
if (linkWireless->activate())
log("Activated! :)");
else
log("Activation failed! :(");
}
log("START = Activate\nL = Host\nR = Connect");
// START = Activate
if ((keys & KEY_START) && !activating) {
activating = true;
activate();
}
if (activating && !(keys & KEY_START))
activating = false;
// L = Host
if ((keys & KEY_L) && !hosting) {
log("Hosting...");
hosting = true;
if (linkWireless->host(std::vector<u32>{0x0c020002, 0x00005ce1,
0x00000000, 0x09000040,
0xc1cfc8cd, 0x00ffccbb})) {
log("Hosting ok. Listening...");
u16 newId = 0;
do {
newId = linkWireless->getNewConnectionId();
log("Hosting ok. " + std::to_string(newId) + " Listening... ");
} while (newId == 0 || newId == 1);
log("CONNECTED! " + std::to_string(newId));
u32 i = 50;
bool sending = false;
// TODO: DEDUP
while (true) {
keys = ~REG_KEYS & KEY_ANY;
if (!sending && (keys & KEY_A)) {
sending = true;
linkWireless->sendData(std::vector<u32>{i});
i++;
}
if (sending && !(keys & KEY_A))
sending = false;
std::vector<u32> receivedData = std::vector<u32>{};
if (!linkWireless->receiveData(receivedData)) {
log("ERROR RECEIVING!");
while (true)
;
}
if (receivedData.size() > 0)
log("RECEIVED: " + std::to_string(receivedData[0]));
while (REG_VCOUNT >= 160)
; // wait till VDraw
while (REG_VCOUNT < 160)
; // wait till VBlank
}
} else {
log("Hosting error");
while (true)
;
}
host();
}
if (hosting && !(keys & KEY_L))
hosting = false;
// R = Connect
if (!connecting && (keys & KEY_R)) {
log("Searching...");
connecting = true;
std::vector<u32> data;
if (linkWireless->getBroadcasts(data)) {
std::string str =
"Press select to conn " + std::to_string(data.size()) + "\n";
for (u32& dat : data)
str += std::to_string(dat) + "\n";
log(str);
if (data.size() > 0) {
do {
keys = ~REG_KEYS & KEY_ANY;
} while (!(keys & KEY_SELECT));
if (!linkWireless->connect((u16)data[0])) {
log("CONNECT FAILED!");
while (true)
;
}
u16 idid = 0;
do {
idid = linkWireless->isFinishedConnect();
} while (idid <= 1);
log("HAVE ID! PRESS SEL! " + std::to_string(idid));
do {
keys = ~REG_KEYS & KEY_ANY;
} while (!(keys & KEY_SELECT));
u16 asd = linkWireless->finishConnection();
if (asd == 0) {
log("FINISH CONNECT FAILED!");
while (true)
;
}
u32 i = 50;
bool sending = false;
log("CONNECTED! " + std::to_string(asd));
// TODO: DEDUP
while (true) {
keys = ~REG_KEYS & KEY_ANY;
if (!sending && (keys & KEY_A)) {
sending = true;
linkWireless->sendData(std::vector<u32>{i});
i++;
}
if (sending && !(keys & KEY_A))
sending = false;
std::vector<u32> receivedData = std::vector<u32>{};
if (!linkWireless->receiveData(receivedData)) {
log("ERROR RECEIVING!");
while (true)
;
}
if (receivedData.size() > 0)
log("RECEIVED: " + std::to_string(receivedData[0]));
while (REG_VCOUNT >= 160)
; // wait till VDraw
while (REG_VCOUNT < 160)
; // wait till VBlank
}
}
} else
log("Search failed :(");
connect();
}
if (connecting && !(keys & KEY_R))
connecting = false;
while (REG_VCOUNT >= 160)
; // wait till VDraw
while (REG_VCOUNT < 160)
; // wait till VBlank
vBlankWait();
}
return 0;
}
void activate() {
log("Trying...");
if (linkWireless->activate())
log("Activated!");
else
log("Activation failed! :(");
hang();
}
void host() {
log("Hosting...");
if (!linkWireless->host(std::vector<u32>{0x0c020002, 0x00005ce1, 0x00000000,
0x09000040, 0xc1cfc8cd,
0x00ffccbb})) {
log("Hosting failed :(");
hang();
return;
}
log("Listening...");
LinkWireless::ClientIdResponses response;
do {
response = linkWireless->acceptConnection();
if (!response.success) {
log("Accept failed :(");
hang();
return;
}
} while (response.clientIds[0] == 0);
log("Connected! " + std::to_string(response.clientIds[0]));
messageLoop(true);
}
void connect() {
log("Searching...");
std::vector<u32> broadcastData;
if (!linkWireless->getBroadcasts(broadcastData)) {
log("Search failed :(");
hang();
return;
}
std::string str = "Press SELECT to connect\n";
for (u32& number : broadcastData)
str += std::to_string(number) + "\n";
log(str);
if (broadcastData.size() == 0) {
log("Nothing found :(");
hang();
return;
}
waitFor(KEY_SELECT);
if (!linkWireless->connect((u16)broadcastData[0])) {
log("Connect failed :(");
hang();
return;
}
LinkWireless::ClientIdResponse response1;
do {
response1 = linkWireless->checkConnection();
if (!response1.success) {
log("Check connection failed :(");
hang();
return;
}
log("Checking: " + std::to_string(response1.clientId));
} while (response1.clientId == 0);
log("Assigned id (press SELECT):\n" + std::to_string(response1.clientId));
waitFor(KEY_SELECT);
auto response2 = linkWireless->finishConnection();
if (!response2.success) {
log("Finish connection failed :(");
hang();
return;
}
if (response2.clientId != response1.clientId) {
log("Assigned IDs don't match :(");
hang();
return;
}
log("Connected! " + std::to_string(response2.clientId));
messageLoop(false);
}
void messageLoop(bool acceptNewClients) {
u32 i = 50;
bool sending = false;
while (true) {
u16 keys = ~REG_KEYS & KEY_ANY;
if (!sending && (keys & KEY_A)) {
sending = true;
linkWireless->sendData(std::vector<u32>{1, i});
i++;
}
if (sending && !(keys & KEY_A))
sending = false;
if (acceptNewClients) {
auto newConnection = linkWireless->acceptConnection();
if (!newConnection.success) {
log("Accept failed :(");
hang();
return;
}
if (newConnection.clientIds.size() > 1)
log("New connection: " + std::to_string(newConnection.clientIds[1]));
}
std::vector<u32> receivedData = std::vector<u32>{};
if (!linkWireless->receiveData(receivedData)) {
log("Receive failed :(");
hang();
return;
}
if (receivedData.size() > 1)
log("<<< " + std::to_string(receivedData[1]));
vBlankWait();
}
}
void log(std::string text) {
tte_erase_screen();
tte_write("#{P:0,0}");
tte_write(text.c_str());
}
void waitFor(u16 key) {
u16 keys;
do {
keys = ~REG_KEYS & KEY_ANY;
} while (!(keys & key));
}
void vBlankWait() {
while (REG_VCOUNT >= 160)
; // wait till VDraw
while (REG_VCOUNT < 160)
; // wait till VBlank
}
void hang() {
waitFor(KEY_DOWN);
}

View File

@@ -30,10 +30,9 @@
#include "LinkGPIO.h"
#include "LinkSPI.h"
// TODO: AVOID response.responses, use result
#define LINK_WIRELESS_PING_WAIT 50
#define LINK_WIRELESS_TRANSFER_WAIT 15
#define LINK_WIRELESS_BROADCAST_SEARCH_WAIT ((160 + 68) * 60)
#define LINK_WIRELESS_TIMEOUT 100
#define LINK_WIRELESS_LOGIN_STEPS 9
#define LINK_WIRELESS_BROADCAST_SIZE 6
@@ -59,6 +58,14 @@ const u16 LINK_WIRELESS_LOGIN_PARTS[] = {0x494e, 0x494e, 0x544e, 0x544e, 0x4e45,
class LinkWireless {
public:
struct ClientIdResponse {
bool success = false;
u16 clientId = 0;
};
struct ClientIdResponses {
bool success = false;
std::vector<u32> clientIds = std::vector<u32>{0}; // TODO: IMPROVE
};
std::function<void(std::string)> debug; // TODO: REMOVE
bool isActive() { return isEnabled; }
@@ -87,13 +94,18 @@ class LinkWireless {
sendCommand(LINK_WIRELESS_COMMAND_START_HOST).success;
}
u16 getNewConnectionId() {
auto response = sendCommand(0x1a);
if (!response.success)
return 0; // TODO: PROPER RETURN TYPE
ClientIdResponses acceptConnection() {
auto result = sendCommand(LINK_WIRELESS_COMMAND_IS_CONNECT_ATTEMPT);
return response.responses.size() > 0 ? (u16)response.responses[0]
: 1; // TODO: FIGURE OUT MULTIPLE IDS
ClientIdResponses response;
if (!result.success)
return response;
response.success = true;
if (result.responses.size() == 0)
return response;
response.clientIds = result.responses;
return response;
}
bool connect(u16 remoteId) {
@@ -102,26 +114,35 @@ class LinkWireless {
.success;
}
u16 isFinishedConnect() {
auto response = sendCommand(LINK_WIRELESS_COMMAND_IS_FINISHED_CONNECT);
if (!response.success || response.responses.size() == 0)
return 0; // TODO: PROPER RETURN TYPE
ClientIdResponse checkConnection() {
auto result = sendCommand(LINK_WIRELESS_COMMAND_IS_FINISHED_CONNECT);
if (msB32(response.responses[0]) > 0)
return 1;
ClientIdResponse response;
if (!result.success)
return response;
response.success = true;
if (result.responses.size() == 0 || msB32(result.responses[0]) > 0)
return response;
response.clientId = (u16)result.responses[0];
return (u16)response.responses[0];
return response;
}
u16 finishConnection() {
auto response = sendCommand(LINK_WIRELESS_COMMAND_FINISH_CONNECTION);
if (!response.success || response.responses.size() == 0)
return 0; // TODO: PROPER RETURN TYPE
ClientIdResponse finishConnection() {
auto result = sendCommand(LINK_WIRELESS_COMMAND_FINISH_CONNECTION);
return (u16)response.responses[0];
ClientIdResponse response;
if (!result.success)
return response;
response.success = true;
if (result.responses.size() == 0)
return response;
response.clientId = (u16)result.responses[0];
return response;
}
// TODO: 0 IS NOT A VALID VALUE
// TODO: CHECK RANGES
bool sendData(std::vector<u32> data) {
return sendCommand(LINK_WIRELESS_COMMAND_SEND_DATA, data).success;
}
@@ -142,19 +163,13 @@ class LinkWireless {
if (!sendCommand(LINK_WIRELESS_COMMAND_BROADCAST_READ_START).success)
return false;
wait(228 * 60); // TODO: NEEDED INDEED!
wait(LINK_WIRELESS_BROADCAST_SEARCH_WAIT);
auto result = sendCommand(LINK_WIRELESS_COMMAND_BROADCAST_READ_END);
data = result.responses;
return result.success;
}
// bool read(std::vector<u32>& data) {
// auto result = sendCommand(LINK_WIRELESS_COMMAND_BROADCAST_READ);
// data = result.responses;
// return result.success;
// }
~LinkWireless() {
delete linkSPI;
delete linkGPIO;