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/module.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>
40 #include <linux/isdn/capilli.h>
41 #include <linux/isdn/capicmd.h>
42 #include <linux/isdn/capiutil.h>
46 #define CAPI_INTEROPERABILITY 0x20
48 #define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
49 #define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
50 #define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
51 #define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
53 #define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
54 #define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
55 #define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
56 #define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
58 #define CAPI_FUNCTION_REGISTER 0
59 #define CAPI_FUNCTION_RELEASE 1
60 #define CAPI_FUNCTION_GET_PROFILE 2
61 #define CAPI_FUNCTION_GET_MANUFACTURER 3
62 #define CAPI_FUNCTION_GET_VERSION 4
63 #define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
64 #define CAPI_FUNCTION_MANUFACTURER 6
65 #define CAPI_FUNCTION_LOOPBACK 7
70 #define CMTP_MAPPING 3
72 static struct cmtp_application
*cmtp_application_add(struct cmtp_session
*session
, __u16 appl
)
74 struct cmtp_application
*app
= kzalloc(sizeof(*app
), GFP_KERNEL
);
76 BT_DBG("session %p application %p appl %d", session
, app
, appl
);
84 list_add_tail(&app
->list
, &session
->applications
);
89 static void cmtp_application_del(struct cmtp_session
*session
, struct cmtp_application
*app
)
91 BT_DBG("session %p application %p", session
, app
);
99 static struct cmtp_application
*cmtp_application_get(struct cmtp_session
*session
, int pattern
, __u16 value
)
101 struct cmtp_application
*app
;
102 struct list_head
*p
, *n
;
104 list_for_each_safe(p
, n
, &session
->applications
) {
105 app
= list_entry(p
, struct cmtp_application
, list
);
108 if (app
->msgnum
== value
)
112 if (app
->appl
== value
)
116 if (app
->mapping
== value
)
125 static int cmtp_msgnum_get(struct cmtp_session
*session
)
129 if ((session
->msgnum
& 0xff) > 200)
130 session
->msgnum
= CMTP_INITIAL_MSGNUM
+ 1;
132 return session
->msgnum
;
135 static void cmtp_send_capimsg(struct cmtp_session
*session
, struct sk_buff
*skb
)
137 struct cmtp_scb
*scb
= (void *) skb
->cb
;
139 BT_DBG("session %p skb %p len %d", session
, skb
, skb
->len
);
142 scb
->data
= (CAPIMSG_COMMAND(skb
->data
) == CAPI_DATA_B3
);
144 skb_queue_tail(&session
->transmit
, skb
);
146 cmtp_schedule(session
);
149 static void cmtp_send_interopmsg(struct cmtp_session
*session
,
150 __u8 subcmd
, __u16 appl
, __u16 msgnum
,
151 __u16 function
, unsigned char *buf
, int len
)
156 BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session
, subcmd
, appl
, msgnum
);
158 if (!(skb
= alloc_skb(CAPI_MSG_BASELEN
+ 6 + len
, GFP_ATOMIC
))) {
159 BT_ERR("Can't allocate memory for interoperability packet");
163 s
= skb_put(skb
, CAPI_MSG_BASELEN
+ 6 + len
);
165 capimsg_setu16(s
, 0, CAPI_MSG_BASELEN
+ 6 + len
);
166 capimsg_setu16(s
, 2, appl
);
167 capimsg_setu8 (s
, 4, CAPI_INTEROPERABILITY
);
168 capimsg_setu8 (s
, 5, subcmd
);
169 capimsg_setu16(s
, 6, msgnum
);
171 /* Interoperability selector (Bluetooth Device Management) */
172 capimsg_setu16(s
, 8, 0x0001);
174 capimsg_setu8 (s
, 10, 3 + len
);
175 capimsg_setu16(s
, 11, function
);
176 capimsg_setu8 (s
, 13, len
);
179 memcpy(s
+ 14, buf
, len
);
181 cmtp_send_capimsg(session
, skb
);
184 static void cmtp_recv_interopmsg(struct cmtp_session
*session
, struct sk_buff
*skb
)
186 struct capi_ctr
*ctrl
= &session
->ctrl
;
187 struct cmtp_application
*application
;
188 __u16 appl
, msgnum
, func
, info
;
191 BT_DBG("session %p skb %p len %d", session
, skb
, skb
->len
);
193 switch (CAPIMSG_SUBCOMMAND(skb
->data
)) {
195 if (skb
->len
< CAPI_MSG_BASELEN
+ 10)
198 func
= CAPIMSG_U16(skb
->data
, CAPI_MSG_BASELEN
+ 5);
199 info
= CAPIMSG_U16(skb
->data
, CAPI_MSG_BASELEN
+ 8);
202 case CAPI_FUNCTION_REGISTER
:
203 msgnum
= CAPIMSG_MSGID(skb
->data
);
205 application
= cmtp_application_get(session
, CMTP_MSGNUM
, msgnum
);
207 application
->state
= BT_CONNECTED
;
208 application
->msgnum
= 0;
209 application
->mapping
= CAPIMSG_APPID(skb
->data
);
210 wake_up_interruptible(&session
->wait
);
215 case CAPI_FUNCTION_RELEASE
:
216 appl
= CAPIMSG_APPID(skb
->data
);
218 application
= cmtp_application_get(session
, CMTP_MAPPING
, appl
);
220 application
->state
= BT_CLOSED
;
221 application
->msgnum
= 0;
222 wake_up_interruptible(&session
->wait
);
227 case CAPI_FUNCTION_GET_PROFILE
:
228 if (skb
->len
< CAPI_MSG_BASELEN
+ 11 + sizeof(capi_profile
))
231 controller
= CAPIMSG_U16(skb
->data
, CAPI_MSG_BASELEN
+ 11);
232 msgnum
= CAPIMSG_MSGID(skb
->data
);
234 if (!info
&& (msgnum
== CMTP_INITIAL_MSGNUM
)) {
235 session
->ncontroller
= controller
;
236 wake_up_interruptible(&session
->wait
);
241 memcpy(&ctrl
->profile
,
242 skb
->data
+ CAPI_MSG_BASELEN
+ 11,
243 sizeof(capi_profile
));
244 session
->state
= BT_CONNECTED
;
245 capi_ctr_ready(ctrl
);
250 case CAPI_FUNCTION_GET_MANUFACTURER
:
251 if (skb
->len
< CAPI_MSG_BASELEN
+ 15)
254 controller
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 10);
257 int len
= min_t(uint
, CAPI_MANUFACTURER_LEN
,
258 skb
->data
[CAPI_MSG_BASELEN
+ 14]);
260 memset(ctrl
->manu
, 0, CAPI_MANUFACTURER_LEN
);
262 skb
->data
+ CAPI_MSG_BASELEN
+ 15, len
);
267 case CAPI_FUNCTION_GET_VERSION
:
268 if (skb
->len
< CAPI_MSG_BASELEN
+ 32)
271 controller
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 12);
274 ctrl
->version
.majorversion
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 16);
275 ctrl
->version
.minorversion
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 20);
276 ctrl
->version
.majormanuversion
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 24);
277 ctrl
->version
.minormanuversion
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 28);
282 case CAPI_FUNCTION_GET_SERIAL_NUMBER
:
283 if (skb
->len
< CAPI_MSG_BASELEN
+ 17)
286 controller
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 12);
289 int len
= min_t(uint
, CAPI_SERIAL_LEN
,
290 skb
->data
[CAPI_MSG_BASELEN
+ 16]);
292 memset(ctrl
->serial
, 0, CAPI_SERIAL_LEN
);
293 strncpy(ctrl
->serial
,
294 skb
->data
+ CAPI_MSG_BASELEN
+ 17, len
);
303 if (skb
->len
< CAPI_MSG_BASELEN
+ 6)
306 func
= CAPIMSG_U16(skb
->data
, CAPI_MSG_BASELEN
+ 3);
308 if (func
== CAPI_FUNCTION_LOOPBACK
) {
309 int len
= min_t(uint
, skb
->len
- CAPI_MSG_BASELEN
- 6,
310 skb
->data
[CAPI_MSG_BASELEN
+ 5]);
311 appl
= CAPIMSG_APPID(skb
->data
);
312 msgnum
= CAPIMSG_MSGID(skb
->data
);
313 cmtp_send_interopmsg(session
, CAPI_RESP
, appl
, msgnum
, func
,
314 skb
->data
+ CAPI_MSG_BASELEN
+ 6, len
);
323 void cmtp_recv_capimsg(struct cmtp_session
*session
, struct sk_buff
*skb
)
325 struct capi_ctr
*ctrl
= &session
->ctrl
;
326 struct cmtp_application
*application
;
330 BT_DBG("session %p skb %p len %d", session
, skb
, skb
->len
);
332 if (skb
->len
< CAPI_MSG_BASELEN
)
335 if (CAPIMSG_COMMAND(skb
->data
) == CAPI_INTEROPERABILITY
) {
336 cmtp_recv_interopmsg(session
, skb
);
340 if (session
->flags
& (1 << CMTP_LOOPBACK
)) {
345 cmd
= CAPICMD(CAPIMSG_COMMAND(skb
->data
), CAPIMSG_SUBCOMMAND(skb
->data
));
346 appl
= CAPIMSG_APPID(skb
->data
);
347 contr
= CAPIMSG_CONTROL(skb
->data
);
349 application
= cmtp_application_get(session
, CMTP_MAPPING
, appl
);
351 appl
= application
->appl
;
352 CAPIMSG_SETAPPID(skb
->data
, appl
);
354 BT_ERR("Can't find application with id %d", appl
);
359 if ((contr
& 0x7f) == 0x01) {
360 contr
= (contr
& 0xffffff80) | session
->num
;
361 CAPIMSG_SETCONTROL(skb
->data
, contr
);
365 BT_ERR("Can't find controller %d for message", session
->num
);
370 capi_ctr_handle_message(ctrl
, appl
, skb
);
373 static int cmtp_load_firmware(struct capi_ctr
*ctrl
, capiloaddata
*data
)
375 BT_DBG("ctrl %p data %p", ctrl
, data
);
380 static void cmtp_reset_ctr(struct capi_ctr
*ctrl
)
382 struct cmtp_session
*session
= ctrl
->driverdata
;
384 BT_DBG("ctrl %p", ctrl
);
388 atomic_inc(&session
->terminate
);
389 cmtp_schedule(session
);
392 static void cmtp_register_appl(struct capi_ctr
*ctrl
, __u16 appl
, capi_register_params
*rp
)
394 DECLARE_WAITQUEUE(wait
, current
);
395 struct cmtp_session
*session
= ctrl
->driverdata
;
396 struct cmtp_application
*application
;
397 unsigned long timeo
= CMTP_INTEROP_TIMEOUT
;
398 unsigned char buf
[8];
399 int err
= 0, nconn
, want
= rp
->level3cnt
;
401 BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
402 ctrl
, appl
, rp
->level3cnt
, rp
->datablkcnt
, rp
->datablklen
);
404 application
= cmtp_application_add(session
, appl
);
406 BT_ERR("Can't allocate memory for new application");
411 nconn
= ctrl
->profile
.nbchannel
* -want
;
416 nconn
= ctrl
->profile
.nbchannel
;
418 capimsg_setu16(buf
, 0, nconn
);
419 capimsg_setu16(buf
, 2, rp
->datablkcnt
);
420 capimsg_setu16(buf
, 4, rp
->datablklen
);
422 application
->state
= BT_CONFIG
;
423 application
->msgnum
= cmtp_msgnum_get(session
);
425 cmtp_send_interopmsg(session
, CAPI_REQ
, 0x0000, application
->msgnum
,
426 CAPI_FUNCTION_REGISTER
, buf
, 6);
428 add_wait_queue(&session
->wait
, &wait
);
430 set_current_state(TASK_INTERRUPTIBLE
);
437 if (application
->state
== BT_CLOSED
) {
438 err
= -application
->err
;
442 if (application
->state
== BT_CONNECTED
)
445 if (signal_pending(current
)) {
450 timeo
= schedule_timeout(timeo
);
452 set_current_state(TASK_RUNNING
);
453 remove_wait_queue(&session
->wait
, &wait
);
456 cmtp_application_del(session
, application
);
461 static void cmtp_release_appl(struct capi_ctr
*ctrl
, __u16 appl
)
463 struct cmtp_session
*session
= ctrl
->driverdata
;
464 struct cmtp_application
*application
;
466 BT_DBG("ctrl %p appl %d", ctrl
, appl
);
468 application
= cmtp_application_get(session
, CMTP_APPLID
, appl
);
470 BT_ERR("Can't find application");
474 application
->msgnum
= cmtp_msgnum_get(session
);
476 cmtp_send_interopmsg(session
, CAPI_REQ
, application
->mapping
, application
->msgnum
,
477 CAPI_FUNCTION_RELEASE
, NULL
, 0);
479 wait_event_interruptible_timeout(session
->wait
,
480 (application
->state
== BT_CLOSED
), CMTP_INTEROP_TIMEOUT
);
482 cmtp_application_del(session
, application
);
485 static u16
cmtp_send_message(struct capi_ctr
*ctrl
, struct sk_buff
*skb
)
487 struct cmtp_session
*session
= ctrl
->driverdata
;
488 struct cmtp_application
*application
;
492 BT_DBG("ctrl %p skb %p", ctrl
, skb
);
494 appl
= CAPIMSG_APPID(skb
->data
);
495 contr
= CAPIMSG_CONTROL(skb
->data
);
497 application
= cmtp_application_get(session
, CMTP_APPLID
, appl
);
498 if ((!application
) || (application
->state
!= BT_CONNECTED
)) {
499 BT_ERR("Can't find application with id %d", appl
);
500 return CAPI_ILLAPPNR
;
503 CAPIMSG_SETAPPID(skb
->data
, application
->mapping
);
505 if ((contr
& 0x7f) == session
->num
) {
506 contr
= (contr
& 0xffffff80) | 0x01;
507 CAPIMSG_SETCONTROL(skb
->data
, contr
);
510 cmtp_send_capimsg(session
, skb
);
515 static char *cmtp_procinfo(struct capi_ctr
*ctrl
)
517 return "CAPI Message Transport Protocol";
520 static int cmtp_proc_show(struct seq_file
*m
, void *v
)
522 struct capi_ctr
*ctrl
= m
->private;
523 struct cmtp_session
*session
= ctrl
->driverdata
;
524 struct cmtp_application
*app
;
525 struct list_head
*p
, *n
;
527 seq_printf(m
, "%s\n\n", cmtp_procinfo(ctrl
));
528 seq_printf(m
, "addr %s\n", session
->name
);
529 seq_printf(m
, "ctrl %d\n", session
->num
);
531 list_for_each_safe(p
, n
, &session
->applications
) {
532 app
= list_entry(p
, struct cmtp_application
, list
);
533 seq_printf(m
, "appl %d -> %d\n", app
->appl
, app
->mapping
);
539 static int cmtp_proc_open(struct inode
*inode
, struct file
*file
)
541 return single_open(file
, cmtp_proc_show
, PDE(inode
)->data
);
544 static const struct file_operations cmtp_proc_fops
= {
545 .owner
= THIS_MODULE
,
546 .open
= cmtp_proc_open
,
549 .release
= single_release
,
552 int cmtp_attach_device(struct cmtp_session
*session
)
554 unsigned char buf
[4];
557 BT_DBG("session %p", session
);
559 capimsg_setu32(buf
, 0, 0);
561 cmtp_send_interopmsg(session
, CAPI_REQ
, 0xffff, CMTP_INITIAL_MSGNUM
,
562 CAPI_FUNCTION_GET_PROFILE
, buf
, 4);
564 ret
= wait_event_interruptible_timeout(session
->wait
,
565 session
->ncontroller
, CMTP_INTEROP_TIMEOUT
);
567 BT_INFO("Found %d CAPI controller(s) on device %s", session
->ncontroller
, session
->name
);
572 if (!session
->ncontroller
)
575 if (session
->ncontroller
> 1)
576 BT_INFO("Setting up only CAPI controller 1");
578 session
->ctrl
.owner
= THIS_MODULE
;
579 session
->ctrl
.driverdata
= session
;
580 strcpy(session
->ctrl
.name
, session
->name
);
582 session
->ctrl
.driver_name
= "cmtp";
583 session
->ctrl
.load_firmware
= cmtp_load_firmware
;
584 session
->ctrl
.reset_ctr
= cmtp_reset_ctr
;
585 session
->ctrl
.register_appl
= cmtp_register_appl
;
586 session
->ctrl
.release_appl
= cmtp_release_appl
;
587 session
->ctrl
.send_message
= cmtp_send_message
;
589 session
->ctrl
.procinfo
= cmtp_procinfo
;
590 session
->ctrl
.proc_fops
= &cmtp_proc_fops
;
592 if (attach_capi_ctr(&session
->ctrl
) < 0) {
593 BT_ERR("Can't attach new controller");
597 session
->num
= session
->ctrl
.cnr
;
599 BT_DBG("session %p num %d", session
, session
->num
);
601 capimsg_setu32(buf
, 0, 1);
603 cmtp_send_interopmsg(session
, CAPI_REQ
, 0xffff, cmtp_msgnum_get(session
),
604 CAPI_FUNCTION_GET_MANUFACTURER
, buf
, 4);
606 cmtp_send_interopmsg(session
, CAPI_REQ
, 0xffff, cmtp_msgnum_get(session
),
607 CAPI_FUNCTION_GET_VERSION
, buf
, 4);
609 cmtp_send_interopmsg(session
, CAPI_REQ
, 0xffff, cmtp_msgnum_get(session
),
610 CAPI_FUNCTION_GET_SERIAL_NUMBER
, buf
, 4);
612 cmtp_send_interopmsg(session
, CAPI_REQ
, 0xffff, cmtp_msgnum_get(session
),
613 CAPI_FUNCTION_GET_PROFILE
, buf
, 4);
618 void cmtp_detach_device(struct cmtp_session
*session
)
620 BT_DBG("session %p", session
);
622 detach_capi_ctr(&session
->ctrl
);