NDS Wifi specs

Discussion of development of software for any "obsolete" computer or video game system. See the WSdev wiki and ObscureDev wiki for more information on certain platforms.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

NDS Wifi specs

Post by nocash »

What should be updated/clarified about NDS Wifi in gbatek?
As far as I know there are some recent findings about local multiplayer mode?

The most recent NDS Wifi additions (from last year) in gbatek were on the packet format, including some details WPA/WPA2 packets (I had hoped to implement that in software... but the NDS hardware seems to automatically use WEP for all encrypted packets - and does automatically smash/modify the frame headers, so one couldn't even "undo" the WEP encryption to convert packets back to raw data... I've finally given up on WPA/WPA2 support).

The "DS Download Play" chapter might also need some work. And especially: Are there any ways to use that feature in homebrew, ie. getting around the RSA signature?
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: NDS Wifi specs

Post by tepples »

If it counts, the "FlashMe" custom firmware for Nintendo DS and Nintendo DS Lite skips checking the RSA signature for DS Download Play.
calima
Posts: 1745
Joined: Tue Oct 06, 2015 10:16 am

Re: NDS Wifi specs

Post by calima »

I don't know about that key specifically, but given Wii keys were in the gigaleak, it's quite possible the DS download play RSA key was too.
Arisotura
Posts: 29
Joined: Sun May 19, 2019 7:01 am

Re: NDS Wifi specs

Post by Arisotura »

W_US_COMPARE

from what I observed, setting bit0 blocks W_BEACONCOUNT IRQ14 until W_US_COUNT matches W_US_COMPARE.


W_CMD_COUNT

this actually defines the time interval during which W_TXBUF_CMD transfers are possible. that TX slot will automatically do the transfer again if there are errors (like MP clients not responding), but it will abort if there isn't enough time left in W_TXBUF_CMD.

W_TXBUF_CMD itself starts its transfer as soon as possible.


speaking of W_TXBUF_CMD: let's get into how MP transfers work.

sending a W_TXBUF_CMD frame starts the following process:

1. MP host sends the CMD frame, as soon as possible. after preamble, IRQ7 is triggered
2. once the transfer is finished: if bit14 in W_TXSTATCNT is set, W_TXSTAT is set to 0x0800, and IRQ1 is triggered
3. hardware waits for MP clients' replies, duration is: 16 + ((10 + W_CMD_REPLYTIME) * count_ones(client_mask_from_frame_body))
4. MP host sends the CMD ack. after preamble, IRQ7 is triggered (this is why you get two IRQ7's from a CMD transfer)
5. during the ack transfer, W_RFSTATUS is 8, and W_RXTXADDR is 0x0FC0
6. once the transfer is finished: if bit13 in W_TXSTATCNT is set, W_TXSTAT is set to 0x0B01, and IRQ1 is triggered.
7. the TX header of the CMD frame is adjusted: bits in TXheader[02] are cleared to indicate that the corresponding clients responded successfully. Nintendo software checks this.

I haven't looked a lot into how retries work. they seem to repeat the entire process.

the CMD ack is sent automatically. the packet is what is described here: the 03:09:BF:00:00:03 flow. MP clients will receive it like a regular frame.

IRQ12 is used to signal the end of the CMD transfer process. it will be either when the final ack is done transferring, if everything was successful, or otherwise at the end of W_CMD_COUNT.

on the client side:

typically, software sets W_TXBUF_REPLY1, and that's about it. the client has little control on the MP transfer process. I haven't found a way to manually transfer a reply frame.

anyway, the reply transfer is automatically initiated when receiving a MP CMD frame. this seems to be based on the frame control value? CMD frames typically have it set to 0x0228, but some other values like 0x0208 work too.

when receiving the MP CMD frame, the hardware determines its position using its W_AID_LOW register and the frame's client bitmask, then waits for its turn to reply. it will always send a reply -- if W_TXBUF_REPLY1 isn't configured, it will send an empty reply frame (with frame control 0x0158). either way, W_TXBUF_REPLY1 is latched into W_TXBUF_REPLY2, and reset to zero. if there is a frame to be sent, the byte at TXheader[04] is set to 01 (or incremented?). Nintendo software checks for this.

I haven't found a W_TXBUSY bit for MP reply transfers.

when transferring the MP reply itself: IRQ7 is triggered. W_RFSTATUS is 8. W_RXTXADDR isn't modified when sending a default empty reply. at the end: if bit12 in W_TXSTATCNT is set, W_TXSTAT is set to 0x0401, and IRQ1 is triggered.

clarifications for RXheader[00] flags bit0-3 (frame type):
C: MP host CMD frame (typically framectl=0228, but this also gets set on framectl=0208 for example)
D: MP ack frame
E: MP client reply frame
F: empty MP client reply frame

this needs a bit more research as to what framectl values work.

anyway, this should cover the multiplayer transfers. let me know if you need any details over something.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Wifi specs

Post by nocash »

Looks good! Thanks for the info!
Arisotura wrote: Mon Nov 02, 2020 7:08 am setting bit0 blocks W_BEACONCOUNT IRQ14 until W_US_COUNT matches W_US_COMPARE.
From what I can see, W_US_COUNT.bit0 seems to be always zero when reading.
If bit0 is write-only, I wonder if it does affect any other registers... like setting/clearing/acknowleding/reloading/latching something.
I've compared most registers before/after writing bit0=0 or 1, but it doesn't seem to change anything... unless changes would happen only in certain states.
Arisotura wrote: Mon Nov 02, 2020 7:08 am during the ack transfer, W_RFSTATUS is 8, and W_RXTXADDR is 0x0FC0
That 0FC0h value would translate to RAM address 4805F80h...
That could be the begin of WEP key area. Hmmm, that might be so if the WEP encryption is in use?
Or it could be the end of "reserved" 20h-byte RAM area at 4805F60h.

Looking at that reserved 20h-byte area...

Code: Select all

[4805F6Eh]=0F00h  ;-automatically set to 0F00h by hardware (during transfer or so)
[4805F70h]=FFFFh  ;\
[4805F72h]=FFFFh  ; set to FFFFh by software
[4805F76h]=FFFFh  ;
[4805F7Eh]=FFFFh  ;/
The remaining halfwords in that area are kept unchanged (ie. usually set to 5A5Ah/A5A5h from Nintendo's initial memfill function).
There might be more halfwords changed during actual data transfers.
Don't know what that area is good for... auto-generated ACK packets? or some kind of internal WEP state?
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
Arisotura
Posts: 29
Joined: Sun May 19, 2019 7:01 am

Re: NDS Wifi specs

Post by Arisotura »

re: W_US_COMPARE bit0. I guess it's a write-only bit.

also, forgot to mention, about W_RFSTATUS:

Code: Select all

// RFSTATUS values:
// 0 = initial
// 1 = waiting for incoming packets
// 2 = switching from RX to TX
// 3 = TX
// 4 = switching from TX to RX
// 5 = MP host data sent, waiting for replies (RFPINS=0x0084)
// 6 = RX
// 7 = ??
// 8 = MP client sending reply, MP host sending ack (RFPINS=0x0046)
// 9 = idle
from the melonDS code. I forgot to mention status 5 in my previous post.

state 7 is probably a transition state, but haven't found when it occurs.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Wifi specs

Post by nocash »

I have spotted a few more RAM-halfwords that get changed by hardware.

Code: Select all

Nintendo's software does init/change several values:
  [480xxxxh]=5A5Ah/A5A5h  ;-initial dummy WifiRAM memfill values
  [4805F70h]=FFFFh        ;\
  [4805F72h]=FFFFh        ; set to FFFFh by software
  [4805F76h]=FFFFh        ;
  [4805F7Eh]=FFFFh        ;/
The hardware does update several values (unless disabled in W_X_220h.bit5):
  [4805F6Eh]=0F00h (nothing received), or 0F01h (received something)
And, if received packet was accepted (eg. when W_RXFILTER.bit0=1=AcceptAll):
  [4805F70h]=Received MAC Address (6 bytes, looks same as port 480824Ch)
  [4805F76h]=xxx0h (increasing value, Sequence Control from packet header)
The problem is that those changes to [4805F6Eh..4805F76h] don't happen always. I have tested them in wifiboot (no changes happening) and in a messy test program (changes do happen). And I can't figure out what difference is activating the RAM changes.

Do you have some wifi hardware test program, too? And does the hardware change [4805F6Eh..4805F76h] in it? Or even better: Can you figure out how to enable/disable that changes?


EDIT:
I am more than stupid: I've spend two days on figuring out why the above hardware updates didn't occur in wifiboot (it was running in DSi wifi mode, not using the NDS wifi hardware, outch).
Well, at least, alongsides I have found a way to manually disable the hardware updates, via bit5 of the "RAM control" register:

Code: Select all

4808220h - W_X_220h - RAM Control (R/W)
  0-1   Disable WifiRAM      (0=Normal, other=locks memory at 4804000h-5FFFh)
  2-4   Unknown              (0=Normal, other=prevents/affects RX to ram?)
  5     Disable Special Log? (0=Normal, 1=Prevent 4805F6Eh..5F77h updates)
  6-15  Unknown              (0=Normal, other=?)
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
Arisotura
Posts: 29
Joined: Sun May 19, 2019 7:01 am

Re: NDS Wifi specs

Post by Arisotura »

hey, interesting find. I wonder why those things go to wifi RAM, when they have more than enough space for it in the register address space.

also, I found my old wifi findings thread, which is a tad messy, but might have things I missed here: http://melonds.kuribo64.net/board/thread.php?id=34

not much to add over my post tho, other than the misc findings about port 0x0244. no idea what bits 6 and 7 do, but bit 12 causes W_TXSEQNO to increment in some weird erratic fashion.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Wifi specs

Post by nocash »

As far as I understand, the normal framectl values are...

Code: Select all

clarifications for RXheader[00] flags bit0-3 (frame type):
 0Ch: MP host CMD frame              ;framectl=0228h=Data, FromDS, Data+CF_Poll
 0Dh: MP host CMD ack frame          ;framectl=????h
 0Eh: MP client reply frame (data)   ;framectl=????h
 0Fh: MP client reply frame (empty)  ;framectl=0158h=Data, ToDS, CF_Ack
But you said that 0208h (and 0248h) do also work same as 0228h...

Code: Select all

         228h = Type=2=Data      FromDS Subtype=2=Data + CF-Poll
         220h = Type=0=Managment FromDS Subtype=2=ReassocRequest
         248h = Type=2=Data      FromDS Subtype=4=NullFunction
Hmmmm, that looks as if they don't test too many (if any) framectl bits.
The hardware hopefully won't send multiplay-replies upon receiving ReassocRequests.
I guess they will also check MAC+BSSID addresses against values from preceeding beacons.
And there might bits or settings to enable/disable multiplay mode...
On master side, it could be simply checking W_TXBUF_CMD.
On slave side, it might check W_AID_LOW=0 (when zero, it should prevent W_TXBUF_REPLY (or empty replies) being sent).

Btw. do you know where the values in the CMD ACK frame come from?
I can see "03:09:BF:00:00:00" and "03:09:BF:00:00:10" in Nintendo's software.
But I don't know where "03:09:BF:00:00:03" comes from (is that hardcoded? or automatically changing the last byte of the "03:09:BF:00:00:xx" from "xx" to "03")?
Apart from the frame header, the CMD ACK is said to contain four data bytes (random/garbage plus 3x00h), but it seems to be unknown where that values come from, and if they have any meaning.

Data frames are usually containing three addresses (destination, source, bssid), it isn't yet clear which of that address(es) are set to "03:09:BF:00:00:xx". Well, I'll try to emulate that stuff or do some tests on hardware, so I could probably figure out it myself.

For the beacon+association part (before entering multiplay mode). I have this flowchart (mostly based on info found in internet):

Code: Select all

  Host advertises a game in beacon frames as described above
  Client sends an authentication request (sequence 1)         ;\step 1
  Host replies with an ACK                                    ;/
  Host sends an authentication reply (sequence 2)             ;\step 2
    (uh, no ACK here?)                                        ;/
  Client sends an association request                         ;\step 3
  Host replies with an ACK                                    ;/
  Host sends an association response                          ;\step 4
  Client replies with an ACK                                  ;/
Two things are unclear to me:
Is there any reason for not having/sending/needing ACK in step 2?
And what does the above "sequence 1" and "sequence 2" mean???

If there's no important meaning behind it... I could remove the "sequence 1/2" stuff. And maybe also remove the whole ACK stuff (assuming that everyone knows that ACKs are always sent for non-broadcast packets).
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Wifi specs

Post by nocash »

I am still working on that stuff. I've written a DS Download Play clone, and a DS Uploader for the opposite direction (and step-by-step figured out more details on each transfer side needed to get them working).

The tables and descriptions in gbatek for Nintendo Beacons and DS Download Play were far from useful: I've finally removed most of the obscure descriptions, and fixed mistakes and missing things in almost table entries.

The Downloader is now reaching the point where it can receive all data packets (though the remote side does then say error, apparently still needing some transfer done confirmation). Um, and the Downloader's initial Auth/Assoc is still very unstable.

The Uploader goes through Auth/Assoc/Username/Rsa/Datastart, but somehow gets Deauthenticated after sending a few data packets (and the RSA part requires an officially signed binary).

Most of the transfer is done using the multiplayer CMD + REPLY registers, so I've also found some new details there. The last two bytes of the 4-byte CMD ACK seem to be Error Flags (bit1-15 for missing replies from slave 1-15).

And some new details for the TX and RX hardware header...

Transmit TXHDR[00h] outputs 16bit status
0000h=Retrying? (TXBUF_LOCn)
0001h=Okay (TXBUF_LOCn,TXBUF_BEACON,TXBUF_CMD)
xx01h=Okay (TXBUF_REPLY, with increasing "xx")
0003h=Failed (TXBUF_LOCn)
0005h=Failed (TXBUF_CMD, with errorflags in TXHDR[2])

Receive RXHDR[00h] lower 4bit values for multiplay, with corresponding FC frame control values
0Ch: CMD frame ;FC=0228h=Data, FromDS, Data+CF_Poll
0Dh: CMD ack frame ;FC=0218h=Data, FromDS, Data+CF-Ack
0Eh: REPLY frame (data) ;FC=0118h=Data, ToDS, Data+CF-Ack
0Fh: REPLY frame (empty) ;FC=0158h=Data, ToDS, CF_Ack
For the replies the (sender?) hardware seems to be automatically setting bit12, so it arrives with FC=1118h instead of FC=0118h.

Receive RXHDR[02h] outputs 16bit whatever
0040h = whatever fixed value (in normal packets)
UNCHANGED = Old wifi ram content (in CMD packets)

Receive RXHDR[04h] always 16bit unchanged
UNCHANGED = Old wifi ram content
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Wifi specs

Post by nocash »

The DS Download Play upload/download code is now working quite reliable. It's still needing some cosmetic fixes... and then I'll have to figure out what to do with it in practice (the downloader could be made part of wifiboot, so it could either download from PC or from other NDS consoles).

Uploading to DS Download Play is working at 97Kbytes/s, which is more or less okay for the 2Mbit/s connection (considering the overload for preamble, headers, gaps, replies, and the rather small 1F8h-byte data packets).
One mean detail is that one must pause the data traffic once every 16 beacons, else the downloader will deauthenticate. That's been pretty hard to figure out what was causing the deauth's. At first, it just seemed to happen randomly after 1-2 seconds, but then I noticed that I could send more data when sending more data packets between beacons, and yet more when sending fewer beacons per second... so I finally figured out that pausing once every 16 beacons did fix the problem... Maybe one could shorten the pause duration by sending two beacons rapdily one after each other (?), but then, the pause may be also nice for leaving some free traffic window to other people in the neighborhood.
Another mean detail is that some download play images (eg. Table Hockey Tech Demo) are containing two 160h-byte ROM headers, one manually repaired header (with intact icon address etc, at offset 0), and the original header (for the RSA check, at offset 220h). When not knowing about that detail, the RSA check will get wrong, and the game will simply hang after upload (while showing the Nintendo logo).

Downloading from the Nanostray game is currently working at 27Kbytes/s. Maybe it's doing more pauses. But probably my reply flow isn't yet perfectly requesting the next packet numbers, so there may be still some chance to get it 2x or even 4x faster. And, talking about cosmetic fixes, I should probably store the incoming data in RAM, and execute the entrypoints after downloading (at the moment I am just ignoring the incoming data).
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Wifi specs

Post by nocash »

Booting the downloaded game is now also working fine. For single-player demos it's no problem at all. And for multiplayer games it's important to have some extra info about the BSSID, SSID, Beacon, and Channel at 27FFC42h.

The uploader and downloader are now both working at about 96Kbyte/s when communicating with retail software. My own uploader+downloader communicating with each other are even reaching about 110Kbyte/s. Either my code is better and faster, or I am violating some transfer specs : )

Hmmmm, I've never really studied how Wifi networks do coexist with each other, is that done using Control Frames to announce which network wants to transfer how much data? It would be nice to have some compact rundown on how to do such things! Or better, somebody tell me that the NDS is doing that things automatically ; )

---

Alongsides, I've stumbled across some Nintendo Zone Beacon descriptions at http://3dbrew.org/wiki/Nintendo_Zone and
http://dsibrew.org/wiki/Nintendo_Zone which is amazing, although, if you can understand that descriptions without further research then you are a million times more intelligent than I could even think of.

What I've figured out is that the 70h-bytes are meant to be resembling the 70h-byte snippets in the DS Download Play 88h-byte Tag=DDh beacon extensions. The "XOR pad that isn't a trivial XOR pad" is meant to refer to RC4 encryption (the WEP algorithm). The Game ID at offset [0Ch] in Tag=DDh extension must be 00000857h=Nintendo Zone (and probably one should include a yet unknown value at offset [13h]). And finally, the most practical info about "what-are-nintendo-zone-beacons" can be found at https://gbatemp.net/threads/dsi-nintend ... st-7460919 - "The BestBuy Nintendo Zone Cartridge does not connect to the Internet, it seems. It just tells the DSi what AP to connect to."

With that, I've managed to send Nintendo Zone beacons myself, causing the Nintendo Zone icon to appear in DSi Launcher. And, when storing the SSID/password for my access point inside of the beacon, then it's also showing a green connection symbol inside of the Nintendo Zone tool.

Well, and then it's throwing an error after some seconds - that might be because of having incorrect Server IDs in the beacon - or it might be because the Nintendo Zone servers were all shut down some years ago... or are there still any working Nintendo Zone severs (for NDS or DSi consoles)?
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Wifi specs

Post by nocash »

Arisotura wrote: Mon Nov 02, 2020 7:08 am it will always send a reply -- if W_TXBUF_REPLY1 isn't configured, it will send an empty reply frame (with frame control 0x0158).
I haven't managed to reproduce that effect. I've tried never writing REPLY1, and also tried writing REPLY1 only once (hoping that it would re-use parts of the TXHDR and/or IEEE header for creating those empty reply frames).
But either it isn't sending empty replies...or they are sent to a nonsense destination/bssid addresses (and thus not received)... or whatever.

What I have observed are SHORT replies (instead of EMPTY replies). With official DS download tool, the normal replies have 10 byte data (with FC=118h). The short replies have only 2 byte data (also with FC=118h). Well, and empty ones would have 0 byte data (with FC=158h), but I haven't seen that yet, neither from DS Download tool, nor from my own code.

That short replies are some sort of dummies. Apparently occuring once and then when the tool isn't ready to send actual reply data, similar to what you have said about empty replies (I don't know if the DS download tool's short replies are hardware or software generated though).
tepples wrote: Sun Nov 01, 2020 9:37 pm If it counts, the "FlashMe" custom firmware for Nintendo DS and Nintendo DS Lite skips checking the RSA signature for DS Download Play.
Could be useful for testing homebrew code. I've just added something similar in unlaunch (for patching the DSi's DS Download Play tool).
The drawback is that installing the patch (on classic NDS/DS-Lite) would require owning a flashcart or some other hardware mod.

But there seems to be something called HaxxStation that could upload code despite of the RSA check on unmodded consoles... it's open source, but it doesn't include any description what it is doing... going by info on other webpages it seems that HaxxStation requires a pirate copy of the offical Download Station ROM.
calima wrote: Mon Nov 02, 2020 1:26 am I don't know about that key specifically, but given Wii keys were in the gigaleak, it's quite possible the DS download play RSA key was too.
That would be the "platinum" leak mentioned here https://www.retroreversing.com/platinumleak ?
That seems to contain nds/dsi firmwares (and maybe also the ds download play tool, assuming that it's part of the firmware). Even without RSA keys, specs or source code for the wifi hardware might be nice (unless it's all japanese). Schematics would be also a nice surprise.
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
Arisotura
Posts: 29
Joined: Sun May 19, 2019 7:01 am

Re: NDS Wifi specs

Post by Arisotura »

nocash wrote: Fri Dec 11, 2020 10:56 am
Arisotura wrote: Mon Nov 02, 2020 7:08 am it will always send a reply -- if W_TXBUF_REPLY1 isn't configured, it will send an empty reply frame (with frame control 0x0158).
I haven't managed to reproduce that effect. I've tried never writing REPLY1, and also tried writing REPLY1 only once (hoping that it would re-use parts of the TXHDR and/or IEEE header for creating those empty reply frames).
But either it isn't sending empty replies...or they are sent to a nonsense destination/bssid addresses (and thus not received)... or whatever.

What I have observed are SHORT replies (instead of EMPTY replies). With official DS download tool, the normal replies have 10 byte data (with FC=118h). The short replies have only 2 byte data (also with FC=118h). Well, and empty ones would have 0 byte data (with FC=158h), but I haven't seen that yet, neither from DS Download tool, nor from my own code.

That short replies are some sort of dummies. Apparently occuring once and then when the tool isn't ready to send actual reply data, similar to what you have said about empty replies (I don't know if the DS download tool's short replies are hardware or software generated though).
that's interesting... so there would be a way to tell the hardware to output different sorts of default replies? dunno.
nocash
Posts: 1405
Joined: Fri Feb 24, 2012 12:09 pm
Contact:

Re: NDS Wifi specs

Post by nocash »

I don't know, I assume the short replies are software generated - so you might see them in emulated transfers, too (they do sometimes occur before/between/after the username replies in ds download play, for example).

I've got the cmd/reply half working in no$gba. My own uploader+downloader are working okay. But the official ds download play tool hangs on ARM9 side after the association/authentication phase and sending one single REPLY (or maybe it's merely initializing REPLY1 without even having received a CMD).

I've checked if REPLY2.bit15 is cleared after transfer - apparently it isn't cleared, so the hardware will retransmit REPLY2 (if no new REPLY1 write did happen). My current guess is that it works as so(?):
- wait for incoming CMD
- if REPLY1.bit15=1 then REPLY2=REPLY1, REPLY1=0000h
- if REPLY2.bit15=1 then send that reply, and increment byte at TXHDR[04h]

Except, once and then, REPLY2 seems to be getting reset to 0000h. I don't know what is causing that. Maybe TXHDR[04h] overflow? Or something like resetting it once per incoming beacon?

Where did you get the empty replies from? From your own test program, or receiving them from retail software?
homepage - patreon - you can think of a bit as a bottle that is either half full or half empty
Post Reply