From 87423e2367b338b4dd85ceaac5f2aee91e6b9dbc Mon Sep 17 00:00:00 2001 From: Sudha Bheemanna Date: Thu, 8 Sep 2016 12:37:45 +0530 Subject: [PATCH] Bluetooth: Set the link for SCO connection This patch sets the link policy for SCO/eSCO connection. Change-Id: I71caef5a3887f73a10329b6886c8cf52b80e8d37 Signed-off-by: Sudha Bheemanna [add link policy setting in sco connection] Signed-off-by: Seung-Woo Kim Signed-off-by: Amit Purwar --- net/bluetooth/hci_event.c | 29 +++++++++++++++++++++++++++++ net/bluetooth/sco.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d888e72..6261613 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -141,6 +141,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); @@ -157,6 +161,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); } @@ -2635,6 +2650,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) { diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 6b4c623..1daed09 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -1100,6 +1100,29 @@ static void sco_conn_ready(struct sco_conn *conn) } #ifdef TIZEN_BT +/* Link policy */ +static int hci_write_acl_link_policy(struct hci_conn *hcon, uint16_t policy) +{ + struct hci_conn *hcon_acl; + struct hci_cp_write_link_policy cp; + + BT_DBG("Write link Policy %d", policy); + + hcon_acl = hci_conn_hash_lookup_ba(hcon->hdev, ACL_LINK, &hcon->dst); + if (!hcon_acl) { + BT_ERR("ACL does not alive"); + return -1; + } + + memset(&cp, 0, sizeof(cp)); + cp.handle = __cpu_to_le16(hcon_acl->handle); + cp.policy = __cpu_to_le16(policy); + + hci_send_cmd(hcon_acl->hdev, HCI_OP_WRITE_LINK_POLICY, sizeof(cp), &cp); + + return 0; +} + /* WBC/NBC feature */ void sco_connect_set_gw_nbc(struct hci_dev *hdev) { @@ -1301,6 +1324,11 @@ static void sco_connect_cfm(struct hci_conn *hcon, __u8 status) conn = sco_conn_add(hcon); if (conn) sco_conn_ready(conn); + +#ifdef TIZEN_BT + /* Link policy */ + hci_write_acl_link_policy(hcon, HCI_LP_RSWITCH); +#endif } else sco_conn_del(hcon, bt_to_errno(status)); } @@ -1312,6 +1340,11 @@ static void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) BT_DBG("hcon %p reason %d", hcon, reason); +#ifdef TIZEN_BT + /* Link policy */ + hci_write_acl_link_policy(hcon, HCI_LP_SNIFF | HCI_LP_RSWITCH); +#endif + sco_conn_del(hcon, bt_to_errno(reason)); } -- 2.7.4