mirror of https://github.com/labapart/gattlib
Add support to retrieve all manufacturer data from GATT advertisement packets
parent
8a108495a1
commit
880f1d2cd0
|
@ -303,15 +303,14 @@ int gattlib_discover_desc(gattlib_connection_t* connection, gattlib_descriptor_t
|
|||
* @param mac_address is the MAC address of the device to get the RSSI
|
||||
* @param advertisement_data is an array of Service UUID and their respective data
|
||||
* @param advertisement_data_count is the number of elements in the advertisement_data array
|
||||
* @param manufacturer_id is the ID of the Manufacturer ID
|
||||
* @param manufacturer_data is the data following Manufacturer ID
|
||||
* @param manufacturer_data_size is the size of manufacturer_data
|
||||
* @param manufacturer_data is an array of `gattlib_manufacturer_data_t`
|
||||
* @param manufacturer_data_count is the number of entry in `gattlib_manufacturer_data_t` array
|
||||
*
|
||||
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
|
||||
*/
|
||||
int gattlib_get_advertisement_data(gattlib_connection_t *connection,
|
||||
gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
|
||||
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
|
||||
gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
|
||||
{
|
||||
return GATTLIB_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -323,15 +322,14 @@ int gattlib_get_advertisement_data(gattlib_connection_t *connection,
|
|||
* @param mac_address is the MAC address of the device to get the RSSI
|
||||
* @param advertisement_data is an array of Service UUID and their respective data
|
||||
* @param advertisement_data_count is the number of elements in the advertisement_data array
|
||||
* @param manufacturer_id is the ID of the Manufacturer ID
|
||||
* @param manufacturer_data is the data following Manufacturer ID
|
||||
* @param manufacturer_data_size is the size of manufacturer_data
|
||||
* @param manufacturer_data is an array of `gattlib_manufacturer_data_t`
|
||||
* @param manufacturer_data_count is the number of entry in `gattlib_manufacturer_data_t` array
|
||||
*
|
||||
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
|
||||
*/
|
||||
int gattlib_get_advertisement_data_from_mac(gattlib_adapter_t* adapter, const char *mac_address,
|
||||
gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
|
||||
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
|
||||
gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
|
||||
{
|
||||
return GATTLIB_NOT_SUPPORTED;
|
||||
}
|
||||
|
|
|
@ -30,27 +30,29 @@ static void on_eddystone_discovered_device(gattlib_adapter_t* adapter, const cha
|
|||
struct on_eddystone_discovered_device_arg *callback_data = user_data;
|
||||
gattlib_advertisement_data_t *advertisement_data = NULL;
|
||||
size_t advertisement_data_count;
|
||||
uint16_t manufacturer_id;
|
||||
uint8_t *manufacturer_data = NULL;
|
||||
size_t manufacturer_data_size;
|
||||
gattlib_manufacturer_data_t* manufacturer_data = NULL;
|
||||
size_t manufacturer_data_count = 0;
|
||||
int ret;
|
||||
|
||||
ret = gattlib_get_advertisement_data_from_mac(adapter, addr,
|
||||
&advertisement_data, &advertisement_data_count,
|
||||
&manufacturer_id, &manufacturer_data, &manufacturer_data_size);
|
||||
&manufacturer_data, &manufacturer_data_count);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback_data->discovered_device_cb(adapter, addr, name,
|
||||
advertisement_data, advertisement_data_count,
|
||||
manufacturer_id, manufacturer_data, manufacturer_data_size,
|
||||
manufacturer_data, manufacturer_data_count,
|
||||
callback_data->user_data);
|
||||
|
||||
if (advertisement_data != NULL) {
|
||||
free(advertisement_data);
|
||||
}
|
||||
if (manufacturer_data != NULL) {
|
||||
for (uintptr_t i = 0; i < manufacturer_data_count; i++) {
|
||||
free(manufacturer_data[i].data);
|
||||
}
|
||||
free(manufacturer_data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@
|
|||
|
||||
int gattlib_get_advertisement_data(gattlib_connection_t *connection,
|
||||
gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
|
||||
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
|
||||
gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
|
||||
{
|
||||
return GATTLIB_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int gattlib_get_advertisement_data_from_mac(gattlib_adapter_t* adapter, const char *mac_address,
|
||||
gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
|
||||
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
|
||||
gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
|
||||
{
|
||||
return GATTLIB_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ int gattlib_get_advertisement_data_from_mac(gattlib_adapter_t* adapter, const ch
|
|||
|
||||
int get_advertisement_data_from_device(OrgBluezDevice1 *bluez_device1,
|
||||
gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
|
||||
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
|
||||
gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
|
||||
{
|
||||
GVariant *manufacturer_data_variant;
|
||||
GVariant *service_data_variant;
|
||||
|
@ -35,36 +35,41 @@ int get_advertisement_data_from_device(OrgBluezDevice1 *bluez_device1,
|
|||
return GATTLIB_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
*manufacturer_id = 0;
|
||||
*manufacturer_data_size = 0;
|
||||
*manufacturer_data_count = 0;
|
||||
*manufacturer_data = NULL;
|
||||
manufacturer_data_variant = org_bluez_device1_get_manufacturer_data(bluez_device1);
|
||||
if (manufacturer_data_variant != NULL) {
|
||||
if (g_variant_n_children(manufacturer_data_variant) != 1) {
|
||||
GATTLIB_LOG(GATTLIB_WARNING, "Manufacturer Data with multiple children: %s",
|
||||
g_variant_print(manufacturer_data_variant, TRUE));
|
||||
return GATTLIB_NOT_SUPPORTED;
|
||||
}
|
||||
GVariant* manufacturer_data_dict = g_variant_get_child_value(manufacturer_data_variant, 0);
|
||||
GVariantIter *iter;
|
||||
GVariant* values;
|
||||
|
||||
g_variant_get(manufacturer_data_dict, "{qv}", manufacturer_id, &values);
|
||||
*manufacturer_data_size = g_variant_n_children(values);
|
||||
|
||||
*manufacturer_data = calloc(*manufacturer_data_size, sizeof(guchar));
|
||||
*manufacturer_data_count = g_variant_n_children(manufacturer_data_variant);
|
||||
*manufacturer_data = malloc(sizeof(gattlib_manufacturer_data_t) * (*manufacturer_data_count));
|
||||
if (*manufacturer_data == NULL) {
|
||||
return GATTLIB_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
GVariant* value;
|
||||
g_variant_get(values, "ay", &iter);
|
||||
size_t index = 0;
|
||||
for (uintptr_t i = 0; i < *manufacturer_data_count; i++) {
|
||||
GVariant* manufacturer_data_dict = g_variant_get_child_value(manufacturer_data_variant, i);
|
||||
GVariantIter *iter;
|
||||
GVariant* values;
|
||||
uint16_t manufacturer_id = 0;
|
||||
|
||||
while ((value = g_variant_iter_next_value(iter)) != NULL) {
|
||||
g_variant_get(value, "y", &(*manufacturer_data)[index++]);
|
||||
g_variant_unref(value);
|
||||
g_variant_get(manufacturer_data_dict, "{qv}", &manufacturer_id, &values);
|
||||
(*manufacturer_data)[i].manufacturer_id = manufacturer_id;
|
||||
(*manufacturer_data)[i].data_size = g_variant_n_children(values);
|
||||
(*manufacturer_data)[i].data = calloc((*manufacturer_data)[i].data_size, sizeof(guchar));
|
||||
if ((*manufacturer_data)[i].data == NULL) {
|
||||
return GATTLIB_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Copy manufacturer data to structure
|
||||
GVariant* value;
|
||||
g_variant_get(values, "ay", &iter);
|
||||
size_t index = 0;
|
||||
|
||||
while ((value = g_variant_iter_next_value(iter)) != NULL) {
|
||||
g_variant_get(value, "y", (*manufacturer_data)[i].data[index++]);
|
||||
g_variant_unref(value);
|
||||
}
|
||||
g_variant_iter_free(iter);
|
||||
}
|
||||
g_variant_iter_free(iter);
|
||||
}
|
||||
|
||||
service_data_variant = org_bluez_device1_get_service_data(bluez_device1);
|
||||
|
@ -114,7 +119,7 @@ int get_advertisement_data_from_device(OrgBluezDevice1 *bluez_device1,
|
|||
|
||||
int gattlib_get_advertisement_data(gattlib_connection_t *connection,
|
||||
gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
|
||||
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
|
||||
gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -138,7 +143,7 @@ int gattlib_get_advertisement_data(gattlib_connection_t *connection,
|
|||
|
||||
ret = get_advertisement_data_from_device(dbus_device,
|
||||
advertisement_data, advertisement_data_count,
|
||||
manufacturer_id, manufacturer_data, manufacturer_data_size);
|
||||
manufacturer_data, manufacturer_data_count);
|
||||
|
||||
g_object_unref(dbus_device);
|
||||
|
||||
|
@ -147,7 +152,7 @@ int gattlib_get_advertisement_data(gattlib_connection_t *connection,
|
|||
|
||||
int gattlib_get_advertisement_data_from_mac(gattlib_adapter_t* adapter, const char *mac_address,
|
||||
gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
|
||||
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
|
||||
gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
|
||||
{
|
||||
OrgBluezDevice1 *bluez_device1;
|
||||
int ret;
|
||||
|
@ -164,7 +169,7 @@ int gattlib_get_advertisement_data_from_mac(gattlib_adapter_t* adapter, const ch
|
|||
|
||||
ret = get_advertisement_data_from_device(bluez_device1,
|
||||
advertisement_data, advertisement_data_count,
|
||||
manufacturer_id, manufacturer_data, manufacturer_data_size);
|
||||
manufacturer_data, manufacturer_data_count);
|
||||
|
||||
g_object_unref(bluez_device1);
|
||||
|
||||
|
|
|
@ -38,14 +38,13 @@ static const char* adapter_name;
|
|||
static void ble_advertising_device(gattlib_adapter_t* adapter, const char* addr, const char* name, void *user_data) {
|
||||
gattlib_advertisement_data_t *advertisement_data;
|
||||
size_t advertisement_data_count;
|
||||
uint16_t manufacturer_id;
|
||||
uint8_t *manufacturer_data;
|
||||
size_t manufacturer_data_size;
|
||||
gattlib_manufacturer_data_t* manufacturer_data = NULL;
|
||||
size_t manufacturer_data_count = 0;
|
||||
int ret;
|
||||
|
||||
ret = gattlib_get_advertisement_data_from_mac(adapter, addr,
|
||||
&advertisement_data, &advertisement_data_count,
|
||||
&manufacturer_id, &manufacturer_data, &manufacturer_data_size);
|
||||
&manufacturer_data, &manufacturer_data_count);
|
||||
if (ret != 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -56,10 +55,13 @@ static void ble_advertising_device(gattlib_adapter_t* adapter, const char* addr,
|
|||
printf("Device %s: ", addr);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < manufacturer_data_size; i++) {
|
||||
printf("%02x ", manufacturer_data[i]);
|
||||
for (size_t i = 0; i < manufacturer_data_count; i++) {
|
||||
printf("- Manufacturer data for id 0x%x: ", manufacturer_data[i].manufacturer_id);
|
||||
for (size_t j = 0; j < manufacturer_data[i].data_size; j++) {
|
||||
printf("%02x ", manufacturer_data[i].data[j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void* ble_task(void *arg) {
|
||||
|
|
|
@ -45,7 +45,7 @@ const char* m_adapter_name;
|
|||
*/
|
||||
void on_eddystone_found(gattlib_adapter_t* adapter, const char* addr, const char* name,
|
||||
gattlib_advertisement_data_t *advertisement_data, size_t advertisement_data_count,
|
||||
uint16_t manufacturer_id, uint8_t *manufacturer_data, size_t manufacturer_data_size,
|
||||
gattlib_manufacturer_data_t* manufacturer_data, size_t manufacturer_data_count,
|
||||
void *user_data)
|
||||
{
|
||||
puts("Found Eddystone device");
|
||||
|
|
|
@ -210,13 +210,13 @@ gattlib_get_rssi_from_mac.argtypes = [c_void_p, c_char_p, POINTER(c_int16)]
|
|||
|
||||
# int gattlib_get_advertisement_data(gattlib_connection_t *connection,
|
||||
# gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
|
||||
# uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
|
||||
# gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
|
||||
gattlib_get_advertisement_data = gattlib.gattlib_get_advertisement_data
|
||||
gattlib_get_advertisement_data.argtypes = [c_void_p, POINTER(POINTER(GattlibAdvertisementData)), POINTER(c_size_t), POINTER(c_uint16), POINTER(c_void_p), POINTER(c_size_t)]
|
||||
|
||||
# int gattlib_get_advertisement_data_from_mac(gattlib_adapter_t* adapter, const char *mac_address,
|
||||
# gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_length,
|
||||
# uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size)
|
||||
# gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count)
|
||||
gattlib_get_advertisement_data_from_mac = gattlib.gattlib_get_advertisement_data_from_mac
|
||||
gattlib_get_advertisement_data_from_mac.argtypes = [c_void_p, c_char_p, POINTER(POINTER(GattlibAdvertisementData)), POINTER(c_size_t), POINTER(c_uint16), POINTER(c_void_p), POINTER(c_size_t)]
|
||||
|
||||
|
|
|
@ -164,6 +164,15 @@ typedef struct {
|
|||
size_t data_length; /**< Length of data attached to the GATT Service */
|
||||
} gattlib_advertisement_data_t;
|
||||
|
||||
/**
|
||||
* Structure to represent manufacturer data from GATT advertisement packet
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t manufacturer_id;
|
||||
uint8_t* data;
|
||||
size_t data_size;
|
||||
} gattlib_manufacturer_data_t;
|
||||
|
||||
typedef void (*gattlib_event_handler_t)(const uuid_t* uuid, const uint8_t* data, size_t data_length, void* user_data);
|
||||
|
||||
/**
|
||||
|
@ -192,14 +201,13 @@ typedef void (*gattlib_discovered_device_t)(gattlib_adapter_t* adapter, const ch
|
|||
* @param name is the name of BLE device if advertised
|
||||
* @param advertisement_data is an array of Service UUID and their respective data
|
||||
* @param advertisement_data_count is the number of elements in the advertisement_data array
|
||||
* @param manufacturer_id is the ID of the Manufacturer ID
|
||||
* @param manufacturer_data is the data following Manufacturer ID
|
||||
* @param manufacturer_data_size is the size of manufacturer_data
|
||||
* @param manufacturer_data is an array of `gattlib_manufacturer_data_t`
|
||||
* @param manufacturer_data_count is the number of entry in `gattlib_manufacturer_data_t` array
|
||||
* @param user_data Data defined when calling `gattlib_register_on_disconnect()`
|
||||
*/
|
||||
typedef void (*gattlib_discovered_device_with_data_t)(gattlib_adapter_t* adapter, const char* addr, const char* name,
|
||||
gattlib_advertisement_data_t *advertisement_data, size_t advertisement_data_count,
|
||||
uint16_t manufacturer_id, uint8_t *manufacturer_data, size_t manufacturer_data_size,
|
||||
gattlib_manufacturer_data_t* manufacturer_data, size_t manufacturer_data_count,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
|
@ -688,15 +696,14 @@ int gattlib_get_rssi_from_mac(gattlib_adapter_t* adapter, const char *mac_addres
|
|||
* @param connection Active GATT connection
|
||||
* @param advertisement_data is an array of Service UUID and their respective data
|
||||
* @param advertisement_data_count is the number of elements in the advertisement_data array
|
||||
* @param manufacturer_id is the ID of the Manufacturer ID
|
||||
* @param manufacturer_data is the data following Manufacturer ID
|
||||
* @param manufacturer_data_size is the size of manufacturer_data
|
||||
* @param manufacturer_data is an array of `gattlib_manufacturer_data_t`
|
||||
* @param manufacturer_data_count is the number of entry in `gattlib_manufacturer_data_t` array
|
||||
*
|
||||
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
|
||||
*/
|
||||
int gattlib_get_advertisement_data(gattlib_connection_t *connection,
|
||||
gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
|
||||
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size);
|
||||
gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count);
|
||||
|
||||
/**
|
||||
* @brief Function to retrieve Advertisement Data from a MAC Address
|
||||
|
@ -705,15 +712,14 @@ int gattlib_get_advertisement_data(gattlib_connection_t *connection,
|
|||
* @param mac_address is the MAC address of the device to get the RSSI
|
||||
* @param advertisement_data is an array of Service UUID and their respective data
|
||||
* @param advertisement_data_count is the number of elements in the advertisement_data array
|
||||
* @param manufacturer_id is the ID of the Manufacturer ID
|
||||
* @param manufacturer_data is the data following Manufacturer ID
|
||||
* @param manufacturer_data_size is the size of manufacturer_data
|
||||
* @param manufacturer_data is an array of `gattlib_manufacturer_data_t`
|
||||
* @param manufacturer_data_count is the number of entry in `gattlib_manufacturer_data_t` array
|
||||
*
|
||||
* @return GATTLIB_SUCCESS on success or GATTLIB_* error code
|
||||
*/
|
||||
int gattlib_get_advertisement_data_from_mac(gattlib_adapter_t* adapter, const char *mac_address,
|
||||
gattlib_advertisement_data_t **advertisement_data, size_t *advertisement_data_count,
|
||||
uint16_t *manufacturer_id, uint8_t **manufacturer_data, size_t *manufacturer_data_size);
|
||||
gattlib_manufacturer_data_t** manufacturer_data, size_t* manufacturer_data_count);
|
||||
|
||||
/**
|
||||
* @brief Convert a UUID into a string
|
||||
|
|
Loading…
Reference in New Issue