Tech Evangelist at Microsoft gets opportunities to work on multiple domains. I have been focusing on game dev and cloud for past couple of years. However, this new IoT opportunity intrigued me and led me to an interesting case. Here’s a tale of few bytes.
A couple of months back when Windows Phone 8.1 was released, new functionalities including BTLEsupport were added. I got in touch with an innovative device manufacturer. They had built a nice small device which could control switch to turn lights on and off, changing TV channels etc. This device was based on BTLE and used custom GATTprofiles. Interestingly, this device was able to pair with Android and iPhone however, failed to show up on Windows Phone 8.1. Well, we knew the issue at that time. Even though with WP8.1 BTLE support was announced, the drivers were not bundled in developer preview.
Once Lumia 630 was launched, (comes with WP8.1 RTM edition) we tried to pair it with this IoT device and failed again. This was a major concern because we were again failing to see the device on WP8.1 with Bluetooth.
Initially, we thought that the custom GATT profile implementation by the device manufacturer might have bugs. Though this should have not stopped the device to at least show up in the list of available Bluetooth devices on Lumia 630. With further digging we figured out that this problem was not related to any particular GATT profile, since advertising and BTLE pairing occurs prior to any profile connections.
Here’s an example of WP BTLE HCI activity when finding a device and pairing to it:
85 Command 0x200c 2 HCI_LE_Set_Scan_Enable
87 Event 0x200c 4 HCI_LE_Set_Scan_Enable Command Complete Success
114 Event 23 LE Advertising Report
Bluetooth Device Address: 0x90-59-af-06-f6-b1
120 Command 0x200d 25 HCI_LE_Create_Connection
Bluetooth Device Address: 0x90-59-af-06-f6-b1
122 Event 0x200d 4 HCI_LE_Create_Connection Command Status Success
123 Event 19 0x000a LE Connection Complete Success
126 M Pairing Request 15
128 2 Pairing Response 15
129 M Pairing Confirm 25
131 2 Pairing Confirm 25
132 M Pairing Random 25
134 2 Pairing Random 25
138 2 Encryption Information 25
139 2 Master Identification 19
140 2 Identity Information 25
141 2 Identity Address Information 16
142 M Signing Information 25
With this, we closed on our investigation and next step was to find out how this scan, advertisement and pairing happens with the IoT device. We asked the device manufacturer to send their advertisement and scan packet details.
Here’s how TI’s Sensor tag works. This device was pairing with WP8.1 RTM
No. of bytes
Length of first data structure
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED
Scan Response packet
Length of second data structure
Length of third data structure
Here’s how device manufacturer was sending packets with their IoT device
Normal or shake parameter
0x00 / 0x01
Their IoT device advertisement structure had additional packets. When we removed them, WP8.1 was able to detect and pair with their device. However, we were not sure why WP8.1 failed to detect the device with additional packets, so we went deeper to understand the root cause.
In their additional packets, vendor section size was set to 0x2 which was not valid. Their IoT device was not spec compliant and Windows Phone 8.1 was rejecting the payload. Vendor specific section must contain at least 3 bytes (1 byte for the section type (0xff) and 2 bytes for the manufacturer code)
Reference: Core Specification Supplement (https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=282152)
The Manufacturer Specific data type is used for manufacturer specific data. The first two data octets should contain a company identifier code from the Assigned Numbers - Company Identifiers document. The interpretation of any other octets within the data shall be defined by the manufacturer specified by the company identifier.
Additionally, we found that BT Core_V4.0 spec Volume 3 Part C Section 11 “Advertising and Scan Response Data Format” Figure 11.1 shows that each AD structure consists of:
1 octet: <Length>
1 octet: <AD Type>
<Length> - 1 octets: <AD Data>
Applying Appendix C “EIR and AD Formats” Section 18.11 “Manufacturer Specific Data” to the above we see that the format of the AD structure in this case should be:
1 octet: <Length> [Must be *at least* 3]
1 octet: 0xFF [AD Type == Manufacturer Specific]
2 octets: Company Identifier
<Length – 3> octets: <Manufacturer specific data>
The IoT device failed to meet the specified format for the AD structure of “Manufacturer Specific Data” in 2 ways:
1. The <Length> field value of 0x02 is too small to be valid, it must be at least 3
2. The Company ID should be the first 2 bytes of the “Manufacturer Specific Data” but it was missing
To fix the issue, we asked device manufacturer to update the format of the Advertisement structure for the “Manufacturer Specific Data” to:
1 octet: 0x04 <Length>
2 octets:< company ID >
1 octet: 0x00 or 0x01 depending on whatever “gesture” value they wanted to advertise
So, at the end a few bytes were held responsible and updating the information helped resolve the issue. In case you are building such device or happen to work on such devices, please make sure that your device pass the BT LE qualification tests.
For those who are interested to know more, here’s how Windows Phone work with BTLE:
1. Establishing a Connection
Windows 8.1 will automatically connect to a device when an application has a registered a handler for the GattCharacteristic.ValueChanged event. However the basic definition of the services included in the Proximity Profile does not contain any indicatable or notifiable characteristics. A device can add a service that contains an indicatable or notifiable characteristic to the services included in the Proximity Profile. This means that a proximity device must support at least one indicatable or notifiable characteristic value and an application must register at least one handler to a GattCharacteristic.ValueChanged event for the connection to be automatically established.
2. Detecting Loss of Connection
As mentioned in Bluetooth Proximity Profile, Windows 8.1 does not expose the RSSI value of Bluetooth connections. Consequently, apps cannot use the RSSI value to calculate the connection path loss. Instead, we recommend that a device tie its proximity to the link loss event.
3. Bluetooth GATT—Windows.Device.Bluetooth.Gatt
· The API lets Windows Store app developers implement GATT client profiles for collecting data from low energy (LE) sensors.
· A Bluetooth 4.0 radio is required to use the GATT API.
· The GATT API prevents access to the following in-box and invalid services:
Service ID Service (Bluetooth SIG name)
0x1812 HID Over GATT Service
· The GATT API provides read-only access to the following in-box and invalid services:
0x1800 GAP Service
0x1801 GATT Service
0x1813 Scan Parameters Service
Note: The Windows Runtime APIs for RFCOMM and GATT are not intended for use in Control Panel apps.
1. Bluetooth LE Proximity Profile Devices and Apps http://msdn.microsoft.com/en-us/library/dn423914(v=vs.85).aspx
2. Bluetooth hardware implementation on Windows Phone: https://dev.windowsphone.com/en-us/OEM/docs/Driver_Components/Bluetooth
Thanks to Jeff and Alain from product group and Kuldeep for their valuable inputs.
Awesome work ujjwal....thanks for sharing