public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [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