diff --git a/src/advertising.c b/src/advertising.c
index 2fc6f91..4476d7c 100644
--- a/src/advertising.c
+++ b/src/advertising.c
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;
}
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;
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);
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;
}
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;
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);
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;
}
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) {
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;
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;
}
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) {
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;
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;
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;
}
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) {
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);
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 */
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);
}
static struct adv_parser {
const char *name;
bool (*func)(DBusMessageIter *iter, struct btd_adv_client *client);
+ bool experimental;
} 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, true },
+ { "SolicitUUIDs", parse_solicit_uuids_ad },
+ { "ScanResponseSolicitUUIDs", parse_solicit_uuids_sr, true },
+ { "ManufacturerData", parse_manufacturer_data_ad },
+ { "ScanResponseManufacturerData", parse_manufacturer_data_sr, true },
+ { "ServiceData", parse_service_data_ad },
+ { "ScanResponseServiceData", parse_service_data_sr, true },
{ "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 },
if (strcmp(parser->name, name))
continue;
+ /* Ignore experimental parsers if the experimental flag is not
+ * set.
+ */
+ if (parser->experimental && !(g_dbus_get_flags() &
+ G_DBUS_FLAG_ENABLE_EXPERIMENTAL))
+ continue;
+
if (parser->func(iter, client)) {
refresh_advertisement(client, NULL);