From: Sudha Bheemanna Date: Thu, 8 Sep 2016 04:40:03 +0000 (+0530) Subject: Bluetooth: Add LE device found MGMT event X-Git-Tag: accepted/tizen/unified/toolchain/20240311.065846~102 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=271922818e938b1583a0bb704245ea38893b1810;p=platform%2Fkernel%2Flinux-starfive.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 Signed-off-by: Wootak Jung --- diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 6640c46..de473e2 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -2690,6 +2690,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 44bef8e..02588f4 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -2391,6 +2391,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); 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 c53bdb0..9f69420 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -1759,6 +1759,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) @@ -1775,6 +1776,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) { @@ -6380,10 +6382,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; @@ -6496,13 +6501,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; } @@ -6519,6 +6532,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. @@ -6582,6 +6600,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, diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 52d4ecd..ccbe063 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -9804,6 +9804,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,