X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=libaltos%2Flibaltos.c;h=97b7b3f9bba44037206e409362824131c833bec9;hp=b7ec98fc58f5c17994c523955b4e20c6d680f23d;hb=8a2be4d36a3b116d82529805430c5fb665688267;hpb=9e18c524fa2d1f648f265b3c3105f5ceacf06c10 diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index b7ec98fc..97b7b3f9 100644 --- a/libaltos/libaltos.c +++ b/libaltos/libaltos.c @@ -643,6 +643,49 @@ altos_list_finish(struct altos_list *usbdevs) free(usbdevs); } +#include + +static void *libbt; +static int bt_initialized; + +static int init_bt(void) { + if (!bt_initialized) { + bt_initialized = 1; + libbt = dlopen("libbluetooth.so.3", RTLD_LAZY); + if (!libbt) + printf("failed to find bluetooth library\n"); + } + return libbt != NULL; +} + +#define join(a,b) a ## b +#define bt_func(name, ret, fail, formals, actuals) \ + static ret join(altos_, name) formals { \ + static ret (*name) formals; \ + if (!init_bt()) return fail; \ + name = dlsym(libbt, #name); \ + if (!name) return fail; \ + return name actuals; \ + } + +bt_func(ba2str, int, -1, (const bdaddr_t *ba, char *str), (ba, str)) +#define ba2str altos_ba2str + +bt_func(str2ba, int, -1, (const char *str, bdaddr_t *ba), (str, ba)) +#define str2ba altos_str2ba + +bt_func(hci_read_remote_name, int, -1, (int sock, const bdaddr_t *ba, int len, char *name, int timeout), (sock, ba, len, name, timeout)) +#define hci_read_remote_name altos_hci_read_remote_name + +bt_func(hci_open_dev, int, -1, (int dev_id), (dev_id)) +#define hci_open_dev altos_hci_open_dev + +bt_func(hci_get_route, int, -1, (bdaddr_t *bdaddr), (bdaddr)) +#define hci_get_route altos_hci_get_route + +bt_func(hci_inquiry, int, -1, (int adapter_id, int len, int max_rsp, const uint8_t *lap, inquiry_info **devs, long flags), (adapter_id, len, max_rsp, lap, devs, flags)) +#define hci_inquiry altos_hci_inquiry + struct altos_bt_list { inquiry_info *ii; int sock; @@ -706,7 +749,8 @@ altos_bt_list_next(struct altos_bt_list *bt_list, return 0; ii = &bt_list->ii[bt_list->rsp]; - ba2str(&ii->bdaddr, device->addr); + if (ba2str(&ii->bdaddr, device->addr) < 0) + return 0; memset(&device->name, '\0', sizeof (device->name)); if (hci_read_remote_name(bt_list->sock, &ii->bdaddr, sizeof (device->name), @@ -742,11 +786,17 @@ altos_bt_open(struct altos_bt_device *device) struct altos_file *file; file = calloc(1, sizeof (struct altos_file)); - if (!file) + if (!file) { + errno = ENOMEM; + altos_set_last_posix_error(); goto no_file; + } addr.rc_family = AF_BLUETOOTH; addr.rc_channel = 1; - str2ba(device->addr, &addr.rc_bdaddr); + if (str2ba(device->addr, &addr.rc_bdaddr) < 0) { + altos_set_last_posix_error(); + goto no_sock; + } for (i = 0; i < 5; i++) { file->fd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); @@ -1071,6 +1121,8 @@ altos_list_next(struct altos_list *list, struct altos_device *device) HRESULT result; DWORD friendlyname_type; DWORD friendlyname_len; + char instanceid[1024]; + DWORD instanceid_len; dev_info_data.cbSize = sizeof (SP_DEVINFO_DATA); while(SetupDiEnumDeviceInfo(list->dev_info, list->index, @@ -1091,6 +1143,7 @@ altos_list_next(struct altos_list *list, struct altos_device *device) pid = 0x6015; serial = 0; } else { + vid = pid = serial = 0; /* Fetch symbolic name for this device and parse out * the vid/pid/serial info */ symbolic_len = sizeof(symbolic); @@ -1098,16 +1151,34 @@ altos_list_next(struct altos_list *list, struct altos_device *device) symbolic, &symbolic_len); if (result != 0) { altos_set_last_windows_error(); + } else { + sscanf((char *) symbolic + sizeof("\\??\\USB#VID_") - 1, + "%04X", &vid); + sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1, + "%04X", &pid); + sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1, + "%d", &serial); + } + if (vid == 0 || pid == 0 || serial == 0) { + if (SetupDiGetDeviceInstanceId(list->dev_info, + &dev_info_data, + instanceid, + sizeof (instanceid), + &instanceid_len)) { + sscanf((char *) instanceid + sizeof("USB\\VID_") - 1, + "%04X", &vid); + sscanf((char *) instanceid + sizeof("USB\\VID_XXXX&PID_") - 1, + "%04X", &pid); + sscanf((char *) instanceid + sizeof("USB\\VID_XXXX&PID_XXXX\\") - 1, + "%d", &serial); + } else { + altos_set_last_windows_error(); + } + } + if (vid == 0 || pid == 0 || serial == 0) { RegCloseKey(dev_key); continue; } - vid = pid = serial = 0; - sscanf((char *) symbolic + sizeof("\\??\\USB#VID_") - 1, - "%04X", &vid); - sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_") - 1, - "%04X", &pid); - sscanf((char *) symbolic + sizeof("\\??\\USB#VID_XXXX&PID_XXXX#") - 1, - "%d", &serial); } /* Fetch the com port name */