6
votes

I am currently attempting to connect to multiple BLE devices using BlueZ 5.0 and Linux. I have one host BLE adapter and I have modified the gatttool to connect and perform this function. If I run an instance of the modified gatttool, I successfully connect and receive notification data from the BLE device. If I run another instance of the modified gatttool and connect to another BLE device, this application starts receiving notification data from both BLE devices and the initial application no longer receives any data. I believe this is due to the socket setup, where both applications are configuring their sockets to the same address and PSM (the newest instance receives the data whereas the other is starved). Is there a way to prevent this condition? Ideally, I want one application to connect to multiple devices. I assume that the application can only have one socket for the reason that multiple sockets will have the same issue as the multiple instances above. My BLE device is a TI CC2540 keyfob acting as a heartrate monitor.

2
Isn't this what you want? If you want one application to connect to multiple devices then you can do it through a single socket. I believe each message comes through with the device's BT address so you can associate it with the right device.Tim Tisdall
I now understand that I should use one socket. The ACL connection handle should be used to separate the data. I am having difficulty accessing this handle via BlueZ. socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM) creates the socket. connect(sock, (struct sockaddr *) &addr, sizeof(addr)) connects the socket. Accessing the handle using ioctl(socket, HCIGETCONNINFO, cr) returns an errno 2 (no file). The dest address is correct. My created socket above returns a value of 5 whereas the socket = hci_open_dev(dev_id) returns value of 6. Is there a better way to get this handle.user2321427
The ioctl(socket, HCIGETCONNINFO, cr) method works fine for bluetooth classic devices but not BLE devices. I need a method to access the ACL data handle for a BLE device for data pairing purposes. Is this possible with BlueZ?user2321427
I have similar problem. Please explain outcome of your experiments?abhiarora

2 Answers

2
votes

I started an answer so I could have more space...

I'm using a combination of Python and C to get my code to work, so my "code" may look funny because it could be from either. Also, I used Bluez 4 as the 5 didn't support the kernel I was using. Let me know if there's an issue and I can clarify.

It seems like there's several ways of doing things, but I ended up opening separate sockets for different tasks. You can open a single socket and then set the socket options to take filtering off and you should get all the packets in one place. However, that was my initial way of doing it and I found that my connections would die within seconds.

To scan for connections I opened a socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI) then did a bind on device 0. (there's a function called hci_get_route to get an available device number) You can then call hci_le_set_scan_parameters to set options, setsockopt(SOL_HCI, HCI_FILTER, filter) to just get LE scan events, and then called hci_le_set_scan_enable to turn on scanning.

Each device connection was made with a socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP) which you then tell to connect to a particular device by calling connect on the socket with a struct sockaddr_l2 that has the particular device address in it. On that socket you should only get packets from that device. (one caveat... I found that my dongle wouldn't allow a connection while active scanning was taking place.. I had to temporarily shut it off just before connecting and then turn it back on. Otherwise I got a BUSY error from errno)

After saying all that, though... I think the way you're supposed to do everything in Bluez 5 is to use DBUS. Unfortunately that wasn't really an option for what I was doing. The functions I mentioned are in the shared lib that apparently isn't installed by default in 5 (you have to explicitly ask for it to be installed with configure). They stopped installing the shared lib by default because they wanted to encourage people to use DBUS instead.

1
votes

WE have combined the code from hcitool and gatttool. The code works well for 2 device (scan, hci_le_create_conn and gatt_connect). I believe there is no limitation on the number of devices used.

1 Start cmd_lescan (from hcitool.c)
2.For each device scanned - 
      cmd_lecc (from hcitool.c)
      gatt_connect (from gatttool.c)

This way one process can manage multiple BLE device. We do not have to turn OFF the scanning, just have ignore non advertisement messages:

        if (meta->subevent != 0x02)
                continue; 

Thanks and looking forward to comments.