Bluetooth: Read host suggested default le data length
[platform/kernel/linux-rpi.git] / net / bluetooth / hci_conn.c
index 2b5059a..32abee4 100644 (file)
@@ -41,6 +41,16 @@ struct sco_param {
        u8  retrans_effort;
 };
 
+#ifdef TIZEN_BT
+static const struct sco_param esco_param_cvsd[] = {
+       { (EDR_ESCO_MASK & ~ESCO_2EV3) | SCO_ESCO_MASK | ESCO_EV3,
+                                     0x000a,   0x01 }, /* S3 */
+       { EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007,   0x01 }, /* S2 */
+       { EDR_ESCO_MASK | ESCO_EV3,   0x0007,   0x01 }, /* S1 */
+       { EDR_ESCO_MASK | ESCO_HV3,   0xffff,   0x01 }, /* D1 */
+       { EDR_ESCO_MASK | ESCO_HV1,   0xffff,   0x01 }, /* D0 */
+};
+#else
 static const struct sco_param esco_param_cvsd[] = {
        { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000a,   0x01 }, /* S3 */
        { EDR_ESCO_MASK & ~ESCO_2EV3, 0x0007,   0x01 }, /* S2 */
@@ -48,16 +58,25 @@ static const struct sco_param esco_param_cvsd[] = {
        { EDR_ESCO_MASK | ESCO_HV3,   0xffff,   0x01 }, /* D1 */
        { EDR_ESCO_MASK | ESCO_HV1,   0xffff,   0x01 }, /* D0 */
 };
+#endif
 
 static const struct sco_param sco_param_cvsd[] = {
        { EDR_ESCO_MASK | ESCO_HV3,   0xffff,   0xff }, /* D1 */
        { EDR_ESCO_MASK | ESCO_HV1,   0xffff,   0xff }, /* D0 */
 };
 
+#ifdef TIZEN_BT
+static const struct sco_param esco_param_msbc[] = {
+       { (EDR_ESCO_MASK & ~ESCO_2EV3) | ESCO_EV3,
+                                     0x000d,   0x02 }, /* T2 */
+       { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d,   0x02 }, /* T2 */
+};
+#else
 static const struct sco_param esco_param_msbc[] = {
        { EDR_ESCO_MASK & ~ESCO_2EV3, 0x000d,   0x02 }, /* T2 */
        { EDR_ESCO_MASK | ESCO_EV3,   0x0008,   0x02 }, /* T1 */
 };
+#endif
 
 /* This function requires the caller holds hdev->lock */
 static void hci_connect_le_scan_cleanup(struct hci_conn *conn)
@@ -541,7 +560,9 @@ static void le_conn_timeout(struct work_struct *work)
        if (conn->role == HCI_ROLE_SLAVE) {
                /* Disable LE Advertising */
                le_disable_advertising(hdev);
+               hci_dev_lock(hdev);
                hci_le_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
+               hci_dev_unlock(hdev);
                return;
        }
 
@@ -574,6 +595,11 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
        conn->tx_power = HCI_TX_POWER_INVALID;
        conn->max_tx_power = HCI_TX_POWER_INVALID;
 
+#ifdef TIZEN_BT
+       /* enable sniff mode for incoming connection */
+       conn->link_policy = hdev->link_policy;
+#endif
+
        set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
        conn->disc_timeout = HCI_DISCONN_TIMEOUT;
 
@@ -921,7 +947,15 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
                cp.scan_interval = cpu_to_le16(hdev->le_scan_int_connect);
                cp.scan_window = cpu_to_le16(hdev->le_scan_window_connect);
 
+#ifdef TIZEN_BT
+               /* LE auto connect */
+               if (!bacmp(&conn->dst, BDADDR_ANY))
+                       cp.filter_policy = 0x1;
+               else
+               bacpy(&cp.peer_addr, &conn->dst);
+#else
                bacpy(&cp.peer_addr, &conn->dst);
+#endif
                cp.peer_addr_type = conn->dst_type;
                cp.own_address_type = own_addr_type;
                cp.conn_interval_min = cpu_to_le16(conn->le_conn_min_interval);
@@ -1569,6 +1603,29 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
 }
 EXPORT_SYMBOL(hci_conn_switch_role);
 
+#ifdef TIZEN_BT
+int hci_conn_change_supervision_timeout(struct hci_conn *conn, __u16 timeout)
+{
+       struct hci_cp_write_link_supervision_timeout cp;
+
+       if (!((get_link_mode(conn)) & HCI_LM_MASTER))
+               return 1;
+
+       if (conn->handle == 0)
+               return 1;
+
+       memset(&cp, 0, sizeof(cp));
+       cp.handle  = cpu_to_le16(conn->handle);
+       cp.timeout = cpu_to_le16(timeout);
+
+       if (hci_send_cmd(conn->hdev, HCI_OP_WRITE_LINK_SUPERVISION_TIMEOUT,
+                        sizeof(cp), &cp) < 0)
+               BT_ERR("HCI_OP_WRITE_LINK_SUPERVISION_TIMEOUT is failed");
+
+       return 0;
+}
+#endif
+
 /* Enter active mode */
 void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
 {
@@ -1589,9 +1646,18 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
        }
 
 timer:
+#ifdef TIZEN_BT
+       if (hdev->idle_timeout > 0) {
+               /* Sniff timer cancel */
+               cancel_delayed_work(&conn->idle_work);
+               queue_delayed_work(hdev->workqueue, &conn->idle_work,
+                                  msecs_to_jiffies(hdev->idle_timeout));
+       }
+#else
        if (hdev->idle_timeout > 0)
                queue_delayed_work(hdev->workqueue, &conn->idle_work,
                                   msecs_to_jiffies(hdev->idle_timeout));
+#endif
 }
 
 /* Drop all connection on the device */
@@ -1626,7 +1692,11 @@ void hci_conn_check_pending(struct hci_dev *hdev)
        hci_dev_unlock(hdev);
 }
 
+#ifndef TIZEN_BT
 static u32 get_link_mode(struct hci_conn *conn)
+#else
+u32 get_link_mode(struct hci_conn *conn)
+#endif
 {
        u32 link_mode = 0;