From: Sudha Bheemanna Date: Thu, 8 Sep 2016 07:07:45 +0000 (+0530) Subject: Bluetooth: Set the link for SCO connection X-Git-Tag: accepted/tizen/unified/20230118.172025~246 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=80af0376401522141b1dbcfc038b86953886073b;p=platform%2Fkernel%2Flinux-rpi.git 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 --- diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 0f5d4bd..b2f270b 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -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); } @@ -2937,6 +2952,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 5099eee..467d484 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -1175,6 +1175,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) { @@ -1376,6 +1399,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)); } @@ -1387,6 +1415,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)); }