diff --git a/bluez/gattlib_discover.c b/bluez/gattlib_discover.c index c2a9206..a72c17b 100644 --- a/bluez/gattlib_discover.c +++ b/bluez/gattlib_discover.c @@ -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; } diff --git a/common/gattlib_eddystone.c b/common/gattlib_eddystone.c index 4e1370e..a700062 100644 --- a/common/gattlib_eddystone.c +++ b/common/gattlib_eddystone.c @@ -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); } } diff --git a/dbus/gattlib_advertisement.c b/dbus/gattlib_advertisement.c index 9aaa640..e025a86 100644 --- a/dbus/gattlib_advertisement.c +++ b/dbus/gattlib_advertisement.c @@ -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); diff --git a/examples/advertisement_data/advertisement_data.c b/examples/advertisement_data/advertisement_data.c index 4f24267..f6c82d1 100644 --- a/examples/advertisement_data/advertisement_data.c +++ b/examples/advertisement_data/advertisement_data.c @@ -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) { diff --git a/examples/find_eddystone/find_eddystone.c b/examples/find_eddystone/find_eddystone.c index d66cc79..1f82fad 100644 --- a/examples/find_eddystone/find_eddystone.c +++ b/examples/find_eddystone/find_eddystone.c @@ -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"); diff --git a/gattlib-py/gattlib/__init__.py b/gattlib-py/gattlib/__init__.py index 8c8460e..52d6169 100644 --- a/gattlib-py/gattlib/__init__.py +++ b/gattlib-py/gattlib/__init__.py @@ -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)] diff --git a/include/gattlib.h b/include/gattlib.h index 2bffabf..2814f83 100644 --- a/include/gattlib.h +++ b/include/gattlib.h @@ -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