Hi Marcel, > do you have a dead simple proof-of-concept that can show this issue. I do not recall any of this issue. Have you tried it with the latest bluetooth-next kernel? I have only tried it with bluez 5.37 under kernel "4.4.0-21-generic #37-Ubuntu SMP Mon Apr 18 18:33:37 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux", and bluez 4.101 under kernel "3.13.0-85-generic #129-Ubuntu SMP Thu Mar 17 20:50:41 UTC 2016 i686 i686 i686 GNU/Linux". I have created a test that I think is reasonably close to being as simple as possible for showing the issue (or possible issue, I could certainly have some misunderstanding of part of the API that just happens to not cause a problem with the older bluez). I have attached the test code, although it finds and opens a custom device which of course you won't have. Probably modifying it to find some other connectable device would show the same issue but I haven't tried so can't say that for certain. The output of the test code with bluez 4.101 is: found device hci_le_create_connn okay Connected And the output with bluez 5.37 is: found device hci_le_create_connn okay attconnect failed errno 115: Operation now in progress That last line, showing that attconnect failed, takes something on the order of a minute to appear. All of this came up when my client wanted to replicate a test system and attempted to do so starting with a current ubuntu install. They ended up just installing an older ubuntu instead so they don't need this fixed. This also means I no longer have the bluez 5.37 install that showed the problem since an older one has been installed over it, but if there's something specific to look at I'll attempt to recreate that test when time permits. allan -- Allan Hessenflow allan@xxxxxxxxxxxx
/* blueztest.c */ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include <unistd.h> #include <errno.h> #include <bluetooth/bluetooth.h> #include <bluetooth/hci.h> #include <bluetooth/hci_lib.h> #include <bluetooth/l2cap.h> #define NIXIE_NAME "Nixie_Engr_A" #define EIR_FLAGS 0x01 #define EIR_UUID16_SOME 0x02 #define EIR_UUID16_ALL 0x03 #define EIR_NAME_SHORT 0x08 #define EIR_NAME_COMPLETE 0x09 static const char usage[] = "usage: %s [-j<dev>]\n" " -i<ifnum> use interface hci<ifnum>\n" ; int main(int argc, char *argv[]) { int result; int hciInterface; int hcifd; uint16_t handle; int attSock; struct hci_filter filter; struct sockaddr_l2 src, dst; struct bt_security btsec; uint8_t devBdAddrType; bdaddr_t devBdAddr; int len; bool scanning; bool found; bool connected; hci_event_hdr *header; evt_le_meta_event *meta; le_advertising_info *info; uint8_t dataLen, dataType; unsigned char buf[HCI_MAX_EVENT_SIZE]; int count; int i, j, k; result = 0; hciInterface = hci_get_route(NULL); hcifd = -1; attSock = -1; scanning = false; found = false; connected = false; for (i = 1; i < argc && result == 0; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'i': hciInterface = atoi(&argv[i][2]); break; default: result = 1; } } else { result = 1; } } if (result) fprintf(stderr, usage, argv[0]); if (result == 0) { hcifd = hci_open_dev(hciInterface); if (hcifd < 0) { fprintf(stderr, "failed to open hci%d\n", hcifd); result = 1; } } if (result == 0) { if (hci_le_set_scan_parameters(hcifd, 0x01, htobs(0x0010), htobs(0x0010), 0x00, 0x00, 1000) < 0) { fprintf(stderr, "failed to set scan parameters\n"); result = 1; } } if (result == 0) { if (hci_le_set_scan_enable(hcifd, 0x01, 1, 1000) < 0) { fprintf(stderr, "failed to enable scan\n"); result = 1; } else scanning = true; } if (result == 0) { hci_filter_clear(&filter); hci_filter_set_ptype(HCI_EVENT_PKT, &filter); hci_filter_set_event(EVT_LE_META_EVENT, &filter); if (setsockopt(hcifd, SOL_HCI, HCI_FILTER, &filter, sizeof(filter)) < 0) { fprintf(stderr, "failed to set filter\n"); result = 1; } } if (result == 0) { attSock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (attSock < 0) { fprintf(stderr, "failed to create att socket\n"); result = 1; } } if (result == 0) { memset(&src, 0, sizeof(src)); src.l2_family = AF_BLUETOOTH; src.l2_cid = htobs(/*ATT_CID*/4); src.l2_bdaddr_type = BDADDR_LE_PUBLIC; memcpy(&src.l2_bdaddr, BDADDR_ANY, sizeof(src.l2_bdaddr)); if (bind(attSock, (struct sockaddr *) &src, sizeof(src)) < 0) { fprintf(stderr, "failed to bind att socket\n"); result = 1; } } if (result == 0) { memset(&btsec, 0, sizeof(btsec)); btsec.level = BT_SECURITY_LOW; if (setsockopt(attSock, SOL_BLUETOOTH, BT_SECURITY, &btsec, sizeof(btsec)) != 0) { fprintf(stderr, "failed to set att socket options\n"); result = -1; } } while (result == 0 && !found) { len = read(hcifd, buf, sizeof(buf)); if (len >= HCI_EVENT_HDR_SIZE) { header = (hci_event_hdr *) buf; switch (header->evt) { case HCI_EVENT_PKT: i = 1 + HCI_EVENT_HDR_SIZE; meta = (evt_le_meta_event *) &buf[i]; i += 1 + EVT_LE_META_EVENT_SIZE; switch (meta->subevent) { case EVT_LE_ADVERTISING_REPORT: count = meta->data[0]; while (count-- && !found) { info = (le_advertising_info *) &buf[i]; j = 0; while (j + 1 < info->length && !connected && result == 0) { dataLen = info->data[j]; dataType = info->data[j + 1]; if (j + dataLen + 1 <= info->length) { switch (dataType) { case EIR_NAME_SHORT: case EIR_NAME_COMPLETE: k = dataLen - 1; if (k > sizeof(NIXIE_NAME) - 1) k = sizeof(NIXIE_NAME) - 1; if (k > 0 && memcmp(&info->data[j + 2], NIXIE_NAME, k) == 0) { fprintf(stderr, "found device\n"); found = true; } break; } } j += dataLen + 1; } i += LE_ADVERTISING_INFO_SIZE + 2 + info->length; } break; default: fprintf(stderr, "unhandled le meta subevent 0x%02x\n", (unsigned int) meta->subevent); break; } break; default: fprintf(stderr, "unhandled event 0x%02x\n", (unsigned int) header->evt); break; } } } if (found && result == 0) { if (scanning) { if (hci_le_set_scan_enable(hcifd, 0x00, 1, 1000) < 0) fprintf(stderr, "stop scan failed\n"); scanning = false; } } if (found && result == 0) { devBdAddrType = info->bdaddr_type; memcpy(&devBdAddr, &info->bdaddr, sizeof(devBdAddr)); if (hci_le_create_conn(hcifd, htobs(4), htobs(4), 0, info->bdaddr_type, info->bdaddr, LE_PUBLIC_ADDRESS/*BISON*/, htobs(15), htobs(15), htobs(0), htobs(100), htobs(1), htobs(1), &handle, 1000) >= 0) { fprintf(stderr, "hci_le_create_connn okay\n"); connected = true; memset(&dst, 0, sizeof(dst)); dst.l2_family = AF_BLUETOOTH; dst.l2_cid = htobs(/*ATT_CID*/4); dst.l2_bdaddr_type = devBdAddrType; memcpy(&dst.l2_bdaddr, &devBdAddr, sizeof(dst.l2_bdaddr)); if (connect(attSock, (struct sockaddr *) &dst, sizeof(dst)) < 0) { fprintf(stderr, "attconnect failed errno %d: %s\n", errno, strerror(errno)); result = 1; } else { fprintf(stderr, "Connected\n"); } } else { fprintf(stderr, "hci_le_create_conn failed\n"); result = 1; } } if (attSock != -1) close(attSock); if (scanning) hci_le_set_scan_enable(hcifd, 0x00, 1, 1000); if (connected) hci_disconnect(hcifd, handle, HCI_OE_USER_ENDED_CONNECTION, 1000); if (hcifd != -1) hci_close_dev(hcifd); return result; }
Attachment:
Makefile
Description: Binary data