]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - net/bluetooth/cmtp/capi.c
Merge branch 'at91/fixes' of git+ssh://master.kernel.org/pub/scm/linux/kernel/git...
[mirror_ubuntu-bionic-kernel.git] / net / bluetooth / cmtp / capi.c
1 /*
2 CMTP implementation for Linux Bluetooth stack (BlueZ).
3 Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
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 as
7 published by the Free Software Foundation;
8
9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20 SOFTWARE IS DISCLAIMED.
21 */
22
23 #include <linux/module.h>
24 #include <linux/proc_fs.h>
25 #include <linux/seq_file.h>
26 #include <linux/types.h>
27 #include <linux/errno.h>
28 #include <linux/kernel.h>
29 #include <linux/sched.h>
30 #include <linux/slab.h>
31 #include <linux/poll.h>
32 #include <linux/fcntl.h>
33 #include <linux/skbuff.h>
34 #include <linux/socket.h>
35 #include <linux/ioctl.h>
36 #include <linux/file.h>
37 #include <linux/wait.h>
38 #include <linux/kthread.h>
39 #include <net/sock.h>
40
41 #include <linux/isdn/capilli.h>
42 #include <linux/isdn/capicmd.h>
43 #include <linux/isdn/capiutil.h>
44
45 #include "cmtp.h"
46
47 #define CAPI_INTEROPERABILITY 0x20
48
49 #define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
50 #define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
51 #define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
52 #define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
53
54 #define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
55 #define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
56 #define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
57 #define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
58
59 #define CAPI_FUNCTION_REGISTER 0
60 #define CAPI_FUNCTION_RELEASE 1
61 #define CAPI_FUNCTION_GET_PROFILE 2
62 #define CAPI_FUNCTION_GET_MANUFACTURER 3
63 #define CAPI_FUNCTION_GET_VERSION 4
64 #define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
65 #define CAPI_FUNCTION_MANUFACTURER 6
66 #define CAPI_FUNCTION_LOOPBACK 7
67
68
69 #define CMTP_MSGNUM 1
70 #define CMTP_APPLID 2
71 #define CMTP_MAPPING 3
72
73 static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
74 {
75 struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL);
76
77 BT_DBG("session %p application %p appl %d", session, app, appl);
78
79 if (!app)
80 return NULL;
81
82 app->state = BT_OPEN;
83 app->appl = appl;
84
85 list_add_tail(&app->list, &session->applications);
86
87 return app;
88 }
89
90 static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
91 {
92 BT_DBG("session %p application %p", session, app);
93
94 if (app) {
95 list_del(&app->list);
96 kfree(app);
97 }
98 }
99
100 static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
101 {
102 struct cmtp_application *app;
103 struct list_head *p, *n;
104
105 list_for_each_safe(p, n, &session->applications) {
106 app = list_entry(p, struct cmtp_application, list);
107 switch (pattern) {
108 case CMTP_MSGNUM:
109 if (app->msgnum == value)
110 return app;
111 break;
112 case CMTP_APPLID:
113 if (app->appl == value)
114 return app;
115 break;
116 case CMTP_MAPPING:
117 if (app->mapping == value)
118 return app;
119 break;
120 }
121 }
122
123 return NULL;
124 }
125
126 static int cmtp_msgnum_get(struct cmtp_session *session)
127 {
128 session->msgnum++;
129
130 if ((session->msgnum & 0xff) > 200)
131 session->msgnum = CMTP_INITIAL_MSGNUM + 1;
132
133 return session->msgnum;
134 }
135
136 static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
137 {
138 struct cmtp_scb *scb = (void *) skb->cb;
139
140 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
141
142 scb->id = -1;
143 scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
144
145 skb_queue_tail(&session->transmit, skb);
146
147 wake_up_interruptible(sk_sleep(session->sock->sk));
148 }
149
150 static void cmtp_send_interopmsg(struct cmtp_session *session,
151 __u8 subcmd, __u16 appl, __u16 msgnum,
152 __u16 function, unsigned char *buf, int len)
153 {
154 struct sk_buff *skb;
155 unsigned char *s;
156
157 BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
158
159 skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC);
160 if (!skb) {
161 BT_ERR("Can't allocate memory for interoperability packet");
162 return;
163 }
164
165 s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
166
167 capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
168 capimsg_setu16(s, 2, appl);
169 capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
170 capimsg_setu8 (s, 5, subcmd);
171 capimsg_setu16(s, 6, msgnum);
172
173 /* Interoperability selector (Bluetooth Device Management) */
174 capimsg_setu16(s, 8, 0x0001);
175
176 capimsg_setu8 (s, 10, 3 + len);
177 capimsg_setu16(s, 11, function);
178 capimsg_setu8 (s, 13, len);
179
180 if (len > 0)
181 memcpy(s + 14, buf, len);
182
183 cmtp_send_capimsg(session, skb);
184 }
185
186 static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
187 {
188 struct capi_ctr *ctrl = &session->ctrl;
189 struct cmtp_application *application;
190 __u16 appl, msgnum, func, info;
191 __u32 controller;
192
193 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
194
195 switch (CAPIMSG_SUBCOMMAND(skb->data)) {
196 case CAPI_CONF:
197 if (skb->len < CAPI_MSG_BASELEN + 10)
198 break;
199
200 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
201 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
202
203 switch (func) {
204 case CAPI_FUNCTION_REGISTER:
205 msgnum = CAPIMSG_MSGID(skb->data);
206
207 application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
208 if (application) {
209 application->state = BT_CONNECTED;
210 application->msgnum = 0;
211 application->mapping = CAPIMSG_APPID(skb->data);
212 wake_up_interruptible(&session->wait);
213 }
214
215 break;
216
217 case CAPI_FUNCTION_RELEASE:
218 appl = CAPIMSG_APPID(skb->data);
219
220 application = cmtp_application_get(session, CMTP_MAPPING, appl);
221 if (application) {
222 application->state = BT_CLOSED;
223 application->msgnum = 0;
224 wake_up_interruptible(&session->wait);
225 }
226
227 break;
228
229 case CAPI_FUNCTION_GET_PROFILE:
230 if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile))
231 break;
232
233 controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
234 msgnum = CAPIMSG_MSGID(skb->data);
235
236 if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
237 session->ncontroller = controller;
238 wake_up_interruptible(&session->wait);
239 break;
240 }
241
242 if (!info && ctrl) {
243 memcpy(&ctrl->profile,
244 skb->data + CAPI_MSG_BASELEN + 11,
245 sizeof(capi_profile));
246 session->state = BT_CONNECTED;
247 capi_ctr_ready(ctrl);
248 }
249
250 break;
251
252 case CAPI_FUNCTION_GET_MANUFACTURER:
253 if (skb->len < CAPI_MSG_BASELEN + 15)
254 break;
255
256 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
257
258 if (!info && ctrl) {
259 int len = min_t(uint, CAPI_MANUFACTURER_LEN,
260 skb->data[CAPI_MSG_BASELEN + 14]);
261
262 memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN);
263 strncpy(ctrl->manu,
264 skb->data + CAPI_MSG_BASELEN + 15, len);
265 }
266
267 break;
268
269 case CAPI_FUNCTION_GET_VERSION:
270 if (skb->len < CAPI_MSG_BASELEN + 32)
271 break;
272
273 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
274
275 if (!info && ctrl) {
276 ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
277 ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
278 ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
279 ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
280 }
281
282 break;
283
284 case CAPI_FUNCTION_GET_SERIAL_NUMBER:
285 if (skb->len < CAPI_MSG_BASELEN + 17)
286 break;
287
288 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
289
290 if (!info && ctrl) {
291 int len = min_t(uint, CAPI_SERIAL_LEN,
292 skb->data[CAPI_MSG_BASELEN + 16]);
293
294 memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
295 strncpy(ctrl->serial,
296 skb->data + CAPI_MSG_BASELEN + 17, len);
297 }
298
299 break;
300 }
301
302 break;
303
304 case CAPI_IND:
305 if (skb->len < CAPI_MSG_BASELEN + 6)
306 break;
307
308 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
309
310 if (func == CAPI_FUNCTION_LOOPBACK) {
311 int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6,
312 skb->data[CAPI_MSG_BASELEN + 5]);
313 appl = CAPIMSG_APPID(skb->data);
314 msgnum = CAPIMSG_MSGID(skb->data);
315 cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
316 skb->data + CAPI_MSG_BASELEN + 6, len);
317 }
318
319 break;
320 }
321
322 kfree_skb(skb);
323 }
324
325 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
326 {
327 struct capi_ctr *ctrl = &session->ctrl;
328 struct cmtp_application *application;
329 __u16 appl;
330 __u32 contr;
331
332 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
333
334 if (skb->len < CAPI_MSG_BASELEN)
335 return;
336
337 if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
338 cmtp_recv_interopmsg(session, skb);
339 return;
340 }
341
342 if (session->flags & (1 << CMTP_LOOPBACK)) {
343 kfree_skb(skb);
344 return;
345 }
346
347 appl = CAPIMSG_APPID(skb->data);
348 contr = CAPIMSG_CONTROL(skb->data);
349
350 application = cmtp_application_get(session, CMTP_MAPPING, appl);
351 if (application) {
352 appl = application->appl;
353 CAPIMSG_SETAPPID(skb->data, appl);
354 } else {
355 BT_ERR("Can't find application with id %d", appl);
356 kfree_skb(skb);
357 return;
358 }
359
360 if ((contr & 0x7f) == 0x01) {
361 contr = (contr & 0xffffff80) | session->num;
362 CAPIMSG_SETCONTROL(skb->data, contr);
363 }
364
365 if (!ctrl) {
366 BT_ERR("Can't find controller %d for message", session->num);
367 kfree_skb(skb);
368 return;
369 }
370
371 capi_ctr_handle_message(ctrl, appl, skb);
372 }
373
374 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
375 {
376 BT_DBG("ctrl %p data %p", ctrl, data);
377
378 return 0;
379 }
380
381 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
382 {
383 struct cmtp_session *session = ctrl->driverdata;
384
385 BT_DBG("ctrl %p", ctrl);
386
387 capi_ctr_down(ctrl);
388
389 kthread_stop(session->task);
390 }
391
392 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
393 {
394 DECLARE_WAITQUEUE(wait, current);
395 struct cmtp_session *session = ctrl->driverdata;
396 struct cmtp_application *application;
397 unsigned long timeo = CMTP_INTEROP_TIMEOUT;
398 unsigned char buf[8];
399 int err = 0, nconn, want = rp->level3cnt;
400
401 BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
402 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
403
404 application = cmtp_application_add(session, appl);
405 if (!application) {
406 BT_ERR("Can't allocate memory for new application");
407 return;
408 }
409
410 if (want < 0)
411 nconn = ctrl->profile.nbchannel * -want;
412 else
413 nconn = want;
414
415 if (nconn == 0)
416 nconn = ctrl->profile.nbchannel;
417
418 capimsg_setu16(buf, 0, nconn);
419 capimsg_setu16(buf, 2, rp->datablkcnt);
420 capimsg_setu16(buf, 4, rp->datablklen);
421
422 application->state = BT_CONFIG;
423 application->msgnum = cmtp_msgnum_get(session);
424
425 cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
426 CAPI_FUNCTION_REGISTER, buf, 6);
427
428 add_wait_queue(&session->wait, &wait);
429 while (1) {
430 set_current_state(TASK_INTERRUPTIBLE);
431
432 if (!timeo) {
433 err = -EAGAIN;
434 break;
435 }
436
437 if (application->state == BT_CLOSED) {
438 err = -application->err;
439 break;
440 }
441
442 if (application->state == BT_CONNECTED)
443 break;
444
445 if (signal_pending(current)) {
446 err = -EINTR;
447 break;
448 }
449
450 timeo = schedule_timeout(timeo);
451 }
452 set_current_state(TASK_RUNNING);
453 remove_wait_queue(&session->wait, &wait);
454
455 if (err) {
456 cmtp_application_del(session, application);
457 return;
458 }
459 }
460
461 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
462 {
463 struct cmtp_session *session = ctrl->driverdata;
464 struct cmtp_application *application;
465
466 BT_DBG("ctrl %p appl %d", ctrl, appl);
467
468 application = cmtp_application_get(session, CMTP_APPLID, appl);
469 if (!application) {
470 BT_ERR("Can't find application");
471 return;
472 }
473
474 application->msgnum = cmtp_msgnum_get(session);
475
476 cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
477 CAPI_FUNCTION_RELEASE, NULL, 0);
478
479 wait_event_interruptible_timeout(session->wait,
480 (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
481
482 cmtp_application_del(session, application);
483 }
484
485 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
486 {
487 struct cmtp_session *session = ctrl->driverdata;
488 struct cmtp_application *application;
489 __u16 appl;
490 __u32 contr;
491
492 BT_DBG("ctrl %p skb %p", ctrl, skb);
493
494 appl = CAPIMSG_APPID(skb->data);
495 contr = CAPIMSG_CONTROL(skb->data);
496
497 application = cmtp_application_get(session, CMTP_APPLID, appl);
498 if ((!application) || (application->state != BT_CONNECTED)) {
499 BT_ERR("Can't find application with id %d", appl);
500 return CAPI_ILLAPPNR;
501 }
502
503 CAPIMSG_SETAPPID(skb->data, application->mapping);
504
505 if ((contr & 0x7f) == session->num) {
506 contr = (contr & 0xffffff80) | 0x01;
507 CAPIMSG_SETCONTROL(skb->data, contr);
508 }
509
510 cmtp_send_capimsg(session, skb);
511
512 return CAPI_NOERROR;
513 }
514
515 static char *cmtp_procinfo(struct capi_ctr *ctrl)
516 {
517 return "CAPI Message Transport Protocol";
518 }
519
520 static int cmtp_proc_show(struct seq_file *m, void *v)
521 {
522 struct capi_ctr *ctrl = m->private;
523 struct cmtp_session *session = ctrl->driverdata;
524 struct cmtp_application *app;
525 struct list_head *p, *n;
526
527 seq_printf(m, "%s\n\n", cmtp_procinfo(ctrl));
528 seq_printf(m, "addr %s\n", session->name);
529 seq_printf(m, "ctrl %d\n", session->num);
530
531 list_for_each_safe(p, n, &session->applications) {
532 app = list_entry(p, struct cmtp_application, list);
533 seq_printf(m, "appl %d -> %d\n", app->appl, app->mapping);
534 }
535
536 return 0;
537 }
538
539 static int cmtp_proc_open(struct inode *inode, struct file *file)
540 {
541 return single_open(file, cmtp_proc_show, PDE(inode)->data);
542 }
543
544 static const struct file_operations cmtp_proc_fops = {
545 .owner = THIS_MODULE,
546 .open = cmtp_proc_open,
547 .read = seq_read,
548 .llseek = seq_lseek,
549 .release = single_release,
550 };
551
552 int cmtp_attach_device(struct cmtp_session *session)
553 {
554 unsigned char buf[4];
555 long ret;
556
557 BT_DBG("session %p", session);
558
559 capimsg_setu32(buf, 0, 0);
560
561 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
562 CAPI_FUNCTION_GET_PROFILE, buf, 4);
563
564 ret = wait_event_interruptible_timeout(session->wait,
565 session->ncontroller, CMTP_INTEROP_TIMEOUT);
566
567 BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
568
569 if (!ret)
570 return -ETIMEDOUT;
571
572 if (!session->ncontroller)
573 return -ENODEV;
574
575 if (session->ncontroller > 1)
576 BT_INFO("Setting up only CAPI controller 1");
577
578 session->ctrl.owner = THIS_MODULE;
579 session->ctrl.driverdata = session;
580 strcpy(session->ctrl.name, session->name);
581
582 session->ctrl.driver_name = "cmtp";
583 session->ctrl.load_firmware = cmtp_load_firmware;
584 session->ctrl.reset_ctr = cmtp_reset_ctr;
585 session->ctrl.register_appl = cmtp_register_appl;
586 session->ctrl.release_appl = cmtp_release_appl;
587 session->ctrl.send_message = cmtp_send_message;
588
589 session->ctrl.procinfo = cmtp_procinfo;
590 session->ctrl.proc_fops = &cmtp_proc_fops;
591
592 if (attach_capi_ctr(&session->ctrl) < 0) {
593 BT_ERR("Can't attach new controller");
594 return -EBUSY;
595 }
596
597 session->num = session->ctrl.cnr;
598
599 BT_DBG("session %p num %d", session, session->num);
600
601 capimsg_setu32(buf, 0, 1);
602
603 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
604 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
605
606 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
607 CAPI_FUNCTION_GET_VERSION, buf, 4);
608
609 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
610 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
611
612 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
613 CAPI_FUNCTION_GET_PROFILE, buf, 4);
614
615 return 0;
616 }
617
618 void cmtp_detach_device(struct cmtp_session *session)
619 {
620 BT_DBG("session %p", session);
621
622 detach_capi_ctr(&session->ctrl);
623 }