/* * sixpair.c version 2007-04-18 * Compile with: gcc -o sixpair sixpair.c -lusb */ #include #include #include #include #define VENDOR 0x054c #define PRODUCT 0x0268 #define USB_DIR_IN 0x80 #define USB_DIR_OUT 0 void fatal(char *msg) { perror(msg); exit(1); } void show_master(usb_dev_handle *devh, int itfnum) { printf("Current Bluetooth master: "); unsigned char msg[8]; int res = usb_control_msg (devh, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0x01, 0x03f5, itfnum, (void*)msg, sizeof(msg), 5000); if ( res < 0 ) { perror("USB_REQ_GET_CONFIGURATION"); return; } printf("%02x:%02x:%02x:%02x:%02x:%02x\n", msg[2], msg[3], msg[4], msg[5], msg[6], msg[7]); } void set_master(usb_dev_handle *devh, int itfnum, int mac[6]) { printf("Setting master bd_addr to %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); char msg[8]= { 0x01, 0x00, mac[0],mac[1],mac[2],mac[3],mac[4],mac[5] }; int res = usb_control_msg (devh, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0x09, 0x03f5, itfnum, msg, sizeof(msg), 5000); if ( res < 0 ) fatal("USB_REQ_SET_CONFIGURATION"); } void process_device(int argc, char **argv, struct usb_device *dev, struct usb_config_descriptor *cfg, int itfnum) { int mac[6], have_mac=0; usb_dev_handle *devh = usb_open(dev); if ( ! devh ) fatal("usb_open"); usb_detach_kernel_driver_np(devh, itfnum); int res = usb_claim_interface(devh, itfnum); if ( res < 0 ) fatal("usb_claim_interface"); show_master(devh, itfnum); if ( argc >= 2 ) { if ( sscanf(argv[1], "%x:%x:%x:%x:%x:%x", &mac[0],&mac[1],&mac[2],&mac[3],&mac[4],&mac[5]) != 6 ) { printf("usage: %s []\n", argv[0]); exit(1); } } else { FILE *f = popen("hcitool dev", "r"); if ( !f || fscanf(f, "%*s\n%*s %x:%x:%x:%x:%x:%x", &mac[0],&mac[1],&mac[2],&mac[3],&mac[4],&mac[5]) != 6 ) { printf("Unable to retrieve local bd_addr from `hcitool dev`.\n"); printf("Please enable Bluetooth or specify an address manually.\n"); exit(1); } pclose(f); } set_master(devh, itfnum, mac); usb_close(devh); } int main(int argc, char *argv[]) { usb_init(); if ( usb_find_busses() < 0 ) fatal("usb_find_busses"); if ( usb_find_devices() < 0 ) fatal("usb_find_devices"); struct usb_bus *busses = usb_get_busses(); if ( ! busses ) fatal("usb_get_busses"); int found = 0; struct usb_bus *bus; for ( bus=busses; bus; bus=bus->next ) { struct usb_device *dev; for ( dev=bus->devices; dev; dev=dev->next) { struct usb_config_descriptor *cfg; for ( cfg = dev->config; cfg < dev->config + dev->descriptor.bNumConfigurations; ++cfg ) { int itfnum; for ( itfnum=0; itfnumbNumInterfaces; ++itfnum ) { struct usb_interface *itf = &cfg->interface[itfnum]; struct usb_interface_descriptor *alt; for ( alt = itf->altsetting; alt < itf->altsetting + itf->num_altsetting; ++alt ) { if ( dev->descriptor.idVendor == VENDOR && dev->descriptor.idProduct == PRODUCT && alt->bInterfaceClass == 3 ) { process_device(argc, argv, dev, cfg, itfnum); ++found; } } } } } } if ( ! found ) printf("No controller found on USB busses.\n"); return 0; }