advertising: Fix attempting to set scan_rsp
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Tue, 14 Jun 2022 18:38:56 +0000 (11:38 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Mon, 15 May 2023 09:25:54 +0000 (14:55 +0530)
BLUETOOTH CORE SPECIFICATION Version 5.3 | Vol 4, Part E page 2450

  • If extended advertising PDU types are being used (bit 4 = 0) then:
  The advertisement shall not be both connectable and scannable.

So instead this attempts to set name as part of Advertising Data rather
then setting it as Scan Response:

bluetoothctl> advertise.secondary 2M
bluetoothctl> advertise.name Intel-3
bluetoothctl> advertise on

< HCI Command: LE Set Extended Advertising Parameters (0x08|0x0036) plen 25
        Handle: 0x01
        Properties: 0x0001
          Connectable
        Min advertising interval: 1280.000 msec (0x0800)
        Max advertising interval: 1280.000 msec (0x0800)
        Channel map: 37, 38, 39 (0x07)
        Own address type: Public (0x00)
        Peer address type: Public (0x00)
        Peer address: 00:00:00:00:00:00 (OUI 00-00-00)
        Filter policy: Allow Scan Request from Any, Allow Connect Request from Any (0x00)
        TX power: Host has no preference (0x7f)
        Primary PHY: LE 1M (0x01)
        Secondary max skip: 0x00
        Secondary PHY: LE 2M (0x02)
        SID: 0x00
        Scan request notifications: Disabled (0x00)
> HCI Event: Command Complete (0x0e) plen 5
      LE Set Extended Advertising Parameters (0x08|0x0036) ncmd 1
        Status: Success (0x00)
        TX power (selected): 7 dbm (0x07)
< HCI Command: LE Set Extended Advertising Data (0x08|0x0037) plen 4
        Handle: 0x01
        Operation: Complete extended advertising data (0x03)
        Fragment preference: Minimize fragmentation (0x01)
        Data length: 0x00
@ MGMT Event: Command Complete (0x0001) plen 7
      Add Extended Advertising Parameters (0x0054) plen 4
        Status: Success (0x00)
        Instance: 1
        TX power: 7 dbm (0x07)
        Available adv data len: 31
        Available scan rsp data len: 31
> HCI Event: Command Complete (0x0e) plen 4
      LE Set Extended Advertising Data (0x08|0x0037) ncmd 1
        Status: Success (0x00)
@ MGMT Command: Add Extended Advertising Data (0x0055) plen 23
        Instance: 1
        Advertising data length: 12
        Name (complete): Intel-3
        Flags: 0x06
          LE General Discoverable Mode
          BR/EDR Not Supported
        Scan response length: 0
< HCI Command: LE Set Extended Advertising Data (0x08|0x0037) plen 16
        Handle: 0x01
        Operation: Complete extended advertising data (0x03)
        Fragment preference: Minimize fragmentation (0x01)
        Data length: 0x0c
        Name (complete): Intel-3
        Flags: 0x06
          LE General Discoverable Mode
          BR/EDR Not Supported
> HCI Event: Command Complete (0x0e) plen 4
      LE Set Extended Advertising Data (0x08|0x0037) ncmd 1
        Status: Success (0x00)
< HCI Command: LE Set Extended Scan Response Data (0x08|0x0038) plen 4
        Handle: 0x01
        Operation: Complete scan response data (0x03)
        Fragment preference: Minimize fragmentation (0x01)
        Data length: 0x00
> HCI Event: Command Complete (0x0e) plen 4
      LE Set Extended Scan Response Data (0x08|0x0038) ncmd 1
        Status: Success (0x00)
< HCI Command: LE Set Extended Advertising Enable (0x08|0x0039) plen 6
        Extended advertising: Enabled (0x01)
        Number of sets: 1 (0x01)
        Entry 0
          Handle: 0x01
          Duration: 0 ms (0x00)
          Max ext adv events: 0
> HCI Event: Command Complete (0x0e) plen 4
      LE Set Extended Advertising Enable (0x08|0x0039) ncmd 2
        Status: Success (0x00)
@ MGMT Event: Command Complete (0x0001) plen 4
      Add Extended Advertising Data (0x0055) plen 1
        Status: Success (0x00)
        Instance: 1

Signed-off-by: Manika Shrivastava <manika.sh@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
lib/mgmt.h
src/advertising.c

index fcef9e1..7f9df86 100644 (file)
@@ -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;
index b0e46d1..78645d5 100644 (file)
@@ -771,6 +771,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);
 }
 
@@ -802,6 +814,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;
 }
 
@@ -1245,7 +1266,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;
@@ -1276,11 +1297,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 +
@@ -1296,7 +1319,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);