From 8170d5c62bb4f0823785993a328b170394d18e65 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 17 Apr 2018 16:26:10 +0300 Subject: [PATCH] device: Add implementation of AdvertisingData This adds the implementation of AdvertisingData property: [CHG] Device 00:1B:DC:07:31:88 AdvertisingData Key: 0x26 [CHG] Device 00:1B:DC:07:31:88 AdvertisingData Value: 01 01 00 ... Change-Id: Idb4d29968e84d10c2643a1e8bc0dc6c981acd716 Signed-off-by: Amit Purwar --- src/adapter.c | 3 +++ src/device.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/device.h | 2 ++ src/eir.c | 27 ++++++++++++++++++++++++ src/eir.h | 8 +++++++ 5 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/adapter.c b/src/adapter.c index dea5f67..4759ec3 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -10796,6 +10796,9 @@ static void update_found_devices(struct btd_adapter *adapter, if (eir_data.sd_list) device_set_service_data(dev, eir_data.sd_list, duplicate); + if (eir_data.data_list) + device_set_data(dev, eir_data.data_list, duplicate); + #ifdef TIZEN_FEATURE_BLUEZ_MODIFY if (bdaddr_type != BDADDR_BREDR && adv_type != ADV_TYPE_SCAN_RESPONSE) device_set_flags(dev, eir_data.flags); diff --git a/src/device.c b/src/device.c index d7d0178..2ef80ec 100644 --- a/src/device.c +++ b/src/device.c @@ -1760,6 +1760,46 @@ dev_property_service_data_exist(const GDBusPropertyTable *property, return bt_ad_has_service_data(device->ad, NULL); } +static void append_advertising_data(void *data, void *user_data) +{ + struct bt_ad_data *ad = data; + DBusMessageIter *dict = user_data; + + g_dbus_dict_append_basic_array(dict, + DBUS_TYPE_BYTE, &ad->type, + DBUS_TYPE_BYTE, &ad->data, ad->len); +} + +static gboolean +dev_property_get_advertising_data(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct btd_device *device = data; + DBusMessageIter dict; + + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_BYTE_AS_STRING + DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + &dict); + + bt_ad_foreach_data(device->ad, append_advertising_data, &dict); + + dbus_message_iter_close_container(iter, &dict); + + return TRUE; +} + +static gboolean +dev_property_advertising_data_exist(const GDBusPropertyTable *property, + void *data) +{ + struct btd_device *device = data; + + return bt_ad_has_data(device->ad, NULL); +} + static gboolean disconnect_all(gpointer user_data) { struct btd_device *device = user_data; @@ -2189,6 +2229,29 @@ void device_set_service_data(struct btd_device *dev, GSList *list, g_slist_foreach(list, add_service_data, dev); } +static void add_data(void *data, void *user_data) +{ + struct eir_ad *ad = data; + struct btd_device *dev = user_data; + + if (!bt_ad_add_data(dev->ad, ad->type, ad->data, ad->len)) + return; + + if (ad->type == EIR_TRANSPORT_DISCOVERY) + g_dbus_emit_property_changed(dbus_conn, dev->path, + DEVICE_INTERFACE, + "AdvertisingData"); +} + +void device_set_data(struct btd_device *dev, GSList *list, + bool duplicate) +{ + if (duplicate) + bt_ad_clear_data(dev->ad); + + g_slist_foreach(list, add_data, dev); +} + static struct btd_service *find_connectable_service(struct btd_device *dev, const char *uuid) { @@ -4349,7 +4412,9 @@ static const GDBusPropertyTable device_properties[] = { { "AdvertisingFlags", "ay", dev_property_get_flags, NULL, dev_property_flags_exist, G_DBUS_PROPERTY_FLAG_EXPERIMENTAL}, - + { "AdvertisingData", "a{yv}", dev_property_get_advertising_data, + NULL, dev_property_advertising_data_exist, + G_DBUS_PROPERTY_FLAG_EXPERIMENTAL }, { } }; diff --git a/src/device.h b/src/device.h index 7a95f93..e642e6d 100644 --- a/src/device.h +++ b/src/device.h @@ -93,6 +93,8 @@ void device_set_manufacturer_data(struct btd_device *dev, GSList *list, bool duplicate); void device_set_service_data(struct btd_device *dev, GSList *list, bool duplicate); +void device_set_data(struct btd_device *dev, GSList *list, + bool duplicate); void device_probe_profile(gpointer a, gpointer b); void device_remove_profile(gpointer a, gpointer b); struct btd_adapter *device_get_adapter(struct btd_device *device); diff --git a/src/eir.c b/src/eir.c index ee5975a..b10dcca 100755 --- a/src/eir.c +++ b/src/eir.c @@ -51,6 +51,14 @@ static void sd_free(void *data) g_free(sd); } +static void data_free(void *data) +{ + struct eir_ad *ad = data; + + g_free(ad->data); + g_free(ad); +} + void eir_data_free(struct eir_data *eir) { g_slist_free_full(eir->services, free); @@ -69,6 +77,8 @@ void eir_data_free(struct eir_data *eir) g_free(eir->manufacturer_data); eir->manufacturer_data = NULL; #endif + g_slist_free_full(eir->data_list, data_free); + eir->data_list = NULL; } static void eir_parse_uuid16(struct eir_data *eir, const void *data, @@ -251,6 +261,20 @@ static void eir_parse_uuid128_data(struct eir_data *eir, const uint8_t *data, eir_parse_sd(eir, &service, data + 16, len - 16); } +static void eir_parse_data(struct eir_data *eir, uint8_t type, + const uint8_t *data, uint8_t len) +{ + struct eir_ad *ad; + + ad = g_malloc(sizeof(*ad)); + ad->type = type; + ad->len = len; + ad->data = g_malloc(len); + memcpy(ad->data, data, len); + + eir->data_list = g_slist_append(eir->data_list, ad); +} + void eir_parse(struct eir_data *eir, const uint8_t *eir_data, uint8_t eir_len) { uint16_t len = 0; @@ -379,6 +403,9 @@ void eir_parse(struct eir_data *eir, const uint8_t *eir_data, uint8_t eir_len) eir_parse_msd(eir, data, data_len); break; + default: + eir_parse_data(eir, eir_data[1], data, data_len); + break; } eir_data += field_len + 1; diff --git a/src/eir.h b/src/eir.h index 5e8bbd5..4a0c88c 100755 --- a/src/eir.h +++ b/src/eir.h @@ -49,6 +49,7 @@ #define EIR_SOLICIT32 0x1F /* LE: Solicit UUIDs, 32-bit */ #define EIR_SVC_DATA32 0x20 /* LE: Service data, 32-bit UUID */ #define EIR_SVC_DATA128 0x21 /* LE: Service data, 128-bit UUID */ +#define EIR_TRANSPORT_DISCOVERY 0x26 /* Transport Discovery Service */ #define EIR_MANUFACTURER_DATA 0xFF /* Manufacturer Specific Data */ /* Flags Descriptions */ @@ -75,6 +76,12 @@ struct eir_sd { uint8_t data_len; }; +struct eir_ad { + uint8_t type; + uint8_t len; + void *data; +}; + struct eir_data { GSList *services; unsigned int flags; @@ -92,6 +99,7 @@ struct eir_data { uint16_t did_source; GSList *msd_list; GSList *sd_list; + GSList *data_list; #ifdef TIZEN_FEATURE_BLUEZ_MODIFY char *manufacturer_data; uint8_t manufacturer_data_len; -- 2.7.4