// SPDX-License-Identifier: CC0-1.0 // // SPDX-FileContributor: NightFox & Co., 2010 // // Basic UDP communications example. // http://www.nightfoxandco.com #include #include #include #include #include #include #define myport 22334 char server_ip[18]; // Stores the IP of the server // Tries to connect to the default access point bool ConnectWIFI(void) { bool status = false; printf("Conectando via WFC...\n\n"); swiWaitForVBlank(); if (NF_WiFiConnectDefaultAp()) { // Return connection parameters printf("Conexion realizada.\n\n"); printf("IP : %s\n", inet_ntoa(NF_IP)); printf("Gateway: %s\n", inet_ntoa(NF_GATEWAY)); printf("Mask : %s\n", inet_ntoa(NF_MASK)); printf("DNS1 : %s\n", inet_ntoa(NF_DNS1)); printf("DNS2 : %s\n\n", inet_ntoa(NF_DNS2)); // Success status = true; } else { // Error printf("Conexion no establecida\n"); } swiWaitForVBlank(); return status; } // Wait for the user to select client (1) or server (2) mode. u8 SelectMode(void) { u8 modo = 0; printf("A - Cliente\nB - Servidor\n"); swiWaitForVBlank(); while (modo == 0) { scanKeys(); u16 keys = keysDown(); if (keys & KEY_A) modo = 1; if (keys & KEY_B) modo = 2; swiWaitForVBlank(); } return modo; } // Send data through the open channel s16 SendData(const char *mydata) { bool checksum = false; bool timeout = false; s32 status = 0; char buffer[NF_WIFI_BUFFER_SIZE]; // Copy data to a temporary buffer sprintf(buffer, "%s", mydata); while (!checksum && !timeout) { // Send data using UDP NF_WIFI_UdpSend(buffer); // Wait for the confirmation from the other end with a 600 ms timeout status = NF_WIFI_UdpListen(600000); // Do a data checksum if (status > 0) { if ((strcmp(NF_SEND_BUFFER, NF_RECV_BUFFER) == 0)) { checksum = true; } else { checksum = true; status = -1; // Checksum error } } else { timeout = true; status = -2; // Timed out } } return status; } // Receive data from the open channel s16 GetData(void) { // Listen to data with a 300 millisecond timeout s32 status = NF_WIFI_UdpListen(300000); // If any data has been received, return them to the sender to check them if (status > 0) NF_WIFI_UdpSend(NF_RECV_BUFFER); return status; } // Scans all IPs in the specified range to look for a server to connect to. s16 LookForServer(void) { // Variables locales char myip[18]; char temp[64]; u16 p = 0; bool loop = true; s8 status = 0; // Get the local IP and extract its range (for example, "192.168.0.") sprintf(temp, "%s", inet_ntoa(NF_IP)); for (int n = 0; n < strlen(temp); n ++) { myip[n] = temp[n]; char c = temp[n]; if (c == '.') { p++; // If this is the third dot, end the string if (p == 3) { myip[n + 1] = '\0'; break; } } } // Scan all possible IPs p = 0; for (int n = 1; n < 255; n ++) { scanKeys(); u16 keys = keysDown(); // Generate IP sprintf(temp, "%s%d", myip, n); printf("%s ", temp); swiWaitForVBlank(); // Create sender socket NF_WIFI_CreateUdpSender(temp, myport); // Send data and verify that it has been received loop = true; while (loop) { status = SendData("HANDSHAKE"); if (status > 0) { // Print received data printf("Encontrado.\n"); // Save its value sprintf(server_ip, temp); p = n; n = 255; loop = false; } else { printf("Timed out.\n"); if (status == -2) loop = false; } } // Close the socket close(NF_SOCKET); // If the user wants to cancel, exit if (keys & KEY_R) break; } return p; } int main(int argc, char **argv) { u8 modo = 0; // Client (1) - Server (2) u32 contador = 0; char temp[256]; bool loop = true; bool senddata = true; // Initialize 2D engine in both screens and use mode 0 NF_Set2D(0, 0); NF_Set2D(1, 0); // Initialize demo text console consoleDemoInit(); // Try to connect to the WiFi access point if (ConnectWIFI()) { // Ask the user if this console is a server or a client modo = SelectMode(); if (modo == 1) { // Run as client if (LookForServer() > 0) NF_WIFI_CreateUdpSender(server_ip, myport); else loop = false; } else { // Run as server NF_WIFI_CreateUdpListener(myport); } // Send or receive data until the transmission is cancelled while (loop) { scanKeys(); u16 keys = keysDown(); if (modo == 1) { // Send data to server // Send data when the user presses A if (keys & KEY_A) senddata = true; // Stop sending data when the user presses B if (keys & KEY_B) senddata = false; // Reset counter when the user presses X if (keys & KEY_X) contador = 0; // Exit if R is pressed if (keys & KEY_R) loop = false; if (senddata) { if (loop) { // Send data if the loop is active sprintf(temp, "%05lu", contador); } else { // If not, send an exit string sprintf(temp, "Exit"); } // Send it and verify that it has been received printf("Envio: %s\n", temp); if (SendData(temp) > 0) { // Print the received data printf("Verificado: %s\n\n", NF_RECV_BUFFER); // Increment counter contador++; if (contador > 9999) contador = 0; } else { printf("Error de envio.\n"); } } } else { // Data reception in the client // Exit loop if R is pressed if (keys & KEY_R) loop = false; // Receive data if (GetData() > 0) { // Print received data printf("Recivido: %s\n", NF_RECV_BUFFER); // If the exit signal has been received if (strcmp(NF_RECV_BUFFER, "Exit") == 0) loop = false; } else { // If there is nothing available, wait for data printf("Esperando datos...\n"); } } // Wait for the screen refresh swiWaitForVBlank(); } } // Close the socket close(NF_SOCKET); // Stop WiFi NF_WiFiDisconnectAp(); printf("\nSesion finalizada\n"); while (1) { swiWaitForVBlank(); } return 0; }