From fb686a02c5f0fdf900670f7587cb3a123f296cb3 Mon Sep 17 00:00:00 2001 From: Andrei Emeltchenko Date: Fri, 7 Dec 2012 14:59:05 +0200 Subject: [PATCH] --- yaml --- r: 352229 b: refs/heads/master c: 8e05e3ba88adcf7ac644e6ef26676ea7c048a08c h: refs/heads/master i: 352227: 609c4d44d6290244b12fdeb09022a1f70f444c93 v: v3 --- [refs] | 2 +- trunk/include/net/bluetooth/a2mp.h | 2 ++ trunk/net/bluetooth/a2mp.c | 38 ++++++++++++++++++++++++++++-- trunk/net/bluetooth/amp.c | 4 +++- 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 68ddca6e5106..c82da59c4ab1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 7952861f4a8d67b6624b2e6c92cd63bd11a332ce +refs/heads/master: 8e05e3ba88adcf7ac644e6ef26676ea7c048a08c diff --git a/trunk/include/net/bluetooth/a2mp.h b/trunk/include/net/bluetooth/a2mp.h index 42f21766c538..8b39327a5200 100644 --- a/trunk/include/net/bluetooth/a2mp.h +++ b/trunk/include/net/bluetooth/a2mp.h @@ -23,6 +23,7 @@ enum amp_mgr_state { READ_LOC_AMP_INFO, READ_LOC_AMP_ASSOC, READ_LOC_AMP_ASSOC_FINAL, + WRITE_REMOTE_AMP_ASSOC, }; struct amp_mgr { @@ -144,5 +145,6 @@ void a2mp_discover_amp(struct l2cap_chan *chan); void a2mp_send_getinfo_rsp(struct hci_dev *hdev); void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status); void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status); +void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status); #endif /* __A2MP_H */ diff --git a/trunk/net/bluetooth/a2mp.c b/trunk/net/bluetooth/a2mp.c index 2f67d5ecc907..a200edf63117 100644 --- a/trunk/net/bluetooth/a2mp.c +++ b/trunk/net/bluetooth/a2mp.c @@ -499,8 +499,16 @@ static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, if (hdev) hci_dev_put(hdev); - a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, hdr->ident, sizeof(rsp), - &rsp); + /* Reply error now and success after HCI Write Remote AMP Assoc + command complete with success status + */ + if (rsp.status != A2MP_STATUS_SUCCESS) { + a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, hdr->ident, + sizeof(rsp), &rsp); + } else { + mgr->state = WRITE_REMOTE_AMP_ASSOC; + mgr->ident = hdr->ident; + } skb_pull(skb, le16_to_cpu(hdr->len)); return 0; @@ -949,6 +957,32 @@ void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status) kfree(req); } +void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status) +{ + struct amp_mgr *mgr; + struct a2mp_physlink_rsp rsp; + struct hci_conn *hs_hcon; + + mgr = amp_mgr_lookup_by_state(WRITE_REMOTE_AMP_ASSOC); + if (!mgr) + return; + + hs_hcon = hci_conn_hash_lookup_state(hdev, AMP_LINK, BT_CONNECT); + if (!hs_hcon) { + rsp.status = A2MP_STATUS_UNABLE_START_LINK_CREATION; + } else { + rsp.remote_id = hs_hcon->remote_id; + rsp.status = A2MP_STATUS_SUCCESS; + } + + BT_DBG("%s mgr %p hs_hcon %p status %u", hdev->name, mgr, hs_hcon, + status); + + rsp.local_id = hdev->id; + a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, mgr->ident, sizeof(rsp), &rsp); + amp_mgr_put(mgr); +} + void a2mp_discover_amp(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; diff --git a/trunk/net/bluetooth/amp.c b/trunk/net/bluetooth/amp.c index 1b0d92c0643a..522865776ec6 100644 --- a/trunk/net/bluetooth/amp.c +++ b/trunk/net/bluetooth/amp.c @@ -317,7 +317,9 @@ void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle) if (!hcon) return; - amp_write_rem_assoc_frag(hdev, hcon); + /* Send A2MP create phylink rsp when all fragments are written */ + if (amp_write_rem_assoc_frag(hdev, hcon)) + a2mp_send_create_phy_link_rsp(hdev, 0); } void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle)