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>
38 #include <linux/wait.h>
41 #include <linux/isdn/capilli.h>
42 #include <linux/isdn/capicmd.h>
43 #include <linux/isdn/capiutil.h>
47 #ifndef CONFIG_BT_CMTP_DEBUG
52 #define CAPI_INTEROPERABILITY 0x20
54 #define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
55 #define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
56 #define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
57 #define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
59 #define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
60 #define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
61 #define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
62 #define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
64 #define CAPI_FUNCTION_REGISTER 0
65 #define CAPI_FUNCTION_RELEASE 1
66 #define CAPI_FUNCTION_GET_PROFILE 2
67 #define CAPI_FUNCTION_GET_MANUFACTURER 3
68 #define CAPI_FUNCTION_GET_VERSION 4
69 #define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
70 #define CAPI_FUNCTION_MANUFACTURER 6
71 #define CAPI_FUNCTION_LOOPBACK 7
76 #define CMTP_MAPPING 3
78 static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
80 struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL);
82 BT_DBG("session %p application %p appl %d", session, app, appl);
87 memset(app, 0, sizeof(*app));
92 list_add_tail(&app->list, &session->applications);
97 static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
99 BT_DBG("session %p application %p", session, app);
102 list_del(&app->list);
107 static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
109 struct cmtp_application *app;
110 struct list_head *p, *n;
112 list_for_each_safe(p, n, &session->applications) {
113 app = list_entry(p, struct cmtp_application, list);
116 if (app->msgnum == value)
120 if (app->appl == value)
124 if (app->mapping == value)
133 static int cmtp_msgnum_get(struct cmtp_session *session)
137 if ((session->msgnum & 0xff) > 200)
138 session->msgnum = CMTP_INITIAL_MSGNUM + 1;
140 return session->msgnum;
143 static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
145 struct cmtp_scb *scb = (void *) skb->cb;
147 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
150 scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
152 skb_queue_tail(&session->transmit, skb);
154 cmtp_schedule(session);
157 static void cmtp_send_interopmsg(struct cmtp_session *session,
158 __u8 subcmd, __u16 appl, __u16 msgnum,
159 __u16 function, unsigned char *buf, int len)
164 BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
166 if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
167 BT_ERR("Can't allocate memory for interoperability packet");
171 s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
173 capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
174 capimsg_setu16(s, 2, appl);
175 capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
176 capimsg_setu8 (s, 5, subcmd);
177 capimsg_setu16(s, 6, msgnum);
179 /* Interoperability selector (Bluetooth Device Management) */
180 capimsg_setu16(s, 8, 0x0001);
182 capimsg_setu8 (s, 10, 3 + len);
183 capimsg_setu16(s, 11, function);
184 capimsg_setu8 (s, 13, len);
187 memcpy(s + 14, buf, len);
189 cmtp_send_capimsg(session, skb);
192 static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
194 struct capi_ctr *ctrl = &session->ctrl;
195 struct cmtp_application *application;
196 __u16 appl, msgnum, func, info;
199 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
201 switch (CAPIMSG_SUBCOMMAND(skb->data)) {
203 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
204 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
207 case CAPI_FUNCTION_REGISTER:
208 msgnum = CAPIMSG_MSGID(skb->data);
210 application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
212 application->state = BT_CONNECTED;
213 application->msgnum = 0;
214 application->mapping = CAPIMSG_APPID(skb->data);
215 wake_up_interruptible(&session->wait);
220 case CAPI_FUNCTION_RELEASE:
221 appl = CAPIMSG_APPID(skb->data);
223 application = cmtp_application_get(session, CMTP_MAPPING, appl);
225 application->state = BT_CLOSED;
226 application->msgnum = 0;
227 wake_up_interruptible(&session->wait);
232 case CAPI_FUNCTION_GET_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 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
257 skb->data + CAPI_MSG_BASELEN + 15,
258 skb->data[CAPI_MSG_BASELEN + 14]);
263 case CAPI_FUNCTION_GET_VERSION:
264 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
267 ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
268 ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
269 ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
270 ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
275 case CAPI_FUNCTION_GET_SERIAL_NUMBER:
276 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
279 memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
280 strncpy(ctrl->serial,
281 skb->data + CAPI_MSG_BASELEN + 17,
282 skb->data[CAPI_MSG_BASELEN + 16]);
291 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
293 if (func == CAPI_FUNCTION_LOOPBACK) {
294 appl = CAPIMSG_APPID(skb->data);
295 msgnum = CAPIMSG_MSGID(skb->data);
296 cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
297 skb->data + CAPI_MSG_BASELEN + 6,
298 skb->data[CAPI_MSG_BASELEN + 5]);
307 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
309 struct capi_ctr *ctrl = &session->ctrl;
310 struct cmtp_application *application;
314 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
316 if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
317 cmtp_recv_interopmsg(session, skb);
321 if (session->flags & (1 << CMTP_LOOPBACK)) {
326 cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
327 appl = CAPIMSG_APPID(skb->data);
328 contr = CAPIMSG_CONTROL(skb->data);
330 application = cmtp_application_get(session, CMTP_MAPPING, appl);
332 appl = application->appl;
333 CAPIMSG_SETAPPID(skb->data, appl);
335 BT_ERR("Can't find application with id %d", appl);
340 if ((contr & 0x7f) == 0x01) {
341 contr = (contr & 0xffffff80) | session->num;
342 CAPIMSG_SETCONTROL(skb->data, contr);
346 BT_ERR("Can't find controller %d for message", session->num);
351 capi_ctr_handle_message(ctrl, appl, skb);
354 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
356 BT_DBG("ctrl %p data %p", ctrl, data);
361 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
363 struct cmtp_session *session = ctrl->driverdata;
365 BT_DBG("ctrl %p", ctrl);
367 capi_ctr_reseted(ctrl);
369 atomic_inc(&session->terminate);
370 cmtp_schedule(session);
373 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
375 DECLARE_WAITQUEUE(wait, current);
376 struct cmtp_session *session = ctrl->driverdata;
377 struct cmtp_application *application;
378 unsigned long timeo = CMTP_INTEROP_TIMEOUT;
379 unsigned char buf[8];
380 int err = 0, nconn, want = rp->level3cnt;
382 BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
383 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
385 application = cmtp_application_add(session, appl);
387 BT_ERR("Can't allocate memory for new application");
392 nconn = ctrl->profile.nbchannel * -want;
397 nconn = ctrl->profile.nbchannel;
399 capimsg_setu16(buf, 0, nconn);
400 capimsg_setu16(buf, 2, rp->datablkcnt);
401 capimsg_setu16(buf, 4, rp->datablklen);
403 application->state = BT_CONFIG;
404 application->msgnum = cmtp_msgnum_get(session);
406 cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
407 CAPI_FUNCTION_REGISTER, buf, 6);
409 add_wait_queue(&session->wait, &wait);
411 set_current_state(TASK_INTERRUPTIBLE);
418 if (application->state == BT_CLOSED) {
419 err = -application->err;
423 if (application->state == BT_CONNECTED)
426 if (signal_pending(current)) {
431 timeo = schedule_timeout(timeo);
433 set_current_state(TASK_RUNNING);
434 remove_wait_queue(&session->wait, &wait);
437 cmtp_application_del(session, application);
442 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
444 struct cmtp_session *session = ctrl->driverdata;
445 struct cmtp_application *application;
447 BT_DBG("ctrl %p appl %d", ctrl, appl);
449 application = cmtp_application_get(session, CMTP_APPLID, appl);
451 BT_ERR("Can't find application");
455 application->msgnum = cmtp_msgnum_get(session);
457 cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
458 CAPI_FUNCTION_RELEASE, NULL, 0);
460 wait_event_interruptible_timeout(session->wait,
461 (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
463 cmtp_application_del(session, application);
466 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
468 struct cmtp_session *session = ctrl->driverdata;
469 struct cmtp_application *application;
473 BT_DBG("ctrl %p skb %p", ctrl, skb);
475 appl = CAPIMSG_APPID(skb->data);
476 contr = CAPIMSG_CONTROL(skb->data);
478 application = cmtp_application_get(session, CMTP_APPLID, appl);
479 if ((!application) || (application->state != BT_CONNECTED)) {
480 BT_ERR("Can't find application with id %d", appl);
481 return CAPI_ILLAPPNR;
484 CAPIMSG_SETAPPID(skb->data, application->mapping);
486 if ((contr & 0x7f) == session->num) {
487 contr = (contr & 0xffffff80) | 0x01;
488 CAPIMSG_SETCONTROL(skb->data, contr);
491 cmtp_send_capimsg(session, skb);
496 static char *cmtp_procinfo(struct capi_ctr *ctrl)
498 return "CAPI Message Transport Protocol";
501 static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
503 struct cmtp_session *session = ctrl->driverdata;
504 struct cmtp_application *app;
505 struct list_head *p, *n;
508 len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl));
509 len += sprintf(page + len, "addr %s\n", session->name);
510 len += sprintf(page + len, "ctrl %d\n", session->num);
512 list_for_each_safe(p, n, &session->applications) {
513 app = list_entry(p, struct cmtp_application, list);
514 len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
517 if (off + count >= len)
525 return ((count < len - off) ? count : len - off);
529 int cmtp_attach_device(struct cmtp_session *session)
531 unsigned char buf[4];
534 BT_DBG("session %p", session);
536 capimsg_setu32(buf, 0, 0);
538 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
539 CAPI_FUNCTION_GET_PROFILE, buf, 4);
541 ret = wait_event_interruptible_timeout(session->wait,
542 session->ncontroller, CMTP_INTEROP_TIMEOUT);
544 BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
549 if (!session->ncontroller)
552 if (session->ncontroller > 1)
553 BT_INFO("Setting up only CAPI controller 1");
555 session->ctrl.owner = THIS_MODULE;
556 session->ctrl.driverdata = session;
557 strcpy(session->ctrl.name, session->name);
559 session->ctrl.driver_name = "cmtp";
560 session->ctrl.load_firmware = cmtp_load_firmware;
561 session->ctrl.reset_ctr = cmtp_reset_ctr;
562 session->ctrl.register_appl = cmtp_register_appl;
563 session->ctrl.release_appl = cmtp_release_appl;
564 session->ctrl.send_message = cmtp_send_message;
566 session->ctrl.procinfo = cmtp_procinfo;
567 session->ctrl.ctr_read_proc = cmtp_ctr_read_proc;
569 if (attach_capi_ctr(&session->ctrl) < 0) {
570 BT_ERR("Can't attach new controller");
574 session->num = session->ctrl.cnr;
576 BT_DBG("session %p num %d", session, session->num);
578 capimsg_setu32(buf, 0, 1);
580 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
581 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
583 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
584 CAPI_FUNCTION_GET_VERSION, buf, 4);
586 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
587 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
589 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
590 CAPI_FUNCTION_GET_PROFILE, buf, 4);
595 void cmtp_detach_device(struct cmtp_session *session)
597 BT_DBG("session %p", session);
599 detach_capi_ctr(&session->ctrl);