Bluetooth: Add LE device found MGMT event
authorSudha Bheemanna <b.sudha@samsung.com>
Thu, 8 Sep 2016 04:40:03 +0000 (10:10 +0530)
committerJaehoon Chung <jh80.chung@samsung.com>
Tue, 12 Nov 2024 04:03:11 +0000 (13:03 +0900)
This patch adds new MGMT event for LE device discovery and allows
the handling of all advertisement packets in platform.

Change-Id: Ifff3ccb291a3a0fc23256763e089613ee4efbec4
Signed-off-by: Sudha Bheemanna <b.sudha@samsung.com>
Signed-off-by: Amit Purwar <amit.purwar@samsung.com>
Signed-off-by: Wootak Jung <wootak.jung@samsung.com>
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/mgmt_tizen.h
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c

index 62b265ba2190ae8154f74236e7523af937d8b5f5..19c322172a2c1ab739ea87b41976d8eda05d6f2f 100644 (file)
@@ -2603,6 +2603,13 @@ struct hci_ev_vendor_specific_rssi_alert {
        __s8    alert_type;
        __s8    rssi_dbm;
 } __packed;
+
+#define LE_MULTI_ADV_STATE_CHANGE_SUB_EVENT 0x55
+struct hci_ev_vendor_specific_multi_adv_state {
+       __u8    adv_instance;
+       __u8    state_change_reason;
+       __le16  connection_handle;
+} __packed;
 #endif
 
 #define HCI_EV_LE_CONN_COMPLETE                0x01
index d53b7c78e30560fc46aaaeb7531ab90e70b9fefb..f8c71af3aab1392f35f5dbe90aa6beffcf3ab316 100644 (file)
@@ -2394,6 +2394,12 @@ int mgmt_le_conn_update_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
                u8 link_type, u8 addr_type, u8 status);
 void mgmt_hardware_error(struct hci_dev *hdev, u8 err_code);
 void mgmt_tx_timeout_error(struct hci_dev *hdev);
+/*  Pass adv type in the le device found */
+void mgmt_le_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
+               u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, u8 *eir,
+               u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len, u8 adv_type);
+void mgmt_multi_adv_state_change_evt(struct hci_dev *hdev, u8 adv_instance,
+               u8 state_change_reason, u16 connection_handle);
 #endif
 
 int hci_abort_conn(struct hci_conn *conn, u8 reason);
index fd5a9fe3f39089ac5bb71d47b2e638f945b04768..504c2d47b07d4dd9c6a4b717a7abb385fc24a2ed 100644 (file)
@@ -211,4 +211,26 @@ struct mgmt_ev_conn_update_failed {
 } __packed;
 /* Add LE connection update Events */
 
+/* For LE device found event */
+#define MGMT_EV_LE_DEVICE_FOUND                        (TIZEN_EV_BASE + 0x0a)
+struct mgmt_ev_le_device_found {
+       struct  mgmt_addr_info addr;
+       __s8    rssi;
+       __le32  flags;
+       __s8    adv_type;
+       __le16  eir_len;
+       __u8    eir[0];
+} __packed;
+/* LE device found event */
+
+/* For LE advertisement state changed event */
+#define MGMT_EV_MULTI_ADV_STATE_CHANGED                (TIZEN_EV_BASE + 0x0b)
+struct mgmt_ev_vendor_specific_multi_adv_state_changed {
+       __u8    adv_instance;
+       __u8    state_change_reason;
+       __le16  connection_handle;
+} __packed;
+/* LE advertisement state changed event */
+
+
 #endif /* __MGMT_TIZEN_H */
index 4001c11f73140257f7645d1fbd6366cee46eacc4..98d3ad57a1bf75cdc82cbd545c8806a8f18fb95e 100644 (file)
@@ -1698,6 +1698,7 @@ static void clear_pending_adv_report(struct hci_dev *hdev)
        d->last_adv_data_len = 0;
 }
 
+#ifndef TIZEN_BT
 static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
                                     u8 bdaddr_type, s8 rssi, u32 flags,
                                     u8 *data, u8 len)
@@ -1714,6 +1715,7 @@ static void store_pending_adv_report(struct hci_dev *hdev, bdaddr_t *bdaddr,
        memcpy(d->last_adv_data, data, len);
        d->last_adv_data_len = len;
 }
+#endif
 
 static void le_set_scan_enable_complete(struct hci_dev *hdev, u8 enable)
 {
@@ -6112,10 +6114,13 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
                               u8 direct_addr_type, s8 rssi, u8 *data, u8 len,
                               bool ext_adv, bool ctl_time, u64 instant)
 {
+#ifndef TIZEN_BT
        struct discovery_state *d = &hdev->discovery;
+       bool match;
+#endif
        struct smp_irk *irk;
        struct hci_conn *conn;
-       bool match, bdaddr_resolved;
+       bool bdaddr_resolved;
        u32 flags;
        u8 *ptr;
 
@@ -6228,13 +6233,21 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
                if (type == LE_ADV_DIRECT_IND)
                        return;
 
+#ifndef TIZEN_BT
+               /* Handle all adv packet in platform */
                if (!hci_pend_le_action_lookup(&hdev->pend_le_reports,
                                               bdaddr, bdaddr_type) &&
                    idr_is_empty(&hdev->adv_monitors_idr))
                        return;
+#endif
 
+#ifdef TIZEN_BT
+               mgmt_le_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
+                                 rssi, flags, data, len, NULL, 0, type);
+#else
                mgmt_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
                                  rssi, flags, data, len, NULL, 0, 0);
+#endif
                return;
        }
 
@@ -6251,6 +6264,11 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
        if (type == LE_ADV_SCAN_RSP)
                flags = MGMT_DEV_FOUND_SCAN_RSP;
 
+#ifdef TIZEN_BT
+       /* Disable adv ind and scan rsp merging */
+       mgmt_le_device_found(hdev, bdaddr, LE_LINK, bdaddr_type, NULL,
+                                 rssi, flags, data, len, NULL, 0, type);
+#else
        /* If there's nothing pending either store the data from this
         * event or send an immediate device found event if the data
         * should not be stored for later.
@@ -6314,6 +6332,7 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
                          d->last_adv_addr_type, NULL, rssi, d->last_adv_flags,
                          d->last_adv_data, d->last_adv_data_len, data, len, 0);
        clear_pending_adv_report(hdev);
+#endif
 }
 
 static void hci_le_adv_report_evt(struct hci_dev *hdev, void *data,
index a9fdbe39555ada6100a9cdccb4ba9f97f3f64a76..f1ce3de0795e4fae61e78d27898d759bbdb86be1 100644 (file)
@@ -9750,6 +9750,48 @@ int mgmt_le_conn_updated(struct hci_dev *hdev, bdaddr_t *bdaddr,
        return mgmt_event(MGMT_EV_CONN_UPDATED, hdev,
                                &ev, sizeof(ev), NULL);
 }
+
+/* le device found event - Pass adv type */
+void mgmt_le_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
+               u8 addr_type, u8 *dev_class, s8 rssi, u32 flags, u8 *eir,
+               u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len, u8 adv_type)
+{
+       char buf[512];
+       struct mgmt_ev_le_device_found *ev = (void *)buf;
+       size_t ev_size;
+
+       if (!hci_discovery_active(hdev) && !hci_le_discovery_active(hdev))
+               return;
+
+       /* Make sure that the buffer is big enough. The 5 extra bytes
+        * are for the potential CoD field.
+        */
+       if (sizeof(*ev) + eir_len + scan_rsp_len + 5 > sizeof(buf))
+               return;
+
+       memset(buf, 0, sizeof(buf));
+
+       bacpy(&ev->addr.bdaddr, bdaddr);
+       ev->addr.type = link_to_bdaddr(link_type, addr_type);
+       ev->rssi = rssi;
+       ev->flags = cpu_to_le32(flags);
+       ev->adv_type = adv_type;
+
+       if (eir_len > 0)
+               memcpy(ev->eir, eir, eir_len);
+
+       if (dev_class && !eir_get_data(ev->eir, eir_len, EIR_CLASS_OF_DEV, NULL))
+               eir_len = eir_append_data(ev->eir, eir_len, EIR_CLASS_OF_DEV,
+                                         dev_class, 3);
+
+       if (scan_rsp_len > 0)
+               memcpy(ev->eir + eir_len, scan_rsp, scan_rsp_len);
+
+       ev->eir_len = cpu_to_le16(eir_len + scan_rsp_len);
+       ev_size = sizeof(*ev) + eir_len + scan_rsp_len;
+
+       mgmt_event(MGMT_EV_LE_DEVICE_FOUND, hdev, ev, ev_size, NULL);
+}
 #endif
 
 static void read_local_oob_ext_data_complete(struct hci_dev *hdev, void *data,