Wiimote/Protocol

From WiiBrew
Jump to navigation Jump to search

Bluetooth Communication

The wiimote communicates with the host via standard bluetooth protocol. The wiimote can be placed into discoverable mode for 20s by pressing the sync button on its back under the battery cover. Holding down the 1 and 2 button continuously will force the wiimote to stay in discoverable mode without turning off. This does not work with the sync button, though. When in discoverable mode, a number of the player LEDs based on the battery level will blink. With full battery all four LEDs will blink, the lower the battery the less LEDs will blink. During device inquiry the host will find all discoverable nearby wiimotes. Now the host can establish a bluetooth baseband connection to the wiimote, no bluetooth pairing is needed, however, if bluetooth pairing is performed, the wiimote is able to reconnect to the host if disconnected. After a bluetooth baseband connection is established (with or without pairing) the HID channels can be opened and used for reading and writing reports from/to the wiimote.

The newer Wiimote RVL-CNT-01-TR shuts down immediately upon receiving any HID output report if it has been turned on using the 1 + 2 method, although it works using the sync button. It is possible that authentication is now mandatory for the 1 + 2 temporary sync[check].

Bluetooth Pairing

The wiimote supports the legacy bluetooth pairing methods. This involves sending a PIN to the wiimote. Bluetooth pairing is not required to use a wiimote and you can proceed by establishing a HID connection without pairing at all. However, if the wiimote is paired, it will actively seek out for its last connected host on disconnection and reestablish the connection. The following section explains the bluetooth device pairing, if no pairing is required, skip this section.

Bluetooth pairing must be initiated by the host by sending a "Require Authentication" HCI command to its bluetooth device. The bluetooth device will ask the host for a link key, which must be rejected so it will ask for a PIN-Code. The PIN-Code is the binary bluetooth address of the wiimote backwards. Following a short piece of C code to calculate the PIN:

Lets assume the Wiimote has the bluetooth address "00:1E:35:3B:7E:6D". If you want the PIN for bluetooth pairing in a simple string, do the following:

char pin[6];
pin[0] = 0x6D;
pin[1] = 0x7E;
pin[2] = 0x3B;
pin[3] = 0x35;
pin[4] = 0x1E;
pin[5] = 0x00;

Now "pin" contains your bluetooth pin that should be used for pairing your devices.

If connecting by holding down the 1+2 buttons, the PIN is the bluetooth address of the wiimote backwards, if connecting by pressing the "sync" button on the back of the wiimote, then the PIN is the bluetooth address of the host backwards.

After sending the PIN to the bluetooth device via HCI commands, the wiimote will return a "Authentication Accepted" command and the pairing is established (both devices are bonded now). After pairing you continue with establishing the HID connection the same way as without pairing.

If the host successfully bonded with the wiimote and established an HID connection the wiimote will save the bluetooth address of the host and enable single press reconnection. That means if the wiimote is now disconnected from the host, it will actively seek out for the host if any button is pressed and establish a baseband and HID connection. The wiimote will never actively send pairing requests since this is not needed. Also remember that this works with any button not only the power-button. However, after establishing the connection, the wiimote sends a button-input-report and this allows the host to see what button was pressed. So the host may reject the new connection if any button except the power-button was pressed.

The new bluetooth pairing method SSP (Secure Simple Pairing) is not supported. Also it is not yet investigated whether a link key has to be created (by sending a PIN) on every connection or whether the link key can be saved and reused on new connections. Though, creating a new link key on every connection works fine.

The wiimote has space for several host addresses (at least 3 are known to work) so it can be paired with more than one host (like PC or Wii) and it will try in reverse order to reconnect to the hosts. That is, the last paired host is tried first and so one. If button 1 and 2 or the sync button on its back are pressed, the wiimote will not actively seek out for its host but instead place itself in discoverable mode and wait for incoming connections so bluetooth pairing does not conflict with normal host-side connections.

It is not known how to remove the hosts addresses from the wiimote, however, with some investigation it should be possible to locate them in the EEPROM and manipulate them. If this is considered a security issue, then don't pair your devices.

SDP information

When queried with the Bluetooth Service Discovery Protocol (SDP), the Wii Remote reports back a great deal of information. In particular, it reports:

Wii Remote/old Wii Remote Plus new Wii Remote Plus
Name Nintendo RVL-CNT-01 Nintendo RVL-CNT-01-TR
Vendor ID 0x057e 0x057e
Product ID 0x0306 0x0330
Major Device Class 1280 ?
Minor Device Class 4 ?
Service Class 0 ?
(Summary of all Class Values) 0x002504 0x000508

HID Interface

Establishing a HID connection with the Wii Remote can be done on PSM 0x11 for the control pipe and PSM 0x13 for the data pipe using the Bluetooth L2CAP protocol. On Windows you don't need to deal with L2CAP yourself, and can use high-level windows HID functions.

The HID standard allows devices to be self-describing, using a HID descriptor block. This block includes an enumeration of reports that the device understands. A report can be thought of similar to a network port assigned to a particular service. Reports are unidirectional however, and the HID descriptor lists for each port the direction (Input or Output) and the payload size for each port. Like all Bluetooth HID devices, the Wii Remote reports its HID descriptor block when queried using the SDP protocol. However, no information regarding the actual data units within each report is returned, only the length in bytes.

Note: An "Input" report is sent by the Wii Remote to the host. An "Output" report is sent by the host to the Wii Remote. When using a Wii Remote, all input reports are prepended with 0xa1 and all output reports are prepended with 0xa2; this is the "(a2)" in many example reports below. Output reports are sent over the data pipe, which is also used to read input reports (thus, the control pipe is essentially unused).

The original Wiimotes (RVL-CNT-01) allowed sending commands using SET REPORT (0x52) over the control pipe, instead of using the data pipe; however, this form does not work on the newer RVL-CNT-01-TR, and as such is not recommended.

These are the reports the Wii Remote uses, and their use:

I/O ID(s) Size Function
O 0x10 1 Rumble
O 0x11 1 Player LEDs
O 0x12 2 Data Reporting mode
O 0x13 1 IR Camera Enable
O 0x14 1 Speaker Enable
O 0x15 1 Status Information Request
O 0x16 21 Write Memory and Registers
O 0x17 6 Read Memory and Registers
O 0x18 21 Speaker Data
O 0x19 1 Speaker Mute
O 0x1a 1 IR Camera Enable 2
I 0x20 6 Status Information
I 0x21 21 Read Memory and Registers Data
I 0x22 4 Acknowledge output report, return function result
I 0x30-0x3f 2-21 Data reports

For clarity, the convention in this document is to show packets including the Bluetooth-HID command (in parentheses), report ID, and payload, as described in sections 7.3 and 7.4 of the Bluetooth HID specification. Each byte is written out in hexadecimal, without the 0x prefix, separated by spaces. For example,

(a1) 30 00 00

is a DATA input packet (0xa1), on channel 0x30, with the two byte payload 0x00, 0x00. When using higher level HID functions rather than Bluetooth functions, the bytes in parentheses will never be present.

Force Feedback is accessible through the first byte of ALL output reports in the same way. This is not included above to avoid clutter.

Output Report common information

The first byte in many Output reports has a similar meaning. In every single Output Report, bit 0 (0x01) of the first byte controls the Rumble feature. Additionally, bit 2 (0x04) is used in several Output Reports as the ON/OFF flag for the specific feature controlled by it. For example, sending 0x04 to Report 0x19 (Speaker Mute) will mute the speaker:

(a2) 19 04

Sending 0x00 will unmute it:

(a2) 19 00

These Output Reports share the above behavior: Data Reporting Mode (0x12), IR Camera Enable (0x13), Speaker Enable (0x14), Speaker Mute (0x19), IR Enable 2 (0x1a).

Input Report common information

The first two bytes of ALL input reports, except 0x3d, contain the Core Buttons (BB BB). This includes all the 0x2~ status reports, not just the 0x3~ data reports. 0x3d is an exception, since it only returns expansion information.

Status Reporting

0x20: Status

To request the status report, send anything to Output Report 0x15. The Status Report will also be automatically sent when an Extension Controller is connected or disconnected.

This will request the status report (and turn off rumble):

(a2) 15 00

This report is sent either on request (in response to report 0x15), or in response to an expansion being plugged in or unplugged (or synced if wireless). If this report is received when not requested, the application 'MUST' send report 0x12 to change the data reporting mode, otherwise no further data reports will be received.

(a1) 20 BB BB LF 00 00 VV

BBBB is the core Buttons data. VV is the current battery level, L is the LED state, and F is a bitmask of flags indicating, whether the battery is flat, whether an expansion is currently connected, etc.

The Wii Remote can report its status, which includes the state of a few basic settings, the status of the Extension Controller (connected or disconnected), and the battery level.

VV is the current battery level, and LF is a bitmask of flags:

Bit Mask Meaning
0 0x01 Battery is nearly empty
1 0x02 An Extension Controller is connected
2 0x04 Speaker enabled
3 0x08 IR camera enabled
4 0x10 LED 1
5 0x20 LED 2
6 0x40 LED 3
7 0x80 LED 4

0x21: Read Memory Data

This report is sent when a read memory request is made. It returns 1 to 16 bytes of data at a time.

(a1) 21 BB BB SE AA AA DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD

BBBB is the core Buttons data.

S (high nybble of SE) is the size in bytes, minus one, for the current data packet. This is 0xf (16 bytes) for all but the last packet, where it might be less if the requested number of bytes is not a multiple of 16.

E (low nybble of SE) is the error flag. Known error values are 0 for no error, 7 when attempting to read from a write-only register or an expansion that is not connected, and 8 when attempting to read from nonexistant memory addresses.

AA AA are the 2 least significant bytes of the absolute memory address of the first byte of data returned (the high byte of the offset is not returned, and neither is whether it is a register or memory that is being used. Thus, this must be known from the read request).

The DD bytes are the data, padded with zeroes to 16 bytes. If more than 16 bytes are requested, multiple packets will be received, with AA AA addresses increasing by 16 each time.

0x22: Acknowledge output report, return function result

This input report is sent to the host to report an error related to an output report, or the function result from that output report. It is sent when bit 1 of the first byte of any output report is set.

(a1) 22 BB BB RR EE

BBBB is the core Buttons data.

RR is the output report number that the Wii remote is acknowledging it received.

EE is the error code or function result. 00 = success. 03 = error. 04 = unknown (possibly returned by report 16H, 17H or 18H) 05 = unknown (possibly returned by report 12H). 08 = unknown (possibly returned bt report 16H).

Data Reporting

The Wii Remote has a number of different data reporting modes. Each of these modes combines certain Core data features with data from external peripherals, and sends it to the host through one of the report IDs, determined by the mode. The data format from the peripherals is determined by the peripherals themselves, all the Wii Remote controller does is pull bytes from them and send them out to the host. Due to this, certain feature combinations are not available, as there are not enough bytes for them in any of the output modes.

The Data Reporting Mode is set by sending a two-byte command to Report 0x12:

(a2) 12 TT MM

Bit 2 of TT specifies whether continuous reporting is desired. If bit 2 (0x04) is set, the Wii Remote will send reports whether there has been any change to the data or not. Otherwise, the Wii Remote will only send an output report when the data has changed.

MM specifies the Reporting Mode. Each Mode is specified by the Output Report ID that the data will be sent to. For example, this will set mode to 0x33:

(a2) 12 00 33

Data will then arrive through Input Report 0x33.

Upon powerup, the Data Reporting Mode defaults to 0x30. Following a connection or disconnection event on the Extension Port, data reporting is disabled and the Data Reporting Mode must be reset before new data can arrive.

Modes which include Accelerometer data also embed part of it in the unused Buttons bits. In all modes except for 0x3e/0x3f, the Buttons data includes the LSBs of the Accelerometer data. In mode 0x3e/0x3f, the interleaved Buttons data includes the Z-axis Accelerometer data.

0x30: Core Buttons

This mode returns data from the buttons in the Wii Remote:

(a1) 30 BB BB

BBBB is the core Buttons data.

0x31: Core Buttons and Accelerometer

This mode returns data from the buttons and the accelerometer in the Wii Remote:

(a1) 31 BB BB AA AA AA

BBBB is the core Buttons data. AA AA AA is the Accelerometer data.

0x32: Core Buttons with 8 Extension bytes

This mode returns data from the buttons in the Wii Remote, and data from an extension controller connected to it:

(a1) 32 BB BB EE EE EE EE EE EE EE EE

BBBB is the core Buttons data. The 8 EE bytes are from the Extension Controller currently connected to the Wii Remote.

0x33: Core Buttons and Accelerometer with 12 IR bytes

This mode returns data from the buttons, accelerometer, and IR Camera in the Wii Remote:

(a1) 33 BB BB AA AA AA II II II II II II II II II II II II 

BBBB is the core Buttons data. AA AA AA is the Accelerometer data. The 12 II bytes are from the built-in IR Camera.

0x34: Core Buttons with 19 Extension bytes

This mode returns data from the buttons in the Wii Remote, and data from an extension controller connected to it:

(a1) 34 BB BB EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE 

BBBB is the core Buttons data. The 19 EE bytes are from the Extension Controller currently connected to the Wii Remote.

0x35: Core Buttons and Accelerometer with 16 Extension Bytes

This mode returns data from the buttons and accelerometer in the Wii Remote, and data from an extension controller connected to it:

(a1) 35 BB BB AA AA AA EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE

BBBB is the core Buttons data. AA AA AA is the Accelerometer data. The 16 EE bytes are from the Extension Controller currently connected to the Wii Remote.

0x36: Core Buttons with 10 IR bytes and 9 Extension Bytes

This mode returns data from the buttons and IR camera in the Wii Remote, and data from an extension controller connected to it:

(a1) 36 BB BB II II II II II II II II II II EE EE EE EE EE EE EE EE EE

BBBB is the core Buttons data. The 10 II bytes are from the built-in IR Camera, and the 9 EE bytes are from the Extension Controller currently connected to the Wii Remote.

0x37: Core Buttons and Accelerometer with 10 IR bytes and 6 Extension Bytes

This mode returns data from the buttons, accelerometer, and IR camera in the Wii Remote, and data from an extension controller connected to it:

(a1) 37 BB BB AA AA AA II II II II II II II II II II EE EE EE EE EE EE

BBBB is the core Buttons data. AA AA AA is the Accelerometer data. The 10 II bytes are from the built-in IR Camera, and the 6 EE bytes are from the Extension Controller currently connected to the Wii Remote.

0x3d: 21 Extension Bytes

This mode returns data from an extension controller connected to the Wii Remote. It is the only input report that does not include core buttons.

(a1) 3d EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE

The 21 EE bytes are from the Extension Controller currently connected to the Wii Remote.

0x3e / 0x3f: Interleaved Core Buttons and Accelerometer with 36 IR bytes

Both 0x3e and 0x3f are equivalent, and return data alternately through report IDs 0x3e and 0x3f. The data is interleaved, and is returned at half the speed of other modes (as two reports are needed for a single data unit). This mode returns data from the buttons, accelerometer, and IR camera in the Wii Remote:

(a1) 3e BB BB AA II II II II II II II II II II II II II II II II II II
(a1) 3f BB BB AA II II II II II II II II II II II II II II II II II II

BBBB is the core button data, as specified in the Buttons section. AA AA is the Accelerometer data, in a format specific to this mode described in the Interleaved Accelerometer Reporting section. The 36 II bytes are from the built-in IR Camera.

Memory and Registers

The Wii Remote includes a built-in EEPROM memory, part of which is accessible to the user to store that. This user part is used to store calibration constants, as well as the Mii Data. Additionally, many peripherals on the Wii Remote have registers which are accessible through a portion of the address space.

Both built-in memory and peripheral registers are accessed using the same reports, where a flag is used to select between the two.

Reading and Writing

To read data, commands are sent to Output Report 0x17:

(a2) 17 MM FF FF FF SS SS

FF FF FF is the offset, and SS SS is the size to read in bytes (both in big-endian format). Bit 2 (0x04) of MM selects the address space. Clearing this bit results in reading from EEPROM Memory, while setting it results in reading from the control registers. Setting bit 3 (0x08) also works to access registers, but setting both results in errors. As with all other reports, it also includes the Rumble flag, which must be set to the current rumble state to avoid affecting it.

Data read is returned through Input Report 0x21:

(a1) 21 BB BB SE FF FF DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD

BB BB is the state of the buttons on the Wii Remote. During data reads, regular input reporting is temporarily suspended. Button data is available through the data input reports, but no other input data can be collected while the transfer lasts. FF FF is the offset expressed in absolute memory address of the Wii remote memory for the first byte of data returned (the high byte of the offset is not returned, and neither is which data memory is being used. Thus, this must be known from the read request). E (low nybble of SE) is the error flag. Known error values are 0 for no error, 7 when attempting to read from a write-only register, and 8 when attempting to read from nonexistant memory. S (high nybble of SE) is the size in bytes, minus one, for the current data packet. This is 0xf (16 bytes) for all but the last packet, where it might be less if the requested number of bytes is not a multiple of 16. The DD bytes are the data, padded with zeroes to 16 bytes. If more than 16 bytes are requested, multiple packets will be received, with FF FF offsets increasing by 16 each time.

To write data, commands are sent to Output Report 0x16:

(a2) 16 MM FF FF FF SS DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD DD

The meaning of the bytes is the same as during reads, except that size can be a maximum of 16 bytes (as there is only space for that much data), and the actual data to write follows (the DD bytes), padded out to 16 bytes.

Some kind of acknowledgement is received on Input Report 0x22. This has not been investigated yet.