Nintendo DS ni-fi protocol information
This page will not be updated. The information is being moved to a wiki (page address coming soon)
where it can be easily expanded and corrected.
You will find some information regarding the Nintendo DS ni-fi protocol on this page.
It has been collected through experimenting and sources on the Web. The information
may not be correct and my wireless protocol knowledge is only what I have learnt whilst playing around
hacking the DS. You can find some more information on WMB transfers
here. Fields are
little endian (boo hiss).
The frames are close to the IEEE802.11 standard only deviating by missing some parameters.
The DS only uses short preamble.
I do not know much about how things change when more than two DSs are around.
When a DS is hosting a Pictochat room or WMB download it acts as an access point and broadcasts
beacons. These beacons do not have a SSID parameter. They have a vendor specific tagged parameter.
The tag number id 0xDD. The data for this parameter always starts with the three byte sequence
00:09:bf, identifying the parameter as Nintendo.
So the layout of the beacons is as follows:
Fixed parameters:
Timestamp
Beacon Interval
Capability Information: (0x0021 - Transmitter is AP, Short Preamble allow)
Tagged parameters:
Supported Rates: (1 Mbit/s and 2Mbit/s)
DS parameter set (gives the channel number the host is using)
Traffic Indication Map (DTIM period of 2, DTIM coutn alternate between 0 and 1)
Nintendo Parameter
The initial 21 bytes (after the Nintendo ID) appear in all beacons I have seen sent out by a DS.
The following table gives
values of the bytes when the DS has been doing various things. The descriptions given is a possible
function of the byte.
| Beacon Type | Blank WMB (Meteos Demo) | WMB (Meteos Demo) | Pictochat room A | Meteos VS play | MKart VS play | Description |
| Offset |
| 00 | 00 | 00 | 00 | 00 | 00 | unknown |
| 01 | 0a | 0a | 0a | 0a | 0a | unknown |
| 02 | 00 | 00 | 00 | 00 | 00 | unknown |
| 03 | 00 | 00 | 00 | c0 | 00 | unknown |
| 04 | 00 | 00 | 00 | 6f | 00 | unknown |
| 05 | 01 | 01 | 01 | 01 | 01 | unknown |
| 06 | 00 | 00 | 00 | 00 | 00 | unknown |
| 07 | 00 | 80 | 00 | 00 | 00 | A repeat of the two bytes at 0b? Showing something is active? |
| 08 | 00 | 00 | 00 | 00 | 00 | see previous |
| 09 | 17 | 17 | 00 | 17 | 25 | The values 17,00,80 and 00 are repeated as the first 4 bytes in the wmb header that follows if a wmb. These values vary between games. |
| 0a | 00 | 00 | 00 | 00 | 00 | see previous |
| 0b | 80 | 80 | 00 | 80 | 00 | see previous |
| 0c | 00 | 00 | 00 | 00 | 00 | see previous |
| 0d | 00 | 00 | 01 | 00 | 95 | This and the following byte are
used in association (see below) for picto and wmb. In the case of picto this number is incremented every so often. |
| 0e | 88 | 88 | 00 | 0a | b4 | see previous byte |
| 0f | 00 | 70 | 08 | 70 | 70 | payload size (in bytes) |
| 10 | 09 | 0b | 01 | 01 | 0b | unknown |
| 11 | 00 | 00 | c0 | 14 | fe | unknown |
| 12 | 01 | 01 | 00 | 01 | 01 | unknown |
| 13 | 08 | 08 | c0 | 44 | 08 | unknown |
| 14 | 00 | 00 | 48 | 00 | 00 | unknown |
| Payload size (in bytes) |
0 | 112 | 8 | 112 | 112 |
The Blank WMB is the first beacon sent out by a DS after starting up as a WMB host.
A WMB host follows the 21 intial bytes with further 112 (although there is no reason why this could
not vary as size fields are included). These 112 are divided into two parts, the
WMB header (14 bytes) and the payload.
The WMB beacons advertise the download being provided and the current clients connected.
The advert beacons come first followed by the client beacon(s). The transmission of the beacons
cycles round.
A non advert beacon must be included otherwise a DS will not pick up the beacons.
| Offset | Size (in bytes) | Description |
| 00 | 2 | Game Id (repeated from initial 21 bytes) |
| 02 | 2 | Stream Id (repeated from initial 21 bytes) |
| 04 | 1 | Non Advert payload marker |
| 05 | 1 | Unknown (only ever seen zero here) |
| 06 | 1 | Current number of clients connected |
| 07 | 1 | Sequence number |
| 08 | 2 | Checksum |
| 0a | 1 | Advert Sequence number |
| 0b | 1 | Advert length in beacons (not including non advert payload beacons) |
| 0c | 2 | Payload size in bytes |
The game id and stream called this as that is what I have seen them called elsewhere.
The non advert payload marker has a value of 0x00 for beacons contains advert payloads and a value
of 0x02 for beacons containing client information (see below).
The sequence number starts at zero for the first advert beacon and increase by one for each beacon
transmitted, resetting to zero when the first advert beacon is next transmitted.
A checksum over the bytes following this checksum field to the end of the payload. The checksum is the
negated sum of the 16 bit words. It can
be computed using the following C code. length is the number of 16 bit words to perform the
checksum over.
static uint16_t beacon_checksum(uint16_t *buff, int length) {
int j;
uint32_t crc = 0;
for (j = 0; j < length; j++) {
crc += buff[j];
}
crc = (crc >> 16) + (crc & 0xffff);
if ( crc & 0x10000) {
crc += 1;
}
crc = ~crc;
crc &= 0xffff;
return crc;
}
Advert sequence number follows the value of the first sequence number for advert payload beacons.
For client information beacons its value is ?? (I have seen 0x01 when no clients are connected and 0x02
when one client is connected).
The payload size gives the number of valid bytes following. If necessary more zero value bytes
are sent to make the beacon upto the correct length. This is not quite true for client payloads.
Advert payload
The advert has the following format:
| Offset | Size (in bytes) | Description |
| 0x0000 | 32 | Icon palette (from the banner in the nds file) |
| 0x0020 | 512 | Icon tiles (from the banner in the nds file) |
| 0x0220 | 1 | Unknown (value does not appear to matter) |
| 0x0221 | 1 | The length of the host name (in character) |
| 0x0222 | 20 | Host name (10 UCS-2 characters) |
| 0x0236 | 1 | Maximum number of player |
| 0x0237 | 1 | Unknown (value of 0x00) |
| 0x0238 | 96 | Game name (48 UCS-2 characters) |
| 0x0298 | 192 | Game description (96 UCS-2 characters) |
The game name and description can by retreived from the banner structure in the nds file.
This advert is split between 9 beacons, the first eight of which have a payload of 98 bytes
and the nineth 72 bytes.
Client payload
Not much known here. It is transmitted in beacons with the non advert marker field set to 0x2.
If no clients are connected then the payload size is set to 1 and the value of the byte
is 0x00.
If one client is connected then the payload size is set to 3. The value of the first two bytes
is 0x02, 0x00. The value of the third varies. The next bit breaks the payload size field in the
header (oh). The next byte gives the size of the client's name in characters. The client's
name then follows.
A DS with authenticate itself and then associate with a Host.
All management frames sent have the destination address and BSS id fields set to the value of the
source address and BSS id fields of the beacons sent by the host. The source address can be set to
whatever you like i.e. it does not have to be a Nintendo MAC address(00:09:bf).
Authentication is the same whatever the host is doing. The frame has the flags set to zero and the
parameters set as follows:
Authentication System : open (0x0000)
Authentication SEQ: 0x0001
Status code: success (0x0000)
The DS will respond with an Authentication frame with SEQ 0x0002 and if it is happy a status code
of success (0x0000). You can now attempt to associate with the DS.
The layout of the Association Request.
Fixed Parameters:
Capability Information: 0x0021 (ESS cap: Tranmitter is an AP, Short Preamble: Short preamble allowed)
Listen Interval: 0x0001
Tagged Parameters:
SSID parameter set (Tag number 0, length 32 bytes, value - see below)
Supported rates (Tag number 1, length 2 bytes, value 0x82 0x84 (1Mbit/s and 2Mbit/s))
For the association to be successful you need
to copy some data out to the Nintendo IE of the most recent beacon that the DS has sent you (the host
changes the value of the data after some number of beacons, the number of beacons between changes varies)
and into the SSID parameter of the AssocReq. All other bytes of the SSID are zero.
Copy two bytes at offset 0x10 from the Nintendo IE data into the bytes at offset 0x4 of the SSID parameter.
The DS will respond to your Assoc Req with a Assoc Resp and if is happy then the status code in the
response will be success (0x0000), if the SSID in your request is not correct the status will be 0x0001.
Any other status means you have problems elsewhere.
If the association is successful the DS will start shouting out data frames.
The layout of the Association Request
is as given for the Pictochat association. For this to be successful you need
to copy some data out to the Nintendo IE of the most recent beacon that the DS has sent you (I'm not
sure if the data does change but I'm playing it safe) and into the SSID parameter of the AssocReq.
All other bytes in the SSID are zero.
Copy 4 bytes starting at offset 0x18 from the Nintendo IE data into the first 4 bytes of the SSID parameter.
Copy 2 bytes starting at offset 0x10 from the Nintendo IE data into the following bytes (i.e. begining at offset 0x4) of the SSID parameter.
The DS will respond to your Assoc Req with a Assoc Resp and if is happy then the status code in the
response will be success (0x0000), if the SSID in your request is not correct the status will be 0x0001.
Any other status means you have problems elsewhere.
If the association is successful the DS will start shouting out data frames.
Data transferr is always initiated by the host. The host sends out Data + CF-Poll frames to which the
client replies with Data + CF-Ack frame. The client can respond with no data + CF-Ack frames if it
is not in a position to give a data response.
Data frames are sent to multicast addresses.
03:09:bf:00:00:00 - the hosts sends Data + CF-Poll frames for the client to this
address. These frames contains the commands.
03:09:bf:00:00:03 - the hosts sends Data + CF-Ack frames to this address shortly after
it transmits a frame to the 00:00:00 address. The data comprise four bytes which values change with
each transmission. The client will happily accept a download from a host that is not sending these
frames. A DS host expects the client to response in the window between the 00:00:00 CF-Poll and this
frame.
03:09:bf:00:00:10 - the client sends Data (no data) + CF-Ack frames to this address
in response to the host's CF-Poll frames.
bing bong
bing bong
|