diff options
author | Sudha Bheemanna <b.sudha@samsung.com> | 2016-09-08 12:37:45 +0530 |
---|---|---|
committer | Seung-Woo Kim <sw0312.kim@samsung.com> | 2016-12-14 13:53:15 +0900 |
commit | ccfffda9305969ccbf32f18e6c8ba696d632d51b (patch) | |
tree | 1a3780a22d6d2c6985b2fd1c38f1099a9af2bdec | |
parent | 9eedcb2b6671f73072428184f496af2e8963f425 (diff) |
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 <b.sudha@samsung.com>
[add link policy setting in sco connection]
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
-rw-r--r-- | net/bluetooth/hci_event.c | 29 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 33 |
2 files changed, 62 insertions, 0 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index c2a445101e93..697a140b4302 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -136,6 +136,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); @@ -152,6 +156,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); } @@ -2461,6 +2476,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 805282b2225f..b20345885c82 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -1081,6 +1081,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) { @@ -1282,6 +1305,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)); } @@ -1293,6 +1321,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)); } |