Bluetooth: Handle ADv set terminated event
authorJaganath Kanakkassery <jaganath.k.os@gmail.com>
Thu, 19 Jul 2018 11:39:46 +0000 (17:09 +0530)
committerMarcel Holtmann <marcel@holtmann.org>
Mon, 30 Jul 2018 11:44:53 +0000 (13:44 +0200)
This event comes after connection complete event for incoming
connections. Since we now have different random address for
each instance, conn resp address is assigned from this event.

As of now only connection part is handled as we are not
enabling duration or max num of events while starting ext adv.

Signed-off-by: Jaganath Kanakkassery <jaganathx.kanakkassery@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/hci.h
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c

index 8d348d0d3eea9738ac4b12f1d9d8b7f310bf9a5e..57e3e3675d664dff2b09e2ea43b7645fc487ec4c 100644 (file)
@@ -2155,6 +2155,14 @@ struct hci_ev_le_enh_conn_complete {
        __u8      clk_accurancy;
 } __packed;
 
+#define HCI_EV_LE_EXT_ADV_SET_TERM     0x12
+struct hci_evt_le_ext_adv_set_term {
+       __u8    status;
+       __u8    handle;
+       __le16  conn_handle;
+       __u8    num_evts;
+} __packed;
+
 /* Internal events generated by Bluetooth stack */
 #define HCI_EV_STACK_INTERNAL  0xfd
 struct hci_ev_stack_internal {
index 840e8fd89fa5c5f36a324d97be8026e453a1ba67..79e02d24a215782f0143cef05573a619fdae3eb4 100644 (file)
@@ -712,6 +712,14 @@ static int hci_init3_req(struct hci_request *req, unsigned long opt)
                                                 * Complete
                                                 */
 
+               /* If the controller supports the LE Extended Advertising
+                * command, enable the corresponding event.
+                */
+               if (ext_adv_capable(hdev))
+                       events[2] |= 0x02;      /* LE Advertising Set
+                                                * Terminated
+                                                */
+
                hci_req_add(req, HCI_OP_LE_SET_EVENT_MASK, sizeof(events),
                            events);
 
index 392c9d8febd08da7b8a10ecfdc14911d1483a77d..754714c8d75288bc90c459bf4a659ac2e719ed7a 100644 (file)
@@ -4798,10 +4798,15 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
                 * the advertising address type.
                 */
                conn->resp_addr_type = hdev->adv_addr_type;
-               if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM)
-                       bacpy(&conn->resp_addr, &hdev->random_addr);
-               else
+               if (hdev->adv_addr_type == ADDR_LE_DEV_RANDOM) {
+                       /* In case of ext adv, resp_addr will be updated in
+                        * Adv Terminated event.
+                        */
+                       if (!ext_adv_capable(hdev))
+                               bacpy(&conn->resp_addr, &hdev->random_addr);
+               } else {
                        bacpy(&conn->resp_addr, &hdev->bdaddr);
+               }
 
                conn->init_addr_type = bdaddr_type;
                bacpy(&conn->init_addr, bdaddr);
@@ -4931,6 +4936,34 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev,
                             le16_to_cpu(ev->supervision_timeout));
 }
 
+static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+       struct hci_evt_le_ext_adv_set_term *ev = (void *) skb->data;
+       struct hci_conn *conn;
+
+       BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+
+       if (ev->status)
+               return;
+
+       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->conn_handle));
+       if (conn) {
+               struct adv_info *adv_instance;
+
+               if (hdev->adv_addr_type != ADDR_LE_DEV_RANDOM)
+                       return;
+
+               if (!hdev->cur_adv_instance) {
+                       bacpy(&conn->resp_addr, &hdev->random_addr);
+                       return;
+               }
+
+               adv_instance = hci_find_adv_instance(hdev, hdev->cur_adv_instance);
+               if (adv_instance)
+                       bacpy(&conn->resp_addr, &adv_instance->random_addr);
+       }
+}
+
 static void hci_le_conn_update_complete_evt(struct hci_dev *hdev,
                                            struct sk_buff *skb)
 {
@@ -5578,6 +5611,10 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
                hci_le_enh_conn_complete_evt(hdev, skb);
                break;
 
+       case HCI_EV_LE_EXT_ADV_SET_TERM:
+               hci_le_ext_adv_term_evt(hdev, skb);
+               break;
+
        default:
                break;
        }