$search
00001 /* 00002 * Copyright (c) 2007, 2008 pascal@pabr.org 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of the Willow Garage, Inc. nor the names of its 00014 * contributors may be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00021 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 00028 */ 00029 00030 #include <string.h> 00031 #include <unistd.h> 00032 #include <stdio.h> 00033 #include <usb.h> 00034 00035 #define VENDOR 0x054c 00036 #define PRODUCT 0x0268 00037 00038 #define USB_DIR_IN 0x80 00039 #define USB_DIR_OUT 0 00040 00041 void fatal(char *msg) { perror(msg); exit(1); } 00042 00043 void show_master(usb_dev_handle *devh, int itfnum) { 00044 printf("Current Bluetooth master: "); 00045 unsigned char msg[8]; 00046 int res = usb_control_msg 00047 (devh, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 00048 0x01, 0x03f5, itfnum, (void*)msg, sizeof(msg), 5000); 00049 if ( res < 0 ) { perror("USB_REQ_GET_CONFIGURATION"); return; } 00050 printf("%02x:%02x:%02x:%02x:%02x:%02x\n", 00051 msg[2], msg[3], msg[4], msg[5], msg[6], msg[7]); 00052 } 00053 00054 void set_master(usb_dev_handle *devh, int itfnum, int mac[6]) { 00055 printf("Setting master bd_addr to %02x:%02x:%02x:%02x:%02x:%02x\n", 00056 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 00057 char msg[8]= { 0x01, 0x00, mac[0],mac[1],mac[2],mac[3],mac[4],mac[5] }; 00058 int res = usb_control_msg 00059 (devh, 00060 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 00061 0x09, 00062 0x03f5, itfnum, msg, sizeof(msg), 00063 5000); 00064 if ( res < 0 ) fatal("USB_REQ_SET_CONFIGURATION"); 00065 } 00066 00067 void process_device(int argc, char **argv, struct usb_device *dev, 00068 struct usb_config_descriptor *cfg, int itfnum) { 00069 int mac[6]; 00070 00071 usb_dev_handle *devh = usb_open(dev); 00072 if ( ! devh ) fatal("usb_open"); 00073 00074 usb_detach_kernel_driver_np(devh, itfnum); 00075 00076 int res = usb_claim_interface(devh, itfnum); 00077 if ( res < 0 ) fatal("usb_claim_interface"); 00078 00079 show_master(devh, itfnum); 00080 00081 if ( argc >= 2 ) { 00082 if ( sscanf(argv[1], "%x:%x:%x:%x:%x:%x", 00083 &mac[0],&mac[1],&mac[2],&mac[3],&mac[4],&mac[5]) != 6 ) { 00084 00085 printf("usage: %s [<bd_addr of master>]\n", argv[0]); 00086 exit(1); 00087 } 00088 } else { 00089 FILE *f = popen("hcitool dev", "r"); 00090 if ( !f || 00091 fscanf(f, "%*s\n%*s %x:%x:%x:%x:%x:%x", 00092 &mac[0],&mac[1],&mac[2],&mac[3],&mac[4],&mac[5]) != 6 ) { 00093 printf("Unable to retrieve local bd_addr from `hcitool dev`.\n"); 00094 printf("Please enable Bluetooth or specify an address manually.\n"); 00095 exit(1); 00096 } 00097 pclose(f); 00098 } 00099 00100 set_master(devh, itfnum, mac); 00101 00102 usb_close(devh); 00103 } 00104 00105 int main(int argc, char *argv[]) { 00106 00107 usb_init(); 00108 if ( usb_find_busses() < 0 ) fatal("usb_find_busses"); 00109 if ( usb_find_devices() < 0 ) fatal("usb_find_devices"); 00110 struct usb_bus *busses = usb_get_busses(); 00111 if ( ! busses ) fatal("usb_get_busses"); 00112 00113 int found = 0; 00114 00115 struct usb_bus *bus; 00116 for ( bus=busses; bus; bus=bus->next ) { 00117 struct usb_device *dev; 00118 for ( dev=bus->devices; dev; dev=dev->next) { 00119 struct usb_config_descriptor *cfg; 00120 for ( cfg = dev->config; 00121 cfg < dev->config + dev->descriptor.bNumConfigurations; 00122 ++cfg ) { 00123 int itfnum; 00124 for ( itfnum=0; itfnum<cfg->bNumInterfaces; ++itfnum ) { 00125 struct usb_interface *itf = &cfg->interface[itfnum]; 00126 struct usb_interface_descriptor *alt; 00127 for ( alt = itf->altsetting; 00128 alt < itf->altsetting + itf->num_altsetting; 00129 ++alt ) { 00130 if ( dev->descriptor.idVendor == VENDOR && 00131 dev->descriptor.idProduct == PRODUCT && 00132 alt->bInterfaceClass == 3 ) { 00133 process_device(argc, argv, dev, cfg, itfnum); 00134 ++found; 00135 } 00136 } 00137 } 00138 } 00139 } 00140 } 00141 00142 if ( ! found ) { 00143 printf("No controller found on USB busses. Please connect your joystick via USB.\n"); 00144 return 1; 00145 } 00146 00147 return 0; 00148 00149 } 00150