* [PATCH v3 0/1] tools: Add raw advertising data support to BlueZ @ 2025-10-10 13:55 Adrian Dudau 2025-10-10 13:55 ` [PATCH v3 1/1] " Adrian Dudau 0 siblings, 1 reply; 4+ messages in thread From: Adrian Dudau @ 2025-10-10 13:55 UTC (permalink / raw) To: linux-bluetooth Cc: luiz.dentz, mihai-octavian.urzica, andrei.istodorescu, Adrian Dudau This patch introduces support for storing and exposing raw advertising data from Bluetooth Low Energy devices through D-Bus properties and internal APIs. Key changes: - Add raw_data fields to eir_data and bt_ad structures - Implement bt_ad_set_raw_data(), bt_ad_clear_raw_data(), bt_ad_has_raw_data(), and bt_ad_get_raw_data() APIs - Expose RawAdvertisingData D-Bus property on device objects - Store raw advertising data during EIR parsing - Update BTP client to include raw advertising data in device found events The RawAdvertisingData property is marked with G_DBUS_PROPERTY_FLAG_TESTING for debugging and protocol testing purposes. This enables applications to access complete raw advertising packet contents for custom parsing, compliance testing, and troubleshooting scenarios. The raw data format follows the Extended Inquiry Response Data Format as described in BLUETOOTH CORE SPECIFICATION Version 6.1 | Vol 3, Part C. Adrian Dudau (1): tools: Add raw advertising data support to BlueZ src/adapter.c | 5 +++++ src/device.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++ src/device.h | 2 ++ src/eir.c | 7 ++++++ src/eir.h | 3 +++ src/shared/ad.c | 50 +++++++++++++++++++++++++++++++++++++++++ src/shared/ad.h | 8 +++++++ tools/btpclient.c | 56 ++++++++++++++++++++++++++++++++++++++++++---- 8 files changed, 184 insertions(+), 4 deletions(-) base-commit: 4be24398f9ef510e4904e7190688fc2c02f3a583 -- 2.45.2 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 1/1] tools: Add raw advertising data support to BlueZ 2025-10-10 13:55 [PATCH v3 0/1] tools: Add raw advertising data support to BlueZ Adrian Dudau @ 2025-10-10 13:55 ` Adrian Dudau 2025-10-10 15:31 ` bluez.test.bot 2025-10-17 15:53 ` [PATCH v3 1/1] " Luiz Augusto von Dentz 0 siblings, 2 replies; 4+ messages in thread From: Adrian Dudau @ 2025-10-10 13:55 UTC (permalink / raw) To: linux-bluetooth Cc: luiz.dentz, mihai-octavian.urzica, andrei.istodorescu, Adrian Dudau This patch introduces support for storing and exposing raw advertising data from Bluetooth Low Energy devices through D-Bus properties and internal APIs. Key changes: - Add raw_data fields to eir_data and bt_ad structures - Implement bt_ad_set_raw_data(), bt_ad_clear_raw_data(), bt_ad_has_raw_data(), and bt_ad_get_raw_data() APIs - Expose RawAdvertisingData D-Bus property on device objects - Store raw advertising data during EIR parsing - Update BTP client to include raw advertising data in device found events The RawAdvertisingData property is marked with G_DBUS_PROPERTY_FLAG_TESTING for debugging and protocol testing purposes. This enables applications to access complete raw advertising packet contents for custom parsing, compliance testing, and troubleshooting scenarios. The raw data format follows the Extended Inquiry Response Data Format as described in BLUETOOTH CORE SPECIFICATION Version 6.1 | Vol 3, Part C. Signed-off-by: Adrian Dudau <adrian-constantin.dudau@nxp.com> --- src/adapter.c | 5 +++++ src/device.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++ src/device.h | 2 ++ src/eir.c | 7 ++++++ src/eir.h | 3 +++ src/shared/ad.c | 50 +++++++++++++++++++++++++++++++++++++++++ src/shared/ad.h | 8 +++++++ tools/btpclient.c | 56 ++++++++++++++++++++++++++++++++++++++++++---- 8 files changed, 184 insertions(+), 4 deletions(-) diff --git a/src/adapter.c b/src/adapter.c index 1ee2f3a08164..66d48c90fe8a 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -7471,6 +7471,11 @@ void btd_adapter_device_found(struct btd_adapter *adapter, if (eir_data.data_list) device_set_data(dev, eir_data.data_list, duplicate); + if (eir_data.raw_data_len > 0) + device_set_raw_adv_data(dev, eir_data.raw_data, + eir_data.raw_data_len, + duplicate); + if (bdaddr_type != BDADDR_BREDR) device_set_flags(dev, eir_data.flags); diff --git a/src/device.c b/src/device.c index 8d74ae0ea0ff..a244ab1cb796 100644 --- a/src/device.c +++ b/src/device.c @@ -1615,6 +1615,47 @@ dev_property_advertising_data_exist(const GDBusPropertyTable *property, return bt_ad_has_data(device->ad, NULL); } +static gboolean +dev_property_get_raw_advertising_data(const GDBusPropertyTable *property, + DBusMessageIter *iter, void *data) +{ + struct btd_device *device = data; + uint8_t *raw_data = NULL; + size_t raw_data_len = 0; + DBusMessageIter array; + + if (!device) + return FALSE; + + bt_ad_get_raw_data(device->ad, &raw_data, &raw_data_len); + + if (!raw_data || raw_data_len == 0) + return FALSE; + + dbus_message_iter_open_container(iter, + DBUS_TYPE_ARRAY, + DBUS_TYPE_BYTE_AS_STRING, + &array); + + dbus_message_iter_append_fixed_array(&array, + DBUS_TYPE_BYTE, + &raw_data, + raw_data_len); + + dbus_message_iter_close_container(iter, &array); + + return TRUE; +} + +static gboolean +dev_property_raw_advertising_data_exist(const GDBusPropertyTable *property, + void *data) +{ + struct btd_device *device = data; + + return bt_ad_has_raw_data(device->ad); +} + static bool device_get_wake_support(struct btd_device *device) { return device->wake_support; @@ -2401,6 +2442,19 @@ void device_set_manufacturer_data(struct btd_device *dev, GSList *list, g_slist_foreach(list, add_manufacturer_data, dev); } +void device_set_raw_adv_data(struct btd_device *dev, + const uint8_t *data, size_t len, + bool duplicate) +{ + if (!dev) + return; + + if (duplicate) + bt_ad_clear_raw_data(dev->ad); + + bt_ad_set_raw_data(dev->ad, data, len); +} + static void add_service_data(void *data, void *user_data) { struct eir_sd *sd = data; @@ -3619,6 +3673,9 @@ static const GDBusPropertyTable device_properties[] = { dev_property_flags_exist }, { "AdvertisingData", "a{yv}", dev_property_get_advertising_data, NULL, dev_property_advertising_data_exist }, + { "RawAdvertisingData", "ay", dev_property_get_raw_advertising_data, + NULL, dev_property_raw_advertising_data_exist, + G_DBUS_PROPERTY_FLAG_TESTING }, { "WakeAllowed", "b", dev_property_get_wake_allowed, dev_property_set_wake_allowed, dev_property_wake_allowed_exist }, diff --git a/src/device.h b/src/device.h index 9ff9cdfefc28..84dfa9faaa82 100644 --- a/src/device.h +++ b/src/device.h @@ -81,6 +81,8 @@ void btd_device_add_uuid(struct btd_device *device, const char *uuid); void device_add_eir_uuids(struct btd_device *dev, GSList *uuids); void device_set_manufacturer_data(struct btd_device *dev, GSList *list, bool duplicate); +void device_set_raw_adv_data(struct btd_device *device, const uint8_t *data, + size_t len, 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, diff --git a/src/eir.c b/src/eir.c index 68ed74fe6493..497e11bd3125 100644 --- a/src/eir.c +++ b/src/eir.c @@ -243,6 +243,13 @@ void eir_parse(struct eir_data *eir, const uint8_t *eir_data, uint8_t eir_len) if (eir_data == NULL) return; + if (eir_len > 0 && eir_len <= EIR_MAX_LEN) { + memcpy(eir->raw_data, eir_data, eir_len); + eir->raw_data_len = eir_len; + } else { + eir->raw_data_len = 0; + } + while (len < eir_len - 1) { uint8_t field_len = eir_data[0]; const uint8_t *data; diff --git a/src/eir.h b/src/eir.h index b9f7c3874eb3..bb7b74527d97 100644 --- a/src/eir.h +++ b/src/eir.h @@ -53,6 +53,7 @@ #define EIR_SD_MAX_LEN 238 /* 240 (EIR) - 2 (len) */ #define EIR_MSD_MAX_LEN 236 /* 240 (EIR) - 2 (len & type) - 2 */ +#define EIR_MAX_LEN 240 struct eir_msd { uint16_t company; @@ -91,6 +92,8 @@ struct eir_data { GSList *msd_list; GSList *sd_list; GSList *data_list; + uint8_t raw_data[EIR_MAX_LEN]; + size_t raw_data_len; }; void eir_data_free(struct eir_data *eir); diff --git a/src/shared/ad.c b/src/shared/ad.c index 9e21cbf61a29..443ba002fc56 100644 --- a/src/shared/ad.c +++ b/src/shared/ad.c @@ -35,6 +35,8 @@ struct bt_ad { struct queue *solicit_uuids; struct queue *service_data; struct queue *data; + uint8_t *raw_data; + size_t raw_data_len; }; struct pattern_match_info { @@ -55,6 +57,8 @@ struct bt_ad *bt_ad_new(void) ad->service_data = queue_new(); ad->data = queue_new(); ad->appearance = UINT16_MAX; + ad->raw_data = NULL; + ad->raw_data_len = 0; return bt_ad_ref(ad); } @@ -199,6 +203,8 @@ void bt_ad_unref(struct bt_ad *ad) free(ad->name); + free(ad->raw_data); + free(ad); } @@ -1252,6 +1258,50 @@ bool bt_ad_has_data(struct bt_ad *ad, const struct bt_ad_data *data) return queue_find(ad->data, data_match, data); } +void bt_ad_set_raw_data(struct bt_ad *ad, const uint8_t *data, size_t len) +{ + if (!ad) + return; + + bt_ad_clear_raw_data(ad); + + ad->raw_data = malloc(len); + if (!ad->raw_data) + return; + + memcpy(ad->raw_data, data, len); + ad->raw_data_len = len; +} + +void bt_ad_clear_raw_data(struct bt_ad *ad) +{ + if (!ad) + return; + + free(ad->raw_data); + ad->raw_data = NULL; + ad->raw_data_len = 0; +} + +bool bt_ad_has_raw_data(struct bt_ad *ad) +{ + if (!ad) + return false; + + return (ad->raw_data && ad->raw_data_len > 0); +} + +bool bt_ad_get_raw_data(struct bt_ad *ad, uint8_t **data, size_t *data_len) +{ + if (!ad || !data || !data_len) + return false; + + *data_len = ad->raw_data_len; + *data = ad->raw_data; + + return (ad->raw_data && ad->raw_data_len > 0); +} + void bt_ad_foreach_data(struct bt_ad *ad, bt_ad_func_t func, void *user_data) { if (!ad) diff --git a/src/shared/ad.h b/src/shared/ad.h index 7c5d94db0458..8a7e018e9387 100644 --- a/src/shared/ad.h +++ b/src/shared/ad.h @@ -176,6 +176,14 @@ bool bt_ad_add_data(struct bt_ad *ad, uint8_t type, void *data, size_t len); bool bt_ad_has_data(struct bt_ad *ad, const struct bt_ad_data *data); +void bt_ad_set_raw_data(struct bt_ad *ad, const uint8_t *data, size_t len); + +void bt_ad_clear_raw_data(struct bt_ad *ad); + +bool bt_ad_has_raw_data(struct bt_ad *ad); + +bool bt_ad_get_raw_data(struct bt_ad *ad, uint8_t **data, size_t *data_len); + void bt_ad_foreach_data(struct bt_ad *ad, bt_ad_func_t func, void *user_data); bool bt_ad_remove_data(struct bt_ad *ad, uint8_t type); diff --git a/tools/btpclient.c b/tools/btpclient.c index a140253d92a6..9b990746d811 100644 --- a/tools/btpclient.c +++ b/tools/btpclient.c @@ -2510,12 +2510,18 @@ static void btp_gap_device_found_ev(struct l_dbus_proxy *proxy) { struct btp_device *device = find_device_by_proxy(proxy); struct btp_adapter *adapter = find_adapter_by_device(device); + struct l_dbus_message_iter dict_iter; + struct btp_device_found_ev *p_ev = NULL; struct btp_device_found_ev ev; struct btp_gap_device_connected_ev ev_conn; const char *str, *addr_str; int16_t rssi; uint8_t address_type; bool connected; + const uint8_t *raw_data = NULL; /* Buffer for Raw Advertising Data */ + uint32_t data_len = 0U; /* Length of the raw_data buffer*/ + + ev.eir_len = 0U; if (!l_dbus_proxy_get_property(proxy, "Address", "s", &addr_str) || str2ba(addr_str, &ev.address) < 0) @@ -2538,11 +2544,53 @@ static void btp_gap_device_found_ev(struct l_dbus_proxy *proxy) BTP_EV_GAP_DEVICE_FOUND_FLAG_AD | BTP_EV_GAP_DEVICE_FOUND_FLAG_SR); - /* TODO Add eir to device found event */ - ev.eir_len = 0; + do { + /* dict_iter will contain the item for RawAdvertisingData */ + if (!l_dbus_proxy_get_property(proxy, + "RawAdvertisingData", + "ay", + &dict_iter)) + break; + + /* raw_data contains the Advertising Data, in raw format + * data_len contains the length read in the data buffer + */ + if (!l_dbus_message_iter_get_fixed_array(&dict_iter, + &raw_data, + &data_len)) + break; + + if (data_len <= 0U) + break; + + /* Allocate new buffer, recalculated to sustain new data + * size of previous struct + new length + */ + p_ev = (struct btp_device_found_ev *) + l_malloc(sizeof(*p_ev) + data_len); - btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_DEVICE_FOUND, adapter->index, - sizeof(ev) + ev.eir_len, &ev); + if (!p_ev) + break; + + /* Populate structure that will contain the raw adv data */ + memcpy(p_ev, &ev, sizeof(ev)); + memcpy(p_ev->eir, raw_data, data_len); + + } while (false); + + if (p_ev) { + p_ev->eir_len = data_len; + + btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_DEVICE_FOUND, + adapter->index, sizeof(*p_ev) + data_len, + p_ev); + + l_free(p_ev); + } else { + btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_DEVICE_FOUND, + adapter->index, sizeof(ev) + ev.eir_len, + &ev); + } if (l_dbus_proxy_get_property(proxy, "Connected", "b", &connected) && connected) { -- 2.45.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* RE: tools: Add raw advertising data support to BlueZ 2025-10-10 13:55 ` [PATCH v3 1/1] " Adrian Dudau @ 2025-10-10 15:31 ` bluez.test.bot 2025-10-17 15:53 ` [PATCH v3 1/1] " Luiz Augusto von Dentz 1 sibling, 0 replies; 4+ messages in thread From: bluez.test.bot @ 2025-10-10 15:31 UTC (permalink / raw) To: linux-bluetooth, adrian-constantin.dudau [-- Attachment #1: Type: text/plain, Size: 1262 bytes --] This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1010113 ---Test result--- Test Summary: CheckPatch PENDING 0.38 seconds GitLint PENDING 0.41 seconds BuildEll PASS 20.07 seconds BluezMake PASS 2756.02 seconds MakeCheck PASS 20.23 seconds MakeDistcheck PASS 185.85 seconds CheckValgrind PASS 238.04 seconds CheckSmatch PASS 308.97 seconds bluezmakeextell PASS 129.29 seconds IncrementalBuild PENDING 0.45 seconds ScanBuild PASS 926.02 seconds Details ############################## Test: CheckPatch - PENDING Desc: Run checkpatch.pl script Output: ############################## Test: GitLint - PENDING Desc: Run gitlint Output: ############################## Test: IncrementalBuild - PENDING Desc: Incremental build with the patches in the series Output: --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3 1/1] tools: Add raw advertising data support to BlueZ 2025-10-10 13:55 ` [PATCH v3 1/1] " Adrian Dudau 2025-10-10 15:31 ` bluez.test.bot @ 2025-10-17 15:53 ` Luiz Augusto von Dentz 1 sibling, 0 replies; 4+ messages in thread From: Luiz Augusto von Dentz @ 2025-10-17 15:53 UTC (permalink / raw) To: Adrian Dudau; +Cc: linux-bluetooth, mihai-octavian.urzica, andrei.istodorescu Hi Adrian, On Fri, Oct 10, 2025 at 9:55 AM Adrian Dudau <adrian-constantin.dudau@nxp.com> wrote: > > This patch introduces support for storing and exposing raw advertising > data from Bluetooth Low Energy devices through D-Bus properties and > internal APIs. > > Key changes: > - Add raw_data fields to eir_data and bt_ad structures > - Implement bt_ad_set_raw_data(), bt_ad_clear_raw_data(), > bt_ad_has_raw_data(), and bt_ad_get_raw_data() APIs > - Expose RawAdvertisingData D-Bus property on device objects > - Store raw advertising data during EIR parsing > - Update BTP client to include raw advertising data in device found events Please split these changes, bt_ad, documentation, implementation and then usage on btpclient shall each be a separate commit. > > The RawAdvertisingData property is marked with G_DBUS_PROPERTY_FLAG_TESTING > for debugging and protocol testing purposes. This enables applications to > access complete raw advertising packet contents for custom parsing, > compliance testing, and troubleshooting scenarios. > > The raw data format follows the Extended Inquiry Response Data Format > as described in BLUETOOTH CORE SPECIFICATION Version 6.1 | Vol 3, Part C. > > Signed-off-by: Adrian Dudau <adrian-constantin.dudau@nxp.com> > --- > src/adapter.c | 5 +++++ > src/device.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++ > src/device.h | 2 ++ > src/eir.c | 7 ++++++ > src/eir.h | 3 +++ > src/shared/ad.c | 50 +++++++++++++++++++++++++++++++++++++++++ > src/shared/ad.h | 8 +++++++ > tools/btpclient.c | 56 ++++++++++++++++++++++++++++++++++++++++++---- > 8 files changed, 184 insertions(+), 4 deletions(-) > > diff --git a/src/adapter.c b/src/adapter.c > index 1ee2f3a08164..66d48c90fe8a 100644 > --- a/src/adapter.c > +++ b/src/adapter.c > @@ -7471,6 +7471,11 @@ void btd_adapter_device_found(struct btd_adapter *adapter, > if (eir_data.data_list) > device_set_data(dev, eir_data.data_list, duplicate); > > + if (eir_data.raw_data_len > 0) > + device_set_raw_adv_data(dev, eir_data.raw_data, > + eir_data.raw_data_len, > + duplicate); > + > if (bdaddr_type != BDADDR_BREDR) > device_set_flags(dev, eir_data.flags); > > diff --git a/src/device.c b/src/device.c > index 8d74ae0ea0ff..a244ab1cb796 100644 > --- a/src/device.c > +++ b/src/device.c > @@ -1615,6 +1615,47 @@ dev_property_advertising_data_exist(const GDBusPropertyTable *property, > return bt_ad_has_data(device->ad, NULL); > } > > +static gboolean > +dev_property_get_raw_advertising_data(const GDBusPropertyTable *property, > + DBusMessageIter *iter, void *data) > +{ > + struct btd_device *device = data; > + uint8_t *raw_data = NULL; > + size_t raw_data_len = 0; > + DBusMessageIter array; > + > + if (!device) > + return FALSE; > + > + bt_ad_get_raw_data(device->ad, &raw_data, &raw_data_len); > + > + if (!raw_data || raw_data_len == 0) > + return FALSE; > + > + dbus_message_iter_open_container(iter, > + DBUS_TYPE_ARRAY, > + DBUS_TYPE_BYTE_AS_STRING, > + &array); > + > + dbus_message_iter_append_fixed_array(&array, > + DBUS_TYPE_BYTE, > + &raw_data, > + raw_data_len); > + > + dbus_message_iter_close_container(iter, &array); > + > + return TRUE; > +} > + > +static gboolean > +dev_property_raw_advertising_data_exist(const GDBusPropertyTable *property, > + void *data) > +{ > + struct btd_device *device = data; > + > + return bt_ad_has_raw_data(device->ad); > +} > + > static bool device_get_wake_support(struct btd_device *device) > { > return device->wake_support; > @@ -2401,6 +2442,19 @@ void device_set_manufacturer_data(struct btd_device *dev, GSList *list, > g_slist_foreach(list, add_manufacturer_data, dev); > } > > +void device_set_raw_adv_data(struct btd_device *dev, > + const uint8_t *data, size_t len, > + bool duplicate) > +{ > + if (!dev) > + return; > + > + if (duplicate) > + bt_ad_clear_raw_data(dev->ad); > + > + bt_ad_set_raw_data(dev->ad, data, len); > +} > + > static void add_service_data(void *data, void *user_data) > { > struct eir_sd *sd = data; > @@ -3619,6 +3673,9 @@ static const GDBusPropertyTable device_properties[] = { > dev_property_flags_exist }, > { "AdvertisingData", "a{yv}", dev_property_get_advertising_data, > NULL, dev_property_advertising_data_exist }, > + { "RawAdvertisingData", "ay", dev_property_get_raw_advertising_data, > + NULL, dev_property_raw_advertising_data_exist, > + G_DBUS_PROPERTY_FLAG_TESTING }, > { "WakeAllowed", "b", dev_property_get_wake_allowed, > dev_property_set_wake_allowed, > dev_property_wake_allowed_exist }, > diff --git a/src/device.h b/src/device.h > index 9ff9cdfefc28..84dfa9faaa82 100644 > --- a/src/device.h > +++ b/src/device.h > @@ -81,6 +81,8 @@ void btd_device_add_uuid(struct btd_device *device, const char *uuid); > void device_add_eir_uuids(struct btd_device *dev, GSList *uuids); > void device_set_manufacturer_data(struct btd_device *dev, GSList *list, > bool duplicate); > +void device_set_raw_adv_data(struct btd_device *device, const uint8_t *data, > + size_t len, 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, > diff --git a/src/eir.c b/src/eir.c > index 68ed74fe6493..497e11bd3125 100644 > --- a/src/eir.c > +++ b/src/eir.c > @@ -243,6 +243,13 @@ void eir_parse(struct eir_data *eir, const uint8_t *eir_data, uint8_t eir_len) > if (eir_data == NULL) > return; > > + if (eir_len > 0 && eir_len <= EIR_MAX_LEN) { > + memcpy(eir->raw_data, eir_data, eir_len); > + eir->raw_data_len = eir_len; > + } else { > + eir->raw_data_len = 0; > + } > + > while (len < eir_len - 1) { > uint8_t field_len = eir_data[0]; > const uint8_t *data; > diff --git a/src/eir.h b/src/eir.h > index b9f7c3874eb3..bb7b74527d97 100644 > --- a/src/eir.h > +++ b/src/eir.h > @@ -53,6 +53,7 @@ > > #define EIR_SD_MAX_LEN 238 /* 240 (EIR) - 2 (len) */ > #define EIR_MSD_MAX_LEN 236 /* 240 (EIR) - 2 (len & type) - 2 */ > +#define EIR_MAX_LEN 240 > > struct eir_msd { > uint16_t company; > @@ -91,6 +92,8 @@ struct eir_data { > GSList *msd_list; > GSList *sd_list; > GSList *data_list; > + uint8_t raw_data[EIR_MAX_LEN]; > + size_t raw_data_len; > }; > > void eir_data_free(struct eir_data *eir); > diff --git a/src/shared/ad.c b/src/shared/ad.c > index 9e21cbf61a29..443ba002fc56 100644 > --- a/src/shared/ad.c > +++ b/src/shared/ad.c > @@ -35,6 +35,8 @@ struct bt_ad { > struct queue *solicit_uuids; > struct queue *service_data; > struct queue *data; > + uint8_t *raw_data; > + size_t raw_data_len; > }; > > struct pattern_match_info { > @@ -55,6 +57,8 @@ struct bt_ad *bt_ad_new(void) > ad->service_data = queue_new(); > ad->data = queue_new(); > ad->appearance = UINT16_MAX; > + ad->raw_data = NULL; > + ad->raw_data_len = 0; > > return bt_ad_ref(ad); > } > @@ -199,6 +203,8 @@ void bt_ad_unref(struct bt_ad *ad) > > free(ad->name); > > + free(ad->raw_data); > + > free(ad); > } > > @@ -1252,6 +1258,50 @@ bool bt_ad_has_data(struct bt_ad *ad, const struct bt_ad_data *data) > return queue_find(ad->data, data_match, data); > } > > +void bt_ad_set_raw_data(struct bt_ad *ad, const uint8_t *data, size_t len) > +{ > + if (!ad) > + return; > + > + bt_ad_clear_raw_data(ad); > + > + ad->raw_data = malloc(len); > + if (!ad->raw_data) > + return; > + > + memcpy(ad->raw_data, data, len); > + ad->raw_data_len = len; > +} > + > +void bt_ad_clear_raw_data(struct bt_ad *ad) > +{ > + if (!ad) > + return; > + > + free(ad->raw_data); > + ad->raw_data = NULL; > + ad->raw_data_len = 0; > +} > + > +bool bt_ad_has_raw_data(struct bt_ad *ad) > +{ > + if (!ad) > + return false; > + > + return (ad->raw_data && ad->raw_data_len > 0); > +} > + > +bool bt_ad_get_raw_data(struct bt_ad *ad, uint8_t **data, size_t *data_len) > +{ > + if (!ad || !data || !data_len) > + return false; > + > + *data_len = ad->raw_data_len; > + *data = ad->raw_data; > + > + return (ad->raw_data && ad->raw_data_len > 0); > +} > + > void bt_ad_foreach_data(struct bt_ad *ad, bt_ad_func_t func, void *user_data) > { > if (!ad) > diff --git a/src/shared/ad.h b/src/shared/ad.h > index 7c5d94db0458..8a7e018e9387 100644 > --- a/src/shared/ad.h > +++ b/src/shared/ad.h > @@ -176,6 +176,14 @@ bool bt_ad_add_data(struct bt_ad *ad, uint8_t type, void *data, size_t len); > > bool bt_ad_has_data(struct bt_ad *ad, const struct bt_ad_data *data); > > +void bt_ad_set_raw_data(struct bt_ad *ad, const uint8_t *data, size_t len); > + > +void bt_ad_clear_raw_data(struct bt_ad *ad); > + > +bool bt_ad_has_raw_data(struct bt_ad *ad); > + > +bool bt_ad_get_raw_data(struct bt_ad *ad, uint8_t **data, size_t *data_len); > + > void bt_ad_foreach_data(struct bt_ad *ad, bt_ad_func_t func, void *user_data); > > bool bt_ad_remove_data(struct bt_ad *ad, uint8_t type); > diff --git a/tools/btpclient.c b/tools/btpclient.c > index a140253d92a6..9b990746d811 100644 > --- a/tools/btpclient.c > +++ b/tools/btpclient.c > @@ -2510,12 +2510,18 @@ static void btp_gap_device_found_ev(struct l_dbus_proxy *proxy) > { > struct btp_device *device = find_device_by_proxy(proxy); > struct btp_adapter *adapter = find_adapter_by_device(device); > + struct l_dbus_message_iter dict_iter; > + struct btp_device_found_ev *p_ev = NULL; > struct btp_device_found_ev ev; > struct btp_gap_device_connected_ev ev_conn; > const char *str, *addr_str; > int16_t rssi; > uint8_t address_type; > bool connected; > + const uint8_t *raw_data = NULL; /* Buffer for Raw Advertising Data */ > + uint32_t data_len = 0U; /* Length of the raw_data buffer*/ > + > + ev.eir_len = 0U; > > if (!l_dbus_proxy_get_property(proxy, "Address", "s", &addr_str) || > str2ba(addr_str, &ev.address) < 0) > @@ -2538,11 +2544,53 @@ static void btp_gap_device_found_ev(struct l_dbus_proxy *proxy) > BTP_EV_GAP_DEVICE_FOUND_FLAG_AD | > BTP_EV_GAP_DEVICE_FOUND_FLAG_SR); > > - /* TODO Add eir to device found event */ > - ev.eir_len = 0; > + do { > + /* dict_iter will contain the item for RawAdvertisingData */ > + if (!l_dbus_proxy_get_property(proxy, > + "RawAdvertisingData", > + "ay", > + &dict_iter)) > + break; > + > + /* raw_data contains the Advertising Data, in raw format > + * data_len contains the length read in the data buffer > + */ > + if (!l_dbus_message_iter_get_fixed_array(&dict_iter, > + &raw_data, > + &data_len)) > + break; > + > + if (data_len <= 0U) > + break; > + > + /* Allocate new buffer, recalculated to sustain new data > + * size of previous struct + new length > + */ > + p_ev = (struct btp_device_found_ev *) > + l_malloc(sizeof(*p_ev) + data_len); > > - btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_DEVICE_FOUND, adapter->index, > - sizeof(ev) + ev.eir_len, &ev); > + if (!p_ev) > + break; > + > + /* Populate structure that will contain the raw adv data */ > + memcpy(p_ev, &ev, sizeof(ev)); > + memcpy(p_ev->eir, raw_data, data_len); > + > + } while (false); > + > + if (p_ev) { > + p_ev->eir_len = data_len; > + > + btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_DEVICE_FOUND, > + adapter->index, sizeof(*p_ev) + data_len, > + p_ev); > + > + l_free(p_ev); > + } else { > + btp_send(btp, BTP_GAP_SERVICE, BTP_EV_GAP_DEVICE_FOUND, > + adapter->index, sizeof(ev) + ev.eir_len, > + &ev); > + } > > if (l_dbus_proxy_get_property(proxy, "Connected", "b", &connected) && > connected) { > -- > 2.45.2 > -- Luiz Augusto von Dentz ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-10-17 15:53 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-10-10 13:55 [PATCH v3 0/1] tools: Add raw advertising data support to BlueZ Adrian Dudau 2025-10-10 13:55 ` [PATCH v3 1/1] " Adrian Dudau 2025-10-10 15:31 ` bluez.test.bot 2025-10-17 15:53 ` [PATCH v3 1/1] " Luiz Augusto von Dentz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox