DSi Wifi rev-engineering

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
DSi Wifi rev-engineering
by on (#229323)
I have just started rev-engineering DSi Wifi.

Some first findings: The SDIO code in browser is about 1200 lines, only ARM code (no THUMB code used). And even better: There seems to be only one function writing to SDIO_CMD, so it should be very easy to capture all SDIO traffic.

Placing a [4004800..4004aff]!!? breakpoint revealed that... the browser doesn't do any wifi traffic (not even wifi initialization) during the lengthy "Please wait" nag screen.

Anyways, for writing the SDIO data to a log file...

Does somebody know how to do file I/O on ARM7 side? I will need using Nintendo's file I/O functions for that (directly writing to SD/MMC ports would probably conflict with other browser functions). I am more or less familar with ARM9 file functions used in Launcher (and Browser may have same/similar functions), but it would be sub-optimal & uncomfortable to pass SDIO data from ARM7 to ARM9 only to have the file functions passing the data back from ARM9 to ARM7 for the actual SD/MMC writes.

PS.
If somebody never heard of DSi Wifi: The Nintendo DSi handheld has two Wifi interfaces: The old NDS interface for older games supports max 2Mbit/s with WEP encryption. The new DSi interface is accessed via SDIO bus and supports WPA2 and max 54Mbit/s. That new interface is yet another of those open source cases where nobody knows how to use it - hence the reverse-engineering.
The plan is to log all SDIO traffic to a log file while running DSi browser, and compare the log file against the SDIO/Wifi stuff that is already documented in gbatek.htm (the wifi hardware is mostly documented, it's just unknown how to use it via software).

EDIT:
I've also started some more general wifi-related side-threads here:
viewtopic.php?f=5&t=18427 - Wifi TKIP on WEP/RC4 hardware - is it really possible?
viewtopic.php?f=5&t=18372 - NTP - Network Time Protocol
viewtopic.php?f=5&t=18306 - Wifi and DHCP benchmarks?

And, I've meanwhile got WPA/WPA2 implemented and working on DSi:
http://problemkaputt.de/wifiboot.htm (binary and source code)
Re: DSi Wifi rev-engineering
by on (#229327)
Btw. the DSi wifi hardware was discovered to exist (and to have open source code available) about 2-3 years ago.
The source code should consist of "driver" and "firmware" code.
So far, I've examined only the low-level "firmware" part, and hoped that some HLL coders would figure out the "driver" part. Though I am meanwhile pessimistic that anybody would do that. But...

If somebody would want to help on examining the "driver" source code:
That would be wonderful! And if you like messing with open source - now is your last chance to do so!

What you need to know to get started: The DSi uses Atheros AR6002 wifi chips (aka "hw2") (or some later revisions, which must be backwards compatible with AR6002, else earlier DSi games couldn't use it, because they have the "driver" stored in the ROM image).

Atheros has released many different source code versions (without trying to maintain backwards compatibility; they were supposedly assuming that people would update both driver and firmware; but, as said above, the DSi can't update drivers).

The source code closest to DSi wifi "firmware" that I've found is called "AR6kSDK.build_sw.18" - so you would need the corresponding "driver" source code for that version.

Theoretically, there would be no further reverse-engineering needed if only somebody could find & compile that source code. Or if you need help implementing the DSi-specific SDIO interface, let me know!

The DSi's SDIO registers at 4004A00h-4004BFFh are already well known. The WMI commands/events used by the Atheros firmware are also well known. The problem is that these commands/events seem to cover only wifi initialization - that means there's only one small detail missing: It's unknown how to do any actual wifi data transfers.
And, it looks as if there's also some extra handshaking on SDIO bus (apart from the command/event stuff) (so the whole interface would consist of commands/events + handshakes + data packets) (supposedly distinguished by some small header in the SDIO transfer blocks).

---

Apart from source code... One interesting detail found in the browser is that it's containing code for both DATA16 and DATA32 FIFO's (of which, I had thought that DATA32 wouldn't work properly with the DSi's SDIO hardware).
The DATA32 stuff is part of the SDIO_CMD function. Whilst DATA16 is used in the SDIO IRQ handler. Not sure if/how that can co-exist, maybe it's using only DATA16 or only DATA32 (or has some method to switch between both modes).
Hmmm, DATA16 is used for byte-wise RAM access with manual 16bit I/O. And DATA32 uses NDMA. So the latter is probably used for fast transfer of larger blocks (and, as it's using NDMA, requires multiple of 4 bytes).
Re: DSi Wifi rev-engineering
by on (#229328)
The old staging ath6kl Linux driver had support for AR6002. You can download the code here:
http://ftp.dei.uc.pt/pub/linux/kernel/p ... h6kl.patch
Re: DSi Wifi rev-engineering
by on (#229347)
nocash wrote:
The source code closest to DSi wifi "firmware" that I've found is called "AR6kSDK.build_sw.18" - so you would need the corresponding "driver" source code for that version.

like http://svn.openmoko.org/trunk/src/targe ... w.18/host/ ?

Btw, I'm not very familiar with the DSi specific hardware ... Am I right guessing that SDIO is a bus towards the SD/MMC card interface that happens to be be connected to a WiFi chip as well ? (possibly using an alternate device identifier ?)
Re: DSi Wifi rev-engineering
by on (#229349)
calima wrote:
The old staging ath6kl Linux driver had support for AR6002. You can download the code here:
http://ftp.dei.uc.pt/pub/linux/kernel/p ... h6kl.patch

That looks more like a change log than actual code. But yeah, something like that should be right.

PypeBros wrote:

Yes, that looks good. And, that seems to be the "driver" side that would run on the ARM CPU, so that's right, too.

There are several AR6002 firmware/driver versions, it would be best to use a matching "driver" for the DSi.
The "build_sw.18" is close, but not perfect. As far as I remember it does use 0047h as WMI command number for WMI_SET_MAC_ADDRESS_CMD, whilst DSi is using F003h instead (one of the many cases where they've screwed up the enumeration for the WMI command numbers).
On the other hand, "build_sw.18" does match up with the response structure for WMI_REPORT_STATISTICS_EVENT, so it's pretty close.

Well, maybe it isn't so important to find perfectly matching source code, one could fix minor details like enum's manually. More important would be the bigger picture: What kind of stuff is transferred, and how does it distinguish between command and data blocks? And how does it connect to an access point at all (I don't even know if the firmware can do that automatically, or if one has to manually send/receive wifi packets to the access point).

PypeBros wrote:
Btw, I'm not very familiar with the DSi specific hardware ... Am I right guessing that SDIO is a bus towards the SD/MMC card interface that happens to be be connected to a WiFi chip as well ? (possibly using an alternate device identifier ?)

Yes, very similar. The SD/MMC controller is at ARM7:4004800h-400490Fh (used for eMMC and SD/MMC-slot), and the SDIO controller is using an identical set of registers at ARM7:4004A00h-4004B0Fh (used for Wifi only). The main difference is that the two controllers are wired to different hardware, apart from that they are nearly identical.

SDIO is mainly using CMD52 and CMD53 (instead of the CMD's used for reading/writing sectors on SD/MMC). Plus a few more CMD's like CMD3,CMD5,CMD7 - but that are needed only during initialization.

The Wifi hardware has BMI (initialization) and WMI (actual use) commands. The BMI stuff is done by the Launcher (and also supported by unlaunch), so the only missing part is to figure out how to do the WMI stuff.
I suspect that most of it is sent via the MBOXes (or maybe everything via MBOX0 only). Plus polling some SDIO registers to detect whether there's any incoming MBOX data available.

In the source code, there's "hif" and "htc2".
Looks as if "hif" is SDIO, which would need to be slightly customized for DSi.
And "htc2" might be what's still missing - ie. it might contain header bytes that distinguish between things like command and data?
Re: DSi Wifi rev-engineering
by on (#229350)
Quote:
Yes, very similar. The SD/MMC controller is at ARM7:4004800h-400490Fh (used for eMMC and SD/MMC-slot), and the SDIO controller is using an identical set of registers at ARM7:4004A00h-4004B0Fh (used for Wifi only). The main difference is that the two controllers are wired to different hardware, apart from that they are nearly identical.

SDIO is mainly using CMD52 and CMD53 (instead of the CMD's used for reading/writing sectors on SD/MMC). Plus a few more CMD's like CMD3,CMD5,CMD7 - but that are needed only during initialization.

oh yeah! I remember these. There was an extension to the SD/MMC standard that described how to interact with other hardware, and some of Y2K personal digital assistants were using either SD or compact flash cards to augment their features with WiFi.
Image

edit: have you had a look at the SDIO specifications already ? in the wireless LAN addendum, I've been surprised to see references to "HTTP transfer" commands. So apparently, the SDIO card may have a full network stack aboard and some RAM from which it pulls and pushes content from the Internet, pretending that these are mere file on a virtual storage device. (or it might not have been done that way on the DSi)
Attachment:
sdio-cmd52.png
sdio-cmd52.png [ 21.83 KiB | Viewed 17113 times ]


edit again: in the same document, we see that the Fxxx commands are "vendor-specific" extensions to the SDIO commands set. Unknown whether 'vendor' is AR6002 manufacturer or Nintendo themselves ...
Re: DSi Wifi rev-engineering
by on (#229393)
Yes, the DSi wifi hardware is alike wifi SDIO card (in the middle of the photo), except it's in daughterboard form, not card-shaped.

SDIO itself is all around CMD52/CMD53, and the standarized CCCR/FBR/CIS registers in "Function 0" space (that are for detecting the hardware and for some basic configuration like SDIO bus width).
I've described that general stuff in the "SDIO Protocol" section in this chapter: http://problemkaputt.de/gbatek.htm#dsis ... andioports

Apart from the SDIO bus standard, the SDIO makers seem to have tried to establish standards for specific SDIO devices like UART, GPS, Camera, and WLAN (as listed in FBR chapter). But I think you can completely forget about that. The DSi's Atheros hardware is marked as "No SDIO standard interface" in the FBR's "Interface Type" register, so I guess it isn't even remotely resembling the "SDIO WLAN interface" standard.
EDIT: Or is it similar? Atheros is referring to WMI commands F000h and up as "Developer commands", that sounds remotely like what you had said about Fxxxh being vendor specific commands. Ie. does the official SDIO WLAN standard have commands 0001h and up resembling Atheros commands like WMI_CONNECT_CMD etc.?

Instead, it's using the Atheros-specific WMI (and BMI) commands described here: http://problemkaputt.de/gbatek.htm#dsia ... ointerface (these are send via MBOX in SDIO "Function 1" space).

Well, and I've also documented most of the internal hardware, http://problemkaputt.de/gbatek.htm#dsia ... alhardware but that's only relevant if you wanted to disassemble the "firmware" part (and for a few cases where the "driver" part is peeking at those registers, eg. for checking the CHIP_ID at 0040ECh (when doing so, it's addressing that internal memory indirectly via WINDOW_READ_ADDR aka "Function 1:0047Ch")).

From what I've seen, the AR6002 is 100% made by Atheros - without any Nintendo-specific customizations in the hardware, nor in the ROM firmware, nor in the RAM firmware.
The later AR6013/AR6014 chips have some small Nintendo-specific customizations, but that's all happening behind your back (ie. DSi games can use those newer chips as if they were AR6002 chips).

---

On the hacking project: I've patched the browser's ARM9 code to write "Hello Test 123" into a "wifi-log.txt" file on SD card. So that's one milestone working. For doing similar writes while ARM7 is doing its SDIO stuff, I think I'll try to create a separate ARM9 thread for it via these browser functions:
Code:
                 arm9_create_thread    equ 0205D478h+1  ;struct,proc,0,stack,C8h,1Fh
                 arm9_sleep_thread     equ 0205D6B0h+1  ;zero

The other options would be hooking the ARM9 main program (but I am not sure which main function(s) it's executiong during wifi connection/transfers), or doing it from inside an IRQ handler (but I guess one can't call the File functions from inside IRQ as they should rely on IRQs themselves).
Re: DSi Wifi rev-engineering
by on (#229429)
The sleep_thread function wasn't quite right. And enable_thread worked, but did additionally require enable_thread. So I ended up with using this function set (for DSi Browser EUR version 00000001.app):
Code:
arm9_file_open        equ 02056F64h  ;handle,filename,mode?
arm9_file_close       equ 02056FB0h  ;handle
arm9_file_read        equ 02057054h  ;handle,dst,len
arm9_file_write       equ 02057088h  ;handle,src,len
arm9_get_filesize     equ 02056FD4h  ;handle
arm9_file_seek        equ 0205703Ch  ;handle,offset,00h
arm9_file_create      equ 02056BD0h  ;filename,03h
arm9_file_delete      equ 02056C10h  ;filename
arm9_create_thread    equ 0205D478h  ;struct,proc,param_for_proc,stack,stacksize(C8h)?,type/prio(03h/1Fh)?
arm9_enable_thread    equ 0205D72Ch  ;struct
arm9_sleep_millisecs  equ 0205D84Ch  ;milliseconds

The sleep(milliseconds) seems to work just fine. Next steps are hooking ARM7... and writing CMD, PARAM, REPLY to memory... works, too... and writing data NumBlk's and BlkLen and actual data bytes (after waiting for DMA or IRQ transfer to complete)... works, too... whew, now all code fragments are complete : )

And putting it together... storing logged ARM7 data in a 64Kbyte ring buffer (or waiting if the buffer is full)... okay... moving the file functions into the ARM9 thread... writing 16Kbyte chunks to file once when the ring buffer contains enough data (or sleeping otherwise)... and writing the remaining fraction when pressing Button B... works, that's getting cool... and converting the binary data to ASCII strings right on ARM7 side; so one won't need post-processing tools for viewing the log file on PC... and, finally, show delays in number of frames (if it's been more than 1 frame since last command)...

Okay, it's all tested & working in no$gba! Here's the output from the SD card wifi-log.txt file from no$gba, starting with SDIO function 0 stuff with 1-byte transfers, and then followed by actual SDIO function 1 stuff with more data bytes in the last dozens of lines:
Code:
No$2000 SDIO log (done without paying $2000 for a SD/SDIO hardware logging tool)

Cmd  Param    Reply    NumBlk x BlkLen Data bytes
----------------------------------------------------------
Delay 01D8
0434 04000900 00001000
0434 04000100 00001011
0434 04001300 00001000
0434 04001500 00001010
0434 04001700 00001000
0434 04200100 00001001
0434 04200300 00001003
0434 04200B00 00001020
0434 04200D00 00001004
0434 04200F00 00001071
0434 04201100 00001002
0434 04201300 00001000
0434 04201500 00001002
0434 04002500 00001003
0434 84002502 00001002
0434 04001100 00001017
0434 04200100 00001001
0434 04200300 00001003
0434 04200B00 00001020
0434 04200D00 00001004
0434 04201700 00001021
0434 04201900 00001002
0434 04201F00 00001022
0434 04202100 00001004
0434 04202300 00001000
0434 04202500 00001000
0434 04202700 00001008
0434 04202900 00001032
0434 84000F82 00001082
0434 84001117 00001017
0434 04020100 00001000
0434 04021300 00001000
0434 04021500 00001011
0434 04021700 00001000
0434 04220100 00001020
0434 04220300 00001004
0434 04220D00 00001021
0434 04220F00 00001002
0434 04221500 00001022
0434 04221700 0000102A
0434 04221900 00001001
0434 04221B00 00001001
0434 04221D00 00001011
0434 04221F00 00001000
0434 04222100 00001000
0434 04222300 00001000
0434 04222500 00001000
0434 04222700 00001000
0434 04222900 00001000
0434 04222B00 00001000
0434 04222D00 00001000
0434 04222F00 00001000
0434 04223100 00001000
0434 04223300 00001008
0434 04223500 00001000
0434 04223700 00001000
0434 04223900 000010FF
0434 04223B00 00001080
0434 04223D00 00001000
0434 04223F00 00001000
0434 04224100 00001000
0434 04224300 00001000
0434 04224500 00001001
0434 04224700 0000100A
0434 04224900 00001000
0434 04224B00 00001000
0434 04224D00 00001000
0434 04224F00 00001000
0434 04225100 00001000
0434 04225300 00001000
0434 04225500 00001000
0434 04225700 00001000
0434 04225900 00001000
0434 04225B00 00001000
0434 04225D00 00001000
0434 04225F00 00001001
0434 04226100 00001000
0434 04226300 00001001
0434 04226500 00001000
0434 04226700 00001001
0434 04226900 00001000
0434 04226B00 00001001
0434 04220100 00001020
0434 04220300 00001004
0434 04220500 00001071
0434 04220700 00001002
0434 04220900 00001000
0434 04220B00 00001002
0434 84022180 00001080
0434 84022300 00001000
0434 04220100 00001020
0434 04220300 00001004
0434 04220D00 00001021
0434 04220F00 00001002
0434 04221500 00001022
0434 04221700 0000102A
0434 04221900 00001001
0434 04221B00 00001001
0434 04221D00 00001011
0434 04221F00 00001000
0434 04222100 00001000
0434 04222300 00001000
0434 04222500 00001000
0434 04222700 00001000
0434 04222900 00001000
0434 04222B00 00001000
0434 04222D00 00001000
0434 04222F00 00001000
0434 04223100 00001000
0434 04223300 00001008
0434 04223500 00001000
0434 04223700 00001000
0434 04223900 000010FF
0434 04223B00 00001080
0434 04223D00 00001000
0434 04223F00 00001000
0434 04224100 00001000
0434 04224300 00001000
0434 04224500 00001001
0434 04224700 0000100A
0434 04224900 00001000
0434 04224B00 00001000
0434 04224D00 00001000
0434 04224F00 00001000
0434 04225100 00001000
0434 04225300 00001000
0434 04225500 00001000
0434 04225700 00001000
0434 04225900 00001000
0434 04225B00 00001000
0434 04225D00 00001000
0434 04225F00 00001001
0434 04226100 00001000
0434 04226300 00001001
0434 04226500 00001000
0434 04226700 00001001
0434 04226900 00001000
0434 04226B00 00001001
0434 04000500 00001002
0434 84000502 00001002
0434 04000700 00001002
4C35 94083004 00001000 0001x0004 00 00 00 00
4C35 9408FA03 00001000 0001x0003 40 00 00
4C35 9408F801 00001000 0001x0001 EC
5C35 1408E804 00001000 0001x0004 20 00 00 00
4C35 9408FA03 00001000 0001x0003 04 50 00
4C35 9408F801 00001000 0001x0001 58
5C35 1408E804 00001000 0001x0004 00 00 00 00
5C35 1408A004 00001000 0001x0004 00 00 00 00
4C35 941FF804 00001000 0001x0004 08 00 00 00
5C35 141FF804 00001000 0001x0004 00 00 00 00
5C35 141FF804 00001000 0001x0004 F7 47 7C 03
5C35 141FF008 00001000 0001x0008 FF FF FF FF 94 B0 FD 02
5C35 1408A004 00001000 0001x0004 00 00 00 00
4C35 941FE010 00001000 0001x0010 03 00 00 00 00 04 50 00 04 00 00 00 02 00 00 00
5C35 1408A004 00001000 0001x0004 00 00 00 00
4C35 941FF008 00001000 0001x0008 06 00 00 00 C0 80 01 00
5C35 141FF804 00001000 0001x0004 06 00 00 00
5C35 1408A004 00001000 0001x0004 00 00 00 00
4C35 941FE80C 00001000 0001x000C 07 00 00 00 C0 80 01 00 08 00 00 00
5C35 1408A004 00001000 0001x0004 00 00 00 00
4C35 941FF008 00001000 0001x0008 06 00 00 00 C4 40 00 00
5C35 141FF804 00001000 0001x0004 06 00 00 00
5C35 1408A004 00001000 0001x0004 00 00 00 00
4C35 941FE80C 00001000 0001x000C 07 00 00 00 C4 40 00 00 09 00 00 00
5C35 1408A004 00001000 0001x0004 00 00 00 00
4C35 941FE80C 00001000 0001x000C 07 00 00 00 28 40 00 00 05 00 00 00
5C35 1408A004 00001000 0001x0004 00 00 00 00
4C35 941FE80C 00001000 0001x000C 07 00 00 00 20 40 00 00 00 00 00 00
Delay 0072
4C35 94083004 00001000 0001x0004 00 00 00 00
5C35 14080010 00001000 0001x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
4C35 94080004 00001000 0001x0004 00 00 00 00
5C35 14080010 00001000 0001x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0434 84000900 00001000

Wow, that's working super cool : ) If there are no unexpected timing problems, then it should work the same way on real hardware.

The above log is showing the browser dealing with the basic SDIO emulation in no$gba (ie. nothing really new as I had already figured out to emulate all that stuff; and no$gba could even already generate a similar log when activating "SD/MMC" logging in the TTY Debug window).
The two new findings are the two delays: The first one is the surreal boot delay (during which the browser refuses to do any browsing or anything useful at all). And the smaller two second delay at the end appears to be some timeout (where the browser dislikes my emulation and/or can't find an access point).

Before testing on hardware, I guess I'll first add some important cosmetic stuff:
Parsing the Parameter word to display Read/Write direction, and SDIO function number and address as "Read/Write Function[N:NNNNN]=Data", with Data extracted from param/reply in case of CMD52.
And especially, parsing the WINDOW_WRITE_ADDR and WINDOW_READ_ADDR stuff to something like "Read/Write AtherosMem[NNNNNNNN]=Data" in a single line (instead of displaying it as separate SDIO commands scattered across three lines).

EDIT: The CMD53 data reading is still bugged in above log. I've had screwed up waiting for IRQ-based transfer completion, so it showed bogus data. Fixing that, it turns out that I had hooked ARM7 code before IRQs got enabled in SDIO_IRQ_MASK. Doing the hook later on, there seem to be cases where IRQs are disabled in CPSR at time sending the SDIO command.
Hmmmm, I could try to force CPSR to enable IRQs for a moment (maybe without crashing everything), or I could try to call the transfer read/write handler manually without IRQs from inside of the hook function when needed. Well, that's for tomorrow.
But, the two cosmetic features mentioned above are already working : ) and it's much easier to read now (and to spot bugs like the above data read issue).
Re: DSi Wifi rev-engineering
by on (#229444)
CPSR.IRQs are normally enabled, except in the last some commands after the timeout delay. I've tried to forcefully enable CPSR.IRQ for that cases, and it seems to work okay without crashing. Here's the new log output with cosmetic improvements:
Code:
No$2000 SDIO log (done without paying $2000 for a SD/SDIO hardware logging tool)
Delay 01D7
Read  Func[0:00004] = 00
Read  Func[0:00000] = 11
Read  Func[0:00009] = 00
...(snip)...
Read  Func[0:01135] = 01
Read  Func[0:00002] = 02
Write Func[0:00002] = 02
Read  Func[0:00003] = 02
Write Func[1:00418] = Len:0001x0004 00 00 00 00
Read  Mem[000040EC] = 02000001
Read  Mem[00500458] = 00000000
Read  Func[1:00450] = Len:0001x0004 01 00 00 00
Write Func[1:00FFC] = Len:0001x0004 08 00 00 00
Read  Func[1:00FFC] = Len:0001x0004 FF FF FF FF
Read  Func[1:00FFC] = Len:0001x0004 0C 00 00 00
Read  Func[1:00FF8] = Len:0001x0008 88 01 00 20 02 00 00 00
Read  Func[1:00450] = Len:0001x0004 01 00 00 00
Write Func[1:00FF0] = Len:0001x0010 03 00 00 00 00 04 50 00 04 00 00 00 02 00 00 00
Read  Func[1:00450] = Len:0001x0004 01 00 00 00
Write Func[1:00FF8] = Len:0001x0008 06 00 00 00 C0 80 01 00
Read  Func[1:00FFC] = Len:0001x0004 00 00 00 00
Read  Func[1:00450] = Len:0001x0004 01 00 00 00
Write Func[1:00FF4] = Len:0001x000C 07 00 00 00 C0 80 01 00 08 00 00 00
Read  Func[1:00450] = Len:0001x0004 01 00 00 00
Write Func[1:00FF8] = Len:0001x0008 06 00 00 00 C4 40 00 00
Read  Func[1:00FFC] = Len:0001x0004 08 00 00 00
Read  Func[1:00450] = Len:0001x0004 01 00 00 00
Write Func[1:00FF4] = Len:0001x000C 07 00 00 00 C4 40 00 00 09 00 00 00
Read  Func[1:00450] = Len:0001x0004 01 00 00 00
Write Func[1:00FF4] = Len:0001x000C 07 00 00 00 28 40 00 00 05 00 00 00
Read  Func[1:00450] = Len:0001x0004 01 00 00 00
Write Func[1:00FF4] = Len:0001x000C 07 00 00 00 20 40 00 00 00 00 00 00
Delay 0072
Write Func[1:00418] = Len:0001x0004 00 00 00 00
Read  Func[1:00400] = Len:0001x0010 00 00 00 00 0F 00 0F 00 00 00 00 00 00 00 00 00
Write Func[1:00400] = Len:0001x0004 00 00 00 00
Read  Func[1:00400] = Len:0001x0010 00 00 00 00 0F 00 0F 00 00 00 00 00 00 00 00 00
Write Func[0:00004] = 00

The old CMD+PARAM+REPLY are completely removed (unless the browser would happen to send anything other than CMD52/CMD53).
The two "Read Mem[NNNNNNNN]" lines are reading CHIP_ID and a RAM word from atheros memory space.
The "Write Func[1:00Fxx]" lines are writing BMI commands through MBOX0, that are only a few BMI commands; for firmware detect/start (the actual BMI firmware upload was already done earlier, by the launcher).
And at the "Delay 0072" location, the wifi unit should supposedly start to respond something, and the browser should then start to send WMI commands & try to connect to the access point - now it's time to test this on real hardware...
Re: DSi Wifi rev-engineering
by on (#229458)
Here's the first DSi wifi hardware log:
Attachment:
wifi-log.txt [364.36 KiB]
Downloaded 484 times

The DSi browser is doing a WEP connection to access point with SSID "ead" with password "dslink-dslink" and, because of security concerns, the console's MAC address is shown by using "mm" bytes as placeholder (and "aa" and "bb" for access point and bssid). After completing the connection, I've entered "problemkaputt.de" as WWW address, waited for the page to be displayed, and then quit logging. The DSi wifi board contains a AR6013G chip. Oh, and the logging tool is now also showing data as ASCII characters, additionally to the HEX bytes.

I think that's everything needed to reverse-engineer how to use the wifi hardware, if some idiot takes the time take the log file apart, then all details should unfold in next some weeks (the idiot is me, probably, but everybody else is very welcome to join in).

Some quick observations: I had expected a large "delay" without traffic while typing "problemkaputt.de", but there's no such delay showing up. Reason is probably that the browser is permanently sending whatever data to "nintendowifi.net", now I wonder if Opera on PC is doing such things, too. Well, I guess all modern software is doing that.

One oddity is that I can't find the html text from the http://problemkaputt.de/index.htm page in the log (eg. no link to "gba.htm" found in the log). On the other hand, the .gif files from my homepage are showing up in the log (with the "GIF87a" header, followed by 'monochrome' 24bit palette entries). Oh, and yeah, the server for my homepage seems to be currently having 50% downtime, but it was working when doing the wifi log.

So the overall file-transfer logging seems to work, it's only the index.htm page not appearing in the log... hmmm, that could be some problem with DMA-completion timing for larger packets (although that should be handled by the logging tool), or maybe the browser had cached the index.htm page somewhere from a previous connection, or the htm got compressed somehow?
Re: DSi Wifi rev-engineering
by on (#229467)
Does the Gzip header (1F 8B 08) appear in the logs? Does "Content-Encoding: gzip" appear in the logs? Does the browser have a "clear cache" or "reload" option?
Re: DSi Wifi rev-engineering
by on (#229484)
Thanks, yes, "1F 8B 08" is in one of the large packets, right after the first "GET" from problemkaputt.de.
That explains why the html text isn't visible.
Re: DSi Wifi rev-engineering
by on (#229507)
I've made a new log, difference is that it's logging only SDIO Writes this time, that's making things a bit more compact.
Well, and then I've spent some necrophile amount of time on hand-editing the log:
- inserted WMI command names
- removed padding bytes (to 80h-byte boundaries)
- merged HEX bytes with "ASCII" strings

One obvious thing is that there are three types writes, with meaning depending on first byte:
- 00h = unknown (occurs only in first six writes after the BMI commands)
- 01h = WMI command
- 02h = Data packet
Then the second byte is unknown, sometimes this or that.
The next two bytes are length.
The next two bytes are unknown, often zero, and sometimes related to command 002Eh:2008h or other stuff?
That six-byte header is then followed by "length" bytes (eg. containing the WMI command number and parameters).

Note: Below might look better without line-wrapping (eg. copy/paste and view in a text editor without wrapping to see a "summary", or view with wrapping to see all details with parameters).
Code:
No$2000 SDIO log (done without paying $2000 for a SD/SDIO hardware logging tool)
 Showing WRITES (after leading BMI commands) from DSi browser with AR6013G chip
 aa aa aa aa aa aa = Access Point
 bb bb bb bb bb bb = Router
 mm mm mm mm mm mm = DSi Console
 "ead"               SSID
 "dslink-dslink"     WEP password
Write Func[1:00F80] = Len:0001x0080 00 00 08 00 00 00 0002   (unknown init?)                    00 01 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 00 00 08 00 00 00 0002   (unknown init?)                    01 01 05 00 00 00
Write Func[1:00F80] = Len:0001x0080 00 00 08 00 00 00 0002   (unknown init?)                    02 01 05 00 00 00
Write Func[1:00F80] = Len:0001x0080 00 00 08 00 00 00 0002   (unknown init?)                    03 01 05 00 00 00
Write Func[1:00F80] = Len:0001x0080 00 00 08 00 00 00 0002   (unknown init?)                    04 01 05 00 00 00
Write Func[1:00F80] = Len:0001x0080 00 00 02 00 00 00 0004   (unknown init??)                   -
Write Func[1:00418] = Len:0001x0004 D1 00 03 01
Write Func[0:00004] = 03
Write Mem[0052B2A0] = 00000002
Write Func[1:00F80] = Len:0001x0080 01 01 06 00 00 00 0022 WMI_TARGET_ERROR_REPORT_BITMASK_CMD  7F 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 06 00 00 00 0047 WMI_SET_FRAMERATES_CMD               02 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 06 00 00 00 0022 WMI_TARGET_ERROR_REPORT_BITMASK_CMD  7F 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 02 00 00 00 000E WMI_GET_CHANNEL_LIST_CMD             -
Write Func[1:00F80] = Len:0001x0080 01 01 25 00 00 00 000A WMI_SET_PROBED_SSID_CMD              00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 08 00 00 00 0011 WMI_SET_CHANNEL_PARAMS_CMD           00 00 02 01 6C 09
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0008 WMI_SET_SCAN_PARAMS_CMD              FF FF FF FF FF FF 6A 00 6A 00 00 01 6A 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               01 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0007 WMI_START_SCAN_CMD                   00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00
Delay 0003+0003
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 25 00 00 00 000A WMI_SET_PROBED_SSID_CMD              00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 08 00 00 00 0011 WMI_SET_CHANNEL_PARAMS_CMD           00 00 02 01 6C 09
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0008 WMI_SET_SCAN_PARAMS_CMD              FF FF FF FF FF FF 6A 00 6A 00 00 01 6A 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               01 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0007 WMI_START_SCAN_CMD                   00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00
Delay 0004
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 25 00 00 00 000A WMI_SET_PROBED_SSID_CMD              00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 08 00 00 00 0011 WMI_SET_CHANNEL_PARAMS_CMD           00 00 02 01 6C 09
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0008 WMI_SET_SCAN_PARAMS_CMD              FF FF FF FF FF FF 6A 00 6A 00 00 01 6A 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               01 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0007 WMI_START_SCAN_CMD                   00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00
Delay 0002+0002+0002
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 25 00 00 00 000A WMI_SET_PROBED_SSID_CMD              00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 08 00 00 00 0011 WMI_SET_CHANNEL_PARAMS_CMD           00 00 02 01 76 09
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0008 WMI_SET_SCAN_PARAMS_CMD              FF FF FF FF FF FF 6B 00 6B 00 00 01 6B 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               01 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0007 WMI_START_SCAN_CMD                   00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00
Delay 0004
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 25 00 00 00 000A WMI_SET_PROBED_SSID_CMD              00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 08 00 00 00 0011 WMI_SET_CHANNEL_PARAMS_CMD           00 00 02 01 76 09
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0008 WMI_SET_SCAN_PARAMS_CMD              FF FF FF FF FF FF 6B 00 6B 00 00 01 6B 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               01 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0007 WMI_START_SCAN_CMD                   00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00
Delay 0005
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 25 00 00 00 000A WMI_SET_PROBED_SSID_CMD              00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 08 00 00 00 0011 WMI_SET_CHANNEL_PARAMS_CMD           00 00 02 01 80 09
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0008 WMI_SET_SCAN_PARAMS_CMD              FF FF FF FF FF FF 6F 00 6F 00 00 01 6F 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               01 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0007 WMI_START_SCAN_CMD                   00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00
Delay 0004+0002
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 25 00 00 00 000A WMI_SET_PROBED_SSID_CMD              00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 08 00 00 00 0011 WMI_SET_CHANNEL_PARAMS_CMD           00 00 02 01 8A 09
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0008 WMI_SET_SCAN_PARAMS_CMD              FF FF FF FF FF FF 70 00 70 00 00 01 70 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               01 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0007 WMI_START_SCAN_CMD                   00 00 00 00 00 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 01 00 00 00 00 00 00 00
Delay 0003
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 06 00 00 00 0022 WMI_TARGET_ERROR_REPORT_BITMASK_CMD  7F 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 0A 00 00 00 0009 WMI_SET_BSS_FILTER_CMD               00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 25 00 00 00 000A WMI_SET_PROBED_SSID_CMD              00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 16 00 00 00 0008 WMI_SET_SCAN_PARAMS_CMD              FF FF FF FF FF FF C8 00 C8 00 00 05 C8 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 08 00 00 00 0011 WMI_SET_CHANNEL_PARAMS_CMD           00 00 02 01 85 09
Write Func[1:00F80] = Len:0001x0080 01 01 05 00 00 00 F000 WMI_SET_BITRATE_CMD                  FF 00 00
Write Func[1:00F80] = Len:0001x0080 01 01 06 00 00 00 0048 WMI_SET_AP_PS_CMD                    01 A4 F7 FF
Write Func[1:00F80] = Len:0001x0080 01 01 03 00 00 00 0004 WMI_SYNCHRONIZE_CMD                  00
Write Func[1:00F80] = Len:0001x0080 01 01 03 00 00 00 0012 WMI_SET_POWER_MODE_CMD               02
Write Func[1:00F80] = Len:0001x0080 01 01 03 00 00 00 0004 WMI_SYNCHRONIZE_CMD                  00
Write Func[1:00F80] = Len:0001x0080 01 01 41 00 00 00 0005 WMI_CREATE_PSTREAM_CMD               14 00 00 00 14 00 00 00 7F 96 98 00 FF FF FF FF 00 00 00 00 00 45 01 00 00 45 01 00 00 45 01 00 00 00 00 00 00 00 00 00 80 8D 5B 00 00 20 00 00 00 00 00 00 D0 80 D0 00 00 02 FF 01 00 05 00
Write Func[1:00F80] = Len:0001x0080 01 01 03 00 00 00 0041 WMI_SET_WSC_STATUS_CMD               00
Write Func[1:00F80] = Len:0001x0080 01 01 03 00 00 00 000D WMI_SET_DISCONNECT_TIMEOUT   (_CMD)  02
Write Func[1:00F80] = Len:0001x0080 01 01 2F 00 00 00 0016 WMI_ADD_CIPHER_KEY_CMD               00 02 03 0D 00 00 00 00 00 00 00 00 "dslink-dslink" 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
Write Func[1:00F80] = Len:0001x0080 01 01 2F 00 08 20 0016 WMI_ADD_CIPHER_KEY_CMD               01 02 01 0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
Write Func[1:00F80] = Len:0001x0080 01 01 2F 00 00 00 0016 WMI_ADD_CIPHER_KEY_CMD               02 02 01 0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
Write Func[1:00F80] = Len:0001x0080 01 01 2F 00 00 00 0016 WMI_ADD_CIPHER_KEY_CMD               03 02 01 0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
Write Func[1:00F80] = Len:0001x0080 01 01 03 00 00 00 003D WMI_SET_KEEPALIVE_CMD                00
Write Func[1:00F80] = Len:0001x0080 01 01 36 00 00 00 0001 WMI_CONNECT_CMD                      01 02 01 02 00 02 00 03 "ead" 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 85 09 aa aa aa aa aa aa 00 00 00 00
Delay 0006+0007+001E+0006
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 02 00 00 00 00 00 00 00
Delay 0009+0002+000E
Write Func[1:00E80] = Len:0003x0080 02 00 60 01 00 00 0000   (data)                             FF FF FF FF FF FF mm mm mm mm mm mm 01 50 AA AA 03 00 00 00 08 00 45 00 01 48 00 01 00 00 80 11 39 A5 00 00 00 00 FF FF FF FF 00 44 00 43 01 34 CE 2E 01 01 06 00 5E 20 82 7D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 mm mm mm mm mm mm 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 63 82 53 63 35 01 01 3D 07 01 mm mm mm mm mm mm 0C 0A "NintendoDS" 37 03 01 03 06 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Delay 0009
Write Func[1:00F80] = Len:0001x0080 01 01 41 00 00 00 0005 WMI_CREATE_PSTREAM_CMD               00 00 00 00 00 00 00 00 88 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 00 FF 06
Delay 0002+0003+0013
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 03 00 00 00 00 00 00 00
Delay 000C
Write Func[1:00E80] = Len:0003x0080 02 00 60 01 00 00 0000   (data)                             FF FF FF FF FF FF mm mm mm mm mm mm 01 50 AA AA 03 00 00 00 08 00 45 00 01 48 00 02 00 00 80 11 39 A4 00 00 00 00 FF FF FF FF 00 44 00 43 01 34 57 64 01 01 06 00 A6 CA 35 B2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 mm mm mm mm mm mm 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 63 82 53 63 35 01 03 3D 07 01 mm mm mm mm mm mm 0C 0A "NintendoDS" 37 03 01 03 06 32 04 C0 A8 01 1E 36 04 C0 A8 01 01 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Delay 002E
Write Func[1:00F80] = Len:0001x0080 02 00 34 00 00 00 1C00   (special data?)                    FF FF FF FF FF FF mm mm mm mm mm mm 00 24 AA AA 03 00 00 00 08 06 00 01 08 00 06 04 00 01 mm mm mm mm mm mm C0 A8 01 1E 00 00 00 00 00 00 C0 A8 01 1E
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 04 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 02 00 34 00 00 00 1C00   (special data?)                    FF FF FF FF FF FF mm mm mm mm mm mm 00 24 AA AA 03 00 00 00 08 06 00 01 08 00 06 04 00 01 mm mm mm mm mm mm C0 A8 01 1E 00 00 00 00 00 00 C0 A8 01 01
Delay 0005
Write Func[1:00F80] = Len:0001x0080 02 00 34 00 00 00 1C00   (special data?)                    FF FF FF FF FF FF mm mm mm mm mm mm 00 24 AA AA 03 00 00 00 08 06 00 01 08 00 06 04 00 01 mm mm mm mm mm mm C0 A8 01 1E 00 00 00 00 00 00 C0 A8 01 1E
Write Func[1:00F80] = Len:0001x0080 02 01 5F 00 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 4F AA AA 03 00 00 00 08 00 45 00 00 47 00 03 00 00 80 11 B7 33 C0 A8 01 1E C0 A8 01 01 12 E6 00 35 00 33 C1 41 F7 83 01 00 00 01 00 00 00 00 00 00 08 "conntest" 0C "nintendowifi" 03 "net" 00 00 01 00 01
Write Func[1:00F80] = Len:0001x0080 02 00 48 00 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 38 AA AA 03 00 00 00 08 00 45 00 00 30 00 04 00 00 80 06 A8 58 C0 A8 01 1E 45 19 8B 8C 12 E7 00 50 47 B7 F9 BF 00 00 00 00 70 02 0B 68 91 01 00 00 02 04 05 50 01 01 04 02
Delay 0007+0003
Write Func[1:00F80] = Len:0001x0080 02 00 34 00 00 00 1C00   (special data?)                    bb bb bb bb bb bb mm mm mm mm mm mm 00 24 AA AA 03 00 00 00 08 06 00 01 08 00 06 04 00 02 mm mm mm mm mm mm C0 A8 01 1E bb bb bb bb bb bb C0 A8 01 01
Write Func[1:00F80] = Len:0001x0080 01 01 41 00 00 00 0005 WMI_CREATE_PSTREAM_CMD               00 00 00 00 00 00 00 00 88 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 FF 01
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 05 00 00 80 06 A8 5F C0 A8 01 1E 45 19 8B 8C 12 E7 00 50 47 B7 F9 C0 9E C7 66 EE 50 10 0B 68 B7 9B 00 00
Write Func[1:00F00] = Len:0002x0080 02 01 86 00 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 76 AA AA 03 00 00 00 08 00 45 00 00 6E 00 06 00 00 80 06 A8 18 C0 A8 01 1E 45 19 8B 8C 12 E7 00 50 47 B7 F9 C0 9E C7 66 EE 50 18 0B 68 59 55 00 00 GET / HTTP/1.0Host: conntest.nintendowifi.netConnection: close
Delay 000A
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 07 00 00 80 06 A8 5D C0 A8 01 1E 45 19 8B 8C 12 E7 00 50 47 B7 FA 06 9E C7 68 62 50 11 09 F5 B7 53 00 00
Write Func[1:00F80] = Len:0001x0080 02 01 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 08 00 00 80 06 A8 5C C0 A8 01 1E 45 19 8B 8C 12 E7 00 50 47 B7 FA 06 9E C7 68 62 50 10 0B 68 B5 E1 00 00
Delay 000A
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 09 00 00 80 06 A8 5B C0 A8 01 1E 45 19 8B 8C 12 E7 00 50 47 B7 FA 07 00 00 00 00 50 04 00 00 C8 7E 00 00
Delay 0012
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 05 00 00 00 00 00 00 00
Delay 003B
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 06 00 00 00 00 00 00 00
Delay 003B
Write Func[1:00F80] = Len:0001x0080 02 00 34 00 00 00 1C00   (special data?)                    FF FF FF FF FF FF mm mm mm mm mm mm 00 24 AA AA 03 00 00 00 08 06 00 01 08 00 06 04 00 01 mm mm mm mm mm mm C0 A8 01 1E 00 00 00 00 00 00 C0 A8 01 01
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 07 00 00 00 00 00 00 00
Delay 000F+0021+000C
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 08 00 00 00 00 00 00 00
Delay 0026+0004+0010
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 09 00 00 00 00 00 00 00
Delay 000C+0005+002A
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 0A 00 00 00 00 00 00 00
Delay 003C
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 0B 00 00 00 00 00 00 00
Delay 0029+0013
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 0C 00 00 00 00 00 00 00
Delay 0020+001C
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 0D 00 00 00 00 00 00 00
Delay 003B
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 0E 00 00 00 00 00 00 00
Delay 003B
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 0F 00 00 00 00 00 00 00
Delay 0020+001B
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 10 00 00 00 00 00 00 00
Delay 003C
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 11 00 00 00 00 00 00 00
Delay 0005+0007+0024
Write Func[1:00F80] = Len:0001x0080 01 01 41 00 08 20 0005 WMI_CREATE_PSTREAM_CMD               00 00 00 00 00 00 00 00 88 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 00 FF 06
Delay 0006+0005
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 12 00 00 00 00 00 00 00
Delay 000A+0030
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 13 00 00 00 00 00 00 00
Delay 000A+0003+000C+0023
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 14 00 00 00 00 00 00 00
Delay 000D+000A+001B+000A
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 15 00 00 00 00 00 00 00
Delay 000C+000A+0014+0011
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 01 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 16 00 00 00 00 00 00 00
Delay 000D+0009+0014+0004+000D
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 17 00 00 00 00 00 00 00
Delay 000D+0004+0005+0015+000D
Write Func[1:00F80] = Len:0001x0080 02 00 56 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 46 AA AA 03 00 00 00 08 00 45 00 00 3E 00 0A 00 00 80 11 B7 35 C0 A8 01 1E C0 A8 01 01 12 E8 00 35 00 2A 68 A0 00 01 01 00 00 01 00 00 00 00 00 00 0D "problemkaputt" 02 "de" 00 00 01 00 01
Write Func[1:00F80] = Len:0001x0080 02 00 48 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 38 AA AA 03 00 00 00 08 00 45 00 00 30 00 0B 00 00 80 06 DE 62 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 7B 74 00 00 00 00 70 02 80 00 FD F7 00 00 02 04 05 50 01 01 04 02
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 0C 00 00 80 06 DE 69 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 7B 75 21 7A 6C 94 50 10 80 00 9C 39 00 00
Write Func[1:00E00] = Len:0004x0080 02 01 BF 01 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 01 AF AA AA 03 00 00 00 08 00 45 00 01 A7 00 0D 00 00 80 06 DC E9 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 7B 75 21 7A 6C 94 50 18 80 00 A8 12 00 00 GET / HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Connection: Keep-Alive
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 01 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 18 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 0E 00 00 80 06 DE 67 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 7C F4 21 7A 72 54 50 10 7A 40 9A BA 00 00
Delay 000C+0008
Write Func[1:00D80] = Len:0005x0080 02 00 20 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 10 AA AA 03 00 00 00 08 00 45 00 02 08 00 0F 00 00 80 06 DC 86 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 7C F4 21 7A 72 54 50 18 7A 40 04 7A 00 00 GET /char-f.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Write Func[1:00F80] = Len:0001x0080 02 00 48 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 38 AA AA 03 00 00 00 08 00 45 00 00 30 00 10 00 00 80 06 DE 5D C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 70 7B 00 00 00 00 70 02 80 00 31 94 00 00 02 04 05 50 01 01 04 02
Write Func[1:00D80] = Len:0005x0080 02 01 20 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 10 AA AA 03 00 00 00 08 00 45 00 02 08 00 11 00 00 80 06 DC 84 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 7E D4 21 7A 74 27 50 18 78 6D FA 99 00 00 GET /char-n.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 12 00 00 80 06 DE 63 C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 70 7C 0E B3 15 F9 50 10 80 00 39 38 00 00
Delay 0002
Write Func[1:00D80] = Len:0005x0080 02 01 20 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 10 AA AA 03 00 00 00 08 00 45 00 02 08 00 13 00 00 80 06 DC 82 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 80 B4 21 7A 76 06 50 18 76 8E 05 BA 00 00 GET /char-a.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Write Func[1:00D80] = Len:0005x0080 02 00 20 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 10 AA AA 03 00 00 00 08 00 45 00 02 08 00 14 00 00 80 06 DC 81 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 82 94 21 7A 77 DA 50 18 74 BA FF D9 00 00 GET /char-e.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Delay 0003
Write Func[1:00D80] = Len:0005x0080 02 00 1D 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 0D AA AA 03 00 00 00 08 00 45 00 02 05 00 15 00 00 80 06 DC 83 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 84 74 21 7A 79 A8 50 18 72 EC 60 7D 00 00 GET /yep.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Delay 000B
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 16 00 00 80 06 DE 5F C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 86 51 21 7A 7B 57 50 10 71 3D 91 5D 00 00
Delay 0005
Write Func[1:00D80] = Len:0005x0080 02 01 20 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 10 AA AA 03 00 00 00 08 00 45 00 02 08 00 17 00 00 80 06 DC 7E C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 86 51 21 7A 7B 57 50 18 80 00 DD 59 00 00 GET /char-u.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Write Func[1:00D80] = Len:0005x0080 02 00 20 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 10 AA AA 03 00 00 00 08 00 45 00 02 08 00 18 00 00 80 06 DC 7D C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 70 7C 0E B3 15 F9 50 18 80 00 91 F7 00 00 GET /char-w.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Write Func[1:00D80] = Len:0005x0080 02 00 20 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 10 AA AA 03 00 00 00 08 00 45 00 02 08 00 19 00 00 80 06 DC 7C C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 72 5C 0E B3 17 D3 50 18 7E 26 95 17 00 00 GET /char-r.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Write Func[1:00D80] = Len:0005x0080 02 00 21 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 11 AA AA 03 00 00 00 08 00 45 00 02 09 00 1A 00 00 80 06 DC 7A C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 74 3C 0E B3 19 AD 50 18 7C 4C 2C 32 00 00 GET /breath2.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 19 00 00 00 00 00 00 00
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 1B 00 00 80 06 DE 5A C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 76 1D 0E B3 24 4D 50 10 71 AC 33 97 00 00
Write Func[1:00F80] = Len:0001x0080 02 01 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 1D 00 00 80 06 DE 58 C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 77 FD 0E B3 2E ED 50 10 67 0C 31 B7 00 00
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 1E 00 00 80 06 DE 57 C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 77 FD 0E B3 39 8D 50 10 5C 6C 31 B7 00 00
Write Func[1:00D80] = Len:0005x0080 02 00 20 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 10 AA AA 03 00 00 00 08 00 45 00 02 08 00 1C 00 00 80 06 DC 79 C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 76 1D 0E B3 24 4D 50 18 71 AC A3 F1 00 00 GET /nonazi.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 20 00 00 80 06 DE 55 C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 77 FD 0E B3 4B 9A 50 10 62 5F 19 B7 00 00
Write Func[1:00F80] = Len:0001x0080 02 01 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 21 00 00 80 06 DE 54 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 88 31 21 7A 7D 2A 50 10 7E 2D 80 BA 00 00
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 22 00 00 80 06 DE 53 C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 77 FD 0E B3 56 3A 50 10 57 BF 19 B7 00 00
Write Func[1:00F80] = Len:0001x0080 02 01 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 23 00 00 80 06 DE 52 C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 77 FD 0E B3 5C 7F 50 10 51 7A 19 B7 00 00
Delay 0002
Write Func[1:00D80] = Len:0005x0080 02 00 20 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 10 AA AA 03 00 00 00 08 00 45 00 02 08 00 24 00 00 80 06 DC 71 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 88 31 21 7A 7D 2A 50 18 7E 2D F1 14 00 00 GET /nonazi.gif HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailers
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 25 00 00 80 06 DE 50 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 8A 11 21 7A 87 CA 50 10 73 8D 7E DA 00 00
Write Func[1:00F80] = Len:0001x0080 02 01 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 26 00 00 80 06 DE 4F C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 8A 11 21 7A 92 6A 50 10 68 ED 7E DA 00 00
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 27 00 00 80 06 DE 4E C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 8A 11 21 7A 93 5F 50 10 80 00 66 D2 00 00
Delay 0006
Write Func[1:00F80] = Len:0001x0080 02 01 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 28 00 00 80 06 DE 4D C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 77 FD 0E B3 5C 7F 50 10 80 00 EB 30 00 00
Delay 0008
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 29 00 00 80 06 DE 4C C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 77 FD 0E B3 5C 7F 50 11 80 00 EB 2F 00 00
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 2A 00 00 80 06 DE 4B C0 A8 01 1E 58 C6 41 CE 12 EA 00 50 F1 DE 77 FE 0E B3 5C 80 50 10 80 00 EB 2E 00 00
Delay 0003
Write Func[1:00D80] = Len:0005x0080 02 01 21 02 00 00 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 02 11 AA AA 03 00 00 00 08 00 45 00 02 09 00 2B 00 00 80 06 DC 69 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 8A 11 21 7A 93 5F 50 18 80 00 65 41 00 00 GET /favicon.ico HTTP/1.1User-Agent: Opera/9.50 (Nintendo DSi; Opera/507; U; en-GB)Host: problemkaputt.deAccept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1Accept-Language: enAccept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0Referer: http://problemkaputt.de/Connection: Keep-Alive, TETE: deflate, gzip, chunked, identity, trailer
Write Func[1:00F80] = Len:0001x0080 02 00 40 00 08 20 0000   (data)                             bb bb bb bb bb bb mm mm mm mm mm mm 00 30 AA AA 03 00 00 00 08 00 45 00 00 28 00 2C 00 00 80 06 DE 49 C0 A8 01 1E 58 C6 41 CE 12 E9 00 50 1A 83 8B F2 21 7A 99 2D 50 10 7A 32 64 F1 00 00
Delay 0012+0009
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 1A 00 00 00 00 00 00 00
Delay 0023+0018
Write Func[1:00F80] = Len:0001x0080 01 01 0E 00 02 00 002E WMIX_HB_CHALLENGE_RESP_CMD           08 20 00 00 1B 00 00 00 00 00 00 00
Delay 0008+000B
Re: DSi Wifi rev-engineering
by on (#229527)
Here's a summary of the MBOX headers spotted in the log. Any ideas what the <Unknown> entries are good for? Or about the other "?" questions marks?

I have tried to find info about those MBOX headers in source code... but I couldn't anything useful... does somebody have more luck there?
File wmi.h contains some snippets that might be header fragments... but it's hard to tell which header bytes those snippets might refer to.
Code:
DSi Atheros Wifi - MBOX Transfer Headers
----------------------------------------

MBOX transfers include a small header for distinguishing between Data Packets
and Commands/Events, and for indicating the actual length (as opposed to the
MBOX transfer length, which is usually garbage-padded to 80h-byte boundary).
The exception are BMI Bootloader commands/responses (which don't have such
headers or padding).

SDIO Functions used after BMI init
  Func[0:00005h]        R   1     Interrupt Flags (bit1=Function 1 IRQ)
  Func[1:00400h]        R   10h   Interrupt Status, etc.
  Func[1:00474h]        R   4     WINDOW DATA (uh, without prior ADDR ?)
  Func[1:00xxxh..00FFF] R/W ..    MBOX0

 ________________________________ Send Headers ________________________________

Header for Sending UNKNOWN Crap
  00h 1  Must be 00h for UNKNOWN Crap
  01h 1  <Unknown1>?? 00h
  02h 2  Length of entries [06h..end]
  04h 2  <Unknown4>?? 0000h
  06h 2  <Unknown6>?? 0002h or 0004h
  08h .. Unknown Parameters (if any)
DSi Browser is sending six such unknown crap things right after the BMI phase.
Purpose is totally unknown, however, one could just send the same crap without
knowning its purpose.

Header for Sending WMI Commands
  00h 1  Must be 01h for WMI Commands
  01h 1  <Unknown1>?? 01h
  02h 2  Length of entries [06h..end]
  04h 2  <Unknown4>?? 0000h, or 0101h/0002h/0102h=HB, or 2008h=2ndCipherKey???
  06h 2  WMI Command Number
  08h .. Parameters (plus leading 4-byte command suffix if CMD=002Eh:000020xxh)
Unknown4 looks kinda random/garbage (eg. 2008h occurs in 2nd CIPHER_KEY, and in
4th PSTREAM command), in so far it's apparently unrelated to the current
command (however, it might be a reply/ack for some previous stuff?).

Header for Sending DATA Packets
  00h 1  Must be 02h for DATA Packets
  01h 1  <Unknown1>?? 00h or 01h        ;maybe two "channels" for simult. GETs?
  02h 2  Length of entries [06h..end]
  04h 2  <Unknown4>?? 0000h or 2008h    ;maybe related to cmd 002Eh:2008h ?
  06h 2  <Unknown6>?? 0000h or 1C00h    ;maybe whatever ?
  08h 6  Destination (MAC Addr of Router) (or FF:FF:FF:FF:FF:FF=Broadcast)
  0Eh 6  Source      (MAC Addr of DSi console)
  14h 2  Length of entries [16h..end]
  16h .. Data (usually starting with LLC stuff, ie. AAh,AAh,03h,00h...)

 ______________________________ Receive Headers ______________________________

Header for Receiving UNKNOWN Crap
  00h 1  Must be 00h for UNKNOWN Crap
  01h .. <Unknown1>?? 00h
DSi Browser is receiving six such unknown crap things right after the BMI
phase. Purpose is totally unknown, however, one could just sent same replies as
being used by the DSi browser.
Moreover, DSi Browser is receiving MORE such unknown crap every once and then,
maybe containing ACKs or other handshake info?

Header for Receiving WMI Events
  00h 1  Must be 01h for WMI Events
  01h 1  <Unknown1>?? 02h    ;EDIT: actually 00h or 02h
  02h 2  Length of entries [06h..end]
  04h 2  <Unknown4>?? 0008h, 000Ch, or FF08h
  06h 2  WMI Event Number
  08h .. Parameters

Header for Receiving DATA Packets
  00h 1  Must be 02h for DATA Packets
  01h 1  <Unknown1>?? 00h or 01h or 02h   ;EDIT: actually always 02h
  02h 2  Length of entries [06h..end]
  04h 2  <Unknown4>?? 0000h, 0008h, 000Ch, 2008h, 7F08h, F408h, F40Ch, FF08h
  06h 1  RSSI (Received Signal Strength Indicator) (00h..3Ch) (aka 0..60)
  07h 1  <Unknown7> 00h
  08h 6  Whatever Address (MAC Addr of Router)        ;\or sometimes swapped?
  0Eh 6  Whatever Address (MAC Addr of DSi console)   ;/
  14h 2  Length of entries [16h..end]
  16h .. Data (usually LLC stuff, ie. AAh,AAh,03h.. or, once F0h,F0h,03h..??)

The send/receive DATA headers are apparently containing incomplete wifi "Frame Headers":
-- without 3rd address field
-- without WEP entries (those are apparently automatically inserted)
-- without Frame Control, Duration/ID, Sequence Control
-- in lack of Frame Control, there seem to be only Data Frames (no Managment/Control Frames)
Unless some of the missing info would be encoded in the <Unknown> header entries.
Re: DSi Wifi rev-engineering
by on (#229570)
I've edited the above post: Byte[01h] for Receive/Event and Receive/Data was wrong. And [06h] for Receive/Data, I had listed 0000h and 1C00h, but that wrong (those values show up only on Sending, not on Receiving; ie. the receive actual values were 0033h..0039h).

For that Receive/Data Byte[06h], Stephen Stair suggested that the values in range 33h..39h might be RSSI (Received Signal Strength Indicator), and that looks just right: Several webpages say that atheros uses 00h..3Ch (0..60) as RSSI range, so 33h..39h would be a strong signal (distance between DSi and Access Point was around 50cm). After walking 4 meters away and hiding behind a cupboard, the values dropped to 13h..24h. So, that's confirmed to be RSSI, at least 6bits, or maybe it's zeropadded to 8bits or even 16bits.
Re: DSi Wifi rev-engineering
by on (#229626)
Oops, I've found a logging error where 3-step WINDOW-read had collided with a WMI-event:
Code:
   bad:
Read  Mem[00520001] = 00520000                    ;this is a logging error (the 3-step MemRead had collided with REGDOMAIN event)
Read  Func[1:00400] = Len:0001x0010 00 00 04 00 0F 00 0F 00 00 00 00 00 00 BC 1A 91
Read  Func[1:00474] = Len:0001x0004 A0 B2 52 00   ;this is final step of above mis-logged MemRead
Write Mem[0052B2A0] = 00000002
   correct:
Read  Mem[005200...                               ;ReadMem addr.msbs (then gets interrupted by event...)
Read  Func[1:00F80] = Len:0001x0080 01 02 0E 00 08 00 06 10 48 03 00 80 02 06 00 00 00 00 00 00   ;REGDOMAIN event
Write Func[1:0047C] = Len:0001x0001 00            ;ReadMem addr.lsb ;[......00]
Read  Func[1:00400] = Len:0001x0010 00 00 04 00 0F 00 0F 00 00 00 00 00 00 3C 1A 11
Read  Func[1:00474] = Len:0001x0004 A0 B2 52 00   ;ReadMem data  ;Mem[00520000] = 0052B2A0
Write Mem[0052B2A0] = 00000002

The problem happened only in that one location, and no idea why Nintendo/Atheros had interrupted the read, it wouldn't make much of a difference to process the event after completing the read.

The good news is that everything up to including the above event & mem accesses are same as wifi initialization in launcher - which is already implemented in unlaunch, so I've cleaned up the unlaunch code a bit, and then I can re-use it in wifiboot.

Two small differences that I have spotted are (probably more related to AR6002 vs AR6013, rather than Launcher vs Browser):
With Launcher/AR6002, I had observed WLAN_SYSTEM_SLEEP [0040C4h]=1Ch/1Dh, but in Browser/AR6013 it's 0Ch/0Dh, maybe the bit4 is initially zero (or completely missing) in newer hardware.
With Launcher/AR6002, I got REGDOMAIN value 80000188h, but Browser/AR6013 gets 80000348h. With that difference, it's more clear what the value is supposed to mean (in the wifi firmware "RGBD" DataSet, 0188h is "JP" and 0348h is "US") (which is both wrong because I am elsewhere, and I have a european console anyways; also, the REGDOMAIN is thrown only after initialization, ie. there is no further such event with actual country code after connecting to an access point) (bottom line is that they must have hardcoded the firmwares with random country codes... or stored random country codes in the wifi EEPROM).

After the above stuff, Launcher is sending a WMI_SET_SCAN_PARAMS_CMD for whatever reason, and does then complete the wifi init by disabling wifi IRQs.

And the Browser is instead sending four other WMI commands, and then repeatedly sends six WMI commands (per channel scanned) until receiving a beacon matching to the access points in system settings. At that point it's sending a dozen more commands for connecting to the access point.
That's all looking very simple (much easier as for NDS wifi, where one had to construct the scanning/connect managment frames manually).

And if that's working, next would be exchanging four DHCP data packets. And if that's working... ideally, all other data packets might be already working, too - and the project would be finished (much earlier than expected).
On the other hand, things like error handling and retries might cause unexpected extra troubles, so it might take some more weeks/months until everything is stable.
Re: DSi Wifi rev-engineering
by on (#229739)
Things are getting better, and worse.

The good thing is that I've got a better understanding of the MBOX Transfer headers.

Leaving apart the initial six handshakes: All further MBOX blocks with [00h]=00h are essentially ACK's for confirming that one has written a Command or Data packet (or maybe confirming that it was written AND processed).
That feature appears to be optional, depending [01h] of the written Command/Data. If it's 00h then no ACK is generated, if it's 01h then one ACK is generated for Commands, and - oddly - two ACKs for Data.
For Commands it's always [01h]=01h (=want ACK), but it might be possible to disable ACKs via [01h]=00h (not tested yet).
For Data it's sometimes [01h]=01h, and sometimes [01h]=00h, even for identical data packet types (eg. some http GET's are sent with ACK requested, and other http GET's without).

The bad thing is BYTE[04h] of received stuff is containing a Length of Extra Data appended at the end of the MBOX. This is usually 08h or 0Ch bytes (or maybe 00h exist, too, don't remember exactly).
For example, one can see that in WMIX_HB_CHALLENGE_RESP_EVENT, the event parameters have fixed length (8 bytes). But the total length at [02h] varies (0016h or 001Ah), and the extra length varies accodingly (08h or 0Ch).
That extra data does usually (or always) start with 02h,06h. And it's then followed by 6 or 10 bytes with whatever content.

Discovering those unknown purpose extra bytes is a bit unpleasant. I had just thought that I had understood the protocol - and then that! : /

The BYTE[05h] of received stuff might be some flags (or a negative value?). One theory is that one of the flags might indicate that the MBOX contains at least one more packet(s) - so one could issue further MBOX reads until the flag goes off.
At least the log does look a bit like that (there are some continous MBOX reads without checking the [1:00400] status bytes). Other theory would be that the ARM-CPU-IRQ flag is checked instead of [1:00400], but I think IRQ acknowledges should be then visible in the log.

I've also started looking at the old NDS wifi source code. It's mostly the ARM7 code that would need to be changed for DSi wifi. And at least half of that code could be probably completely removed. The trick would be not to remove important & still needed parts.
And the other issue is that most of the NDS code is IRQ driven - which is good - but it's also making the program flow a good bit more confusing (as opposed to a much easier design like using a simple loop for channel-scanning, followed by a mainloop for forwarding data to ARM9).
Re: DSi Wifi rev-engineering
by on (#229743)
PS. Here's a newer version of the wifi-log.txt file, with several annotations, and with 80h-byte padding removed in most cases (at least in the first half of the log) (some of the larger data packets still have the padding, and the DBGLOG events do so, too).
Attachment:
wifi-v2.txt [249.99 KiB]
Downloaded 378 times

EDIT: Grumph, some of the scanning events contain "01 00 xx xx FF FF 04 10 ..." in MBOX.
That's with [04h]=FFh, in that special case [04h] is apparently something other than length of Extra Data.
Re: DSi Wifi rev-engineering
by on (#230084)
I've implemented channel scanning and access point connection in past some days. The first thing done was removing the whole ARM7 code from wificode/dswifi, as well as W_xxx constants for the NDS-WIFI hardware registers. That worked surprisingly well, throwing only a few errors on missing 'public' functions/constants:
Code:
  arm7_installWifiFIFO
  arm7_wifiValue32Handler   ;this includes Init (from ARM9 via FIFO)
  arm7_Wifi_Update
  arm7_Wifi_Deinit
  arm7_Wifi_Interrupt
  IRQ_WIFI (add IRQ2_DSI_WIFI, and don't forget adding IRQ2_ALL)
For the DSi, I've made a new "Init" function, it's basically a copy of the wifi init code from unlaunch, except without wifi firmware uploading in the BMI stage. However, I guess I can remove that whole stuff in final version as unlaunch (or launcher) are already doing the same initialization, so it would be pointless to repeat the same initialization in the .dsi title (although the DSi browser is doing right that, but pointless is a also good term to describe the DSi browser after all).

Next, I've sent a few WMI init commands (as done by the browser), and then the WMI commands for channel scanning, and passed the scanning's WMI events to the old ARM7 code (here resurrection a code snipped from the removed ARM7 stuff). That worked so well that the ARM9 did display the name of my access point right away (which I am still buffled about, I didn't even have had the Wifi_Update function implemented at that time, which, I thought it were needed to setup some state variables for being in scanning mode).

Then I've added WMI connect commands, and changed them to use the channel number and access point details from the scanning steps (and matching wifi password from wifi FLASH memory). And learned some things alongsides:
-- Connect error (eg. bad password) throws DISCONNECT event (instead of CONNECT event).
-- My DSi has only channel 1-11 enabled (trying to scan channel 12,13,14 via SET_CHANNEL_PARAMS throws CMDERROR event).
-- WEP uses only key0, but seems to require dummy CIPHER values for WEP key1-3 (else CONNECT throws ERROR_REPORT event).
-- Receiving data/events bigger than one 80h-byte-block does require "CMD12" enabled in SDIO_STOP_INTERNAL_ACTION bit8 (although, CMD12 shouldn't actually exist for SDIO; ie. the bit probably rather means "stop at end" than literally sending CMD12 in this case).

Obscure 8 or 12 bytes appended at the end of the received data:
The 8 bytes are containing lookahead for the next MBOX packet (so one won't need to manually read the RX_LOOKAHEAD0 register). That's good for knowing if one can read another MBOX packet right away (and also for knowing the length of that packet). The 8 bytes are "02h,06h, AAh, lookahead[4], 55h". If there's no lookahead available yet, then the 8 bytes are often appened nonetheless, but with 00h/00h instead of AAh/55h (and with garbage[4] instead of lookahead[4]).

The other 4 bytes (the first 4 bytes when having 12 bytes appended) contain ACK info, either cmd.ack or data.ack. I am not entirely sure what is ack'ed there (cmd/data received, or cmd/data received AND processed AND delivered). But... whatever it's meant to mean... I am taking it as confirmation that one can send more cmd/data after the corresponding cmd.ack/data.ack. That's useful because the Function 1 status registers contain a lot of info on RX state (flags, lookahead, etc), but little info on TX state (I've merely found a TX overflow flag, which would mean that one would NEED to send data for determining if an overflow would occur).

The length of above 8 or 12 bytes is indicated as [04h]=08h or [04h]=0Ch. And, unlike as one might expect, absence of that bytes isn't indicated by [04h]=00h. Instead, that's indicated as [01h]=00h and [04h]=garbage. Which, I think it's really just garbage, it's often [04h]=00h, or sometimes [04h]=FFh, and I've even seen [04h]=5Eh once.

Next stuff on Todo list
Scanning and connection are working fine so far (and they are meanwhile already done on IRQ level). Next will be forwarding Data packets to/from ARM9. I hope to get that working tomorrow (or even today). It looks easy enough, the main issue is parsing the MBOX headers to NDS-style headers for the ARM9 code. The extra obstacle is that ARM9 packets are stored in ring-buffers, which may need address wrapping once and then.

For the packet size, officially, wifi frame bodies can be up to 2312 (908h) bytes, plus some header/checksum bytes. I was concerned that this could conflict with the MBOX size of 800h bytes, possibly needing to split larger packets somehow. But I do now think the issue doesn't exist in practice, because the network MTU is usually set to about 1400 bytes (DSi firmware allows to select 1500 bytes as maximum). MTU is short for "Max Transmission Unit".

And some confusing oddities
Apropos weird abbreviations. The RSSI (Received Signal Strength Indicator) in the MBOX header appears to be actually what Atheros is referring to as SNR (Signal to Noise Ratio). RSSI and SNR are widely used confusing terms expressed in decibels (whereas, my understanding is that "decibel" is tech slang for "meaningless virtual unit"; similar to percents, but leaving it unspecified whether the units are counted in per cents, or per volt, or per watt, or per milliwatt, or per whatver). The best SNR explanatation that I've found is explaining that the Signal to Noise Ratio "isn't actually a ratio" (it's an offset between signal level and noise level, ie. computed by substracting two values, not by dividing them).

The relation between RSSI and SNR can be seen in the WMI_BSSINFO_EVENT structure. Or actually, there are two structures:
An old 10h-byte structure with both RSSI and SNR (this format is used by DSi).
A new 0Ch-byte structure with SNR only (this format is implemented in DSi, too, but seems to be left unused).
For the new 0Ch-byte format, Atheros does advise to compute the missing RSSI value as "rssi=snr-95" (in result, RSSI should be a negative number, assuming SNR being 0..60). Going by the values spotted in the wifi log, the same formula is also used for the old 10h-byte format, though with a weird and possibly bugged corner case:

The SNR is/was believed to be in range 0..60 (00h..3Ch) on Atheros hardware. But I've also spotted a BSSINFO event with SNR=FCh, which, I guess it's meant to be "-4" (even though that would mean that the signal was weaker than the noise level; or at least weaker than the virtually assumed noise). On the other hand, Atheros seems to see SNR=FCh as "+252", at least they somehow ended up with storing RSSI=009Dh in the 10h-byte event structure (I guess they just didn't know about using 8bit-to-16bit sign-extension, either that, or somebody is operating a megawatt Wifi network in the closer neighborhood, on one of the Jupiter moons, for example).
Re: DSi Wifi rev-engineering
by on (#230091)
A "bel" is a 10 to 1 ratio in power. A "decibel" is one-tenth of a bel, or a 10^.1 = 1.26:1 ratio in power. If the signal to noise ratio is 6 decibels, then the signal power divided by the noise power is 10^.6 = 3.98:1.
Re: DSi Wifi rev-engineering
by on (#230122)
I've looked at the wikipedia page after writing the above post, too. As I understand it now: The difference between "percent" and "decibel" is that percents are linear, and decibels are logarithmic (ie. 2db is more than twice as much as 1db) (*).
Ah, then, that sounds as if SNR is actually a "ratio" despite of having it calculated by subtracting "signal-noise". Hmmm, that logarithmic stuff is confusing and exceeds my daily add/sub/shift/and/or/xor maths.

Okay, and a difference of 256db means factor 10^(25.6)? Then, that's funny, with the wrong sign-extension, the difference between -4db and +252db is 256db. And, assuming that an average access point is using 1 watt for transmitting signals... the BSSINFO event from Atheros is telling me that there's a "39810 billion terawatt" access point right next door? That might be reason of concern for most people living on this planet (coincidentally, the energy emitted by the sun is just about 10x higher).

But back to DSi Wifi: The code for sending TX Data is theoretically working now (still untested because I have no code for receving RX Data responses yet). I am hoping that it will be up to 25 times faster than the old 2Mbit/s NDS wifi. Or maybe 10^25.6 times faster. Or so. Something like that. Just hope that it won't end up being slower than before!

(*) and the other differences are that the reference point is called "100%" for percents, and 1db "0db"for decibels; and that it isn't frowned upon to exceed the reference point in the latter case.
Re: DSi Wifi rev-engineering
by on (#230124)
nocash wrote:
And, assuming that an average access point is using 1 watt for transmitting signals
802.11 power ratings are usually measured in dBuV, decibels relative to 1 microvolt transmitted/received signal.
Re: DSi Wifi rev-engineering
by on (#230126)
Does that make a difference on the estimated power consumption? I guess that the transmitter energy is something in range of watts, even if the receiver sees only some microwatts or microvolts of that signal. But either way, factor X for received power implies factor X for transmitted power, doesn't it?

That, assuming that the access point is really located somewhere next door (if it's more than a few 100 meters away, then it's probably broadcasting using the power of more than a thousand of suns).
Re: DSi Wifi rev-engineering
by on (#230127)
Decibels (and Bels) are always a relative measurement: there's no universal 0. You can't talk about 1 dB as some absolute quantity: instead you have to have a defined 0 reference.

Hence dBuV. The ratio relative to 1 microvolt.

802.11 access points transmit somewhere around 100mW. q.v. https://wlan1nde.wordpress.com/2014/11/ ... ower-etsi/

And the numbers exposed to the end user are usually actually displayed as the absolute value of the dBmW - "90" means "-90dBmW"
Re: DSi Wifi rev-engineering
by on (#230169)
Success! And Failure!
Data RX/TX is implemented & sending/receiving DHCP packets is working. After passing the DHCP stage, it's been waiting for a .nds/.dsi file to be uploaded from PC to DSi via UDP/TCP packets, and that upload worked right away, too.
Only, the DSi transfer speed doesn't look any faster than old NDS wifi, well, at least it doesn't look much slower either (I'll need to display some "Kbyte/second" indicator to be sure). Anyways, it's definetly miles away from being 25x faster.
The issue might be just that my 32bit ARM7 code is too slow because it's using code/data in uncached Main RAM, that could be fixed by using faster memory & more DMA transfers. If that doesn't help then it might be related to atheros bitrate/fixrates/framerate/pstream settings or the like. Or maybe some IRQ handlers aren't called often enough to process incoming data.
Re: DSi Wifi rev-engineering
by on (#230254)
NDS-Wifi upload speed is about 110 Kbyte/s (ideally should be 200Kbyte/s).
DSi-Wifi upload speed is about 150 Kbyte/s (ideally should be 5000Kbyte/s).

That's both not so good. At least DSi is slightly "faster" than NDS, but it's ways slower than it should be. One problem is that if I try to use DMA or faster memory, then transfers stop working, or become unreliable/slower. I thinks that's related to the SDIO hardware: SDIO commands can have multiple 80h-byte blocks, and it seems that one must wait for "something" between separate blocks.
As for "something", that's unfortunately unknown. Looking at DSi browser, it's using NDMA with SDIO_DATA32 mode for dealing with multiple blocks, so that's probably the way to go, hoping that NDMA will automatically use the correct timings. If there's a way to poll any "next block ready" flags for manual timings then I don't know about it yet.

For now, I switched to some other stuff: The code is now auto-detecting if the DSi's SDIO registers exist (and are enabled), and automatically switches between NDS-Wifi and DSi-Wifi accordingly. That's working... but brought up another small problem: The program currently tends to hang after upload's on NDS consoles (or DSi's in NDS mode). I didn't have had that problem some months ago, looks as if some newer changes have broken NDS compatibility.

Next Problem: My new DSi-Wifi code was for WEP only, so I've logged initialization for open networks and WPA networks today.
Open network is simple: It does simply skip the four ADD_CIPHER_KEY commands, and sends the CONNECT command (with only three parameter bytes different as than for WEP).

WPA network is nightmarish. It's ways more complicated than WEP. For WEP one just uses ADD_CIPHER_KEY and CONNECT, and everything is done automatically. Theoretically, WPA should work the same, but instead, it's using CONNECT (without setting any cipher keys yet), and then it's using twelve Data RX/TX commands for manually exchanging data with the access point, and throws in two ADD_CIPHER_KEY commands inbetween of that data transfers. And worst, the WPA password doesn't show up anywhere in that process, apparently one is supposed to encrypt the password manually (or convert it to SHA256 or so) (the ADD_CIPHER_KEY commands have key length set to 32 bytes, despite of the actual ASCII password being shorter).

Below is the WPA connection sequence. Please let me know if somebody can make sense of it, or can point me on helpful documents or source code! The CMD/EVENT stuff is more or less clear (apart from ADD_CIPHER_KEY_CMD not containing plaintext passwords). But I've no idea what the twelve "Data #1..#12" packets are supposed for. At the moment, I am feeling a bit overhelmed by unexpected problems - I hope some of it will sort out tomorrow.
Code:
connection details:
 access point:     fritzbox (with SSID "ead")
 encryption:       WPA-PSK(TKIP)
 password:         ernstaugustdeich
 modus:            infrastruktur
 groupkeyinterval: 3600 seconds
 MAC for DSi       mm mm mm mm mm mm
 MAC for AP        aa aa aa aa aa aa
 MAC for router    bb bb bb bb bb bb

MBOX traffic for sdio_connect sequence:
 (preceeded by usual channel scanning stuff)
 Write WMI_TARGET_ERROR_REPORT_BITMASK_CMD +2008h    01 01 06 00 08 20  22 00 7F 00 00 00
 Write WMI_SET_BSS_FILTER_CMD                        01 01 0A 00 00 00  09 00 00 00 00 00 00 00 00 00
 Write WMI_SET_PROBED_SSID_CMD                       01 01 25 00 00 00  0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 Write WMI_SET_SCAN_PARAMS_CMD                       01 01 16 00 00 00  08 00 FF FF FF FF FF FF C8 00 C8 00 00 05 C8 00 00 00 00 00 00 00
 Write WMI_SET_CHANNEL_PARAMS_CMD                    01 01 08 00 00 00  11 00 00 00 02 01 9E 09
 Write WMI_SET_BITRATE_CMD                           01 01 05 00 00 00  00 F0 FF 00 00
 Write WMI_SET_AP_PS_CMD                             01 01 06 00 00 00  48 00 01 A4 F7 FF
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 00
 Write WMI_SET_POWER_MODE_CMD                        01 01 03 00 00 00  12 00 02
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 00
 Write WMI_CREATE_PSTREAM_CMD                        01 01 41 00 00 00  05 00 14 00 00 00 14 00 00 00 7F 96 98 00 FF FF FF FF 00 00 00 00 00 45 01 00 00 45 01 00 00 45 01 00 00 00 00 00 00 00 00 00 80 8D 5B 00 00 20 00 00 00 00 00 00 D0 80 D0 00 00 02 FF 01 00 05 00
 Write WMI_SET_WSC_STATUS_CMD                        01 01 03 00 00 00  41 00 00
 Write WMI_SET_DISCONNECT_TIMEOUT(_CMD)              01 01 03 00 00 00  0D 00 02
 Write WMI_SET_TKIP_COUNTERMEASURES_CMD  !!!         01 01 03 00 00 00  20 00 00
 Write WMI_SET_BSS_FILTER_CMD                        01 01 0A 00 00 00  09 00 00 00 00 00 00 00 00 00
 Write WMI_SET_SCAN_PARAMS_CMD                       01 01 16 00 00 00  08 00 FF FF FF FF FF FF C8 00 C8 00 00 05 C8 00 00 00 00 00 00 00
 Write WMI_SET_CHANNEL_PARAMS_CMD +2008h             01 01 08 00 08 20  11 00 00 00 02 01 9E 09
 Write WMI_SET_KEEPALIVE_CMD                         01 01 03 00 00 00  3D 00 00
 Write WMI_CONNECT_CMD      ;<----------             01 01 36 00 00 00  01 00 01 01 03 03 00 03 00 03 65 61 64 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9E 09 aa aa aa aa aa aa 00 00 00 00   ;connect to "ead"
 Read  WMIX_DBGLOG_EVENT                             01 00 E2 05 00 00  10 10 08 30 00 00 00 00 00 00 F1 05 2C 44 08 30 00 00 2C 06 29 84 07 00 00 00 14 00 00 00 2C 06 06 A4 ...
 Write WMIX_HB_CHALLENGE_RESP_CMD          +0101h    01 01 0E 00 01 01  2E 00 08 20 00 00 02 00 00 00 00 00 00 00
 Read  WMIX_HB_CHALLENGE_RESP_EVENT                  01 02 16 00 08 00  10 10 07 30 00 00 02 00 00 00 00 00 00 00 02 06 00 00 02 0C 00 00
 Delay 0009 till IRQ
 Read  WMI_CONNECT_EVENT    ;<----------             01 02 7F 00 08 00  02 10 9E 09 aa aa aa aa aa aa 64 00 64 00 01 00 00 00 1A 31 16 DD 18 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02 00 00 11 04 01 00 00 03 65 61 64 01 08 82 84 8B 0C 12 96 18 24 32 04 30 48 60 6C DD 16 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02 51 04 00 00 01 C0 01 08 82 84 8B 0C 12 96 18 24 32 04 30 48 60 6C 00 02 06 00 00 00 00 00 00    ;for "ead"
 Read  Data #1 read                                  02 02 83 00 08 F4  3B 00 mm mm mm mm mm mm aa aa aa aa aa aa 00 6B AA AA 03 00 00 00 88 8E 01 03 00 5F FE 00 89 00 20 00 00 00 00 00 00 00 01 0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 06 00 A5 A5 01 00 00
 Write Data #2 write                                 02 00 93 00 00 00  00 1C aa aa aa aa aa aa mm mm mm mm mm mm 00 83 AA AA 03 00 00 00 88 8E 01 03 00 77 FE 01 09 00 20 00 00 00 00 00 00 00 01 B1 F9 1C 00 66 00 55 8F 42 F7 07 F4 00 01 10 01 01 27 40 00 00 00 00 00 7F 06 9C 6C FF 2F B6 C7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1B 1E 61 E7 C3 1F CF 0D 88 9F 7B E9 27 4B 80 AA 00 18 DD 16 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02
 Read  Data #3 read                                  02 02 A1 00 0C F4  3B 00 mm mm mm mm mm mm aa aa aa aa aa aa 00 85 AA AA 03 00 00 00 88 8E 01 03 00 79 FE 01 C9 00 20 00 00 00 00 00 00 00 02 0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30 7A 4F 98 41 29 D5 BF 43 04 58 74 E2 3E 8E 10 00 1A DD 18 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02 00 00 01 02 02 01 02 06 00 14 00 0A 00 00
 Write Data #4 write                                 02 00 7B 00 00 00  00 1C aa aa aa aa aa aa mm mm mm mm mm mm 00 6B AA AA 03 00 00 00 88 8E 01 03 00 5F FE 01 09 00 20 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 95 53 EE 13 CE 18 28 7C 50 87 C1 78 54 67 E4 B7 00 00
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 01
 Write Data #5 write n/a +0204h                      02 01 02 00 00 00  04 02
 Write Data #6 write n/a +0204h                      02 00 02 00 00 00  04 02
 Write WMI_ADD_CIPHER_KEY_CMD      ;<---             01 01 2F 00 00 00  16 00 00 03 00 20 00 00 00 00 00 00 00 00 07 A2 68 3A DF B2 B5 29 2F 82 70 8E 0F C0 CB 0E 9B 5F AE 0F 0F EB 79 18 F2 BC 3A FA EA 12 FB 3C 03
 Read   (handshake with len=0Eh) (acklen=4) (!!!)    00 02 0E 00 0E 00  01 04 01 01 02 01 02 06 00 00 00 00 00 00  ;(this isn't WPA related, just interesting because it does deliver a "Cmd.ack" and "Data.ack" in the same packet)
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 01
 Read  Data #7 read                                  02 02 A3 00 08 F4  3B 00 mm mm mm mm mm mm aa aa aa aa aa aa 00 8B AA AA 03 00 00 00 88 8E 01 03 00 7F FE 03 A1 00 20 00 00 00 00 00 00 00 03 0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D8 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 DA 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 8B 0D 67 18 1E B2 81 48 02 9D 84 6A 0B DC 03 48 00 20 04 4C 38 D8 37 85 D8 75 D2 C7 AD 15 F9 F8 32 78 96 BE 01 97 0C 5F 9F A9 6E B6 9C 5B 3C 3C 5B 16 02 06 00 DB 2A 92 8A 00
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 01
 Write Data #8 write n/a +020Dh                      02 00 02 00 00 00  0D 02
 Write Data #9 write n/a +0209h                      02 00 02 00 00 00  09 02
 Write WMI_ADD_CIPHER_KEY_CMD      ;<---             01 01 2F 00 00 00  16 00 02 03 01 20 00 00 00 00 00 00 00 00 44 9B 5A DC 41 27 79 2E ED 65 AA 1F D3 65 36 2F 02 A4 1B DD B8 2B 2F 39 84 D0 69 6F 46 E4 55 53 03
 Write WMI_SYNCHRONIZE_CMD                           01 01 03 00 00 00  04 00 01
 Write Data #10 write                                02 00 7B 00 00 00  00 1C aa aa aa aa aa aa mm mm mm mm mm mm 00 6B AA AA 03 00 00 00 88 8E 01 03 00 5F FE 03 21 00 20 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70 A2 B7 B0 78 07 D3 67 C8 1B C9 ED 4B 55 20 E1 00 00
 Delay 001A till IRQ
 Read  WMI_NEIGHBOR_REPORT_EVENT                     01 02 16 00 0C 00  08 10 01 aa aa aa aa aa aa 00 01 02 02 01 02 06 00 00 1A 31 16 00
 Delay 0010 till heartbeat
 Write WMIX_HB_CHALLENGE_RESP_CMD          +0101h    01 01 0E 00 01 01  2E 00 08 20 00 00 03 00 00 00 00 00 00 00
 Read  WMIX_HB_CHALLENGE_RESP_EVENT                  01 02 16 00 08 00  10 10 07 30 00 00 03 00 00 00 00 00 00 00 02 06 00 00 1A 31 16 00
 Delay 0006 till IRQ
 Read  Data #11 read                                 02 02 4E 00 08 00  3B 00 01 00 5E 00 00 01 bb bb bb bb bb bb 00 36 AA AA 03 00 00 00 08 00 46 00 00 20 00 00 40 00 01 02 43 2D C0 A8 01 01 E0 00 00 01 94 04 00 00 11 0A EE F5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 06 00 CC 65 A2 27 00
 Delay 000B till IRQ
 Read  Data #12 read                                 02 02 40 00 08 7F  3C 00 01 00 5E 7F FF FA bb bb bb bb bb bb 00 28 AA AA 03 00 00 00 08 00 46 00 00 20 00 00 40 00 01 02 33 2E C0 A8 01 07 EF FF FF FA 94 04 00 00 16 00 FA 04 EF FF FF FA 02 06 00 25 16 2F E3 00
 (followed by usual DHCP stuff)
Re: DSi Wifi rev-engineering
by on (#230318)
I've logged WPA2-PCK-AES, too. It's very similar to the above WPA-PCK-TKIP log, up to even issuing the TKIP countermeasures command. Differences spotted are: Some changed bytes in CONNECT command. The two CIPHER keys are only 16bytes for WPA2-AES (unlike 32bytes for WPA-TKIP). And the "Data #7 read" and "Data #10 write" are missing in the WPA2 log.

I haven't found a good reference to nail down the Data stuff. Though it's probably described somewhere in some x-hundred pages IEEE document. Some vague info that I've gathered is that WPA and/WPA2 are using a 4-stage handshake; that might be related to Data #1..#4? Those four packets have protocol ID 888Eh (after the SNAP/LLC header), which seem to be related to something called EAPOL or IEEE 802.1X.

Data #7 and #10 do also have ID 888Eh, but they exist for WPA only (not WPA2), so WPA looks more like a 6-stage handshake, not 4-stage.

Then Data #5,#6,#8,#9 writes aren't having any data body, and don't even have src/dst MAC addresses. They do merely have the unknown halfword, which is usually 0000h (or 1C00h for ARP packets?), and in this case it's 0204,020Dh,0209h. One guess would be that it does clear all cached RX/TX packets. Or maybe changing filtering, selecting which packets are desired to be received? Or maybe it does activate encryption of the following packets.

Data #11,#12 reads do receive something, but the browser doesn't seem to take any actions in response (like sending reply data, or sending WMI commands). Instead, the browser is just sending the DHCP packets in the next step, so it looks as if one could just ignore data #11..#12. Hmmm, for WPA2, there's also another data read inserted, preceeding #11.

So, the important part would be understanding Data #1..#4 (and #7,#10 if present), knowing the meaning of the bytes after the SNAP/LLC header (after the "AA AA 03 .." bytes), and knowing what to do with those bytes, like passing them through SHA-something maybe (or some document mentioned MD5 being WPA related). Uhm, or is that key-initialization step more likely being done through AES and TKIP, for WPA2-AES and WPA-TKIP accordingly?

AES would be easy as DSi is using that elsewhere, too, so I am familar with it. For TKIP I've no idea what it's doing internally, and how to implement it in software (or is it just a variation of the RC4 (WEP) cipher? that would be relative easy).
Re: DSi Wifi rev-engineering
by on (#230349)
I've tried to break down the data packets, there seem to be several 32-byte fields (or maybe they contain two 16-byte fields or whatever).

And the four WPA2 data packets:
Code:
---------------------------------------------------------------------------------------------------------
WPA2 Data #1 read
  8    WMI header (02 02 83 00 08 F4  32 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 5F)
  12   ?  02 00 8A 00 10 00 00 00 00 00 00 00
  1    ?  01
  32   ?  32 0A B2 DC 9B AB CE 36 B4 B1 6E DF 4B 76 62 00 9C 41 90 12 64 17 4A 4F C6 28 0C 89 BF 73 54 90
  32   ?  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  16   ?  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  2    ?  00 00
  8    WMI handshake info (02 06 00 3B 3B 00 00 00)
---------------------------------------------------------------------------------------------------------
<snip> EDIT: see next post for better break down


And the six WPA data packets:
Code:
---------------------------------------------------------------------------------------------------------
WPA Data #1 read
  8    WMI header (02 02 83 00 08 F4  3B 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03              ;version, type?
  2    Length (00 5F)
  12      FE 00 89 00 20 00 00 00 00 00 00 00
  1    ?  01
  32   ?  0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D9
  32   ?  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  16   ?  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  2    ?  00 00
  8    WMI handshake (02 06 00 A5 A5 01 00 00)
---------------------------------------------------------------------------------------------------------
<snip> EDIT: see next post for better break down

I've had a look at IEEE 802.1X-2001 and IEEE 802.1X-2010, but didn't spot any eye-catching tables that would match up with the data packets. The documents contain several references to RFC documents, so maybe the required info is hiding there. And the 2001 version mentions MD5, the newer 2010 version does doesn't mention MD5 at all, so that file seems to be useless (and to new for the DSi anyways). There should be also a IEEE 802.1X-2004 version, and possibly also -2007, but they don't seem to be available for downlaod; at least not on webpages compatible with my PC : /
Re: DSi Wifi rev-engineering
by on (#230355)
Ah, now I've found the matching specification:
IEEE Std 802.11i-2004
I still had that in a file on my harddisk from NDS-Wifi days, and it's called "11i" (not "1x").

Now the WPA2 packets look as so:
Code:
---------------------------------------------------------------------------------------------------------
WPA2 Data #1 read
  8    WMI header (02 02 83 00 08 F4  32 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 5F)
  1    Descriptor Type    (02)
  2    Key Information    (00 8A)
  2    Key Length         (00 10)
  8    Key Replay Counter (00 00 00 00 00 00 00 01)
  32   Key Nonce          (32 0A B2 DC 9B AB CE 36 B4 B1 6E DF 4B 76 62 00 9C 41 90 12 64 17 4A 4F C6 28 0C 89 BF 73 54 90)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  2    Key Data Length    (00 00)
  8    WMI handshake info (02 06 00 3B 3B 00 00 00)
---------------------------------------------------------------------------------------------------------
WPA2 Data #2 write
  8    WMI header (02 00 91 00 00 00  00 1C)
  12   MAC addresses (aa aa aa aa aa aa mm mm mm mm mm mm)
  2    Length (00 81)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 75)
  1    Descriptor Type    (02)
  2    Key Information    (01 0A)
  2    Key Length         (00 00)
  8    Key Replay Counter (00 00 00 00 00 00 00 01)
  32   Key Nonce          (A8 DC C3 00 67 00 55 8F 49 F7 07 F4 00 01 10 01 60 16 15 00 00 00 00 00 7F 06 9C 6C FF 2F 61 22)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (B9 FA 85 43 28 AC 29 67 36 A8 1E 44 6E 69 08 E9)
  2    Key Data Length    (00 16)
  ..   Key Data           (30 14 01 00 00 0F AC 04 01 00 00 0F AC 04 01 00 00 0F AC 02 00 00)
---------------------------------------------------------------------------------------------------------
WPA2 Data #3 read
  8    WMI header (02 02 BF 00 0C F4  33 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 A3)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 97)
  1    Descriptor Type    (02)
  2    Key Information    (13 CA)
  2    Key Length         (00 10)
  8    Key Replay Counter (00 00 00 00 00 00 00 02)
  32   Key Nonce          (32 0A B2 DC 9B AB CE 36 B4 B1 6E DF 4B 76 62 00 9C 41 90 12 64 17 4A 4F C6 28 0C 89 BF 73 54 90)  ;<-- same as in #1
  16   EAPOL Key IV       (A6 A6 A6 A6 A6 A6 A6 A6 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (05 85 CB E1 56 2B 42 10 A8 5D 54 F8 2A ED 50 4D)
  2    Key Data Length    (00 38)
  ..   Key Data           (34 FC 74 21 0D BB C0 B9 89 E2 D9 D4 B4 58 E1 67 7B D0 9B BC 31 C8 42 0A 97 0D AD A1 11 7A E3 48 48 BF B5 FB 48 69 45 D0 CF F1 49 24 EE 90 D8 5B 61 7B 3E 31 67 24 E9 41)
  4    WMI handshake info (01 02 02 01)
  8    WMI handshake info (02 06 00 2F 00 DD 1E 00)
---------------------------------------------------------------------------------------------------------
WPA2 Data #4 write
  8    WMI header (02 00 7B 00 00 00  00 1C)
  12   MAC addresses (aa aa aa aa aa aa mm mm mm mm mm mm)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 5F)
  1    Descriptor Type    (02)
  2    Key Information    (03 0A)
  2    Key Length         (00 00)
  8    Key Replay Counter (00 00 00 00 00 00 00 02)
  32   Key Nonce          (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (DE 4B 9C F1 B8 C3 D3 D0 04 2F 49 8B 97 12 23 C2)
  2    Key Data Length    (00 00)
---------------------------------------------------------------------------------------------------------


And WPA packets are also matching the same format (yet with different "descriptor type", "key information", and different "key length"):
Code:
---------------------------------------------------------------------------------------------------------
WPA Data #1 read -- matches "IEEE Std 802.11i-2004"
  8    WMI header (02 02 83 00 08 F4  3B 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03              ;version, type?
  2    Length (00 5F)
  1    Descriptor Type    (FE)
  2    Key Information    (00 89)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 01)
  32   Key Nonce          (0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D9)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  2    Key Data Length    (00 00)
  8    WMI handshake (02 06 00 A5 A5 01 00 00)
---------------------------------------------------------------------------------------------------------
WPA Data #2 write
  8    WMI header (02 00 93 00 00 00  00 1C)
  12   MAC addresses (aa aa aa aa aa aa mm mm mm mm mm mm)
  2    Length (00 83)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?                  (01 03)
  2    Length             (00 77)
  1    Descriptor Type    (FE)
  2    Key Information    (01 09)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 01)
  32   Key Nonce          (B1 F9 1C 00 66 00 55 8F 42 F7 07 F4 00 01 10 01 01 27 40 00 00 00 00 00 7F 06 9C 6C FF 2F B6 C7)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (1B 1E 61 E7 C3 1F CF 0D 88 9F 7B E9 27 4B 80 AA)
  2    Key Data Length    (00 18)
  24   Key Data           (DD 16 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02)
---------------------------------------------------------------------------------------------------------
WPA Data #3 read
  8    WMI header (02 02 A1 00 0C F4  3B 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 85)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 79)
  1    Descriptor Type    (FE)
  2    Key Information    (01 C9)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 02)
  32   Key Nonce          (0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D9)  ;<-- same as in #1
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (30 7A 4F 98 41 29 D5 BF 43 04 58 74 E2 3E 8E 10)
  2    Key Data Length    (00 1A)
  26   Key Data           (DD 18 00 50 F2 01 01 00 00 50 F2 02 01 00 00 50 F2 02 01 00 00 50 F2 02 00 00)
  4    WMI handshake (01 02 02 01)
  8    WMI handshake (02 06 00 14 00 0A 00 00)
---------------------------------------------------------------------------------------------------------
WPA Data #4 write
  8    WMI header (02 00 7B 00 00 00  00 1C)
  12   MAC addresses (aa aa aa aa aa aa mm mm mm mm mm mm)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 5F)
  1    Descriptor Type    (FE)
  2    Key Information    (01 09)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 02)
  32   Key Nonce          (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (95 53 EE 13 CE 18 28 7C 50 87 C1 78 54 67 E4 B7)
  2    Key Data Length    (00 00)
---------------------------------------------------------------------------------------------------------
WPA Data #7 read (this NOT for WPA2 !!!)
  8    WMI header (02 02 A3 00 08 F4  3B 00)
  12   MAC addresses (mm mm mm mm mm mm aa aa aa aa aa aa)
  2    Length (00 8B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 7F)
  1    Descriptor Type    (FE)
  2    Key Information    (03 A1)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 03)
  32   Key Nonce          (0A E4 4D E8 8F 91 BA DA 89 73 78 7E 46 AF 28 97 9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 D8)
  16   EAPOL Key IV       (9E C7 97 80 A7 20 4B 53 71 F6 27 F7 62 A7 B4 DA)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (8B 0D 67 18 1E B2 81 48 02 9D 84 6A 0B DC 03 48)
  2    Key Data Length    (00 20)
  26   Key Data           (04 4C 38 D8 37 85 D8 75 D2 C7 AD 15 F9 F8 32 78 96 BE 01 97 0C 5F 9F A9 6E B6 9C 5B 3C 3C 5B 16)
  8    WMI handshake (02 06 00 DB 2A 92 8A 00)
---------------------------------------------------------------------------------------------------------
WPA Data #10 write (this NOT for WPA2 !!!)
  8    WMI header (02 00 7B 00 00 00  00 1C)
  12   MAC addresses (aa aa aa aa aa aa mm mm mm mm mm mm)
  2    Length (00 6B)
  8    LLC/SNAP (AA AA 03 00 00 00 88 8E)
  2    ?  01 03
  2    Length (00 5F)
  1    Descriptor Type    (FE)
  2    Key Information    (03 21)
  2    Key Length         (00 20)
  8    Key Replay Counter (00 00 00 00 00 00 00 03)
  32   Key Nonce          (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  16   EAPOL Key IV       (00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00)
  8    Key RSC            (00 00 00 00 00 00 00 00)
  8    Reserved           (00 00 00 00 00 00 00 00)
  16   Key MIC            (70 A2 B7 B0 78 07 D3 67 C8 1B C9 ED 4B 55 20 E1)
  2    Key Data Length    (00 00)
---------------------------------------------------------------------------------------------------------
Re: DSi Wifi rev-engineering
by on (#230476)
Some recent findings and ups & downs... if it's too much blah-blah-text: Just skip to the "Todo" part (and best give some advice about the missing cipher).

PDF's are always ugly, and I know that the format isn't made for screen-viewing, but IEEE Std 802.11i-2004 is even uglier as it has enabled all nag & gag features: It's using super-small font, and automatically defaults to using a window with only half screen height, and prevents scrolling across page boundaries, and invokes sudden monster-zooming when accidentally hitting the mouse button - I really don't what the features are good for, and why anyone would enable them, except maybe for mimmicking open standards and/or for claiming ownership of something without actually sharing legible information : /
Hmmmm, the only way to view sections of the document seems to be to copy/paste separate pages into a text editor, and then manually fix the formatting & indents.
Well, and the actual content of the document... the stuff that I am interested in is somewhere in the middle of the doc, but it isn't described very well. It's kinda useless, unless when combining it with the reference code in the appendices. And even then, the reference code doesn't match up with the descriptions in the document. And the wonderful reference code kinda looks as if was neever tested in practice (like passing 6 parameters to a function that accepts only 5 parameters).
The descriptions in the other chapters are also somewhat unclear and bugged, in one place they've declared to compute a MIC (=checksum) starting "at including bit0-2" of a big-endian number (hah?) (interesting problem, that could mean anything, but the answer to that problem turned out to be irrelevant - because, what they've really meant was starting "at including the 5 bytes preceedng" that big-endian number).
The two sections worth reading are the glossary and the hex numbers shown in test cases; that two sections are containing more practially/useful info than the rest of the document.

Keys, there are lots of keys used, and it took some days to get a rough idea what they are used for (and if or how they do relate to the actual wifi password).
The first key needed is the 32-byte PSK: This is calculated by passing the Password and SSID through some SHA1-HMAC function. In total it does requires 8192 executions of the SHA1-HMAC function, which can get quite slow, especially when doing it on ARM7 side. If needed, the calculation could be made about twice as fast by pre-computing the HMAC key only once per 4096 calculations. But, the good thing is that Nintendo has fortunately pre-compted the KSK, and stored it in Wifi-FLASH (alongsides with the original password).
The next key needed is the 32-byte PMK, which is just the same as the PSK, so that one is easy. The next key is 48-byte PTK, this is also computed using three or four SHA1-HMAC's across the PSK (aka PMK) and the BSSID and DSi MAC address, and the two "Nonce" values from the Data #1 and #2 packets.
And then, 16-byte KCK, KEK, and TK are simply the first, middle, last 16-byte fragments of the 48-byte PTK. I've meanwhile managed to compute all those keys, and to use the KCK to verify the SHA1-HMAC (aka MIC checksum) in the Data #2 packet.

Some Oddities are that the reference code implies using SHA1-HMAC for WPA and WPA2, but other sections of the document suggest using MD5-HMAC for WPA, which, I guess that's actually so, and it's making things a bit more difficult as the DSi BIOS has a SHA1 function, but no MD5 function, so I'll have to code MD5 myself (a bit uncomfortable, and consuming lots of memory when using unrolled code).
Yet elsewhere, the document suggests the MIC values not being computed via SHA1 nor MD5, but rather by a scary function named Michael (which, I guess that's just nonsense, or maybe it applies only for the lower-level data-traffic, but not for the initial key-handshake needed for DSi). Anyways, it makes me wonder if the IEEE people were some kind of fundamentalists, threatening the archangel to rightfully kill you with his sword, if you were sneaking for free internet from their precious wifi-network.

RSA: One thing that is intensely used on DSi is RSA. And, interestingly, WPA/WPA2 are badly missing any such private/public key mechanism. That's weird, maybe RSA wasn't so popular back in 2004? Or hardware was too slow? Probably not. WPA and WPA2 do use "different" encryption keys per user, but they differ only in relation to the MAC addresses and Nonce values exchanged in the unencrypted handshake. Well, and on the SSID and Password, but that are usually known to all members of the network (ie. friends & family & roommates & neighbors). Of course, the other network members are "not supposed" to use your handshake data, but if they wanted to spy on you, then I can't see anything that would prevent them from doing so.
In that context, WPA and WPA2 don't give so much more privacy than open networks, the main "benefit" is preventing people without passwords from using the internet for free.
On the other hand, wired LAN isn't encrypted either, so that's having similar privacy issues.

Firmware: I also had a look at the AR6002 wifi-firmware, checking if it's really not supporting automatic connection: There's a MD5-HMAC function in there, but it's left unused, and doesn't even have it's function vectors installed (and SHA1-HMAC is missing completely). So it looks as if they were originally planning to add auto-connection on firmware-side, and then moved the code to driver-side, which might have some advantages (if one were having a "driver+fimware" combo), but it's not so comfortable on the DSi (with driverless "romimage+firmware" combo).

Todo: I still need one of the actual keys for ADD_CIPHER. The first ADD_CIPHER command is simply using KEK TK (the last bytes of the PTK). But I haven't yet found out where the bytes for second ADD_CIPHER are from. Maybe it's from the TK KEK (but it doesn't match up)? Or from the GMK and GTK stuff mentioned in the docs? Though I've no idea if GMK/GTK exist in the 4-way handshake seen in the WPA2 log at all (they might exist only in 6-way handshake seen in WPA log). Or the missing cipher might come from the "Key Data" field in the handshake packets...
I've no clue what that "Key Data" is supposed to be used for. Comparing the official docs with the values spotted in Data #2 packet:
Code:
  1st byte - Should be DDh - that's true for WPA log, but not so for WPA2 log
  2nd byte - Should be Length - that's true
  3rd-5th byte - Should be OUI value 00-0F-AC - that's wrong (WPA has 00-50-F2 in there, and WPA2 does have 00-0F-AC, but that's in 5th-7th byte)
  6th byte - Should be a cipher suite, whatever why one would need that value
  7th-last byte - Should be whatver/unspecified (in practice it's just repeating the above whatever OUI stuff)

Okay, that looks all wrong, and almost certainly totally useless. However, Data #3 has some more "Key Data" in there (about 38h bytes), and it's encrypted. I just don't know if it's worth decrypting. If it's the same useless OUI stuff then it could just be ignored. Some of the extra bytes might be a 16-byte AES-CTR-MAC checksum (which could be ignored, too). Well, and maybe the missing cipher key is in the remaining bytes, or maybe not.
I am afraid that I'll need to give it a try, and check how the decrypted data looks like. In theory, ARM7 has AES decryption hardware, but it does (probably) require endian-adjustment, and Nintendo's AES-CTR-MAC implementation seems to be a bit non-standard, so it might be unable to decrypt anything at all - and might require to implement AES decryption by software : /
Re: DSi Wifi rev-engineering
by on (#230527)
Got it. The "Key Data" isn't using AES-CCM at all, instead it's encrypted using "AES Key wrap" (and requires "unwrap" to decrypt it).
I've got the "Key Data" from WPA2 Data #3 decrypted (using 80x86 code), and actually found the values for 2nd ADD_CIPHER in there.
The DSi hardware doesn't support "raw AES decrypt" (only AES-CTR and AES-CCM), so I'll definetly need to implement AES in software.

I think I have now found all major stuff needed for WPA2. What's still missing is understanding WPA, I guess it's using MD5 instead of SHA1, and RC4 instead of the AES Key wrap, well, and if that is working, then one could probably also implement WPA on NDS (which would bring up more problems on figuring out the lower-level packet structure for WPA).
Re: DSi Wifi rev-engineering
by on (#230847)
WPA2 and WPA are now more or less working with DSi-Wifi!

I've tested WPA2 on three access points. Two are working fine, the third is successfully passing WPA2 handshakes and exchanging DHCP data packets, but, thereafter, somehow refuses to respond to wifiboot broadcast messages.
I've also tested one of the access points in WPA mode, that's working fine, too. Except, the console somehow gets stunned when hitting the power button after WPA uploads: Wifi stops working, even when switching power off for several minutes. Must be some warmboot flag lurking in memory, one workaround is running the Launcher to resurrect wifi, but I hope I'll find a better solution for that.

There are still a dozen smaller issues, and one major issue would be increasing the transfer speed via NDMA. Plus some work on documenting the initialization sequence, and the parameters for WMI messages.
Re: DSi Wifi rev-engineering
by on (#231309)
I've rewritten the MBOX Transfer Headers with new findings added:
Code:
MBOX Send Header/Body
  00h 1    Type        (00h=BootInfo, 01h=WMI Command, 02h=Data Packet)
  01h 1    Request Ack (00h=No, 01h=Yes)
  02h 2    Length of entries [06h..end]  (LEN)
  04h 2    ?
  06h LEN  Body (BootInfo/Event/Data)
  ..  ..   Padding to 80h-byte boundary (for SDIO block size 80h)
Send Body for BootInfo:
  06h ..   related to BE/BK/VI/VO stuff (best effort, background, video, voice)
Send Body for WMI Commands:
  06h 2  WMI Command Number
  08h .. Parameters
Send Body for Data Packets:
  06h 2  <Unknown6>?? 0000h or 1C00h    ;maybe whatever ?
  08h 6  Destination (MAC Addr of Router) (or FF:FF:FF:FF:FF:FF=Broadcast)
  0Eh 6  Source      (MAC Addr of DSi console)
  14h 2  Length Data at [16h...]  ;(LEN1-10h)   ;<-- BIG-ENDIAN !!!
  16h .. Data (usually starting with LLC stuff, ie. AAh,AAh,03h,00h...)
Send Body for empty Data Packets (used when changing WPA/WPA2 CIPHER keys):
  06h 1  Garbage (usually LSB of a previously used WMI command number)
  07h 1  Unknown (02h)

MBOX Receive Header/Body
  00h      1    Type        (00h=Ack only, 01h=WMI Event, 02h=Data Packet)
  01h      1    Ack Present (00h=No, 02h=Yes)
  02h      2    Length of entries [06h..end]     (LEN1+LEN2)
  04h      1    Length of Ack at [06h+LEN1..end] (LEN2) ;garbage when [01h]=00h
  05h      1    ? (00h,20h?,7Fh,F4h,FFh)
  06h      LEN1 Body (Event/Data)
  06h+LEN1 LEN2 Ack List
  ..       ..   Padding to 80h-byte boundary (for SDIO block size 80h)
Receive Body for Ack only:
  06h -  N/A (or boot request info; occurs only shortly after BMI)
Receive Body for Events:
  06h 2  WMI Event Number
  08h .. Parameters
Receive Body for Data Packets:
  06h 1  RSSI (Received Signal Strength Indicator) (00h..3Ch) (aka 0..60)
  07h 1  <Unknown7> 00h
  08h 6  Destination (MAC Addr of DSi console) (or FF:FF:FF:FF:FF:FF=Broadcast)
  0Eh 6  Source      (MAC Addr of Router)
  14h 2  Length of Data entries at [16h..(end-xtracrap)]   ;<-- BIG-ENDIAN !!!
  16h .. Data (usually LLC stuff, ie. AAh,AAh,03h.. or, once F0h,F0h,03h..??)
Ack List (can contain multiple List items):
  X+00h  List Item Type (01h=Ack, 02h=Lookahead)
  X+01h  List Item Len (02h*N for Ack's, 06h for Lookahead)
  X+02h  List Item data
Ack Items (can contain multiple Ack items):
  Y+00h  Ack Item Type (01h=Command Ack, 02h=Data Ack, 05h=Data Ack, too?)
  Y+01h  Ack Item Count? (usually 1) (or 2 for double-ack?)
Lookahead Item (if valid: allows to omit reading Func[1:00408h]):
  Z+00h  Lookahead valid ID1 (00h=No, 55h=Valid)
  Z+01h  Lookahead MBOX0 (or garbage if ID1/ID2 not valid)
  Z+05h  Lookahead valid ID2 (00h=No, AAh=Valid)

With that description, I can now recognize similar definitions in "htc.h", for example, what I've called "Ack List" is officially called "Trailer". And the "Ack Item Count" is apparently called "Credits". I guess one could send multiple data packets up to a certain buffer size limit, and use the Credits reply to determine how many of the sent-packets are already processed (no longer taking up buffer space).
Unfortunately, "htc.h" doesn't contain definitions for all bytes, eg. [05h] and [07h] are still unknown.
Re: DSi Wifi rev-engineering
by on (#231314)
And, here's a rundown on what values could found in EAPOL handshake messages, extracted from multiple sources.
Code:
Wifi WPA/WPA2 Handshake Messages (EAPOL)
----------------------------------------

4-Way Handshake and Group Key Handshake messages
For WPA, the Group Key Handshake occurs immediately after the 4-way Handshake
(effecitively making it a 6-way handshake). For WPA2, the Group Key is
contained in the 4-way Handshake, so the Group Key Handshake isn't needed.
For both WPA and WPA2, the access point may change the Group Key every once and
then, and invoke a new Group Key Handshake for the new key.

EAPOL Key Frame
This is preceeded by a LLC/SNAP header (AAh,AAh,03h,00h,00h,00h,88h,8Eh), the
888Eh in last two bytes indicates that following bytes to contain an EAPOL Key
Frame:
  00h  2    Version/Type (or Type/Version?) (01 03)
  02h  2    Length of [04h..end] (005Fh+LEN)                      ;BIG-ENDIAN
  04h  1    Descriptor Type (FEh=WPA, 02h=WPA2)
  05h  2    Key Information (flags, see below)                    ;BIG-ENDIAN
  07h  2    Key Length (0=None, 20h=TKIP, 10h=CCMP, 05h/0Dh=WEP)  ;BIG-ENDIAN
  09h  8    Key Replay Counter (usually 0 or 1 in first message)  ;BIG-ENDIAN
  11h  32   Key Nonce (ANonce/SNonce)
  31h  16   Key Data IV (RC4 uses IV+KEK) (not used for AES-Key-Wrap)
  41h  8    Key RSC (TSC/PN) (whatever, for GTK)               ;LITTLE-ENDIAN
  49h  8    Reserved (zerofilled)
  51h  16   Key MIC on [00h..end] (with MIC initially zerofilled)       ;HMAC
  61h  2    Key Data Length (LEN) (00 nn)                         ;BIG-ENDIAN
  63h  LEN  Key Data (can be encrypted in certain messages)

Key Information flags
  0-2   Key Descriptor Version (0=WPA/MD5/RC4, 1=WPA2/SHA1/AESkeywrap)
  3     Key Type (0=Group, 1=Pairwise)
  4-5   Reserved (0) or WPA Group Key Index (1 or 2)
  6     Install  (0=No, 1=Yes, configure temporal key)
  7     Key Ack  (0=No, 1=Yes, AP wants a reply; with same Key Replay Counter)
  8     Key MIC  (0=No, 1=Yes, key frame contains MIC)
  9     Secure   (0=No, 1=Yes, initial key-exchange complete)
  10    Error    (0=No, 1=Yes, MIC failure and Request=1)
  11    Request  (0=No, 1=Yes, request AP to invoke a new handshake)
  12    Encrypted(0=No, 1=Yes, Key Data is encrypted; via RC4 or AESkeywrap)
  13-15 Reserved (0)

Key Data
Key Data does usually consist of element(s) in following form:
  00h 1   Element ID (for WPA: DDh=RSNIE - for WPA2: 30h=RSNIE, DDh=KDE)
  01h 1   Element Length of [02h..end]
  02h ..  Element Data (OUI's etc.)
WPA and WPA2 assign different meanings to Element ID value DDh. The 3-byte
maker prefix in OUI values does also differ for WPA/WPA2. And, the meaning of
the OUI's varies depending on WHERE they are used (eg. 00-0F-AC-02 could be a
Cipher Suite entry, or an Authentication entry):
  EAPOL Descriptor Type values
  WPA          WPA2         Meaning
  FEh          02h          Indicates if ElementIDs and OUIs are WPA or WPA2
  EAPOL Key Information flags/values
  0089h        008Ah        Handshake #1  ;\
  0109h        010Ah        Handshake #2  ; 4-way Handshake
  01C9h        13CAh        Handshake #3  ;
  0109h(again) 030Ah        Handshake #4  ;/
  0391h/03A1h  1382h        Handshake #5  ;\Group Key Handshake
  0311h/0321h  0302h        Handshake #6  ;/
  EAPOL Key Data Element IDs
  DDh          30h          Element ID for RSNIE (Robust Network Security info)
  -            DDh          Element ID for KDE (Key Data Encapsulation)
  -            DDh          Element ID for padding (followed by 00h-bytes)
  RSNIE Version Prefix OUI's (WPA only):
  00-50-F2-01  -            RSNIE Version Prefix (followed by 2 bytes?)
  RSNIE Group Cipher suite selector OUI's (aka Multicast):
  00-50-F2-01  00-0F-AC-01  RSNIE Group Cipher WEP-40  (default for US/NSA)
  00-50-F2-02  00-0F-AC-02  RSNIE Group Cipher TKIP    (default for WPA)
  00-50-F2-04  00-0F-AC-04  RSNIE Group Cipher CCMP    (default for WPA2)
  00-50-F2-05  00-0F-AC-05  RSNIE Group Cipher WEP-104 (default for WEP)
  RSNIE Pairwise Cipher suite selector OUI's (aka Unicast):
  00-50-F2-00  00-0F-AC-00  RSNIE Pairwise Cipher None (WEP, Group Cipher only)
  00-50-F2-02  00-0F-AC-02  RSNIE Pairwise Cipher TKIP (default for WPA)
  00-50-F2-04  00-0F-AC-04  RSNIE Pairwise Cipher CCMP (default for WPA2)
  RSNIE Authentication AKM suite selector OUI's :
  00-50-F2-01  00-0F-AC-01  RSNIE Authentication over IEEE 802.1X
  00-50-F2-02  00-0F-AC-02  RSNIE Authentication over PSK
  KDE Key Data Encapsulation OUI's (WPA2 only):
  -            00-0F-AC-01  KDE GTK         (followed by 2+N bytes)
  -            00-0F-AC-02  KDE STAKey      (followed by 2+6+N bytes)
  -            00-0F-AC-03  KDE MAC address (followed by 6 bytes)
  -            00-0F-AC-04  KDE PMKID       (followed by 16 bytes)

RSNIE (Robust Network Security Information Element)
RSNIE allows to exchange information about the desired/supported encryption
methods. RSNIE is found in handshake message 2/3 (and also in Beacons). In most
cases one could just ignore the RSNIE stuff (eg. if Wifi FLASH is already
configured to use a specific cipher type). A special case might be networks
that use a weaker Group Cipher (for older devices) combined with offering
stronger Pairwise Ciphers (for devices that support them).
  WPA2 RSNIE (Robust Network Security Information Element):
  00h  1  Element ID (30h=RSNIE for WPA2)
  01h  1  Element Len of [02h..end] (usually 14h)
  02h  2  RSNIE Version 1                        (01 00)     ;WHATEVER-ENDIAN?
  04h  4  RSNIE Group Cipher Suite OUI (CCMP)    (00 0F AC 04)
  08h  2  RSNIE Pairwise Cipher Suite Count (1)  (01 00) (in  ;LITTLE-ENDIAN
  0Ah  4  RSNIE Pairwise Cipher Suite OUI (CCMP) (00 0F AC 04)
  0Eh  2  RSNIE Authentication Count (1)         (01 00)      ;LITTLE-ENDIAN
  10h  4  RSNIE Authentication OUI (PSK)         (00 0F AC 02)
  14h  2  RSNIE Capabilities                     (00 00)      ;LITTLE-ENDIAN?
  16h (2) RSNIE Optional PMKID Count  ;\usually none such     ;LITTLE-ENDIAN
  18h (16)RSNIE Optional PMKID's      ;/
  WPA RSNIE (Robust Network Security Information Element):
  00h  1  Element ID (DDh=RSNIE for WPA)
  01h  1  Element Len of [02h..end] (usually 16h or 18h)
  02h  4  RSNIE Version OUI (version)   (00 50 F2 01)       ;<-- WPA only
  06h  2  RSNIE Version value? (1)      (01 00)              ;WHATEVER-ENDIAN?
  08h  4  RSNIE Mcast OUI (TKIP)        (00 50 F2 02)
  0Ch  2  RSNIE Ucast Count (1)         (01 00)               ;LITTLE-ENDIAN
  0Eh  4  RSNIE Ucast OUI (TKIP)        (00 50 F2 02)
  12h  2  RSNIE Auth AKM Count (1)      (01 00)               ;LITTLE-ENDIAN
  14h  4  RSNIE Auth AKM OUI (PSK)      (00 50 F2 02)
  18h (2) RSNIE Capabilities maybe?     (00 00)               ;LITTLE-ENDIAN?
  RSN Capabilities flags (usually 0000h) (also spotted: 0C 00):
  0   RSN Pre-Auth capabilities
  1   RSN No Pairwise capabilities
  2-3 RSN PTKSA Replay Counters (0..3 = 1,2,4,16 replay counters)
  4-5 RSN GTKSA Replay Counters (0..3 = 1,2,4,16 replay counters)
  6   Managment Frame Protection Required
  7   Managment Frame Protection Capable
  8   Joint Multi-band RSNA
  9   PeerKey Enabled
  10  SPP A-MSDU Capable
  11  SPP A-MSDU Required
  12  PBAC
  13  Ext Key ID for Unicast
  14-15 Reserved (0)

KDE Key Data Encapsulation (or raw data for WPA)
KDE (or WPA's raw data) is mainly useful for transferring the GTK group key.
Note that Key Data in WPA2 message 3 contains both RSNIE and KDE GTK (and KDE
padding). Whilst the raw data in WPA cannot be mixed RSNIE.
  WPA2 KDE GTK (Key Data Encapsulation for Group Key, in encrypted Key Data):
  00h  1   Element ID (DDh=KDE for WPA2)
  01h  1   Element Len (16h)
  02h  4   KDE OUI GTK (00-0F-AC-01) (occurs in message 3/5)
  06h  1   KDE GTK Key ID (01h or 02h)      ;bit2: Tx ?
  07h  1   KDE GTK Reserved (00h)
  08h  16  KDE GTK Key GTK (for Key ID from above byte [06h])
  WPA2 KDE PKMID (Key Data Encapsulation for PKMID) (optional, not needed):
  00h  1   Element ID (DDh=KDE for WPA2)
  01h  1   Element Len (14h)
  02h  4   KDE OUI PMKID (00-0F-AC-04) (optionally occurs in message 1)
  06h  16  KDE PMKID (useless checksum on PMK, sometimes exposed in message 1)
  WPA2 KDE Padding (for padding Key Data to Nx8 bytes for AES-Key-wrap):
  00h  1   Element ID (DDh=KDE for WPA2)
  01h  0-6 Padding (00h) (aka Element Len=00h)
  WPA GTK (raw Group Key; without Element ID or KDE-style encapsulation):
  00h  16  Key GTK (for Key ID from Key Information bit4-5) (in message 5)

I hope that's more or less complete and covers all important stuff. I couldn't find specs for the endianness of RSNIE Version and RSNIE Capabilites, so I will leave that as unknown/undefined for now. If I should guess, I assume Version is little endian, ie. 01 00 meaning 0001h=v1 (or who knows, it might also mean 0100h=v1.00). And for Capabilities, there is (hopefully) some common practice to use a specific endiannes for it (at least one source suggests that it's meant being little endian).

I am still having problems to connect to one of my WPA2 access points.
One uncommon thing is that it does expose the KDE PMKID stuff in message 1 (my other access points don't do that). But I am quite that that's just some unimportant oddity.
The other uncommon thing is that it does report 0C 00 in RSNIE Capabilities. Which, that's pretty much unclear what it means (and if it's important at all).
If it's little endian, 000Ch, then the access point does have 16 PTK replay counters (probably referring to the "RSC/TSC", not to the EAPOL Replay Count) (though even if so, it's quite possible that the DSi doesn't need to care about whether the access point supports that many counters).
If it's big endian, 0C00h, then the access point does have/require SPP-A-MSDU, whatever that means, SPP seems to be some kind of "protection" and "A-MSDU" seems to be multiple-small-packets merged into one large packet.

The DSi browser can connect to that access point without problems - and apparently without using any special commands or parameters, regardless of the 0C 00 capabilities value. I start to suspect that the problem might be unrelated to handshakes & cipher keys - maybe the access point just dislikes the messages that I am sending during TCP accept or so.

Well, I could/should use something like wireshark to find out if my TCP messages are sent okay, and if the access point is sending any response to that messages. Though I don't really have any (good) experiences with wireshark... from what I remember, it dislikes my hardware (especially for capturing lower-level packets), and even if it's working, it tends to capture an overhelming amount of packets, so it might need quite some patience to dig through the captured data.
Re: DSi Wifi rev-engineering
by on (#231672)
Release!
http://problemkaputt.de/wifiboot.zip - wifiboot v2.4 (binary and source code)

Compatibility
WPA2 is still working with only 2 of 3 tested access points. When testing it, please let me know if it's working, or not working with your access point(s).

Transfer speed
When uploading the Eragon demo, I am reaching 300-500Kbytes/s (depending on daytime/noise in the neighborhood) when using a more distant access point, and, for reason, fairly constant 400Kbytes/s when using a closeby access point.
For comparision: NDS-Wifi is reaching about 60Kbytes/s (the measurement last month saying 110Kbyte/s was probably wrong, caused by lost vblank IRQs, which were used as timing reference).
The speed isn't perfect yet, but it's ways faster than NDS-Wifi (even if NDS would ever reach full 2MBit/s). Some things that helped to improve the speed were using NDMA (for SDIO-to-memory), and DMA for (for memory-to-memory), and WRAM (for the packet buffer), and, especially: setting the ARM7_RUNNING flag (else SDIO was handled only on vblank IRQs, not on SDIO IRQs, which had frustatingly caused more packets to get 'lost' (which did then cause slowdown whenever trying to speedup things)).
Next thing to try would be running ARM7 code in WRAM or VRAM instead of slow Main RAM, maybe that will boost the transfer speed a bit more.

How to use
Configure your access point in DSI System Settings --> Internet --> Advanced Setup (the advanced stuff supports WPA/WPA2).
Load wifiboot.nds (when using unlaunch: observe that it does contain a built-in older wifiboot version in eMMC, be sure to use the newer wifiboot version (loaded from SD card); if you want to use wifiboot more often, best assign a hotkey to it, or make it the boot default).
On PC side, you can use no$gba --> Utility --> Upload (and set Options --> Other --> Multiboot Port to "Dslink/Wifi"). Or use the dslink.exe commandline tool from devkitpro. Uploading should work for any nds/dsi homebrews that rely on using only their bootcode blocks (without loading further data from cartridge ROM after booting).

Todo
Now that WPA/WPA2 are working (including manually handling the EAPOL messages), there's no good reason not to implement WPA for NDS-Wifi, too. The main issue might be making a GUI for entering WPA passwords on NDS, apart from that it should only require some extra tweaking on manually adding the Extended IV and MIC to the WPA packets.
The DSi would benefit from a GUI, too (system settings are prompting to re-enter the password anytime when switching between WPA and WPA2, which is a bit uncomfortable for testing). Well, and I hope I'll get the transfer a bit faster, and fix the isssue with the non-working access point.

Source code
Copy the .zip contents to no$gba's "stuff" subfolder, then use Utility --> Assemble File --> wifiboot.a22 in no$gba. For use with other assemblers you would probably need to change hex numbers from 1234h to something like 0x1234 or #0x1234. I am wondering if anybody will be able or willing to do such things ; ) if you want to: maybe better wait a while and check back if there are newer updates/bugfixes before porting to source code to other formats.
Changes to the old NDS-Wifi code are marked "with_nds_wifi" and "with_dsi_wifi" (in wificore.a22). The new DSi-Wifi code is currently mostly located in wifiboot.a22 and wifisdio.a22 (I'll move that to wificore.a22 in future versions).

Thanks
Thanks to Stephen Stair for making the original NDS-Wifi library (dswifi) and to wintermute for the original wifi uploader (dslink).
Re: DSi Wifi rev-engineering
by on (#231896)
I tried the new wifiboot, and even if the ds seems to recognize the network, it won't connect. I attached the output of the program.
Re: DSi Wifi rev-engineering
by on (#231931)
The 03 10 in upper right of the hexdump means DISCONNECT event (1003h), usually that means wrong password or too weak signal strength.
CRYPT: OPEN means that you have configured the access point as "open network" in DSi system settings, without using any WEP/WPA/WPA2 password. Is that right? I thought you had mentioned using WPA2 in the unlaunch thread.
RSSI: 0 is pretty weak signal strength, quite possible that it can see the access point - but fail to connect to it. It will probably work better if you get closer to access point, something like RSSI: 20...60 should be fine.
CHANNEL: 2 should work (but wifiboot is scanning the standard channels (1, 6, 11) first, so those might work a bit faster).
PM: 1 new messages in your browser means that I was hoping that you might test wifiboot, but you seem to have found the update without seeing the message : )

I have spent the last some days on researching the country code in the REG_DOMAIN event. The AR6002 ROM contains a database with settings for 112 countries (though 5 of them are dummy/debug entries). The actual/local 10bit country code is stored in I2C EEPROM byte[08h..09h]. The Country selection in DSi System Settings doesn't affect the Wifi-country.
The obvious country specific thing is number of 2.4GHz channels, usually 1-13, or 1-11. But there are some other differences that I wasn't aware of. Most interestingly, Tx power is 100mW (20dB) in most of the world, but canada/mexico/taiwan/usa/etc. have 500mW (27dB), and newzealand/belize/bolivia/venezuela do even have 1000mW (30dB).
For some reason, there are also 5GHz channels in the database (although AR6002 shouldn't support that, maybe 5GHz could/should be supported on AR6013/AR6014, although Nintendo claims that DSi and 3DS support 2.4GHz only). And, the database contains a bunch of additional flags, which I couldn't guess which flag has which meaning; most of them are probably 5GHz-specific, like indoor/outdoor flag etc.
Some related docs:
http://www.davros.org/misc/iso3166.html - ISO country codes
http://madwifi-project.org/wiki/UserDocs/CountryCode - Atheros countries
https://kernel.googlesource.com/pub/scm ... 4f8/db.txt - official atheros "db.txt" source (click "log" for older versions, which may be closer to DSi era)

Now I am wondering if Nintendo has actually used wifi boards with appropriate country codes when selling DSi consoles. There seems to be no country info on the daughterboard stickers (and the sticker with the model no may be hidden underneath of a black isolation/sticker anyways). And, my european DSi came with japanese wifi board (country 188h), that looks wrong - but it might be no real problem in practice as japan uses 100mW, too, and uses only ch1-13, too (theoretically japan could have unlocked ch14, but that seems to be depracted in newer ieee standards). And, as long as the access point is using standard channel 1, 6, or 11, it won't matter if the console has channel 12-13 (or 14) enabled or disabled.

However, the Tx power might have some more serious ups and downs. If it's too weak then you can't connect to access points that would be within reach. And if it's too high... worst would be disturbing the neighborhood, raising battery consumption, overheating the console, without actually improving anything (assuming that access point can't reply at same strength)... unless the wifi unit does somehow automatically use only as much as actually needed; the browser uses POWER_MODE command with setting MAX_PERF_POWER (whatever that means, MAX doesn't sound good), the other option would be REC_POWER (whatever that means).

Confusingly, Wifi-FLASH does also have an entry with enabled channels (for NDS Wifi), which appears to be always set to 3FFEh aka channel 1-13 on all NDS and DSi consoles (even on US wifi boards that allow only channel 1-11 for DSi Wifi). This setting is used for local networking (eg. local multiplayer, ds download play, pictochat), whereas, those seem to use the first/middle/last of those enabled channels, ie. 1,7,13, probably randomly picking one of those channels. I am not sure if/how that complies with FCC rules in many countries (unless I've missed a software layer that masks off channel 13). Hmmm, https://en.wikipedia.org/wiki/List_of_WLAN_channels does have some smallprint (in the "Notes" at the very bottom of the page) stating the channel 12-13 were perfectly legal even in usa, as long as they are used at "low-power" (whatever that means). Canada has a similar rule for ch12 (but doesn't permit ch13).
Re: DSi Wifi rev-engineering
by on (#231935)
Weird, I tested the connection before launching wifiboot, and I connected fine, could it be that it read the network info from the saved wep networks? I'm not sure but if iirc I had the first network configured as open with that ssid, maybe it read from.there instead of from the advanced network settings?
Re: DSi Wifi rev-engineering
by on (#231946)
Yes, if you are using the same SSID in two entries won't work. Easy workaround would be to delete the other entry.
Re: DSi Wifi rev-engineering
by on (#231953)
Ok, i tested again, both with my home network after removing the duplicate entries and also using my phone as hotspot with wpa2 protection, and in both the cases it got stuck at "connecting".
As for your message, i really didn't notice it, as i come to the site after the mail notifications, and i received none for the pm...
Re: DSi Wifi rev-engineering
by on (#232027)
It's showing only "Nocash Wifiboot v2.4" and "Connecting"? That would be still miles away from any possible problems with the new code. Troubleshooting for connecting:
Make sure that you do use wifiboot v2.4, not the older v2.3 version in unlaunch
Make sure that the access points use channel 1..11, not 12,13,14
Make sure that you didn't accidentally delete the WPA2 settings alongsides with the open network settings
Make sure that you didn't forget to configure your phone hotspot in system settings
Make sure that you didn't mis-spell the SSID's
Make sure that signals are strong enough, if neccessary get closer to the access point
Theoretically there should be no problem in the connecting/scanning stage as that part did work when you had it configured as open network. The scanning is basically searching for an access point that broadcasts one of the SSID strings that you had configured in system settings, there isn't much that could get wrong there, in theory.

One thing that I should have mentioned is that the new WPA/WPA2 features are currently supporting only WPA-TKIP and WPA2-AES (system settings does also allow using more obscure variants like WPA-AES and WPA2-TKIP).
And, if the access point is configured to support both WPA and WPA2, I haven't tested that combination yet. It would probably fail when using WPA2 on DSi side, but should work for WPA on DSi side.
Though that two issues shouldn't affect the connecting/scanning stage (but you might run into that issues later on).
Re: DSi Wifi rev-engineering
by on (#232090)
I tested with all the network encryptions available for my router, so WPA, wpa2 and WPA+wpa2, and I also manually put the channel to 1, to be sure it was in the supported range, but I still had no success in connecting, in the dsi settings it put all the passwords (the one for WPA too) as aes and not a single time as tkip (so probably WPA one didn't work for that, as you said it only support tkip). Idk if there's something else I should configure to make it work, but as now I had no success. :(
Re: DSi Wifi rev-engineering
by on (#232104)
Hmmm, but you are still seeing only "Nocash Wifiboot v2.4" and "Connecting", and the rest of the screen is blank?
That sounds as if unlaunch isn't seeing the "advanced" access point settings in wifi-flash at all.
Can you dump the wifi-flash? In fwtool it's called "firmware" (because NDS did have the firmware stored in that memory, too). And maybe send the dump per PM (there is some personal stuff like mac address, wifi password, and birthday in there though).
Or check the description below, maybe your settings are somehow different. Most importantly, the byte at [0E7h] should be 00h (for Open/WEP) or 10h (for WPA/WPA2). And the SSID should be correct (and zeropadded).
Btw. did you manually enter the settings, or did you use AOSS/WPS? I have never used AOSS/WPS, and don't know if they would require special actions. AOSS is reportedly storing another value in [0E7h], so wifiboot won't accept that (though, maybe I could just ignore that uncommon value and accept the setting without needing to do anything special).

Code:
Connection data 4 at WifiFlash[00020h]*8-A00h (eg. 01F400h) (DSi only)
Connection data 5 at WifiFlash[00020h]*8-800h (eg. 01F600h) (DSi only)
Connection data 6 at WifiFlash[00020h]*8-600h (eg. 01F800h) (DSi only)
The DSi has three extra 200h-byte regions (for use DSi games, with the new
WPA/WPA2 encryption support, and with additional proxy support), these extra
regions are found under "Advanced Setup" in the DSi firmware's "Internet"
configuration menu.
  Addr Siz Expl.
  000h 32  Proxy Authentication Username (ASCII string, padded with 00's)
  000h 32  Proxy Authentication Password (ASCII string, padded with 00's)
  040h 32  SSID (ASCII string, padded with 00's) (see [0E8h] for length)
  060h ..  Maybe same as NDS
  080h ..  WEP Key (zerofilled for WPA)
  0xxh ..  Maybe same as NDS
  0C0h 4   IP Address           (0=Auto/DHCP)
  0C4h 4   Gateway              (0=Auto/DHCP)
  0C8h 4   Primary DNS Server   (0=Auto/DHCP)
  0CCh 4   Secondary DNS Server (0=Auto/DHCP)
  0D0h 1   Subnet Mask (0=Auto/DHCP, 1..1Ch=Leading Ones) (eg. 6 = FC.00.00.00)
  0D1h ..  Unknown (zerofilled)
  0E6h 1   WEP (00h=None/WPA/WPA2, 01h/02h/03h/05h/06h/07h=WEP, same as NDS)
  0E7h 1   WPA (00h=Normal, 10h=WPA/WPA2, or FFh=unused/deleted)
  0E8h 1   SSID Length in characters (01h..20h, or 00h=unused)
  0E9h 1   Unknown (usually 00h)
  0EAh 2   MTU Value (Max transmission unit) (576..1500, usually 1400)
  0ECh 3   Unknown (usually 00h-filled)
  0EFh 1   bit0/1/2 - connection 4/5/6 (1=Configured, 0=Not configured)
  0F0h 14  Zerofilled (or maybe ID as on NDS, if any such ID exists for DSi?)
  0FEh 2   CRC16 for Entries 000h..0FDh (with initial value 0000h)
  100h 32  Precomputed PSK (based on WPA/WPA2 password and SSID) ;\all zero
  120h 64  WPA/WPA2 password (ASCII string, padded with 00's)    ;/for WEP
  160h 33  Zerofilled
  181h 1   WPA (0=None/WEP, 4=WPA-TKIP, 5=WPA2-TKIP, 6=WPA-AES, 7=WPA2-AES)
  182h 1   Proxy Enable         (00h=None, 01h=Yes)
  183h 1   Proxy Authentication (00h=None, 01h=Yes)
  184h 48  Proxy Name (ASCII string, max 47 chars, padded with 00's)
  1B4h 52  Zerofilled
  1E8h 2   Proxy Port (16bit)
  1EAh 20  Zerofilled
  1FEh 2   CRC16 for Entries 100h..1FDh (with initial value 0000h) (0=deleted)
The location of the first data block (aka settings number 4) is at the User
Settings address minus A00h, ie. Firmware Header [00020h]*8-A00h.
Observe that NDS consoles do have Firmware bootcode/data in that area, so those
new regions exist on DSi only. Presence of the new regions is indicated in
Firmware Header [001FEh], that byte is usually FFh=NDS or 20h=DSi, the DSi
browser does internally replace FFh by 10h, and does then check if byte>=20h
(ie. the new areas exist if the byte is 20h..FEh).
Re: DSi Wifi rev-engineering
by on (#232444)
I am still fighting with one access point, again and again. I think I've now tracked down the problem to ARP messages getting lost.
The DSi does receive the wifiboot request via UDP, and it does then send a "Who Has" ARP message to 192.168.1.29 (my PC), which is unanswered when using the router as access point, but it's working okay with three other access points. And even with the router, I can send "Who Has" ARP message to 192.168.1.1 (the router itself), which works okay, it's only the "Who Has" for the PC not working.

So... it looks as if the router (or another switch between the router and PC) isn't forwarding the ARP : /

Frustrating issue. I guess I'll have to figure out how many switches and other crap we have in this building. Or try to find a long cable for wiring my PC directly to the router, trying to bypass the problem that way.

My ARP retry handler did have three evil bugs - but fixing them didn't help on the above issue : (
Normally, the ARP is working without needing retries, except on the router, where it's never working with/without retries.

--- Alongsides, some other findings: ---

AR6002 (on older DSi wifi boards) is really worse than AR6013 (on later DSi wifi boards). AR6002 is getting much warmer, and it's also less reliable (occassionally fails on CONNECT command for distant APs, which works flawless with AR6013).

The SET_BITRATE command works only vaguely: It's somehow reaching more than 200Kbyte/s when selecting 1MBit/s ; )

System Settings behaves a bit weird. When using search access point, it detects my router being WPA2-TKIP, despite of the router announcing itself as WPA2-AES in beacons (including AES groupkey). Nethertheless, the connection does somehow pass with the WPA2-TKIP setting, theoretically that can't work at all since the group key is AES, not TKIP. Almost looks as if Nintendo is ignoring their own configuration settings in that case.

Apropos configuration settings: Without more info from edo9300 (or other people with same problem), I will just ignore that issue for now. Maybe there will be bug reports with more details showing up after including the new wifiboot version in the unlaunch package, though it would be also nice to bugfix such issues before including the new wifiboot in unlaunch. Or well, it doesn't matter that much to get everything perfectly working before next release.
Re: DSi Wifi rev-engineering
by on (#232576)
I have added some code for extracting the supported WPA and WPA2 cipher modes from beacons (instead of trusting the cipher mode selection configured in wifi flash).

Displaying the values received from my access points, and changing their access point configurations...
I seem to have most or all expected combinations: WPA-TKIP, WPA-AES, WPA2-TKIP, WPA2-AES, as well as mixed modes WPA2-TKIP/AES, WPA/WPA2-AES, and WPA-TKIP-WPA2-TKIP/AES. So, I could test all that stuff, yipiehyuh, that will probably take some time : /

And, I do even have an access point that supports something called "802.1X" and "WPA" and "WPA2-enterprise", despite of the confusing names, all three are using something called Radius server. As far as I know, that's better than normal WPA/WPA2, but not for home use, or so. I guess I'll omit supporting that, I've no idea how it works, and I don't even know if I do have a Radius server (it doesn't look as if the access point would have that built-in).

I didn't find access points with WPA-WEP or WPA2-WEP, but I guess that's rarely used, if ever (although it's semi-documented in IEEE specs). Raw WEP networks do just have the WEP set in capability flags, without further WPA/WPA2 info in beacons (which would mainly make sense for backwards compatibility, ie. when supporting TKIP or AES pairwise keys combined with insecure WEP group keys (though I don't know how the group key would be assigned in that case, probably as fixed WEP key, instead of via EAPOL group key handshakes)).

One more obscure finding in my local network is that somebody (not me) has installed a new repeater some days ago, using the same SSID and password as the router - but with a different cipher mode. The router uses WPA2-AES, the repeater uses WPA2-TKIP/AES. So, well, that explains occassional connection problems. I had blamed that on AR6002 being less reliable than AR6013, but now it looks more as if the new repeater made fun of saying "Hello, I pretend being your AES router, and you won't guess that I don't support AES group keys!"
Re: DSi Wifi rev-engineering
by on (#232582)
nocash wrote:
... And, I do even have an access point that supports something called "802.1X" and "WPA" and "WPA2-enterprise", despite of the confusing names, all three are using something called Radius server. As far as I know, that's better than normal WPA/WPA2, but not for home use, or so. I guess I'll omit supporting that, I've no idea how it works, and I don't even know if I do have a Radius server (it doesn't look as if the access point would have that built-in).

For consumer (read: non-workplace/non-enterprise) use, don't worry about 802.1X. 802.1X is a form of authentication protocol/model used for both wired and wireless networks. It was originally designed for Ethernet (called EAPOL (EAP Over LAN), where the idea was that you wanted an authentication layer atop Ethernet to ensure nobody could just plug something into a port and immediately begin using it. It's implemented at layer 2, thus has its own framing type/format. Later it was extended to support 802.11 wireless, where sometimes it's just called EAP. The implementation is pretty simple: there's a client (server/laptop/desktop/whatever) which runs software that generates the frames + handles the authentication. This talks to an "authenticator", which for Ethernet would be a switch or bridge that supports 802.1X itself. That device then talks to an authentication server (which is what stores credentials or whatever else), usually via the RADIUS protocol.

RADIUS is a TCP or UDP-based protocol that's used for authentication (i.e. approval/rejection). It was designed back in the early 90s for dial-up use, mainly used for defining whether or not a particular customer/user had the ability to log in/authenticate on dial-up or not (as well as delegating L2TP parameters if necessary); but it's a general-purpose protocol. In the later 90s, companies began using it for ISDN and later ADSL/SDSL authentication, usually in combination with PPP. It can be used as a kind of "back-end" for 802.1X.

Anything that's labelled "Enterprise" with WPA or WPA2 as a prefix involves RADIUS or 802.1X -- not needed for consumer stuff.

Some reference materials for you:

https://www.vocal.com/secure-communicat ... -over-lan/
https://kb.netgear.com/188/What-is-802- ... entication
https://networkengineering.stackexchang ... entication
https://en.wikipedia.org/wiki/RADIUS
Re: DSi Wifi rev-engineering
by on (#232657)
Ok, i finally found some time to test again the connections, but still had no lock, before i connected using the wps configuration, so i thought that might have been the issue, and thus i redid the setup in the "normal" way, but still no luck, it remained stuck on connecting. Then i receched the configurations and i noticed tat the password encryption was ser to wpa2-psk (tkip), not aes (apprently for my router that's the default), so i forced it to be aes, but even if now the network is correctly recognized by the app (no longer shown as "open"), and it's no longer stuck on connecting, i'm still getting the same response as the one i posted on my first answer. I think it's worth noting that during the testes, all those configurations worked fine for the dsi browser, both wps, tkip and aes.
Re: DSi Wifi rev-engineering
by on (#232694)
Yes, WPA2-TKIP doesn't work in current version. But I am working on it, and next version should support it (as well as other variants). Btw. a router using WPA2-TKIP would be the newest protocol combined with weakest security, which would be really weird. Unless it's actually using some more meaningful backwards-compatibility mode, like WPA2-AES/TKIP (the DSi's System Settings GUI can't display that combination), or WPA-TKIP+WPA2-TKIP (but in that case wifiboot should have worked fine with WPA-TKIP).

Anyways, my major concern is that - when you had used WPS - my understanding is that you were only seeing this two lines:
Code:
Nocash Wifiboot v2.4
Connecting
on the screen, and the rest of the screen was blank? Yes-yes, I've already asked that twice, but it would be really nice if you could answer that question (alike clearly saying "Yes, only that 2 lines" or "No, more than those 2 lines"). Because, if it's really showing only that two lines then it would be a major problem (ie. it would mean that wifiboot can't read your settings from flash, and then it just won't work, no matter if everything else is perfectly implemented).

My code is now converting beacon info to best matching encryption type. The beacon info consists of WPA or WPA2, and TKIP or AES group key, and TKIP or AES (or both) pairwise key. Plus WEP and open network. That gives quite a number of different combinations. The best matching combination would depend on having WEP or WPA(2) password defined in flash memory, and on having matching decryption hardware (ie. NDS can't do AES, but could probably implement TKIP in software).

Another parameter would be the selected encryption type in flash memory - I am tempted to ignore that setting because it's only hindering connection. If the the WPA(2) password is defined, then one could connect anyways, no matter if the access point is using WPA or WPA2 and AES or TKIP. And if the access point is using a AES/TKIP-combo then one couldn't define that in DSi settings anyways.

Concerning security, it would be difficult for attackers to mimmick a (working) WPA/WPA2 access point, so I don't think that there is much of a security risk when allowing WPA-TKIP despite of flash settings saying WPA2-AES, for example.
The exception would be allowing Open Network (or WEP) despite of flash settings saying something else. That would be highly insecure, up to including other people to upload their own executables to your console via wifiboot. That's perhaps unlikely to happen, but, admittedly, my current code is allowing to do that : )
Re: DSi Wifi rev-engineering
by on (#232695)
koitsu wrote:

One stunning thing in EAPOL is the "Version" byte. Official specs seem to define it as part of 16bit value (that contains Type and Version bytes; without clearly saying which byte is Type, and which is Version).
The above linked document suggests that Version is the 1st byte, and Type is 2nd byte of that 16bit value. But even then, the bytes are usually 01 03. If the 1st byte is Version, then it would be Version=01, whilst most docs are saying that v2 is current version. I could only guess what is happening there:
- Maybe version is 00=v1 and 01=v2
- Maybe version is 01=v1 and 02=v1.1 and 03=v2, or the like
- Maybe version is 02=v2=current, but everybody is held to use 01=v1 for better backwards compatibility.
- Maybe version is unimportant and should be ignored
Re: DSi Wifi rev-engineering
by on (#232767)
Ops, sorry for the misunderstanding, yes, I'm only seeing those 2 lines, also another thing I noticed, in my router settings, when I'm selecting the network encryption, it's actually selected "wep+wpa2" (that's pretty weird tho)
Re: DSi Wifi rev-engineering
by on (#232783)
Okay, thanks! I guess I'll need to test WPS myself tonight/tomorrow & dump the resulting DSi-Wifi-FLASH settings, there should be an access point with WPS button somewhere upstairs. The Wifi-FLASH is probably merely having a "WPS-was-used" flag in there, which is currently seen as unknown value by wifiboot.

WEP+WPA2 is really weird, WPA+WPA2 would be a bit more common, or maybe WEP+WPA+WPA2 if one wants support it all. Also, if WEP implies RC4, and WPA2 usually implies AES, then I can't imagine how system settings had detected it as using TKIP. But yeah, theoretically, WEP+WPA2 should be possible for backwards compatibility. But I've no idea how to support that in practice.

The first problem is that I don't know if or how EAPOL is capable of sending WEP groupkeys (it would be pointless as the WEP group key should be identical to the WEP pairwise key, which is fixed for WEP, so EAPOL wouldn't need to send it at all; at least not to clients that do use WEP as pairwise key).
The other problem, for real working compatibility with stuff like NDS, is that WPA/WPA2 are using keyindex=1/2 for group keys, whilst NDS games seem to require to use keyindex=0 for both group+pairwise key.

Does your router have two separate passwords for WEP and WPA2? WEP does usually require a fixed-length password (13 characters, or 26-hex-digits), and WPA/WPA2 can have variable-length text strings as password.
Re: DSi Wifi rev-engineering
by on (#232812)
Here are the differences between normal-setup and automated-WPS-setup. Bit1 of entry [0E7h] is just what one would have expected, the unexpected part is that bit0 is also set.
Also noteworthy: The plaintext password is stored at 120h and up, that's useful when changing the SSID, so the console can recompute the new PSK for password+ssid. And oddly, WPS has some garbage in unused password characters.
Code:
Offset       WPS   Normal
1F6E7        13    10         ;<-- diff
1F6FE        F4    A0         ;\crc
1F6FF        9D    78         ;/
1F734-1F75E  xxx   00-filled  ;-garbage (unused password chars)
1F7FE        F3    49         ;\crc
1F7FF        2C    1B         ;/

Dumping that info was painful: I've tried three access points, with the DSi prompting me to push and hold the WPS button and wait two minutes until seeing a WPS Failure message (on the first three or four attempts with the first two access points), or until eventually passing okay (on the third access point).
Alltogether, it would have been ways to enter the password manually than using WPS. But anyways, it's now dumped and known what bytes are stored in flash memory (just in case anybody would be interested in such things).
Re: DSi Wifi rev-engineering
by on (#232869)
edo9300 wrote:
Ops, sorry for the misunderstanding, yes, I'm only seeing those 2 lines, also another thing I noticed, in my router settings, when I'm selecting the network encryption, it's actually selected "wep+wpa2" (that's pretty weird tho)

Apparently I remembered wrongly (when I wrote this message I couldn't go look up the router settings because the web interface was kinda bugged) anyways the encryption is WPA+wpa2, not wep+wpa2 (in fact that was a butt too weird).
Re: DSi Wifi rev-engineering
by on (#232871)
Update, finally managed to connect, I set the encryption to wpa2 only and it worked
Re: DSi Wifi rev-engineering
by on (#232894)
Got the wifiboot v2.5 update finished & uploaded.
http://problemkaputt.de/wifiboot.zip (binary and source code)
I hope the DSi code is now able to connect to most or all access points including such with mixed TKIP+AES ciphers.

Code:
;wifiboot v2.5 - 26 Jan 2019
; - dsi-wifi: detects supported cipher/combinations (from AP beacons)
; - dsi-wifi: determines best-matching-cipher (AP beacons versus FLASH settings)
; - dsi-wifi: supports wifi-flash entries with WPS-flag (ie. ignores that flag)
; - dsi-wifi: relocated all code to vram (slightly faster than slow main ram)
; - dsi-wifi: displays life-updates for current signal strength
; - dsi-wifi: source code: REG_SDIO_xxx symbols instead of numeric I/O addresses
; - dsi-wifi: uses WMI_GET_CHANNEL_LIST to determine enabled channels/domain
; - dsi-wifi: shows REG_DOMAIN country code (eg. 0188=JP, 0348=US)

PS. for whatever reason, NDS-wifi upload speed is back at 110Kbyte/s today, last week it was only 60Kbyte/s, maybe the weather is good for it today. DSi-wifi speed still ranges somewhere at 300..600Kbyte/s.
Re: DSi Wifi rev-engineering
by on (#232896)
nocash wrote:
Got the wifiboot v2.5 update finished & uploaded.
http://problemkaputt.de/wifiboot.zip (binary and source code)
I hope the DSi code is now able to connect to most or all access points including such with mixed TKIP+AES ciphers.

Code:
;wifiboot v2.5 - 26 Jan 2019
; - dsi-wifi: detects supported cipher/combinations (from AP beacons)
; - dsi-wifi: determines best-matching-cipher (AP beacons versus FLASH settings)
; - dsi-wifi: supports wifi-flash entries with WPS-flag (ie. ignores that flag)
; - dsi-wifi: relocated all code to vram (slightly faster than slow main ram)
; - dsi-wifi: displays life-updates for current signal strength
; - dsi-wifi: source code: REG_SDIO_xxx symbols instead of numeric I/O addresses
; - dsi-wifi: uses WMI_GET_CHANNEL_LIST to determine enabled channels/domain
; - dsi-wifi: shows REG_DOMAIN country code (eg. 0188=JP, 0348=US)

PS. for whatever reason, NDS-wifi upload speed is back at 110Kbyte/s today, last week it was only 60Kbyte/s, maybe the weather is good for it today. DSi-wifi speed still ranges somewhere at 300..600Kbyte/s.

Wonderful, tested this new release and connected flawlessy first try to the wpa+wpa2 network configured with wps :), only thing, i couldn't use dslink to upload stuff, nor i can use no$gba upload feature as i get a nocashio driver failure, otehrwise it is connected fine to the network.
Re: DSi Wifi rev-engineering
by on (#232902)
Okay, so it's working, except that uploading doesn't work. Which was the main purpose. But yeah, better than nothing!

Hmmmm, and the nocashio driver - that was for parallel port uploads on windows XP and up, but wasn't intended to be used when selecting wifi as upload method. But yes, now that you mention it, yes, looks as if no$gba insists on installing the driver for wifi, too.
Thanks for the info! I'll fix that in next no$gba update... best before releasing the new wifiboot bundled with next unlaunch update, so that the hordes of DSi developers won't run into the problem.
The devasting part is that the wifi upload function in no$gba was one of the top-new-features released in June 2018. And now you seem to have been the first person to have tried using that feature.
But yeah, also much better than nobody ever having tried using it at all.

And dslink.exe doesn't work either? Then it might be still an issue with wifiboot being not-so compatible with most or all access points : /
Well, I guess I will just wait 20-30 years until a software/hardware archaeologist downloads the wifiboot source code and hopefully fixes the bug for me...

Over here it's working with 3 of 4 access points, so there might be a relative good chance to find a working access point (unless it turns out to work only with those 3 access points, and fails with millions of others).

PS. Did you use the WPS "push-button" method, or WPS "pin-number" method? I've so far tried only the push-button thing. The DSi firmware also allows using a pin-number (a random number displayed on the DSi screen, supposed to be entered in the access point's settings).
I haven't tested that pin-number method, and don't know if it does store yet different values in wifi-flash. Intuitively, I would assume that it's even more difficult than the push-button method (which took me about 20 minutes to get it working). But if somebody is using that pin-number stuff, it would be interesting to hear if it's working, or if it's storing uncommon values in wifi-flash.
Re: DSi Wifi rev-engineering
by on (#232915)
nocash wrote:
Okay, so it's working, except that uploading doesn't work. Which was the main purpose. But yeah, better than nothing!

Hmmmm, and the nocashio driver - that was for parallel port uploads on windows XP and up, but wasn't intended to be used when selecting wifi as upload method. But yes, now that you mention it, yes, looks as if no$gba insists on installing the driver for wifi, too.
Thanks for the info! I'll fix that in next no$gba update... best before releasing the new wifiboot bundled with next unlaunch update, so that the hordes of DSi developers won't run into the problem.
The devasting part is that the wifi upload function in no$gba was one of the top-new-features released in June 2018. And now you seem to have been the first person to have tried using that feature.
But yeah, also much better than nobody ever having tried using it at all.

And dslink.exe doesn't work either? Then it might be still an issue with wifiboot being not-so compatible with most or all access points : /
Well, I guess I will just wait 20-30 years until a software/hardware archaeologist downloads the wifiboot source code and hopefully fixes the bug for me...

Over here it's working with 3 of 4 access points, so there might be a relative good chance to find a working access point (unless it turns out to work only with those 3 access points, and fails with millions of others).

PS. Did you use the WPS "push-button" method, or WPS "pin-number" method? I've so far tried only the push-button thing. The DSi firmware also allows using a pin-number (a random number displayed on the DSi screen, supposed to be entered in the access point's settings).
I haven't tested that pin-number method, and don't know if it does store yet different values in wifi-flash. Intuitively, I would assume that it's even more difficult than the push-button method (which took me about 20 minutes to get it working). But if somebody is using that pin-number stuff, it would be interesting to hear if it's working, or if it's storing uncommon values in wifi-flash.

I tried using dslink after setting the network to open, but it didn't seem to work with wifiboot (i also tried the version 2.3 bundled with unaunch, still same result), as for wps, i think nowadays it's almost impossible to find a router that pairs wps with the pin, iirc i saw this stuff only once, but then never see that after as all teh current routers have only the button setup (it's weird that it took 20 minutest for you btw)
Re: DSi Wifi rev-engineering
by on (#233904)
I've updated no$gba - http://problemkaputt.de/gba.htm

The utility/upload function should now work without bugging you about installing nocashio for wifi uploads (as long as you select "Dslink/Wifi" in the "Multiboot Port" setting in no$gba's "Other" options screen). Don't know if it will help on problems with your router (if dslink.exe didn't work then the no$gba uploader probably won't work either). For testing best start uploading something that is known to be working as wifi-upload (eg. magicflr.nds, unlaunch.dsi, or wifiboot.nds itself).

The built-in help (and gbatek) are now also containing the new findings about the dsi-wifi hardware, some general info about wpa/wpa2, and a bunch of info about nintendo's auto-load and title-list structures.

Code:
08 Feb 2019 - version 2.9c
- wifiboot: now supports dsi-wifi-hardware with wpa/wpa2 encryption
- utility/upload: omits nocashio lpt-port-driver for wifi upload (thanx edo9300)
- dsi/wifi/hack: dsi browser patch for writing all sdio traffic to wifi-log.txt
- dsi/wifi/help: new chapter for DSi Atheros Wifi - MBOX Transfer Headers
- dsi/wifi/help: added notes on used WMI params (connect, cipher, pstream, etc)
- dsi/wifi/help: more details for access point 4/5/6 settings in wifi-flash
- nds/wifi/help: updated ds download play chapter (and separate beacon chapter)
- nds/wifi/help: new chapters for WPA/WPA2: handshake, keys/mics, encryption
- nds/help: added reverse-engineered dldi specs (flashcart driver for homebrew)
- dsi/help: added several notes on files found in firmware v1.0J (thanks AnKi)
- dsi/ndma: added support for SDIO startup mode (much alike as SDMMC startup)
- dsi/boot: init AES Key2.X (for Data Managment export to SD card, thanx zoogie)
- dsi/help: device list: details on naming for "public & private savedata"
- dsi/autoload/help: new chapter for auto-loading (formerly in i2c chapter)
- dsi/autoload/help: added skeleton/info on 2000000h (autoload parameters)
- dsi/autoload/help: added more details on 2000300h (autoload by title id)
- dsi/autoload/help: added specs for 2000800h (unlaunch autoload by path\name)
- dsi/autoload/help: added specs for 2FFD800h (nintendo's title list and flags)
- dma/gba/nds7: re-fixed dma0/1/2 len, don't crop 16bit to 8bit (thanx normmatt)
- dsi/bios: added warn if/when using missing RSA keys (missing bios dsi dump)
- aboutbox: added email/contact page (debug version only, not gaming version)
- xed editor: fixed scrolling upon backspace in first some lines (thanks yuki)
Re: DSi Wifi rev-engineering
by on (#237794)
Finally got around to test the write-ability of the DSi's new tiny Wifi-FLASH chips. I had some boards with those chips laying around for a year, but didn't test them yet, parts because overwriting the first some bytes could potentially brick the console (what I have done new is wiring one of the FLASH chips from a broken wifi board to my PC, which can't brick anything).
Results are: A 128Kbyte memory space, with only 4Kbyte actual writeable memory (kinda weird design, and not really needed; the more important part for NDS compatibility is the 24bit address bus).
Code:
DSi "5A32" chip (32Kit aka 4Kbyte)
Early DSi DWM-W015 boards did have 128Kbyte FLASH, but later boards have custum
4Kbyte FLASH chips (these 4K chips are found on later DSi DWM-W015 boards, and
DSi DWM-W024 boards, and 3DS DWM-W028 boards). The chips are having a 24bit
address bus (needed for NDS compatibility), and, a weird non-writeable gap
within a 128Kbyte memory are:
  000000h..0002FFh  Writeable only if /WP=HIGH (otherwise writes are ignored)
  000300h..01F2FFh  Not writeable (FFh-filled, writes are ignored)
  01F300h..01FFFFh  Writeable
  020000h and up    Mirrors of 0..01FFFFh (same read/write-ability as above)
There are several part numbers: "5A32" (DSi), "5K32" (3DS), "32B, 3XH" (3DS),
and "26FV032T" (DSi), that chips are probably all the same size & functionally
same; most of those 4Kbyte chips have tiny packages (except "26FV032T" which
comes in classic large package).

Pin-Outs (Large Package, in NDS, and early DSi boards)
  1   D    Serial Data In (latched at rising clock edge)          _________
  2   C    Serial Clock (max 25MHz)                             /|o        |
  3   /RES Reset                                            1 -| |         |- 8
  4   /S   Chip Select (instructions start at falling edge) 2 -| |         |- 7
  5   /W   Write Protect (makes first 256 pages read-only)  3 -| |_________|- 6
  6   VCC  Supply (2.7V..3.6V typ) (4V max) (DS:VDD3.3)     4 -|/          |- 5
  7   VSS  Ground                                              |___________|
  8   Q    Serial Data Out (changes at falling clock edge)

Pin-Outs (Tiny Package, in newer DSi boards, and 3DS)
  1   /S   Chip Select (instructions start at falling edge)     ___________
  2   Q    Serial Data Out (changes at falling clock edge)  1 -| o         |- 8
  3   /W   Write Protect (makes first pages read-only)      2 -|           |- 7
  4   VSS  Ground                                           3 -|           |- 6
  5   D    Serial Data In (latched at rising clock edge)    4 -|___________|- 5
  6   C    Serial Clock
  7   /RES Reset
  8   VCC  Supply (2.7V..3.6V typ) (DSi: VDD33)

Next, I wanted to test the chip ID for the 26FV032T flash chip on a Hon Hai J27H020 board (which should be equivalent to Mitsumi DWM-W024 boards). But, that didn't worked out : /
When I got that J27H020 board, I had immediately desoldered the shielding plate (and smeared some solder on the antenna connector). I have replaced the antenna connector last week, and put the shielding plate back on the board... but it doesn't work... the console is booting up okay, but it can't find any access points (neither wirh my own firmware/wifiboot code, nor with Nintendo's original firmware, System Settings, and Browser).
Maybe I had damaged the board when removing the shield plate (it was soldered all way round, instead of just to a handful of solder points). Hmmm, or maybe the Hon Hai J27H020 boards require different antenna's?
Would be interesting if other people had similar problems when swapping Mitsumi boards against Hon Hai boards (one known problem is, of course, that DWM-W024 and J27H020 do both require firmware v1.4 or newer; the older firmwares support DWM-W015 only).

Anyways, while searching for J27H020 info, I came across FCC ID webpages, with some interesting info on the wifi hardware & pinouts:
Code:
Wifi FCC ID
The wifi hardware has been registered by Mitsume, Hon Hai, and Nintendo
themselves:
  https://fccid.io/BKE - Nintendo
  https://fccid.io/EW4 - Mitsumi
  https://fccid.io/MCL - Hon Hai (Foxconn)
The above webpages include some unrelated stuff (like bluetooth), and some
duplicate entries. The wifi/console related entries are:
  https://fccid.io/EW4-AGBWA      GBA        ;\GBA wireless adaptor
  https://fccid.io/EW4-OXYWA      GBA-Micro  ;/(not wifi/wlan compatible)
  https://fccid.io/BKENTR001      NDS (non-remove-able board)
  https://fccid.io/BKEUSG-001     NDS-Lite (old remove-able board, with MM3155)
  https://fccid.io/EW4DWMW006     NDS-Lite (new remove-able board, with MM3218)
  https://fccid.io/BKERVL036      Wii
  https://fccid.io/EW4DWMW004     Wii (mitsumi) (also W016, and maybe W014 ?)
  https://fccid.io/MCLJ27H010     Wii (foxconn) (also H003 ?)
  https://fccid.io/EW4DWMW015     DSi (old wifi board, mitsumi)
  https://fccid.io/EW4DWMW024     DSi (new wifi board, mitsumi)
  https://fccid.io/MCLJ27H020     DSi (new wifi board, foxconn)
  https://fccid.io/EW4DWMW028     3DS (mitsumi)
  https://fccid.io/MCLJ27H023     3DS (foxconn)
  https://fccid.io/MCLJ27H02301   2DS (foxconn)
  https://fccid.io/BKERED001      New3DS (on mainboard)
The pages include test reports, photos (including some prototypes), and most
interestingly, the Mitsumi "Label location" pages usually include pinout &
signal names for the wifi board.

DSi Wifi board pinout
https://fccid.io/EW4DWMW024/Label/Label-format-and-location-1137926.pdf
https://fccid.io/EW4DWMW015/Label/Label-Location-1031953.pdf
  1  MX_SD_CLK    2  GND
  3  GND          4  VDD_18
  5  SDIO_DATA0   6  VDD_18
  7  SDIO_DATA3   8  GND
  9  SDIO_DATA1   10 VDD_33
  11 SDIO_CMD     12 VDD_33
  13 SDIO_DATA2   14 GND
  15 JTAG_TDO     16 ATH_TX_H
  17 JTAG_TMS     18 SYS_RST_L
  19 GND          20 JTAG_TDI
  21 CLK32k       22 JTAG_TCK
  23 GND          24 JTAG_TRST_L
  25 NC(VDD28_TP) 26 SEL_ATH_L
  27 SPI_CS2      28 W_B
  29 BBP_SLEEP    30 SPI_CLK
  31 RF_SLEEP     32 SPI_DO   MISO
  33 RF_SCS       34 SPI_DI   MOSI
  35 BPP_SCS      36 CCA        ;typo: should be BBP (not BPP)
  37 BB_RF_SDO    38 RXPE
  39 BB_RF_SDI    40 TRDATA
  41 BB_RF_SCLK   42 GND
  43 NC(VDD18_TP) 44 TRCLK
  45 GND          46 TRRDY
  47 MCLK         48 TXPE
  49 GND          50 RESET

DS-Lite Wifi board DWM-W006 pinout
https://fccid.io/EW4DWMW006/Label/ID-label-format-and-location-706511.pdf
  1  GND          16 +3.3V
  2  TXPE         17 GND
  3  RXPE         18 RF_SCS
  4  CCA          19 BBP_SLEEP
  5  TRRDY        20 BBP_SCS
  6  GND          21 RF_SLEEP
  7  TRCLK        22 RESET
  8  TRDATA       23 GND
  9  GND          24 SPI_CLK
  10 BB_RF_SDO    25 SPI_DI
  11 BB_RF_SDI    26 SPI_DO
  12 BB_RF_SCLK   27 W_B
  13 GND          28 SIP_CS2     ;typo: should be SPI (not SIP)
  14 MCLK         29 LD
  15 GND          30 GND

Wii Wifi board
https://fccid.io/EW4DWMW004/Label/ID-Label-670426.pdf
  1  GND          12 VDD3.3
  2  SDIO_DATA_2  13 GND
  3  SDIO_DATA_1  14 GPIO_0
  4  GND          15 GND
  5  SDIO_CLK     16 SDIO_DATA_3
  6  GND          17 SDIO_DATA_0
  7  GPIO_1       18 GND
  8  GND          19 SDIO_CMD
  9  N.C.(VDD1.8) 20 GND
  10 N.C.(VDD1.8) 21 ANT_A (MAIN)
  11 VDD3.3       22 ANT_B (AUX)

3DS Wifi Board DWM-W028
https://fccid.io/EW4DWMW028/Label/ID-label-location-1272988.pdf
  1  MCLK         2  RF_CSRF
  3  GND          4  BB_CSBB
  5  RXPE         6  BB_RF_SDIN
  7  TXPE         8  BB_RF_SDOUT
  9  CCA          10 BB_RF_SCK
  11 TRDATA       12 GND
  13 TRCLK        14 BBP_SLEEP_L
  15 TRRDY        16 RF_SLEEP_L
  17 TRST_L       18 SEL_ATH_L
  19 GND          20 GND
  21 SDIO_DATA_0  22 JTAG_TDO
  23 SDIO_DATA_1  24 JTAG_TMS
  25 SDIO_DATA_2  26 JTAG_TDI
  27 SDIO_DATA_3  28 JTAG_TCK
  29 GND          30 SPI_CS2
  31 SDIO_CLK     32 W_B
  33 GND          34 SPI_CLK
  35 SDIO_CMD     36 SPI_DO
  37 UART_TXD     38 SPI_DI
  39 UART_RXD     40 SYS_RST_L
  41 GND          42 ATH_TX_H
  43 CLK32k       44 RESET
  45 GND          46 GND
  47 VDD_18       48 VDD_33
  49 VDD_18       50 VDD_33
Functionally same as DSi, but not pin-compatible, and with two UART pins
(instead of the NC pins).

The missing part are pinouts for original NDS-Wifi-boards. However, the DS-Lite board pinout could be used to rev-engineer the MM3155-chip pinout, and the MM3155-chip pinout could be then used to rev-engineer the NDS-Wifi-board pinout (not that that would be too useful for any practical purposes, but it's interesting to know what each pin is good for, and sometimes it does actually help to better understand the hardware capabilities).
Re: DSi Wifi rev-engineering
by on (#240698)
Released wifiboot v2.6 and no$gba v2.9e
http://problemkaputt.de/wifiboot.htm
http://problemkaputt.de/gba.htm
The main news is allowing to upload 3DS .firm files from no$gba utility menu to 3DS consoles.

That is my first 3DS program : )
And it's even a useful one... at least for people whom are coding .firm files.
Which is probably meaning useful to 3-5 people, but anyways.

10 Jul 2019 - wifiboot v2.6
- 3ds-wifi: added support for uploading 3DS.firm files via 3ds sdio
- source code cleaned up (REGBASE symbols, moved new SDIO code to wificore)
- extended transfer protocol (new bootinfo block, icon/title, rtc/time, etc)
- co-releases: 3ds.firm upload in no$gba/utility, wifiboot protocol in gbatek

10 Jul 2019 - version 2.9e
- wifiboot uploader: supports uploading 3ds .firm files from no$gba to 3ds
- wifiboot uploader: new bootinfo block (icon/title and rtc/time)
- wifiboot/help: added DS Wifi Dslink/Wifiboot Protocol chapter
- 3ds/help: added notes on SD/MMC Signals and 3DS Hardmodding
- 3ds/help: 3ds NWM wifi driver info (pool addresses and type1/4/5 variants)
- 3ds/help: specs for CID/OTP/NCSD/FIRM sectors for 3ds-#.mmc and new3ds-#.mmc
- setup: added 3ds/new3ds as nds mode variants (for debug view, not emulation)
- 3ds/aes: supports keyinit as by bootrom per otp (for filesys viewer)
- 3ds/emmc: loaded from 3DS-1.mmc or New3DS-1.mmc (for filesys viewer only yet)
- 3ds/bios: loaded from BIOS3DS.ROM (ARM9+ARM11) or BIOS3DS9.ROM+BIOS3DS11.ROM
- 3ds/help: added file/filesys info and arm11 mpcore/irq register specs
- wifi/help: added several new details (mostly from newly dumped AR6014 rom)
- a22i: supports abbrev ALU Rd,Rm,RotateShift (using Rd for both Rd and Rn)
- wifi/help: added wifi-board pinouts from fccid, and 4kbyte-wifi-flash-specs
- 3ds/crypt: supports sha256, sha224, aes-cbc, new keyscrambler (keyx/y)
- filesys viewer: show/decrypt 3ds stuff (partitions and firm/sav blocks)
- filesys viewer: faster directory loading (abort on first unused 00h entry)
Re: DSi Wifi rev-engineering
by on (#240702)
And some behind the scenes findings... I've spend the last 1-2 weeks on gazing at the 3DS AR6014 wifi firmware's rom/ram code (and also peeked at the DSi AR6002/AR6013 versions here and there).

Going by most or all official atheros source code, the last three WMI commands at 0047h and up should be:
Code:
  0047h  WMI_SET_FRAMERATES_CMD    ;aka WMI_FRAME_RATES_CMD
  0048h  WMI_SET_AP_PS_CMD         ;aka WMI_AP_PS_CMD
  0049h  WMI_SET_QOS_SUPP_CMD
But actually, DSi and 3DS have them as so:
Code:
  0047h  WMI_START_WHATEVER_TIMER_CMD                        ;-whatever on DSi!
  0048h  WMI_SET_FRAMERATES_CMD    ;aka WMI_FRAME_RATES_CMD  ;-cmd 0048h on DSi (instead of 0047h)!
  0049h  WMI_HOST_EXIT_NOTIFY_CMD  ;special DSi/3DS command (called host exit notify in ar6013/6014 ascii strings)


And then there are these two commands:
Code:
  003Bh  WMI_SET_BT_STATUS_CMD    ;\Bluetooth Coexistence
  003Ch  WMI_SET_BT_PARAMS_CMD    ;/
They are implemented in AR6002, but AR6013/6014 are simply ignoring that two commands (the firmware does have code for handling the commands, but the function vectors are instead pointing to dummy handlers... so it looks as if somebody has intentionally or accidentally made them nonfunctional).

The Type4/Type5 firmware variants for 3DS have these extra commands:
Code:
Special 3DS commands (for Type4 firmware, with AP mode):
  004Ah  WMI_AP_HIDDEN_SSID_CMD                         ;01h bytes (1)
  004Bh  WMI_AP_SET_NUM_STA_CMD aka WMI_AP_NUM_STA_CMD  ;01h bytes (1)
  004Ch  WMI_AP_ACL_POLICY_CMD                          ;01h bytes (1)
  004Dh  WMI_AP_ACL_MAC_LIST_CMD aka WMI_AP_ACL_MAC_CMD ;09h bytes (1+1+6+1)
  004Eh  WMI_AP_CONFIG_COMMIT_CMD                       ;34h bytes (..)
  004Fh  WMI_AP_SET_MLME_CMD                            ;09h bytes (6+2+1)
  0050h  WMI_AP_SET_PVB_CMD     ;ignored on 3DS         ;06h bytes (ignored)
  0051h  WMI_AP_CONN_INACT_CMD                          ;04h bytes (4)
  0052h  WMI_AP_PROT_SCAN_TIME_CMD                      ;08h bytes (4+4)
  0053h  WMI_?                                      ;01h bytes (1)
  0054h  N/A
  0055h  WMI_?                                      ;04h bytes (2+2)
  0056h  WMI_ignored_?                              ;01h bytes (ignored)
  0057h  WMI_?  ;with EVENT_1022h                   ;00h bytes
  0058h  WMI_?     <-- with optional params?        ;var       (2+2+1+1+N)
  0059h  WMI_?       ;only lower 8bit used          ;04h bytes (4; only 1 used)
  005Ah  WMI_?                                      ;01h bytes (1)
  005Bh  WMI_?                                      ;04h bytes (2+1+1)
  005Ch  WMI_?                                      ;04h bytes (1+3)
  005Dh  WMI_?                                      ;0Ah bytes (1+1+2+1+1+2+2)
  005Eh  WMI_?                                      ;01h bytes (1)
  005Fh  WMI_?                                      ;04h bytes (4)
Special 3DS commands (for Type5 firmware, with MacFilter and GameID):
  0060h  WMI_?                             ;3Ah bytes
  0061h  WMI_?                             ;28h bytes
  0062h  WMI_?                             ;12h bytes
  0063h  WMI_?                             ;02h bytes
  0064h  WMI_?                             ;03h bytes
  0065h  WMI_?                             ;07h bytes
  0066h  WMI_?                             ;07h bytes
  0067h  WMI_?                             ;03h bytes
  0068h  WMI_?  ;can be with EVENT_1023h   ;01h bytes
  0069h  WMI_?                             ;00h bytes
  006Ah  WMI_?                             ;00h bytes
  006Bh  WMI_?                             ;01h bytes
  006Ch  WMI_?                             ;06h bytes
  006Dh  WMI_?  ;with EVENT_1026h          ;00h bytes
  006Eh  WMI_?                             ;01h bytes
  006Fh  WMI_?                             ;06h bytes
  0070h  WMI_?                             ;01h bytes
  0071h  WMI_?                             ;08h bytes
  0072h  WMI_?                             ;02h bytes
  0073h  WMI_?  ;with EVENT_1027h          ;01h bytes
The AP mode commands appear to be same as what is command number F00Ah..F013h in official atheros code. I guess the 3DS is using that AP stuff to host multiplayer games.
So, I think both Type4 (AP Mode) and Type5 (MacFilter) are somehow "local network" related. Maybe one is for Streetpass, and one for Single-gamepak DownloadPlay (and maybe also one of them for Multi-gamepak local multiplayer).

Oh, and I have taken another approach on comparing the 3DS NWM wifi firmware versions. Searching for known Xtensa code didn't work (for unknown revisions). So, I am now searching for known ARM literal pool structures (to obtain size & offset of the Xtensa code blocks). I've compared four NWM files yet, and found them to contain three different Xtensa code revisions:
Code:
  Stub.data   038h bytes                   ;\Database and EEPROM reading stub
  Stub.code   316h bytes                   ; (always same size/content)
  Database    1E8h bytes                   ;/
  Main.type1  0FD3h, 10F7h, or 1B1Bh bytes ;\Main firmware (compressed)
  Main.type4  A053h, A482h, or A5EBh bytes ; (size/content varies per version)
  Main.type5  78F6h, 7A2Eh, or 7A2Eh bytes ;/
Or, well Type5 has only two different sizes (I haven't checked yet if the 7A2Eh-byte versions are identical).

For normal use the oldest/smallest Type1 versions seems to be fine. I've tried to disassemble that code, it's only 1600 lines, but to really understand what it is doing one would also need to disassemble 70,000 lines of ROM code (which, I have only disassembled parts of it).
Anyways, in general, the RAM code containx the usual "main init" function (required because the atheros ROMs are lacking that code). And the remaining RAM code seems to be mostly containing a newer revision of the atheros/mitsumi mode switching code, and lots code for testing GPIO bit14 (which might be also mode switching related).
Re: DSi Wifi rev-engineering
by on (#242088)
Released wifiboot v2.7 - http://problemkaputt.de/wifiboot.htm

wifiboot v2.7 - 26 Aug 2019
- fast reconnect: re-uses old channel number and dhcp settings on warmboot
- 3ds: forces sys mode, for compatibility with luma3ds (thanks psi)
- 3ds: faster power button and power off handling, and home button reset
- 3ds: init arm11 irq targets (in case they were destroyed by fastboot.3ds)
- 3ds: issues disconnect_cmd after upload (doing same on dsi/ar6013 crashes?)
Re: DSi Wifi rev-engineering
by on (#242362)
Hello,
I've been having an issue with Wifiboot, namely it doesn't recognize hidden WiFi networks.
I have configured my router to have a guest, non-password protected WiFi hotspot with MAC filtering just for the DS consoles.
If I enable SSID broadcasting, everything works fine, however, when I turn it off, while the consoles can still connect to the hotspot (via games or via the Internet config screen), Wifiboot suddenly can't connect anymore.

Another "issue" is the application doesn't have any icon (really doesn't matter, but I figured I could point it out)
Re: DSi Wifi rev-engineering
by on (#242402)
Yes, sorry, hidden networks aren't supported in wifiboot (nor dslink). The channel scanning relies on receiving Beacons with SSID strings from the access point. I didn't even knew that Nintendo supports that hidden access point feature - and don't know if/how I could implement it. First of, two questions:

Why are you doing that, is that your security fix fow using WEP, or some energy saving scheme?
And are you really using a DS console, or a DSi?

Implementing that feature should be probably done by sending a Probe Request to the access point, and then receiving a Probe Response (which is equivalent to normal Beacons).
I had considered doing that even for normal access points because it might save 100ms of time spend on waiting for Beacons to arrive.
On the other hand, it would require sending Probe Request to all 3 or 6 access points - and if they do actually all respond with Probe Responses then packets would be more likely to collide and things might get slower and/or more unreliable.

With NDS-Wifi it should be possible to send Probe Requests, but I have no idea if (or how) DSi-Wifi does support it. The other approach that might work would be blindly trying to connect to the access points without any Beacons or Probing, but that might also slow down things when trying to connect to all 3 or 6 access points on all channels.

Altogether it would be easiest to use non-hidden access points. Unless....

Are those hidden access points a must-have feature used by many people?
Or do you know some good connection flowchart that would avoid most of the above possible problems?

PS. Yes, an icon would be nice... maybe a Wifi symbol or Download symbol or so.
Re: DSi Wifi rev-engineering
by on (#242404)
Google Search keyword: hidden ssid

Some people have recommended disabling beacons (or "hiding the SSID") based on the same logic as not having to outrun the proverbial lion: it makes you less visible as a target than nearby networks run by others. But disabling beacons doesn't add security. In fact, some operating systems are known to broadcast probe requests for all saved networks with hidden SSIDs continuously in case one is nearby, which leaks the SSIDs to others listening to your device's probe requests using Wireshark (doo doo doo-doo doo-doo).

Sources:
Re: DSi Wifi rev-engineering
by on (#242489)
First of all, thank you very much for replying.

nocash wrote:
Why are you doing that, is that your security fix fow using WEP, or some energy saving scheme?
And are you really using a DS console, or a DSi?

I really disabled SSID broadcast just for the convenience of not having an open but filtered showing up on every WiFi device in my house. I really don't care if people can still sniff the WiFi traffic, because I only use it for the DS consoles. And even if MAC filtering is still not impenetrable, I could just turn the WiFi network on when needed and then turn it off.
I do have a N3DS, DSi, DSL and DSP so I use both kind of consoles.

nocash wrote:
Altogether it would be easiest to use non-hidden access points. Unless....

Are those hidden access points a must-have feature used by many people?
Or do you know some good connection flowchart that would avoid most of the above possible problems?

I don't know, but if I had to guess it's just me and a few dozen people using a setup like this, most people probably use their phone with an open hotspot when they need to connect with the DS. Now I could be wrong, but if it turns out to be actually the case, I certainly don't pretend you implement a feature for just a few people to use.
Sorry, but I'm a complete noob when it comes to anything ever remotely related to low-level networking, so I can't be of much help with the second question :/

nocash wrote:
PS. Yes, an icon would be nice... maybe a Wifi symbol or Download symbol or so.

I propose a WiFi symbol next to a boot as the icon :P

tepples wrote:
In fact, some operating systems are known to broadcast probe requests for all saved networks with hidden SSIDs continuously in case one is nearby, which leaks the SSIDs to others listening to your device's probe requests using Wireshark (doo doo doo-doo doo-doo).

I don't think I'm extremely "vulnerable" to this exploit since the network is used exclusively by the DS consoles, and those only look for WiFi when it's strictly necessary.
Re: DSi Wifi rev-engineering
by on (#242507)
Okay, I'll probably leave hidden SSID's unimplemented. But, you have the hidden WEP guest mode compined with non-hidden WPA/WPA2? Then you could at least use the WPA/WPA2 access point for DSi (and 3DS).

zacchi4k wrote:
I propose a WiFi symbol next to a boot as the icon
Or Nancy Sinatra with a Wifi icon (and the melody playing during transfer).