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/export.h>
24 #include <linux/proc_fs.h>
25 #include <linux/seq_file.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>
38 #include <linux/kthread.h>
41 #include <linux/isdn/capilli.h>
42 #include <linux/isdn/capicmd.h>
43 #include <linux/isdn/capiutil.h>
47 #define CAPI_INTEROPERABILITY 0x20
49 #define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
50 #define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
51 #define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
52 #define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
54 #define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
55 #define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
56 #define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
57 #define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
59 #define CAPI_FUNCTION_REGISTER 0
60 #define CAPI_FUNCTION_RELEASE 1
61 #define CAPI_FUNCTION_GET_PROFILE 2
62 #define CAPI_FUNCTION_GET_MANUFACTURER 3
63 #define CAPI_FUNCTION_GET_VERSION 4
64 #define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
65 #define CAPI_FUNCTION_MANUFACTURER 6
66 #define CAPI_FUNCTION_LOOPBACK 7
71 #define CMTP_MAPPING 3
73 static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
75 struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL);
77 BT_DBG("session %p application %p appl %d", session, app, appl);
85 list_add_tail(&app->list, &session->applications);
90 static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
92 BT_DBG("session %p application %p", session, app);
100 static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
102 struct cmtp_application *app;
103 struct list_head *p, *n;
105 list_for_each_safe(p, n, &session->applications) {
106 app = list_entry(p, struct cmtp_application, list);
109 if (app->msgnum == value)
113 if (app->appl == value)
117 if (app->mapping == value)
126 static int cmtp_msgnum_get(struct cmtp_session *session)
130 if ((session->msgnum & 0xff) > 200)
131 session->msgnum = CMTP_INITIAL_MSGNUM + 1;
133 return session->msgnum;
136 static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
138 struct cmtp_scb *scb = (void *) skb->cb;
140 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
143 scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
145 skb_queue_tail(&session->transmit, skb);
147 wake_up_interruptible(sk_sleep(session->sock->sk));
150 static void cmtp_send_interopmsg(struct cmtp_session *session,
151 __u8 subcmd, __u16 appl, __u16 msgnum,
152 __u16 function, unsigned char *buf, int len)
157 BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
159 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 appl = CAPIMSG_APPID(skb->data);
348 contr = CAPIMSG_CONTROL(skb->data);
350 application = cmtp_application_get(session, CMTP_MAPPING, appl);
352 appl = application->appl;
353 CAPIMSG_SETAPPID(skb->data, appl);
355 BT_ERR("Can't find application with id %d", appl);
360 if ((contr & 0x7f) == 0x01) {
361 contr = (contr & 0xffffff80) | session->num;
362 CAPIMSG_SETCONTROL(skb->data, contr);
365 capi_ctr_handle_message(ctrl, appl, skb);
368 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
370 BT_DBG("ctrl %p data %p", ctrl, data);
375 static void cmtp_reset_ctr(struct capi_ctr *ctrl)
377 struct cmtp_session *session = ctrl->driverdata;
379 BT_DBG("ctrl %p", ctrl);
383 atomic_inc(&session->terminate);
384 wake_up_process(session->task);
387 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
389 DECLARE_WAITQUEUE(wait, current);
390 struct cmtp_session *session = ctrl->driverdata;
391 struct cmtp_application *application;
392 unsigned long timeo = CMTP_INTEROP_TIMEOUT;
393 unsigned char buf[8];
394 int err = 0, nconn, want = rp->level3cnt;
396 BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
397 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
399 application = cmtp_application_add(session, appl);
401 BT_ERR("Can't allocate memory for new application");
406 nconn = ctrl->profile.nbchannel * -want;
411 nconn = ctrl->profile.nbchannel;
413 capimsg_setu16(buf, 0, nconn);
414 capimsg_setu16(buf, 2, rp->datablkcnt);
415 capimsg_setu16(buf, 4, rp->datablklen);
417 application->state = BT_CONFIG;
418 application->msgnum = cmtp_msgnum_get(session);
420 cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
421 CAPI_FUNCTION_REGISTER, buf, 6);
423 add_wait_queue(&session->wait, &wait);
425 set_current_state(TASK_INTERRUPTIBLE);
432 if (application->state == BT_CLOSED) {
433 err = -application->err;
437 if (application->state == BT_CONNECTED)
440 if (signal_pending(current)) {
445 timeo = schedule_timeout(timeo);
447 set_current_state(TASK_RUNNING);
448 remove_wait_queue(&session->wait, &wait);
451 cmtp_application_del(session, application);
456 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
458 struct cmtp_session *session = ctrl->driverdata;
459 struct cmtp_application *application;
461 BT_DBG("ctrl %p appl %d", ctrl, appl);
463 application = cmtp_application_get(session, CMTP_APPLID, appl);
465 BT_ERR("Can't find application");
469 application->msgnum = cmtp_msgnum_get(session);
471 cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
472 CAPI_FUNCTION_RELEASE, NULL, 0);
474 wait_event_interruptible_timeout(session->wait,
475 (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT);
477 cmtp_application_del(session, application);
480 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
482 struct cmtp_session *session = ctrl->driverdata;
483 struct cmtp_application *application;
487 BT_DBG("ctrl %p skb %p", ctrl, skb);
489 appl = CAPIMSG_APPID(skb->data);
490 contr = CAPIMSG_CONTROL(skb->data);
492 application = cmtp_application_get(session, CMTP_APPLID, appl);
493 if ((!application) || (application->state != BT_CONNECTED)) {
494 BT_ERR("Can't find application with id %d", appl);
495 return CAPI_ILLAPPNR;
498 CAPIMSG_SETAPPID(skb->data, application->mapping);
500 if ((contr & 0x7f) == session->num) {
501 contr = (contr & 0xffffff80) | 0x01;
502 CAPIMSG_SETCONTROL(skb->data, contr);
505 cmtp_send_capimsg(session, skb);
510 static char *cmtp_procinfo(struct capi_ctr *ctrl)
512 return "CAPI Message Transport Protocol";
515 static int cmtp_proc_show(struct seq_file *m, void *v)
517 struct capi_ctr *ctrl = m->private;
518 struct cmtp_session *session = ctrl->driverdata;
519 struct cmtp_application *app;
520 struct list_head *p, *n;
522 seq_printf(m, "%s\n\n", cmtp_procinfo(ctrl));
523 seq_printf(m, "addr %s\n", session->name);
524 seq_printf(m, "ctrl %d\n", session->num);
526 list_for_each_safe(p, n, &session->applications) {
527 app = list_entry(p, struct cmtp_application, list);
528 seq_printf(m, "appl %d -> %d\n", app->appl, app->mapping);
534 static int cmtp_proc_open(struct inode *inode, struct file *file)
536 return single_open(file, cmtp_proc_show, PDE_DATA(inode));
539 static const struct file_operations cmtp_proc_fops = {
540 .owner = THIS_MODULE,
541 .open = cmtp_proc_open,
544 .release = single_release,
547 int cmtp_attach_device(struct cmtp_session *session)
549 unsigned char buf[4];
552 BT_DBG("session %p", session);
554 capimsg_setu32(buf, 0, 0);
556 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
557 CAPI_FUNCTION_GET_PROFILE, buf, 4);
559 ret = wait_event_interruptible_timeout(session->wait,
560 session->ncontroller, CMTP_INTEROP_TIMEOUT);
562 BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
567 if (!session->ncontroller)
570 if (session->ncontroller > 1)
571 BT_INFO("Setting up only CAPI controller 1");
573 session->ctrl.owner = THIS_MODULE;
574 session->ctrl.driverdata = session;
575 strcpy(session->ctrl.name, session->name);
577 session->ctrl.driver_name = "cmtp";
578 session->ctrl.load_firmware = cmtp_load_firmware;
579 session->ctrl.reset_ctr = cmtp_reset_ctr;
580 session->ctrl.register_appl = cmtp_register_appl;
581 session->ctrl.release_appl = cmtp_release_appl;
582 session->ctrl.send_message = cmtp_send_message;
584 session->ctrl.procinfo = cmtp_procinfo;
585 session->ctrl.proc_fops = &cmtp_proc_fops;
587 if (attach_capi_ctr(&session->ctrl) < 0) {
588 BT_ERR("Can't attach new controller");
592 session->num = session->ctrl.cnr;
594 BT_DBG("session %p num %d", session, session->num);
596 capimsg_setu32(buf, 0, 1);
598 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
599 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
601 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
602 CAPI_FUNCTION_GET_VERSION, buf, 4);
604 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
605 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
607 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
608 CAPI_FUNCTION_GET_PROFILE, buf, 4);
613 void cmtp_detach_device(struct cmtp_session *session)
615 BT_DBG("session %p", session);
617 detach_capi_ctr(&session->ctrl);