diff options
Diffstat (limited to 'src/Wifi.cpp')
-rw-r--r-- | src/Wifi.cpp | 197 |
1 files changed, 60 insertions, 137 deletions
diff --git a/src/Wifi.cpp b/src/Wifi.cpp index 3716b4c..1486b40 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -27,91 +27,19 @@ using Platform::Log; using Platform::LogLevel; -namespace Wifi -{ //#define WIFI_LOG printf #define WIFI_LOG(...) {} #define PRINT_MAC(pf, mac) Log(LogLevel::Debug, "%s: %02X:%02X:%02X:%02X:%02X:%02X\n", pf, (mac)[0], (mac)[1], (mac)[2], (mac)[3], (mac)[4], (mac)[5]); -u8 RAM[0x2000]; -u16 IO[0x1000>>1]; - #define IOPORT(x) IO[(x)>>1] #define IOPORT8(x) ((u8*)IO)[x] // destination MACs for MP frames -const u8 MPCmdMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x00}; -const u8 MPReplyMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x10}; -const u8 MPAckMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x03}; - -const int kTimerInterval = 8; -const u32 kTimeCheckMask = ~(kTimerInterval - 1); - -bool Enabled; -bool PowerOn; - -s32 TimerError; - -u16 Random; - -// general, always-on microsecond counter -u64 USTimestamp; - -u64 USCounter; -u64 USCompare; -bool BlockBeaconIRQ14; - -u32 CmdCounter; - -u8 BBRegs[0x100]; -u8 BBRegsRO[0x100]; - -u8 RFVersion; -u32 RFRegs[0x40]; - -struct TXSlot -{ - bool Valid; - u16 Addr; - u16 Length; - u8 Rate; - u8 CurPhase; - int CurPhaseTime; - u32 HalfwordTimeMask; -}; - -TXSlot TXSlots[6]; -u8 TXBuffer[0x2000]; - -u8 RXBuffer[2048]; -u32 RXBufferPtr; -int RXTime; -u32 RXHalfwordTimeMask; - -u32 ComStatus; // 0=waiting for packets 1=receiving 2=sending -u32 TXCurSlot; -u32 RXCounter; - -int MPReplyTimer; -u16 MPClientMask, MPClientFail; - -u8 MPClientReplies[15*1024]; - -u16 MPLastSeqno; - -bool MPInited; -bool LANInited; - -int USUntilPowerOn; -bool ForcePowerOn; - -// MULTIPLAYER SYNC APPARATUS -bool IsMP; -bool IsMPClient; -u64 NextSync; // for clients: timestamp for next sync point -u64 RXTimestamp; +const u8 Wifi::MPCmdMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x00}; +const u8 Wifi::MPReplyMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x10}; +const u8 Wifi::MPAckMAC[6] = {0x03, 0x09, 0xBF, 0x00, 0x00, 0x03}; // multiplayer host TX sequence: // 1. preamble @@ -148,9 +76,20 @@ u64 RXTimestamp; // * TX errors (if applicable) -bool Init() +bool MACEqual(u8* a, const u8* b) +{ + return (*(u32*)&a[0] == *(u32*)&b[0]) && (*(u16*)&a[4] == *(u16*)&b[4]); +} + +bool MACIsBroadcast(u8* a) +{ + return (*(u32*)&a[0] == 0xFFFFFFFF) && (*(u16*)&a[4] == 0xFFFF); +} + + +Wifi::Wifi() { - NDS::RegisterEventFunc(NDS::Event_Wifi, 0, USTimer); + NDS::RegisterEventFunc(NDS::Event_Wifi, 0, MemberEventFunc(Wifi, USTimer)); //MPInited = false; //LANInited = false; @@ -161,24 +100,22 @@ bool Init() Platform::LAN_Init(); LANInited = true; - WifiAP::Init(); - - return true; + WifiAP = new class WifiAP(this); } -void DeInit() +Wifi::~Wifi() { if (MPInited) Platform::MP_DeInit(); if (LANInited) Platform::LAN_DeInit(); - WifiAP::DeInit(); + delete WifiAP; WifiAP = nullptr; NDS::UnregisterEventFunc(NDS::Event_Wifi, 0); } -void Reset() +void Wifi::Reset() { memset(RAM, 0, 0x2000); memset(IO, 0, 0x1000); @@ -277,10 +214,10 @@ void Reset() NextSync = 0; RXTimestamp = 0; - WifiAP::Reset(); + WifiAP->Reset(); } -void DoSavestate(Savestate* file) +void Wifi::DoSavestate(Savestate* file) { file->Section("WIFI"); @@ -355,7 +292,7 @@ void DoSavestate(Savestate* file) } -void ScheduleTimer(bool first) +void Wifi::ScheduleTimer(bool first) { if (first) TimerError = 0; @@ -367,7 +304,7 @@ void ScheduleTimer(bool first) NDS::ScheduleEvent(NDS::Event_Wifi, !first, delay, 0, 0); } -void UpdatePowerOn() +void Wifi::UpdatePowerOn() { bool on = Enabled; @@ -405,17 +342,14 @@ void UpdatePowerOn() } } -void SetPowerCnt(u32 val) +void Wifi::SetPowerCnt(u32 val) { Enabled = val & (1<<1); UpdatePowerOn(); } -void PowerDown(); -void StartTX_Beacon(); - -void SetIRQ(u32 irq) +void Wifi::SetIRQ(u32 irq) { u32 oldflags = IOPORT(W_IF) & IOPORT(W_IE); @@ -426,7 +360,7 @@ void SetIRQ(u32 irq) NDS::SetIRQ(1, NDS::IRQ_Wifi); } -void SetIRQ13() +void Wifi::SetIRQ13() { SetIRQ(13); @@ -440,7 +374,7 @@ void SetIRQ13() } } -void SetIRQ14(int source) // 0=USCOMPARE 1=BEACONCOUNT 2=forced +void Wifi::SetIRQ14(int source) // 0=USCOMPARE 1=BEACONCOUNT 2=forced { if (source != 2) IOPORT(W_BeaconCount1) = IOPORT(W_BeaconInterval); @@ -469,7 +403,7 @@ void SetIRQ14(int source) // 0=USCOMPARE 1=BEACONCOUNT 2=forced IOPORT(W_ListenCount)--; } -void SetIRQ15() +void Wifi::SetIRQ15() { SetIRQ(15); @@ -481,7 +415,7 @@ void SetIRQ15() } -void SetStatus(u32 status) +void Wifi::SetStatus(u32 status) { // TODO, eventually: states 2/4/7 u16 rfpins[10] = {0x04, 0x84, 0, 0x46, 0, 0x84, 0x87, 0, 0x46, 0x04}; @@ -490,7 +424,7 @@ void SetStatus(u32 status) } -void PowerDown() +void Wifi::PowerDown() { IOPORT(W_TXReqRead) &= ~0x000F; IOPORT(W_PowerState) |= 0x0200; @@ -504,20 +438,14 @@ void PowerDown() } -bool MACEqual(const u8* a, const u8* b) -{ - return (*(u32*)&a[0] == *(u32*)&b[0]) && (*(u16*)&a[4] == *(u16*)&b[4]); -} - - -int PreambleLen(int rate) +int Wifi::PreambleLen(int rate) { if (rate == 1) return 192; if (IOPORT(W_Preamble) & 0x0004) return 96; return 192; } -u32 NumClients(u16 bitmask) +u32 Wifi::NumClients(u16 bitmask) { u32 ret = 0; for (int i = 1; i < 16; i++) @@ -527,14 +455,14 @@ u32 NumClients(u16 bitmask) return ret; } -void IncrementTXCount(TXSlot* slot) +void Wifi::IncrementTXCount(TXSlot* slot) { u8 cnt = RAM[slot->Addr + 0x4]; if (cnt < 0xFF) cnt++; *(u16*)&RAM[slot->Addr + 0x4] = cnt; } -void ReportMPReplyErrors(u16 clientfail) +void Wifi::ReportMPReplyErrors(u16 clientfail) { // TODO: do these trigger any IRQ? @@ -547,7 +475,7 @@ void ReportMPReplyErrors(u16 clientfail) } } -void TXSendFrame(TXSlot* slot, int num) +void Wifi::TXSendFrame(TXSlot* slot, int num) { u32 noseqno = 0; @@ -597,7 +525,7 @@ void TXSendFrame(TXSlot* slot, int num) case 2: case 3: Platform::MP_SendPacket(TXBuffer, 12+len, USTimestamp); - if (!IsMP) WifiAP::SendPacket(TXBuffer, 12+len); + if (!IsMP) WifiAP->SendPacket(TXBuffer, 12+len); break; case 1: @@ -617,7 +545,7 @@ void TXSendFrame(TXSlot* slot, int num) } } -void StartTX_LocN(int nslot, int loc) +void Wifi::StartTX_LocN(int nslot, int loc) { TXSlot* slot = &TXSlots[nslot]; @@ -637,7 +565,7 @@ void StartTX_LocN(int nslot, int loc) slot->CurPhaseTime = PreambleLen(slot->Rate); } -void StartTX_Cmd() +void Wifi::StartTX_Cmd() { TXSlot* slot = &TXSlots[1]; @@ -672,7 +600,7 @@ void StartTX_Cmd() } } -void StartTX_Beacon() +void Wifi::StartTX_Beacon() { TXSlot* slot = &TXSlots[4]; @@ -691,7 +619,7 @@ void StartTX_Beacon() IOPORT(W_TXBusy) |= 0x0010; } -void FireTX() +void Wifi::FireTX() { if (!(IOPORT(W_RXCnt) & 0x8000)) return; @@ -736,7 +664,7 @@ void FireTX() } } -void SendMPDefaultReply() +void Wifi::SendMPDefaultReply() { u8 reply[12 + 28]; @@ -766,7 +694,7 @@ void SendMPDefaultReply() WIFI_LOG("wifi: sent %d/40 bytes of MP default reply\n", txlen); } -void SendMPReply(u16 clienttime, u16 clientmask) +void Wifi::SendMPReply(u16 clienttime, u16 clientmask) { TXSlot* slot = &TXSlots[5]; @@ -827,7 +755,7 @@ void SendMPReply(u16 clienttime, u16 clientmask) IOPORT(W_TXBusy) |= 0x0080; } -void SendMPAck(u16 cmdcount, u16 clientfail) +void Wifi::SendMPAck(u16 cmdcount, u16 clientfail) { u8 ack[12 + 32]; @@ -873,10 +801,7 @@ void SendMPAck(u16 cmdcount, u16 clientfail) WIFI_LOG("wifi: sent %d/44 bytes of MP ack, %d %d\n", txlen, ComStatus, RXTime); } -bool CheckRX(int type); -void MPClientReplyRX(int client); - -bool ProcessTX(TXSlot* slot, int num) +bool Wifi::ProcessTX(TXSlot* slot, int num) { slot->CurPhaseTime -= kTimerInterval; if (slot->CurPhaseTime > 0) @@ -1137,7 +1062,7 @@ bool ProcessTX(TXSlot* slot, int num) } -inline void IncrementRXAddr(u16& addr, u16 inc = 2) +inline void Wifi::IncrementRXAddr(u16& addr, u16 inc) { for (u32 i = 0; i < inc; i += 2) { @@ -1148,7 +1073,7 @@ inline void IncrementRXAddr(u16& addr, u16 inc = 2) } } -void StartRX() +void Wifi::StartRX() { u16 framelen = *(u16*)&RXBuffer[8]; RXTime = framelen; @@ -1176,7 +1101,7 @@ void StartRX() ComStatus |= 1; } -void FinishRX() +void Wifi::FinishRX() { ComStatus &= ~0x1; RXCounter = 0; @@ -1451,7 +1376,7 @@ void FinishRX() } } -void MPClientReplyRX(int client) +void Wifi::MPClientReplyRX(int client) { if (IOPORT(W_PowerState) & 0x0300) return; @@ -1492,7 +1417,7 @@ void MPClientReplyRX(int client) StartRX(); } -bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames +bool Wifi::CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames { if (IOPORT(W_PowerState) & 0x0300) return false; @@ -1517,7 +1442,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames { rxlen = Platform::MP_RecvPacket(RXBuffer, ×tamp); if ((rxlen <= 0) && (!IsMP)) - rxlen = WifiAP::RecvPacket(RXBuffer); + rxlen = WifiAP->RecvPacket(RXBuffer); } else { @@ -1632,7 +1557,7 @@ bool CheckRX(int type) // 0=regular 1=MP replies 2=MP host frames } -void MSTimer() +void Wifi::MSTimer() { if (IOPORT(W_USCompareCnt)) { @@ -1656,7 +1581,7 @@ void MSTimer() } } -void USTimer(u32 param) +void Wifi::USTimer(u32 param) { USTimestamp += kTimerInterval; @@ -1676,7 +1601,7 @@ void USTimer(u32 param) } if (!(USTimestamp & 0x3FF & kTimeCheckMask)) - WifiAP::MSTimer(); + WifiAP->MSTimer(); bool switchOffPowerSaving = false; if (USUntilPowerOn < 0) @@ -1839,7 +1764,7 @@ void USTimer(u32 param) } -void RFTransfer_Type2() +void Wifi::RFTransfer_Type2() { u32 id = (IOPORT(W_RFData2) >> 2) & 0x1F; @@ -1856,7 +1781,7 @@ void RFTransfer_Type2() } } -void RFTransfer_Type3() +void Wifi::RFTransfer_Type3() { u32 id = (IOPORT(W_RFData1) >> 8) & 0x3F; @@ -1873,7 +1798,7 @@ void RFTransfer_Type3() } -u16 Read(u32 addr) +u16 Wifi::Read(u32 addr) { if (addr >= 0x04810000) return 0; @@ -1976,7 +1901,7 @@ u16 Read(u32 addr) return IOPORT(addr&0xFFF); } -void Write(u32 addr, u16 val) +void Wifi::Write(u32 addr, u16 val) { if (addr >= 0x04810000) return; @@ -2331,14 +2256,12 @@ void Write(u32 addr, u16 val) } -u8* GetMAC() +u8* Wifi::GetMAC() { return (u8*)&IOPORT(W_MACAddr0); } -u8* GetBSSID() +u8* Wifi::GetBSSID() { return (u8*)&IOPORT(W_BSSID0); } - -} |