Blip
Blip

Reputation: 161

BLE scan() not returning complete advertisement payload

Summary: Micropython Bluetooth BLE scan() does not return the complete advertisement payload, specifically missing "Complete Local Name".

Setup:

I'm trying to scan and discover a Xiaomi temperature device using Micropython. Using the Nordic Semiconductor APP nRF Connect on my phone displays the following advertised raw data:

020106111695FE30585B05015646D238C1A42801000B094C5957534430334D4D43

Broken up, this decodes to the following details

len==2,  0x01==FLAGS:           0201 06 
len==17, 0x16==SERVICE_DATA:    1116 95FE30585B05015646D238C1A4280100
len==11, 0x09==NAME:            0B09 4C5957534430334D4D43

The last element is the 0x09 (Complete Local Name), but the problem is that Micropython ble.scan() does not return the complete advert. payload. When scanning in Micropython, the last element (name) is missing. The raw data returned in adv_data is:

020106111695fe30585b05015646d238c1a4280100

I just made a small modification to _irq(...) of ble_simple_central.py to simply display all discovered devices and to illustrate the problem:

    def _irq(self, event, data):
        if event == _IRQ_SCAN_RESULT:
            addr_type, addr, adv_type, rssi, adv_data = data
            addr_h = binascii.hexlify(bytes(addr)).decode('utf-8')
            adv_data_h = binascii.hexlify(bytes(adv_data)).decode('utf-8')
            print('addr_type: {}, addr: {}, adv_type: {}, rssi: {}, adv_data: {}'.format(addr_type, addr_h, adv_type, rssi, adv_data_h))

The output (for the Xiaomi device) is:

addr_type: 0, addr: a4c138d24656, adv_type: 0, rssi: -68, adv_data: 020106111695fe30585b05015646d238c1a4280100

Am I forgetting something? Does the Xiaomi misbehave? Does Micropython or the Bluetooth specificationrequire that the advertise payload to be formatted differently?

Upvotes: 3

Views: 3009

Answers (1)

Blip
Blip

Reputation: 161

Based on comment and great tip from Emil, the solution was to set parameter 'active' in BLE.gap_scan(..., active=True) to receive scan responses in the results.

This makes the irq callback receive 2 separate messages with different adv_types:

  • 0x00 - ADV_IND - containing the advertising data
  • 0x04 - SCAN_RSP - containing the name

Doc ref: Observer Role (Scanner)

Upvotes: 3

Related Questions