NDS Wifi specs
Re: NDS Wifi specs
I had a couple test programs back then, sender and receiver. I did get the empty replies when I didn't set TXBUF_REPLY1 on the receiver side. maybe it's something like having to make sure you have W_BSSID and W_AID registers set properly, but I think you have those set up already.
Re: NDS Wifi specs
Yes, W_BSSID and W_AID_LOW are set as usually, I just had removed the W_TXBUF_REPLY1 write. Don't know why that didn't cause an empty reply, maybe that feature can be disable somewhere, or something had filtered it out on the other console.
___
Emulating the DS Download Play tool is getting difficult.
The ARM9 code is generating a Dummy reply, and then one Username reply.
But the ARM7 code is only sending the Dummy reply, and never happens to send the Username reply.
Instead, the Dummy gets retransmitted about 43h times, and ARM7 does then issue a "shutdown" message to ARM9, switching ARM9 into an endless loop.
My emulated reply timings are a bit very crappy, but I don't know if that is causing the problem. I've quite deeply disassembled the Download Play code, but it's hard to understand how the ARM7+ARM9 functions interact with each other.
Presumably, something makes the ARM7 think that it isn't yet ready to send the next REPLY. But I've no idea what/why/where : /
The state is REPLY1=0, REPLY2=8000h, and TXBUF[04h] incremented on each (re-)transmit. So ARM7 should know that the Dummy reply was sent, and that the next reply could be written to REPLY1.
___
Btw. there are two nds-wifi hardware versions, with W_ID chip ID values 1440h=Old NDS, and C340h=Newer DS-Lite/DSi/3DS.
The DSi's local multiplayer code (and maybe also DS-lite-era code) is doing something like this:
That looks as if the newer hardware is slower, and requires extra delays. On the other hand, older NDS launch titles didn't support that stuff, and they are apparently working on newer hardware either way.
___
Emulating the DS Download Play tool is getting difficult.
The ARM9 code is generating a Dummy reply, and then one Username reply.
But the ARM7 code is only sending the Dummy reply, and never happens to send the Username reply.
Instead, the Dummy gets retransmitted about 43h times, and ARM7 does then issue a "shutdown" message to ARM9, switching ARM9 into an endless loop.
My emulated reply timings are a bit very crappy, but I don't know if that is causing the problem. I've quite deeply disassembled the Download Play code, but it's hard to understand how the ARM7+ARM9 functions interact with each other.
Presumably, something makes the ARM7 think that it isn't yet ready to send the next REPLY. But I've no idea what/why/where : /
The state is REPLY1=0, REPLY2=8000h, and TXBUF[04h] incremented on each (re-)transmit. So ARM7 should know that the Dummy reply was sent, and that the next reply could be written to REPLY1.
___
Btw. there are two nds-wifi hardware versions, with W_ID chip ID values 1440h=Old NDS, and C340h=Newer DS-Lite/DSi/3DS.
The DSi's local multiplayer code (and maybe also DS-lite-era code) is doing something like this:
Code: Select all
if W_ID = 1440h then normal behaviour
else insert some extra 1000us (?) delays in various places
Re: NDS Wifi specs
Two months later - new year, new try.
I've given up on disassembling the DSi's DS Download Play tool, and instead switched to disassembling the much older Metroid First Hunt cartridge (which looks only half as complicated: less special-case-do-this-if-that stuff, and also I/O port access less obscured from compiler optimization).
Unfortunately, the underlaying mess is about same as in the newer wifi driver versions... there are lots of function numbers that are passed on as callback requests from one thread to another thread (which is then passing another callback number to another thread, and so on) (all without giving much clue about which callbacks are intended, and which are error handlers).
But I think that I've tracked down the source of the problem. The RX_done IRQ handler is checking REPLY2, and when disliking it, triggers Deauth via the call at 37FA350h (which does then go through at least four callback funcions (15h, 186h, 25h, 05h) before actually generating the Deauth packet.
Removing the opcode at 37FA350h does fix the problem. And to fix it without that patch... I guess the critical part is when to forward REPLY1 to REPLY2, or when to set the reply's TXHDR[00h] to 01h.
After finding the issue in Metroid, I've now also tracked down the same problem in the DSi's DS Download Play tool, it's checking REPLY1 instead of REPLY2, but otherwise it seems to be the same issue. Except, DS Download Play is additionally hanging elsewhere if incoming packets are arriving too fast: The cmd_ack callback (185h) is then trying to send another callback (2Ch) to another thread, but without ever finding time to execute that thread.
I've given up on disassembling the DSi's DS Download Play tool, and instead switched to disassembling the much older Metroid First Hunt cartridge (which looks only half as complicated: less special-case-do-this-if-that stuff, and also I/O port access less obscured from compiler optimization).
Unfortunately, the underlaying mess is about same as in the newer wifi driver versions... there are lots of function numbers that are passed on as callback requests from one thread to another thread (which is then passing another callback number to another thread, and so on) (all without giving much clue about which callbacks are intended, and which are error handlers).
But I think that I've tracked down the source of the problem. The RX_done IRQ handler is checking REPLY2, and when disliking it, triggers Deauth via the call at 37FA350h (which does then go through at least four callback funcions (15h, 186h, 25h, 05h) before actually generating the Deauth packet.
Removing the opcode at 37FA350h does fix the problem. And to fix it without that patch... I guess the critical part is when to forward REPLY1 to REPLY2, or when to set the reply's TXHDR[00h] to 01h.
After finding the issue in Metroid, I've now also tracked down the same problem in the DSi's DS Download Play tool, it's checking REPLY1 instead of REPLY2, but otherwise it seems to be the same issue. Except, DS Download Play is additionally hanging elsewhere if incoming packets are arriving too fast: The cmd_ack callback (185h) is then trying to send another callback (2Ch) to another thread, but without ever finding time to execute that thread.
Re: NDS Wifi specs
I've logged the register changes that are happening on slave side on real hardware. Here's a summary:
The important part is that the REPLY registers (and their TXHDR's) must be updated simultaneously with the RX Done IRQ0, for CMD DATA. Nintendo's RX Done IRQ handler is checking that stuff to determine if the replies are delivered. And, for whatever reason, it does insist on reply delivery to occur ONLY alongsides with the CMD DATA's RX Done IRQ.
With that, my multiplayer wifi emulation is now more or less working (yet not always perfectly stable, in metroid it does still disconnect after some seconds).
For reference, below is the whole log. That's manually typed up from the log shown on the console's LCD screen (hopefully without typos). And, I've merged it with data from several test runs (eg. with different TXSTATCNT settings) (and with different test runs having different WRCSR values).
The RXTX_ADDR values are only summarized (in reality, the transfer would extend thoughout the next some microseconds, with about one halfword each 8us, at 2Mbit/s).
The US_COUNT values are showing the duration without register changes, then followed by the new register values. The logging granularity is about 7-8us (ie. changes that seem to occur after 8us may have in fact occurred simultaneously with the preceeding changes).
Code: Select all
Flowchart (at Slave side)
At incoming CMD DATA packet: ;\
RF_STATUS=6 ;RX processing incoming stuff ;
After RX preamble: ; CMD
IRQ6 (RX Start, for CMD DATA) ; DATA
After RX data: ;
IRQ0 (RX Done, for CMD DATA) ;
WRCSR=WRCSR+(size of CMD DATA) ;
RF_STATUS=5 ;preparing REPLY ;
if REPLY2.bit15=1 ;
TXHDR[1]=TXHDR[0] ;<-- or sometimes random? ;\adjust TXHDR[0,1] ;
TXHDR[0]=01h ;<-- mark done/discarded ;/for <old> REPLY2 ;
REPLY2=REPLY1, REPLY1=0000h ;-forward new reply ;
if REPLY2.bit15=1 ;
TXHDR[4] incremented (unless already max FFh) ;\adjust TXHDR[4,5] ;
TXHDR[5]=00h ;/for <new> REPLY2 ;
TX_SEQNO incremented ;<-- done here if REPLY2 exists ;/
After some moment (at the AID_LOW slot?): ;\
RF_STATUS=8 ;TX sending REPLY ;
After TX preamble: ; REPLY
IRQ7 (TX Start, for REPLY) ;
After TX data: ;
RF_STATUS=1 ;RX awaiting next packet ;
optional: IRQ1 (TX Done) (only if enabled in TXSTATCNT, and REPLY2.bit15=1)
optional: TXSTAT=0401h (only if enabled in TXSTATCNT) ;
if REPLY2.bit15=0 ;
SEQNO increased ;<-- done here when REPLY2 is empty ;/
After some moment: ;\
RF_STATUS=6 ;RX processing incoming stuff ;
After RX preamble: ; CMD
IRQ6 (RX Start, for CMD ACK) ; ACK
After RX data: ;
IRQ0 (RX Done, for CMD ACK) ;
WRCSR=WRCSR+(size of CMD ACK) ;
RF_STATUS=1 ;RX awaiting next packet ;/
Thereafter, Nintendo's software seems to require a delay (at least
100h microseconds) before receiving the next CMD DATA packet.
With that, my multiplayer wifi emulation is now more or less working (yet not always perfectly stable, in metroid it does still disconnect after some seconds).
For reference, below is the whole log. That's manually typed up from the log shown on the console's LCD screen (hopefully without typos). And, I've merged it with data from several test runs (eg. with different TXSTATCNT settings) (and with different test runs having different WRCSR values).
The RXTX_ADDR values are only summarized (in reality, the transfer would extend thoughout the next some microseconds, with about one halfword each 8us, at 2Mbit/s).
The US_COUNT values are showing the duration without register changes, then followed by the new register values. The logging granularity is about 7-8us (ie. changes that seem to occur after 8us may have in fact occurred simultaneously with the preceeding changes).
Code: Select all
nds_wifi_state_logger (when downloading from nanostray)
US=0020h ;\
IF=80h (TX Start, for REPLY) (that is, empty dummy reply?) ;
RF_PINS=46h (formerly 44h) ;
US=006Ch ; REPLY
SEQNO+1 (for REPLY) (increase from 3 to 4) ;
US=0007h ;
RF_STAT=1 ;RX awaiting (formerly 8) ;
RF_PINS=04h ;/
US=0033h
RF_PINS=84h
US=0020h
RF_STAT=6 ;RX processing
RF_PINS=85h
US=0053h ;<--- partial preamble? (minus time needed for sensing preamble?)
(RXTX_ADDR+0..14h) (eg. 08CAh..08DEh)
IF=40h (RX Start, for CMD ACK) ;\
RF_PINS=87h ;
US=007Fh ;
WRCSR+14h (now 920h) (eg. or 8DCh) ; CMD ACK
RF_STAT=1 ;RX awaiting ;
(sometimes shortly: RF_PINS=07h) :
RF_PINS=84h ;
US=0007h ;
IF=01h (RX Done, for CMD ACK) ;/
(sometimes US=80h, IF=4000h)
US=05F6h ;--- huge gap
RF_STAT=6 ;RX processing
RF_PINS=85h
(RXTX_ADDR+0..18h) (eg. 08DEh..08F6h)
US=0053h ;<--- partial preamble?
IF=40h (RX Start, for CMD DATA) ;\
RF_PINS=87h ;
US=00A6h ;<--- data time? (1Ah*4+more?) ;
IF=01h (RX Done, for CMD DATA) ;
WRCSR+1Ah (now 93Ah) ; CMD DATA
REPLY1=0000h (formerly 84D0h) ;ram 48049A0h (960h+40h) ;
REPLY2=84D0h (formerly 0) ;
(RXTX_ADDR=04D6h) (aka REPLY+6) ;
RF_STAT=5 ;preparing REPLY ;
RF_PINS=04h ;
SEQNO+1 ;
TXHDR.4.B=0001h (formerly 0000h) ;per new REPLY2 ;/
(TXHDR.0.B=E701h (formerly 0000h) ;per old? REPLY2 (if any);/
US=0006h
RF_STAT=8 ;TX sending REPLY
RF_PINS=44h ;TXing PREAMBLE
(RXTX_ADDR=04D6h..04D7h)
US=0060h ;<-- preamble time
IF=80h (TX Start, for REPLY) ;\
RF_PINS=46h ;TXing DATA ;
US=0099h ;<-- data time ;
(RXTX_ADDR=04D8h..04EBh) (aka max 4D0h+1Bh) ;+(0Ch+26h)/2+2? ;
RF_STAT=1 ;RX awaiting ; REPLY
(sometimes shortly: RF_PINS=06h) ;
RF_PINS=04h ;
(optional: IF=02h (when enabled in TXSTATCNT) ;
(optional: TXSTAT=0401h (when enabled in TXSTATCNT) ;
(else stays at TXSTAT=2001h (or whatever old value) ;/
US=000Dh
RF_PINS=84h
US=0020h
RF_STAT=6 ;RX processing
RF_PINS=85h
US=0053h
IF=40h (RX Start, for CMD ACK) ;\
RF_PINS=87h ;
US=0080h ;
RF_STAT=1 ;RX awaiting ; CMD ACK
RF_PINS=84h ;
US=0006h ;
IF=01h (RX Done, for CMD ACK) ;
WRCSR+14h (now 94Eh) ;/
(if REPLY's forward REPLY1 to REPLY2) ;\uh, done here??? probably blah
(if REPLY's raise TXHDR.4) ;/
US=053Dh ;--- huge gap
RF_PINS=85h ;RXing... preamble?
US=0006h
RF_STAT=6 ;RX processing
US=004Dh
RF_PINS=87h ;RXing... data?
US=0006h ;\
IF=40h (RX Start, for CMD DATA) ;
US=00A6h ;
IF=01h (RX Done, for CMD DATA) ; CMD DATA
WRCSR+1Ah (now 968h) ;
REPLY2=0000h (formerly 84D0h) ;
RF_STAT=5 ;preparing REPLY ;
RF_PINS=04h ;
TXHDR.0.B=A201h (or xx01h) (formerly 0000h) ;old REPLY2 ;
(TXHDR.0.A=0001h) ;new REPLY2, if any ;/
US=0007h
RF_STAT=8 ;TX sending REPLY
RF_PINS=44h
US=0060h ;<-- preamble time
IF=80h (TX Start, for REPLY) ;\
RF_PINS=46h ;
US=006Ch ;<-- reply time (short/empty?) ;
SEQNO+1 (for REPLY) ; REPLY
US=0006h ;
RF_STAT=1 ;RX awaiting ; hm, IRQ-less?
RF_PINS=04h ;/ (if REPLY's, IF=02h)
US=0034h
RF_PINS=84h
US=0020h
RF_STAT=6 ;RX processing
RF_PINS=85h
US=0053h
IF=40h (RX Start, for CMD ACK) ;\
RF_PINS=87h ;
US=007Fh ;
WRCSR+14h (now 97Ch) ; CMD ACK
RF_STAT=1 ;RX awaiting ;
RF_PINS=84h ;
US=0007h ;
IF=01h (RX Done, for CMD ACK) ;/
US=0556h ;--- huge gap
RF_STAT=6 ;RX processing
RF_PINS=85h
US=004Dh
RF_PINS=87h
US=0006h
IF=40h (RX Start, for CMD DATA)
US=00A6h
IF=01h (RX Done, for CMD DATA)
WRCSR+1Ah (now 996h)
N/A REPLY1=0000h (formerly 84D0h)
N/A REPLY2=84D0h (formerly 0)
RF_STAT=5 ;preparing REPLY
RF_PINS=04h
N/A SEQNO+1
N/A TXHDR.4.B=0001h (formerly 0000h)
US=0007h
RF_STAT=8 ;TX sending REPLY
RF_PINS=44h
US=0060h ;<-- preamble time
IF=80h (TX Start, for REPLY) xx
RF_PINS=46h xx
US=0073h ;<-- shorter?
RF_STAT=1
RF_PINS=04h
SEQNO+1 ;<------- HERE (instead above)
US=0033h
RF_PINS=84h
US=0020h
RF_STAT=6 ;RX processing
RF_PINS=85h
US=0053h
IF=40h (RX Start, for CMD ACK)
RF_PINS=87h
US=0080h
RF_STAT=1
RF_PINS=84h
US=0006h
IF=01h (RX Done, for CMD ACK)
N/A WRCSR+14h
US=03FEh ;--- huge gap
RF_STAT=6 ;RX processing
RF_PINS=85h
US=0053h
RF_PINS=87h
US=0006h
IF=40h (RX Start, for CMD DATA)
US=00A6h
IF=01h (RX Done, for CMD DATA)
WRCSR+1Ah (now 9C4h)
N/A REPLY2=0000h (formerly 84D0h)
RF_STAT=5 ;preparing REPLY
RF_PINS=04h
N/A TXHDR.0.B=A201h (formerly 0000h)
US=0007h
RF_STAT=8 ;TX sending REPLY
RF_PINS=44h
US=0060h ;<-- preamble time
IF=80h (TX Start, for REPLY)
RF_PINS=46h
Re: NDS Wifi specs
Now I've logged the Multiplay Master side, too.
Here's a summary of the log...
And the full log...
RF_STATUS=7 is actually a transition state (occurs shortly before RF_STATUS=8).
RXTX_ADDR=0FC0h stays constant throughout the whole ACK transfer (it doesn't seem to increase from 0FBxh to 0FC0h). I guess they've just used that special "invalid" address value to indicate that none of the TXBUF's is in use.
It's been surprisingly difficult to receive REPLY's. That could be bad luck (CMD packets or REPLY's getting lost). On the other hand, I had no problems with lost packets when receiving intact streams of CMD+ACK pairs. One reason for not getting REPLY's seems to have been that I had set TXSTATCNT=FFFFh for logging TXSTAT changes. Setting the LSBs of TXSTATCNT seems to have some completely disabled replies (TXSTATCNT=F000h works better). And, RXFILTER=0FFFh seems to be also increasing chances to receive replies (not sure if that's really needed, it's working also with other RXFILTER settings, but setting more RXFILTER bits appeared to work a bit better).
I don't fully understand how CMD_COUNT works. It's usually set to the time needed to transfer one set of CMD+REPLY+ACK packets. The problem is that the CMD transfer may start about 500us after writing to CMD_COUNT and TXBUF_CMD, so CMD_COUNT is already half ellapsed at begin of transfer. I think that was part of the problem when I had used TXSTATCNT=FFFFh (I sometimes got REPLY RX start, but then immediately followed by ACK TX Done, without actually transferring the REPLY and ACK).
Here's a summary of the log...
Code: Select all
Flowchart (at Master side)
After starting transfer via TXREQ and TXBUF_CMD write:
TXBUSY=2 (formerly 0) (after TXBUF_CMD write, or sometimes a bit later)
After about 50-500 microseconds: ;\
RF_STAT=3 (TXing) (formerly 2) ;
RXTX_ADDR=0006h..0008h (TXbuf+0Ch..) (formerly in RXBUF) ; CMD
SEQNO+1 ;
After TX preamble: ;
IF=80h (TX Start, for CMD) ;
RXTX_ADDR=0009h..0xxxh (TXbuf..) ;
After TX data: ;
optional: IF=02h (TX Done, for CMD) (if enabled in TXSTATCNT);
optional: TXSTAT=0800h (CMD done) (if enabled in TXSTATCNT);
RF_STAT=5 (CMD done, prepare for REPLY) ;/
US=0017h ;\
RXTX_ADDR=rxbuf.. ;
After RX preamble: ;
IF=40h (RX Start, for REPLY) ; REPLY
RXTX_ADDR=rxbuf.. ; (if any)
After RX data: ;
IF=01h (RX Done, for REPLY) ;
WRCSR+18h (for REPLY) ;/
After a dozen microseconds: ;\
RF_STAT=7 ;Switching from REPLY to ACK ;
RF_STAT=8 ;TXing ACK (shortly after above STAT=7) ;
RXTX_ADDR=0FC0h (special dummy addr during TX ACK) ;
After TX preamble: ; ACK
IF=80h (TX Start, for ACK) ;
After TX data: ;
optional: IF=02h (TX Done, for ACK) (if enabled in TXSTATCNT);
optional: TXSTAT=0B01h (ACK done) (if enabled in TXSTATCNT);
TXBUSY=0000h (formerly 0002h) ;
TXBUF_CMD.bit15=0 ;
TXHDR_0=0001h (okay) (formerly 0000h) ;
TXHDR_2=0000h (no error flags) (formerly 0002h) ;
SEQNO+1 ;
RF_STAT=1 ;RX awaiting ;
IF=1000h (CMD timeslot done) (shortly AFTER above IF=02h) ;/
Code: Select all
nds_wifi_state_log (when uploading to ds download play on dsi)
(after starting transfer via TXREQ and TXBUF_CMD write)
TXBUSY=2 (formerly 0) (right after TXBUF_CMD write, or sometimes a bit later)
US=0148h (other day: 002Ch or 01E5h) ;\
RF_STAT=3 (TXing) (formerly 2) ;
RF_PINS=04h (formerly 84h) ;
RF_PINS=44h (shortly after above 04h) ; CMD
RXTX_ADDR=0006h..0008h (TXbuf+0Ch..) (formerly in RXBUF) ;
SEQNO+1 ;
US=0060h <-- preamble time for CMD ;
RF_PINS=46h ;
US=0006h ;
IF=80h (TX Start, for CMD) ;
RXTX_ADDR=0009h..0xxxh (TXbuf..) ;
US=0885h <-- data time for CMD ;
optional: IF=02h (TX Done, for CMD) (if enabled in TXSTATCNT);
optional: TXSTAT=0800h (CMD done) (if enabled in TXSTATCNT);
RF_STAT=5 (CMD done, prepare for REPLY) ;
RF_PINS=06h ;
RF_PINS=04h (shortly after above 06h) ;
RF_PINS=84h (shortly after above 04h) ;/
US=0017h ;\
RF_PINS=85h ;
RXTX_ADDR=rxbuf.. ;
US=0050h <-- partial preamble time for REPLY ; REPLY
IF=40h (RX Start, for REPLY) ; (if any)
RF_PINS=87h ;
RXTX_ADDR=rxbuf.. ;
US=0090h <-- data time for REPLY ;
RF_PINS=84h ;
US=0006h ;
IF=01h (RX Done, for REPLY) ;
WRCSR+18h (for REPLY) ;/
US=000Dh ;\
RF_STAT=7 ;Switching from REPLY to ACK ;
RF_STAT=8 ;TXing ACK (shortly after above STAT=7) ;
RF_PINS=04h ;
US=0006h ; ACK
RF_PINS=44h (shortly after above PINS=04h) ;
RXTX_ADDR=0FC0h (special dummy addr during TX ACK) ;
US=0060h <-- preamble time for ACK ;
RF_PINS=46h ;
US=0006h ;
IF=80h (TX Start, for ACK) ;
US=007Dh <-- data time for ACK ;
optional: IF=02h (TX Done, for ACK) (if enabled in TXSTATCNT);
optional: TXSTAT=0B01h (ACK done) (if enabled in TXSTATCNT);
TXBUSY=0000h (formerly 0002h) ;
TXBUF_CMD.bit15=0 ;
TXHDR_0=0001h (okay) (formerly 0000h) ;
TXHDR_2=0000h (no error flags) (formerly 0002h) ;
SEQNO+1 ;
RF_STAT=1 ;RX awaiting ;
RF_PINS=84h ;
IF=1000h (CMD timeslot done) (shortly AFTER above IF=02h) ;/
RXTX_ADDR=0FC0h stays constant throughout the whole ACK transfer (it doesn't seem to increase from 0FBxh to 0FC0h). I guess they've just used that special "invalid" address value to indicate that none of the TXBUF's is in use.
It's been surprisingly difficult to receive REPLY's. That could be bad luck (CMD packets or REPLY's getting lost). On the other hand, I had no problems with lost packets when receiving intact streams of CMD+ACK pairs. One reason for not getting REPLY's seems to have been that I had set TXSTATCNT=FFFFh for logging TXSTAT changes. Setting the LSBs of TXSTATCNT seems to have some completely disabled replies (TXSTATCNT=F000h works better). And, RXFILTER=0FFFh seems to be also increasing chances to receive replies (not sure if that's really needed, it's working also with other RXFILTER settings, but setting more RXFILTER bits appeared to work a bit better).
I don't fully understand how CMD_COUNT works. It's usually set to the time needed to transfer one set of CMD+REPLY+ACK packets. The problem is that the CMD transfer may start about 500us after writing to CMD_COUNT and TXBUF_CMD, so CMD_COUNT is already half ellapsed at begin of transfer. I think that was part of the problem when I had used TXSTATCNT=FFFFh (I sometimes got REPLY RX start, but then immediately followed by ACK TX Done, without actually transferring the REPLY and ACK).
Re: NDS Wifi specs
Now I have managed to receive Empty Replies, too. Receiving those is enabled by setting RXFILTER.bit8. What is weird is that I've received different types of empty packets (both with HWHDR[0]=801Fh, Rate=2Mbit/s, 18h-byte IEEE header, and 0-byte frame body):
The one with FC=0158h is what you have described for empty multiplayer REPLY.
And the other one with FC=0000h, that would be an empty Assoc Request (or maybe just garbage with FC=zero). It does occur shortly after the actual (non-empty) Assoc Request. I've no idea why it's sending that empty one.
Code: Select all
FC=0000, Duration=00A2, Addr1=Own, Addr2=Remote, Addr3=Own, Seq=0010
FC=0158, Duration=0126, Addr1=Own, Addr2=Remote, Addr3=0309BF000010, Seq=0020
And the other one with FC=0000h, that would be an empty Assoc Request (or maybe just garbage with FC=zero). It does occur shortly after the actual (non-empty) Assoc Request. I've no idea why it's sending that empty one.
Re: NDS Wifi specs
nice findings!
also re: RFSTATUS=7. I kinda suspected it was a transition state of that kind, just had not observed it in hardware.
also reminds me: I should look into how the hardware calculates packet durations. those are set in a specific way during MP exchanges, I guess the purpose is to tell other wifi devices "this exchange is going to last this long, please don't use this channel in the meantime". setting durations properly isn't too important as far as emulators are concerned, but might be more important if we ever try connecting an emulator to an actual DS (not that I have high hopes about the feasibility of such a thing).
also re: RFSTATUS=7. I kinda suspected it was a transition state of that kind, just had not observed it in hardware.
also reminds me: I should look into how the hardware calculates packet durations. those are set in a specific way during MP exchanges, I guess the purpose is to tell other wifi devices "this exchange is going to last this long, please don't use this channel in the meantime". setting durations properly isn't too important as far as emulators are concerned, but might be more important if we ever try connecting an emulator to an actual DS (not that I have high hopes about the feasibility of such a thing).
Re: NDS Wifi specs
I don't really know the IEEE specs for the Duration values. I guess they are reserving extra time for responses?
And also don't know if the NDS durations are used or adjusted by hardware or software (or if that differs per packet type).
What I have observed when logging incoming multiplyer REPLY's is that smaller packets are having larger duration values. So there, Nintendo seems to adjust them to get constant timings per "packet_size + duration".
Eg. if a packet is 8 bytes (64bit) smaller, then duration is 32 us larger (for 2Mbit/s).
They could as well append 8-byte padding, but that would (minimally) increase risk of transfer errors during those padding bytes.
Btw. one random question/idea: Are TXBUF_LOC1..3 really all same, or could they have specific purposes? Like one of them being specifically used for sending responses to managment requests.
Well, I am currently sending everything through LOC3, data frames (for internet), and managment requests, and managment replies. So, at least I know that LOC3 is working for all purposes.
In case of managment replies, I am sending them immediately after the request (which, I think, will ensure them being transferred during the "Duration" period of the request (though I still seem to need retries for getting the managment reply transferred, at least the retries would be definetly outside of the "Duration" period, so I may be doing something wrong there)).
And also don't know if the NDS durations are used or adjusted by hardware or software (or if that differs per packet type).
What I have observed when logging incoming multiplyer REPLY's is that smaller packets are having larger duration values. So there, Nintendo seems to adjust them to get constant timings per "packet_size + duration".
Eg. if a packet is 8 bytes (64bit) smaller, then duration is 32 us larger (for 2Mbit/s).
They could as well append 8-byte padding, but that would (minimally) increase risk of transfer errors during those padding bytes.
Btw. one random question/idea: Are TXBUF_LOC1..3 really all same, or could they have specific purposes? Like one of them being specifically used for sending responses to managment requests.
Well, I am currently sending everything through LOC3, data frames (for internet), and managment requests, and managment replies. So, at least I know that LOC3 is working for all purposes.
In case of managment replies, I am sending them immediately after the request (which, I think, will ensure them being transferred during the "Duration" period of the request (though I still seem to need retries for getting the managment reply transferred, at least the retries would be definetly outside of the "Duration" period, so I may be doing something wrong there)).