aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>2012-05-29 06:59:11 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2012-06-04 23:34:13 -0400
commit47f2d97d38816aaca94c9b6961c6eff1cfcd0bd6 (patch)
tree1d7c3ff629cd4844f2f4d76ac4ed824258ed4542 /net/bluetooth
parent329d81af29344a2ad2f9595310be74644421797a (diff)
Bluetooth: A2MP: Process A2MP Get Info Request
Process A2MP Get Info Request. Example of trace log for invalid controller id is shown below: ... > ACL data: handle 11 flags 0x02 dlen 13 A2MP: Get Info req: id 238 < ACL data: handle 11 flags 0x00 dlen 30 A2MP: Get Info rsp: id 238 status (1) Invalid Controller ID ... Note that If the Status field is set to Invalid Controller ID all subsequent fields in the AMP Get Info Response shall be ignored by the receiver. Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/a2mp.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 6cdaa85ab5e9..350088e2015a 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -177,6 +177,40 @@ static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb,
177 return 0; 177 return 0;
178} 178}
179 179
180static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb,
181 struct a2mp_cmd *hdr)
182{
183 struct a2mp_info_req *req = (void *) skb->data;
184 struct a2mp_info_rsp rsp;
185 struct hci_dev *hdev;
186
187 if (le16_to_cpu(hdr->len) < sizeof(*req))
188 return -EINVAL;
189
190 BT_DBG("id %d", req->id);
191
192 rsp.id = req->id;
193 rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
194
195 hdev = hci_dev_get(req->id);
196 if (hdev && hdev->amp_type != HCI_BREDR) {
197 rsp.status = 0;
198 rsp.total_bw = cpu_to_le32(hdev->amp_total_bw);
199 rsp.max_bw = cpu_to_le32(hdev->amp_max_bw);
200 rsp.min_latency = cpu_to_le32(hdev->amp_min_latency);
201 rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap);
202 rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size);
203 }
204
205 if (hdev)
206 hci_dev_put(hdev);
207
208 a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp), &rsp);
209
210 skb_pull(skb, sizeof(*req));
211 return 0;
212}
213
180/* Handle A2MP signalling */ 214/* Handle A2MP signalling */
181static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) 215static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
182{ 216{
@@ -215,6 +249,9 @@ static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
215 break; 249 break;
216 250
217 case A2MP_GETINFO_REQ: 251 case A2MP_GETINFO_REQ:
252 err = a2mp_getinfo_req(mgr, skb, hdr);
253 break;
254
218 case A2MP_GETAMPASSOC_REQ: 255 case A2MP_GETAMPASSOC_REQ:
219 case A2MP_CREATEPHYSLINK_REQ: 256 case A2MP_CREATEPHYSLINK_REQ:
220 case A2MP_DISCONNPHYSLINK_REQ: 257 case A2MP_DISCONNPHYSLINK_REQ: