aboutsummaryrefslogtreecommitdiff
path: root/src/DSi_NWifi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/DSi_NWifi.cpp')
-rw-r--r--src/DSi_NWifi.cpp310
1 files changed, 267 insertions, 43 deletions
diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp
index 7bb91aa..4843cfb 100644
--- a/src/DSi_NWifi.cpp
+++ b/src/DSi_NWifi.cpp
@@ -21,6 +21,7 @@
#include "DSi.h"
#include "DSi_NWifi.h"
#include "SPI.h"
+#include "WifiAP.h"
const u8 CIS0[256] =
@@ -111,15 +112,31 @@ const u8 CIS1[256] =
};
-// hax
-DSi_NWifi* hax_wifi;
-void triggerirq(u32 param)
+DSi_NWifi* Ctx = nullptr;
+
+
+DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
{
- hax_wifi->SetIRQ_F1_Counter(0);
+ // TODO: check the actual mailbox size (presumably 0x200)
+ for (int i = 0; i < 8; i++)
+ Mailbox[i] = new FIFO<u8>(0x200);
+
+ // this seems to control whether the firmware upload is done
+ EEPROMReady = 0;
+
+ Ctx = this;
}
+DSi_NWifi::~DSi_NWifi()
+{
+ for (int i = 0; i < 8; i++)
+ delete Mailbox[i];
+
+ NDS::CancelEvent(NDS::Event_DSi_NWifi);
+ Ctx = nullptr;
+}
-DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
+void DSi_NWifi::Reset()
{
TransferCmd = 0xFFFFFFFF;
RemSize = 0;
@@ -136,7 +153,7 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
// TODO: check the actual mailbox size (presumably 0x200)
for (int i = 0; i < 8; i++)
- Mailbox[i] = new FIFO<u8>(0x200);
+ Mailbox[i]->Clear();
u8* mac = SPI_Firmware::GetWifiMAC();
printf("NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
@@ -158,15 +175,11 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
*(u16*)&EEPROM[0x004] = chk;
- EEPROMReady = 0;
-
BootPhase = 0;
-}
-DSi_NWifi::~DSi_NWifi()
-{
- for (int i = 0; i < 8; i++)
- delete Mailbox[i];
+ ErrorMask = 0;
+
+ NDS::CancelEvent(NDS::Event_DSi_NWifi);
}
@@ -671,6 +684,7 @@ void DSi_NWifi::BMI_Command()
{
// HLE command handling stub
u32 cmd = MB_Read32(0);
+ printf("BMI: cmd %08X\n", cmd);
switch (cmd)
{
@@ -678,8 +692,8 @@ void DSi_NWifi::BMI_Command()
{
printf("BMI_DONE\n");
EEPROMReady = 1; // GROSS FUCKING HACK
- u8 ready_msg[8] = {0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00};
- SendWMIFrame(ready_msg, 8, 0, 0x00, 0x0000);
+ u8 ready_msg[6] = {0x0A, 0x00, 0x08, 0x06, 0x16, 0x00};
+ SendWMIEvent(0, 0x0001, ready_msg, 6);
BootPhase = 1;
}
return;
@@ -743,7 +757,7 @@ void DSi_NWifi::BMI_Command()
{
u32 len = MB_Read32(0);
printf("BMI LZ write %08X\n", len);
- //FILE* f = fopen("wififirm.bin", "ab");
+ //FILE* f = fopen("debug/wififirm.bin", "ab");
for (int i = 0; i < len; i++)
{
@@ -770,7 +784,6 @@ void DSi_NWifi::WMI_Command()
u16 h2 = MB_Read16(0);
u16 cmd = MB_Read16(0);
- printf("WMI: cmd %04X\n", cmd);
switch (cmd)
{
@@ -778,50 +791,162 @@ void DSi_NWifi::WMI_Command()
{
u16 svc_id = MB_Read16(0);
u16 conn_flags = MB_Read16(0);
-
- u8 svc_resp[10];
- *(u16*)&svc_resp[0] = 0x0003;
- *(u16*)&svc_resp[2] = svc_id;
- svc_resp[4] = 0;
- svc_resp[5] = (svc_id & 0xFF) + 1;
- *(u16*)&svc_resp[6] = 0x0001;
- *(u16*)&svc_resp[8] = 0x0001;
- SendWMIFrame(svc_resp, 10, 0, 0x00, 0x0000);
+ printf("service connect %04X %04X %04X\n", svc_id, conn_flags, MB_Read16(0));
+
+ u8 svc_resp[8];
+ // responses from hardware:
+ // 0003 0100 00 01 0602 00 00
+ // 0003 0101 00 02 0600 00 00
+ // 0003 0102 00 03 0600 00 00
+ // 0003 0103 00 04 0600 00 00
+ // 0003 0104 00 05 0600 00 00
+ *(u16*)&svc_resp[0] = svc_id;
+ svc_resp[2] = 0;
+ svc_resp[3] = (svc_id & 0xFF) + 1;
+ *(u16*)&svc_resp[4] = (svc_id==0x0100) ? 0x0602 : 0x0600; // max message size
+ *(u16*)&svc_resp[6] = 0x0000;
+ SendWMIEvent(0, 0x0003, svc_resp, 8);
}
break;
case 0x0004: // setup complete
{
- u8 ready_evt[14];
- memset(ready_evt, 0, 14);
- *(u16*)&ready_evt[0] = 0x1001;
- memcpy(&ready_evt[2], SPI_Firmware::GetWifiMAC(), 6);
- ready_evt[8] = 0x02;
- *(u32*)&ready_evt[10] = 0x23000024;
- // ctrl[0] = trailer size
- // trailer[1] = trailer extra size
- // trailer[0] = trailer type???
- SendWMIFrame(ready_evt, 14, 1, 0x00, 0x0000);
+ u8 ready_evt[12];
+ memcpy(&ready_evt[0], SPI_Firmware::GetWifiMAC(), 6);
+ ready_evt[6] = 0x02;
+ ready_evt[7] = 0;
+ *(u32*)&ready_evt[8] = 0x2300006C;
+ SendWMIEvent(1, 0x1001, ready_evt, 12);
+
+ u8 regdomain_evt[4];
+ *(u32*)&regdomain_evt[0] = 0x80000000 | (*(u16*)&EEPROM[0x008] & 0x0FFF);
+ SendWMIEvent(1, 0x1006, regdomain_evt, 4);
+
+ NDS::ScheduleEvent(NDS::Event_DSi_NWifi, true, 33611, MSTimer, 0);
+ }
+ break;
+
+ case 0x0008: // set scan params
+ {
+ // TODO: do something with the params!!
+
+ SendWMIAck();
+ }
+ break;
+
+ case 0x0009: // set BSS filter
+ {
+ // TODO: do something with the params!!
+ u8 bssfilter = Mailbox[0]->Read();
+ Mailbox[0]->Read();
+ Mailbox[0]->Read();
+ Mailbox[0]->Read();
+ u32 iemask = MB_Read32(0);
+
+ printf("WMI: set BSS filter, filter=%02X, iemask=%08X\n", bssfilter, iemask);
+
+ SendWMIAck();
+ }
+ break;
+
+ case 0x000A: // set probed BSSID
+ {
+ u8 id = Mailbox[0]->Read();
+ u8 flags = Mailbox[0]->Read();
+ u8 len = Mailbox[0]->Read();
+
+ char ssid[33];
+ for (int i = 0; i < len && i < 32; i++)
+ ssid[i] = Mailbox[0]->Read();
+ ssid[32]= '\0';
+
+ // TODO: store it somewhere
+ printf("WMI: set probed SSID: id=%d, flags=%02X, len=%d, SSID=%s\n", id, flags, len, ssid);
+
+ SendWMIAck();
+ }
+ break;
+
+ case 0x000E: // get channel list
+ {
+ int nchan = 11; // TODO: customize??
+ u8 reply[2 + (nchan*2) + 2];
+
+ reply[0] = 0;
+ reply[1] = nchan;
+ for (int i = 0; i < nchan; i++)
+ *(u16*)&reply[2 + (i*2)] = 2412 + (i*5);
+ *(u16*)&reply[2 + (nchan*2)] = 0;
+
+ SendWMIEvent(1, 0x000E, reply, 4+(nchan*2));
+
+ SendWMIAck();
+ }
+ break;
+
+ case 0x0011: // set channel params
+ {
+ Mailbox[0]->Read();
+ u8 scan = Mailbox[0]->Read();
+ u8 phymode = Mailbox[0]->Read();
+ u8 len = Mailbox[0]->Read();
+
+ u16 channels[32];
+ for (int i = 0; i < len && i < 32; i++)
+ channels[i] = MB_Read16(0);
+
+ // TODO: store it somewhere
+ printf("WMI: set channel params: scan=%d, phymode=%d, len=%d, channels=", scan, phymode, len);
+ for (int i = 0; i < len && i < 32; i++)
+ printf("%d,", channels[i]);
+ printf("\n");
+
+ SendWMIAck();
+ }
+ break;
+
+ case 0x0022: // set error bitmask
+ {
+ ErrorMask = MB_Read32(0);
+
+ SendWMIAck();
+ }
+ break;
+
+ case 0x0047: // cmd47 -- timer shenanigans??
+ {
+ //
+
+ SendWMIAck();
}
break;
default:
printf("unknown WMI command %04X\n", cmd);
+ for (int i = 0; i < len; i++)
+ {
+ printf("%02X ", Mailbox[0]->Read());
+ if ((i&0xF)==0xF) printf("\n");
+ }
+ printf("\n");
break;
}
MB_Drain(0);
}
-void DSi_NWifi::SendWMIFrame(u8* data, u32 len, u8 ep, u8 flags, u16 ctrl)
+//void DSi_NWifi::SendWMIFrame(u8* data, u32 len, u8 ep, u8 flags, u16 ctrl)
+void DSi_NWifi::SendWMIEvent(u8 ep, u16 id, u8* data, u32 len)
{
u32 wlen = 0;
- Mailbox[4]->Write(ep); // eid
- Mailbox[4]->Write(flags); // flags
- MB_Write16(4, len); // payload length
- MB_Write16(4, ctrl); // ctrl
- wlen += 6;
+ Mailbox[4]->Write(ep); // eid
+ Mailbox[4]->Write(0x02); // flags (trailer)
+ MB_Write16(4, len+2+8); // data length (plus event ID and trailer)
+ Mailbox[4]->Write(8); // trailer length
+ Mailbox[4]->Write(0); //
+ MB_Write16(4, id); // event ID
+ wlen += 8;
for (int i = 0; i < len; i++)
{
@@ -829,6 +954,53 @@ void DSi_NWifi::SendWMIFrame(u8* data, u32 len, u8 ep, u8 flags, u16 ctrl)
wlen++;
}
+ // trailer
+ Mailbox[4]->Write(0x02);
+ Mailbox[4]->Write(0x06);
+ Mailbox[4]->Write(0x00);
+ Mailbox[4]->Write(0x00);
+ Mailbox[4]->Write(0x00);
+ Mailbox[4]->Write(0x00);
+ Mailbox[4]->Write(0x00);
+ Mailbox[4]->Write(0x00);
+ wlen += 8;
+
+ for (; wlen & 0x7F; wlen++)
+ Mailbox[4]->Write(0);
+}
+
+void DSi_NWifi::SendWMIAck()
+{
+ u32 wlen = 0;
+
+ Mailbox[4]->Write(0); // eid
+ Mailbox[4]->Write(0x02); // flags (trailer)
+ MB_Write16(4, 0xC); // data length (plus event ID and trailer)
+ Mailbox[4]->Write(0xC); // trailer length
+ Mailbox[4]->Write(0); //
+ wlen += 6;
+
+ // trailer
+ Mailbox[4]->Write(0x01);
+ Mailbox[4]->Write(0x02);
+ Mailbox[4]->Write(0x01);
+ Mailbox[4]->Write(0x01);
+ Mailbox[4]->Write(0x02);
+ Mailbox[4]->Write(0x06);
+
+ // observed trailer data:
+ // 00 06 00 00 02 00 (in the first few responses)
+ // 00 00 00 00 00 00
+ // TODO: work out what that all means?
+ // does software even care?
+ Mailbox[4]->Write(0x00);
+ Mailbox[4]->Write(0x06);
+ Mailbox[4]->Write(0x00);
+ Mailbox[4]->Write(0x00);
+ Mailbox[4]->Write(0x02);
+ Mailbox[4]->Write(0x00);
+ wlen += 0xC;
+
for (; wlen & 0x7F; wlen++)
Mailbox[4]->Write(0);
}
@@ -849,7 +1021,7 @@ u32 DSi_NWifi::WindowRead(u32 addr)
// base address of EEPROM data
// TODO find what the actual address is!
return 0x1FFC00;
- case 0x58: return EEPROMReady; // hax
+ case 0x58: return EEPROMReady;
}
return 0;
@@ -879,3 +1051,55 @@ void DSi_NWifi::WindowWrite(u32 addr, u32 val)
{
printf("NWifi: window write %08X %08X\n", addr, val);
}
+
+
+void DSi_NWifi::CheckRX()
+{return;
+ u16 framelen;
+ u16 framectl;
+
+ for (;;)
+ {
+ int rxlen = WifiAP::RecvPacket(RXBuffer);
+ if (rxlen == 0) return;
+ if (rxlen < 12+24) continue;
+
+ framelen = *(u16*)&RXBuffer[10];
+ if (framelen != rxlen-12)
+ {
+ printf("bad frame length\n");
+ continue;
+ }
+ framelen -= 4;
+
+ framectl = *(u16*)&RXBuffer[12+0];
+ if ((framectl & 0x00FC) == 0x0080) // beacon
+ {
+ printf("NWifi: got beacon\n");
+
+ u32 bodylen = framelen - 24;
+ if (bodylen > 256-16) bodylen = 256-16;
+
+ u8 beacon_evt[256];
+ memset(beacon_evt, 0, 256);
+ *(u16*)&beacon_evt[0] = 0x1004; // WMI_BSSINFO_EVENT
+ *(u16*)&beacon_evt[2] = 2442; // channel (in MHz???? welp)
+ beacon_evt[2] = 0x01; // frame type
+ beacon_evt[3] = 0x33; // 'snr' (???????)
+ *(u16*)&beacon_evt[4] = 0xFFD4; // 'rssi', 'snr'-95 (?????)
+ memcpy(&beacon_evt[6], &RXBuffer[12+16], 6); // BSSID
+ *(u32*)&beacon_evt[12] = 0; // ieMask (???????)
+ memcpy(&beacon_evt[16], &RXBuffer[12+24], bodylen); // frame body
+ //SendWMIFrame(beacon_evt, 16+bodylen, 1, 0, 0);
+ }
+ }
+}
+
+void DSi_NWifi::MSTimer(u32 param)
+{
+ WifiAP::MSTimer();
+
+ Ctx->CheckRX();
+
+ NDS::ScheduleEvent(NDS::Event_DSi_NWifi, true, 33611, MSTimer, 0);
+}