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>
25 #include <linux/types.h>
26 #include <linux/errno.h>
27 #include <linux/kernel.h>
28 #include <linux/sched.h>
29 #include <linux/slab.h>
30 #include <linux/poll.h>
31 #include <linux/fcntl.h>
32 #include <linux/skbuff.h>
33 #include <linux/socket.h>
34 #include <linux/ioctl.h>
35 #include <linux/file.h>
36 #include <linux/wait.h>
39 #include <linux/isdn/capilli.h>
40 #include <linux/isdn/capicmd.h>
41 #include <linux/isdn/capiutil.h>
45 #ifndef CONFIG_BT_CMTP_DEBUG
50 #define CAPI_INTEROPERABILITY 0x20
52 #define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
53 #define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
54 #define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
55 #define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
57 #define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
58 #define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
59 #define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
60 #define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
62 #define CAPI_FUNCTION_REGISTER 0
63 #define CAPI_FUNCTION_RELEASE 1
64 #define CAPI_FUNCTION_GET_PROFILE 2
65 #define CAPI_FUNCTION_GET_MANUFACTURER 3
66 #define CAPI_FUNCTION_GET_VERSION 4
67 #define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
68 #define CAPI_FUNCTION_MANUFACTURER 6
69 #define CAPI_FUNCTION_LOOPBACK 7
74 #define CMTP_MAPPING 3
76 static struct cmtp_application
*cmtp_application_add(struct cmtp_session
*session
, __u16 appl
)
78 struct cmtp_application
*app
= kzalloc(sizeof(*app
), GFP_KERNEL
);
80 BT_DBG("session %p application %p appl %d", session
, app
, appl
);
88 list_add_tail(&app
->list
, &session
->applications
);
93 static void cmtp_application_del(struct cmtp_session
*session
, struct cmtp_application
*app
)
95 BT_DBG("session %p application %p", session
, app
);
103 static struct cmtp_application
*cmtp_application_get(struct cmtp_session
*session
, int pattern
, __u16 value
)
105 struct cmtp_application
*app
;
106 struct list_head
*p
, *n
;
108 list_for_each_safe(p
, n
, &session
->applications
) {
109 app
= list_entry(p
, struct cmtp_application
, list
);
112 if (app
->msgnum
== value
)
116 if (app
->appl
== value
)
120 if (app
->mapping
== value
)
129 static int cmtp_msgnum_get(struct cmtp_session
*session
)
133 if ((session
->msgnum
& 0xff) > 200)
134 session
->msgnum
= CMTP_INITIAL_MSGNUM
+ 1;
136 return session
->msgnum
;
139 static void cmtp_send_capimsg(struct cmtp_session
*session
, struct sk_buff
*skb
)
141 struct cmtp_scb
*scb
= (void *) skb
->cb
;
143 BT_DBG("session %p skb %p len %d", session
, skb
, skb
->len
);
146 scb
->data
= (CAPIMSG_COMMAND(skb
->data
) == CAPI_DATA_B3
);
148 skb_queue_tail(&session
->transmit
, skb
);
150 cmtp_schedule(session
);
153 static void cmtp_send_interopmsg(struct cmtp_session
*session
,
154 __u8 subcmd
, __u16 appl
, __u16 msgnum
,
155 __u16 function
, unsigned char *buf
, int len
)
160 BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session
, subcmd
, appl
, msgnum
);
162 if (!(skb
= alloc_skb(CAPI_MSG_BASELEN
+ 6 + len
, GFP_ATOMIC
))) {
163 BT_ERR("Can't allocate memory for interoperability packet");
167 s
= skb_put(skb
, CAPI_MSG_BASELEN
+ 6 + len
);
169 capimsg_setu16(s
, 0, CAPI_MSG_BASELEN
+ 6 + len
);
170 capimsg_setu16(s
, 2, appl
);
171 capimsg_setu8 (s
, 4, CAPI_INTEROPERABILITY
);
172 capimsg_setu8 (s
, 5, subcmd
);
173 capimsg_setu16(s
, 6, msgnum
);
175 /* Interoperability selector (Bluetooth Device Management) */
176 capimsg_setu16(s
, 8, 0x0001);
178 capimsg_setu8 (s
, 10, 3 + len
);
179 capimsg_setu16(s
, 11, function
);
180 capimsg_setu8 (s
, 13, len
);
183 memcpy(s
+ 14, buf
, len
);
185 cmtp_send_capimsg(session
, skb
);
188 static void cmtp_recv_interopmsg(struct cmtp_session
*session
, struct sk_buff
*skb
)
190 struct capi_ctr
*ctrl
= &session
->ctrl
;
191 struct cmtp_application
*application
;
192 __u16 appl
, msgnum
, func
, info
;
195 BT_DBG("session %p skb %p len %d", session
, skb
, skb
->len
);
197 switch (CAPIMSG_SUBCOMMAND(skb
->data
)) {
199 func
= CAPIMSG_U16(skb
->data
, CAPI_MSG_BASELEN
+ 5);
200 info
= CAPIMSG_U16(skb
->data
, CAPI_MSG_BASELEN
+ 8);
203 case CAPI_FUNCTION_REGISTER
:
204 msgnum
= CAPIMSG_MSGID(skb
->data
);
206 application
= cmtp_application_get(session
, CMTP_MSGNUM
, msgnum
);
208 application
->state
= BT_CONNECTED
;
209 application
->msgnum
= 0;
210 application
->mapping
= CAPIMSG_APPID(skb
->data
);
211 wake_up_interruptible(&session
->wait
);
216 case CAPI_FUNCTION_RELEASE
:
217 appl
= CAPIMSG_APPID(skb
->data
);
219 application
= cmtp_application_get(session
, CMTP_MAPPING
, appl
);
221 application
->state
= BT_CLOSED
;
222 application
->msgnum
= 0;
223 wake_up_interruptible(&session
->wait
);
228 case CAPI_FUNCTION_GET_PROFILE
:
229 controller
= CAPIMSG_U16(skb
->data
, CAPI_MSG_BASELEN
+ 11);
230 msgnum
= CAPIMSG_MSGID(skb
->data
);
232 if (!info
&& (msgnum
== CMTP_INITIAL_MSGNUM
)) {
233 session
->ncontroller
= controller
;
234 wake_up_interruptible(&session
->wait
);
239 memcpy(&ctrl
->profile
,
240 skb
->data
+ CAPI_MSG_BASELEN
+ 11,
241 sizeof(capi_profile
));
242 session
->state
= BT_CONNECTED
;
243 capi_ctr_ready(ctrl
);
248 case CAPI_FUNCTION_GET_MANUFACTURER
:
249 controller
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 10);
253 skb
->data
+ CAPI_MSG_BASELEN
+ 15,
254 skb
->data
[CAPI_MSG_BASELEN
+ 14]);
259 case CAPI_FUNCTION_GET_VERSION
:
260 controller
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 12);
263 ctrl
->version
.majorversion
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 16);
264 ctrl
->version
.minorversion
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 20);
265 ctrl
->version
.majormanuversion
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 24);
266 ctrl
->version
.minormanuversion
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 28);
271 case CAPI_FUNCTION_GET_SERIAL_NUMBER
:
272 controller
= CAPIMSG_U32(skb
->data
, CAPI_MSG_BASELEN
+ 12);
275 memset(ctrl
->serial
, 0, CAPI_SERIAL_LEN
);
276 strncpy(ctrl
->serial
,
277 skb
->data
+ CAPI_MSG_BASELEN
+ 17,
278 skb
->data
[CAPI_MSG_BASELEN
+ 16]);
287 func
= CAPIMSG_U16(skb
->data
, CAPI_MSG_BASELEN
+ 3);
289 if (func
== CAPI_FUNCTION_LOOPBACK
) {
290 appl
= CAPIMSG_APPID(skb
->data
);
291 msgnum
= CAPIMSG_MSGID(skb
->data
);
292 cmtp_send_interopmsg(session
, CAPI_RESP
, appl
, msgnum
, func
,
293 skb
->data
+ CAPI_MSG_BASELEN
+ 6,
294 skb
->data
[CAPI_MSG_BASELEN
+ 5]);
303 void cmtp_recv_capimsg(struct cmtp_session
*session
, struct sk_buff
*skb
)
305 struct capi_ctr
*ctrl
= &session
->ctrl
;
306 struct cmtp_application
*application
;
310 BT_DBG("session %p skb %p len %d", session
, skb
, skb
->len
);
312 if (CAPIMSG_COMMAND(skb
->data
) == CAPI_INTEROPERABILITY
) {
313 cmtp_recv_interopmsg(session
, skb
);
317 if (session
->flags
& (1 << CMTP_LOOPBACK
)) {
322 cmd
= CAPICMD(CAPIMSG_COMMAND(skb
->data
), CAPIMSG_SUBCOMMAND(skb
->data
));
323 appl
= CAPIMSG_APPID(skb
->data
);
324 contr
= CAPIMSG_CONTROL(skb
->data
);
326 application
= cmtp_application_get(session
, CMTP_MAPPING
, appl
);
328 appl
= application
->appl
;
329 CAPIMSG_SETAPPID(skb
->data
, appl
);
331 BT_ERR("Can't find application with id %d", appl
);
336 if ((contr
& 0x7f) == 0x01) {
337 contr
= (contr
& 0xffffff80) | session
->num
;
338 CAPIMSG_SETCONTROL(skb
->data
, contr
);
342 BT_ERR("Can't find controller %d for message", session
->num
);
347 capi_ctr_handle_message(ctrl
, appl
, skb
);
350 static int cmtp_load_firmware(struct capi_ctr
*ctrl
, capiloaddata
*data
)
352 BT_DBG("ctrl %p data %p", ctrl
, data
);
357 static void cmtp_reset_ctr(struct capi_ctr
*ctrl
)
359 struct cmtp_session
*session
= ctrl
->driverdata
;
361 BT_DBG("ctrl %p", ctrl
);
363 capi_ctr_reseted(ctrl
);
365 atomic_inc(&session
->terminate
);
366 cmtp_schedule(session
);
369 static void cmtp_register_appl(struct capi_ctr
*ctrl
, __u16 appl
, capi_register_params
*rp
)
371 DECLARE_WAITQUEUE(wait
, current
);
372 struct cmtp_session
*session
= ctrl
->driverdata
;
373 struct cmtp_application
*application
;
374 unsigned long timeo
= CMTP_INTEROP_TIMEOUT
;
375 unsigned char buf
[8];
376 int err
= 0, nconn
, want
= rp
->level3cnt
;
378 BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
379 ctrl
, appl
, rp
->level3cnt
, rp
->datablkcnt
, rp
->datablklen
);
381 application
= cmtp_application_add(session
, appl
);
383 BT_ERR("Can't allocate memory for new application");
388 nconn
= ctrl
->profile
.nbchannel
* -want
;
393 nconn
= ctrl
->profile
.nbchannel
;
395 capimsg_setu16(buf
, 0, nconn
);
396 capimsg_setu16(buf
, 2, rp
->datablkcnt
);
397 capimsg_setu16(buf
, 4, rp
->datablklen
);
399 application
->state
= BT_CONFIG
;
400 application
->msgnum
= cmtp_msgnum_get(session
);
402 cmtp_send_interopmsg(session
, CAPI_REQ
, 0x0000, application
->msgnum
,
403 CAPI_FUNCTION_REGISTER
, buf
, 6);
405 add_wait_queue(&session
->wait
, &wait
);
407 set_current_state(TASK_INTERRUPTIBLE
);
414 if (application
->state
== BT_CLOSED
) {
415 err
= -application
->err
;
419 if (application
->state
== BT_CONNECTED
)
422 if (signal_pending(current
)) {
427 timeo
= schedule_timeout(timeo
);
429 set_current_state(TASK_RUNNING
);
430 remove_wait_queue(&session
->wait
, &wait
);
433 cmtp_application_del(session
, application
);
438 static void cmtp_release_appl(struct capi_ctr
*ctrl
, __u16 appl
)
440 struct cmtp_session
*session
= ctrl
->driverdata
;
441 struct cmtp_application
*application
;
443 BT_DBG("ctrl %p appl %d", ctrl
, appl
);
445 application
= cmtp_application_get(session
, CMTP_APPLID
, appl
);
447 BT_ERR("Can't find application");
451 application
->msgnum
= cmtp_msgnum_get(session
);
453 cmtp_send_interopmsg(session
, CAPI_REQ
, application
->mapping
, application
->msgnum
,
454 CAPI_FUNCTION_RELEASE
, NULL
, 0);
456 wait_event_interruptible_timeout(session
->wait
,
457 (application
->state
== BT_CLOSED
), CMTP_INTEROP_TIMEOUT
);
459 cmtp_application_del(session
, application
);
462 static u16
cmtp_send_message(struct capi_ctr
*ctrl
, struct sk_buff
*skb
)
464 struct cmtp_session
*session
= ctrl
->driverdata
;
465 struct cmtp_application
*application
;
469 BT_DBG("ctrl %p skb %p", ctrl
, skb
);
471 appl
= CAPIMSG_APPID(skb
->data
);
472 contr
= CAPIMSG_CONTROL(skb
->data
);
474 application
= cmtp_application_get(session
, CMTP_APPLID
, appl
);
475 if ((!application
) || (application
->state
!= BT_CONNECTED
)) {
476 BT_ERR("Can't find application with id %d", appl
);
477 return CAPI_ILLAPPNR
;
480 CAPIMSG_SETAPPID(skb
->data
, application
->mapping
);
482 if ((contr
& 0x7f) == session
->num
) {
483 contr
= (contr
& 0xffffff80) | 0x01;
484 CAPIMSG_SETCONTROL(skb
->data
, contr
);
487 cmtp_send_capimsg(session
, skb
);
492 static char *cmtp_procinfo(struct capi_ctr
*ctrl
)
494 return "CAPI Message Transport Protocol";
497 static int cmtp_ctr_read_proc(char *page
, char **start
, off_t off
, int count
, int *eof
, struct capi_ctr
*ctrl
)
499 struct cmtp_session
*session
= ctrl
->driverdata
;
500 struct cmtp_application
*app
;
501 struct list_head
*p
, *n
;
504 len
+= sprintf(page
+ len
, "%s\n\n", cmtp_procinfo(ctrl
));
505 len
+= sprintf(page
+ len
, "addr %s\n", session
->name
);
506 len
+= sprintf(page
+ len
, "ctrl %d\n", session
->num
);
508 list_for_each_safe(p
, n
, &session
->applications
) {
509 app
= list_entry(p
, struct cmtp_application
, list
);
510 len
+= sprintf(page
+ len
, "appl %d -> %d\n", app
->appl
, app
->mapping
);
513 if (off
+ count
>= len
)
521 return ((count
< len
- off
) ? count
: len
- off
);
525 int cmtp_attach_device(struct cmtp_session
*session
)
527 unsigned char buf
[4];
530 BT_DBG("session %p", session
);
532 capimsg_setu32(buf
, 0, 0);
534 cmtp_send_interopmsg(session
, CAPI_REQ
, 0xffff, CMTP_INITIAL_MSGNUM
,
535 CAPI_FUNCTION_GET_PROFILE
, buf
, 4);
537 ret
= wait_event_interruptible_timeout(session
->wait
,
538 session
->ncontroller
, CMTP_INTEROP_TIMEOUT
);
540 BT_INFO("Found %d CAPI controller(s) on device %s", session
->ncontroller
, session
->name
);
545 if (!session
->ncontroller
)
548 if (session
->ncontroller
> 1)
549 BT_INFO("Setting up only CAPI controller 1");
551 session
->ctrl
.owner
= THIS_MODULE
;
552 session
->ctrl
.driverdata
= session
;
553 strcpy(session
->ctrl
.name
, session
->name
);
555 session
->ctrl
.driver_name
= "cmtp";
556 session
->ctrl
.load_firmware
= cmtp_load_firmware
;
557 session
->ctrl
.reset_ctr
= cmtp_reset_ctr
;
558 session
->ctrl
.register_appl
= cmtp_register_appl
;
559 session
->ctrl
.release_appl
= cmtp_release_appl
;
560 session
->ctrl
.send_message
= cmtp_send_message
;
562 session
->ctrl
.procinfo
= cmtp_procinfo
;
563 session
->ctrl
.ctr_read_proc
= cmtp_ctr_read_proc
;
565 if (attach_capi_ctr(&session
->ctrl
) < 0) {
566 BT_ERR("Can't attach new controller");
570 session
->num
= session
->ctrl
.cnr
;
572 BT_DBG("session %p num %d", session
, session
->num
);
574 capimsg_setu32(buf
, 0, 1);
576 cmtp_send_interopmsg(session
, CAPI_REQ
, 0xffff, cmtp_msgnum_get(session
),
577 CAPI_FUNCTION_GET_MANUFACTURER
, buf
, 4);
579 cmtp_send_interopmsg(session
, CAPI_REQ
, 0xffff, cmtp_msgnum_get(session
),
580 CAPI_FUNCTION_GET_VERSION
, buf
, 4);
582 cmtp_send_interopmsg(session
, CAPI_REQ
, 0xffff, cmtp_msgnum_get(session
),
583 CAPI_FUNCTION_GET_SERIAL_NUMBER
, buf
, 4);
585 cmtp_send_interopmsg(session
, CAPI_REQ
, 0xffff, cmtp_msgnum_get(session
),
586 CAPI_FUNCTION_GET_PROFILE
, buf
, 4);
591 void cmtp_detach_device(struct cmtp_session
*session
)
593 BT_DBG("session %p", session
);
595 detach_capi_ctr(&session
->ctrl
);