]> Pileus Git - ~andy/linux/blob - net/bluetooth/a2mp.c
71400612843d9f9a05a68fb69d96586593bfea6a
[~andy/linux] / net / bluetooth / a2mp.c
1 /*
2    Copyright (c) 2010,2011 Code Aurora Forum.  All rights reserved.
3    Copyright (c) 2011,2012 Intel Corp.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License version 2 and
7    only version 2 as published by the Free Software Foundation.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 */
14
15 #include <net/bluetooth/bluetooth.h>
16 #include <net/bluetooth/hci_core.h>
17 #include <net/bluetooth/l2cap.h>
18 #include <net/bluetooth/a2mp.h>
19 #include <net/bluetooth/amp.h>
20
21 /* Global AMP Manager list */
22 LIST_HEAD(amp_mgr_list);
23 DEFINE_MUTEX(amp_mgr_list_lock);
24
25 /* A2MP build & send command helper functions */
26 static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data)
27 {
28         struct a2mp_cmd *cmd;
29         int plen;
30
31         plen = sizeof(*cmd) + len;
32         cmd = kzalloc(plen, GFP_KERNEL);
33         if (!cmd)
34                 return NULL;
35
36         cmd->code = code;
37         cmd->ident = ident;
38         cmd->len = cpu_to_le16(len);
39
40         memcpy(cmd->data, data, len);
41
42         return cmd;
43 }
44
45 void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data)
46 {
47         struct l2cap_chan *chan = mgr->a2mp_chan;
48         struct a2mp_cmd *cmd;
49         u16 total_len = len + sizeof(*cmd);
50         struct kvec iv;
51         struct msghdr msg;
52
53         cmd = __a2mp_build(code, ident, len, data);
54         if (!cmd)
55                 return;
56
57         iv.iov_base = cmd;
58         iv.iov_len = total_len;
59
60         memset(&msg, 0, sizeof(msg));
61
62         msg.msg_iov = (struct iovec *) &iv;
63         msg.msg_iovlen = 1;
64
65         l2cap_chan_send(chan, &msg, total_len, 0);
66
67         kfree(cmd);
68 }
69
70 static inline void __a2mp_cl_bredr(struct a2mp_cl *cl)
71 {
72         cl->id = 0;
73         cl->type = 0;
74         cl->status = 1;
75 }
76
77 /* hci_dev_list shall be locked */
78 static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl, u8 num_ctrl)
79 {
80         int i = 0;
81         struct hci_dev *hdev;
82
83         __a2mp_cl_bredr(cl);
84
85         list_for_each_entry(hdev, &hci_dev_list, list) {
86                 /* Iterate through AMP controllers */
87                 if (hdev->id == HCI_BREDR_ID)
88                         continue;
89
90                 /* Starting from second entry */
91                 if (++i >= num_ctrl)
92                         return;
93
94                 cl[i].id = hdev->id;
95                 cl[i].type = hdev->amp_type;
96                 cl[i].status = hdev->amp_status;
97         }
98 }
99
100 /* Processing A2MP messages */
101 static int a2mp_command_rej(struct amp_mgr *mgr, struct sk_buff *skb,
102                             struct a2mp_cmd *hdr)
103 {
104         struct a2mp_cmd_rej *rej = (void *) skb->data;
105
106         if (le16_to_cpu(hdr->len) < sizeof(*rej))
107                 return -EINVAL;
108
109         BT_DBG("ident %d reason %d", hdr->ident, le16_to_cpu(rej->reason));
110
111         skb_pull(skb, sizeof(*rej));
112
113         return 0;
114 }
115
116 static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
117                              struct a2mp_cmd *hdr)
118 {
119         struct a2mp_discov_req *req = (void *) skb->data;
120         u16 len = le16_to_cpu(hdr->len);
121         struct a2mp_discov_rsp *rsp;
122         u16 ext_feat;
123         u8 num_ctrl;
124
125         if (len < sizeof(*req))
126                 return -EINVAL;
127
128         skb_pull(skb, sizeof(*req));
129
130         ext_feat = le16_to_cpu(req->ext_feat);
131
132         BT_DBG("mtu %d efm 0x%4.4x", le16_to_cpu(req->mtu), ext_feat);
133
134         /* check that packet is not broken for now */
135         while (ext_feat & A2MP_FEAT_EXT) {
136                 if (len < sizeof(ext_feat))
137                         return -EINVAL;
138
139                 ext_feat = get_unaligned_le16(skb->data);
140                 BT_DBG("efm 0x%4.4x", ext_feat);
141                 len -= sizeof(ext_feat);
142                 skb_pull(skb, sizeof(ext_feat));
143         }
144
145         read_lock(&hci_dev_list_lock);
146
147         num_ctrl = __hci_num_ctrl();
148         len = num_ctrl * sizeof(struct a2mp_cl) + sizeof(*rsp);
149         rsp = kmalloc(len, GFP_ATOMIC);
150         if (!rsp) {
151                 read_unlock(&hci_dev_list_lock);
152                 return -ENOMEM;
153         }
154
155         rsp->mtu = __constant_cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU);
156         rsp->ext_feat = 0;
157
158         __a2mp_add_cl(mgr, rsp->cl, num_ctrl);
159
160         read_unlock(&hci_dev_list_lock);
161
162         a2mp_send(mgr, A2MP_DISCOVER_RSP, hdr->ident, len, rsp);
163
164         kfree(rsp);
165         return 0;
166 }
167
168 static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb,
169                               struct a2mp_cmd *hdr)
170 {
171         struct a2mp_cl *cl = (void *) skb->data;
172
173         while (skb->len >= sizeof(*cl)) {
174                 BT_DBG("Controller id %d type %d status %d", cl->id, cl->type,
175                        cl->status);
176                 cl = (struct a2mp_cl *) skb_pull(skb, sizeof(*cl));
177         }
178
179         /* TODO send A2MP_CHANGE_RSP */
180
181         return 0;
182 }
183
184 static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb,
185                             struct a2mp_cmd *hdr)
186 {
187         struct a2mp_info_req *req  = (void *) skb->data;
188         struct hci_dev *hdev;
189
190         if (le16_to_cpu(hdr->len) < sizeof(*req))
191                 return -EINVAL;
192
193         BT_DBG("id %d", req->id);
194
195         hdev = hci_dev_get(req->id);
196         if (!hdev) {
197                 struct a2mp_info_rsp rsp;
198
199                 rsp.id = req->id;
200                 rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
201
202                 a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp),
203                           &rsp);
204         }
205
206         if (hdev->dev_type != HCI_BREDR) {
207                 mgr->state = READ_LOC_AMP_INFO;
208                 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
209         }
210
211         hci_dev_put(hdev);
212
213         skb_pull(skb, sizeof(*req));
214         return 0;
215 }
216
217 static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb,
218                                 struct a2mp_cmd *hdr)
219 {
220         struct a2mp_amp_assoc_req *req = (void *) skb->data;
221         struct hci_dev *hdev;
222         struct amp_mgr *tmp;
223
224         if (le16_to_cpu(hdr->len) < sizeof(*req))
225                 return -EINVAL;
226
227         BT_DBG("id %d", req->id);
228
229         /* Make sure that other request is not processed */
230         tmp = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC);
231
232         hdev = hci_dev_get(req->id);
233         if (!hdev || hdev->amp_type == HCI_BREDR || tmp) {
234                 struct a2mp_amp_assoc_rsp rsp;
235                 rsp.id = req->id;
236
237                 if (tmp) {
238                         rsp.status = A2MP_STATUS_COLLISION_OCCURED;
239                         amp_mgr_put(tmp);
240                 } else {
241                         rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
242                 }
243
244                 a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, hdr->ident, sizeof(rsp),
245                           &rsp);
246
247                 goto done;
248         }
249
250         amp_read_loc_assoc(hdev, mgr);
251
252 done:
253         if (hdev)
254                 hci_dev_put(hdev);
255
256         skb_pull(skb, sizeof(*req));
257         return 0;
258 }
259
260 static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
261                                    struct a2mp_cmd *hdr)
262 {
263         struct a2mp_physlink_req *req = (void *) skb->data;
264
265         struct a2mp_physlink_rsp rsp;
266         struct hci_dev *hdev;
267
268         if (le16_to_cpu(hdr->len) < sizeof(*req))
269                 return -EINVAL;
270
271         BT_DBG("local_id %d, remote_id %d", req->local_id, req->remote_id);
272
273         rsp.local_id = req->remote_id;
274         rsp.remote_id = req->local_id;
275
276         hdev = hci_dev_get(req->remote_id);
277         if (!hdev || hdev->amp_type != HCI_AMP) {
278                 rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
279                 goto send_rsp;
280         }
281
282         /* TODO process physlink create */
283
284         rsp.status = A2MP_STATUS_SUCCESS;
285
286 send_rsp:
287         if (hdev)
288                 hci_dev_put(hdev);
289
290         a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, hdr->ident, sizeof(rsp),
291                   &rsp);
292
293         skb_pull(skb, le16_to_cpu(hdr->len));
294         return 0;
295 }
296
297 static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb,
298                                  struct a2mp_cmd *hdr)
299 {
300         struct a2mp_physlink_req *req = (void *) skb->data;
301         struct a2mp_physlink_rsp rsp;
302         struct hci_dev *hdev;
303
304         if (le16_to_cpu(hdr->len) < sizeof(*req))
305                 return -EINVAL;
306
307         BT_DBG("local_id %d remote_id %d", req->local_id, req->remote_id);
308
309         rsp.local_id = req->remote_id;
310         rsp.remote_id = req->local_id;
311         rsp.status = A2MP_STATUS_SUCCESS;
312
313         hdev = hci_dev_get(req->local_id);
314         if (!hdev) {
315                 rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
316                 goto send_rsp;
317         }
318
319         /* TODO Disconnect Phys Link here */
320
321         hci_dev_put(hdev);
322
323 send_rsp:
324         a2mp_send(mgr, A2MP_DISCONNPHYSLINK_RSP, hdr->ident, sizeof(rsp), &rsp);
325
326         skb_pull(skb, sizeof(*req));
327         return 0;
328 }
329
330 static inline int a2mp_cmd_rsp(struct amp_mgr *mgr, struct sk_buff *skb,
331                                struct a2mp_cmd *hdr)
332 {
333         BT_DBG("ident %d code 0x%2.2x", hdr->ident, hdr->code);
334
335         skb_pull(skb, le16_to_cpu(hdr->len));
336         return 0;
337 }
338
339 /* Handle A2MP signalling */
340 static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
341 {
342         struct a2mp_cmd *hdr;
343         struct amp_mgr *mgr = chan->data;
344         int err = 0;
345
346         amp_mgr_get(mgr);
347
348         while (skb->len >= sizeof(*hdr)) {
349                 u16 len;
350
351                 hdr = (void *) skb->data;
352                 len = le16_to_cpu(hdr->len);
353
354                 BT_DBG("code 0x%2.2x id %d len %u", hdr->code, hdr->ident, len);
355
356                 skb_pull(skb, sizeof(*hdr));
357
358                 if (len > skb->len || !hdr->ident) {
359                         err = -EINVAL;
360                         break;
361                 }
362
363                 mgr->ident = hdr->ident;
364
365                 switch (hdr->code) {
366                 case A2MP_COMMAND_REJ:
367                         a2mp_command_rej(mgr, skb, hdr);
368                         break;
369
370                 case A2MP_DISCOVER_REQ:
371                         err = a2mp_discover_req(mgr, skb, hdr);
372                         break;
373
374                 case A2MP_CHANGE_NOTIFY:
375                         err = a2mp_change_notify(mgr, skb, hdr);
376                         break;
377
378                 case A2MP_GETINFO_REQ:
379                         err = a2mp_getinfo_req(mgr, skb, hdr);
380                         break;
381
382                 case A2MP_GETAMPASSOC_REQ:
383                         err = a2mp_getampassoc_req(mgr, skb, hdr);
384                         break;
385
386                 case A2MP_CREATEPHYSLINK_REQ:
387                         err = a2mp_createphyslink_req(mgr, skb, hdr);
388                         break;
389
390                 case A2MP_DISCONNPHYSLINK_REQ:
391                         err = a2mp_discphyslink_req(mgr, skb, hdr);
392                         break;
393
394                 case A2MP_CHANGE_RSP:
395                 case A2MP_DISCOVER_RSP:
396                 case A2MP_GETINFO_RSP:
397                 case A2MP_GETAMPASSOC_RSP:
398                 case A2MP_CREATEPHYSLINK_RSP:
399                 case A2MP_DISCONNPHYSLINK_RSP:
400                         err = a2mp_cmd_rsp(mgr, skb, hdr);
401                         break;
402
403                 default:
404                         BT_ERR("Unknown A2MP sig cmd 0x%2.2x", hdr->code);
405                         err = -EINVAL;
406                         break;
407                 }
408         }
409
410         if (err) {
411                 struct a2mp_cmd_rej rej;
412
413                 rej.reason = __constant_cpu_to_le16(0);
414                 hdr = (void *) skb->data;
415
416                 BT_DBG("Send A2MP Rej: cmd 0x%2.2x err %d", hdr->code, err);
417
418                 a2mp_send(mgr, A2MP_COMMAND_REJ, hdr->ident, sizeof(rej),
419                           &rej);
420         }
421
422         /* Always free skb and return success error code to prevent
423            from sending L2CAP Disconnect over A2MP channel */
424         kfree_skb(skb);
425
426         amp_mgr_put(mgr);
427
428         return 0;
429 }
430
431 static void a2mp_chan_close_cb(struct l2cap_chan *chan)
432 {
433         l2cap_chan_put(chan);
434 }
435
436 static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state)
437 {
438         struct amp_mgr *mgr = chan->data;
439
440         if (!mgr)
441                 return;
442
443         BT_DBG("chan %p state %s", chan, state_to_string(state));
444
445         chan->state = state;
446
447         switch (state) {
448         case BT_CLOSED:
449                 if (mgr)
450                         amp_mgr_put(mgr);
451                 break;
452         }
453 }
454
455 static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan,
456                                               unsigned long len, int nb)
457 {
458         return bt_skb_alloc(len, GFP_KERNEL);
459 }
460
461 static struct l2cap_ops a2mp_chan_ops = {
462         .name = "L2CAP A2MP channel",
463         .recv = a2mp_chan_recv_cb,
464         .close = a2mp_chan_close_cb,
465         .state_change = a2mp_chan_state_change_cb,
466         .alloc_skb = a2mp_chan_alloc_skb_cb,
467
468         /* Not implemented for A2MP */
469         .new_connection = l2cap_chan_no_new_connection,
470         .teardown = l2cap_chan_no_teardown,
471         .ready = l2cap_chan_no_ready,
472 };
473
474 static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn)
475 {
476         struct l2cap_chan *chan;
477         int err;
478
479         chan = l2cap_chan_create();
480         if (!chan)
481                 return NULL;
482
483         BT_DBG("chan %p", chan);
484
485         chan->chan_type = L2CAP_CHAN_CONN_FIX_A2MP;
486         chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
487
488         chan->ops = &a2mp_chan_ops;
489
490         l2cap_chan_set_defaults(chan);
491         chan->remote_max_tx = chan->max_tx;
492         chan->remote_tx_win = chan->tx_win;
493
494         chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
495         chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
496
497         skb_queue_head_init(&chan->tx_q);
498
499         chan->mode = L2CAP_MODE_ERTM;
500
501         err = l2cap_ertm_init(chan);
502         if (err < 0) {
503                 l2cap_chan_del(chan, 0);
504                 return NULL;
505         }
506
507         chan->conf_state = 0;
508
509         l2cap_chan_add(conn, chan);
510
511         chan->remote_mps = chan->omtu;
512         chan->mps = chan->omtu;
513
514         chan->state = BT_CONNECTED;
515
516         return chan;
517 }
518
519 /* AMP Manager functions */
520 void amp_mgr_get(struct amp_mgr *mgr)
521 {
522         BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount));
523
524         kref_get(&mgr->kref);
525 }
526
527 static void amp_mgr_destroy(struct kref *kref)
528 {
529         struct amp_mgr *mgr = container_of(kref, struct amp_mgr, kref);
530
531         BT_DBG("mgr %p", mgr);
532
533         mutex_lock(&amp_mgr_list_lock);
534         list_del(&mgr->list);
535         mutex_unlock(&amp_mgr_list_lock);
536
537         kfree(mgr);
538 }
539
540 int amp_mgr_put(struct amp_mgr *mgr)
541 {
542         BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount));
543
544         return kref_put(&mgr->kref, &amp_mgr_destroy);
545 }
546
547 static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn)
548 {
549         struct amp_mgr *mgr;
550         struct l2cap_chan *chan;
551
552         mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
553         if (!mgr)
554                 return NULL;
555
556         BT_DBG("conn %p mgr %p", conn, mgr);
557
558         mgr->l2cap_conn = conn;
559
560         chan = a2mp_chan_open(conn);
561         if (!chan) {
562                 kfree(mgr);
563                 return NULL;
564         }
565
566         mgr->a2mp_chan = chan;
567         chan->data = mgr;
568
569         conn->hcon->amp_mgr = mgr;
570
571         kref_init(&mgr->kref);
572
573         mutex_lock(&amp_mgr_list_lock);
574         list_add(&mgr->list, &amp_mgr_list);
575         mutex_unlock(&amp_mgr_list_lock);
576
577         return mgr;
578 }
579
580 struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn,
581                                        struct sk_buff *skb)
582 {
583         struct amp_mgr *mgr;
584
585         mgr = amp_mgr_create(conn);
586         if (!mgr) {
587                 BT_ERR("Could not create AMP manager");
588                 return NULL;
589         }
590
591         BT_DBG("mgr: %p chan %p", mgr, mgr->a2mp_chan);
592
593         return mgr->a2mp_chan;
594 }
595
596 struct amp_mgr *amp_mgr_lookup_by_state(u8 state)
597 {
598         struct amp_mgr *mgr;
599
600         mutex_lock(&amp_mgr_list_lock);
601         list_for_each_entry(mgr, &amp_mgr_list, list) {
602                 if (mgr->state == state) {
603                         amp_mgr_get(mgr);
604                         mutex_unlock(&amp_mgr_list_lock);
605                         return mgr;
606                 }
607         }
608         mutex_unlock(&amp_mgr_list_lock);
609
610         return NULL;
611 }
612
613 void a2mp_send_getinfo_rsp(struct hci_dev *hdev)
614 {
615         struct amp_mgr *mgr;
616         struct a2mp_info_rsp rsp;
617
618         mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_INFO);
619         if (!mgr)
620                 return;
621
622         BT_DBG("%s mgr %p", hdev->name, mgr);
623
624         rsp.id = hdev->id;
625         rsp.status = A2MP_STATUS_INVALID_CTRL_ID;
626
627         if (hdev->amp_type != HCI_BREDR) {
628                 rsp.status = 0;
629                 rsp.total_bw = cpu_to_le32(hdev->amp_total_bw);
630                 rsp.max_bw = cpu_to_le32(hdev->amp_max_bw);
631                 rsp.min_latency = cpu_to_le32(hdev->amp_min_latency);
632                 rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap);
633                 rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size);
634         }
635
636         a2mp_send(mgr, A2MP_GETINFO_RSP, mgr->ident, sizeof(rsp), &rsp);
637         amp_mgr_put(mgr);
638 }
639
640 void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status)
641 {
642         struct amp_mgr *mgr;
643         struct amp_assoc *loc_assoc = &hdev->loc_assoc;
644         struct a2mp_amp_assoc_rsp *rsp;
645         size_t len;
646
647         mgr = amp_mgr_lookup_by_state(READ_LOC_AMP_ASSOC);
648         if (!mgr)
649                 return;
650
651         BT_DBG("%s mgr %p", hdev->name, mgr);
652
653         len = sizeof(struct a2mp_amp_assoc_rsp) + loc_assoc->len;
654         rsp = kzalloc(len, GFP_KERNEL);
655         if (!rsp) {
656                 amp_mgr_put(mgr);
657                 return;
658         }
659
660         rsp->id = hdev->id;
661
662         if (status) {
663                 rsp->status = A2MP_STATUS_INVALID_CTRL_ID;
664         } else {
665                 rsp->status = A2MP_STATUS_SUCCESS;
666                 memcpy(rsp->amp_assoc, loc_assoc->data, loc_assoc->len);
667         }
668
669         a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, mgr->ident, len, rsp);
670         amp_mgr_put(mgr);
671         kfree(rsp);
672 }