Re: [BlueZ 06/12] core: add advertising-data

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

 



Hi Michael,

> On Thu, Mar 12, 2015 at 10:11 AM, Michael Janssen <jamuraa@xxxxxxxxxxxx> wrote:
> The advetising_data structure provides an abstraction for easy
> translation of defined Advertisement Data fields into the resulting
> raw bytes needed by the Bluetooth HCI LE Set Advertising Data command.

The subject should say "shared:" rather than "core:", since the latter
has been used for the desktop daemon's core sources only (e.g.
adapter, device, etc).

I'll let the others comment on this, I don't have any objections as
this seems like a useful container structure for AD.

> ---
>  Makefile.am                   |   2 +
>  src/shared/advertising-data.c | 350 ++++++++++++++++++++++++++++++++++++++++++
>  src/shared/advertising-data.h |  69 +++++++++
>  3 files changed, 421 insertions(+)
>  create mode 100644 src/shared/advertising-data.c
>  create mode 100644 src/shared/advertising-data.h
>
> diff --git a/Makefile.am b/Makefile.am
> index 38f9420..bab1502 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -111,6 +111,8 @@ shared_sources = src/shared/io.h src/shared/timeout.h \
>                         src/shared/uhid.h src/shared/uhid.c \
>                         src/shared/pcap.h src/shared/pcap.c \
>                         src/shared/btsnoop.h src/shared/btsnoop.c \
> +                       src/shared/advertising-data.h \
> +                       src/shared/advertising-data.c \
>                         src/shared/att-types.h \
>                         src/shared/att.h src/shared/att.c \
>                         src/shared/gatt-helpers.h src/shared/gatt-helpers.c \
> diff --git a/src/shared/advertising-data.c b/src/shared/advertising-data.c
> new file mode 100644
> index 0000000..4f86a78
> --- /dev/null
> +++ b/src/shared/advertising-data.c
> @@ -0,0 +1,350 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2015  Google Inc.
> + *
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + */
> +
> +#include "src/shared/advertising-data.h"
> +
> +#include "src/shared/queue.h"
> +#include "src/shared/util.h"
> +
> +struct advertising_data {
> +       int ref_count;
> +       struct queue *service_uuids;
> +       struct queue *manufacturer_data;
> +       struct queue *solicit_uuids;
> +       struct queue *service_data;
> +};
> +
> +struct uuid_tagged_data {
> +       bt_uuid_t uuid;
> +       uint8_t *data;
> +       size_t len;
> +};
> +
> +struct manufacturer_tagged_data {
> +       uint16_t manufacturer_id;
> +       uint8_t *data;
> +       size_t len;
> +};
> +
> +struct advertising_data *advertising_data_new(void)
> +{
> +       struct advertising_data *ad;
> +
> +       ad = new0(struct advertising_data, 1);
> +       if (!ad)
> +               return NULL;
> +
> +       ad->service_uuids = queue_new();
> +       if (!ad->service_uuids)
> +               goto fail;
> +
> +       ad->manufacturer_data = queue_new();
> +       if (!ad->manufacturer_data)
> +               goto fail;
> +
> +       ad->solicit_uuids = queue_new();
> +       if (!ad->solicit_uuids)
> +               goto fail;
> +
> +       ad->service_data = queue_new();
> +       if (!ad->service_data)
> +               goto fail;
> +
> +       return advertising_data_ref(ad);
> +
> +fail:
> +       queue_destroy(ad->service_uuids, NULL);
> +       queue_destroy(ad->manufacturer_data, NULL);
> +       queue_destroy(ad->solicit_uuids, NULL);
> +       queue_destroy(ad->service_data, NULL);
> +
> +       free(ad);
> +
> +       return NULL;
> +}
> +
> +struct advertising_data *advertising_data_ref(struct advertising_data *ad)
> +{
> +       ad->ref_count++;
> +       return ad;
> +}
> +
> +static void uuid_tagged_destroy(void *data)
> +{
> +       struct uuid_tagged_data *tagged = data;
> +
> +       free(tagged->data);
> +       free(tagged);
> +}
> +
> +static bool uuid_tagged_match(const void *data, const void *elem)
> +{
> +       const struct uuid_tagged_data *tagged = elem;
> +       const bt_uuid_t *uuid = data;
> +
> +       return !bt_uuid_cmp(&tagged->uuid, uuid);
> +}
> +
> +static void manuf_tagged_destroy(void *data)
> +{
> +       struct manufacturer_tagged_data *tagged = data;
> +
> +       free(tagged->data);
> +       free(tagged);
> +}
> +
> +static bool manuf_tagged_match(const void *data, const void *elem)
> +{
> +       const struct manufacturer_tagged_data *tagged = elem;
> +       uint16_t manuf_id = PTR_TO_UINT(elem);
> +
> +       return tagged->manufacturer_id == manuf_id;
> +}
> +
> +void advertising_data_unref(struct advertising_data *ad)
> +{
> +       if (!ad)
> +               return;
> +
> +       if (__sync_sub_and_fetch(&ad->ref_count, 1))
> +               return;
> +
> +       queue_destroy(ad->service_uuids, free);
> +
> +       queue_destroy(ad->manufacturer_data, manuf_tagged_destroy);
> +
> +       queue_destroy(ad->solicit_uuids, free);
> +
> +       queue_destroy(ad->service_data, uuid_tagged_destroy);
> +
> +       free(ad);
> +}
> +
> +uint8_t *advertising_data_generate(struct advertising_data *ad, uint8_t *length)
> +{
> +       /* TODO: implement */
> +       return NULL;
> +}
> +
> +static bool queue_add_uuid(struct queue *queue, const bt_uuid_t *uuid)
> +{
> +       bt_uuid_t *new_uuid;
> +
> +       if (!queue)
> +               return false;
> +
> +       new_uuid = new0(bt_uuid_t, 1);
> +       if (!new_uuid)
> +               return false;
> +
> +       bt_uuid_to_uuid128(uuid, new_uuid);
> +
> +       queue_push_tail(queue, new_uuid);
> +
> +       return true;
> +}
> +
> +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);
> +}
> +
> +static bool queue_remove_uuid(struct queue *queue, bt_uuid_t *uuid)
> +{
> +       bt_uuid_t *removed;
> +
> +       if (!queue || !uuid)
> +               return false;
> +
> +       removed = queue_remove_if(queue, uuid_match, uuid);
> +
> +       if (removed) {
> +               free(removed);
> +               return true;
> +       }
> +
> +       return false;
> +}
> +
> +bool advertising_data_add_service_uuid(struct advertising_data *ad,
> +                                                       const bt_uuid_t *uuid)
> +{
> +       if (!ad)
> +               return false;
> +
> +       return queue_add_uuid(ad->service_uuids, uuid);
> +}
> +
> +bool advertising_data_remove_service_uuid(struct advertising_data *ad,
> +                                                       bt_uuid_t *uuid)
> +{
> +       if (!ad)
> +               return false;
> +
> +       return queue_remove_uuid(ad->service_uuids, uuid);
> +}
> +
> +void advertising_data_clear_service_uuid(struct advertising_data *ad)
> +{
> +       queue_destroy(ad->service_uuids, free);
> +
> +       ad->service_uuids = queue_new();
> +}
> +
> +bool advertising_data_add_manufacturer_data(struct advertising_data *ad,
> +                                               uint16_t manufacturer_id,
> +                                               void *data, size_t len)
> +{
> +       struct manufacturer_tagged_data *new_data;
> +
> +       if (!ad)
> +               return false;
> +
> +       new_data = new0(struct manufacturer_tagged_data, 1);
> +       if (!new_data)
> +               return false;
> +
> +       new_data->manufacturer_id = manufacturer_id;
> +
> +       new_data->data = malloc(len);
> +       if (!new_data->data) {
> +               free(new_data);
> +               return false;
> +       }
> +
> +       memcpy(new_data->data, data, len);
> +
> +       if (queue_push_tail(ad->manufacturer_data, new_data))
> +               return true;
> +
> +       manuf_tagged_destroy(new_data);
> +
> +       return false;
> +}
> +
> +bool advertising_data_remove_manufacturer_data(struct advertising_data *ad,
> +                                               uint16_t manufacturer_id)
> +{
> +       struct manufacturer_tagged_data *data;
> +
> +       if (!ad)
> +               return false;
> +
> +       data = queue_remove_if(ad->manufacturer_data, manuf_tagged_match,
> +                                               UINT_TO_PTR(manufacturer_id));
> +
> +       if (!data)
> +               return false;
> +
> +       manuf_tagged_destroy(data);
> +
> +       return true;
> +}
> +
> +void advertising_data_clear_manufacturer_data(struct advertising_data *ad)
> +{
> +       queue_destroy(ad->manufacturer_data, manuf_tagged_destroy);
> +
> +       ad->manufacturer_data = queue_new();
> +}
> +
> +bool advertising_data_add_solicit_uuid(struct advertising_data *ad,
> +                                                       const bt_uuid_t *uuid)
> +{
> +       if (!ad)
> +               return false;
> +
> +       return queue_add_uuid(ad->solicit_uuids, uuid);
> +}
> +
> +bool advertising_data_remove_solicit_uuid(struct advertising_data *ad,
> +                                                       bt_uuid_t *uuid)
> +{
> +       if (!ad)
> +               return false;
> +
> +       return queue_remove_uuid(ad->solicit_uuids, uuid);
> +}
> +
> +void advertising_data_clear_solicit_uuid(struct advertising_data *ad)
> +{
> +       queue_destroy(ad->solicit_uuids, free);
> +
> +       ad->solicit_uuids = queue_new();
> +}
> +
> +bool advertising_data_add_service_data(struct advertising_data *ad,
> +                                               const bt_uuid_t *uuid,
> +                                               void *data, size_t len)
> +{
> +       struct uuid_tagged_data *new_data;
> +
> +       if (!ad)
> +               return false;
> +
> +       new_data = new0(struct uuid_tagged_data, 1);
> +       if (!new_data)
> +               return false;
> +
> +       bt_uuid_to_uuid128(uuid, &new_data->uuid);
> +
> +       new_data->data = malloc(len);
> +       if (!new_data) {
> +               free(new_data);
> +               return false;
> +       }
> +
> +       memcpy(new_data->data, data, len);
> +
> +       if (queue_push_tail(ad->service_data, new_data))
> +               return true;
> +
> +       uuid_tagged_destroy(new_data);
> +
> +       return false;
> +}
> +
> +bool advertising_data_remove_service_data(struct advertising_data *ad,
> +                                                       bt_uuid_t *uuid)
> +{
> +       struct uuid_tagged_data *data;
> +
> +       if (!ad)
> +               return false;
> +
> +       data = queue_remove_if(ad->service_data, uuid_tagged_match, uuid);
> +
> +       if (!data)
> +               return false;
> +
> +       uuid_tagged_destroy(data);
> +
> +       return true;
> +}
> +
> +void advertising_data_clear_service_data(struct advertising_data *ad)
> +{
> +       queue_destroy(ad->service_data, uuid_tagged_destroy);
> +
> +       ad->service_data = queue_new();
> +}
> +
> diff --git a/src/shared/advertising-data.h b/src/shared/advertising-data.h
> new file mode 100644
> index 0000000..05d2b51
> --- /dev/null
> +++ b/src/shared/advertising-data.h
> @@ -0,0 +1,69 @@
> +/*
> + *
> + *  BlueZ - Bluetooth protocol stack for Linux
> + *
> + *  Copyright (C) 2015  Google Inc.
> + *
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful,
> + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *  GNU General Public License for more details.
> + *
> + */
> +
> +#include <inttypes.h>
> +#include <stdbool.h>
> +
> +#include "lib/bluetooth.h"
> +#include "lib/uuid.h"
> +
> +struct advertising_data;
> +
> +struct advertising_data *advertising_data_new(void);
> +
> +struct advertising_data *advertising_data_ref(struct advertising_data *ad);
> +
> +void advertising_data_unref(struct advertising_data *ad);
> +
> +uint8_t *advertising_data_generate(struct advertising_data *ad,
> +                                                       uint8_t *length);
> +
> +bool advertising_data_add_service_uuid(struct advertising_data *ad,
> +                                                       const bt_uuid_t *uuid);
> +
> +bool advertising_data_remove_service_uuid(struct advertising_data *ad,
> +                                                       bt_uuid_t *uuid);
> +
> +void advertising_data_clear_service_uuid(struct advertising_data *ad);
> +
> +bool advertising_data_add_manufacturer_data(struct advertising_data *ad,
> +                                               uint16_t manufacturer_data,
> +                                               void *data, size_t len);
> +
> +bool advertising_data_remove_manufacturer_data(struct advertising_data *ad,
> +                                               uint16_t manufacturer_id);
> +
> +void advertising_data_clear_manufacturer_data(struct advertising_data *ad);
> +
> +bool advertising_data_add_solicit_uuid(struct advertising_data *ad,
> +                                                       const bt_uuid_t *uuid);
> +
> +bool advertising_data_remove_solicit_uuid(struct advertising_data *ad,
> +                                                       bt_uuid_t *uuid);
> +
> +void advertising_data_clear_solicit_uuid(struct advertising_data *ad);
> +
> +bool advertising_data_add_service_data(struct advertising_data *ad,
> +                                               const bt_uuid_t *uuid,
> +                                               void *data, size_t len);
> +
> +bool advertising_data_remove_service_data(struct advertising_data *ad,
> +                                                       bt_uuid_t *uuid);
> +
> +void advertising_data_clear_service_data(struct advertising_data *ad);
> --
> 2.2.0.rc0.207.ga3a616c
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Thanks,
Arman
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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