Skip to main content
The Wii Remote (Wiimote) communicates with the Wii console (and Dolphin) via Bluetooth using the HID (Human Interface Device) protocol. This document details the Bluetooth communication protocol based on actual packet captures.

Device Information

Device Name: Nintendo RVL-CNT-01
Device Type: Bluetooth HID device
Bluetooth Profile: HID (0x1124)
Profile Version: 0x100

Bluetooth Connection Process

Discovery and Inquiry

The Wiimote must first be discovered through Bluetooth inquiry:
< HCI Command: Inquiry (0x01|0x0001) plen 5
    lap 0x9e8b33 len 8 num 0
> HCI Event: Command Status (0x0f) plen 4
    Inquiry (0x01|0x0001) status 0x00 ncmd 1
> HCI Event: Inquiry Complete (0x01) plen 1
    status 0x00
During inquiry, the Wiimote continues to send periodic button state updates even before connection is established.

Connection Establishment

Once discovered, establish connection using the Wiimote’s Bluetooth address:
< HCI Command: Create Connection (0x01|0x0005) plen 13
    bdaddr 00:1F:C5:36:2B:32 ptype 0xcc18 rswitch 0x01 clkoffset 0x0000
    Packet type: DM1 DM3 DM5 DH1 DH3 DH5
> HCI Event: Command Status (0x0f) plen 4
    Create Connection (0x01|0x0005) status 0x00 ncmd 1
> HCI Event: Connect Complete (0x03) plen 11
    status 0x00 handle 12 bdaddr 00:1F:C5:36:2B:32 type ACL encrypt 0x00

Feature Discovery

After connection, query device features:
< HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2
    handle 12
> HCI Event: Read Remote Supported Features (0x0b) plen 11
    status 0x00 handle 12
    Features: 0xbc 0x02 0x04 0x38 0x08 0x00 0x00 0x00
< HCI Command: Write Link Policy Settings (0x02|0x000d) plen 4
    handle 12 policy 0x0f
    Link policy: RSWITCH HOLD SNIFF PARK
> HCI Event: Command Complete (0x0e) plen 6
    status 0x00 handle 12

Device Naming

< HCI Command: Remote Name Request (0x01|0x0019) plen 10
    bdaddr 00:1F:C5:36:2B:32 mode 2 clkoffset 0x0000
> HCI Event: Remote Name Req Complete (0x07) plen 255
    status 0x00 bdaddr 00:1F:C5:36:2B:32 name 'Nintendo RVL-CNT-01'

L2CAP Channels

The Wiimote uses L2CAP (Logical Link Control and Adaptation Protocol) for data communication.

Channel Establishment

SDP Channel (PSM 1) - Service Discovery:
< ACL data: handle 12 flags 0x02 dlen 12
    L2CAP(s): Connect req: psm 1 scid 0x0040
> ACL data: handle 12 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0043 scid 0x0040 result 0 status 0
      Connection successful
HID Control Channel (PSM 0x11):
L2CAP(s): Connect req: psm 17 scid 0x0040
HID Interrupt Channel (PSM 0x13):
L2CAP(s): Connect req: psm 19 scid 0x0041

Channel Configuration

After connection, configure channel parameters:
< ACL data: handle 12 flags 0x02 dlen 12
    L2CAP(s): Config req: dcid 0x0043 flags 0x00 clen 0
> ACL data: handle 12 flags 0x02 dlen 18
    L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 4
      Success
      MTU 185
The Wiimote uses an MTU (Maximum Transmission Unit) of 185 bytes for L2CAP communication.

Service Discovery Protocol (SDP)

The Wiimote exposes two SDP service records:

Service Record 0x10000 (HID Service)

Service Record Handle: 0x10000
Service Class ID List: HID (0x1124)
Protocol Descriptor List:
  - L2CAP (0x0100) on channel 0x11
  - HIDP (0x0011)
Browse Group List: Public Browse Group (0x1002)
Language Base Attribute ID List:
  - Language: en (0x656e)
  - Encoding: UTF-8 (0x6a)
  - Base: 0x100
Bluetooth Profile Descriptor List:
  - HID (0x1124) version 0x100
Service Name: "Nintendo RVL-CNT-01"
Service Description: "Nintendo RVL-CNT-01"
Provider Name: "Nintendo"
HID-Specific Attributes:
Attribute IDTypeValueDescription
0x0200uint0x100HID Parser Version
0x0201uint0x111Device Subclass
0x0202uint0x4Country Code
0x0203uint0x33Virtual Cable
0x0204bool0x0Reconnect Initiate
0x0205bool0x1Normally Connectable
0x0206data(HID descriptor)HID Descriptor List
0x0207data0x409, 0x100Language ID Base List
0x0208bool0x0SDP Disable
0x0209bool0x1Battery Power
0x020abool0x1Remote Wake
0x020buint0x100Profile Version
0x020cuint0xc80Supervision Timeout
0x020dbool0x0Normally Connectable
0x020ebool0x0Boot Device

Service Record 0x10001 (PnP Information)

Service Record Handle: 0x10001
Service Class ID List: PNP Information (0x1200)
Protocol Descriptor List:
  - L2CAP (0x0100) on channel 0x1
  - SDP (0x0001)
Browse Group List: Public Browse Group (0x1002)
Bluetooth Profile Descriptor List:
  - PNP Information (0x1200) version 0x100
Attributes:
Attribute IDTypeValue
0x0200uint0x100
0x0201uint0x57e
0x0202uint0x306
0x0203uint0x600
0x0204bool0x1
0x0205uint0x2

HID Descriptor

The Wiimote’s HID descriptor (attribute 0x0206) defines its report structure:
05 01 09 05 a1 01 85 10 15 00 26 ff 00 75 08 95 01 06 00 ff 09 01 91 00
85 11 95 01 09 01 91 00 85 12 95 02 09 01 91 00 85 13 95 01 09 01 91 00
85 14 95 01 09 01 91 00 85 15 95 01 09 01 91 00 85 16 95 15 09 01 91 00
85 17 95 06 09 01 91 00 85 18 95 15 09 01 91 00 85 19 95 01 09 01 91 00
85 1a 95 01 09 01 91 00 85 20 95 06 09 01 81 00 85 21 95 15 09 01 81 00
85 22 95 04 09 01 81 00 85 30 95 02 09 01 81 00 85 31 95 05 09 01 81 00
85 32 95 0a 09 01 81 00 85 33 95 11 09 01 81 00 85 34 95 15 09 01 81 00
85 35 95 15 09 01 81 00 85 36 95 15 09 01 81 00 85 37 95 15 09 01 81 00
85 3d 95 15 09 01 81 00 85 3e 95 15 09 01 81 00 85 3f 95 15 09 01 81 00
c0

Report IDs

The descriptor defines multiple report types: Output Reports (0x91):
Report IDSizeDescription
0x101 byteCommand
0x111 byteCommand
0x122 bytesCommand
0x131 byteCommand
0x141 byteCommand
0x151 byteCommand
0x1621 bytesCommand
0x176 bytesCommand
0x1821 bytesCommand
0x191 byteCommand
0x1a1 byteCommand
Input Reports (0x81):
Report IDSizeDescription
0x206 bytesCore buttons
0x2121 bytesCore buttons + accelerometer
0x224 bytesCore buttons (IR basic)
0x302 bytesCore buttons
0x315 bytesCore buttons + accelerometer
0x3210 bytesCore buttons + 8 extension bytes
0x3317 bytesCore buttons + accelerometer + 12 IR bytes
0x3421 bytesCore buttons + 19 extension bytes
0x3521 bytesCore buttons + accelerometer + 16 extension bytes
0x3621 bytesCore buttons + 10 IR bytes + 9 extension bytes
0x3721 bytesCore buttons + accelerometer + 10 IR bytes + 6 extension bytes
0x3d21 bytesExtension only
0x3e21 bytesInterleaved core buttons + accelerometer
0x3f21 bytesInterleaved core buttons + accelerometer + IR

Data Communication

The Wiimote continuously sends button state updates through the HID interrupt channel:
> ACL data: handle 12 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 0]
      0000: a1 30 00 10                                       .0..

Button State Packet Format

Byte 0: 0xa1 (HID report header)
Byte 1: Report ID (e.g., 0x30 for core buttons)
Byte 2-3: Button state bitfield
Example button states:
  • a1 30 00 10 - Button 1 pressed
  • a1 30 00 00 - No buttons pressed
  • a1 30 10 00 - Button 2 pressed
The Wiimote sends button state updates continuously, even when no buttons are pressed, to maintain connection and provide real-time input.

Connection Teardown

Disconnect L2CAP Channel

< ACL data: handle 12 flags 0x02 dlen 12
    L2CAP(s): Disconn req: dcid 0x0043 scid 0x0040
> ACL data: handle 12 flags 0x02 dlen 12
    L2CAP(s): Disconn rsp: dcid 0x0043 scid 0x0040
< HCI Command: Disconnect (0x01|0x0006) plen 3
    handle 12 reason 0x13
    Reason: Remote User Terminated Connection
> HCI Event: Command Status (0x0f) plen 4
    Disconnect (0x01|0x0006) status 0x00 ncmd 1
> HCI Event: Disconn Complete (0x05) plen 4
    status 0x00 handle 12 reason 0x16
    Reason: Connection Terminated by Local Host

Packet Flow Control

Bluetooth uses flow control to manage packet transmission:
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 12 packets 2
This event indicates that 2 packets have been successfully transmitted and the host can send more data.

Implementation Notes for Dolphin

Connection Handling

  1. Perform Bluetooth inquiry to discover Wiimote
  2. Create ACL connection to Wiimote’s Bluetooth address
  3. Query device features and set link policy
  4. Establish L2CAP channels for SDP, HID control, and HID interrupt
  5. Parse HID descriptor to understand report formats

Data Reception

  1. Listen on HID interrupt channel (PSM 0x13)
  2. Parse report ID to determine data format
  3. Extract button states, accelerometer data, IR data, extension data
  4. Update emulated Wiimote state

Timing Considerations

  • Wiimote sends updates approximately every 5-10ms
  • ACL packet fragmentation occurs for larger reports
  • Flow control events must be respected to avoid packet loss
When implementing Wiimote emulation, ensure proper handling of ACL packet fragmentation (flags 0x02 for first packet, 0x01 for continuation) to correctly reassemble L2CAP frames.

Reference Materials

The Wiimote uses standard Bluetooth HID protocols defined in:
  • Bluetooth Core Specification
  • HID Profile Specification v1.0
  • USB HID Usage Tables
For complete protocol details, refer to HID_SPEC_V10.rar in the source documentation.