Question: Phrased another way. My Intel Bluetooth controller accepts data from my Polar Bluetooth LE device and places the data on the D-bus system bus. How do I use the bluez API and D-Bus to read my Polar sensors heart rate data?
In an attempt to at least see the Polar sensor, I ran c code written by Parthiban Nallathambi at www.linumiz.com: https://www.linumiz.com/bluetooth-list-devices-using-gdbus/. Providing this for credit and background.
The code accurately displayed the Polar sensor attributes, but no data. FYI, the 1st few executions it actually did display ManufacturerData:
Address : D2:9C:2A:C8:F9:CA
AddressType : random
Name : Polar H9 ADAC102E
Alias : Polar H9 ADAC102E
Appearance : Other
Paired : 1
Trusted : 1
Blocked : 0
LegacyPairing : 0
Connected : 0
UUIDs :
00001800-0000-1000-8000-00805f9b34fb
00001801-0000-1000-8000-00805f9b34fb
0000180a-0000-1000-8000-00805f9b34fb
0000180d-0000-1000-8000-00805f9b34fb
0000180f-0000-1000-8000-00805f9b34fb
0000181c-0000-1000-8000-00805f9b34fb
0000feee-0000-1000-8000-00805f9b34fb
6217ff4b-fb31-1140-ad5a-a45545d7ecf3
Adapter : Other
ServicesResolved : 0
Then I ran bluetoothctl to display vendor data in ManufacturerData:
steven@DEVELOPMENT-JETSON:~$ bluetoothctl
[NEW] Device D2:9C:2A:C8:F9:CA Polar H9 ADAC102E
[NEW] Primary Service
/org/bluez/hci0/dev_D2_9C_2A_C8_F9_CA/service0045
0000feee-0000-1000-8000-00805f9b34fb
Polar Electro Oy
[NEW] Characteristic
/org/bluez/hci0/dev_D2_9C_2A_C8_F9_CA/service000e/char000f
00002a37-0000-1000-8000-00805f9b34fb
Heart Rate Measurement
[bluetooth]# **connect D2:9C:2A:C8:F9:CA**
Attempting to connect to D2:9C:2A:C8:F9:CA
[CHG] Device D2:9C:2A:C8:F9:CA Connected: yes
Connection successful
[CHG] Device D2:9C:2A:C8:F9:CA ServicesResolved: yes
[Polar H9 ADAC102E]# scan on
Discovery started
[CHG] Device D2:9C:2A:C8:F9:CA RSSI: -67
[CHG] Device D2:9C:2A:C8:F9:CA ManufacturerData Key: 0x006b
[CHG] Device D2:9C:2A:C8:F9:CA ManufacturerData Value: 33 1e 33 33 3.33
I'm just baffled, I can't find any examples of c code that does the following (pseudo code):
Not looking for someone to write the code, but for someone to point me at the bluez/dbus functions or code if you have it :-), that will accomplish this. Thanks for you time. I'm just stumped.
I have already looked at the Bluetooth for Linux Developers Study Guide, but its in Python and I'm looking for a C guide.
If you followed the example in here then you should have a function named bluez_property_value
, in here you need to compare the key
param with "ManufacturerData" and then extract that information using GVariant
in this case is an a{qv}
an array of dictionaries containing a q
id and a v
variant where this variant is an array of bytes ay
.
void bluez_property_value(const gchar *key, GVariant *value)
{
if (g_strcmp0(key, "ManufacturerData") != 0)
return;
const guint16 id;
GVariant *manufacturing_data = NULL;
GVariantIter *iter;
g_variant_get(value, "a{qv}", &iter);
while (g_variant_iter_loop(iter, "{qv}", &id, &manufacturing_data))
{
const guint8 byte;
GVariantIter *bytes;
g_variant_get(manufacturing_data, "ay", &bytes);
while (g_variant_iter_next(bytes, "y", &byte))
fprintf(stdout, "%02X", byte);
fflush(stdout)
}
}
/**
* @brief read a float from unsigned int,
* Check if the first bit is 1, if it is the number is negative
* so we need to negate the number with the ~ operator and extract
* a the subset of the bits from the number.
*
* @param number the number to read from
* @return double, the negative or positive value
*/
double read_negative_value(int number)
{
if ((number & 0x8000) > 0)
return -(double) ((~number) & 0x7FFF);
return (double) number;
}
EDIT: Fix code format.
EDIT2: Added a function to read negative values from manufacturer data.