Wifi: warning, possible awesomeness inside
DeSmuME can now connect to the WFC servers. Connections may be unstable though. (hint, MKDS suffers from a timing problem when the race starts) Also it seems safe to use the same fixed MAC. The only packets that contain the MAC address of the DS are DHCP and ARP packets sent at the beginning.
This commit is contained in:
parent
31f60d908a
commit
5cd32213da
|
@ -71,6 +71,17 @@ wifimac_t wifiMac;
|
|||
Adhoc_t Adhoc;
|
||||
SoftAP_t SoftAP;
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
WIFI TODO
|
||||
|
||||
- emulate transmission delays for Beacon and Extra transfers
|
||||
- emulate delays when receiving as well (may need some queuing system)
|
||||
- take transfer rate and preamble into account
|
||||
- figure out RFSTATUS and RFPINS
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Firmware info needed for if no firmware image is available
|
||||
|
@ -1482,31 +1493,15 @@ u16 WIFI_read16(u32 address)
|
|||
return wifiMac.pid;
|
||||
case REG_WIFI_AID_HIGH:
|
||||
return wifiMac.aid;
|
||||
|
||||
// RFSTATUS, RFPINS
|
||||
// TODO: figure out how to emulate those correctly
|
||||
// without breaking Nintendo's games
|
||||
case REG_WIFI_RFSTATUS:
|
||||
//WIFI_LOG(3, "Read RF_STATUS: %04X\n", wifiMac.rfStatus);
|
||||
//printf("-------------------- read RFSTATUS at %08X -----------------------------\n", NDS_ARM7.instruct_adr);
|
||||
return 0x0009;
|
||||
//return wifiMac.rfStatus;
|
||||
case REG_WIFI_RFPINS:
|
||||
//WIFI_LOG(3, "Read RF_PINS: %04X\n", wifiMac.rfPins);
|
||||
//emu_halt();
|
||||
// printf("-------------------- read RFPINS at %08X -----------------------------\n", NDS_ARM7.instruct_adr);
|
||||
//return wifiMac.rfPins;
|
||||
return 0x0004;
|
||||
case 0x210:
|
||||
//printf("read TX reg %04X\n", address);
|
||||
break;
|
||||
/*case 0x1B6:
|
||||
{
|
||||
u16 val = wifiMac.RXNum << 8;
|
||||
wifiMac.RXNum = 0;
|
||||
return val;
|
||||
}*/
|
||||
/* case 0x94:
|
||||
case 0x98:
|
||||
case 0x1B6:
|
||||
case 0x1C4:*/
|
||||
// printf("wifi: Read from port %03X\n", address);
|
||||
return 0x00C6;
|
||||
|
||||
case 0x268:
|
||||
return wifiMac.RXTXAddr;
|
||||
|
||||
|
@ -1828,24 +1823,28 @@ void Adhoc_usTrigger()
|
|||
// so the RX header length field is indeed header+body
|
||||
// Hence the CRC32 has been removed from those templates.
|
||||
|
||||
const u8 SoftAP_MACAddr[6] = {0x00, 0xF0, 0x1A, 0x2B, 0x3C, 0x4D};
|
||||
// If you wanna change SoftAP's MAC address, change this
|
||||
// Warning, don't mistake this for an array, it isn't
|
||||
#define SOFTAP_MACADDR 0x00, 0xF0, 0x1A, 0x2B, 0x3C, 0x4D
|
||||
|
||||
const u8 SoftAP_MACAddr[6] = {SOFTAP_MACADDR};
|
||||
|
||||
const u8 SoftAP_Beacon[] = {
|
||||
/* 802.11 header */
|
||||
0x80, 0x00, // Frame control
|
||||
0x00, 0x00, // Duration ID
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Receiver
|
||||
0x00, 0xF0, 0x1A, 0x2B, 0x3C, 0x4D, // Sender
|
||||
0x00, 0xF0, 0x1A, 0x2B, 0x3C, 0x4D, // BSSID
|
||||
SOFTAP_MACADDR, // Sender
|
||||
SOFTAP_MACADDR, // BSSID
|
||||
0x00, 0x00, // Sequence control
|
||||
|
||||
/* Frame body */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Timestamp (modified later)
|
||||
0x80, 0x00, // Beacon interval
|
||||
0x0F, 0x00, // Capablilty information
|
||||
0x21, 0x00, // Capablilty information
|
||||
0x01, 0x02, 0x82, 0x84, // Supported rates
|
||||
0x03, 0x01, 0x06, // Current channel
|
||||
0x05, 0x04, 0x00, 0x00, 0x00, 0x00, // TIM
|
||||
0x05, 0x04, 0x02, 0x01, 0x00, 0x00, // TIM (no idea what the hell it is)
|
||||
0x00, 0x06, 'S', 'o', 'f', 't', 'A', 'P', // SSID
|
||||
};
|
||||
|
||||
|
@ -1854,14 +1853,14 @@ const u8 SoftAP_ProbeResponse[] = {
|
|||
0x50, 0x00, // Frame control
|
||||
0x00, 0x00, // Duration ID
|
||||
0x00, 0x09, 0xBF, 0x12, 0x34, 0x56, // Receiver
|
||||
0x00, 0xF0, 0x1A, 0x2B, 0x3C, 0x4D, // Sender
|
||||
0x00, 0xF0, 0x1A, 0x2B, 0x3C, 0x4D, // BSSID
|
||||
SOFTAP_MACADDR, // Sender
|
||||
SOFTAP_MACADDR, // BSSID
|
||||
0x00, 0x00, // Sequence control
|
||||
|
||||
/* Frame body */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Timestamp (modified later)
|
||||
0x80, 0x00, // Beacon interval
|
||||
0x0F, 0x00, // Capablilty information
|
||||
0x21, 0x00, // Capablilty information
|
||||
0x01, 0x02, 0x82, 0x84, // Supported rates
|
||||
0x03, 0x01, 0x06, // Current channel
|
||||
0x00, 0x06, 'S', 'o', 'f', 't', 'A', 'P', // SSID
|
||||
|
@ -1873,8 +1872,8 @@ const u8 SoftAP_AuthFrame[] = {
|
|||
0xB0, 0x00, // Frame control
|
||||
0x00, 0x00, // Duration ID
|
||||
0x00, 0x09, 0xBF, 0x12, 0x34, 0x56, // Receiver
|
||||
0x00, 0xF0, 0x1A, 0x2B, 0x3C, 0x4D, // Sender
|
||||
0x00, 0xF0, 0x1A, 0x2B, 0x3C, 0x4D, // BSSID
|
||||
SOFTAP_MACADDR, // Sender
|
||||
SOFTAP_MACADDR, // BSSID
|
||||
0x00, 0x00, // Sequence control
|
||||
|
||||
/* Frame body */
|
||||
|
@ -1888,12 +1887,12 @@ const u8 SoftAP_AssocResponse[] = {
|
|||
0x10, 0x00, // Frame control
|
||||
0x00, 0x00, // Duration ID
|
||||
0x00, 0x09, 0xBF, 0x12, 0x34, 0x56, // Receiver
|
||||
0x00, 0xF0, 0x1A, 0x2B, 0x3C, 0x4D, // Sender
|
||||
0x00, 0xF0, 0x1A, 0x2B, 0x3C, 0x4D, // BSSID
|
||||
SOFTAP_MACADDR, // Sender
|
||||
SOFTAP_MACADDR, // BSSID
|
||||
0x00, 0x00, // Sequence control
|
||||
|
||||
/* Frame body */
|
||||
0x0F, 0x00, // Capability information
|
||||
0x21, 0x00, // Capability information
|
||||
0x00, 0x00, // Status
|
||||
0x01, 0xC0, // Assocation ID
|
||||
0x01, 0x02, 0x82, 0x84, // Supported rates
|
||||
|
@ -1981,59 +1980,33 @@ void SoftAP_SendPacket(u8 *packet, u32 len)
|
|||
{
|
||||
u16 frameCtl = *(u16*)&packet[0];
|
||||
|
||||
/*WIFI_LOG(3, */printf("SoftAP: Received a packet of length %i bytes. Frame control = %04X\n",
|
||||
WIFI_LOG(3, "SoftAP: Received a packet of length %i bytes. Frame control = %04X\n",
|
||||
len, frameCtl);
|
||||
|
||||
switch((frameCtl >> 2) & 0x3)
|
||||
{
|
||||
case 0x0: // Management frame
|
||||
{
|
||||
u32 packetLen;
|
||||
|
||||
switch((frameCtl >> 4) & 0xF)
|
||||
{
|
||||
case 0x4: // Probe request (WFC)
|
||||
{
|
||||
u32 packetLen = sizeof(SoftAP_ProbeResponse);
|
||||
u32 totalLen = (packetLen + 12);
|
||||
|
||||
// Make the RX header
|
||||
WIFI_MakeRXHeader(SoftAP.curPacket, 0x0010, 20, packetLen, 0, 0);
|
||||
|
||||
// Copy the probe response template
|
||||
packetLen = sizeof(SoftAP_ProbeResponse);
|
||||
memcpy(&SoftAP.curPacket[12], SoftAP_ProbeResponse, packetLen);
|
||||
|
||||
// Add the MAC address
|
||||
memcpy(&SoftAP.curPacket[12 + 4], FW_Mac, 6);
|
||||
|
||||
// Add the timestamp
|
||||
u64 timestamp = SoftAP.usecCounter;
|
||||
*(u64*)&SoftAP.curPacket[12 + 24] = timestamp;
|
||||
|
||||
// Let's prepare to send
|
||||
SoftAP.curPacketSize = totalLen;
|
||||
SoftAP.curPacketPos = 0;
|
||||
SoftAP.curPacketSending = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xB: // Authentication
|
||||
{
|
||||
u32 packetLen = sizeof(SoftAP_AuthFrame);
|
||||
u32 totalLen = (packetLen + 12);
|
||||
|
||||
// Make the RX header
|
||||
WIFI_MakeRXHeader(SoftAP.curPacket, 0x0010, 20, packetLen, 0, 0);
|
||||
|
||||
// Copy the authentication frame template
|
||||
packetLen = sizeof(SoftAP_AuthFrame);
|
||||
memcpy(&SoftAP.curPacket[12], SoftAP_AuthFrame, packetLen);
|
||||
|
||||
// Add the MAC address
|
||||
memcpy(&SoftAP.curPacket[12 + 4], FW_Mac, 6);
|
||||
|
||||
// Let's prepare to send
|
||||
SoftAP.curPacketSize = totalLen;
|
||||
SoftAP.curPacketPos = 0;
|
||||
SoftAP.curPacketSending = TRUE;
|
||||
|
||||
SoftAP.status = APStatus_Authenticated;
|
||||
}
|
||||
break;
|
||||
|
@ -2043,23 +2016,9 @@ void SoftAP_SendPacket(u8 *packet, u32 len)
|
|||
if (SoftAP.status != APStatus_Authenticated)
|
||||
return;
|
||||
|
||||
u32 packetLen = sizeof(SoftAP_AssocResponse);
|
||||
u32 totalLen = (packetLen + 12);
|
||||
|
||||
// Make the RX header
|
||||
WIFI_MakeRXHeader(SoftAP.curPacket, 0x0010, 20, packetLen, 0, 0);
|
||||
|
||||
// Copy the association response template
|
||||
packetLen = sizeof(SoftAP_AssocResponse);
|
||||
memcpy(&SoftAP.curPacket[12], SoftAP_AssocResponse, packetLen);
|
||||
|
||||
// Add the MAC address
|
||||
memcpy(&SoftAP.curPacket[12 + 4], FW_Mac, 6);
|
||||
|
||||
// Let's prepare to send
|
||||
SoftAP.curPacketSize = totalLen;
|
||||
SoftAP.curPacketPos = 0;
|
||||
SoftAP.curPacketSending = TRUE;
|
||||
|
||||
SoftAP.status = APStatus_Associated;
|
||||
WIFI_LOG(1, "SoftAP connected!\n");
|
||||
}
|
||||
|
@ -2067,17 +2026,33 @@ void SoftAP_SendPacket(u8 *packet, u32 len)
|
|||
|
||||
case 0xA: // Disassociation
|
||||
SoftAP.status = APStatus_Authenticated;
|
||||
break;
|
||||
return;
|
||||
|
||||
case 0xC: // Deauthentication
|
||||
SoftAP.status = APStatus_Disconnected;
|
||||
WIFI_LOG(1, "SoftAP disconnected\n");
|
||||
break;
|
||||
return;
|
||||
|
||||
default:
|
||||
WIFI_LOG(2, "SoftAP: unknown management frame type %04X\n", (frameCtl >> 4) & 0xF);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&SoftAP.curPacket[12 + 4], FW_Mac, 6); // Receiver MAC
|
||||
|
||||
*(u16*)&SoftAP.curPacket[12 + 22] = SoftAP.seqNum << 4; // Sequence number
|
||||
SoftAP.seqNum++;
|
||||
|
||||
u16 rxflags = 0x0010;
|
||||
if (WIFI_compareMAC(wifiMac.bss.bytes, &SoftAP.curPacket[12 + 16]))
|
||||
rxflags |= 0x8000;
|
||||
|
||||
WIFI_MakeRXHeader(SoftAP.curPacket, rxflags, 20, packetLen, 0, 0); // make the RX header
|
||||
|
||||
// Let's prepare to send
|
||||
SoftAP.curPacketSize = packetLen + 12;
|
||||
SoftAP.curPacketPos = 0;
|
||||
SoftAP.curPacketSending = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2092,8 +2067,8 @@ void SoftAP_SendPacket(u8 *packet, u32 len)
|
|||
u32 epacketLen = ((len - 30 - 4) + 14);
|
||||
u8 epacket[2048];
|
||||
|
||||
printf("----- SENDING ETHERNET PACKET: len=%i, ethertype=%04X -----\n",
|
||||
len, *(u16*)&packet[30]);
|
||||
//printf("----- SENDING ETHERNET PACKET: len=%i, ethertype=%04X -----\n",
|
||||
// len, *(u16*)&packet[30]);
|
||||
|
||||
memcpy(&epacket[0], &packet[16], 6);
|
||||
memcpy(&epacket[6], &packet[10], 6);
|
||||
|
@ -2115,20 +2090,23 @@ void SoftAP_SendPacket(u8 *packet, u32 len)
|
|||
INLINE void SoftAP_SendBeacon()
|
||||
{
|
||||
u32 packetLen = sizeof(SoftAP_Beacon);
|
||||
u32 totalLen = (packetLen + 12);
|
||||
|
||||
// Make the RX header
|
||||
WIFI_MakeRXHeader(SoftAP.curPacket, 0x0011, 20, packetLen, 0, 0);
|
||||
memcpy(&SoftAP.curPacket[12], SoftAP_Beacon, packetLen); // Copy the beacon template
|
||||
|
||||
// Copy the beacon template
|
||||
memcpy(&SoftAP.curPacket[12], SoftAP_Beacon, packetLen);
|
||||
*(u16*)&SoftAP.curPacket[12 + 22] = SoftAP.seqNum << 4; // Sequence number
|
||||
SoftAP.seqNum++;
|
||||
|
||||
// Add the timestamp
|
||||
u64 timestamp = SoftAP.usecCounter;
|
||||
*(u64*)&SoftAP.curPacket[12 + 24] = timestamp;
|
||||
*(u64*)&SoftAP.curPacket[12 + 24] = timestamp; // Timestamp
|
||||
|
||||
u16 rxflags = 0x0010;
|
||||
if (WIFI_compareMAC(wifiMac.bss.bytes, &SoftAP.curPacket[12 + 16]))
|
||||
rxflags |= 0x8000;
|
||||
|
||||
WIFI_MakeRXHeader(SoftAP.curPacket, 0x8011, 20, packetLen, 0, 0);
|
||||
|
||||
// Let's prepare to send
|
||||
SoftAP.curPacketSize = totalLen;
|
||||
SoftAP.curPacketSize = packetLen + 12;
|
||||
SoftAP.curPacketPos = 0;
|
||||
SoftAP.curPacketSending = TRUE;
|
||||
}
|
||||
|
@ -2159,20 +2137,26 @@ static void SoftAP_RXHandler(u_char* user, const struct pcap_pkthdr* h, const u_
|
|||
// 24+ (h->caplen-12), 24 + (h->len-12), data[6], data[7], data[8], data[9], data[10], data[11],
|
||||
// data[0], data[1], data[2], data[3], data[4], data[5], *(u16*)&data[12]);
|
||||
|
||||
u16 rxflags = 0x0018;
|
||||
if (WIFI_compareMAC(wifiMac.bss.bytes, (u8*)SoftAP_MACAddr))
|
||||
rxflags |= 0x8000;
|
||||
|
||||
// Make a valid 802.11 frame
|
||||
WIFI_MakeRXHeader(wpacket, 0x0018, 20, wpacketLen, 0, 0);
|
||||
WIFI_MakeRXHeader(wpacket, rxflags, 20, wpacketLen, 0, 0);
|
||||
*(u16*)&wpacket[12+0] = 0x0208;
|
||||
*(u16*)&wpacket[12+2] = 0x0000;
|
||||
memcpy(&wpacket[12+4], &data[0], 6);
|
||||
memcpy(&wpacket[12+10], SoftAP_MACAddr, 6);
|
||||
memcpy(&wpacket[12+16], &data[6], 6);
|
||||
*(u16*)&wpacket[12+22] = 0x0000; // Sequence control. Todo?
|
||||
*(u16*)&wpacket[12+22] = SoftAP.seqNum << 4;
|
||||
*(u16*)&wpacket[12+24] = 0xAAAA;
|
||||
*(u16*)&wpacket[12+26] = 0x0003;
|
||||
*(u16*)&wpacket[12+28] = 0x0000;
|
||||
*(u16*)&wpacket[12+30] = *(u16*)&data[12];
|
||||
memcpy(&wpacket[12+32], &data[14], wpacketLen);
|
||||
|
||||
SoftAP.seqNum++;
|
||||
|
||||
// put it in the RX buffer
|
||||
for (int i = 0; i < (12 + wpacketLen); i += 2)
|
||||
{
|
||||
|
@ -2183,7 +2167,7 @@ static void SoftAP_RXHandler(u_char* user, const struct pcap_pkthdr* h, const u_
|
|||
// Done!
|
||||
wifiMac.RXWriteCursor = ((wifiMac.RXWriteCursor + 1) & (~1));
|
||||
WIFI_IOREG(REG_WIFI_RXHWWRITECSR) = wifiMac.RXWriteCursor;
|
||||
wifiMac.RXNum++;
|
||||
|
||||
WIFI_triggerIRQ(WIFI_IRQ_RXEND);
|
||||
}
|
||||
|
||||
|
@ -2191,6 +2175,9 @@ void SoftAP_usTrigger()
|
|||
{
|
||||
SoftAP.usecCounter++;
|
||||
|
||||
// other packets will have priority over beacons
|
||||
// 'cause they might be only once of them
|
||||
// whereas there will be sooo much beacons
|
||||
if(!SoftAP.curPacketSending)
|
||||
{
|
||||
//if(wifiMac.ioMem[0xD0 >> 1] & 0x0400)
|
||||
|
@ -2199,8 +2186,6 @@ void SoftAP_usTrigger()
|
|||
// Okay for 128 ms then
|
||||
if((SoftAP.usecCounter & 131071) == 0)
|
||||
{
|
||||
//printf("send beacon, store to %04X (readcsr=%04X), size=%x\n",
|
||||
// wifiMac.RXHWWriteCursor<<1, wifiMac.RXReadCursor<<1, sizeof(SoftAP_Beacon)+12);
|
||||
SoftAP_SendBeacon();
|
||||
}
|
||||
}
|
||||
|
@ -2211,40 +2196,23 @@ void SoftAP_usTrigger()
|
|||
/* ie ~8 microseconds to transfer a word. */
|
||||
if((SoftAP.curPacketSending) && !(SoftAP.usecCounter & 7))
|
||||
{
|
||||
if(SoftAP.curPacketPos >= 0)
|
||||
{
|
||||
if(SoftAP.curPacketPos == 0)
|
||||
{
|
||||
WIFI_triggerIRQ(WIFI_IRQ_RXSTART);
|
||||
if(SoftAP.curPacketPos == 0)
|
||||
WIFI_triggerIRQ(WIFI_IRQ_RXSTART);
|
||||
|
||||
wifiMac.rfStatus = 0x0009;
|
||||
wifiMac.rfPins = 0x0004;
|
||||
}
|
||||
else
|
||||
{
|
||||
wifiMac.rfStatus = 0x0001;
|
||||
wifiMac.rfPins = 0x0084;
|
||||
}
|
||||
|
||||
u16 word = *(u16*)&SoftAP.curPacket[SoftAP.curPacketPos];
|
||||
WIFI_RXPutWord(word);
|
||||
}
|
||||
u16 word = *(u16*)&SoftAP.curPacket[SoftAP.curPacketPos];
|
||||
WIFI_RXPutWord(word);
|
||||
|
||||
SoftAP.curPacketPos += 2;
|
||||
if(SoftAP.curPacketPos >= SoftAP.curPacketSize)
|
||||
{
|
||||
//printf("SoftAP: packet finished sending, size=%i, startaddr=%04X", SoftAP.curPacketSize, WIFI_IOREG(REG_WIFI_RXHWWRITECSR));
|
||||
SoftAP.curPacketSize = 0;
|
||||
SoftAP.curPacketPos = 0;
|
||||
SoftAP.curPacketSending = FALSE;
|
||||
|
||||
wifiMac.RXWriteCursor = ((wifiMac.RXWriteCursor + 1) & (~1));
|
||||
WIFI_IOREG(REG_WIFI_RXHWWRITECSR) = wifiMac.RXWriteCursor;
|
||||
//printf(", end=%04X\n", wifiMac.RXWriteCursor);
|
||||
|
||||
WIFI_triggerIRQ(WIFI_IRQ_RXEND);
|
||||
|
||||
SoftAP.seqNum += 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue