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 if (skb->len < CAPI_MSG_BASELEN + 10)
205 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
206 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
209 case CAPI_FUNCTION_REGISTER:
210 msgnum = CAPIMSG_MSGID(skb->data);
212 application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
214 application->state = BT_CONNECTED;
215 application->msgnum = 0;
216 application->mapping = CAPIMSG_APPID(skb->data);
217 wake_up_interruptible(&session->wait);
222 case CAPI_FUNCTION_RELEASE:
223 appl = CAPIMSG_APPID(skb->data);
225 application = cmtp_application_get(session, CMTP_MAPPING, appl);
227 application->state = BT_CLOSED;
228 application->msgnum = 0;
229 wake_up_interruptible(&session->wait);
234 case CAPI_FUNCTION_GET_PROFILE:
235 if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile))
238 controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
239 msgnum = CAPIMSG_MSGID(skb->data);
241 if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
242 session->ncontroller = controller;
243 wake_up_interruptible(&session->wait);
248 memcpy(&ctrl->profile,
249 skb->data + CAPI_MSG_BASELEN + 11,
250 sizeof(capi_profile));
251 session->state = BT_CONNECTED;
252 capi_ctr_ready(ctrl);
257 case CAPI_FUNCTION_GET_MANUFACTURER:
258 if (skb->len < CAPI_MSG_BASELEN + 15)
261 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
264 int len = min_t(uint, CAPI_MANUFACTURER_LEN,
265 skb->data[CAPI_MSG_BASELEN + 14]);
267 memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN);
269 skb->data + CAPI_MSG_BASELEN + 15, len);
274 case CAPI_FUNCTION_GET_VERSION:
275 if (skb->len < CAPI_MSG_BASELEN + 32)
278 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
281 ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
282 ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
283 ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
284 ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
289 case CAPI_FUNCTION_GET_SERIAL_NUMBER:
290 if (skb->len < CAPI_MSG_BASELEN + 17)
293 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
296 int len = min_t(uint, CAPI_SERIAL_LEN,
297 skb->data[CAPI_MSG_BASELEN + 16]);
299 memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
300 strncpy(ctrl->serial,
301 skb->data + CAPI_MSG_BASELEN + 17, len);
310 if (skb->len < CAPI_MSG_BASELEN + 6)
313 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
315 if (func == CAPI_FUNCTION_LOOPBACK) {
316 int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6,
317 skb->data[CAPI_MSG_BASELEN + 5]);
318 appl = CAPIMSG_APPID(skb->data);
319 msgnum = CAPIMSG_MSGID(skb->data);
320 cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
321 skb->data + CAPI_MSG_BASELEN + 6, len);
330 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
332 struct capi_ctr *ctrl = &session->ctrl;
333 struct cmtp_application *application;
337 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
339 if (skb->len < CAPI_MSG_BASELEN)
342 if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
343 cmtp_recv_interopmsg(session, skb);
347 if (session->flags & (1 << CMTP_LOOPBACK)) {
352 cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
353 appl = CAPIMSG_APPID(skb->data);
354 contr = CAPIMSG_CONTROL(skb->data);
356 application = cmtp_application_get(session, CMTP_MAPPING, appl);
358 appl = application->appl;
359 CAPIMSG_SETAPPID(skb->data, appl);
361 BT_ERR("Can't find application with id %d", appl);
366 if ((contr & 0x7f) == 0x01) {
367 contr = (contr & 0xffffff80) | session->num;
368 CAPIMSG_SETCONTROL(skb->data, contr);
372 BT_ERR("Can't find controller %d for message", session->num);
377 capi_ctr_handle_message(ctrl, appl, skb);
380 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
382 BT_DBG("ctrl %p data %p", ctrl, data);
387 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
389 struct cmtp_session *session = ctrl->driverdata;
391 BT_DBG("ctrl %p", ctrl);
393 capi_ctr_reseted(ctrl);
395 atomic_inc(&session->terminate);
396 cmtp_schedule(session);
399 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
401 DECLARE_WAITQUEUE(wait, current);
402 struct cmtp_session *session = ctrl->driverdata;
403 struct cmtp_application *application;
404 unsigned long timeo = CMTP_INTEROP_TIMEOUT;
405 unsigned char buf[8];
406 int err = 0, nconn, want = rp->level3cnt;
408 BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
409 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
411 application = cmtp_application_add(session, appl);
413 BT_ERR("Can't allocate memory for new application");
418 nconn = ctrl->profile.nbchannel * -want;
423 nconn = ctrl->profile.nbchannel;
425 capimsg_setu16(buf, 0, nconn);
426 capimsg_setu16(buf, 2, rp->datablkcnt);
427 capimsg_setu16(buf, 4, rp->datablklen);
429 application->state = BT_CONFIG;
430 application->msgnum = cmtp_msgnum_get(session);
432 cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
433 CAPI_FUNCTION_REGISTER, buf, 6);
435 add_wait_queue(&session->wait, &wait);
437 set_current_state(TASK_INTERRUPTIBLE);
444 if (application->state == BT_CLOSED) {
445 err = -application->err;
449 if (application->state == BT_CONNECTED)
452 if (signal_pending(current)) {
457 timeo = schedule_timeout(timeo);
459 set_current_state(TASK_RUNNING);
460 remove_wait_queue(&session->wait, &wait);
463 cmtp_application_del(session, application);
468 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
470 struct cmtp_session *session = ctrl->driverdata;
471 struct cmtp_application *application;
473 BT_DBG("ctrl %p appl %d", ctrl, appl);
475 application = cmtp_application_get(session, CMTP_APPLID, appl);
477 BT_ERR("Can't find application");
481 application->msgnum = cmtp_msgnum_get(session);
483 cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
484 CAPI_FUNCTION_RELEASE, NULL, 0);
486 wait_event_interruptible_timeout(session->wait,
487 (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
489 cmtp_application_del(session, application);
492 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
494 struct cmtp_session *session = ctrl->driverdata;
495 struct cmtp_application *application;
499 BT_DBG("ctrl %p skb %p", ctrl, skb);
501 appl = CAPIMSG_APPID(skb->data);
502 contr = CAPIMSG_CONTROL(skb->data);
504 application = cmtp_application_get(session, CMTP_APPLID, appl);
505 if ((!application) || (application->state != BT_CONNECTED)) {
506 BT_ERR("Can't find application with id %d", appl);
507 return CAPI_ILLAPPNR;
510 CAPIMSG_SETAPPID(skb->data, application->mapping);
512 if ((contr & 0x7f) == session->num) {
513 contr = (contr & 0xffffff80) | 0x01;
514 CAPIMSG_SETCONTROL(skb->data, contr);
517 cmtp_send_capimsg(session, skb);
522 static char *cmtp_procinfo(struct capi_ctr *ctrl)
524 return "CAPI Message Transport Protocol";
527 static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
529 struct cmtp_session *session = ctrl->driverdata;
530 struct cmtp_application *app;
531 struct list_head *p, *n;
534 len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl));
535 len += sprintf(page + len, "addr %s\n", session->name);
536 len += sprintf(page + len, "ctrl %d\n", session->num);
538 list_for_each_safe(p, n, &session->applications) {
539 app = list_entry(p, struct cmtp_application, list);
540 len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
543 if (off + count >= len)
551 return ((count < len - off) ? count : len - off);
555 int cmtp_attach_device(struct cmtp_session *session)
557 unsigned char buf[4];
560 BT_DBG("session %p", session);
562 capimsg_setu32(buf, 0, 0);
564 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
565 CAPI_FUNCTION_GET_PROFILE, buf, 4);
567 ret = wait_event_interruptible_timeout(session->wait,
568 session->ncontroller, CMTP_INTEROP_TIMEOUT);
570 BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
575 if (!session->ncontroller)
578 if (session->ncontroller > 1)
579 BT_INFO("Setting up only CAPI controller 1");
581 session->ctrl.owner = THIS_MODULE;
582 session->ctrl.driverdata = session;
583 strcpy(session->ctrl.name, session->name);
585 session->ctrl.driver_name = "cmtp";
586 session->ctrl.load_firmware = cmtp_load_firmware;
587 session->ctrl.reset_ctr = cmtp_reset_ctr;
588 session->ctrl.register_appl = cmtp_register_appl;
589 session->ctrl.release_appl = cmtp_release_appl;
590 session->ctrl.send_message = cmtp_send_message;
592 session->ctrl.procinfo = cmtp_procinfo;
593 session->ctrl.ctr_read_proc = cmtp_ctr_read_proc;
595 if (attach_capi_ctr(&session->ctrl) < 0) {
596 BT_ERR("Can't attach new controller");
600 session->num = session->ctrl.cnr;
602 BT_DBG("session %p num %d", session, session->num);
604 capimsg_setu32(buf, 0, 1);
606 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
607 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
609 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
610 CAPI_FUNCTION_GET_VERSION, buf, 4);
612 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
613 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
615 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
616 CAPI_FUNCTION_GET_PROFILE, buf, 4);
621 void cmtp_detach_device(struct cmtp_session *session)
623 BT_DBG("session %p", session);
625 detach_capi_ctr(&session->ctrl);