Skip to content

Commit

Permalink
Bluetooth: AMP: Use HCI cmd to Read AMP Info
Browse files Browse the repository at this point in the history
When receiving A2MP Get Info Request execute Read Local AMP Info HCI
command to AMP controller with function to be executed upon receiving
command complete event. Function will handle A2MP Get Info Response.

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 Sep 27, 2012
1 parent f97268f commit 8e2a0d9
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 17 deletions.
2 changes: 2 additions & 0 deletions include/net/bluetooth/a2mp.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,7 @@ int amp_mgr_put(struct amp_mgr *mgr);
struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn,
struct sk_buff *skb);
struct amp_mgr *amp_mgr_lookup_by_state(u8 state);
void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data);
void a2mp_send_getinfo_rsp(struct hci_dev *hdev);

#endif /* __A2MP_H */
57 changes: 41 additions & 16 deletions net/bluetooth/a2mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data)
return cmd;
}

static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len,
void *data)
void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data)
{
struct l2cap_chan *chan = mgr->a2mp_chan;
struct a2mp_cmd *cmd;
Expand Down Expand Up @@ -185,31 +184,30 @@ static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb,
struct a2mp_cmd *hdr)
{
struct a2mp_info_req *req = (void *) skb->data;
struct a2mp_info_rsp rsp;
struct hci_dev *hdev;

if (le16_to_cpu(hdr->len) < sizeof(*req))
return -EINVAL;

BT_DBG("id %d", req->id);

rsp.id = req->id;
rsp.status = A2MP_STATUS_INVALID_CTRL_ID;

hdev = hci_dev_get(req->id);
if (hdev && hdev->amp_type != HCI_BREDR) {
rsp.status = 0;
rsp.total_bw = cpu_to_le32(hdev->amp_total_bw);
rsp.max_bw = cpu_to_le32(hdev->amp_max_bw);
rsp.min_latency = cpu_to_le32(hdev->amp_min_latency);
rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap);
rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size);
if (!hdev) {
struct a2mp_info_rsp rsp;

rsp.id = req->id;
rsp.status = A2MP_STATUS_INVALID_CTRL_ID;

a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp),
&rsp);
}

if (hdev)
hci_dev_put(hdev);
if (hdev->dev_type != HCI_BREDR) {
mgr->state = READ_LOC_AMP_INFO;
hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
}

a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp), &rsp);
hci_dev_put(hdev);

skb_pull(skb, sizeof(*req));
return 0;
Expand Down Expand Up @@ -599,3 +597,30 @@ struct amp_mgr *amp_mgr_lookup_by_state(u8 state)

return NULL;
}

void a2mp_send_getinfo_rsp(struct hci_dev *hdev)
{
struct amp_mgr *mgr;
struct a2mp_info_rsp rsp;

mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_INFO);
if (!mgr)
return;

BT_DBG("%s mgr %p", hdev->name, mgr);

rsp.id = hdev->id;
rsp.status = A2MP_STATUS_INVALID_CTRL_ID;

if (hdev->amp_type != HCI_BREDR) {
rsp.status = 0;
rsp.total_bw = cpu_to_le32(hdev->amp_total_bw);
rsp.max_bw = cpu_to_le32(hdev->amp_max_bw);
rsp.min_latency = cpu_to_le32(hdev->amp_min_latency);
rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap);
rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size);
}

a2mp_send(mgr, A2MP_GETINFO_RSP, mgr->ident, sizeof(rsp), &rsp);
amp_mgr_put(mgr);
}
6 changes: 5 additions & 1 deletion net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/mgmt.h>
#include <net/bluetooth/a2mp.h>

/* Handle HCI Event packets */

Expand Down Expand Up @@ -846,7 +847,7 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);

if (rp->status)
return;
goto a2mp_rsp;

hdev->amp_status = rp->amp_status;
hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
Expand All @@ -860,6 +861,9 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);

hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);

a2mp_rsp:
a2mp_send_getinfo_rsp(hdev);
}

static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
Expand Down

0 comments on commit 8e2a0d9

Please sign in to comment.