diff --git a/src/Wifi.cpp b/src/Wifi.cpp index c5039d14..e08be346 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -21,6 +21,7 @@ #include "NDS.h" #include "SPI.h" #include "Wifi.h" +#include "WifiAP.h" #include "Platform.h" @@ -126,6 +127,8 @@ bool Init() MPInited = false; LANInited = false; + WifiAP::Init(); + return true; } @@ -135,6 +138,8 @@ void DeInit() Platform::MP_DeInit(); if (LANInited) Platform::LAN_DeInit(); + + WifiAP::DeInit(); } void Reset() @@ -204,6 +209,8 @@ void Reset() MPNumReplies = 0; CmdCounter = 0; + + WifiAP::Reset(); } @@ -767,7 +774,7 @@ bool CheckRX(bool block) for (;;) { int rxlen = Platform::MP_RecvPacket(RXBuffer, block); - //if (rxlen == 0) rxlen = Platform::LAN_RecvPacket(RXBuffer); + if (rxlen == 0) rxlen = WifiAP::RecvPacket(RXBuffer); if (rxlen == 0) return false; if (rxlen < 12+24) continue; @@ -909,6 +916,8 @@ void MSTimer() void USTimer(u32 param) { + WifiAP::USTimer(); + if (IOPORT(W_USCountCnt)) { USCounter++; @@ -1478,4 +1487,15 @@ void Write(u32 addr, u16 val) IOPORT(addr&0xFFF) = val; } + +u8* GetMAC() +{ + return (u8*)&IOPORT(W_MACAddr0); +} + +u8* GetBSSID() +{ + return (u8*)&IOPORT(W_BSSID0); +} + } diff --git a/src/Wifi.h b/src/Wifi.h index f0bf0ad4..72334e01 100644 --- a/src/Wifi.h +++ b/src/Wifi.h @@ -154,6 +154,9 @@ void USTimer(u32 param); u16 Read(u32 addr); void Write(u32 addr, u16 val); +u8* GetMAC(); +u8* GetBSSID(); + } #endif diff --git a/src/WifiAP.cpp b/src/WifiAP.cpp index e4594977..cbec697c 100644 --- a/src/WifiAP.cpp +++ b/src/WifiAP.cpp @@ -18,6 +18,7 @@ #include #include +#include "NDS.h" #include "Wifi.h" #include "WifiAP.h" @@ -25,6 +26,137 @@ namespace WifiAP { -// +#define AP_MAC 0x00, 0xF0, 0x77, 0x77, 0x77, 0x77 +#define AP_NAME "melonAP" + +const u8 APMac[6] = {AP_MAC}; + +#define PWRITE_8(p, v) *p++ = v; +#define PWRITE_16(p, v) *(u16*)p = v; p += 2; +#define PWRITE_32(p, v) *(u32*)p = v; p += 4; +#define PWRITE_64(p, v) *(u64*)p = v; p += 8; + +#define PWRITE_MAC(p, a,b,c,d,e,f) \ + *p++ = a; *p++ = b; *p++ = c; *p++ = d; *p++ = e; *p++ = f; + +#define PWRITE_MAC2(p, m) \ + *p++ = m[0]; *p++ = m[1]; *p++ = m[2]; *p++ = m[3]; *p++ = m[4]; *p++ = m[5]; + +#define PWRITE_SEQNO(p) PWRITE_16(p, SeqNo); SeqNo += 0x10; + +#define PWRITE_TXH(p, len, rate) \ + PWRITE_16(p, 0); \ + PWRITE_16(p, 0); \ + PWRITE_16(p, 0); \ + PWRITE_16(p, 0); \ + PWRITE_8(p, rate); \ + PWRITE_8(p, 0); \ + PWRITE_16(p, len); + +//#define PALIGN_4(p, base) p += ((4 - ((ptrdiff_t)(p-base) & 0x3)) & 0x3); +// no idea what is the ideal padding there +// but in the case of management frames the padding shouldn't be counted as an information element +#define PLEN(p, base) (int)(ptrdiff_t)(p-base) +#define PALIGN_4(p, base) while (PLEN(p,base) & 0x3) *p++ = 0xFF; + + +u64 USCounter; + +u16 SeqNo; + +bool BeaconDue; + +u8 PacketBuffer[2048]; +int PacketLen; +int RXNum; + + +bool Init() +{ + return true; +} + +void DeInit() +{ +} + +void Reset() +{ + // random starting point for the counter + USCounter = 0x428888017ULL; + SeqNo = 0x0120; + + BeaconDue = false; + + memset(PacketBuffer, 0, sizeof(PacketBuffer)); + PacketLen = 0; + RXNum = 0; +} + + +void USTimer() +{ + USCounter++; + + u32 chk = (u32)USCounter; + if (!(chk & 0x1FFFF)) + { + // send beacon every 128ms + BeaconDue = true; + } +} + + +int SendPacket(u8* data, int len) +{ + // +} + +int RecvPacket(u8* data) +{ + if (BeaconDue) + { + BeaconDue = false; + + // craft beacon + u8* base = data + 12; + u8* p = base; + + PWRITE_16(p, 0x0080); + PWRITE_16(p, 0x0000); // duration?? + PWRITE_MAC(p, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF); // recv + PWRITE_MAC2(p, APMac); // sender + PWRITE_MAC2(p, APMac); // BSSID + PWRITE_SEQNO(p); + + PWRITE_64(p, USCounter); + PWRITE_16(p, 128); // beacon interval + PWRITE_16(p, 0x0021); // capability + PWRITE_8(p, 0x01); PWRITE_8(p, 0x02); PWRITE_8(p, 0x82); PWRITE_8(p, 0x84); // rates + PWRITE_8(p, 0x03); PWRITE_8(p, 0x01); PWRITE_8(p, 0x06); // current channel + PWRITE_8(p, 0x05); PWRITE_8(p, 0x04); PWRITE_8(p, 0); PWRITE_8(p, 0); PWRITE_8(p, 0); PWRITE_8(p, 0); // TIM + PWRITE_8(p, 0x00); PWRITE_8(p, strlen(AP_NAME)); + memcpy(p, AP_NAME, strlen(AP_NAME)); p += strlen(AP_NAME); + + PALIGN_4(p, base); + PWRITE_32(p, 0xDEADBEEF); // checksum. doesn't matter for now + + int len = PLEN(p, base); + p = data; + PWRITE_TXH(p, len, 20); + + /*static int zorp=0; + zorp++; + char derp[55]; + sprintf(derp, "derpo%d.bin", zorp); + FILE* f = fopen(derp, "wb"); + fwrite(data, len+12, 1, f); + fclose(f);*/ + + return len+12; + } + + return 0; +} } diff --git a/src/WifiAP.h b/src/WifiAP.h index 27f497c6..fccfa1ab 100644 --- a/src/WifiAP.h +++ b/src/WifiAP.h @@ -26,7 +26,11 @@ bool Init(); void DeInit(); void Reset(); -// +void USTimer(); + +// packet format: 12-byte TX header + original 802.11 frame +int SendPacket(u8* data, int len); +int RecvPacket(u8* data); } diff --git a/src/libui_sdl/Platform.cpp b/src/libui_sdl/Platform.cpp index d835af1b..c5985de0 100644 --- a/src/libui_sdl/Platform.cpp +++ b/src/libui_sdl/Platform.cpp @@ -91,6 +91,7 @@ u8 PacketBuffer[2048]; const char* PCapLibNames[] = { #ifdef __WIN32__ + // TODO: name for npcap in non-WinPCap mode "wpcap.dll", #else // TODO: Linux lib names