@@ -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)
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(-)