diff options
-rw-r--r-- | include/net/bluetooth/amp.h | 1 | ||||
-rw-r--r-- | net/bluetooth/a2mp.c | 32 | ||||
-rw-r--r-- | net/bluetooth/amp.c | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 20 |
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 | ||
27 | int amp_ctrl_put(struct amp_ctrl *ctrl); | 27 | int amp_ctrl_put(struct amp_ctrl *ctrl); |
28 | void amp_ctrl_get(struct amp_ctrl *ctrl); | ||
28 | struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr); | 29 | struct amp_ctrl *amp_ctrl_add(struct amp_mgr *mgr); |
29 | struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id); | 30 | struct amp_ctrl *amp_ctrl_lookup(struct amp_mgr *mgr, u8 id); |
30 | void amp_ctrl_list_flush(struct amp_mgr *mgr); | 31 | void 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 */ |
22 | static void amp_ctrl_get(struct amp_ctrl *ctrl) | 22 | void 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 | ||
1732 | static 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 | |||
1732 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1748 | static 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; |