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/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>
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;
142 static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
144 struct cmtp_scb *scb = (void *) skb->cb;
146 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
149 scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
151 skb_queue_tail(&session->transmit, skb);
153 cmtp_schedule(session);
156 static void cmtp_send_interopmsg(struct cmtp_session *session,
157 __u8 subcmd, __u16 appl, __u16 msgnum,
158 __u16 function, unsigned char *buf, int len)
163 BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
165 if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
166 BT_ERR("Can't allocate memory for interoperability packet");
170 s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
172 capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
173 capimsg_setu16(s, 2, appl);
174 capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
175 capimsg_setu8 (s, 5, subcmd);
176 capimsg_setu16(s, 6, msgnum);
178 /* Interoperability selector (Bluetooth Device Management) */
179 capimsg_setu16(s, 8, 0x0001);
181 capimsg_setu8 (s, 10, 3 + len);
182 capimsg_setu16(s, 11, function);
183 capimsg_setu8 (s, 13, len);
186 memcpy(s + 14, buf, len);
188 cmtp_send_capimsg(session, skb);
191 static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
193 struct capi_ctr *ctrl = &session->ctrl;
194 struct cmtp_application *application;
195 __u16 appl, msgnum, func, info;
198 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
200 switch (CAPIMSG_SUBCOMMAND(skb->data)) {
202 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
203 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
206 case CAPI_FUNCTION_REGISTER:
207 msgnum = CAPIMSG_MSGID(skb->data);
209 application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
211 application->state = BT_CONNECTED;
212 application->msgnum = 0;
213 application->mapping = CAPIMSG_APPID(skb->data);
214 wake_up_interruptible(&session->wait);
219 case CAPI_FUNCTION_RELEASE:
220 appl = CAPIMSG_APPID(skb->data);
222 application = cmtp_application_get(session, CMTP_MAPPING, appl);
224 application->state = BT_CLOSED;
225 application->msgnum = 0;
226 wake_up_interruptible(&session->wait);
231 case CAPI_FUNCTION_GET_PROFILE:
232 controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
233 msgnum = CAPIMSG_MSGID(skb->data);
235 if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
236 session->ncontroller = controller;
237 wake_up_interruptible(&session->wait);
242 memcpy(&ctrl->profile,
243 skb->data + CAPI_MSG_BASELEN + 11,
244 sizeof(capi_profile));
245 session->state = BT_CONNECTED;
246 capi_ctr_ready(ctrl);
251 case CAPI_FUNCTION_GET_MANUFACTURER:
252 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
256 skb->data + CAPI_MSG_BASELEN + 15,
257 skb->data[CAPI_MSG_BASELEN + 14]);
262 case CAPI_FUNCTION_GET_VERSION:
263 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
266 ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
267 ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
268 ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
269 ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
274 case CAPI_FUNCTION_GET_SERIAL_NUMBER:
275 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
278 memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
279 strncpy(ctrl->serial,
280 skb->data + CAPI_MSG_BASELEN + 17,
281 skb->data[CAPI_MSG_BASELEN + 16]);
290 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
292 if (func == CAPI_FUNCTION_LOOPBACK) {
293 appl = CAPIMSG_APPID(skb->data);
294 msgnum = CAPIMSG_MSGID(skb->data);
295 cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
296 skb->data + CAPI_MSG_BASELEN + 6,
297 skb->data[CAPI_MSG_BASELEN + 5]);
306 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
308 struct capi_ctr *ctrl = &session->ctrl;
309 struct cmtp_application *application;
313 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
315 if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
316 cmtp_recv_interopmsg(session, skb);
320 if (session->flags & (1 << CMTP_LOOPBACK)) {
325 cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
326 appl = CAPIMSG_APPID(skb->data);
327 contr = CAPIMSG_CONTROL(skb->data);
329 application = cmtp_application_get(session, CMTP_MAPPING, appl);
331 appl = application->appl;
332 CAPIMSG_SETAPPID(skb->data, appl);
334 BT_ERR("Can't find application with id %d", appl);
339 if ((contr & 0x7f) == 0x01) {
340 contr = (contr & 0xffffff80) | session->num;
341 CAPIMSG_SETCONTROL(skb->data, contr);
345 BT_ERR("Can't find controller %d for message", session->num);
350 capi_ctr_handle_message(ctrl, appl, skb);
353 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
355 BT_DBG("ctrl %p data %p", ctrl, data);
360 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
362 struct cmtp_session *session = ctrl->driverdata;
364 BT_DBG("ctrl %p", ctrl);
366 capi_ctr_reseted(ctrl);
368 atomic_inc(&session->terminate);
369 cmtp_schedule(session);
372 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
374 DECLARE_WAITQUEUE(wait, current);
375 struct cmtp_session *session = ctrl->driverdata;
376 struct cmtp_application *application;
377 unsigned long timeo = CMTP_INTEROP_TIMEOUT;
378 unsigned char buf[8];
379 int err = 0, nconn, want = rp->level3cnt;
381 BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
382 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
384 application = cmtp_application_add(session, appl);
386 BT_ERR("Can't allocate memory for new application");
391 nconn = ctrl->profile.nbchannel * -want;
396 nconn = ctrl->profile.nbchannel;
398 capimsg_setu16(buf, 0, nconn);
399 capimsg_setu16(buf, 2, rp->datablkcnt);
400 capimsg_setu16(buf, 4, rp->datablklen);
402 application->state = BT_CONFIG;
403 application->msgnum = cmtp_msgnum_get(session);
405 cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
406 CAPI_FUNCTION_REGISTER, buf, 6);
408 add_wait_queue(&session->wait, &wait);
410 set_current_state(TASK_INTERRUPTIBLE);
417 if (application->state == BT_CLOSED) {
418 err = -application->err;
422 if (application->state == BT_CONNECTED)
425 if (signal_pending(current)) {
430 timeo = schedule_timeout(timeo);
432 set_current_state(TASK_RUNNING);
433 remove_wait_queue(&session->wait, &wait);
436 cmtp_application_del(session, application);
441 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
443 struct cmtp_session *session = ctrl->driverdata;
444 struct cmtp_application *application;
446 BT_DBG("ctrl %p appl %d", ctrl, appl);
448 application = cmtp_application_get(session, CMTP_APPLID, appl);
450 BT_ERR("Can't find application");
454 application->msgnum = cmtp_msgnum_get(session);
456 cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
457 CAPI_FUNCTION_RELEASE, NULL, 0);
459 wait_event_interruptible_timeout(session->wait,
460 (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
462 cmtp_application_del(session, application);
465 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
467 struct cmtp_session *session = ctrl->driverdata;
468 struct cmtp_application *application;
472 BT_DBG("ctrl %p skb %p", ctrl, skb);
474 appl = CAPIMSG_APPID(skb->data);
475 contr = CAPIMSG_CONTROL(skb->data);
477 application = cmtp_application_get(session, CMTP_APPLID, appl);
478 if ((!application) || (application->state != BT_CONNECTED)) {
479 BT_ERR("Can't find application with id %d", appl);
480 return CAPI_ILLAPPNR;
483 CAPIMSG_SETAPPID(skb->data, application->mapping);
485 if ((contr & 0x7f) == session->num) {
486 contr = (contr & 0xffffff80) | 0x01;
487 CAPIMSG_SETCONTROL(skb->data, contr);
490 cmtp_send_capimsg(session, skb);
495 static char *cmtp_procinfo(struct capi_ctr *ctrl)
497 return "CAPI Message Transport Protocol";
500 static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
502 struct cmtp_session *session = ctrl->driverdata;
503 struct cmtp_application *app;
504 struct list_head *p, *n;
507 len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl));
508 len += sprintf(page + len, "addr %s\n", session->name);
509 len += sprintf(page + len, "ctrl %d\n", session->num);
511 list_for_each_safe(p, n, &session->applications) {
512 app = list_entry(p, struct cmtp_application, list);
513 len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
516 if (off + count >= len)
524 return ((count < len - off) ? count : len - off);
528 int cmtp_attach_device(struct cmtp_session *session)
530 unsigned char buf[4];
533 BT_DBG("session %p", session);
535 capimsg_setu32(buf, 0, 0);
537 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
538 CAPI_FUNCTION_GET_PROFILE, buf, 4);
540 ret = wait_event_interruptible_timeout(session->wait,
541 session->ncontroller, CMTP_INTEROP_TIMEOUT);
543 BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
548 if (!session->ncontroller)
551 if (session->ncontroller > 1)
552 BT_INFO("Setting up only CAPI controller 1");
554 session->ctrl.owner = THIS_MODULE;
555 session->ctrl.driverdata = session;
556 strcpy(session->ctrl.name, session->name);
558 session->ctrl.driver_name = "cmtp";
559 session->ctrl.load_firmware = cmtp_load_firmware;
560 session->ctrl.reset_ctr = cmtp_reset_ctr;
561 session->ctrl.register_appl = cmtp_register_appl;
562 session->ctrl.release_appl = cmtp_release_appl;
563 session->ctrl.send_message = cmtp_send_message;
565 session->ctrl.procinfo = cmtp_procinfo;
566 session->ctrl.ctr_read_proc = cmtp_ctr_read_proc;
568 if (attach_capi_ctr(&session->ctrl) < 0) {
569 BT_ERR("Can't attach new controller");
573 session->num = session->ctrl.cnr;
575 BT_DBG("session %p num %d", session, session->num);
577 capimsg_setu32(buf, 0, 1);
579 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
580 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
582 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
583 CAPI_FUNCTION_GET_VERSION, buf, 4);
585 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
586 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
588 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
589 CAPI_FUNCTION_GET_PROFILE, buf, 4);
594 void cmtp_detach_device(struct cmtp_session *session)
596 BT_DBG("session %p", session);
598 detach_capi_ctr(&session->ctrl);