aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/amp.h1
-rw-r--r--net/bluetooth/a2mp.c32
-rw-r--r--net/bluetooth/amp.c2
-rw-r--r--net/bluetooth/hci_event.c20
4 files changed, 54 insertions, 1 deletions
diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h
index 1b06d7b01359..b1e54903dd42 100644
--- a/include/net/bluetooth/amp.h
+++ b/include/net/bluetooth/amp.h
@@ -25,6 +25,7 @@ struct amp_ctrl {
25}; 25};
26 26
27int amp_ctrl_put(struct amp_ctrl *ctrl); 27int amp_ctrl_put(struct amp_ctrl *ctrl);
28void amp_ctrl_get(struct amp_ctrl *ctrl);
28struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr); 29struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr);
29struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id); 30struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id);
30void amp_ctrl_list_flush(struct amp_mgr *mgr); 31void amp_ctrl_list_flush(struct amp_mgr *mgr);
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index dbfdbbb9707c..47565d28b27f 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -438,6 +438,7 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
438 struct a2mp_physlink_rsp rsp; 438 struct a2mp_physlink_rsp rsp;
439 struct hci_dev *hdev; 439 struct hci_dev *hdev;
440 struct hci_conn *hcon; 440 struct hci_conn *hcon;
441 struct amp_ctrl *ctrl;
441 442
442 if (le16_to_cpu(hdr->len) < sizeof(*req)) 443 if (le16_to_cpu(hdr->len) < sizeof(*req))
443 return -EINVAL; 444 return -EINVAL;
@@ -453,6 +454,37 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
453 goto send_rsp; 454 goto send_rsp;
454 } 455 }
455 456
457 ctrl = amp_ctrl_lookup(mgr, rsp.remote_id);
458 if (!ctrl) {
459 ctrl = amp_ctrl_add(mgr);
460 if (ctrl) {
461 amp_ctrl_get(ctrl);
462 } else {
463 rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION;
464 goto send_rsp;
465 }
466 }
467
468 if (ctrl) {
469 u8 *assoc, assoc_len = le16_to_cpu(hdr->len) - sizeof(*req);
470
471 ctrl->id = rsp.remote_id;
472
473 assoc = kzalloc(assoc_len, GFP_KERNEL);
474 if (!assoc) {
475 amp_ctrl_put(ctrl);
476 return -ENOMEM;
477 }
478
479 memcpy(assoc, req->amp_assoc, assoc_len);
480 ctrl->assoc = assoc;
481 ctrl->assoc_len = assoc_len;
482 ctrl->assoc_rem_len = assoc_len;
483 ctrl->assoc_len_so_far = 0;
484
485 amp_ctrl_put(ctrl);
486 }
487
456 hcon = phylink_add(hdev, mgr, req->local_id); 488 hcon = phylink_add(hdev, mgr, req->local_id);
457 if (hcon) { 489 if (hcon) {
458 amp_accept_phylink(hdev, mgr, hcon); 490 amp_accept_phylink(hdev, mgr, hcon);
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c
index 845e43073c40..5dab2d1c7c82 100644
--- a/net/bluetooth/amp.c
+++ b/net/bluetooth/amp.c
@@ -19,7 +19,7 @@
19#include <crypto/hash.h> 19#include <crypto/hash.h>
20 20
21/* Remote AMP Controllers interface */ 21/* Remote AMP Controllers interface */
22static void amp_ctrl_get(struct amp_ctrl *ctrl) 22void amp_ctrl_get(struct amp_ctrl *ctrl)
23{ 23{
24 BT_DBG("ctrl %p orig refcnt %d", ctrl, 24 BT_DBG("ctrl %p orig refcnt %d", ctrl,
25 atomic_read(&ctrl->kref.refcount)); 25 atomic_read(&ctrl->kref.refcount));
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d702ba1c171c..7e716698fe64 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1729,6 +1729,22 @@ static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1729 amp_write_remote_assoc(hdev, cp->phy_handle); 1729 amp_write_remote_assoc(hdev, cp->phy_handle);
1730} 1730}
1731 1731
1732static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1733{
1734 struct hci_cp_accept_phy_link *cp;
1735
1736 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1737
1738 if (status)
1739 return;
1740
1741 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1742 if (!cp)
1743 return;
1744
1745 amp_write_remote_assoc(hdev, cp->phy_handle);
1746}
1747
1732static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 1748static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1733{ 1749{
1734 __u8 status = *((__u8 *) skb->data); 1750 __u8 status = *((__u8 *) skb->data);
@@ -2551,6 +2567,10 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2551 hci_cs_create_phylink(hdev, ev->status); 2567 hci_cs_create_phylink(hdev, ev->status);
2552 break; 2568 break;
2553 2569
2570 case HCI_OP_ACCEPT_PHY_LINK:
2571 hci_cs_accept_phylink(hdev, ev->status);
2572 break;
2573
2554 default: 2574 default:
2555 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 2575 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
2556 break; 2576 break;