Nintendo wifi config utility

From DeSmuME
Revision as of 21:05, 31 May 2009 by Luigi (Talk | contribs)
Jump to: navigation, search

The Nintendo wifi config utility is an utility that's provided with most wifi-compliant games.
It allows the user to easily connect to an access point.


The goal is to get this utility to recognize SoftAP (the software access point inside DeSmuME).


The utility doesn't rely on beacons to find access points. It does active scanning.
It sends probe request frames periodically and examinates the probe responses received from access points.


The problem is that, on DeSmuME, that util doesn't seem to like the probe responses generated by SoftAP.
It always overwrites the first few bytes of the response. It seems to want to read the packet header, but
instead it'll read at the end of the packet. The possible causes of that problem are:

  1. incorrect wifi emulation
  2. unknown wifi mode
  3. CPU bug


After investigating, I found that the util wants to read two values in the RX header (frame type and
transfer rate), but instead of reading them at <packet_start> and <packet_start + 0x6>, it reads them at
<u16[packet_start+0x8] + 0xC> and <u16[packet_start+0x8] + 0x12>.


I believe the issue is most likely a CPU bug. Because I've tested two homebrews that use the wifi lib by sgstair
(one of them is a modified version of the apConnect example provided with devKitPro, the other one was provided
with the dswifi lib I think), and sometimes they'll hang while waiting for incoming packets. I tested them on my DS
and they always worked without hanging. That's why I believe there's a common bug between these homebrews and the Nintendo
wifi config util. That common bug is likely a CPU bug, seeing the consequences:

  1. with the homebrews, sometimes, hanging, and possibly screens turning white
  2. with the util, values read from right after the packet body (they should be read from the RX header)


Here are the instructions executed when the util accesses what should be the first halfword of the packet
(but is the halfword located right after the packet body):

0600CC40:
E3570EFB | cmp r7, FB0
21DA09BA | ldrhcs r0, [r10, +9A]
204770A0 | subcs r7, r7, r0, lsr 1
E59F02E8 | ldr r0, [pc, +2E8]
E1520000 | cmp r2, r0
9A000006 | bls 0600CC74
E59F02E0 | ldr r0, [pc, +2E0]
E1C800B0 | strh r0, [r8, 0]
E1A07006 | mov r7, r6
E1DA0BB4 | ldrh r0, [r10, +BB4]
E2800001 | add r0, r0, 1
E1CA0BB4 | strh r0, [r10, +BB4]
EA000025 | b 0600CD0C
0600CC74:
E3550000 | cmp r5, 0
0A000023 | beq 0600CD0C
E1570006 | cmp r7, r6
0A000021 | beq 0600CD0C
E1A01087 | mov r1, r7, lsl 1
E59F02A8 | ldr r0, [pc, +2A8]
E0800087 | add r0, r0, r7
E2811512 | add r1, r1, 4800000
E2811901 | add r1, r1, 4000
E1D110B0 | ldrh r1, [r1]

0600CD0C:
r8 = frame type from packet's RX header
E1D800B0 | ldrh r0, [r8]
E200000F | and r0, r0, F
E350000C | cmp r0, C
1A00004C | bne 0600CE50
E288000C | add r0, r8, C
EBFFFE16 | bl 0600C580
E1D0B0B0 | ldrh r11, [r0]
E2880022 | add r0, r8, 22
EBFFFE13 | bl 0600C580
E1D060B0 | ldrh r6, [r0]
E1D900B0 | ldrh r0, [r9]
E1500006 | cmp r0, r6
1A000009 | bne 0600CD68
E21B0B02 | ands r0, r11, 800
0A000007 | beq 0600CD68
E59F01D0 | ldr r0, [pc, +1D0]
...

Translation to pseudocode:

* proc_0600CC40:
if(r7 >= 0xFB0)
 r0 = halfword[r10 + 0x9A];
 r7 -= (r0 >> 1);
r0 = word[pc + 0x2E8];
if(r2 <= r0)
 goto label_0600CC74;
r0 = word[pc + 0x2E0];
halfword[r8] = r0;
r7 = r6; // r6 = 0x0000061E
r0 = halfword[r10 + 0xBB4];
r0++;
halfword[r10 + 0xBB4] = r0;
goto proc_0600CD0C; // this routines decrements r7 by 2. is it really supposed to do that?
* label_0600CC74:
if(r5 == 0)
 goto proc_0600CD0C;
if(r7 == r6)
 goto proc_0600CD0C;
r1 = (r7 << 1);
r0 = word[pc + 0x2A8];
r0 += r7;
r1 += 0x4800000;
r1 += 0x4000;
r1 = halfword[r1];

Personal tools