Custom GAP advertising packet

From UNamur InfoSec
Jump to navigation Jump to search

We can change the content of the generic access profile (GAP) advertising packet (AP) to contain the information we want it to contain. If we have only a small amount of data we want to communicate to the world, then we can use the modified GAP AP to send that information to any BLE scanner, without waiting for it to establish a connection. In this article, we’re going to modify advertising data step by step, then receive the result with a custom-built Evothings app.

GAP data review

The general GAP broadcast’s data breakdown is illustrated in this diagram:

Gap struct.png

The BLE stack eats part of our package’s 47B, so only 26B are available for our data

Every BLE package can contain a maximum of 47 bytes (which isn’t much), but:

  1. The BLE stack requires 8 bytes (1 + 4 + 3) for its own purposes.
  2. The advertising packet data unit (PDU) therefore has at maximum 39 bytes. But the BLE stack once again requires some overhead, taking up another 8 bytes (2 + 6).
  3. The PDU’s advertising data field has 31 bytes left, divided into advertising data (AD) structures. Then:
    • The GAP broadcast must contain flags that tell the device about the type of advertisement we’re sending. The flag structure uses three bytes in total: one for data length, one for data type and one for the data itself. The reason we need the first two bytes (the data length and type indications) is to help the parser work correctly with our flag information. We have 28 bytes left.
    • Now we’re finally sending our own data in its own data structure. But our own data structure also needs an indication of length and type (two bytes in total). So we have 26 bytes left.

All of which means that we have only 26B to use for the data we want to send over GAP.

And here’s what the bottom two layers of structure look like for our particular example - sending manufacturer data:

Example gap struct.png

The example we use here only requires two data structures, one of 3B, one of 28B (of which two are used for data length and type indications)

Example Custom GAP data on Arduino (Adafruit Bluefruit LE feather 32u4)

The example code use the library from Adafruit Bluefruite LE nRF51: https://github.com/adafruit/Adafruit_BluefruitLE_nRF51

Begin by create a file call BlueFruitConfig.h which define all the configuration need for the device

#define BUFSIZE                        128   // Size of the read buffer for incoming data
#define VERBOSE_MODE                   true  // If set to 'true' enables debug output

#define BLUEFRUIT_SWUART_RXD_PIN       9    // Required for software serial!
#define BLUEFRUIT_SWUART_TXD_PIN       10   // Required for software serial!
#define BLUEFRUIT_UART_CTS_PIN         11   // Required for software serial!
#define BLUEFRUIT_UART_RTS_PIN         -1   // Optional, set to -1 if unused

#ifdef Serial1    // this makes it not complain on compilation if there's no Serial1
  #define BLUEFRUIT_HWSERIAL_NAME      Serial1
#endif

#define BLUEFRUIT_UART_MODE_PIN        12    // Set to -1 if unused

#define BLUEFRUIT_SPI_CS               8
#define BLUEFRUIT_SPI_IRQ              7
#define BLUEFRUIT_SPI_RST              4    // Optional but recommended, set to -1 if unused

#define BLUEFRUIT_SPI_SCK              13
#define BLUEFRUIT_SPI_MISO             12
#define BLUEFRUIT_SPI_MOSI             11

Example Scan Program on Raspberry Pi (Using bluepy library)

Reference

Custom GAP Advertising Package https://docs.mbed.com/docs/ble-intros/en/latest/Advanced/CustomGAP/

Adafruit feather 32u4 BLE GAP https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le/ble-gap

Bluepy Scanner Class http://ianharvey.github.io/bluepy-doc/scanner.html