2 CMTP implementation for Linux Bluetooth stack (BlueZ).
3 Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
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;
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.
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.
23 #include <linux/module.h>
24 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
25 #include <linux/proc_fs.h>
26 #include <linux/seq_file.h>
28 #include <linux/types.h>
29 #include <linux/errno.h>
30 #include <linux/kernel.h>
31 #include <linux/sched.h>
32 #include <linux/slab.h>
33 #include <linux/poll.h>
34 #include <linux/fcntl.h>
35 #include <linux/skbuff.h>
36 #include <linux/socket.h>
37 #include <linux/ioctl.h>
38 #include <linux/file.h>
39 #include <linux/wait.h>
42 #include <linux/isdn/capilli.h>
43 #include <linux/isdn/capicmd.h>
44 #include <linux/isdn/capiutil.h>
48 #define CAPI_INTEROPERABILITY 0x20
50 #define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
51 #define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
52 #define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
53 #define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
55 #define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
56 #define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
57 #define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
58 #define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
60 #define CAPI_FUNCTION_REGISTER 0
61 #define CAPI_FUNCTION_RELEASE 1
62 #define CAPI_FUNCTION_GET_PROFILE 2
63 #define CAPI_FUNCTION_GET_MANUFACTURER 3
64 #define CAPI_FUNCTION_GET_VERSION 4
65 #define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
66 #define CAPI_FUNCTION_MANUFACTURER 6
67 #define CAPI_FUNCTION_LOOPBACK 7
72 #define CMTP_MAPPING 3
74 static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
76 struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL);
78 BT_DBG("session %p application %p appl %d", session, app, appl);
86 list_add_tail(&app->list, &session->applications);
91 static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
93 BT_DBG("session %p application %p", session, app);
101 static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
103 struct cmtp_application *app;
104 struct list_head *p, *n;
106 list_for_each_safe(p, n, &session->applications) {
107 app = list_entry(p, struct cmtp_application, list);
110 if (app->msgnum == value)
114 if (app->appl == value)
118 if (app->mapping == value)
127 static int cmtp_msgnum_get(struct cmtp_session *session)
131 if ((session->msgnum & 0xff) > 200)
132 session->msgnum = CMTP_INITIAL_MSGNUM + 1;
134 return session->msgnum;
137 static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
139 struct cmtp_scb *scb = (void *) skb->cb;
141 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
144 scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
146 skb_queue_tail(&session->transmit, skb);
148 cmtp_schedule(session);
151 static void cmtp_send_interopmsg(struct cmtp_session *session,
152 __u8 subcmd, __u16 appl, __u16 msgnum,
153 __u16 function, unsigned char *buf, int len)
158 BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
160 if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
161 BT_ERR("Can't allocate memory for interoperability packet");
165 s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
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);
173 /* Interoperability selector (Bluetooth Device Management) */
174 capimsg_setu16(s, 8, 0x0001);
176 capimsg_setu8 (s, 10, 3 + len);
177 capimsg_setu16(s, 11, function);
178 capimsg_setu8 (s, 13, len);
181 memcpy(s + 14, buf, len);
183 cmtp_send_capimsg(session, skb);
186 static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
188 struct capi_ctr *ctrl = &session->ctrl;
189 struct cmtp_application *application;
190 __u16 appl, msgnum, func, info;
193 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
195 switch (CAPIMSG_SUBCOMMAND(skb->data)) {
197 if (skb->len < CAPI_MSG_BASELEN + 10)
200 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
201 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
204 case CAPI_FUNCTION_REGISTER:
205 msgnum = CAPIMSG_MSGID(skb->data);
207 application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
209 application->state = BT_CONNECTED;
210 application->msgnum = 0;
211 application->mapping = CAPIMSG_APPID(skb->data);
212 wake_up_interruptible(&session->wait);
217 case CAPI_FUNCTION_RELEASE:
218 appl = CAPIMSG_APPID(skb->data);
220 application = cmtp_application_get(session, CMTP_MAPPING, appl);
222 application->state = BT_CLOSED;
223 application->msgnum = 0;
224 wake_up_interruptible(&session->wait);
229 case CAPI_FUNCTION_GET_PROFILE:
230 if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile))
233 controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
234 msgnum = CAPIMSG_MSGID(skb->data);
236 if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
237 session->ncontroller = controller;
238 wake_up_interruptible(&session->wait);
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);
252 case CAPI_FUNCTION_GET_MANUFACTURER:
253 if (skb->len < CAPI_MSG_BASELEN + 15)
256 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
259 int len = min_t(uint, CAPI_MANUFACTURER_LEN,
260 skb->data[CAPI_MSG_BASELEN + 14]);
262 memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN);
264 skb->data + CAPI_MSG_BASELEN + 15, len);
269 case CAPI_FUNCTION_GET_VERSION:
270 if (skb->len < CAPI_MSG_BASELEN + 32)
273 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
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);
284 case CAPI_FUNCTION_GET_SERIAL_NUMBER:
285 if (skb->len < CAPI_MSG_BASELEN + 17)
288 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
291 int len = min_t(uint, CAPI_SERIAL_LEN,
292 skb->data[CAPI_MSG_BASELEN + 16]);
294 memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
295 strncpy(ctrl->serial,
296 skb->data + CAPI_MSG_BASELEN + 17, len);
305 if (skb->len < CAPI_MSG_BASELEN + 6)
308 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
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);
325 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
327 struct capi_ctr *ctrl = &session->ctrl;
328 struct cmtp_application *application;
332 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
334 if (skb->len < CAPI_MSG_BASELEN)
337 if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
338 cmtp_recv_interopmsg(session, skb);
342 if (session->flags & (1 << CMTP_LOOPBACK)) {
347 cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
348 appl = CAPIMSG_APPID(skb->data);
349 contr = CAPIMSG_CONTROL(skb->data);
351 application = cmtp_application_get(session, CMTP_MAPPING, appl);
353 appl = application->appl;
354 CAPIMSG_SETAPPID(skb->data, appl);
356 BT_ERR("Can't find application with id %d", appl);
361 if ((contr & 0x7f) == 0x01) {
362 contr = (contr & 0xffffff80) | session->num;
363 CAPIMSG_SETCONTROL(skb->data, contr);
367 BT_ERR("Can't find controller %d for message", session->num);
372 capi_ctr_handle_message(ctrl, appl, skb);
375 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
377 BT_DBG("ctrl %p data %p", ctrl, data);
382 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
384 struct cmtp_session *session = ctrl->driverdata;
386 BT_DBG("ctrl %p", ctrl);
388 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30))
391 capi_ctr_reseted(ctrl);
394 atomic_inc(&session->terminate);
395 cmtp_schedule(session);
398 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
400 DECLARE_WAITQUEUE(wait, current);
401 struct cmtp_session *session = ctrl->driverdata;
402 struct cmtp_application *application;
403 unsigned long timeo = CMTP_INTEROP_TIMEOUT;
404 unsigned char buf[8];
405 int err = 0, nconn, want = rp->level3cnt;
407 BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
408 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
410 application = cmtp_application_add(session, appl);
412 BT_ERR("Can't allocate memory for new application");
417 nconn = ctrl->profile.nbchannel * -want;
422 nconn = ctrl->profile.nbchannel;
424 capimsg_setu16(buf, 0, nconn);
425 capimsg_setu16(buf, 2, rp->datablkcnt);
426 capimsg_setu16(buf, 4, rp->datablklen);
428 application->state = BT_CONFIG;
429 application->msgnum = cmtp_msgnum_get(session);
431 cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
432 CAPI_FUNCTION_REGISTER, buf, 6);
434 add_wait_queue(&session->wait, &wait);
436 set_current_state(TASK_INTERRUPTIBLE);
443 if (application->state == BT_CLOSED) {
444 err = -application->err;
448 if (application->state == BT_CONNECTED)
451 if (signal_pending(current)) {
456 timeo = schedule_timeout(timeo);
458 set_current_state(TASK_RUNNING);
459 remove_wait_queue(&session->wait, &wait);
462 cmtp_application_del(session, application);
467 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
469 struct cmtp_session *session = ctrl->driverdata;
470 struct cmtp_application *application;
472 BT_DBG("ctrl %p appl %d", ctrl, appl);
474 application = cmtp_application_get(session, CMTP_APPLID, appl);
476 BT_ERR("Can't find application");
480 application->msgnum = cmtp_msgnum_get(session);
482 cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
483 CAPI_FUNCTION_RELEASE, NULL, 0);
485 wait_event_interruptible_timeout(session->wait,
486 (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
488 cmtp_application_del(session, application);
491 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
493 struct cmtp_session *session = ctrl->driverdata;
494 struct cmtp_application *application;
498 BT_DBG("ctrl %p skb %p", ctrl, skb);
500 appl = CAPIMSG_APPID(skb->data);
501 contr = CAPIMSG_CONTROL(skb->data);
503 application = cmtp_application_get(session, CMTP_APPLID, appl);
504 if ((!application) || (application->state != BT_CONNECTED)) {
505 BT_ERR("Can't find application with id %d", appl);
506 return CAPI_ILLAPPNR;
509 CAPIMSG_SETAPPID(skb->data, application->mapping);
511 if ((contr & 0x7f) == session->num) {
512 contr = (contr & 0xffffff80) | 0x01;
513 CAPIMSG_SETCONTROL(skb->data, contr);
516 cmtp_send_capimsg(session, skb);
521 static char *cmtp_procinfo(struct capi_ctr *ctrl)
523 return "CAPI Message Transport Protocol";
526 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
527 static int cmtp_proc_show(struct seq_file *m, void *v)
529 struct capi_ctr *ctrl = m->private;
530 struct cmtp_session *session = ctrl->driverdata;
531 struct cmtp_application *app;
532 struct list_head *p, *n;
534 seq_printf(m, "%s\n\n", cmtp_procinfo(ctrl));
535 seq_printf(m, "addr %s\n", session->name);
536 seq_printf(m, "ctrl %d\n", session->num);
538 list_for_each_safe(p, n, &session->applications) {
539 app = list_entry(p, struct cmtp_application, list);
540 seq_printf(m, "appl %d -> %d\n", app->appl, app->mapping);
546 static int cmtp_proc_open(struct inode *inode, struct file *file)
548 return single_open(file, cmtp_proc_show, PDE(inode)->data);
551 static const struct file_operations cmtp_proc_fops = {
552 .owner = THIS_MODULE,
553 .open = cmtp_proc_open,
556 .release = single_release,
561 static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
563 struct cmtp_session *session = ctrl->driverdata;
564 struct cmtp_application *app;
565 struct list_head *p, *n;
568 len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl));
569 len += sprintf(page + len, "addr %s\n", session->name);
570 len += sprintf(page + len, "ctrl %d\n", session->num);
572 list_for_each_safe(p, n, &session->applications) {
573 app = list_entry(p, struct cmtp_application, list);
574 len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
577 if (off + count >= len)
585 return ((count < len - off) ? count : len - off);
589 int cmtp_attach_device(struct cmtp_session *session)
591 unsigned char buf[4];
594 BT_DBG("session %p", session);
596 capimsg_setu32(buf, 0, 0);
598 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
599 CAPI_FUNCTION_GET_PROFILE, buf, 4);
601 ret = wait_event_interruptible_timeout(session->wait,
602 session->ncontroller, CMTP_INTEROP_TIMEOUT);
604 BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
609 if (!session->ncontroller)
612 if (session->ncontroller > 1)
613 BT_INFO("Setting up only CAPI controller 1");
615 session->ctrl.owner = THIS_MODULE;
616 session->ctrl.driverdata = session;
617 strcpy(session->ctrl.name, session->name);
619 session->ctrl.driver_name = "cmtp";
620 session->ctrl.load_firmware = cmtp_load_firmware;
621 session->ctrl.reset_ctr = cmtp_reset_ctr;
622 session->ctrl.register_appl = cmtp_register_appl;
623 session->ctrl.release_appl = cmtp_release_appl;
624 session->ctrl.send_message = cmtp_send_message;
626 session->ctrl.procinfo = cmtp_procinfo;
627 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34))
628 session->ctrl.proc_fops = &cmtp_proc_fops;
630 session->ctrl.ctr_read_proc = cmtp_ctr_read_proc;
633 if (attach_capi_ctr(&session->ctrl) < 0) {
634 BT_ERR("Can't attach new controller");
638 session->num = session->ctrl.cnr;
640 BT_DBG("session %p num %d", session, session->num);
642 capimsg_setu32(buf, 0, 1);
644 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
645 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
647 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
648 CAPI_FUNCTION_GET_VERSION, buf, 4);
650 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
651 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
653 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
654 CAPI_FUNCTION_GET_PROFILE, buf, 4);
659 void cmtp_detach_device(struct cmtp_session *session)
661 BT_DBG("session %p", session);
663 detach_capi_ctr(&session->ctrl);