diff mbox series

[BlueZ] advertising: Add scan response properties to LEAdvertisement1

Message ID 20241111135250.2319622-1-yuxinwang9999@gmail.com (mailing list archive)
State New
Headers show
Series [BlueZ] advertising: Add scan response properties to LEAdvertisement1 | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch success CheckPatch PASS
tedd_an/GitLint success Gitlint PASS
tedd_an/BuildEll success Build ELL PASS
tedd_an/BluezMake success Bluez Make PASS
tedd_an/MakeCheck success Bluez Make Check PASS
tedd_an/MakeDistcheck success Make Distcheck PASS
tedd_an/CheckValgrind success Check Valgrind PASS
tedd_an/CheckSmatch success CheckSparse PASS
tedd_an/bluezmakeextell success Make External ELL PASS
tedd_an/IncrementalBuild success Incremental Build PASS
tedd_an/ScanBuild success Scan Build PASS

Commit Message

Yuxin Wang Nov. 11, 2024, 1:52 p.m. UTC
This update introduces a few properties to org.bluez.LEAdvertisement1
for manipulating Scan Response Data, similar to the existing properties
for Advertising Data.

Resolves: https://github.com/bluez/bluez/issues/667
---
 doc/org.bluez.LEAdvertisement.rst |  37 ++++++++-
 src/advertising.c                 | 132 ++++++++++++++++++++++--------
 2 files changed, 130 insertions(+), 39 deletions(-)

Comments

Luiz Augusto von Dentz Nov. 11, 2024, 2:26 p.m. UTC | #1
Hi Yuxin,

On Mon, Nov 11, 2024 at 8:53 AM Yuxin Wang <yuxinwang9999@gmail.com> wrote:
>
> This update introduces a few properties to org.bluez.LEAdvertisement1
> for manipulating Scan Response Data, similar to the existing properties
> for Advertising Data.

Why would it matter if it's part of the scan data or not? Also ever
since the introduction of extended advertising (EA) these fields are
no longer separated so introducing these fields now is not really
solving any problem in my opinion.

> Resolves: https://github.com/bluez/bluez/issues/667
> ---
>  doc/org.bluez.LEAdvertisement.rst |  37 ++++++++-
>  src/advertising.c                 | 132 ++++++++++++++++++++++--------
>  2 files changed, 130 insertions(+), 39 deletions(-)
>
> diff --git a/doc/org.bluez.LEAdvertisement.rst b/doc/org.bluez.LEAdvertisement.rst
> index d3f9cc4..40be2ff 100644
> --- a/doc/org.bluez.LEAdvertisement.rst
> +++ b/doc/org.bluez.LEAdvertisement.rst
> @@ -75,13 +75,14 @@ dict ManufacturerData
>  array{string} SolicitUUIDs
>  ``````````````````````````
>
> -       Array of UUIDs to include in "Service Solicitation" Advertisement Data.
> +       List of UUIDs to include in the "Service Solicitation" field of the
> +       Advertising Data.
>
>  dict ServiceData
>  ````````````````
>
> -       Service Data elements to include. The keys are the UUID to associate
> -       with the data.
> +       Service Data elements to include in the Advertising Data. The keys
> +       are the UUID to associate with the data.
>
>  dict Data
>  `````````
> @@ -101,6 +102,36 @@ dict Data
>                 <Transport Discovery> <Organization Flags...>
>                 0x26                   0x01         0x01...
>
> +array{string} ScanResponseServiceUUIDs
> +``````````````````````````````````````
> +
> +       List of UUIDs to include in the "Service UUID" field of the Scan
> +       Response Data.
> +
> +dict ScanResponseManufacturerData
> +`````````````````````````````````
> +
> +       Manufacturer Data fields to include in the Scan Response Data. Keys
> +       are the Manufacturer ID to associate with the data.
> +
> +array{string} ScanResponseSolicitUUIDs
> +``````````````````````````````````````
> +
> +       List of UUIDs to include in the "Service Solicitation" field of the
> +       Scan Response Data.
> +
> +dict ScanResponseServiceData
> +````````````````````````````
> +
> +       Service Data elements to include in the Scan Response Data. The keys
> +       are the UUID to associate with the data.
> +
> +dict ScanResponseData
> +`````````````````````
> +
> +       Scan Response Data to include. Key is the advertising type and value is
> +       the data as byte array.
> +
>  bool Discoverable
>  `````````````````
>
> diff --git a/src/advertising.c b/src/advertising.c
> index bd121e5..ba70419 100644
> --- a/src/advertising.c
> +++ b/src/advertising.c
> @@ -255,13 +255,12 @@ static bool parse_type(DBusMessageIter *iter, struct btd_adv_client *client)
>         return false;
>  }
>
> -static bool parse_service_uuids(DBusMessageIter *iter,
> -                                       struct btd_adv_client *client)
> +static bool parse_service_uuids(DBusMessageIter *iter, struct bt_ad *ad)
>  {
>         DBusMessageIter ariter;
>
>         if (!iter) {
> -               bt_ad_clear_service_uuid(client->data);
> +               bt_ad_clear_service_uuid(ad);
>                 return true;
>         }
>
> @@ -270,7 +269,7 @@ static bool parse_service_uuids(DBusMessageIter *iter,
>
>         dbus_message_iter_recurse(iter, &ariter);
>
> -       bt_ad_clear_service_uuid(client->data);
> +       bt_ad_clear_service_uuid(ad);
>
>         while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
>                 const char *uuid_str;
> @@ -283,7 +282,7 @@ static bool parse_service_uuids(DBusMessageIter *iter,
>                 if (bt_string_to_uuid(&uuid, uuid_str) < 0)
>                         goto fail;
>
> -               if (!bt_ad_add_service_uuid(client->data, &uuid))
> +               if (!bt_ad_add_service_uuid(ad, &uuid))
>                         goto fail;
>
>                 dbus_message_iter_next(&ariter);
> @@ -292,17 +291,28 @@ static bool parse_service_uuids(DBusMessageIter *iter,
>         return true;
>
>  fail:
> -       bt_ad_clear_service_uuid(client->data);
> +       bt_ad_clear_service_uuid(ad);
>         return false;
>  }
>
> -static bool parse_solicit_uuids(DBusMessageIter *iter,
> +static bool parse_service_uuids_ad(DBusMessageIter *iter,
> +                                       struct btd_adv_client *client)
> +{
> +       return parse_service_uuids(iter, client->data);
> +}
> +
> +static bool parse_service_uuids_sr(DBusMessageIter *iter,
>                                         struct btd_adv_client *client)
> +{
> +       return parse_service_uuids(iter, client->scan);
> +}
> +
> +static bool parse_solicit_uuids(DBusMessageIter *iter, struct bt_ad *ad)
>  {
>         DBusMessageIter ariter;
>
>         if (!iter) {
> -               bt_ad_clear_solicit_uuid(client->data);
> +               bt_ad_clear_solicit_uuid(ad);
>                 return true;
>         }
>
> @@ -311,7 +321,7 @@ static bool parse_solicit_uuids(DBusMessageIter *iter,
>
>         dbus_message_iter_recurse(iter, &ariter);
>
> -       bt_ad_clear_solicit_uuid(client->data);
> +       bt_ad_clear_solicit_uuid(ad);
>
>         while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
>                 const char *uuid_str;
> @@ -324,7 +334,7 @@ static bool parse_solicit_uuids(DBusMessageIter *iter,
>                 if (bt_string_to_uuid(&uuid, uuid_str) < 0)
>                         goto fail;
>
> -               if (!bt_ad_add_solicit_uuid(client->data, &uuid))
> +               if (!bt_ad_add_solicit_uuid(ad, &uuid))
>                         goto fail;
>
>                 dbus_message_iter_next(&ariter);
> @@ -333,17 +343,28 @@ static bool parse_solicit_uuids(DBusMessageIter *iter,
>         return true;
>
>  fail:
> -       bt_ad_clear_solicit_uuid(client->data);
> +       bt_ad_clear_solicit_uuid(ad);
>         return false;
>  }
>
> -static bool parse_manufacturer_data(DBusMessageIter *iter,
> +static bool parse_solicit_uuids_ad(DBusMessageIter *iter,
>                                         struct btd_adv_client *client)
> +{
> +       return parse_solicit_uuids(iter, client->data);
> +}
> +
> +static bool parse_solicit_uuids_sr(DBusMessageIter *iter,
> +                                       struct btd_adv_client *client)
> +{
> +       return parse_solicit_uuids(iter, client->scan);
> +}
> +
> +static bool parse_manufacturer_data(DBusMessageIter *iter, struct bt_ad *ad)
>  {
>         DBusMessageIter entries;
>
>         if (!iter) {
> -               bt_ad_clear_manufacturer_data(client->data);
> +               bt_ad_clear_manufacturer_data(ad);
>                 return true;
>         }
>
> @@ -352,7 +373,7 @@ static bool parse_manufacturer_data(DBusMessageIter *iter,
>
>         dbus_message_iter_recurse(iter, &entries);
>
> -       bt_ad_clear_manufacturer_data(client->data);
> +       bt_ad_clear_manufacturer_data(ad);
>
>         while (dbus_message_iter_get_arg_type(&entries)
>                                                 == DBUS_TYPE_DICT_ENTRY) {
> @@ -383,7 +404,7 @@ static bool parse_manufacturer_data(DBusMessageIter *iter,
>
>                 DBG("Adding ManufacturerData for %04x", manuf_id);
>
> -               if (!bt_ad_add_manufacturer_data(client->data, manuf_id,
> +               if (!bt_ad_add_manufacturer_data(ad, manuf_id,
>                                                         manuf_data, len))
>                         goto fail;
>
> @@ -393,17 +414,28 @@ static bool parse_manufacturer_data(DBusMessageIter *iter,
>         return true;
>
>  fail:
> -       bt_ad_clear_manufacturer_data(client->data);
> +       bt_ad_clear_manufacturer_data(ad);
>         return false;
>  }
>
> -static bool parse_service_data(DBusMessageIter *iter,
> +static bool parse_manufacturer_data_ad(DBusMessageIter *iter,
> +                                       struct btd_adv_client *client)
> +{
> +       return parse_manufacturer_data(iter, client->data);
> +}
> +
> +static bool parse_manufacturer_data_sr(DBusMessageIter *iter,
>                                         struct btd_adv_client *client)
> +{
> +       return parse_manufacturer_data(iter, client->scan);
> +}
> +
> +static bool parse_service_data(DBusMessageIter *iter, struct bt_ad *ad)
>  {
>         DBusMessageIter entries;
>
>         if (!iter) {
> -               bt_ad_clear_service_data(client->data);
> +               bt_ad_clear_service_data(ad);
>                 return true;
>         }
>
> @@ -412,7 +444,7 @@ static bool parse_service_data(DBusMessageIter *iter,
>
>         dbus_message_iter_recurse(iter, &entries);
>
> -       bt_ad_clear_service_data(client->data);
> +       bt_ad_clear_service_data(ad);
>
>         while (dbus_message_iter_get_arg_type(&entries)
>                                                 == DBUS_TYPE_DICT_ENTRY) {
> @@ -447,7 +479,7 @@ static bool parse_service_data(DBusMessageIter *iter,
>
>                 DBG("Adding ServiceData for %s", uuid_str);
>
> -               if (!bt_ad_add_service_data(client->data, &uuid, service_data,
> +               if (!bt_ad_add_service_data(ad, &uuid, service_data,
>                                                                         len))
>                         goto fail;
>
> @@ -457,10 +489,22 @@ static bool parse_service_data(DBusMessageIter *iter,
>         return true;
>
>  fail:
> -       bt_ad_clear_service_data(client->data);
> +       bt_ad_clear_service_data(ad);
>         return false;
>  }
>
> +static bool parse_service_data_ad(DBusMessageIter *iter,
> +                                       struct btd_adv_client *client)
> +{
> +       return parse_service_data(iter, client->data);
> +}
> +
> +static bool parse_service_data_sr(DBusMessageIter *iter,
> +                                       struct btd_adv_client *client)
> +{
> +       return parse_service_data(iter, client->scan);
> +}
> +
>  static bool set_rsi(struct btd_adv_client *client)
>  {
>         struct bt_crypto *crypto;
> @@ -667,12 +711,12 @@ static bool parse_timeout(DBusMessageIter *iter,
>         return true;
>  }
>
> -static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
> +static bool parse_data(DBusMessageIter *iter, struct bt_ad *ad)
>  {
>         DBusMessageIter entries;
>
>         if (!iter) {
> -               bt_ad_clear_data(client->data);
> +               bt_ad_clear_data(ad);
>                 return true;
>         }
>
> @@ -681,7 +725,7 @@ static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
>
>         dbus_message_iter_recurse(iter, &entries);
>
> -       bt_ad_clear_data(client->data);
> +       bt_ad_clear_data(ad);
>
>         while (dbus_message_iter_get_arg_type(&entries)
>                                                 == DBUS_TYPE_DICT_ENTRY) {
> @@ -712,7 +756,7 @@ static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
>
>                 DBG("Adding Data for type 0x%02x len %u", type, len);
>
> -               if (!bt_ad_add_data(client->data, type, data, len))
> +               if (!bt_ad_add_data(ad, type, data, len))
>                         goto fail;
>
>                 dbus_message_iter_next(&entries);
> @@ -721,10 +765,22 @@ static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
>         return true;
>
>  fail:
> -       bt_ad_clear_data(client->data);
> +       bt_ad_clear_data(ad);
>         return false;
>  }
>
> +static bool parse_data_ad(DBusMessageIter *iter,
> +                                       struct btd_adv_client *client)
> +{
> +       return parse_data(iter, client->data);
> +}
> +
> +static bool parse_data_sr(DBusMessageIter *iter,
> +                                       struct btd_adv_client *client)
> +{
> +       return parse_data(iter, client->scan);
> +}
> +
>  static bool set_flags(struct btd_adv_client *client, uint8_t flags)
>  {
>         /* Set BR/EDR Not Supported for LE only */
> @@ -832,15 +888,14 @@ static uint8_t *generate_adv_data(struct btd_adv_client *client,
>  static uint8_t *generate_scan_rsp(struct btd_adv_client *client,
>                                                 uint32_t *flags, size_t *len)
>  {
> -       if (!client->name) {
> +       if (client->name) {
> +               *flags &= ~MGMT_ADV_FLAG_LOCAL_NAME;
> +               bt_ad_add_name(client->scan, client->name);
> +       } else if (bt_ad_is_empty(client->scan)) {
>                 *len = 0;
>                 return NULL;
>         }
>
> -       *flags &= ~MGMT_ADV_FLAG_LOCAL_NAME;
> -
> -       bt_ad_add_name(client->scan, client->name);
> -
>         return bt_ad_generate(client->scan, len);
>  }
>
> @@ -1212,16 +1267,21 @@ static struct adv_parser {
>         bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
>  } parsers[] = {
>         { "Type", parse_type },
> -       { "ServiceUUIDs", parse_service_uuids },
> -       { "SolicitUUIDs", parse_solicit_uuids },
> -       { "ManufacturerData", parse_manufacturer_data },
> -       { "ServiceData", parse_service_data },
> +       { "ServiceUUIDs", parse_service_uuids_ad },
> +       { "ScanResponseServiceUUIDs", parse_service_uuids_sr },
> +       { "SolicitUUIDs", parse_solicit_uuids_ad },
> +       { "ScanResponseSolicitUUIDs", parse_solicit_uuids_sr },
> +       { "ManufacturerData", parse_manufacturer_data_ad },
> +       { "ScanResponseManufacturerData", parse_manufacturer_data_sr },
> +       { "ServiceData", parse_service_data_ad },
> +       { "ScanResponseServiceData", parse_service_data_sr },
>         { "Includes", parse_includes },
>         { "LocalName", parse_local_name },
>         { "Appearance", parse_appearance },
>         { "Duration", parse_duration },
>         { "Timeout", parse_timeout },
> -       { "Data", parse_data },
> +       { "Data", parse_data_ad },
> +       { "ScanResponseData", parse_data_sr },
>         { "Discoverable", parse_discoverable },
>         { "DiscoverableTimeout", parse_discoverable_timeout },
>         { "SecondaryChannel", parse_secondary },
> --
> 2.39.5
>
bluez.test.bot@gmail.com Nov. 11, 2024, 3:41 p.m. UTC | #2
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=908428

---Test result---

Test Summary:
CheckPatch                    PASS      0.54 seconds
GitLint                       PASS      1.62 seconds
BuildEll                      PASS      24.69 seconds
BluezMake                     PASS      1656.56 seconds
MakeCheck                     PASS      14.26 seconds
MakeDistcheck                 PASS      180.46 seconds
CheckValgrind                 PASS      254.63 seconds
CheckSmatch                   PASS      357.24 seconds
bluezmakeextell               PASS      120.99 seconds
IncrementalBuild              PASS      1413.64 seconds
ScanBuild                     PASS      1014.12 seconds



---
Regards,
Linux Bluetooth
Yuxin Wang Nov. 11, 2024, 4:32 p.m. UTC | #3
Hi Luiz,

I would ideally like to use Extended Advertising (EA) as well.
However, EA is an optional feature that not all BLE 5.0 devices
support, such as the Raspberry Pi 4. For devices that do not support
EA, including BLE 4.2 devices, using Scan Response Data is the only
option to advertise more content.

In my scenario, the advertising data is about 50 bytes. Therefore,
using Scan Response Data is a reasonable solution to be compatible
with all devices.

I'm not sure how useful the Scan Response Data is, but there may be
others looking for this feature:

- https://www.linux.org/threads/bluez-how-to-fully-use-adv-and-scan-resp-packets.53468/
- https://github.com/bluez/bluez/issues/667

The Scan Response Data is also mentioned in the Matter Core
Specification, which states, "Note that if additional vendor-specific
information is to be conveyed and does not fit within the Advertising
Data, it may be included in the Scan Response Data."

While advanced users may manipulate Scan Response Data via the
Management Socket or btmgmt, these methods are less user-friendly.
Setting Scan Response Data has already been implemented in the
underlying code but has not yet been made accessible via DBus.


On Mon, Nov 11, 2024 at 10:26 PM Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
>
> Hi Yuxin,
>
> On Mon, Nov 11, 2024 at 8:53 AM Yuxin Wang <yuxinwang9999@gmail.com> wrote:
> >
> > This update introduces a few properties to org.bluez.LEAdvertisement1
> > for manipulating Scan Response Data, similar to the existing properties
> > for Advertising Data.
>
> Why would it matter if it's part of the scan data or not? Also ever
> since the introduction of extended advertising (EA) these fields are
> no longer separated so introducing these fields now is not really
> solving any problem in my opinion.
>
> > Resolves: https://github.com/bluez/bluez/issues/667
> > ---
> >  doc/org.bluez.LEAdvertisement.rst |  37 ++++++++-
> >  src/advertising.c                 | 132 ++++++++++++++++++++++--------
> >  2 files changed, 130 insertions(+), 39 deletions(-)
> >
> > diff --git a/doc/org.bluez.LEAdvertisement.rst b/doc/org.bluez.LEAdvertisement.rst
> > index d3f9cc4..40be2ff 100644
> > --- a/doc/org.bluez.LEAdvertisement.rst
> > +++ b/doc/org.bluez.LEAdvertisement.rst
> > @@ -75,13 +75,14 @@ dict ManufacturerData
> >  array{string} SolicitUUIDs
> >  ``````````````````````````
> >
> > -       Array of UUIDs to include in "Service Solicitation" Advertisement Data.
> > +       List of UUIDs to include in the "Service Solicitation" field of the
> > +       Advertising Data.
> >
> >  dict ServiceData
> >  ````````````````
> >
> > -       Service Data elements to include. The keys are the UUID to associate
> > -       with the data.
> > +       Service Data elements to include in the Advertising Data. The keys
> > +       are the UUID to associate with the data.
> >
> >  dict Data
> >  `````````
> > @@ -101,6 +102,36 @@ dict Data
> >                 <Transport Discovery> <Organization Flags...>
> >                 0x26                   0x01         0x01...
> >
> > +array{string} ScanResponseServiceUUIDs
> > +``````````````````````````````````````
> > +
> > +       List of UUIDs to include in the "Service UUID" field of the Scan
> > +       Response Data.
> > +
> > +dict ScanResponseManufacturerData
> > +`````````````````````````````````
> > +
> > +       Manufacturer Data fields to include in the Scan Response Data. Keys
> > +       are the Manufacturer ID to associate with the data.
> > +
> > +array{string} ScanResponseSolicitUUIDs
> > +``````````````````````````````````````
> > +
> > +       List of UUIDs to include in the "Service Solicitation" field of the
> > +       Scan Response Data.
> > +
> > +dict ScanResponseServiceData
> > +````````````````````````````
> > +
> > +       Service Data elements to include in the Scan Response Data. The keys
> > +       are the UUID to associate with the data.
> > +
> > +dict ScanResponseData
> > +`````````````````````
> > +
> > +       Scan Response Data to include. Key is the advertising type and value is
> > +       the data as byte array.
> > +
> >  bool Discoverable
> >  `````````````````
> >
> > diff --git a/src/advertising.c b/src/advertising.c
> > index bd121e5..ba70419 100644
> > --- a/src/advertising.c
> > +++ b/src/advertising.c
> > @@ -255,13 +255,12 @@ static bool parse_type(DBusMessageIter *iter, struct btd_adv_client *client)
> >         return false;
> >  }
> >
> > -static bool parse_service_uuids(DBusMessageIter *iter,
> > -                                       struct btd_adv_client *client)
> > +static bool parse_service_uuids(DBusMessageIter *iter, struct bt_ad *ad)
> >  {
> >         DBusMessageIter ariter;
> >
> >         if (!iter) {
> > -               bt_ad_clear_service_uuid(client->data);
> > +               bt_ad_clear_service_uuid(ad);
> >                 return true;
> >         }
> >
> > @@ -270,7 +269,7 @@ static bool parse_service_uuids(DBusMessageIter *iter,
> >
> >         dbus_message_iter_recurse(iter, &ariter);
> >
> > -       bt_ad_clear_service_uuid(client->data);
> > +       bt_ad_clear_service_uuid(ad);
> >
> >         while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
> >                 const char *uuid_str;
> > @@ -283,7 +282,7 @@ static bool parse_service_uuids(DBusMessageIter *iter,
> >                 if (bt_string_to_uuid(&uuid, uuid_str) < 0)
> >                         goto fail;
> >
> > -               if (!bt_ad_add_service_uuid(client->data, &uuid))
> > +               if (!bt_ad_add_service_uuid(ad, &uuid))
> >                         goto fail;
> >
> >                 dbus_message_iter_next(&ariter);
> > @@ -292,17 +291,28 @@ static bool parse_service_uuids(DBusMessageIter *iter,
> >         return true;
> >
> >  fail:
> > -       bt_ad_clear_service_uuid(client->data);
> > +       bt_ad_clear_service_uuid(ad);
> >         return false;
> >  }
> >
> > -static bool parse_solicit_uuids(DBusMessageIter *iter,
> > +static bool parse_service_uuids_ad(DBusMessageIter *iter,
> > +                                       struct btd_adv_client *client)
> > +{
> > +       return parse_service_uuids(iter, client->data);
> > +}
> > +
> > +static bool parse_service_uuids_sr(DBusMessageIter *iter,
> >                                         struct btd_adv_client *client)
> > +{
> > +       return parse_service_uuids(iter, client->scan);
> > +}
> > +
> > +static bool parse_solicit_uuids(DBusMessageIter *iter, struct bt_ad *ad)
> >  {
> >         DBusMessageIter ariter;
> >
> >         if (!iter) {
> > -               bt_ad_clear_solicit_uuid(client->data);
> > +               bt_ad_clear_solicit_uuid(ad);
> >                 return true;
> >         }
> >
> > @@ -311,7 +321,7 @@ static bool parse_solicit_uuids(DBusMessageIter *iter,
> >
> >         dbus_message_iter_recurse(iter, &ariter);
> >
> > -       bt_ad_clear_solicit_uuid(client->data);
> > +       bt_ad_clear_solicit_uuid(ad);
> >
> >         while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
> >                 const char *uuid_str;
> > @@ -324,7 +334,7 @@ static bool parse_solicit_uuids(DBusMessageIter *iter,
> >                 if (bt_string_to_uuid(&uuid, uuid_str) < 0)
> >                         goto fail;
> >
> > -               if (!bt_ad_add_solicit_uuid(client->data, &uuid))
> > +               if (!bt_ad_add_solicit_uuid(ad, &uuid))
> >                         goto fail;
> >
> >                 dbus_message_iter_next(&ariter);
> > @@ -333,17 +343,28 @@ static bool parse_solicit_uuids(DBusMessageIter *iter,
> >         return true;
> >
> >  fail:
> > -       bt_ad_clear_solicit_uuid(client->data);
> > +       bt_ad_clear_solicit_uuid(ad);
> >         return false;
> >  }
> >
> > -static bool parse_manufacturer_data(DBusMessageIter *iter,
> > +static bool parse_solicit_uuids_ad(DBusMessageIter *iter,
> >                                         struct btd_adv_client *client)
> > +{
> > +       return parse_solicit_uuids(iter, client->data);
> > +}
> > +
> > +static bool parse_solicit_uuids_sr(DBusMessageIter *iter,
> > +                                       struct btd_adv_client *client)
> > +{
> > +       return parse_solicit_uuids(iter, client->scan);
> > +}
> > +
> > +static bool parse_manufacturer_data(DBusMessageIter *iter, struct bt_ad *ad)
> >  {
> >         DBusMessageIter entries;
> >
> >         if (!iter) {
> > -               bt_ad_clear_manufacturer_data(client->data);
> > +               bt_ad_clear_manufacturer_data(ad);
> >                 return true;
> >         }
> >
> > @@ -352,7 +373,7 @@ static bool parse_manufacturer_data(DBusMessageIter *iter,
> >
> >         dbus_message_iter_recurse(iter, &entries);
> >
> > -       bt_ad_clear_manufacturer_data(client->data);
> > +       bt_ad_clear_manufacturer_data(ad);
> >
> >         while (dbus_message_iter_get_arg_type(&entries)
> >                                                 == DBUS_TYPE_DICT_ENTRY) {
> > @@ -383,7 +404,7 @@ static bool parse_manufacturer_data(DBusMessageIter *iter,
> >
> >                 DBG("Adding ManufacturerData for %04x", manuf_id);
> >
> > -               if (!bt_ad_add_manufacturer_data(client->data, manuf_id,
> > +               if (!bt_ad_add_manufacturer_data(ad, manuf_id,
> >                                                         manuf_data, len))
> >                         goto fail;
> >
> > @@ -393,17 +414,28 @@ static bool parse_manufacturer_data(DBusMessageIter *iter,
> >         return true;
> >
> >  fail:
> > -       bt_ad_clear_manufacturer_data(client->data);
> > +       bt_ad_clear_manufacturer_data(ad);
> >         return false;
> >  }
> >
> > -static bool parse_service_data(DBusMessageIter *iter,
> > +static bool parse_manufacturer_data_ad(DBusMessageIter *iter,
> > +                                       struct btd_adv_client *client)
> > +{
> > +       return parse_manufacturer_data(iter, client->data);
> > +}
> > +
> > +static bool parse_manufacturer_data_sr(DBusMessageIter *iter,
> >                                         struct btd_adv_client *client)
> > +{
> > +       return parse_manufacturer_data(iter, client->scan);
> > +}
> > +
> > +static bool parse_service_data(DBusMessageIter *iter, struct bt_ad *ad)
> >  {
> >         DBusMessageIter entries;
> >
> >         if (!iter) {
> > -               bt_ad_clear_service_data(client->data);
> > +               bt_ad_clear_service_data(ad);
> >                 return true;
> >         }
> >
> > @@ -412,7 +444,7 @@ static bool parse_service_data(DBusMessageIter *iter,
> >
> >         dbus_message_iter_recurse(iter, &entries);
> >
> > -       bt_ad_clear_service_data(client->data);
> > +       bt_ad_clear_service_data(ad);
> >
> >         while (dbus_message_iter_get_arg_type(&entries)
> >                                                 == DBUS_TYPE_DICT_ENTRY) {
> > @@ -447,7 +479,7 @@ static bool parse_service_data(DBusMessageIter *iter,
> >
> >                 DBG("Adding ServiceData for %s", uuid_str);
> >
> > -               if (!bt_ad_add_service_data(client->data, &uuid, service_data,
> > +               if (!bt_ad_add_service_data(ad, &uuid, service_data,
> >                                                                         len))
> >                         goto fail;
> >
> > @@ -457,10 +489,22 @@ static bool parse_service_data(DBusMessageIter *iter,
> >         return true;
> >
> >  fail:
> > -       bt_ad_clear_service_data(client->data);
> > +       bt_ad_clear_service_data(ad);
> >         return false;
> >  }
> >
> > +static bool parse_service_data_ad(DBusMessageIter *iter,
> > +                                       struct btd_adv_client *client)
> > +{
> > +       return parse_service_data(iter, client->data);
> > +}
> > +
> > +static bool parse_service_data_sr(DBusMessageIter *iter,
> > +                                       struct btd_adv_client *client)
> > +{
> > +       return parse_service_data(iter, client->scan);
> > +}
> > +
> >  static bool set_rsi(struct btd_adv_client *client)
> >  {
> >         struct bt_crypto *crypto;
> > @@ -667,12 +711,12 @@ static bool parse_timeout(DBusMessageIter *iter,
> >         return true;
> >  }
> >
> > -static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
> > +static bool parse_data(DBusMessageIter *iter, struct bt_ad *ad)
> >  {
> >         DBusMessageIter entries;
> >
> >         if (!iter) {
> > -               bt_ad_clear_data(client->data);
> > +               bt_ad_clear_data(ad);
> >                 return true;
> >         }
> >
> > @@ -681,7 +725,7 @@ static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
> >
> >         dbus_message_iter_recurse(iter, &entries);
> >
> > -       bt_ad_clear_data(client->data);
> > +       bt_ad_clear_data(ad);
> >
> >         while (dbus_message_iter_get_arg_type(&entries)
> >                                                 == DBUS_TYPE_DICT_ENTRY) {
> > @@ -712,7 +756,7 @@ static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
> >
> >                 DBG("Adding Data for type 0x%02x len %u", type, len);
> >
> > -               if (!bt_ad_add_data(client->data, type, data, len))
> > +               if (!bt_ad_add_data(ad, type, data, len))
> >                         goto fail;
> >
> >                 dbus_message_iter_next(&entries);
> > @@ -721,10 +765,22 @@ static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
> >         return true;
> >
> >  fail:
> > -       bt_ad_clear_data(client->data);
> > +       bt_ad_clear_data(ad);
> >         return false;
> >  }
> >
> > +static bool parse_data_ad(DBusMessageIter *iter,
> > +                                       struct btd_adv_client *client)
> > +{
> > +       return parse_data(iter, client->data);
> > +}
> > +
> > +static bool parse_data_sr(DBusMessageIter *iter,
> > +                                       struct btd_adv_client *client)
> > +{
> > +       return parse_data(iter, client->scan);
> > +}
> > +
> >  static bool set_flags(struct btd_adv_client *client, uint8_t flags)
> >  {
> >         /* Set BR/EDR Not Supported for LE only */
> > @@ -832,15 +888,14 @@ static uint8_t *generate_adv_data(struct btd_adv_client *client,
> >  static uint8_t *generate_scan_rsp(struct btd_adv_client *client,
> >                                                 uint32_t *flags, size_t *len)
> >  {
> > -       if (!client->name) {
> > +       if (client->name) {
> > +               *flags &= ~MGMT_ADV_FLAG_LOCAL_NAME;
> > +               bt_ad_add_name(client->scan, client->name);
> > +       } else if (bt_ad_is_empty(client->scan)) {
> >                 *len = 0;
> >                 return NULL;
> >         }
> >
> > -       *flags &= ~MGMT_ADV_FLAG_LOCAL_NAME;
> > -
> > -       bt_ad_add_name(client->scan, client->name);
> > -
> >         return bt_ad_generate(client->scan, len);
> >  }
> >
> > @@ -1212,16 +1267,21 @@ static struct adv_parser {
> >         bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
> >  } parsers[] = {
> >         { "Type", parse_type },
> > -       { "ServiceUUIDs", parse_service_uuids },
> > -       { "SolicitUUIDs", parse_solicit_uuids },
> > -       { "ManufacturerData", parse_manufacturer_data },
> > -       { "ServiceData", parse_service_data },
> > +       { "ServiceUUIDs", parse_service_uuids_ad },
> > +       { "ScanResponseServiceUUIDs", parse_service_uuids_sr },
> > +       { "SolicitUUIDs", parse_solicit_uuids_ad },
> > +       { "ScanResponseSolicitUUIDs", parse_solicit_uuids_sr },
> > +       { "ManufacturerData", parse_manufacturer_data_ad },
> > +       { "ScanResponseManufacturerData", parse_manufacturer_data_sr },
> > +       { "ServiceData", parse_service_data_ad },
> > +       { "ScanResponseServiceData", parse_service_data_sr },
> >         { "Includes", parse_includes },
> >         { "LocalName", parse_local_name },
> >         { "Appearance", parse_appearance },
> >         { "Duration", parse_duration },
> >         { "Timeout", parse_timeout },
> > -       { "Data", parse_data },
> > +       { "Data", parse_data_ad },
> > +       { "ScanResponseData", parse_data_sr },
> >         { "Discoverable", parse_discoverable },
> >         { "DiscoverableTimeout", parse_discoverable_timeout },
> >         { "SecondaryChannel", parse_secondary },
> > --
> > 2.39.5
> >
>
>
> --
> Luiz Augusto von Dentz
diff mbox series

Patch

diff --git a/doc/org.bluez.LEAdvertisement.rst b/doc/org.bluez.LEAdvertisement.rst
index d3f9cc4..40be2ff 100644
--- a/doc/org.bluez.LEAdvertisement.rst
+++ b/doc/org.bluez.LEAdvertisement.rst
@@ -75,13 +75,14 @@  dict ManufacturerData
 array{string} SolicitUUIDs
 ``````````````````````````
 
-	Array of UUIDs to include in "Service Solicitation" Advertisement Data.
+	List of UUIDs to include in the "Service Solicitation" field of the
+	Advertising Data.
 
 dict ServiceData
 ````````````````
 
-	Service Data elements to include. The keys are the UUID to associate
-	with the data.
+	Service Data elements to include in the Advertising Data. The keys
+	are the UUID to associate with the data.
 
 dict Data
 `````````
@@ -101,6 +102,36 @@  dict Data
 		<Transport Discovery> <Organization Flags...>
 		0x26                   0x01         0x01...
 
+array{string} ScanResponseServiceUUIDs
+``````````````````````````````````````
+
+	List of UUIDs to include in the "Service UUID" field of the Scan
+	Response Data.
+
+dict ScanResponseManufacturerData
+`````````````````````````````````
+
+	Manufacturer Data fields to include in the Scan Response Data. Keys
+	are the Manufacturer ID to associate with the data.
+
+array{string} ScanResponseSolicitUUIDs
+``````````````````````````````````````
+
+	List of UUIDs to include in the "Service Solicitation" field of the
+	Scan Response Data.
+
+dict ScanResponseServiceData
+````````````````````````````
+
+	Service Data elements to include in the Scan Response Data. The keys
+	are the UUID to associate with the data.
+
+dict ScanResponseData
+`````````````````````
+
+	Scan Response Data to include. Key is the advertising type and value is
+	the data as byte array.
+
 bool Discoverable
 `````````````````
 
diff --git a/src/advertising.c b/src/advertising.c
index bd121e5..ba70419 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -255,13 +255,12 @@  static bool parse_type(DBusMessageIter *iter, struct btd_adv_client *client)
 	return false;
 }
 
-static bool parse_service_uuids(DBusMessageIter *iter,
-					struct btd_adv_client *client)
+static bool parse_service_uuids(DBusMessageIter *iter, struct bt_ad *ad)
 {
 	DBusMessageIter ariter;
 
 	if (!iter) {
-		bt_ad_clear_service_uuid(client->data);
+		bt_ad_clear_service_uuid(ad);
 		return true;
 	}
 
@@ -270,7 +269,7 @@  static bool parse_service_uuids(DBusMessageIter *iter,
 
 	dbus_message_iter_recurse(iter, &ariter);
 
-	bt_ad_clear_service_uuid(client->data);
+	bt_ad_clear_service_uuid(ad);
 
 	while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
 		const char *uuid_str;
@@ -283,7 +282,7 @@  static bool parse_service_uuids(DBusMessageIter *iter,
 		if (bt_string_to_uuid(&uuid, uuid_str) < 0)
 			goto fail;
 
-		if (!bt_ad_add_service_uuid(client->data, &uuid))
+		if (!bt_ad_add_service_uuid(ad, &uuid))
 			goto fail;
 
 		dbus_message_iter_next(&ariter);
@@ -292,17 +291,28 @@  static bool parse_service_uuids(DBusMessageIter *iter,
 	return true;
 
 fail:
-	bt_ad_clear_service_uuid(client->data);
+	bt_ad_clear_service_uuid(ad);
 	return false;
 }
 
-static bool parse_solicit_uuids(DBusMessageIter *iter,
+static bool parse_service_uuids_ad(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	return parse_service_uuids(iter, client->data);
+}
+
+static bool parse_service_uuids_sr(DBusMessageIter *iter,
 					struct btd_adv_client *client)
+{
+	return parse_service_uuids(iter, client->scan);
+}
+
+static bool parse_solicit_uuids(DBusMessageIter *iter, struct bt_ad *ad)
 {
 	DBusMessageIter ariter;
 
 	if (!iter) {
-		bt_ad_clear_solicit_uuid(client->data);
+		bt_ad_clear_solicit_uuid(ad);
 		return true;
 	}
 
@@ -311,7 +321,7 @@  static bool parse_solicit_uuids(DBusMessageIter *iter,
 
 	dbus_message_iter_recurse(iter, &ariter);
 
-	bt_ad_clear_solicit_uuid(client->data);
+	bt_ad_clear_solicit_uuid(ad);
 
 	while (dbus_message_iter_get_arg_type(&ariter) == DBUS_TYPE_STRING) {
 		const char *uuid_str;
@@ -324,7 +334,7 @@  static bool parse_solicit_uuids(DBusMessageIter *iter,
 		if (bt_string_to_uuid(&uuid, uuid_str) < 0)
 			goto fail;
 
-		if (!bt_ad_add_solicit_uuid(client->data, &uuid))
+		if (!bt_ad_add_solicit_uuid(ad, &uuid))
 			goto fail;
 
 		dbus_message_iter_next(&ariter);
@@ -333,17 +343,28 @@  static bool parse_solicit_uuids(DBusMessageIter *iter,
 	return true;
 
 fail:
-	bt_ad_clear_solicit_uuid(client->data);
+	bt_ad_clear_solicit_uuid(ad);
 	return false;
 }
 
-static bool parse_manufacturer_data(DBusMessageIter *iter,
+static bool parse_solicit_uuids_ad(DBusMessageIter *iter,
 					struct btd_adv_client *client)
+{
+	return parse_solicit_uuids(iter, client->data);
+}
+
+static bool parse_solicit_uuids_sr(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	return parse_solicit_uuids(iter, client->scan);
+}
+
+static bool parse_manufacturer_data(DBusMessageIter *iter, struct bt_ad *ad)
 {
 	DBusMessageIter entries;
 
 	if (!iter) {
-		bt_ad_clear_manufacturer_data(client->data);
+		bt_ad_clear_manufacturer_data(ad);
 		return true;
 	}
 
@@ -352,7 +373,7 @@  static bool parse_manufacturer_data(DBusMessageIter *iter,
 
 	dbus_message_iter_recurse(iter, &entries);
 
-	bt_ad_clear_manufacturer_data(client->data);
+	bt_ad_clear_manufacturer_data(ad);
 
 	while (dbus_message_iter_get_arg_type(&entries)
 						== DBUS_TYPE_DICT_ENTRY) {
@@ -383,7 +404,7 @@  static bool parse_manufacturer_data(DBusMessageIter *iter,
 
 		DBG("Adding ManufacturerData for %04x", manuf_id);
 
-		if (!bt_ad_add_manufacturer_data(client->data, manuf_id,
+		if (!bt_ad_add_manufacturer_data(ad, manuf_id,
 							manuf_data, len))
 			goto fail;
 
@@ -393,17 +414,28 @@  static bool parse_manufacturer_data(DBusMessageIter *iter,
 	return true;
 
 fail:
-	bt_ad_clear_manufacturer_data(client->data);
+	bt_ad_clear_manufacturer_data(ad);
 	return false;
 }
 
-static bool parse_service_data(DBusMessageIter *iter,
+static bool parse_manufacturer_data_ad(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	return parse_manufacturer_data(iter, client->data);
+}
+
+static bool parse_manufacturer_data_sr(DBusMessageIter *iter,
 					struct btd_adv_client *client)
+{
+	return parse_manufacturer_data(iter, client->scan);
+}
+
+static bool parse_service_data(DBusMessageIter *iter, struct bt_ad *ad)
 {
 	DBusMessageIter entries;
 
 	if (!iter) {
-		bt_ad_clear_service_data(client->data);
+		bt_ad_clear_service_data(ad);
 		return true;
 	}
 
@@ -412,7 +444,7 @@  static bool parse_service_data(DBusMessageIter *iter,
 
 	dbus_message_iter_recurse(iter, &entries);
 
-	bt_ad_clear_service_data(client->data);
+	bt_ad_clear_service_data(ad);
 
 	while (dbus_message_iter_get_arg_type(&entries)
 						== DBUS_TYPE_DICT_ENTRY) {
@@ -447,7 +479,7 @@  static bool parse_service_data(DBusMessageIter *iter,
 
 		DBG("Adding ServiceData for %s", uuid_str);
 
-		if (!bt_ad_add_service_data(client->data, &uuid, service_data,
+		if (!bt_ad_add_service_data(ad, &uuid, service_data,
 									len))
 			goto fail;
 
@@ -457,10 +489,22 @@  static bool parse_service_data(DBusMessageIter *iter,
 	return true;
 
 fail:
-	bt_ad_clear_service_data(client->data);
+	bt_ad_clear_service_data(ad);
 	return false;
 }
 
+static bool parse_service_data_ad(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	return parse_service_data(iter, client->data);
+}
+
+static bool parse_service_data_sr(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	return parse_service_data(iter, client->scan);
+}
+
 static bool set_rsi(struct btd_adv_client *client)
 {
 	struct bt_crypto *crypto;
@@ -667,12 +711,12 @@  static bool parse_timeout(DBusMessageIter *iter,
 	return true;
 }
 
-static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
+static bool parse_data(DBusMessageIter *iter, struct bt_ad *ad)
 {
 	DBusMessageIter entries;
 
 	if (!iter) {
-		bt_ad_clear_data(client->data);
+		bt_ad_clear_data(ad);
 		return true;
 	}
 
@@ -681,7 +725,7 @@  static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
 
 	dbus_message_iter_recurse(iter, &entries);
 
-	bt_ad_clear_data(client->data);
+	bt_ad_clear_data(ad);
 
 	while (dbus_message_iter_get_arg_type(&entries)
 						== DBUS_TYPE_DICT_ENTRY) {
@@ -712,7 +756,7 @@  static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
 
 		DBG("Adding Data for type 0x%02x len %u", type, len);
 
-		if (!bt_ad_add_data(client->data, type, data, len))
+		if (!bt_ad_add_data(ad, type, data, len))
 			goto fail;
 
 		dbus_message_iter_next(&entries);
@@ -721,10 +765,22 @@  static bool parse_data(DBusMessageIter *iter, struct btd_adv_client *client)
 	return true;
 
 fail:
-	bt_ad_clear_data(client->data);
+	bt_ad_clear_data(ad);
 	return false;
 }
 
+static bool parse_data_ad(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	return parse_data(iter, client->data);
+}
+
+static bool parse_data_sr(DBusMessageIter *iter,
+					struct btd_adv_client *client)
+{
+	return parse_data(iter, client->scan);
+}
+
 static bool set_flags(struct btd_adv_client *client, uint8_t flags)
 {
 	/* Set BR/EDR Not Supported for LE only */
@@ -832,15 +888,14 @@  static uint8_t *generate_adv_data(struct btd_adv_client *client,
 static uint8_t *generate_scan_rsp(struct btd_adv_client *client,
 						uint32_t *flags, size_t *len)
 {
-	if (!client->name) {
+	if (client->name) {
+		*flags &= ~MGMT_ADV_FLAG_LOCAL_NAME;
+		bt_ad_add_name(client->scan, client->name);
+	} else if (bt_ad_is_empty(client->scan)) {
 		*len = 0;
 		return NULL;
 	}
 
-	*flags &= ~MGMT_ADV_FLAG_LOCAL_NAME;
-
-	bt_ad_add_name(client->scan, client->name);
-
 	return bt_ad_generate(client->scan, len);
 }
 
@@ -1212,16 +1267,21 @@  static struct adv_parser {
 	bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
 } parsers[] = {
 	{ "Type", parse_type },
-	{ "ServiceUUIDs", parse_service_uuids },
-	{ "SolicitUUIDs", parse_solicit_uuids },
-	{ "ManufacturerData", parse_manufacturer_data },
-	{ "ServiceData", parse_service_data },
+	{ "ServiceUUIDs", parse_service_uuids_ad },
+	{ "ScanResponseServiceUUIDs", parse_service_uuids_sr },
+	{ "SolicitUUIDs", parse_solicit_uuids_ad },
+	{ "ScanResponseSolicitUUIDs", parse_solicit_uuids_sr },
+	{ "ManufacturerData", parse_manufacturer_data_ad },
+	{ "ScanResponseManufacturerData", parse_manufacturer_data_sr },
+	{ "ServiceData", parse_service_data_ad },
+	{ "ScanResponseServiceData", parse_service_data_sr },
 	{ "Includes", parse_includes },
 	{ "LocalName", parse_local_name },
 	{ "Appearance", parse_appearance },
 	{ "Duration", parse_duration },
 	{ "Timeout", parse_timeout },
-	{ "Data", parse_data },
+	{ "Data", parse_data_ad },
+	{ "ScanResponseData", parse_data_sr },
 	{ "Discoverable", parse_discoverable },
 	{ "DiscoverableTimeout", parse_discoverable_timeout },
 	{ "SecondaryChannel", parse_secondary },