X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=libaltos%2Flibaltos.c;h=97b7b3f9bba44037206e409362824131c833bec9;hp=a623d5ae0b5c187f9b0c5a7bec962b1c73e2451d;hb=8a2be4d36a3b116d82529805430c5fb665688267;hpb=d9982c257463f23be940eea66bd4dc3aadff0043 diff --git a/libaltos/libaltos.c b/libaltos/libaltos.c index a623d5ae..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); @@ -817,7 +867,7 @@ get_string(io_object_t object, CFStringRef entry, char *result, int result_len) got_string = CFStringGetCString(entry_as_string, result, result_len, kCFStringEncodingASCII); - + CFRelease(entry_as_string); if (got_string) return 1; @@ -830,7 +880,7 @@ get_number(io_object_t object, CFStringRef entry, int *result) { CFTypeRef entry_as_number; Boolean got_number; - + entry_as_number = IORegistryEntrySearchCFProperty (object, kIOServicePlane, entry, @@ -885,7 +935,7 @@ altos_list_next(struct altos_list *list, struct altos_device *device) object = IOIteratorNext(list->iterator); if (!object) return 0; - + if (!get_number (object, CFSTR(kUSBVendorID), &device->vendor) || !get_number (object, CFSTR(kUSBProductID), &device->product)) continue; @@ -989,7 +1039,7 @@ log_message(char *fmt, ...) if (log) { SYSTEMTIME time; GetLocalTime(&time); - fprintf (log, "%4d-%02d-%02d %2d:%02d:%02d. ", + fprintf (log, "%4d-%02d-%02d %2d:%02d:%02d. ", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond); va_start(a, fmt); @@ -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 */ @@ -1340,7 +1411,7 @@ altos_open(struct altos_device *device) altos_set_last_windows_error(); Sleep(100); } - + if (file->handle == INVALID_HANDLE_VALUE) { free(file); return NULL;