summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/mgmt.h3
-rw-r--r--src/advertising.c39
2 files changed, 35 insertions, 7 deletions
diff --git a/lib/mgmt.h b/lib/mgmt.h
index 922a24367..430bd0ef6 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -511,6 +511,9 @@ struct mgmt_rp_add_advertising {
#define MGMT_ADV_PARAM_TX_POWER (1 << 15)
#define MGMT_ADV_PARAM_SCAN_RSP (1 << 16)
+#define MGMT_ADV_FLAG_SEC_MASK (MGMT_ADV_FLAG_SEC_1M | MGMT_ADV_FLAG_SEC_2M | \
+ MGMT_ADV_FLAG_SEC_CODED)
+
#define MGMT_OP_REMOVE_ADVERTISING 0x003F
struct mgmt_cp_remove_advertising {
uint8_t instance;
diff --git a/src/advertising.c b/src/advertising.c
index ca23774ba..1fe371a9f 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -776,6 +776,18 @@ static uint8_t *generate_adv_data(struct btd_adv_client *client,
bt_ad_add_appearance(client->data, appearance);
}
+ /* Scan response shall not be used when connectable and setting a
+ * secondary PHY since that would end up using EA types instead of
+ * legacy which doesn't support being connectable and scannable
+ * simultaneously.
+ */
+ if ((*flags & MGMT_ADV_FLAG_CONNECTABLE) &&
+ (*flags & MGMT_ADV_FLAG_SEC_MASK) &&
+ client->name) {
+ *flags &= ~MGMT_ADV_FLAG_LOCAL_NAME;
+ bt_ad_add_name(client->data, client->name);
+ }
+
return bt_ad_generate(client->data, len);
}
@@ -807,6 +819,15 @@ static bool adv_client_has_scan_response(struct btd_adv_client *client,
return false;
}
+ /* Scan response shall not be used when connectable and setting a
+ * secondary PHY since that would end up using EA types instead of
+ * legacy which doesn't support being connectable and scannable
+ * simultaneously.
+ */
+ if (flags & MGMT_ADV_FLAG_CONNECTABLE &&
+ flags & MGMT_ADV_FLAG_SEC_MASK)
+ return false;
+
return true;
}
@@ -1250,7 +1271,7 @@ static void add_adv_params_callback(uint8_t status, uint16_t length,
uint8_t *adv_data = NULL;
size_t adv_data_len;
uint8_t *scan_rsp = NULL;
- size_t scan_rsp_len = -1;
+ size_t scan_rsp_len = 0;
uint32_t flags = 0;
unsigned int mgmt_ret;
dbus_int16_t tx_power;
@@ -1281,11 +1302,13 @@ static void add_adv_params_callback(uint8_t status, uint16_t length,
goto fail;
}
- scan_rsp = generate_scan_rsp(client, &flags, &scan_rsp_len);
- if ((!scan_rsp && scan_rsp_len) ||
- scan_rsp_len > rp->max_scan_rsp_len) {
- error("Scan data couldn't be generated.");
- goto fail;
+ if (adv_client_has_scan_response(client, flags)) {
+ scan_rsp = generate_scan_rsp(client, &flags, &scan_rsp_len);
+ if ((!scan_rsp && scan_rsp_len) ||
+ scan_rsp_len > rp->max_scan_rsp_len) {
+ error("Scan data couldn't be generated.");
+ goto fail;
+ }
}
param_len = sizeof(struct mgmt_cp_add_advertising) + adv_data_len +
@@ -1301,7 +1324,9 @@ static void add_adv_params_callback(uint8_t status, uint16_t length,
cp->adv_data_len = adv_data_len;
cp->scan_rsp_len = scan_rsp_len;
memcpy(cp->data, adv_data, adv_data_len);
- memcpy(cp->data + adv_data_len, scan_rsp, scan_rsp_len);
+
+ if (scan_rsp)
+ memcpy(cp->data + adv_data_len, scan_rsp, scan_rsp_len);
free(adv_data);
free(scan_rsp);