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/config.h>
24 #include <linux/module.h>
26 #include <linux/types.h>
27 #include <linux/errno.h>
28 #include <linux/kernel.h>
29 #include <linux/major.h>
30 #include <linux/sched.h>
31 #include <linux/slab.h>
32 #include <linux/poll.h>
33 #include <linux/fcntl.h>
34 #include <linux/skbuff.h>
35 #include <linux/socket.h>
36 #include <linux/ioctl.h>
37 #include <linux/file.h>
40 #include <linux/isdn/capilli.h>
41 #include <linux/isdn/capicmd.h>
42 #include <linux/isdn/capiutil.h>
46 #ifndef CONFIG_BT_CMTP_DEBUG
51 #define CAPI_INTEROPERABILITY 0x20
53 #define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
54 #define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
55 #define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
56 #define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
58 #define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
59 #define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
60 #define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
61 #define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
63 #define CAPI_FUNCTION_REGISTER 0
64 #define CAPI_FUNCTION_RELEASE 1
65 #define CAPI_FUNCTION_GET_PROFILE 2
66 #define CAPI_FUNCTION_GET_MANUFACTURER 3
67 #define CAPI_FUNCTION_GET_VERSION 4
68 #define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
69 #define CAPI_FUNCTION_MANUFACTURER 6
70 #define CAPI_FUNCTION_LOOPBACK 7
75 #define CMTP_MAPPING 3
77 static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
79 struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL);
81 BT_DBG("session %p application %p appl %d", session, app, appl);
86 memset(app, 0, sizeof(*app));
91 list_add_tail(&app->list, &session->applications);
96 static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
98 BT_DBG("session %p application %p", session, app);
101 list_del(&app->list);
106 static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
108 struct cmtp_application *app;
109 struct list_head *p, *n;
111 list_for_each_safe(p, n, &session->applications) {
112 app = list_entry(p, struct cmtp_application, list);
115 if (app->msgnum == value)
119 if (app->appl == value)
123 if (app->mapping == value)
132 static int cmtp_msgnum_get(struct cmtp_session *session)
136 if ((session->msgnum & 0xff) > 200)
137 session->msgnum = CMTP_INITIAL_MSGNUM + 1;
139 return session->msgnum;
143 static void cmtp_send_interopmsg(struct cmtp_session *session,
144 __u8 subcmd, __u16 appl, __u16 msgnum,
145 __u16 function, unsigned char *buf, int len)
150 BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
152 if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
153 BT_ERR("Can't allocate memory for interoperability packet");
157 s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
159 capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
160 capimsg_setu16(s, 2, appl);
161 capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
162 capimsg_setu8 (s, 5, subcmd);
163 capimsg_setu16(s, 6, msgnum);
165 /* Interoperability selector (Bluetooth Device Management) */
166 capimsg_setu16(s, 8, 0x0001);
168 capimsg_setu8 (s, 10, 3 + len);
169 capimsg_setu16(s, 11, function);
170 capimsg_setu8 (s, 13, len);
173 memcpy(s + 14, buf, len);
175 cmtp_send_capimsg(session, skb);
178 static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
180 struct capi_ctr *ctrl = &session->ctrl;
181 struct cmtp_application *application;
182 __u16 appl, msgnum, func, info;
185 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
187 switch (CAPIMSG_SUBCOMMAND(skb->data)) {
189 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
190 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
193 case CAPI_FUNCTION_REGISTER:
194 msgnum = CAPIMSG_MSGID(skb->data);
196 application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
198 application->state = BT_CONNECTED;
199 application->msgnum = 0;
200 application->mapping = CAPIMSG_APPID(skb->data);
201 wake_up_interruptible(&session->wait);
206 case CAPI_FUNCTION_RELEASE:
207 appl = CAPIMSG_APPID(skb->data);
209 application = cmtp_application_get(session, CMTP_MAPPING, appl);
211 application->state = BT_CLOSED;
212 application->msgnum = 0;
213 wake_up_interruptible(&session->wait);
218 case CAPI_FUNCTION_GET_PROFILE:
219 controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
220 msgnum = CAPIMSG_MSGID(skb->data);
222 if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
223 session->ncontroller = controller;
224 wake_up_interruptible(&session->wait);
229 memcpy(&ctrl->profile,
230 skb->data + CAPI_MSG_BASELEN + 11,
231 sizeof(capi_profile));
232 session->state = BT_CONNECTED;
233 capi_ctr_ready(ctrl);
238 case CAPI_FUNCTION_GET_MANUFACTURER:
239 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
243 skb->data + CAPI_MSG_BASELEN + 15,
244 skb->data[CAPI_MSG_BASELEN + 14]);
249 case CAPI_FUNCTION_GET_VERSION:
250 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
253 ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
254 ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
255 ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
256 ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
261 case CAPI_FUNCTION_GET_SERIAL_NUMBER:
262 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
265 memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
266 strncpy(ctrl->serial,
267 skb->data + CAPI_MSG_BASELEN + 17,
268 skb->data[CAPI_MSG_BASELEN + 16]);
277 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
279 if (func == CAPI_FUNCTION_LOOPBACK) {
280 appl = CAPIMSG_APPID(skb->data);
281 msgnum = CAPIMSG_MSGID(skb->data);
282 cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
283 skb->data + CAPI_MSG_BASELEN + 6,
284 skb->data[CAPI_MSG_BASELEN + 5]);
293 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
295 struct capi_ctr *ctrl = &session->ctrl;
296 struct cmtp_application *application;
300 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
302 if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
303 cmtp_recv_interopmsg(session, skb);
307 if (session->flags & (1 << CMTP_LOOPBACK)) {
312 cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
313 appl = CAPIMSG_APPID(skb->data);
314 contr = CAPIMSG_CONTROL(skb->data);
316 application = cmtp_application_get(session, CMTP_MAPPING, appl);
318 appl = application->appl;
319 CAPIMSG_SETAPPID(skb->data, appl);
321 BT_ERR("Can't find application with id %d", appl);
326 if ((contr & 0x7f) == 0x01) {
327 contr = (contr & 0xffffff80) | session->num;
328 CAPIMSG_SETCONTROL(skb->data, contr);
332 BT_ERR("Can't find controller %d for message", session->num);
337 capi_ctr_handle_message(ctrl, appl, skb);
340 void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
342 struct cmtp_scb *scb = (void *) skb->cb;
344 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
347 scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
349 skb_queue_tail(&session->transmit, skb);
351 cmtp_schedule(session);
355 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
357 BT_DBG("ctrl %p data %p", ctrl, data);
362 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
364 struct cmtp_session *session = ctrl->driverdata;
366 BT_DBG("ctrl %p", ctrl);
368 capi_ctr_reseted(ctrl);
370 atomic_inc(&session->terminate);
371 cmtp_schedule(session);
374 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
376 DECLARE_WAITQUEUE(wait, current);
377 struct cmtp_session *session = ctrl->driverdata;
378 struct cmtp_application *application;
379 unsigned long timeo = CMTP_INTEROP_TIMEOUT;
380 unsigned char buf[8];
381 int err = 0, nconn, want = rp->level3cnt;
383 BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
384 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
386 application = cmtp_application_add(session, appl);
388 BT_ERR("Can't allocate memory for new application");
393 nconn = ctrl->profile.nbchannel * -want;
398 nconn = ctrl->profile.nbchannel;
400 capimsg_setu16(buf, 0, nconn);
401 capimsg_setu16(buf, 2, rp->datablkcnt);
402 capimsg_setu16(buf, 4, rp->datablklen);
404 application->state = BT_CONFIG;
405 application->msgnum = cmtp_msgnum_get(session);
407 cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
408 CAPI_FUNCTION_REGISTER, buf, 6);
410 add_wait_queue(&session->wait, &wait);
412 set_current_state(TASK_INTERRUPTIBLE);
419 if (application->state == BT_CLOSED) {
420 err = -application->err;
424 if (application->state == BT_CONNECTED)
427 if (signal_pending(current)) {
432 timeo = schedule_timeout(timeo);
434 set_current_state(TASK_RUNNING);
435 remove_wait_queue(&session->wait, &wait);
438 cmtp_application_del(session, application);
443 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
445 DECLARE_WAITQUEUE(wait, current);
446 struct cmtp_session *session = ctrl->driverdata;
447 struct cmtp_application *application;
448 unsigned long timeo = CMTP_INTEROP_TIMEOUT;
450 BT_DBG("ctrl %p appl %d", ctrl, appl);
452 application = cmtp_application_get(session, CMTP_APPLID, appl);
454 BT_ERR("Can't find application");
458 application->msgnum = cmtp_msgnum_get(session);
460 cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
461 CAPI_FUNCTION_RELEASE, NULL, 0);
463 add_wait_queue(&session->wait, &wait);
465 set_current_state(TASK_INTERRUPTIBLE);
467 if (application->state == BT_CLOSED)
470 if (signal_pending(current))
473 timeo = schedule_timeout(timeo);
475 set_current_state(TASK_RUNNING);
476 remove_wait_queue(&session->wait, &wait);
478 cmtp_application_del(session, application);
481 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
483 struct cmtp_session *session = ctrl->driverdata;
484 struct cmtp_application *application;
488 BT_DBG("ctrl %p skb %p", ctrl, skb);
490 appl = CAPIMSG_APPID(skb->data);
491 contr = CAPIMSG_CONTROL(skb->data);
493 application = cmtp_application_get(session, CMTP_APPLID, appl);
494 if ((!application) || (application->state != BT_CONNECTED)) {
495 BT_ERR("Can't find application with id %d", appl);
497 return CAPI_ILLAPPNR;
500 CAPIMSG_SETAPPID(skb->data, application->mapping);
502 if ((contr & 0x7f) == session->num) {
503 contr = (contr & 0xffffff80) | 0x01;
504 CAPIMSG_SETCONTROL(skb->data, contr);
507 cmtp_send_capimsg(session, skb);
512 static char *cmtp_procinfo(struct capi_ctr *ctrl)
514 return "CAPI Message Transport Protocol";
517 static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
519 struct cmtp_session *session = ctrl->driverdata;
520 struct cmtp_application *app;
521 struct list_head *p, *n;
524 len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl));
525 len += sprintf(page + len, "addr %s\n", session->name);
526 len += sprintf(page + len, "ctrl %d\n", session->num);
528 list_for_each_safe(p, n, &session->applications) {
529 app = list_entry(p, struct cmtp_application, list);
530 len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
533 if (off + count >= len)
541 return ((count < len - off) ? count : len - off);
545 int cmtp_attach_device(struct cmtp_session *session)
547 DECLARE_WAITQUEUE(wait, current);
548 unsigned long timeo = CMTP_INTEROP_TIMEOUT;
549 unsigned char buf[4];
551 BT_DBG("session %p", session);
553 capimsg_setu32(buf, 0, 0);
555 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
556 CAPI_FUNCTION_GET_PROFILE, buf, 4);
558 add_wait_queue(&session->wait, &wait);
560 set_current_state(TASK_INTERRUPTIBLE);
562 if (session->ncontroller)
565 if (signal_pending(current))
568 timeo = schedule_timeout(timeo);
570 set_current_state(TASK_RUNNING);
571 remove_wait_queue(&session->wait, &wait);
573 BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
578 if (!session->ncontroller)
582 if (session->ncontroller > 1)
583 BT_INFO("Setting up only CAPI controller 1");
585 session->ctrl.owner = THIS_MODULE;
586 session->ctrl.driverdata = session;
587 strcpy(session->ctrl.name, session->name);
589 session->ctrl.driver_name = "cmtp";
590 session->ctrl.load_firmware = cmtp_load_firmware;
591 session->ctrl.reset_ctr = cmtp_reset_ctr;
592 session->ctrl.register_appl = cmtp_register_appl;
593 session->ctrl.release_appl = cmtp_release_appl;
594 session->ctrl.send_message = cmtp_send_message;
596 session->ctrl.procinfo = cmtp_procinfo;
597 session->ctrl.ctr_read_proc = cmtp_ctr_read_proc;
599 if (attach_capi_ctr(&session->ctrl) < 0) {
600 BT_ERR("Can't attach new controller");
604 session->num = session->ctrl.cnr;
606 BT_DBG("session %p num %d", session, session->num);
608 capimsg_setu32(buf, 0, 1);
610 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
611 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
613 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
614 CAPI_FUNCTION_GET_VERSION, buf, 4);
616 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
617 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
619 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
620 CAPI_FUNCTION_GET_PROFILE, buf, 4);
625 void cmtp_detach_device(struct cmtp_session *session)
627 BT_DBG("session %p", session);
629 detach_capi_ctr(&session->ctrl);