BlueZ
From WiiLi
BlueZ is a C library that can be downloaded to utilize the Bluetooth protocol in Linux. It is currently included in the 2.4 or 2.6 kernels, yet you may need the source code to compile it into your own driver code.
Contents |
[edit] Documentation
BlueZ has really crappy API documentation, which is probably why everyone is using Python to write their "drivers" at the moment. But eventually a proper daemon or perhaps kernel module needs to be written in C. Here are some good references I've found about the BlueZ code:
- Some slides by the Bluez crew: [1]
- Master thesis about Bluetooth: [2]
- Introduction to Bluetooth programming under Linux: [3]
- Some HCI docs from AFFIX (not bluez, warning!) [4]
[edit] Data Structures
bdaddr_t
Bluetooth device address data structure. Basically a packed 6 byte address:
/* BD Address */
typedef struct {
uint8_t b[6];
} __attribute__((packed)) bdaddr_t;
(line 103 bluetooth/bluetooth.h in 2.6.15 kernel)
inquiry_info
typedef struct {
bdaddr_t bdaddr;
uint8_t pscan_rep_mode;
uint8_t pscan_period_mode;
uint8_t pscan_mode;
uint8_t dev_class[3];
uint16_t clock_offset;
} __attribute__ ((packed)) inquiry_info;
(line 1089 of bluetooth/hci.h)
Most useful thing here is the BD address. The other stuff is of little interest to us, though it might be cool to output the piconet clock_offset! :)
[edit] Functions
int str2ba ( const char *str, bdaddr_t *ba );
Takes a null terminated string str and dumps the equivalent bluetooth address into ba.
int ba2str ( bdaddr_t *ba, const char *str );
Takes a bdaddr_t structure and turns it into a null terminated string. Useful for outputting information. (e.g. storing a known Wii controller)
int hci_get_route( bdaddr_t *bdaddr );
Finds you the device ID (e.g. which dongle you're using!) which has a route to the desired device. In any sane case there will only be one dongle and so its safe to pass this function NULL, and it'll return this device's number. As it happens that number is usually zero! :)
int hci_open_dev ( int dev_id);
Opens a bluetooth socket with the specified device ID. (e.g. the dongle)
int hci_inquiry(int dev_id, int len, int max_rsp, const unit8_t *lap, inquiry_info **ii, long flags);
This one's a biggy. Instead of getting that useful socket number we obtained from hci_open_dev, this function uses the device ID from hci_get_route. This function performs a bluetooth device discovery, blocking for 1.28*len seconds. max_rsp is the maximum number of responses that you can handle, in your inquiry_info data structure,
int hci_read_remote_name(int sock, const bdaddr_t *ba, int len, char *name, int timeout);
This gets us a "friendly name" for our devices of interest using the socket sock, finding the address bdaddr_t, for a timeout timeout (milliseconds) inside a buffer of maximum size len. Returns -1 on failure and 0 on success.
For example:
abionnnn@x50:~/Desktop1/wiimote$ g++ simple-detect.cpp -o simple-detect -lbluetooth abionnnn@x50:~/Desktop1/wiimote$ ./simple-detect device id: 0 00:19:1D:90:71:27 Nintendo RVL-CNT-01
We can test if we are indeed dealing with a Wiimote by testing all the known names. RVL-CNT-01 is currently one of the three known names.
More info soon
hci_send_cmd(sock, ogf, ocf, plen, *param); ....
[edit] Reverse engineering hidd
Most of the functionality we need is in the bluez-util package program hidd. So its best to see how we can extract the most important information from it.
[edit] Targets
[edit] Asynchronous device discovery
etc.
Linux
WiiLi Link | GameCube Linux | Artwork | Wiimux
Hardware
Wiimote (Drivers, Extension Port, Mii Data) | Wii balance board | Classic Controller | Nunchuk | GameCube Controller (Keyboard, GBA) | Nintendo DS
Bluetooth (BlueZ, Devices) | Ethernet Adapter | USB Devices | Wii KeyBoard Compatibility | Modchips
Homebrew
GameCube | Wii | Action Replay
Specs
Wii | Comparison
File System
Wii Optical Disc | Wii Flash Memory | SD Card | Wii Memory block Size List
GameCube Optical Disc | GameCube Memory Card | Game Save Parser
Wiimote | Communications | BlueZ
Drivers (BlueSoleil) | Devices

