Bluetooth : fix build error
[platform/kernel/linux-starfive.git] / net / bluetooth / hci_event.c
index 43b1b8e..d219042 100644 (file)
@@ -159,6 +159,10 @@ static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
        struct hci_rp_write_link_policy *rp = (void *) skb->data;
        struct hci_conn *conn;
        void *sent;
+#ifdef TIZEN_BT
+       struct hci_cp_write_link_policy cp;
+       struct hci_conn *sco_conn;
+#endif
 
        BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
@@ -175,6 +179,17 @@ static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
        if (conn)
                conn->link_policy = get_unaligned_le16(sent + 2);
 
+#ifdef TIZEN_BT
+       sco_conn = hci_conn_hash_lookup_sco(hdev);
+       if (sco_conn && bacmp(&sco_conn->dst, &conn->dst) == 0 &&
+           conn->link_policy & HCI_LP_SNIFF) {
+               BT_ERR("SNIFF is not allowed during sco connection");
+               cp.handle = __cpu_to_le16(conn->handle);
+               cp.policy = __cpu_to_le16(conn->link_policy & ~HCI_LP_SNIFF);
+               hci_send_cmd(hdev, HCI_OP_WRITE_LINK_POLICY, sizeof(cp), &cp);
+       }
+#endif
+
        hci_dev_unlock(hdev);
 }
 
@@ -1410,6 +1425,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)
@@ -1426,6 +1442,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)
 {
@@ -1622,11 +1639,21 @@ static void hci_cc_le_read_def_data_len(struct hci_dev *hdev,
 
        BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
+#ifdef TIZEN_BT
+       hci_dev_lock(hdev);
+#else
        if (rp->status)
                return;
+#endif
 
        hdev->le_def_tx_len = le16_to_cpu(rp->tx_len);
        hdev->le_def_tx_time = le16_to_cpu(rp->tx_time);
+
+#ifdef TIZEN_BT
+       mgmt_le_read_host_suggested_data_length_complete(hdev, rp->status);
+
+       hci_dev_unlock(hdev);
+#endif
 }
 
 static void hci_cc_le_write_def_data_len(struct hci_dev *hdev,
@@ -1638,14 +1665,27 @@ static void hci_cc_le_write_def_data_len(struct hci_dev *hdev,
        BT_DBG("%s status 0x%2.2x", hdev->name, status);
 
        if (status)
+#ifndef TIZEN_BT
                return;
+#else
+               goto unblock;
+#endif
 
        sent = hci_sent_cmd_data(hdev, HCI_OP_LE_WRITE_DEF_DATA_LEN);
        if (!sent)
+#ifndef TIZEN_BT
                return;
+#else
+               goto unblock;
+#endif
 
        hdev->le_def_tx_len = le16_to_cpu(sent->tx_len);
        hdev->le_def_tx_time = le16_to_cpu(sent->tx_time);
+
+#ifdef TIZEN_BT
+unblock:
+       mgmt_le_write_host_suggested_data_length_complete(hdev, status);
+#endif
 }
 
 static void hci_cc_le_add_to_resolv_list(struct hci_dev *hdev,
@@ -1744,13 +1784,22 @@ static void hci_cc_le_read_max_data_len(struct hci_dev *hdev,
 
        BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
+#ifndef TIZEN_BT
        if (rp->status)
                return;
+#else
+       hci_dev_lock(hdev);
+#endif
 
        hdev->le_max_tx_len = le16_to_cpu(rp->tx_len);
        hdev->le_max_tx_time = le16_to_cpu(rp->tx_time);
        hdev->le_max_rx_len = le16_to_cpu(rp->rx_len);
        hdev->le_max_rx_time = le16_to_cpu(rp->rx_time);
+
+#ifdef TIZEN_BT
+       mgmt_le_read_maximum_data_length_complete(hdev, rp->status);
+       hci_dev_unlock(hdev);
+#endif
 }
 
 static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
@@ -1860,6 +1909,17 @@ static void hci_cc_get_raw_rssi(struct hci_dev *hdev,
        mgmt_raw_rssi_response(hdev, rp, rp->status);
 }
 
+static void hci_vendor_ext_rssi_link_alert_evt(struct hci_dev *hdev,
+                                              struct sk_buff *skb)
+{
+       struct hci_ev_vendor_specific_rssi_alert *ev = (void *)skb->data;
+
+       BT_DBG("RSSI event LE_RSSI_LINK_ALERT %X", LE_RSSI_LINK_ALERT);
+
+       mgmt_rssi_alert_evt(hdev, ev->conn_handle, ev->alert_type,
+                           ev->rssi_dbm);
+}
+
 static void hci_vendor_specific_group_ext_evt(struct hci_dev *hdev,
                                              struct sk_buff *skb)
 {
@@ -1874,9 +1934,7 @@ static void hci_vendor_specific_group_ext_evt(struct hci_dev *hdev,
 
        switch (event_le_ext_sub_code) {
        case LE_RSSI_LINK_ALERT:
-               BT_DBG("RSSI event LE_RSSI_LINK_ALERT %X",
-                      LE_RSSI_LINK_ALERT);
-               mgmt_rssi_alert_evt(hdev, skb);
+               hci_vendor_ext_rssi_link_alert_evt(hdev, skb);
                break;
 
        default:
@@ -1884,6 +1942,18 @@ static void hci_vendor_specific_group_ext_evt(struct hci_dev *hdev,
        }
 }
 
+static void hci_vendor_multi_adv_state_change_evt(struct hci_dev *hdev,
+                                                 struct sk_buff *skb)
+{
+       struct hci_ev_vendor_specific_multi_adv_state *ev = (void *)skb->data;
+
+       BT_DBG("LE_MULTI_ADV_STATE_CHANGE_SUB_EVENT");
+
+       mgmt_multi_adv_state_change_evt(hdev, ev->adv_instance,
+                                       ev->state_change_reason,
+                                       ev->connection_handle);
+}
+
 static void hci_vendor_specific_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_vendor_specific *ev = (void *)skb->data;
@@ -1899,10 +1969,39 @@ static void hci_vendor_specific_evt(struct hci_dev *hdev, struct sk_buff *skb)
                hci_vendor_specific_group_ext_evt(hdev, skb);
                break;
 
+       case LE_MULTI_ADV_STATE_CHANGE_SUB_EVENT:
+               hci_vendor_multi_adv_state_change_evt(hdev, skb);
+               break;
+
        default:
                break;
        }
 }
+
+static void hci_le_data_length_changed_complete_evt(struct hci_dev *hdev,
+               struct sk_buff *skb)
+{
+       struct hci_ev_le_data_len_change *ev = (void *)skb->data;
+       struct hci_conn *conn;
+
+       BT_DBG("%s status", hdev->name);
+
+       hci_dev_lock(hdev);
+
+       conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+       if (conn) {
+               conn->tx_len = le16_to_cpu(ev->tx_len);
+               conn->tx_time = le16_to_cpu(ev->tx_time);
+               conn->rx_len = le16_to_cpu(ev->rx_len);
+               conn->rx_time = le16_to_cpu(ev->rx_time);
+
+               mgmt_le_data_length_change_complete(hdev, &conn->dst,
+                                           conn->tx_len, conn->tx_time,
+                                           conn->rx_len, conn->rx_time);
+       }
+
+       hci_dev_unlock(hdev);
+}
 #endif
 
 static void hci_cc_read_rssi(struct hci_dev *hdev, struct sk_buff *skb)
@@ -2184,7 +2283,7 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
        if (conn &&
            (conn->state == BT_CONFIG || conn->state == BT_CONNECTED)) {
                if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
-                       mgmt_device_connected(hdev, conn, 0, name, name_len);
+                       mgmt_device_connected(hdev, conn, name, name_len);
                else
                        mgmt_device_name_update(hdev, bdaddr, name, name_len);
        }
@@ -2812,6 +2911,11 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
                        hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
                                     &cp);
                }
+#ifdef TIZEN_BT
+               if (get_link_mode(conn) & HCI_LM_MASTER)
+                       hci_conn_change_supervision_timeout(conn,
+                                       LINK_SUPERVISION_TIMEOUT);
+#endif
        } else {
                conn->state = BT_CLOSED;
                if (conn->type == ACL_LINK)
@@ -2896,6 +3000,20 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
        if (ie)
                memcpy(ie->data.dev_class, ev->dev_class, 3);
 
+#ifdef TIZEN_BT
+               if ((ev->link_type == SCO_LINK || ev->link_type == ESCO_LINK) &&
+                   hci_conn_hash_lookup_sco(hdev)) {
+                       struct hci_cp_reject_conn_req cp;
+
+                       bacpy(&cp.bdaddr, &ev->bdaddr);
+                       cp.reason = HCI_ERROR_REJ_LIMITED_RESOURCES;
+                       hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ,
+                                    sizeof(cp), &cp);
+                       hci_dev_unlock(hdev);
+                       return;
+               }
+#endif
+
        conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
                        &ev->bdaddr);
        if (!conn) {
@@ -3050,6 +3168,22 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
        hci_conn_del(conn);
 
+#ifdef TIZEN_BT
+       if (conn->type == ACL_LINK && !hci_conn_num(hdev, ACL_LINK)) {
+               int iscan;
+               int pscan;
+
+               iscan = test_bit(HCI_ISCAN, &hdev->flags);
+               pscan = test_bit(HCI_PSCAN, &hdev->flags);
+               if (!iscan && !pscan) {
+                       u8 scan_enable = SCAN_PAGE;
+
+                       hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE,
+                                    sizeof(scan_enable), &scan_enable);
+               }
+       }
+#endif
+
 unlock:
        hci_dev_unlock(hdev);
 }
@@ -3067,6 +3201,24 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
        if (!conn)
                goto unlock;
 
+#ifdef TIZEN_BT
+       /*  PIN or Key Missing patch */
+       BT_DBG("remote_auth %x, remote_cap %x, auth_type %x, io_capability %x",
+              conn->remote_auth, conn->remote_cap,
+              conn->auth_type, conn->io_capability);
+
+       if (ev->status == 0x06 && hci_conn_ssp_enabled(conn)) {
+               struct hci_cp_auth_requested cp;
+
+               BT_DBG("Pin or key missing");
+               hci_remove_link_key(hdev, &conn->dst);
+               cp.handle = cpu_to_le16(conn->handle);
+               hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
+                            sizeof(cp), &cp);
+               goto unlock;
+       }
+#endif
+
        if (!ev->status) {
                clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags);
 
@@ -3906,6 +4058,11 @@ static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_hardware_error *ev = (void *) skb->data;
 
+#ifdef TIZEN_BT
+       hci_dev_lock(hdev);
+       mgmt_hardware_error(hdev, ev->code);
+       hci_dev_unlock(hdev);
+#endif
        hdev->hw_error_code = ev->code;
 
        queue_work(hdev->req_workqueue, &hdev->error_reset);
@@ -3928,6 +4085,11 @@ static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
                clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
 
                hci_role_switch_cfm(conn, ev->status, ev->role);
+#ifdef TIZEN_BT
+               if (!ev->status && (get_link_mode(conn) & HCI_LM_MASTER))
+                       hci_conn_change_supervision_timeout(conn,
+                                       LINK_SUPERVISION_TIMEOUT);
+#endif
        }
 
        hci_dev_unlock(hdev);
@@ -4697,6 +4859,14 @@ unlock:
 
 static u8 hci_get_auth_req(struct hci_conn *conn)
 {
+#ifdef TIZEN_BT
+       if (conn->remote_auth == HCI_AT_GENERAL_BONDING_MITM) {
+               if (conn->remote_cap != HCI_IO_NO_INPUT_OUTPUT &&
+                   conn->io_capability != HCI_IO_NO_INPUT_OUTPUT)
+                       return HCI_AT_GENERAL_BONDING_MITM;
+       }
+#endif
+
        /* If remote requests no-bonding follow that lead */
        if (conn->remote_auth == HCI_AT_NO_BONDING ||
            conn->remote_auth == HCI_AT_NO_BONDING_MITM)
@@ -5352,6 +5522,10 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
                        }
                }
        } else {
+#ifdef TIZEN_BT
+               /* LE auto connect */
+               bacpy(&conn->dst, bdaddr);
+#endif
                cancel_delayed_work(&conn->le_conn_timeout);
        }
 
@@ -5676,10 +5850,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;
 
@@ -5773,17 +5951,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;
        }
 
@@ -5808,6 +5994,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.
@@ -5871,6 +6062,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)
@@ -6239,6 +6431,11 @@ static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
        case HCI_EV_LE_EXT_ADV_SET_TERM:
                hci_le_ext_adv_term_evt(hdev, skb);
                break;
+#ifdef TIZEN_BT
+       case HCI_EV_LE_DATA_LEN_CHANGE:
+               hci_le_data_length_changed_complete_evt(hdev, skb);
+               break;
+#endif
 
        default:
                break;