User Tools


Link to this comparison view

2.0:advertising [2015/09/16 02:00] (current)
Line 1: Line 1:
 +====== Beacons and Advertising ======
 +
 +
 +===== BLE Advertising Overview =====
 +
 +A BLE peripheral device can advertise to allow detection and connection by BLE central devices.  ​
 +
 +Advertising is governed by the Bluetooth GAP (Generic Access Profile) specification. Peripheral devices advertise to a Central device. Typically Peripheral devices have limited resources and use low power, while Central devices are more powerful and provide an interface for human interaction. ​
 +
 +For GAP documentation,​ see https://​www.bluetooth.org:​
 +  * Bluetooth Core Standard version 4, Vol 3, Part C, particularly sections 8 and 11
 +  * Core Specification Supplement, Part A
 +  * [[https://​www.bluetooth.org/​en-us/​specification/​assigned-numbers/​company-identifiers|Bluetooth Company Identifiers]]
 +
 +The Bluetooth GAP specification limits advertising data to two packets:
 +  * Advertising Data payload
 +  * Scan Response payload
 +  ​
 +For details of the format see [[#​advertising_data_format|Advertising Data Format]] below.
 +
 +==== Advertising with TruConnect ====  ​
 +
 +The TruConnect device acts as the Peripheral.
 +
 +TruConnect supports:
 +  * advertising in high or low mode. See [[commands#​adv|adv]].
 +  * advertising with a [[#​generic_beacon|generic beacon]], with complete control of all advertising data. This supports all formats, including:
 +    * [[#​eddystone_beacons|Eddystone Beacons]]
 +    * [[#​altbeacon|AltBeacon]] ​  
 +  * advertising [[#​uuid_and_name|service ID and name]]
 +  * advertising with [[#​uuid_name_and_gpios|service ID, name and value of GPIOs]]
 +  * advertising with the Apple [[#​ibeacon|iBeacon]] standard
 +  * turning off advertising. See [[commands#​adv|adv]].
 +
 +To start your TruConnect device advertising:​
 +
 +  * Set the type of beacon and the required fields in the beacon. See [[variables#​bl_v_d_f|bl v d f]] 
 +  * Set the content for the type of advertising configured. See:
 +    * [[variables#​bl_v_d_b|bl v d b]] --- generic beacon content
 +    * [[variables#​bl_v_d_g|bl v d g]] --- GPIO mask
 +    * [[variables#​bl_v_d_i|bl v d i]] --- iBeacon content
 +  * Start advertising. See [[commands#​adv|adv]] ​
 +
 +By default, a TruConnect device advertises the TruConnect Service ID and the default module name. See [[#​uuid_and_name|UUID and Name]] for details. ​
 +
 +==== Advertising Commands and Variables ====  ​
 +  ​
 +Commands supporting BLE advertising are:
 +  * [[commands#​adv|adv]] - advertise in high mode or low mode, or turn advertising off
 +    ​
 +Variables supporting BLE advertising are:
 +  * Advertising mode and settings
 +    * [[variables#​bl_t_a|bl t a]] --- advertising power  ​
 +    * [[variables#​bl_v_h_d|bl v h d]] --- advertising high mode duration
 +    * [[variables#​bl_v_h_i|bl v h i]] --- advertising high mode interval ​   ​
 +    * [[variables#​bl_v_l_d|bl v l d]] --- advertising low mode duration
 +    * [[variables#​bl_v_l_i|bl v l i]] --- advertising low mode interval
 +    * [[variables#​bl_v_m|bl v m]] --- advertising mode
 +  * Advertising data
 +    * [[variables#​bl_s_u|bl s u]] --- BLE service UUID
 +    * [[variables#​sy_d_n|sy d n]] --- device name
 +  * Beacon settings:
 +    * [[variables#​bl_v_d_b|bl v d b]] --- advertising data, generic beacon content
 +    * [[variables#​bl_v_d_f|bl v d f]] --- advertising data format
 +    * [[variables#​bl_v_d_g|bl v d g]] --- advertising data, GPIO mask
 +    * [[variables#​bl_v_d_i|bl v d i]] --- advertising data, iBeacon content
 +
 +===== Advertising Data Format =====
 +
 +The peripheral device transmits an advertising packet 31 octets in length. The central device scans and receives the advertising packet. The central can then request additional information. In response the peripheral sends a scan response packet, 31 octets in length. ​
 +
 +The advertising packet and the scan response packet have the same general format.
 +
 +The BLE advertising packet and scan response packet both consist of one or more structures of the form:
 +^ Length ^ Type ^ Content ^ 
 +| 1 octet | 1 octet | Length - 1 octets|
 +
 +''​Length''​ specifies the length of the data, not including the ''​Length''​ octet.
 +The data consists of an octet specifying the data type, followed by the data content. ​
 +<​code>​Length = Content_length + Type_length = Content_length + 1</​code>​
 +
 +Unused octets are set to ''​00''​.
 +
 +The diagram below shows the general structure of the advertising packet and the scan response packet.
 +
 +{{./​advertising/​advertisingdataformat1.png}}
 +
 +Source: Bluetooth Core standard v4, Vol 3, Part C - Generic Access Profile, Section 11, Advertising and Scan Response Data Format
 +
 +===== Advertising Format Examples =====
 +
 +In the example tables, the top row shows the octets in the advertising packet or scan response packet, with data in hexadecimal notation. The Least Significant Byte (LSB) is on the left. Unless otherwise noted, data is sent in little-endian order. Some proprietary formats package the data in big-endian order.
 +
 +The bottom line shows the interpretation,​ with numbers in decimal notation. Configurable parts of the advertising packet are **emphasised**. ​
 +
 +==== Generic Beacon ====
 +
 +Set BLE advertising format [[variables#​bl_v_d_f|bl v d f]] to **b**:
 +
 +<​code>​set bl v d f b</​code>​
 +
 +You can then supply data in any format for the 31 octets of the beacon. You can use the generic beacon to advertise in any format, including open formats such as:
 +    * [[#​eddystone_beacons|Eddystone Beacons]]
 +    * [[#​altbeacon|AltBeacon]] ​  
 +
 +=== Example Generic Beacon ===
 +
 +A typical generic beacon starts with a flags structure, followed by a manufacturer specific data structure. The first three octets of the manufacturer data structure specify Manufacturer type and the manufacturer ID. This leaves 24 octets for the remaining free format data. 
 +
 +|             ​02| ​       01|       ​05| ​                     1B|       ​FF| ​     4602|                  0011...EEFF0011...6677|
 +|  Length:​2 ​    ​|Type:​Flags|**Flags**| ​ **Length**:​27 octets ​ |Type:Mfr | **Mfr ID**|  **generic beacon data**:24 octets max|
 +
 +
 +The generic data, including the leading two octet Manufacturer ID, is delivered in the order specified in the [[variables#​bl_v_d_b|bl v d b]] variable argument, with the leftmost byte of the argument representing the least significant byte. To send the example advertising data above, set [[variables#​bl_v_d_b|bl v d b]] as follows:
 +
 +<​code>​
 +set bl v d b 0201051bff460200112233445566778899aabbccddeeff0011223344556677
 +</​code>​
 +
 +==== iBeacon ====
 +
 +Set BLE advertising format [[variables#​bl_v_d_f|bl v d f]] to **i**:
 +
 +<​code>​set bl v d f i</​code>​
 +
 +|      02|        01|   ​05| ​                 1A|       ​FF| ​   4C00|                   ​02| ​                       15|E2C56DB5...96AA ​  ​| ​    ​0001| ​    ​0002| ​     B9|
 +|Length:​2|Type:​Flags|Flags| ​ Length:26 octets ​ |Type:Mfr |Apple ID|Proximity beacon type|Remaining length:21 octets|**UUID**:​16 octets|**Major**|**Minor**|Tx Power|
 +    ​
 +
 +The iBeacon format is essentially a generic data beacon with a proprietary internal format. It uses 30 octets of the possible 31.
 +
 +The configurable part of the iBeacon content is UUID, Major, and Minor, specified in the [[variables#​bl_v_d_i|bl v d i]] variable. The setting corresponding to the example above is:
 +
 +<​code>​
 +set bl v d i e2c56db5-dffb-48d2-b060-d0f5a71096aa,​0001,​0002
 +</​code>​
 +
 +**Note**: iBeacon is a proprietary format and does not follow the general BLE specification requiring little-endian order. Within the iBeacon data, the UUID is displayed in big-endian order (Most Significant Byte (MSB) at the left).
 +
 +The last byte of the iBeacon is a single-octet Tx Power. This is 2's complement format, representing RSSI measured at 1 metre from the device, calculated by TruConnect based on the TruConnect device'​s antenna and settings. The Tx power value ''​B9''​ in the example translates to -71 dBm.
 +
 +==== UUID and Name ====
 +
 +This is the default advertising mode for a TruConnect device. ​
 +
 +Set BLE advertising format [[variables#​bl_v_d_f|bl v d f]] to **s**:
 +
 +<​code>​set bl v d f s</​code>​
 +
 +|      02|        01|   ​05| ​      ​11| ​      ​07| ​       0011...EEFF| ​     09|       ​09| ​     0011...6677|
 +|Length:​2|Type:​Flags|Flags|Length:​17|Type:​UUID|**UUID**:​ 16 octets|Length:​9|Type:​Name|**Name**:​8 octets|
 +
 +UUID and name are determined as follows:
 +
 +^   ​Value ​  ​^ ​  ​Associated Variable ​     ^  Default ​                                ​^ ​ Notes   ​^ ​
 +| ''​UUID'' ​ |[[variables#​bl_s_u|bl s u]] | ''​175f8f23-a570-49bd-9627-815a6a27de2a''​ |TruConnect Service ID \\ - see [[ble_connections#​truconnect_service_and_characteristics|TruConnect Service and Characteristics]] |
 +| ''​name'' ​ |[[variables#​sy_d_n|sy d n]] | ''​AMS-####'' ​                        | ''####''​ stands for the last 4 digits of the BD_ADDR \\ - see [[variables#​bl_a|bl a]]. Example: ''​AMS-0DC4''​ |
 +
 +**Note**: according to the BLE specification,​ the Service UUID appears in the advertising response as a hex number in little-endian order, with LSB first. On the TruConnect terminal, and typically in other displays for human readers, the UUID is shown with the least significant byte at the right. For example, the TruConnect Service UUID appears as follows:
 +
 +**On the TruConnect terminal, LSB at right**:
 +<​code>​
 +> get bl s u
 +175f8f23-a570-49bd-9627-815a6a27de2a
 +</​code>​
 +**In the advertising packet, LSB at left**: ​
 +<​code>​2ADE276A5A812796BD4970A5238F5F17</​code>​
 +
 +The name is a string of ASCII character codes, and appears in the advertisement in the same order as the string. For example, the name ''​AMS-ODC4''​ appears as ''​414d532d30444334''​.
 +
 +The entire advertisement,​ using the TruConnect Service ID and example name above, with LSB at left, appears as:
 +
 +''​02010511072ade276a5a812796bd4970a5238f5f170909414d532d30444334''​
 +
 +==== UUID, Name and GPIOs ====
 +
 +Set BLE advertising format [[variables#​bl_v_d_f|bl v d f]] to **s,g**:
 +
 +<​code>​set bl v d f s,​g</​code>​
 +
 +The 31-octet advertising packet, containing flags, UUID and Name is the same as for [[#​uuid_and_name|UUID and Name]] above.
 +
 +The GPIO data structure follows in the scan response packet, in the format:
 +
 +|       ​06| ​      ​FF| ​ 4602|           ​01| ​            4002|
 +| Length:6| Type:​Mfr|Mfr ID|Subtype: GPIO|  **GPIO data** ​ |
 +
 +In the example, the Mfr (Manufacturer) type and ID are as described in Supplement to the Bluetooth Core Specification,​ Part A, Data Types Specification Section 1.4, Manufacturer Specific Data. 
 +
 +The Subtype:​GPIO is a proprietary format determined by ACKme networks. ​
 +
 +The GPIO data is shown in little-endian format, and GPIOs are numbered from GPIO 0 (bit 0) to GPIO 15 (bit 15).
 +
 +The value ''​4002''​ in this example corresponds to the bits (shown with bit 0 at the right here): ''​0000 0010 0100 0000''​. That is, GPIO 6 and GPIO 9 are set to ''​1'',​ and all others are ''​0''​. ​
 +
 +To control which GPIOs appear in the GPIO data, use the [[variables#​bl_v_d_g|bl v d g]] variable to set the GPIO mask. The default is ''​FFFF'',​ with no GPIOs masked.
 +
 +For example, to mask all but GPIO 6 and GPIO 9 (Button 1 and Button 2 on the Wahoo), use the example above, which in hex, with LSB at right is ''​0240'':​
 +<​code>​
 +set bl v d g 0240
 +</​code>​
 +
 +The result in the scan response GPIO data appears with LSB first, so when both GPIO 6 and GPIO 9 are high the GPIO data is ''​40''​ then ''​02''​.
 +
 +**Note**: GPIOs must be set to STDIO function for their levels to appear in the GPIO scan response packet. See [[peripherals|Peripherals]] for details on setting GPIO function. ​
 +
 +==== Eddystone Beacons ====
 +
 +Eddystone is an open beacon format from Google that works with Android and iOS. See https://​github.com/​google/​eddystone
 +
 +You can construct Eddystone beacons using the generic beacon type.
 +
 +Set BLE advertising format [[variables#​bl_v_d_f|bl v d f]] to **b**:
 +
 +<​code>​set bl v d f b</​code>​
 +
 +=== Eddystone Beacon Preamble === 
 +
 +Eddystone beacons begin with a preamble containing two structures:
 +|       ​02| ​       01|       ​05| ​            ​03| ​                                        ​03| ​         AAFE|
 +| Length:​2|Type:​Flags|**Flags**|Length:​3 octets|Type:​Complete list of 16 bit service UUIDs |Eddystone UUID|
 +
 +Only the value of the flags can be modified.
 +
 +The final service data structure depends on the frame type: URL, UID or TLM.
 +
 +=== Eddystone URL Beacon ===
 +
 +See https://​github.com/​google/​eddystone/​tree/​master/​eddystone-url
 +
 +The Eddystone URL Beacon begins with the [[#​eddystone_beacon_preamble|preamble]] above.
 +
 +The final service data structure has the following layout:
 +
 +|                               ​0E| ​               16|            AAFE|                       ​10| ​         EB|                                           ​02| ​         73656E736F7273 |           ​07| ​        ​00...00|
 +|**Service Data Length**:14 octets|Type:​ Service Data|  Eddystone UID|Frame type: Eddystone-URL|**Tx Power**|**URL scheme**: <​nowiki>'​http://'</​nowiki>' ​  ​|**URL body**: '​sensors'​ | **domain**: '​.com'​ code |pad to 31 octets|
 +
 +To set the value of [[variables#​bl_v_d_b|bl v d b]] to the values in the above example URL beacon:
 +
 +<​code>​set bl v d b 0201050303aafe0e16aafe10eb0273656E736F727307000000000000000000</​code>​
 +
 +With an app that can decode Eddystone beacons, the URL reported for the above example is ''<​nowiki>​http://​sensors.com</​nowiki>''​
 +
 +The codes for URL scheme and domain are decoded into the expanded text when encountered. You can refer to domains not included in the encoded list by spelling them out in full. Ensure the Service Data Length is adjusted to truncate at the end of your URL. For example:
 +
 +|                               ​0C| ​               16|            AAFE|                       ​10| ​         EB|                                           ​02| ​         61636B2E6D65 |          00...00|
 +|**Service Data Length**:12 octets|Type:​ Service Data|  Eddystone UID|Frame type: Eddystone-URL|**Tx Power**|**URL scheme**: <​nowiki>'​http://'</​nowiki>' ​  ​|**URL body**: '​ack.me'​ | pad to 31 octets|
 +corresponding to the TruConnect command:
 +<​code>​set bl v d b 0201050303aafe0c16aafe10eb0261636b2e6d650000000000000000000000</​code>​
 +
 +The URL reported for the above example is ''<​nowiki>​http://​ack.me</​nowiki>''​
 +
 +=== Eddystone UID Beacon ===
 +
 +See https://​github.com/​google/​eddystone/​tree/​master/​eddystone-uid
 +
 +The Eddystone UID Beacon begins with the [[#​eddystone_beacon_preamble|preamble]] above.
 +
 +The final service data structure has the following layout:
 +
 +|                           ​17| ​               16|            AAFE|                       ​00| ​         EB|  00112233445566778899| ​       000000000001| ​                        0000|
 +|Service Data Length:23 octets|Type:​ Service Data|  Eddystone UUID|Frame type: Eddystone-UID|**Tx Power**| ​ **UID namespace** ​  ​| ​ **UID instance** ​ | Reserved octets must be zero|
 +
 +The UID namespace and UID instance are in big-endian order. ​
 +
 +To set the value of [[variables#​bl_v_d_b|bl v d b]] to the values in the above example URL beacon:
 +
 +<​code>​set bl v d b 0201050303aafe1716aafe00eb001122334455667788990000000000010000</​code>​
 +
 +With an app that can decode Eddystone beacons, the reported UID namespace for the above example is ''​00112233445566778899'',​ and the reported UUID instance is ''​000000000001''​.
 +
 +
 +=== Eddystone TLM Beacon === 
 +See https://​github.com/​google/​eddystone/​tree/​master/​eddystone-tlm
 +
 +The Eddystone TLM Beacon begins with the [[#​eddystone_beacon_preamble|preamble]] above.
 +
 +The final service data structure has the following layout:
 +
 +|                           ​11| ​               16|            AAFE|                       ​20| ​        ​00| ​     04b0|            0c4D|     ​00004e20| ​                                         00035a0c|00...|
 +|Service Data Length:17 octets|Type:​ Service Data|  Eddystone UUID|Frame type: Eddystone-TLM|TLM Version|**VBATT**:​1.2V| **TEMP**:​12.3 deg C|  **ADV_CNT**:​20,​000| **SEC_CNT**:​ 6 hrs, 6 mins, 6 secs|6 zero octets|
 +
 +Data types and formats:
 +
 +^ Data Type ^ Description ​                                ^ Format ^ Example ^ 
 +|**VBATT** ​     |Battery voltage ​                            |1mV per bit \\ if not supported: ''​0x0000'' ​              |1.2V = hex(1200) = ''​0x04b0''​ |
 +|**TEMP** ​      ​|Beacon temperature ​                         |8.8 fixed point notation \\ if not supported: ''​0x8000'' ​ |12.3 degrees: \\ MSB:​hex(12)=''​0x0c''​ \\ LSB:hex(0.3 * 256)=''​0x4D''​ |
 +|**ADV_CNT** ​   |Advertising PDU (Protocol Data Unit) count. |Integer ​                                                  ​|hex(20000) = ''​0x4e20''​ |
 +|**SEC_CNT** ​   |Time since power-on or reboot ​              |0.1 seconds per bit.                                      |6 hrs, 6 mins, 6 secs = hex(21966 * 10) = ''​0x035a0c''​ |
 +
 +**Note**: All data types are in big-endian order.
 +
 +The Eddystone TLM beacon should be sent directly after an Eddystone UID or Eddystone URL beacon, so the telemetry data can be associated with an identifier. In the Google Eddystone TLM documentation this is called interleaving. ​
 +
 +For example, set [[variables#​bl_v_d_b|bl v d b]] to the [[#​eddystone_url_beacon|Eddystone URL beacon]] above, then after a few seconds set [[variables#​bl_v_d_b|bl v d b]] to the values in the above example Eddystone TLM as follows:
 +
 +<​code>​
 +set bl v d b 0201050303aafe1116aafe200004b00c4d00004e2000035a0c000000000000
 +</​code>​
 +
 +**Note**: To be of value, Eddystone TLM beacons must be created dynamically. This requires an MCU or other controller device to assemble the beacon from data read instantaneously from the TruConnect module, and program the TruConnect device to send the beacon using the [[variables#​bl_v_d_b|set bl v d b]] command.
 +  ​
 +==== AltBeacon ====
 +
 +AltBeacon is an open protocol for proximity beacon advertisements.
 +
 +See http://​altbeacon.org/​
 +
 +You can construct AltBeacon advertisements using the generic beacon type.
 +
 +Set BLE advertising format [[variables#​bl_v_d_f|bl v d f]] to **b**:
 +
 +<​code>​set bl v d f b</​code>​
 +
 +The full AltBeacon PDU (Protocol Data Unit) starts with the standard 3-octet flags structure, and has the following layout
 +
 +|      02|        01|       ​05| ​      ​1B| ​     FF|      4602|          BEAC|       ​001122...EEFF| ​    ​0001| ​    ​0002| ​     EB|                      23|
 +|Length:​2|Type:​Flags|**Flags**|Length:​27|Type:​Mfr|**Mfr ID**|AltBeacon code|**UUID**:​ 16 octets |**Major**|**Minor**|**RSSI**|**Manufacturer Special**| ​
 +
 +To send the above AltBeacon advertisement,​ set [[variables#​bl_v_d_b|bl v d b]] as follows:
 +<​code>​
 +set bl v d b 0201051bff4602beac00112233445566778899aabbccddeeff00010002eb23 ​   ​
 +</​code>​
 +
 +
 +
 +