From: Sudha Bheemanna Date: Thu, 8 Sep 2016 04:40:03 +0000 (+0530) Subject: Bluetooth: Add LE device found MGMT event X-Git-Tag: submit/tizen/20220208.074352~240 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=10ab62e5e18cdbc760d9d611cd3ad702b233bebf;p=platform%2Fkernel%2Flinux-rpi.git Bluetooth: Add LE device found MGMT event This patch adds new MGMT event for LE device discovery and allows the handling of all advertisement packets in platform. Change-Id: I1927acb75eff0b60a5899898c6d7a000e1a108ef Signed-off-by: Sudha Bheemanna Signed-off-by: Amit Purwar --- diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 8e9cab8..eaa013c 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -2331,6 +2331,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 diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 7a59470..9cdcd22 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1887,6 +1887,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 u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, diff --git a/include/net/bluetooth/mgmt_tizen.h b/include/net/bluetooth/mgmt_tizen.h index fd5a9fe..504c2d4 100644 --- a/include/net/bluetooth/mgmt_tizen.h +++ b/include/net/bluetooth/mgmt_tizen.h @@ -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 */ diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 4aa90b9..bdd4b04 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1332,6 +1332,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) @@ -1348,6 +1349,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) { @@ -5571,10 +5573,14 @@ 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) { +#ifndef TIZEN_BT struct discovery_state *d = &hdev->discovery; +#endif struct smp_irk *irk; struct hci_conn *conn; +#ifndef TIZEN_BT bool match; +#endif u32 flags; u8 *ptr; @@ -5668,17 +5674,25 @@ 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 if (type == LE_ADV_NONCONN_IND || type == LE_ADV_SCAN_IND) flags = MGMT_DEV_FOUND_NOT_CONNECTABLE; else flags = 0; +#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); +#endif return; } @@ -5703,6 +5717,11 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr, else flags = 0; +#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. @@ -5766,6 +5785,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); clear_pending_adv_report(hdev); +#endif } static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index d932b48..ee76377 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -8642,6 +8642,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, u8 status,