2 * Wiimote Bluetooth mouse driver
6 * Copyright (C) 2009, 2010 Daniel Borkmann <daniel@netsniff-ng.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #define PROGNAME_STRING "wiimote"
24 #define VERSION_STRING "0.5.0"
39 #include <sys/socket.h>
41 #include <bluetooth/bluetooth.h>
42 #include <bluetooth/l2cap.h>
43 #include <bluetooth/hci.h>
44 #include <bluetooth/hci_lib.h>
45 #include <bluetooth/sdp.h>
46 #include <bluetooth/hidp.h>
50 static volatile sig_atomic_t sigint
= 0;
60 static struct option long_options
[] = {
61 {"addr", required_argument
, 0, 'a'},
62 {"dev", required_argument
, 0, 'd'},
63 {"scan", no_argument
, 0, 's'},
64 {"version", no_argument
, 0, 'v'},
65 {"help", no_argument
, 0, 'h'},
72 static int l2cap_connect(bdaddr_t
*src
, bdaddr_t
*dst
, unsigned short psm
)
74 struct sockaddr_l2 addr
;
75 struct l2cap_options opts
;
78 if ((sk
= socket(PF_BLUETOOTH
, SOCK_SEQPACKET
, BTPROTO_L2CAP
)) < 0)
81 memset(&addr
, 0, sizeof(addr
));
82 addr
.l2_family
= AF_BLUETOOTH
;
83 bacpy(&addr
.l2_bdaddr
, src
);
85 if (bind(sk
, (struct sockaddr
*) &addr
, sizeof(addr
)) < 0) {
90 memset(&opts
, 0, sizeof(opts
));
91 opts
.imtu
= HIDP_DEFAULT_MTU
;
92 opts
.omtu
= HIDP_DEFAULT_MTU
;
93 opts
.flush_to
= 0xffff;
95 setsockopt(sk
, SOL_L2CAP
, L2CAP_OPTIONS
, &opts
, sizeof(opts
));
97 memset(&addr
, 0, sizeof(addr
));
98 addr
.l2_family
= AF_BLUETOOTH
;
99 bacpy(&addr
.l2_bdaddr
, dst
);
100 addr
.l2_psm
= htobs(psm
);
102 if (connect(sk
, (struct sockaddr
*) &addr
, sizeof(addr
)) < 0) {
110 static void version(void)
112 printf("%s %s\n", PROGNAME_STRING
, VERSION_STRING
);
116 static void help(void)
118 printf("%s %s\n\n", PROGNAME_STRING
, VERSION_STRING
);
119 printf("Usage: wiimote [options]\n\n");
120 printf(" -a|--addr <arg> BT address to connect to\n");
121 printf(" -d|--dev <arg> Wiimote device file (e.g. /dev/wiimote)\n");
122 printf(" -s|--scan Scan for Wiimote devices\n");
123 printf(" -v|--version Prints out version\n");
124 printf(" -h|--help Prints out this help\n\n");
125 printf("Please report bugs to <daniel@netsniff-ng.org>\n");
126 printf("Copyright (C) 2009, 2010 Daniel Borkmann\n");
127 printf("License: GNU GPL version 2\n");
128 printf("This is free software: you are free to change and "
129 "redistribute it.\n");
130 printf("There is NO WARRANTY, to the extent permitted by law.\n");
134 static inline void init_configuration(struct wiimote_ctl
*wctl
)
137 memset(wctl
, 0, sizeof(*wctl
));
140 static void clean_configuration(struct wiimote_ctl
*wctl
)
147 static void wiimote_scan_devices(void)
151 int device_id
, sock
, len
= 8, flags
;
152 int max_resp
= 255, num_resp
;
154 char address
[19] = { 0 };
155 char name
[248] = { 0 };
157 inquiry_info
*ii
= NULL
;
159 printf("Scanning for Wiimote devices ...\n");
160 printf("Set your Wiimote into discoverable mode (press 1 + 2).\n");
162 flags
= IREQ_CACHE_FLUSH
;
164 device_id
= hci_get_route(NULL
);
166 sock
= hci_open_dev(device_id
);
167 if(device_id
< 0 || sock
< 0) {
168 perror("hci_open_dev");
172 ii
= malloc(max_resp
* sizeof(*ii
));
178 num_resp
= hci_inquiry(device_id
, len
, max_resp
, NULL
, &ii
, flags
);
180 perror("hci_inquiry");
182 for(i
= 0; i
< num_resp
; ++i
) {
183 ba2str(&(ii
+ i
)->bdaddr
, address
);
184 memset(name
, 0, sizeof(name
));
186 if(hci_read_remote_name(sock
, &(ii
+ i
)->bdaddr
, sizeof(name
),
188 strcpy(name
, "[unknown]");
191 if(strstr(name
, "Nintendo") != NULL
)
192 printf("%s -- %s\n", address
, name
);
199 static void set_configuration(int argc
, char **argv
, struct wiimote_ctl
*wctl
)
206 while ((c
= getopt_long(argc
, argv
, "a:d:svh", long_options
,
216 /* Allowed: XX:XX:XX:XX:XX:XX */
219 fprintf(stderr
, "Wrong address format!\n");
223 wctl
->address
= strdup(optarg
);
230 wctl
->device
= strdup(optarg
);
237 wiimote_scan_devices();
244 printf("Option -%c requires an argument!\n",
248 if(isprint(optopt
)) {
249 printf("Unknown option character "
250 "`0x%X\'!\n", optopt
);
262 static void check_configuration(struct wiimote_ctl
*wctl
)
265 if(!wctl
->address
|| !wctl
->device
) {
266 clean_configuration(wctl
);
271 static void signal_action(int s
)
273 sigint
= (s
== SIGINT
);
276 static void set_signalhandler(void)
279 struct sigaction usr_action
;
281 sigfillset(&block_mask
);
282 usr_action
.sa_handler
= signal_action
;
283 usr_action
.sa_mask
= block_mask
;
284 usr_action
.sa_flags
= 0;
285 sigaction(SIGINT
, &usr_action
, NULL
);
288 static int wiimote_init(struct wiimote_ctl
*wctl
)
292 wctl
->fd_device
= open(wctl
->device
, O_RDWR
);
293 if(wctl
->fd_device
< 0) {
298 wctl
->sock_ctrl
= socket(AF_BLUETOOTH
, SOCK_SEQPACKET
, BTPROTO_L2CAP
);
299 wctl
->sock_intr
= socket(AF_BLUETOOTH
, SOCK_SEQPACKET
, BTPROTO_L2CAP
);
301 if(wctl
->sock_ctrl
< 0 || wctl
->sock_intr
< 0) {
309 static void wiimote_cleanup(struct wiimote_ctl
*wctl
)
311 close(wctl
->fd_device
);
312 close(wctl
->sock_ctrl
);
313 close(wctl
->sock_intr
);
316 static int wiimote_inject_config_data(struct wiimote_ctl
*wctl
)
319 uint8_t calibration_data
[] = WII_SET_CALIBRATION_DATA
;
320 uint8_t enable_ba_data
[] = WII_ENABLE_BUTTON_ACCELM
;
324 rc
= write(wctl
->sock_ctrl
, calibration_data
, sizeof(calibration_data
));
330 rc
= write(wctl
->sock_ctrl
, enable_ba_data
, sizeof(enable_ba_data
));
339 static int wiimote_connect_intr_channel(struct wiimote_ctl
*wctl
)
341 struct sockaddr_l2 addr_intr
;
345 addr_intr
.l2_family
= AF_BLUETOOTH
;
346 addr_intr
.l2_psm
= htobs(L2CAP_PSM_HIDP_INTR
);
348 str2ba(wctl
->address
, &addr_intr
.l2_bdaddr
);
350 // return connect(wctl->sock_intr, (struct sockaddr *) &addr_intr,
351 // sizeof(addr_intr));
353 wctl
->sock_intr
= l2cap_connect(BDADDR_ANY
, &addr_intr
.l2_bdaddr
, L2CAP_PSM_HIDP_INTR
);
354 perror("l2cap_connect intr");
355 return (wctl
->sock_intr
< 0);
358 static int wiimote_connect_ctrl_channel(struct wiimote_ctl
*wctl
)
360 struct sockaddr_l2 addr_ctrl
;
364 addr_ctrl
.l2_family
= AF_BLUETOOTH
;
365 addr_ctrl
.l2_psm
= htobs(L2CAP_PSM_HIDP_CTRL
);
367 str2ba(wctl
->address
, &addr_ctrl
.l2_bdaddr
);
369 // return connect(wctl->sock_ctrl, (struct sockaddr *) &addr_ctrl,
370 // sizeof(addr_ctrl));
372 wctl
->sock_ctrl
= l2cap_connect(BDADDR_ANY
, &addr_ctrl
.l2_bdaddr
, L2CAP_PSM_HIDP_CTRL
);
373 perror("l2cap_connect intr");
374 return (wctl
->sock_ctrl
< 0);
377 static int wiimote_connect_channels(struct wiimote_ctl
*wctl
)
383 rc
= wiimote_connect_ctrl_channel(wctl
);
384 if(rc
) { perror("ctrl channel");
386 rc
= wiimote_connect_intr_channel(wctl
);
387 if(rc
) { perror("intr channel");
389 rc
= wiimote_inject_config_data(wctl
);
390 if(rc
) { perror("conf data");
395 static int wiimote_leds(struct wiimote_ctl
*wctl
, int l1
, int l2
, int l3
, int l4
)
398 uint8_t enable_leds
[] = WII_GENERIC_LED
;
403 enable_leds
[2] |= 0x10;
405 enable_leds
[2] |= 0x20;
407 enable_leds
[2] |= 0x40;
409 enable_leds
[2] |= 0x80;
411 rc
= write(wctl
->sock_ctrl
, enable_leds
, sizeof(enable_leds
));
420 static int wiimote_rumble(struct wiimote_ctl
*wctl
, uint32_t usec
)
423 uint8_t enable_rumble
[] = WII_ENABLE_RUMBLE
;
424 uint8_t disable_rumble
[] = WII_DISABLE_RUMBLE
;
428 rc
= write(wctl
->sock_ctrl
, enable_rumble
, sizeof(enable_rumble
));
436 rc
= write(wctl
->sock_ctrl
, disable_rumble
, sizeof(disable_rumble
));
445 static void *wiimote_rumble_thread(void *arg
)
447 struct wiimote_ctl
*wctl
= (struct wiimote_ctl
*) arg
;
450 wiimote_leds(wctl
, 1, 0, 0, 0);
452 wiimote_leds(wctl
, 0, 1, 0, 0);
454 wiimote_leds(wctl
, 0, 0, 1, 0);
456 wiimote_leds(wctl
, 0, 0, 0, 1);
458 wiimote_leds(wctl
, 0, 0, 1, 0);
460 wiimote_leds(wctl
, 0, 1, 0, 0);
462 wiimote_leds(wctl
, 1, 0, 0, 0);
469 static int wiimote_read_sensors_loop(struct wiimote_ctl
*wctl
)
474 float calx
, caly
, calz
;
478 uint8_t buffer
[WII_BLK_TRANSMISSION_LEN
];
479 struct wiimote_data wbuf
;
483 /* Initial settings */
489 usleep(WII_BLK_SLEEP_GAP_LEN
);
491 memset(buffer
, 0, sizeof(buffer
));
493 rc
= read(wctl
->sock_intr
, buffer
, sizeof(buffer
));
499 /* Check for valid buffer */
500 if(buffer
[0] != 0xA1 && buffer
[1] != 0x33)
503 wbuf
.buttons
= ((uint16_t) ((buffer
[2] & ~0x60) << 8) & 0xFF00) |
504 ((uint16_t) (buffer
[3] & ~0x60) & 0x00FF);
506 /* Some bits are also encoded between button status bits */
507 dx
= 1.0f
* (buffer
[4] | (buffer
[2] & 0x60) >> 5) - calx
;
508 dy
= 1.0f
* (buffer
[5] | (buffer
[3] & 0x20) >> 5) - caly
;
509 dz
= 1.0f
* (buffer
[6] | (buffer
[3] & 0x40) >> 6) - calz
;
511 norm
= 1.f
/ sqrtf(dx
* dx
+ dy
* dy
+ dz
* dz
);
513 dx
= 2.0f
* atanf(dx
* norm
);
514 dy
= 2.0f
* atanf(dy
* norm
);
516 roll
= dx
* 180.0f
/ M_PI
;
517 pitch
= dy
* 180.0f
/ M_PI
;
520 if((int) roll
> 30 || (int) roll
< -30)
521 wbuf
.pos_dx
= (int) roll
/ 20;
524 if((int) pitch
> 30 || (int) pitch
< -30)
525 wbuf
.pos_dy
= (int) pitch
/ 20;
527 wbuf
.pos_dy
*= WII_INVERT_Y_AXIS
;
529 rc
= write(wctl
->fd_device
, &wbuf
, sizeof(wbuf
));
539 int main(int argc
, char **argv
)
542 pthread_t rumble_thread
;
543 struct wiimote_ctl wctl
;
545 init_configuration(&wctl
);
546 set_configuration(argc
, argv
, &wctl
);
547 check_configuration(&wctl
);
550 printf("Set your Wiimote (%s) into discoverable mode (press 1 + 2).\n",
554 while(wiimote_connect_channels(&wctl
) != 0 && !sigint
)
556 wiimote_rumble(&wctl
, 2000000);
558 rc
= pthread_create(&rumble_thread
, NULL
, wiimote_rumble_thread
, &wctl
);
560 perror("pthread_create");
564 wiimote_read_sensors_loop(&wctl
);
565 wiimote_cleanup(&wctl
);
567 clean_configuration(&wctl
);