startLeScan with 128 bit UUIDs doesn't work on native Android BLE implementation

后端 未结 11 2253
别跟我提以往
别跟我提以往 2020-11-28 04:19

I am having trouble using startLeScan( new UUID[]{ MY_DESIRED_128_BIT_SERVICE_UUID }, callback ) on the new introduced BLE API of Android 4.3 on my Nexus 4.

The cal

相关标签:
11条回答
  • 2020-11-28 04:52

    I've found a bug in Android source 5.x, but not present in 6.x.

    There a function in this file: http://androidxref.com/5.1.1_r6/xref/external/bluetooth/bluedroid/bta/dm/bta_dm_api.c#1560 used to pass a 32 bit data_mask to bluetooth le advertising and scan response stack. But the structure "tBTA_DM_API_SET_ADV_CONFIG;" manage 16 bit long value !!! So change UINT16 to UINT32 dor data_mask, recompile Android and it will works. Rif http://androidxref.com/5.1.1_r6/xref/external/bluetooth/bluedroid/bta/dm/bta_dm_int.h#594

    0 讨论(0)
  • 2020-11-28 04:53

    You need add service UUID in the advertisement data as the link

    Then you can try again startLeScan (UUID[],callback).

    I had succeed by this method to discovery thermometer device with specific UUID[0x1809]

    It does work for me.

    0 讨论(0)
  • 2020-11-28 04:58

    @Navin's code is good, but it includes an overflow bug from the original 16-bit Android code. (If either byte is larger than 127 then it becomes a negative integer.)

    Here's an implementation which fixes that bug and adds 128-bit support:

    private List<UUID> parseUuids(byte[] advertisedData) {
         List<UUID> uuids = new ArrayList<UUID>();
    
         ByteBuffer buffer = ByteBuffer.wrap(advertisedData).order(ByteOrder.LITTLE_ENDIAN);
         while (buffer.remaining() > 2) {
             byte length = buffer.get();
             if (length == 0) break;
    
             byte type = buffer.get();
             switch (type) {
                 case 0x02: // Partial list of 16-bit UUIDs
                 case 0x03: // Complete list of 16-bit UUIDs
                     while (length >= 2) {
                         uuids.add(UUID.fromString(String.format(
                                 "%08x-0000-1000-8000-00805f9b34fb", buffer.getShort())));
                         length -= 2;
                     }
                     break;
    
                 case 0x06: // Partial list of 128-bit UUIDs
                 case 0x07: // Complete list of 128-bit UUIDs
                     while (length >= 16) {
                         long lsb = buffer.getLong();
                         long msb = buffer.getLong();
                         uuids.add(new UUID(msb, lsb));
                         length -= 16;
                     }
                     break;
    
                 default:
                     buffer.position(buffer.position() + length - 1);
                     break;
             }
         }
    
         return uuids;
     }
    
    0 讨论(0)
  • 2020-11-28 05:00

    Are you certain that the peripheral is listing the specified service UUID in the advertisement data or scan response data?

    0 讨论(0)
  • 2020-11-28 05:01

    My experience is that I had to supply EVERY service that a device I want to connect to presents, not just the one I am concerned with. I ended up doing service discovery after scan to get around this.

    0 讨论(0)
提交回复
热议问题