diff --git a/desmume/src/driver.h b/desmume/src/driver.h index 073cedbdb..3e1b7d08f 100644 --- a/desmume/src/driver.h +++ b/desmume/src/driver.h @@ -49,6 +49,8 @@ public: virtual bool WIFI_SocketsAvailable() { return true; } virtual bool WIFI_PCapAvailable() { return false; } + virtual void WIFI_GetUniqueMAC(u8* mac) {} + virtual bool WIFI_WFCWarning() { return false; } virtual int PCAP_findalldevs(pcap_if_t** alldevs, char* errbuf) { return -1; } diff --git a/desmume/src/firmware.cpp b/desmume/src/firmware.cpp index 9456bcf4d..8d50dd35e 100644 --- a/desmume/src/firmware.cpp +++ b/desmume/src/firmware.cpp @@ -869,3 +869,9 @@ void NDS_FillDefaultFirmwareConfigData( struct NDS_fw_config_data *fw_config) { fw_config->touch_cal[1].screen_x = 0xe0 + 1; fw_config->touch_cal[1].screen_y = 0x80 + 1; } + +void NDS_PatchFirmwareMAC() +{ + memcpy((MMU.fw.data + 0x36), FW_Mac, sizeof(FW_Mac)); + (*(u16*)(MMU.fw.data + 0x2A)) = calc_CRC16(0, (MMU.fw.data + 0x2C), 0x138); +} diff --git a/desmume/src/firmware.h b/desmume/src/firmware.h index 2db38fe3e..2a4888544 100644 --- a/desmume/src/firmware.h +++ b/desmume/src/firmware.h @@ -80,6 +80,7 @@ public: int copy_firmware_user_data( u8 *dest_buffer, const u8 *fw_data); int NDS_CreateDummyFirmware( struct NDS_fw_config_data *user_settings); void NDS_FillDefaultFirmwareConfigData( struct NDS_fw_config_data *fw_config); +void NDS_PatchFirmwareMAC(); #endif diff --git a/desmume/src/wifi.cpp b/desmume/src/wifi.cpp index 07eebd479..79027a8ad 100644 --- a/desmume/src/wifi.cpp +++ b/desmume/src/wifi.cpp @@ -1631,10 +1631,9 @@ typedef struct _Adhoc_FrameHeader bool Adhoc_Init() { + BOOL opt_true = TRUE; int res; - Adhoc.usecCounter = 0; - if (!driver->WIFI_SocketsAvailable()) { WIFI_LOG(1, "Ad-hoc: failed to initialize sockets.\n"); @@ -1650,6 +1649,10 @@ bool Adhoc_Init() return false; } + // Enable the socket to be bound to an address/port that is already in use + // This enables us to communicate with another DeSmuME instance running on the same computer. + res = setsockopt(wifi_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt_true, sizeof(BOOL)); + // Bind the socket to any address on port 7000 sockaddr_t saddr; saddr.sa_family = AF_INET; @@ -1665,8 +1668,7 @@ bool Adhoc_Init() // Enable broadcast mode // Not doing so results in failure when sendto'ing to broadcast address - BOOL opt = TRUE; - res = setsockopt(wifi_socket, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, sizeof(BOOL)); + res = setsockopt(wifi_socket, SOL_SOCKET, SO_BROADCAST, (const char*)&opt_true, sizeof(BOOL)); if (res < 0) { WIFI_LOG(1, "Ad-hoc: failed to enable broadcast mode.\n"); @@ -1679,6 +1681,8 @@ bool Adhoc_Init() *(u32*)&sendAddr.sa_data[2] = htonl(INADDR_BROADCAST); *(u16*)&sendAddr.sa_data[0] = htons(BASEPORT); + Adhoc_Reset(); + WIFI_LOG(1, "Ad-hoc: initialization successful.\n"); return true; @@ -1693,6 +1697,12 @@ void Adhoc_DeInit() void Adhoc_Reset() { Adhoc.usecCounter = 0; + + driver->WIFI_GetUniqueMAC(FW_Mac); + NDS_PatchFirmwareMAC(); + + printf("WIFI: ADHOC: MAC = %02X:%02X:%02X:%02X:%02X:%02X\n", + FW_Mac[0], FW_Mac[1], FW_Mac[2], FW_Mac[3], FW_Mac[4], FW_Mac[5]); } void Adhoc_SendPacket(u8* packet, u32 len) diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index b23ccdca2..972f83211 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -2256,6 +2256,35 @@ class WinDriver : public BaseDriver virtual bool WIFI_SocketsAvailable() { return bSocketsAvailable; } virtual bool WIFI_PCapAvailable() { return bWinPCapAvailable; } + virtual void WIFI_GetUniqueMAC(u8* mac) + { + if (mac == NULL) return; + + char hostname[256]; + if (gethostname(hostname, 256) != 0) + strncpy(hostname, "127.0.0.1", 256); + + hostent* he = gethostbyname(hostname); + unsigned long ipaddr; + if (he == NULL) + ipaddr = 0x0100007F; // 127.0.0.1 + else + ipaddr = *(unsigned long*)he->h_addr_list[0]; + + unsigned long pid = GetCurrentProcessId(); + + unsigned long hash = pid; + while ((hash & 0xFF000000) == 0) + hash <<= 1; + hash >>= 1; + hash += ipaddr >> 8; + hash &= 0x00FFFFFF; + + mac[3] = hash >> 16; + mac[4] = (hash >> 8) & 0xFF; + mac[5] = hash & 0xFF; + } + virtual bool WIFI_WFCWarning() { return MessageBox(NULL, "You are trying to connect to the Nintendo WFC servers.\n"