aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2020-06-16 02:52:53 +0200
committerArisotura <thetotalworm@gmail.com>2020-06-16 02:52:53 +0200
commit1101ed773bd9ed0b8024b987cc9e6621d58f8fea (patch)
tree4bad278090393610b7c8deadedea712f9b4d4af0 /src
parentafbdd96a907e85849d67e14bf6c9217e20f666ea (diff)
make it get further
Diffstat (limited to 'src')
-rw-r--r--src/DSi_NWifi.cpp174
-rw-r--r--src/DSi_NWifi.h7
2 files changed, 171 insertions, 10 deletions
diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp
index af93cce..99da932 100644
--- a/src/DSi_NWifi.cpp
+++ b/src/DSi_NWifi.cpp
@@ -22,6 +22,7 @@
#include "DSi_NWifi.h"
#include "SPI.h"
#include "WifiAP.h"
+#include "Platform.h"
const u8 CIS0[256] =
@@ -117,9 +118,17 @@ DSi_NWifi* Ctx = nullptr;
DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
{
- // TODO: check the actual mailbox size (presumably 0x200)
+ // HACK
+ // the mailboxes are supposed to be 0x80 bytes
+ // however, as we do things instantly, emulating this is meaningless
+ // and only adds complication
for (int i = 0; i < 8; i++)
- Mailbox[i] = new FIFO<u8>(0x200);
+ Mailbox[i] = new FIFO<u8>(0x600);//0x80);
+
+ // extra FIFOs acting as bigger TX/RX buffers, to work on frames
+ // bigger than 0x80
+ //Mailbox[8] = new FIFO<u8>(0x608);
+ //Mailbox[9] = new FIFO<u8>(0x608);
// this seems to control whether the firmware upload is done
EEPROMReady = 0;
@@ -151,7 +160,6 @@ void DSi_NWifi::Reset()
WindowReadAddr = 0;
WindowWriteAddr = 0;
- // TODO: check the actual mailbox size (presumably 0x200)
for (int i = 0; i < 8; i++)
Mailbox[i]->Clear();
@@ -687,7 +695,6 @@ void DSi_NWifi::HandleCommand()
void DSi_NWifi::BMI_Command()
{
- // HLE command handling stub
u32 cmd = MB_Read32(0);
switch (cmd)
@@ -782,7 +789,6 @@ void DSi_NWifi::BMI_Command()
void DSi_NWifi::HTC_Command()
{
- // HLE command handling stub
u16 h0 = MB_Read16(0);
u16 len = MB_Read16(0);
u16 h2 = MB_Read16(0);
@@ -847,11 +853,18 @@ void DSi_NWifi::HTC_Command()
void DSi_NWifi::WMI_Command()
{
- // HLE command handling stub
u16 h0 = MB_Read16(0);
u16 len = MB_Read16(0);
u16 h2 = MB_Read16(0);
+ u8 ep = h0 & 0xFF;
+ if (ep > 0x01) // data endpoints
+ {
+ WMI_SendPacket(len);
+ MB_Drain(0);
+ return;
+ }
+
u16 cmd = MB_Read16(0);
switch (cmd)
@@ -863,6 +876,25 @@ void DSi_NWifi::WMI_Command()
}
break;
+ case 0x0003: // disconnect
+ {
+ if (ConnectionStatus != 1)
+ printf("WMI: ?? trying to disconnect while not connected\n");
+
+ printf("WMI: disconnect\n");
+ ConnectionStatus = 0;
+
+ u8 reply[10];
+ *(u16*)&reply[0] = 3; // checkme
+ memcpy(&reply[2], WifiAP::APMac, 6);
+ reply[8] = 3; // disconnect reason (via cmd)
+ reply[9] = 0; // assoc-response length (?????)
+ SendWMIEvent(1, 0x1003, reply, 10);
+
+ SendWMIAck();
+ }
+ break;
+
case 0x0004: // synchronize
{
Mailbox[0]->Read();
@@ -1078,6 +1110,14 @@ void DSi_NWifi::WMI_Command()
}
break;
+ case 0x0049: // 'host exit notify'
+ {
+ //
+
+ SendWMIAck();
+ }
+ break;
+
case 0xF000: // set bitrate
{
// TODO!
@@ -1090,8 +1130,8 @@ void DSi_NWifi::WMI_Command()
break;
default:
- printf("unknown WMI command %04X\n", cmd);
- for (int i = 0; i < len; i++)
+ printf("unknown WMI command %04X (header: %04X:%04X:%04X)\n", cmd, h0, len, h2);
+ for (int i = 0; i < len-2; i++)
{
printf("%02X ", Mailbox[0]->Read());
if ((i&0xF)==0xF) printf("\n");
@@ -1161,6 +1201,65 @@ void DSi_NWifi::WMI_ConnectToNetwork()
ConnectionStatus = 1;
}
+void DSi_NWifi::WMI_SendPacket(u16 len)
+{
+ if (ConnectionStatus != 1)
+ {
+ printf("WMI: !! trying to send shit while not connected\n");
+ // TODO: report error??
+ return;
+ }
+
+ u16 hdr = MB_Read16(0);
+ if (hdr != 0x0000)
+ {
+ printf("WMI: special frame %04X\n", hdr);
+ return;
+ }
+
+ printf("WMI: send packet, len=%d\n", len);
+
+ u8 dstmac[6];
+ u8 srcmac[6];
+ u16 plen;
+
+ *(u32*)&dstmac[0] = MB_Read32(0);
+ *(u16*)&dstmac[4] = MB_Read16(0);
+ *(u32*)&srcmac[0] = MB_Read32(0);
+ *(u16*)&srcmac[4] = MB_Read16(0);
+ plen = MB_Read16(0);
+ plen = ((plen & 0xFF00) >> 8) | ((plen & 0x00FF) << 8);
+
+ if (plen > len-16)
+ {
+ printf("WMI: bad packet length %d > %d\n", plen, len-16);
+ return;
+ }
+
+ u32 h0 = MB_Read32(0);
+ u16 h1 = MB_Read16(0);
+
+ if (h0 != 0x0003AAAA || h1 != 0x0000)
+ {
+ printf("WMI: bad LLC/SLIP header\n");
+ return;
+ }
+
+ u16 ethertype = MB_Read16(0);
+
+ int lan_len = (plen - 8) + 14;
+
+ memcpy(&LANBuffer[0], dstmac, 6); // destination MAC
+ memcpy(&LANBuffer[6], srcmac, 6); // source MAC
+ *(u16*)&LANBuffer[12] = ethertype; // type
+ for (int i = 0; i < lan_len; i++)
+ {
+ LANBuffer[14+i] = Mailbox[0]->Read();
+ }
+
+ Platform::LAN_SendPacket(LANBuffer, lan_len);
+}
+
//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)
{
@@ -1269,6 +1368,58 @@ void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
Mailbox[4]->Write(0);
}
+void DSi_NWifi::CheckRX()
+{
+ int rxlen = Platform::LAN_RecvPacket(LANBuffer);
+ if (rxlen > 0)
+ {
+ // check destination MAC
+ if (*(u32*)&LANBuffer[0] != 0xFFFFFFFF || *(u16*)&LANBuffer[4] != 0xFFFF)
+ {
+ if (memcmp(&LANBuffer[0], &EEPROM[0x00A], 6))
+ return;
+ }
+
+ // packet is good
+
+ printf("WMI: receive packet %04X, len=%d\n", *(u16*)&LANBuffer[12], rxlen);
+
+ int datalen = rxlen - 14; // length of packet body
+
+ int wlen = 0;
+ MB_Write16(4, 0x0002);
+ MB_Write16(4, 16 + 8 + datalen);
+ MB_Write16(4, 0x0000);
+ wlen += 6;
+
+ MB_Write16(4, 0x0000);
+ MB_Write32(4, *(u32*)&LANBuffer[0]);
+ MB_Write16(4, *(u16*)&LANBuffer[4]);
+ MB_Write32(4, *(u32*)&LANBuffer[6]);
+ MB_Write16(4, *(u16*)&LANBuffer[10]);
+ u16 plen = datalen + 8;
+ plen = ((plen & 0xFF00) >> 8) | ((plen & 0x00FF) << 8);
+ MB_Write16(4, plen);
+ wlen += 16;
+
+ MB_Write16(4, 0xAAAA);
+ MB_Write16(4, 0x0003);
+ MB_Write16(4, 0x0000);
+ MB_Write16(4, *(u16*)&LANBuffer[12]);
+ wlen += 8;
+
+ for (int i = 0; i < datalen; i++)
+ Mailbox[4]->Write(LANBuffer[14+i]);
+
+ wlen += datalen;
+
+ for (; wlen & 0x7F; wlen++)
+ Mailbox[4]->Write(0);
+
+ UpdateIRQ_F1();
+ }
+}
+
u32 DSi_NWifi::WindowRead(u32 addr)
{
@@ -1340,6 +1491,7 @@ void DSi_NWifi::_MSTimer()
};
SendWMIBSSInfo(0x01, beacon, sizeof(beacon));
+ UpdateIRQ_F1();
printf("send beacon\n");
}
@@ -1347,8 +1499,14 @@ void DSi_NWifi::_MSTimer()
{
u32 status = 0;
SendWMIEvent(1, 0x100A, (u8*)&status, 4);
+ UpdateIRQ_F1();
}
}
+
+ if (ConnectionStatus == 1)
+ {
+ CheckRX();
+ }
}
void DSi_NWifi::MSTimer(u32 param)
diff --git a/src/DSi_NWifi.h b/src/DSi_NWifi.h
index 46cf714..14a5d14 100644
--- a/src/DSi_NWifi.h
+++ b/src/DSi_NWifi.h
@@ -70,11 +70,14 @@ private:
void WMI_Command();
void WMI_ConnectToNetwork();
+ void WMI_SendPacket(u16 len);
void SendWMIEvent(u8 ep, u16 id, u8* data, u32 len);
void SendWMIAck();
void SendWMIBSSInfo(u8 type, u8* data, u32 len);
+ void CheckRX();
+
u32 WindowRead(u32 addr);
void WindowWrite(u32 addr, u32 val);
@@ -113,7 +116,7 @@ private:
while (!Mailbox[n]->IsEmpty()) Mailbox[n]->Read();
}
- FIFO<u8>* Mailbox[8];
+ FIFO<u8>* Mailbox[10];
u8 F0_IRQEnable;
u8 F0_IRQStatus;
@@ -134,7 +137,7 @@ private:
u64 BeaconTimer;
u32 ConnectionStatus;
- u8 RXBuffer[2048];
+ u8 LANBuffer[2048];
};
#endif // DSI_NWIFI_H