linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ 1/5] shared/ad: Use util_iov_push_* helpers to generate data
@ 2023-07-12 19:38 Luiz Augusto von Dentz
  2023-07-12 19:38 ` [PATCH BlueZ 2/5] main: Remove DEFAULT_SIRK Luiz Augusto von Dentz
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2023-07-12 19:38 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This makes use of util_iov_push_* helpers to generate the data.
---
 src/shared/ad.c | 163 ++++++++++++++++++++++--------------------------
 1 file changed, 74 insertions(+), 89 deletions(-)

diff --git a/src/shared/ad.c b/src/shared/ad.c
index 8b3fde2b1dcd..e8bebe70708e 100644
--- a/src/shared/ad.c
+++ b/src/shared/ad.c
@@ -365,84 +365,80 @@ static size_t calculate_length(struct bt_ad *ad)
 }
 
 static void serialize_uuids(struct queue *uuids, uint8_t uuid_type,
-						uint8_t ad_type, uint8_t *buf,
-						uint8_t *pos)
+				uint8_t ad_type, struct iovec *iov)
 {
 	const struct queue_entry *entry = queue_get_entries(uuids);
-	bool added = false;
-	uint8_t length_pos = 0;
+	uint8_t *len = NULL;
 
 	while (entry) {
 		bt_uuid_t *uuid = entry->data;
 
 		if (uuid->type == uuid_type) {
-			if (!added) {
-				length_pos = (*pos)++;
-				buf[(*pos)++] = ad_type;
-				added = true;
+			if (!len) {
+				len = iov->iov_base + iov->iov_len;
+				util_iov_push_u8(iov, 1);
+				util_iov_push_u8(iov, ad_type);
 			}
 
-			if (uuid_type != BT_UUID32)
-				bt_uuid_to_le(uuid, buf + *pos);
-			else
-				bt_put_le32(uuid->value.u32, buf + *pos);
-
-			*pos += bt_uuid_len(uuid);
+			switch (uuid->type) {
+			case BT_UUID16:
+				util_iov_push_le16(iov, uuid->value.u16);
+				*len += 2;
+				break;
+			case BT_UUID32:
+				util_iov_push_le32(iov, uuid->value.u32);
+				*len += 4;
+				break;
+			case BT_UUID128:
+				bt_uuid_to_le(uuid, util_iov_push(iov, 16));
+				*len += 16;
+				break;
+			case BT_UUID_UNSPEC:
+				break;
+			}
 		}
 
 		entry = entry->next;
 	}
-
-	if (added)
-		buf[length_pos] = *pos - length_pos - 1;
 }
 
-static void serialize_service_uuids(struct queue *uuids, uint8_t *buf,
-								uint8_t *pos)
+static void serialize_service_uuids(struct queue *uuids, struct iovec *iov)
 {
-	serialize_uuids(uuids, BT_UUID16, BT_AD_UUID16_ALL, buf, pos);
+	serialize_uuids(uuids, BT_UUID16, BT_AD_UUID16_ALL, iov);
 
-	serialize_uuids(uuids, BT_UUID32, BT_AD_UUID32_ALL, buf, pos);
+	serialize_uuids(uuids, BT_UUID32, BT_AD_UUID32_ALL, iov);
 
-	serialize_uuids(uuids, BT_UUID128, BT_AD_UUID128_ALL, buf, pos);
+	serialize_uuids(uuids, BT_UUID128, BT_AD_UUID128_ALL, iov);
 }
 
-static void serialize_solicit_uuids(struct queue *uuids, uint8_t *buf,
-								uint8_t *pos)
+static void serialize_solicit_uuids(struct queue *uuids, struct iovec *iov)
 {
-	serialize_uuids(uuids, BT_UUID16, BT_AD_SOLICIT16, buf, pos);
+	serialize_uuids(uuids, BT_UUID16, BT_AD_SOLICIT16, iov);
 
-	serialize_uuids(uuids, BT_UUID32, BT_AD_SOLICIT32, buf, pos);
+	serialize_uuids(uuids, BT_UUID32, BT_AD_SOLICIT32, iov);
 
-	serialize_uuids(uuids, BT_UUID128, BT_AD_SOLICIT128, buf, pos);
+	serialize_uuids(uuids, BT_UUID128, BT_AD_SOLICIT128, iov);
 }
 
-static void serialize_manuf_data(struct queue *manuf_data, uint8_t *buf,
-								uint8_t *pos)
+static void serialize_manuf_data(struct queue *manuf_data, struct iovec *iov)
 {
 	const struct queue_entry *entry = queue_get_entries(manuf_data);
 
 	while (entry) {
 		struct bt_ad_manufacturer_data *data = entry->data;
 
-		buf[(*pos)++] = data->len + 2 + 1;
+		util_iov_push_u8(iov, data->len + 2 + 1);
+		util_iov_push_u8(iov, BT_AD_MANUFACTURER_DATA);
 
-		buf[(*pos)++] = BT_AD_MANUFACTURER_DATA;
-
-		bt_put_le16(data->manufacturer_id, buf + (*pos));
-
-		*pos += 2;
-
-		memcpy(buf + *pos, data->data, data->len);
-
-		*pos += data->len;
+		util_iov_push_le16(iov, data->manufacturer_id);
+		util_iov_push_mem(iov, data->len, data->data);
 
 		entry = entry->next;
 	}
 }
 
-static void serialize_service_data(struct queue *service_data, uint8_t *buf,
-								uint8_t *pos)
+static void serialize_service_data(struct queue *service_data,
+					struct iovec *iov)
 {
 	const struct queue_entry *entry = queue_get_entries(service_data);
 
@@ -450,81 +446,69 @@ static void serialize_service_data(struct queue *service_data, uint8_t *buf,
 		struct bt_ad_service_data *data = entry->data;
 		int uuid_len = bt_uuid_len(&data->uuid);
 
-		buf[(*pos)++] =  uuid_len + data->len + 1;
+		util_iov_push_u8(iov, data->len + uuid_len + 1);
 
 		switch (uuid_len) {
 		case 2:
-			buf[(*pos)++] = BT_AD_SERVICE_DATA16;
+			util_iov_push_u8(iov, BT_AD_SERVICE_DATA16);
+			util_iov_push_le16(iov, data->uuid.value.u16);
 			break;
 		case 4:
-			buf[(*pos)++] = BT_AD_SERVICE_DATA32;
+			util_iov_push_u8(iov, BT_AD_SERVICE_DATA32);
+			util_iov_push_le32(iov, data->uuid.value.u32);
 			break;
 		case 16:
-			buf[(*pos)++] = BT_AD_SERVICE_DATA128;
+			util_iov_push_u8(iov, BT_AD_SERVICE_DATA128);
+			bt_uuid_to_le(&data->uuid,
+					util_iov_push(iov, uuid_len));
 			break;
 		}
 
-		if (uuid_len != 4)
-			bt_uuid_to_le(&data->uuid, buf + *pos);
-		else
-			bt_put_le32(data->uuid.value.u32, buf + *pos);
-
-		*pos += uuid_len;
-
-		memcpy(buf + *pos, data->data, data->len);
-
-		*pos += data->len;
+		util_iov_push_mem(iov, data->len, data->data);
 
 		entry = entry->next;
 	}
 }
 
-static void serialize_name(struct bt_ad *ad, uint8_t *buf, uint8_t *pos)
+static void serialize_name(struct bt_ad *ad, struct iovec *iov)
 {
-	int len;
+	size_t len;
 	uint8_t type = BT_AD_NAME_COMPLETE;
 
 	if (!ad->name)
 		return;
 
 	len = strlen(ad->name);
-	if (len > ad->max_len - (*pos + 2)) {
+	if (len > ad->max_len - (iov->iov_len + 2)) {
 		type = BT_AD_NAME_SHORT;
-		len = ad->max_len - (*pos + 2);
+		len = ad->max_len - (iov->iov_len + 2);
 	}
 
-	buf[(*pos)++] = len + 1;
-	buf[(*pos)++] = type;
-
-	memcpy(buf + *pos, ad->name, len);
-	*pos += len;
+	util_iov_push_u8(iov, len + 1);
+	util_iov_push_u8(iov, type);
+	util_iov_push_mem(iov, len, ad->name);
 }
 
-static void serialize_appearance(struct bt_ad *ad, uint8_t *buf, uint8_t *pos)
+static void serialize_appearance(struct bt_ad *ad, struct iovec *iov)
 {
 	if (ad->appearance == UINT16_MAX)
 		return;
 
-	buf[(*pos)++] = sizeof(ad->appearance) + 1;
-	buf[(*pos)++] = BT_AD_GAP_APPEARANCE;
-
-	bt_put_le16(ad->appearance, buf + (*pos));
-	*pos += 2;
+	util_iov_push_u8(iov, sizeof(ad->appearance) + 1);
+	util_iov_push_u8(iov, BT_AD_GAP_APPEARANCE);
+	util_iov_push_le16(iov, ad->appearance);
 }
 
-static void serialize_data(struct queue *queue, uint8_t *buf, uint8_t *pos)
+static void serialize_data(struct queue *queue, struct iovec *iov)
 {
 	const struct queue_entry *entry = queue_get_entries(queue);
 
 	while (entry) {
 		struct bt_ad_data *data = entry->data;
 
-		buf[(*pos)++] = data->len + 1;
-		buf[(*pos)++] = data->type;
-
-		memcpy(buf + *pos, data->data, data->len);
-
-		*pos += data->len;
+		util_iov_push_u8(iov, data->len + 1);
+		util_iov_push_u8(iov, data->type);
+		util_iov_push_mem(iov, data->len, data->data);
 
 		entry = entry->next;
 	}
@@ -532,8 +516,7 @@ static void serialize_data(struct queue *queue, uint8_t *buf, uint8_t *pos)
 
 uint8_t *bt_ad_generate(struct bt_ad *ad, size_t *length)
 {
-	uint8_t *adv_data;
-	uint8_t pos = 0;
+	struct iovec iov;
 
 	if (!ad)
 		return NULL;
@@ -543,25 +526,27 @@ uint8_t *bt_ad_generate(struct bt_ad *ad, size_t *length)
 	if (*length > ad->max_len)
 		return NULL;
 
-	adv_data = malloc0(*length);
-	if (!adv_data)
+	iov.iov_base = malloc0(*length);
+	if (!iov.iov_base)
 		return NULL;
 
-	serialize_service_uuids(ad->service_uuids, adv_data, &pos);
+	iov.iov_len = 0;
 
-	serialize_solicit_uuids(ad->solicit_uuids, adv_data, &pos);
+	serialize_service_uuids(ad->service_uuids, &iov);
 
-	serialize_manuf_data(ad->manufacturer_data, adv_data, &pos);
+	serialize_solicit_uuids(ad->solicit_uuids, &iov);
 
-	serialize_service_data(ad->service_data, adv_data, &pos);
+	serialize_manuf_data(ad->manufacturer_data, &iov);
 
-	serialize_name(ad, adv_data, &pos);
+	serialize_service_data(ad->service_data, &iov);
 
-	serialize_appearance(ad, adv_data, &pos);
+	serialize_name(ad, &iov);
 
-	serialize_data(ad->data, adv_data, &pos);
+	serialize_appearance(ad, &iov);
 
-	return adv_data;
+	serialize_data(ad->data, &iov);
+
+	return iov.iov_base;
 }
 
 bool bt_ad_is_empty(struct bt_ad *ad)
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ 2/5] main: Remove DEFAULT_SIRK
  2023-07-12 19:38 [PATCH BlueZ 1/5] shared/ad: Use util_iov_push_* helpers to generate data Luiz Augusto von Dentz
@ 2023-07-12 19:38 ` Luiz Augusto von Dentz
  2023-07-12 19:38 ` [PATCH BlueZ 3/5] shared/util: Introduce strisutf8 Luiz Augusto von Dentz
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2023-07-12 19:38 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

DEFAULT_SIRK is currently not used.
---
 src/main.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/src/main.c b/src/main.c
index 8dfd2543ba1c..150a5af4cca4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -61,9 +61,6 @@
 #define DEFAULT_TEMPORARY_TIMEOUT         30 /* 30 seconds */
 #define DEFAULT_NAME_REQUEST_RETRY_DELAY 300 /* 5 minutes */
 
-/*CSIP Profile - Server */
-#define DEFAULT_SIRK "761FAE703ED681F0C50B34155B6434FB"
-
 #define SHUTDOWN_GRACE_SECONDS 10
 
 struct btd_opts btd_opts;
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ 3/5] shared/util: Introduce strisutf8
  2023-07-12 19:38 [PATCH BlueZ 1/5] shared/ad: Use util_iov_push_* helpers to generate data Luiz Augusto von Dentz
  2023-07-12 19:38 ` [PATCH BlueZ 2/5] main: Remove DEFAULT_SIRK Luiz Augusto von Dentz
@ 2023-07-12 19:38 ` Luiz Augusto von Dentz
  2023-07-12 19:38 ` [PATCH BlueZ 4/5] shared/ad: Make use of util_iov_pull_* to parse data Luiz Augusto von Dentz
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2023-07-12 19:38 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This introduces strisutf8 which can be used to verify if a string is
encoded using UTF-8 format.
---
 src/shared/util.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++
 src/shared/util.h |  3 +++
 2 files changed, 65 insertions(+)

diff --git a/src/shared/util.c b/src/shared/util.c
index 4d1c0d00545d..e9c1c18f5ea7 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -1705,3 +1705,65 @@ int strsuffix(const char *str, const char *suffix)
 
 	return strncmp(str + len - suffix_len, suffix, suffix_len);
 }
+
+char *strstrip(char *str)
+{
+	size_t size;
+	char *end;
+
+	if (!str)
+		return NULL;
+
+	size = strlen(str);
+	if (!size)
+		return str;
+
+	end = str + size - 1;
+	while (end >= str && isspace(*end))
+		end--;
+	*(end + 1) = '\0';
+
+	while (*str && isspace(*str))
+		str++;
+
+	return str;
+}
+
+bool strisutf8(const char *str, size_t len)
+{
+	size_t i = 0;
+
+	while (i < len) {
+		unsigned char c = str[i];
+		size_t size = 0;
+
+		/* Check the first byte to determine the number of bytes in the
+		 * UTF-8 character.
+		 */
+		if ((c & 0x80) == 0x00)
+			size = 1;
+		else if ((c & 0xE0) == 0xC0)
+			size = 2;
+		else if ((c & 0xF0) == 0xE0)
+			size = 3;
+		else if ((c & 0xF8) == 0xF0)
+			size = 4;
+		else
+			/* Invalid UTF-8 sequence */
+			return false;
+
+		/* Check the following bytes to ensure they have the correct
+		 * format.
+		 */
+		for (size_t j = 1; j < size; ++j) {
+			if (i + j > len || (str[i + j] & 0xC0) != 0x80)
+				/* Invalid UTF-8 sequence */
+				return false;
+		}
+
+		/* Move to the next character */
+		i += size;
+	}
+
+	return true;
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index ce57b53be9ef..c37b0f7296ab 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -12,6 +12,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <alloca.h>
 #include <byteswap.h>
 #include <string.h>
@@ -88,6 +89,8 @@ do {						\
 
 char *strdelimit(char *str, char *del, char c);
 int strsuffix(const char *str, const char *suffix);
+char *strstrip(char *str);
+bool strisutf8(const char *str, size_t length);
 
 void *util_malloc(size_t size);
 void *util_memdup(const void *src, size_t size);
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ 4/5] shared/ad: Make use of util_iov_pull_* to parse data
  2023-07-12 19:38 [PATCH BlueZ 1/5] shared/ad: Use util_iov_push_* helpers to generate data Luiz Augusto von Dentz
  2023-07-12 19:38 ` [PATCH BlueZ 2/5] main: Remove DEFAULT_SIRK Luiz Augusto von Dentz
  2023-07-12 19:38 ` [PATCH BlueZ 3/5] shared/util: Introduce strisutf8 Luiz Augusto von Dentz
@ 2023-07-12 19:38 ` Luiz Augusto von Dentz
  2023-07-12 19:38 ` [PATCH BlueZ 5/5] test-eir: Run tests using bt_ad Luiz Augusto von Dentz
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2023-07-12 19:38 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This makes use of util_iov_pull_* helpers to parse data.
---
 src/shared/ad.c | 266 ++++++++++++++++++++++++++++++++++++++++++++----
 src/shared/ad.h |  10 +-
 2 files changed, 253 insertions(+), 23 deletions(-)

diff --git a/src/shared/ad.c b/src/shared/ad.c
index e8bebe70708e..951c56c604e6 100644
--- a/src/shared/ad.c
+++ b/src/shared/ad.c
@@ -14,6 +14,11 @@
 
 #define _GNU_SOURCE
 
+#include <ctype.h>
+
+#include "lib/bluetooth.h"
+#include "lib/hci.h"
+
 #include "src/shared/ad.h"
 
 #include "src/eir.h"
@@ -80,7 +85,11 @@ static bool ad_is_type_valid(uint8_t type)
 struct bt_ad *bt_ad_new_with_data(size_t len, const uint8_t *data)
 {
 	struct bt_ad *ad;
-	uint16_t parsed_len = 0;
+	struct iovec iov = {
+		.iov_base = (void *)data,
+		.iov_len = len,
+	};
+	uint8_t elen;
 
 	if (data == NULL || !len)
 		return NULL;
@@ -89,31 +98,29 @@ struct bt_ad *bt_ad_new_with_data(size_t len, const uint8_t *data)
 	if (!ad)
 		return NULL;
 
-	while (parsed_len < len - 1) {
-		uint8_t d_len;
-		uint8_t d_type;
-		const uint8_t *d;
-		uint8_t field_len = data[0];
+	bt_ad_set_max_len(ad, len);
 
-		if (field_len == 0)
+	while (util_iov_pull_u8(&iov, &elen)) {
+		uint8_t type;
+		void *data;
+
+		if (elen == 0 || elen > iov.iov_len)
 			break;
 
-		parsed_len += field_len + 1;
-
-		if (parsed_len > len)
-			break;
-
-		d = &data[2];
-		d_type = data[1];
-		d_len = field_len - 1;
-
-		if (!ad_is_type_valid(d_type))
+		if (!util_iov_pull_u8(&iov, &type))
 			goto failed;
 
-		if (!ad_replace_data(ad, d_type, d, d_len))
+		elen--;
+
+		if (!ad_is_type_valid(type))
 			goto failed;
 
-		data += field_len + 1;
+		data = util_iov_pull_mem(&iov, elen);
+		if (!data)
+			goto failed;
+
+		if (!ad_replace_data(ad, type, data, elen))
+			goto failed;
 	}
 
 	return ad;
@@ -203,10 +210,181 @@ static bool data_type_match(const void *data, const void *user_data)
 	return a->type == type;
 }
 
+static bool ad_replace_uuid16(struct bt_ad *ad, struct iovec *iov)
+{
+	uint16_t value;
+
+	while ((util_iov_pull_le16(iov, &value))) {
+		bt_uuid_t uuid;
+
+		if (bt_uuid16_create(&uuid, value))
+			return false;
+
+		if (bt_ad_has_service_uuid(ad, &uuid))
+			continue;
+
+		if (!bt_ad_add_service_uuid(ad, &uuid))
+			return false;
+	}
+
+	return true;
+}
+
+static bool ad_replace_uuid32(struct bt_ad *ad, struct iovec *iov)
+{
+	uint32_t value;
+
+	while ((util_iov_pull_le32(iov, &value))) {
+		bt_uuid_t uuid;
+
+		if (bt_uuid32_create(&uuid, value))
+			return false;
+
+		if (bt_ad_has_service_uuid(ad, &uuid))
+			continue;
+
+		if (!bt_ad_add_service_uuid(ad, &uuid))
+			return false;
+	}
+
+	return true;
+}
+
+static bool ad_replace_uuid128(struct bt_ad *ad, struct iovec *iov)
+{
+	void *data;
+
+	while ((data = util_iov_pull_mem(iov, 16))) {
+		uint128_t value;
+		bt_uuid_t uuid;
+
+		bswap_128(data, &value);
+
+		if (bt_uuid128_create(&uuid, value))
+			return false;
+
+		if (bt_ad_has_service_uuid(ad, &uuid))
+			continue;
+
+		if (!bt_ad_add_service_uuid(ad, &uuid))
+			return false;
+	}
+
+	return true;
+}
+
+static bool ad_replace_name(struct bt_ad *ad, struct iovec *iov)
+{
+	char utf8_name[HCI_MAX_NAME_LENGTH + 2];
+	int i;
+
+	memset(utf8_name, 0, sizeof(utf8_name));
+	strncpy(utf8_name, (const char *)iov->iov_base, iov->iov_len);
+
+	if (strisutf8(utf8_name, iov->iov_len))
+		goto done;
+
+	/* Assume ASCII, and replace all non-ASCII with spaces */
+	for (i = 0; utf8_name[i] != '\0'; i++) {
+		if (!isascii(utf8_name[i]))
+			utf8_name[i] = ' ';
+	}
+
+	/* Remove leading and trailing whitespace characters */
+	strstrip(utf8_name);
+
+done:
+	return bt_ad_add_name(ad, utf8_name);
+}
+
+static bool ad_replace_uuid16_data(struct bt_ad *ad, struct iovec *iov)
+{
+	uint16_t value;
+	bt_uuid_t uuid;
+
+	if (!util_iov_pull_le16(iov, &value))
+		return false;
+
+	if (bt_uuid16_create(&uuid, value))
+		return false;
+
+	return bt_ad_add_service_data(ad, &uuid, iov->iov_base, iov->iov_len);
+}
+
+static bool ad_replace_uuid32_data(struct bt_ad *ad, struct iovec *iov)
+{
+	uint32_t value;
+	bt_uuid_t uuid;
+
+	if (!util_iov_pull_le32(iov, &value))
+		return false;
+
+	if (bt_uuid32_create(&uuid, value))
+		return false;
+
+	return bt_ad_add_service_data(ad, &uuid, iov->iov_base, iov->iov_len);
+}
+
+static bool ad_replace_uuid128_data(struct bt_ad *ad, struct iovec *iov)
+{
+	void *data;
+	uint128_t value;
+	bt_uuid_t uuid;
+
+	data = util_iov_pull_mem(iov, 16);
+	if (!data)
+		return false;
+
+	bswap_128(data, &value);
+
+	if (bt_uuid128_create(&uuid, value))
+		return false;
+
+	return bt_ad_add_service_data(ad, &uuid, iov->iov_base, iov->iov_len);
+}
+
+static bool ad_replace_manufacturer_data(struct bt_ad *ad, struct iovec *iov)
+{
+	uint16_t value;
+
+	if (!util_iov_pull_le16(iov, &value))
+		return false;
+
+	return bt_ad_add_manufacturer_data(ad, value, iov->iov_base,
+							iov->iov_len);
+}
+
 static bool ad_replace_data(struct bt_ad *ad, uint8_t type, const void *data,
 							size_t len)
 {
 	struct bt_ad_data *new_data;
+	struct iovec iov = {
+		.iov_base = (void *)data,
+		.iov_len = len,
+	};
+
+	switch (type) {
+	case BT_AD_UUID16_SOME:
+	case BT_AD_UUID16_ALL:
+		return ad_replace_uuid16(ad, &iov);
+	case BT_AD_UUID32_SOME:
+	case BT_AD_UUID32_ALL:
+		return ad_replace_uuid32(ad, &iov);
+	case BT_AD_UUID128_SOME:
+	case BT_AD_UUID128_ALL:
+		return ad_replace_uuid128(ad, &iov);
+	case BT_AD_NAME_SHORT:
+	case BT_AD_NAME_COMPLETE:
+		return ad_replace_name(ad, &iov);
+	case BT_AD_SERVICE_DATA16:
+		return ad_replace_uuid16_data(ad, &iov);
+	case BT_AD_SERVICE_DATA32:
+		return ad_replace_uuid32_data(ad, &iov);
+	case BT_AD_SERVICE_DATA128:
+		return ad_replace_uuid128_data(ad, &iov);
+	case BT_AD_MANUFACTURER_DATA:
+		return ad_replace_manufacturer_data(ad, &iov);
+	}
 
 	new_data = queue_find(ad->data, data_type_match, UINT_TO_PTR(type));
 	if (new_data) {
@@ -220,13 +398,12 @@ static bool ad_replace_data(struct bt_ad *ad, uint8_t type, const void *data,
 
 	new_data = new0(struct bt_ad_data, 1);
 	new_data->type = type;
-	new_data->data = malloc(len);
+	new_data->data = util_memdup(data, len);
 	if (!new_data->data) {
 		free(new_data);
 		return false;
 	}
 
-	memcpy(new_data->data, data, len);
 	new_data->len = len;
 
 	if (queue_push_tail(ad->data, new_data))
@@ -590,7 +767,7 @@ static bool uuid_match(const void *data, const void *elem)
 	const bt_uuid_t *match_uuid = data;
 	const bt_uuid_t *uuid = elem;
 
-	return bt_uuid_cmp(match_uuid, uuid);
+	return !bt_uuid_cmp(match_uuid, uuid);
 }
 
 static bool queue_remove_uuid(struct queue *queue, bt_uuid_t *uuid)
@@ -618,6 +795,14 @@ bool bt_ad_add_service_uuid(struct bt_ad *ad, const bt_uuid_t *uuid)
 	return queue_add_uuid(ad->service_uuids, uuid);
 }
 
+bool bt_ad_has_service_uuid(struct bt_ad *ad, const bt_uuid_t *uuid)
+{
+	if (!ad)
+		return false;
+
+	return queue_find(ad->service_uuids, uuid_match, uuid);
+}
+
 bool bt_ad_remove_service_uuid(struct bt_ad *ad, bt_uuid_t *uuid)
 {
 	if (!ad)
@@ -894,6 +1079,14 @@ bool bt_ad_add_name(struct bt_ad *ad, const char *name)
 	return true;
 }
 
+const char *bt_ad_get_name(struct bt_ad *ad)
+{
+	if (!ad)
+		return false;
+
+	return ad->name;
+}
+
 void bt_ad_clear_name(struct bt_ad *ad)
 {
 	if (!ad)
@@ -933,6 +1126,20 @@ bool bt_ad_add_flags(struct bt_ad *ad, uint8_t *flags, size_t len)
 	return ad_replace_data(ad, BT_AD_FLAGS, flags, len);
 }
 
+uint8_t bt_ad_get_flags(struct bt_ad *ad)
+{
+	struct bt_ad_data *data;
+
+	if (!ad)
+		return 0;
+
+	data = queue_find(ad->data, data_type_match, UINT_TO_PTR(BT_AD_FLAGS));
+	if (!data || data->len != 1)
+		return 0;
+
+	return data->data[0];
+}
+
 bool bt_ad_has_flags(struct bt_ad *ad)
 {
 	struct bt_ad_data *data;
@@ -1077,6 +1284,21 @@ void bt_ad_clear_data(struct bt_ad *ad)
 	queue_remove_all(ad->data, NULL, NULL, data_destroy);
 }
 
+int8_t bt_ad_get_tx_power(struct bt_ad *ad)
+{
+	struct bt_ad_data *data;
+
+	if (!ad)
+		return 0;
+
+	data = queue_find(ad->data, data_type_match,
+					UINT_TO_PTR(BT_AD_TX_POWER));
+	if (!data || data->len != 1)
+		return 127;
+
+	return data->data[0];
+}
+
 struct bt_ad_pattern *bt_ad_pattern_new(uint8_t type, size_t offset, size_t len,
 							const uint8_t *data)
 {
diff --git a/src/shared/ad.h b/src/shared/ad.h
index 93ba1b6cfa0b..87b3401a389d 100644
--- a/src/shared/ad.h
+++ b/src/shared/ad.h
@@ -112,11 +112,13 @@ bool bt_ad_is_empty(struct bt_ad *ad);
 
 bool bt_ad_add_service_uuid(struct bt_ad *ad, const bt_uuid_t *uuid);
 
+bool bt_ad_has_service_uuid(struct bt_ad *ad, const bt_uuid_t *uuid);
+
 bool bt_ad_remove_service_uuid(struct bt_ad *ad, bt_uuid_t *uuid);
 
 void bt_ad_clear_service_uuid(struct bt_ad *ad);
 
-bool bt_ad_add_manufacturer_data(struct bt_ad *ad, uint16_t manufacturer_data,
+bool bt_ad_add_manufacturer_data(struct bt_ad *ad, uint16_t id,
 						void *data, size_t len);
 
 bool bt_ad_has_manufacturer_data(struct bt_ad *ad,
@@ -150,6 +152,8 @@ void bt_ad_clear_service_data(struct bt_ad *ad);
 
 bool bt_ad_add_name(struct bt_ad *ad, const char *name);
 
+const char *bt_ad_get_name(struct bt_ad *ad);
+
 void bt_ad_clear_name(struct bt_ad *ad);
 
 bool bt_ad_add_appearance(struct bt_ad *ad, uint16_t appearance);
@@ -160,6 +164,8 @@ bool bt_ad_add_flags(struct bt_ad *ad, uint8_t *flags, size_t len);
 
 bool bt_ad_has_flags(struct bt_ad *ad);
 
+uint8_t bt_ad_get_flags(struct bt_ad *ad);
+
 void bt_ad_clear_flags(struct bt_ad *ad);
 
 bool bt_ad_add_data(struct bt_ad *ad, uint8_t type, void *data, size_t len);
@@ -172,6 +178,8 @@ bool bt_ad_remove_data(struct bt_ad *ad, uint8_t type);
 
 void bt_ad_clear_data(struct bt_ad *ad);
 
+int8_t bt_ad_get_tx_power(struct bt_ad *ad);
+
 struct bt_ad_pattern *bt_ad_pattern_new(uint8_t type, size_t offset,
 					size_t len, const uint8_t *data);
 
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH BlueZ 5/5] test-eir: Run tests using bt_ad
  2023-07-12 19:38 [PATCH BlueZ 1/5] shared/ad: Use util_iov_push_* helpers to generate data Luiz Augusto von Dentz
                   ` (2 preceding siblings ...)
  2023-07-12 19:38 ` [PATCH BlueZ 4/5] shared/ad: Make use of util_iov_pull_* to parse data Luiz Augusto von Dentz
@ 2023-07-12 19:38 ` Luiz Augusto von Dentz
  2023-07-12 22:41 ` [BlueZ,1/5] shared/ad: Use util_iov_push_* helpers to generate data bluez.test.bot
  2023-07-12 22:50 ` [PATCH BlueZ 1/5] " patchwork-bot+bluetooth
  5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2023-07-12 19:38 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This enables the same tests done with eir_data using bt_ad.
---
 unit/test-eir.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/unit/test-eir.c b/unit/test-eir.c
index e05a37d01306..49ce65f24bc9 100644
--- a/unit/test-eir.c
+++ b/unit/test-eir.c
@@ -21,6 +21,7 @@
 #include "lib/sdp.h"
 #include "src/shared/tester.h"
 #include "src/shared/util.h"
+#include "src/shared/ad.h"
 #include "src/eir.h"
 
 struct test_data {
@@ -539,6 +540,54 @@ static void print_debug(const char *str, void *user_data)
 	tester_debug("%s%s", prefix, str);
 }
 
+static void test_ad(const struct test_data *test, struct eir_data *eir)
+{
+	struct bt_ad *ad;
+	GSList *list;
+
+	ad = bt_ad_new_with_data(test->eir_size, test->eir_data);
+	g_assert(ad);
+
+	g_assert_cmpint(bt_ad_get_flags(ad), ==, test->flags);
+	g_assert_cmpstr(bt_ad_get_name(ad), ==, test->name);
+	g_assert_cmpint(bt_ad_get_tx_power(ad), ==, test->tx_power);
+
+	if (test->uuid) {
+		int i;
+
+		for (i = 0; test->uuid[i]; i++) {
+			bt_uuid_t uuid;
+
+			bt_string_to_uuid(&uuid, test->uuid[i]);
+			g_assert(bt_ad_has_service_uuid(ad, &uuid));
+		}
+	}
+
+	for (list = eir->msd_list; list; list = list->next) {
+		struct eir_msd *msd = list->data;
+		struct bt_ad_manufacturer_data adm;
+
+		adm.manufacturer_id = msd->company;
+		adm.data = msd->data;
+		adm.len = msd->data_len;
+
+		g_assert(bt_ad_has_manufacturer_data(ad, &adm));
+	}
+
+	for (list = eir->sd_list; list; list = list->next) {
+		struct eir_sd *sd = list->data;
+		struct bt_ad_service_data ads;
+
+		bt_string_to_uuid(&ads.uuid, sd->uuid);
+		ads.data = sd->data;
+		ads.len = sd->data_len;
+
+		g_assert(bt_ad_has_service_data(ad, &ads));
+	}
+
+	bt_ad_unref(ad);
+}
+
 static void test_parsing(gconstpointer data)
 {
 	const struct test_data *test = data;
@@ -599,6 +648,8 @@ static void test_parsing(gconstpointer data)
 							"Service Data:");
 	}
 
+	test_ad(data, &eir);
+
 	eir_data_free(&eir);
 
 	tester_test_passed();
-- 
2.40.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* RE: [BlueZ,1/5] shared/ad: Use util_iov_push_* helpers to generate data
  2023-07-12 19:38 [PATCH BlueZ 1/5] shared/ad: Use util_iov_push_* helpers to generate data Luiz Augusto von Dentz
                   ` (3 preceding siblings ...)
  2023-07-12 19:38 ` [PATCH BlueZ 5/5] test-eir: Run tests using bt_ad Luiz Augusto von Dentz
@ 2023-07-12 22:41 ` bluez.test.bot
  2023-07-12 22:50 ` [PATCH BlueZ 1/5] " patchwork-bot+bluetooth
  5 siblings, 0 replies; 7+ messages in thread
From: bluez.test.bot @ 2023-07-12 22:41 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz

[-- Attachment #1: Type: text/plain, Size: 2178 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=765012

---Test result---

Test Summary:
CheckPatch                    PASS      2.76 seconds
GitLint                       PASS      1.54 seconds
BuildEll                      PASS      33.65 seconds
BluezMake                     PASS      1194.55 seconds
MakeCheck                     PASS      13.10 seconds
MakeDistcheck                 PASS      191.75 seconds
CheckValgrind                 PASS      314.67 seconds
CheckSmatch                   PASS      435.57 seconds
bluezmakeextell               PASS      130.95 seconds
IncrementalBuild              PASS      4989.68 seconds
ScanBuild                     WARNING   1400.37 seconds

Details
##############################
Test: ScanBuild - WARNING
Desc: Run Scan Build
Output:
In file included from tools/mesh-gatt/crypto.c:32:
./src/shared/util.h:191:9: warning: 1st function call argument is an uninitialized value
        return be32_to_cpu(get_unaligned((const uint32_t *) ptr));
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/shared/util.h:33:26: note: expanded from macro 'be32_to_cpu'
#define be32_to_cpu(val) bswap_32(val)
                         ^~~~~~~~~~~~~
/usr/include/byteswap.h:34:21: note: expanded from macro 'bswap_32'
#define bswap_32(x) __bswap_32 (x)
                    ^~~~~~~~~~~~~~
In file included from tools/mesh-gatt/crypto.c:32:
./src/shared/util.h:201:9: warning: 1st function call argument is an uninitialized value
        return be64_to_cpu(get_unaligned((const uint64_t *) ptr));
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./src/shared/util.h:34:26: note: expanded from macro 'be64_to_cpu'
#define be64_to_cpu(val) bswap_64(val)
                         ^~~~~~~~~~~~~
/usr/include/byteswap.h:37:21: note: expanded from macro 'bswap_64'
#define bswap_64(x) __bswap_64 (x)
                    ^~~~~~~~~~~~~~
2 warnings generated.



---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH BlueZ 1/5] shared/ad: Use util_iov_push_* helpers to generate data
  2023-07-12 19:38 [PATCH BlueZ 1/5] shared/ad: Use util_iov_push_* helpers to generate data Luiz Augusto von Dentz
                   ` (4 preceding siblings ...)
  2023-07-12 22:41 ` [BlueZ,1/5] shared/ad: Use util_iov_push_* helpers to generate data bluez.test.bot
@ 2023-07-12 22:50 ` patchwork-bot+bluetooth
  5 siblings, 0 replies; 7+ messages in thread
From: patchwork-bot+bluetooth @ 2023-07-12 22:50 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hello:

This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Wed, 12 Jul 2023 12:38:50 -0700 you wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> This makes use of util_iov_push_* helpers to generate the data.
> ---
>  src/shared/ad.c | 163 ++++++++++++++++++++++--------------------------
>  1 file changed, 74 insertions(+), 89 deletions(-)

Here is the summary with links:
  - [BlueZ,1/5] shared/ad: Use util_iov_push_* helpers to generate data
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=c48468328f28
  - [BlueZ,2/5] main: Remove DEFAULT_SIRK
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=9b0087bc3d25
  - [BlueZ,3/5] shared/util: Introduce strisutf8
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=d1b33eb8bf0f
  - [BlueZ,4/5] shared/ad: Make use of util_iov_pull_* to parse data
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=bc2ab4ba3c61
  - [BlueZ,5/5] test-eir: Run tests using bt_ad
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=b8f916b7ee6e

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2023-07-12 22:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-12 19:38 [PATCH BlueZ 1/5] shared/ad: Use util_iov_push_* helpers to generate data Luiz Augusto von Dentz
2023-07-12 19:38 ` [PATCH BlueZ 2/5] main: Remove DEFAULT_SIRK Luiz Augusto von Dentz
2023-07-12 19:38 ` [PATCH BlueZ 3/5] shared/util: Introduce strisutf8 Luiz Augusto von Dentz
2023-07-12 19:38 ` [PATCH BlueZ 4/5] shared/ad: Make use of util_iov_pull_* to parse data Luiz Augusto von Dentz
2023-07-12 19:38 ` [PATCH BlueZ 5/5] test-eir: Run tests using bt_ad Luiz Augusto von Dentz
2023-07-12 22:41 ` [BlueZ,1/5] shared/ad: Use util_iov_push_* helpers to generate data bluez.test.bot
2023-07-12 22:50 ` [PATCH BlueZ 1/5] " patchwork-bot+bluetooth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).