Question

I am trying to find any workarounds for a Bluetooth LE bug on OSX. In particular, I want to know where OSX goes wrong in reading the Bluetooth LE GATT table. Thus, I am viewing the L2CAP packets in PacketLogger from Hardware IO Tools for XCode.

When I use Bluetooth Explorer to connect to the Bluetooth LE device, I am expecting to see 3.4.4.9 Read By Group Type Request(uuid=0x2800 «Primary Service», startingHandle=0x0001, endingHandle=0xffff) to discover primary services (or Find By Type Value Request(uuid=0x2800, value:uuid of service)), followed by 3.4.4.1 Read By Type Request(uuid=0x2803 «Characteristic») to discover characteristics. This is what I see when I sniff the packets from an iPhone (using a CC2540).

But on OSX, the only L2CAP requests that I see in PacketLogger (and the CC2540) after connecting are:

  1. Read By Type Request(attributeType=0x2803, startingHandle=0x001a, endingHandle=0x001a)
  2. Read By Type Request(attributeType=0x2802 «Include», startingHandle=0x0001, endingHandle=0x0004)
  3. Read By Type Request(attributeType=0x2802, startingHandle=0x0005, endingHandle=0x0009)
  4. Read By Type Request(attributeType=0x2802, startingHandle=0x0010, endingHandle=0x0019)
  5. Read By Type Request(attributeType=0x2802, startingHandle=0x001a, endingHandle=0x001a)
  6. Read By Type Request(attributeType=0x2803, startingHandle=0x001a, endingHandle=0x001a)
  7. Read By Type Request(attributeType=0x2802, startingHandle=0x0021, endingHandle=0x0027)
  8. Read By Type Request(attributeType=0x2802, startingHandle=0x002b, endingHandle=0x002e)

These are not enough requests to discover the services, yet Bluetooth Explorer lists all the service UUIDs at this point. This indicates that OSX already knows where the services are on this Bluetooth LE device. Does blued cache device services and read them on startup? If so, how can I clear the cache?

I have tried turning off Bluetooth, killing blued, and restarting OSX, but every time OSX never rediscovers the services.

Was it helpful?

Solution

Yes, blued does cache the Bluetooth LE GATT table. If the cache is bad, do the following to delete it, thanks to “blued process is killing my CPU”:

  1. Delete /Library/Preferences/com.apple.Bluetooth.plist. This will remove knowledge of all bonded Bluetooth and Bluetooth LE devices.
  2. Kill /usr/sbin/blued. It will be restarted by launchd.
  3. Run Bluetooth LE program again. PacketLogger will now show Read By Group Type requests to rediscover the primary services.

Caching is allowed when the central has established a “bond” with the peripheral (not just paired), according to Bluetooth 4.0 Volume 3 Part G Section 2.5.2 Attribute Caching. I’m not sure how to verify that the central indeed bonded with the peripheral, but I assume that it did.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top