[PATCH v2 2/4] shared/ad: Fix hardcoding maximum data length

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

Instances shall not assume BT_AD_MAX_DATA_LEN is always the maximum
length as they could be used with EA which supports bigger length.
---
 src/shared/ad.c | 56 ++++++++++++++++++++++++++++++-------------------
 src/shared/ad.h |  2 ++
 2 files changed, 36 insertions(+), 22 deletions(-)

diff --git a/src/shared/ad.c b/src/shared/ad.c
index 7350aa206d1e..8b3fde2b1dcd 100644
--- a/src/shared/ad.c
+++ b/src/shared/ad.c
@@ -22,6 +22,7 @@
 
 struct bt_ad {
 	int ref_count;
+	uint8_t max_len;
 	char *name;
 	uint16_t appearance;
 	struct queue *service_uuids;
@@ -42,6 +43,7 @@ struct bt_ad *bt_ad_new(void)
 	struct bt_ad *ad;
 
 	ad = new0(struct bt_ad, 1);
+	ad->max_len = BT_AD_MAX_DATA_LEN;
 	ad->service_uuids = queue_new();
 	ad->manufacturer_data = queue_new();
 	ad->solicit_uuids = queue_new();
@@ -52,6 +54,16 @@ struct bt_ad *bt_ad_new(void)
 	return bt_ad_ref(ad);
 }
 
+bool bt_ad_set_max_len(struct bt_ad *ad, uint8_t len)
+{
+	if (!ad || len < BT_AD_MAX_DATA_LEN)
+		return false;
+
+	ad->max_len = len;
+
+	return true;
+}
+
 static bool ad_replace_data(struct bt_ad *ad, uint8_t type, const void *data,
 							size_t len);
 
@@ -298,17 +310,17 @@ static size_t uuid_data_length(struct queue *uuid_data)
 	return length;
 }
 
-static size_t name_length(const char *name, size_t *pos)
+static size_t name_length(struct bt_ad *ad, size_t *pos)
 {
 	size_t len;
 
-	if (!name)
+	if (!ad->name)
 		return 0;
 
-	len = 2 + strlen(name);
+	len = 2 + strlen(ad->name);
 
-	if (len > BT_AD_MAX_DATA_LEN - *pos)
-		len = BT_AD_MAX_DATA_LEN - *pos;
+	if (len > ad->max_len - (*pos))
+		len = ad->max_len - (*pos);
 
 	return len;
 }
@@ -343,7 +355,7 @@ static size_t calculate_length(struct bt_ad *ad)
 
 	length += uuid_data_length(ad->service_data);
 
-	length += name_length(ad->name, &length);
+	length += name_length(ad, &length);
 
 	length += ad->appearance != UINT16_MAX ? 4 : 0;
 
@@ -467,36 +479,36 @@ static void serialize_service_data(struct queue *service_data, uint8_t *buf,
 	}
 }
 
-static void serialize_name(const char *name, uint8_t *buf, uint8_t *pos)
+static void serialize_name(struct bt_ad *ad, uint8_t *buf, uint8_t *pos)
 {
 	int len;
 	uint8_t type = BT_AD_NAME_COMPLETE;
 
-	if (!name)
+	if (!ad->name)
 		return;
 
-	len = strlen(name);
-	if (len > BT_AD_MAX_DATA_LEN - (*pos + 2)) {
+	len = strlen(ad->name);
+	if (len > ad->max_len - (*pos + 2)) {
 		type = BT_AD_NAME_SHORT;
-		len = BT_AD_MAX_DATA_LEN - (*pos + 2);
+		len = ad->max_len - (*pos + 2);
 	}
 
 	buf[(*pos)++] = len + 1;
 	buf[(*pos)++] = type;
 
-	memcpy(buf + *pos, name, len);
+	memcpy(buf + *pos, ad->name, len);
 	*pos += len;
 }
 
-static void serialize_appearance(uint16_t value, uint8_t *buf, uint8_t *pos)
+static void serialize_appearance(struct bt_ad *ad, uint8_t *buf, uint8_t *pos)
 {
-	if (value == UINT16_MAX)
+	if (ad->appearance == UINT16_MAX)
 		return;
 
-	buf[(*pos)++] = sizeof(value) + 1;
+	buf[(*pos)++] = sizeof(ad->appearance) + 1;
 	buf[(*pos)++] = BT_AD_GAP_APPEARANCE;
 
-	bt_put_le16(value, buf + (*pos));
+	bt_put_le16(ad->appearance, buf + (*pos));
 	*pos += 2;
 }
 
@@ -528,7 +540,7 @@ uint8_t *bt_ad_generate(struct bt_ad *ad, size_t *length)
 
 	*length = calculate_length(ad);
 
-	if (*length > BT_AD_MAX_DATA_LEN)
+	if (*length > ad->max_len)
 		return NULL;
 
 	adv_data = malloc0(*length);
@@ -543,9 +555,9 @@ uint8_t *bt_ad_generate(struct bt_ad *ad, size_t *length)
 
 	serialize_service_data(ad->service_data, adv_data, &pos);
 
-	serialize_name(ad->name, adv_data, &pos);
+	serialize_name(ad, adv_data, &pos);
 
-	serialize_appearance(ad->appearance, adv_data, &pos);
+	serialize_appearance(ad, adv_data, &pos);
 
 	serialize_data(ad->data, adv_data, &pos);
 
@@ -653,7 +665,7 @@ bool bt_ad_add_manufacturer_data(struct bt_ad *ad, uint16_t manufacturer_id,
 	if (!ad)
 		return false;
 
-	if (len > (BT_AD_MAX_DATA_LEN - 2 - sizeof(uint16_t)))
+	if (len > (ad->max_len - 2 - sizeof(uint16_t)))
 		return false;
 
 	new_data = queue_find(ad->manufacturer_data, manufacturer_id_data_match,
@@ -790,7 +802,7 @@ bool bt_ad_add_service_data(struct bt_ad *ad, const bt_uuid_t *uuid, void *data,
 	if (!ad)
 		return false;
 
-	if (len > (BT_AD_MAX_DATA_LEN - 2 - (size_t)bt_uuid_len(uuid)))
+	if (len > (ad->max_len - 2 - (size_t)bt_uuid_len(uuid)))
 		return false;
 
 	new_data = queue_find(ad->service_data, service_uuid_match, uuid);
@@ -1009,7 +1021,7 @@ bool bt_ad_add_data(struct bt_ad *ad, uint8_t type, void *data, size_t len)
 	if (!ad)
 		return false;
 
-	if (len > (BT_AD_MAX_DATA_LEN - 2))
+	if (len > (size_t)(ad->max_len - 2))
 		return false;
 
 	for (i = 0; i < sizeof(type_reject_list); i++) {
diff --git a/src/shared/ad.h b/src/shared/ad.h
index b100a6796109..93ba1b6cfa0b 100644
--- a/src/shared/ad.h
+++ b/src/shared/ad.h
@@ -98,6 +98,8 @@ struct bt_ad_pattern {
 
 struct bt_ad *bt_ad_new(void);
 
+bool bt_ad_set_max_len(struct bt_ad *ad, uint8_t len);
+
 struct bt_ad *bt_ad_new_with_data(size_t len, const uint8_t *data);
 
 struct bt_ad *bt_ad_ref(struct bt_ad *ad);
-- 
2.40.1




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux