Skip to content

Commit

Permalink
Bluetooth: AMP: Send A2MP Create Phylink Rsp after Assoc write
Browse files Browse the repository at this point in the history
Postpone sending A2MP Create Phylink Response until we got successful
HCI Command Complete after HCI Write Remote AMP Assoc.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
  • Loading branch information
Andrei Emeltchenko authored and Gustavo Padovan committed Jan 9, 2013
1 parent 7952861 commit 8e05e3b
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
2 changes: 2 additions & 0 deletions include/net/bluetooth/a2mp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 */
38 changes: 36 additions & 2 deletions net/bluetooth/a2mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion net/bluetooth/amp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 8e05e3b

Please sign in to comment.