1 /* 2 CMTP implementation for Linux Bluetooth stack (BlueZ). 3 Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org> 4 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; 8 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. 17 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. 21 */ 22 23 #include <linux/config.h> 24 #include <linux/module.h> 25 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 <net/sock.h> 39 40 #include <linux/isdn/capilli.h> 41 #include <linux/isdn/capicmd.h> 42 #include <linux/isdn/capiutil.h> 43 44 #include "cmtp.h" 45 46 #ifndef CONFIG_BT_CMTP_DEBUG 47 #undef BT_DBG 48 #define BT_DBG(D...) 49 #endif 50 51 #define CAPI_INTEROPERABILITY 0x20 52 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) 57 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) 62 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 71 72 73 #define CMTP_MSGNUM 1 74 #define CMTP_APPLID 2 75 #define CMTP_MAPPING 3 76 77 static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl) 78 { 79 struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL); 80 81 BT_DBG("session %p application %p appl %d", session, app, appl); 82 83 if (!app) 84 return NULL; 85 86 memset(app, 0, sizeof(*app)); 87 88 app->state = BT_OPEN; 89 app->appl = appl; 90 91 list_add_tail(&app->list, &session->applications); 92 93 return app; 94 } 95 96 static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app) 97 { 98 BT_DBG("session %p application %p", session, app); 99 100 if (app) { 101 list_del(&app->list); 102 kfree(app); 103 } 104 } 105 106 static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value) 107 { 108 struct cmtp_application *app; 109 struct list_head *p, *n; 110 111 list_for_each_safe(p, n, &session->applications) { 112 app = list_entry(p, struct cmtp_application, list); 113 switch (pattern) { 114 case CMTP_MSGNUM: 115 if (app->msgnum == value) 116 return app; 117 break; 118 case CMTP_APPLID: 119 if (app->appl == value) 120 return app; 121 break; 122 case CMTP_MAPPING: 123 if (app->mapping == value) 124 return app; 125 break; 126 } 127 } 128 129 return NULL; 130 } 131 132 static int cmtp_msgnum_get(struct cmtp_session *session) 133 { 134 session->msgnum++; 135 136 if ((session->msgnum & 0xff) > 200) 137 session->msgnum = CMTP_INITIAL_MSGNUM + 1; 138 139 return session->msgnum; 140 } 141 142 static void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb) 143 { 144 struct cmtp_scb *scb = (void *) skb->cb; 145 146 BT_DBG("session %p skb %p len %d", session, skb, skb->len); 147 148 scb->id = -1; 149 scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3); 150 151 skb_queue_tail(&session->transmit, skb); 152 153 cmtp_schedule(session); 154 } 155 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) 159 { 160 struct sk_buff *skb; 161 unsigned char *s; 162 163 BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum); 164 165 if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) { 166 BT_ERR("Can't allocate memory for interoperability packet"); 167 return; 168 } 169 170 s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len); 171 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); 177 178 /* Interoperability selector (Bluetooth Device Management) */ 179 capimsg_setu16(s, 8, 0x0001); 180 181 capimsg_setu8 (s, 10, 3 + len); 182 capimsg_setu16(s, 11, function); 183 capimsg_setu8 (s, 13, len); 184 185 if (len > 0) 186 memcpy(s + 14, buf, len); 187 188 cmtp_send_capimsg(session, skb); 189 } 190 191 static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb) 192 { 193 struct capi_ctr *ctrl = &session->ctrl; 194 struct cmtp_application *application; 195 __u16 appl, msgnum, func, info; 196 __u32 controller; 197 198 BT_DBG("session %p skb %p len %d", session, skb, skb->len); 199 200 switch (CAPIMSG_SUBCOMMAND(skb->data)) { 201 case CAPI_CONF: 202 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5); 203 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8); 204 205 switch (func) { 206 case CAPI_FUNCTION_REGISTER: 207 msgnum = CAPIMSG_MSGID(skb->data); 208 209 application = cmtp_application_get(session, CMTP_MSGNUM, msgnum); 210 if (application) { 211 application->state = BT_CONNECTED; 212 application->msgnum = 0; 213 application->mapping = CAPIMSG_APPID(skb->data); 214 wake_up_interruptible(&session->wait); 215 } 216 217 break; 218 219 case CAPI_FUNCTION_RELEASE: 220 appl = CAPIMSG_APPID(skb->data); 221 222 application = cmtp_application_get(session, CMTP_MAPPING, appl); 223 if (application) { 224 application->state = BT_CLOSED; 225 application->msgnum = 0; 226 wake_up_interruptible(&session->wait); 227 } 228 229 break; 230 231 case CAPI_FUNCTION_GET_PROFILE: 232 controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11); 233 msgnum = CAPIMSG_MSGID(skb->data); 234 235 if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) { 236 session->ncontroller = controller; 237 wake_up_interruptible(&session->wait); 238 break; 239 } 240 241 if (!info && ctrl) { 242 memcpy(&ctrl->profile, 243 skb->data + CAPI_MSG_BASELEN + 11, 244 sizeof(capi_profile)); 245 session->state = BT_CONNECTED; 246 capi_ctr_ready(ctrl); 247 } 248 249 break; 250 251 case CAPI_FUNCTION_GET_MANUFACTURER: 252 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10); 253 254 if (!info && ctrl) { 255 strncpy(ctrl->manu, 256 skb->data + CAPI_MSG_BASELEN + 15, 257 skb->data[CAPI_MSG_BASELEN + 14]); 258 } 259 260 break; 261 262 case CAPI_FUNCTION_GET_VERSION: 263 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); 264 265 if (!info && ctrl) { 266 ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16); 267 ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20); 268 ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24); 269 ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28); 270 } 271 272 break; 273 274 case CAPI_FUNCTION_GET_SERIAL_NUMBER: 275 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); 276 277 if (!info && ctrl) { 278 memset(ctrl->serial, 0, CAPI_SERIAL_LEN); 279 strncpy(ctrl->serial, 280 skb->data + CAPI_MSG_BASELEN + 17, 281 skb->data[CAPI_MSG_BASELEN + 16]); 282 } 283 284 break; 285 } 286 287 break; 288 289 case CAPI_IND: 290 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3); 291 292 if (func == CAPI_FUNCTION_LOOPBACK) { 293 appl = CAPIMSG_APPID(skb->data); 294 msgnum = CAPIMSG_MSGID(skb->data); 295 cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func, 296 skb->data + CAPI_MSG_BASELEN + 6, 297 skb->data[CAPI_MSG_BASELEN + 5]); 298 } 299 300 break; 301 } 302 303 kfree_skb(skb); 304 } 305 306 void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb) 307 { 308 struct capi_ctr *ctrl = &session->ctrl; 309 struct cmtp_application *application; 310 __u16 cmd, appl; 311 __u32 contr; 312 313 BT_DBG("session %p skb %p len %d", session, skb, skb->len); 314 315 if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) { 316 cmtp_recv_interopmsg(session, skb); 317 return; 318 } 319 320 if (session->flags & (1 << CMTP_LOOPBACK)) { 321 kfree_skb(skb); 322 return; 323 } 324 325 cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data)); 326 appl = CAPIMSG_APPID(skb->data); 327 contr = CAPIMSG_CONTROL(skb->data); 328 329 application = cmtp_application_get(session, CMTP_MAPPING, appl); 330 if (application) { 331 appl = application->appl; 332 CAPIMSG_SETAPPID(skb->data, appl); 333 } else { 334 BT_ERR("Can't find application with id %d", appl); 335 kfree_skb(skb); 336 return; 337 } 338 339 if ((contr & 0x7f) == 0x01) { 340 contr = (contr & 0xffffff80) | session->num; 341 CAPIMSG_SETCONTROL(skb->data, contr); 342 } 343 344 if (!ctrl) { 345 BT_ERR("Can't find controller %d for message", session->num); 346 kfree_skb(skb); 347 return; 348 } 349 350 capi_ctr_handle_message(ctrl, appl, skb); 351 } 352 353 static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) 354 { 355 BT_DBG("ctrl %p data %p", ctrl, data); 356 357 return 0; 358 } 359 360 static void cmtp_reset_ctr(struct capi_ctr *ctrl) 361 { 362 struct cmtp_session *session = ctrl->driverdata; 363 364 BT_DBG("ctrl %p", ctrl); 365 366 capi_ctr_reseted(ctrl); 367 368 atomic_inc(&session->terminate); 369 cmtp_schedule(session); 370 } 371 372 static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) 373 { 374 DECLARE_WAITQUEUE(wait, current); 375 struct cmtp_session *session = ctrl->driverdata; 376 struct cmtp_application *application; 377 unsigned long timeo = CMTP_INTEROP_TIMEOUT; 378 unsigned char buf[8]; 379 int err = 0, nconn, want = rp->level3cnt; 380 381 BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d", 382 ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen); 383 384 application = cmtp_application_add(session, appl); 385 if (!application) { 386 BT_ERR("Can't allocate memory for new application"); 387 return; 388 } 389 390 if (want < 0) 391 nconn = ctrl->profile.nbchannel * -want; 392 else 393 nconn = want; 394 395 if (nconn == 0) 396 nconn = ctrl->profile.nbchannel; 397 398 capimsg_setu16(buf, 0, nconn); 399 capimsg_setu16(buf, 2, rp->datablkcnt); 400 capimsg_setu16(buf, 4, rp->datablklen); 401 402 application->state = BT_CONFIG; 403 application->msgnum = cmtp_msgnum_get(session); 404 405 cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum, 406 CAPI_FUNCTION_REGISTER, buf, 6); 407 408 add_wait_queue(&session->wait, &wait); 409 while (1) { 410 set_current_state(TASK_INTERRUPTIBLE); 411 412 if (!timeo) { 413 err = -EAGAIN; 414 break; 415 } 416 417 if (application->state == BT_CLOSED) { 418 err = -application->err; 419 break; 420 } 421 422 if (application->state == BT_CONNECTED) 423 break; 424 425 if (signal_pending(current)) { 426 err = -EINTR; 427 break; 428 } 429 430 timeo = schedule_timeout(timeo); 431 } 432 set_current_state(TASK_RUNNING); 433 remove_wait_queue(&session->wait, &wait); 434 435 if (err) { 436 cmtp_application_del(session, application); 437 return; 438 } 439 } 440 441 static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl) 442 { 443 struct cmtp_session *session = ctrl->driverdata; 444 struct cmtp_application *application; 445 446 BT_DBG("ctrl %p appl %d", ctrl, appl); 447 448 application = cmtp_application_get(session, CMTP_APPLID, appl); 449 if (!application) { 450 BT_ERR("Can't find application"); 451 return; 452 } 453 454 application->msgnum = cmtp_msgnum_get(session); 455 456 cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum, 457 CAPI_FUNCTION_RELEASE, NULL, 0); 458 459 wait_event_interruptible_timeout(session->wait, 460 (application->state == BT_CLOSED), CMTP_INTEROP_TIMEOUT); 461 462 cmtp_application_del(session, application); 463 } 464 465 static u16 cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) 466 { 467 struct cmtp_session *session = ctrl->driverdata; 468 struct cmtp_application *application; 469 __u16 appl; 470 __u32 contr; 471 472 BT_DBG("ctrl %p skb %p", ctrl, skb); 473 474 appl = CAPIMSG_APPID(skb->data); 475 contr = CAPIMSG_CONTROL(skb->data); 476 477 application = cmtp_application_get(session, CMTP_APPLID, appl); 478 if ((!application) || (application->state != BT_CONNECTED)) { 479 BT_ERR("Can't find application with id %d", appl); 480 return CAPI_ILLAPPNR; 481 } 482 483 CAPIMSG_SETAPPID(skb->data, application->mapping); 484 485 if ((contr & 0x7f) == session->num) { 486 contr = (contr & 0xffffff80) | 0x01; 487 CAPIMSG_SETCONTROL(skb->data, contr); 488 } 489 490 cmtp_send_capimsg(session, skb); 491 492 return CAPI_NOERROR; 493 } 494 495 static char *cmtp_procinfo(struct capi_ctr *ctrl) 496 { 497 return "CAPI Message Transport Protocol"; 498 } 499 500 static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl) 501 { 502 struct cmtp_session *session = ctrl->driverdata; 503 struct cmtp_application *app; 504 struct list_head *p, *n; 505 int len = 0; 506 507 len += sprintf(page + len, "%s\n\n", cmtp_procinfo(ctrl)); 508 len += sprintf(page + len, "addr %s\n", session->name); 509 len += sprintf(page + len, "ctrl %d\n", session->num); 510 511 list_for_each_safe(p, n, &session->applications) { 512 app = list_entry(p, struct cmtp_application, list); 513 len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping); 514 } 515 516 if (off + count >= len) 517 *eof = 1; 518 519 if (len < off) 520 return 0; 521 522 *start = page + off; 523 524 return ((count < len - off) ? count : len - off); 525 } 526 527 528 int cmtp_attach_device(struct cmtp_session *session) 529 { 530 unsigned char buf[4]; 531 long ret; 532 533 BT_DBG("session %p", session); 534 535 capimsg_setu32(buf, 0, 0); 536 537 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM, 538 CAPI_FUNCTION_GET_PROFILE, buf, 4); 539 540 ret = wait_event_interruptible_timeout(session->wait, 541 session->ncontroller, CMTP_INTEROP_TIMEOUT); 542 543 BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name); 544 545 if (!ret) 546 return -ETIMEDOUT; 547 548 if (!session->ncontroller) 549 return -ENODEV; 550 551 if (session->ncontroller > 1) 552 BT_INFO("Setting up only CAPI controller 1"); 553 554 session->ctrl.owner = THIS_MODULE; 555 session->ctrl.driverdata = session; 556 strcpy(session->ctrl.name, session->name); 557 558 session->ctrl.driver_name = "cmtp"; 559 session->ctrl.load_firmware = cmtp_load_firmware; 560 session->ctrl.reset_ctr = cmtp_reset_ctr; 561 session->ctrl.register_appl = cmtp_register_appl; 562 session->ctrl.release_appl = cmtp_release_appl; 563 session->ctrl.send_message = cmtp_send_message; 564 565 session->ctrl.procinfo = cmtp_procinfo; 566 session->ctrl.ctr_read_proc = cmtp_ctr_read_proc; 567 568 if (attach_capi_ctr(&session->ctrl) < 0) { 569 BT_ERR("Can't attach new controller"); 570 return -EBUSY; 571 } 572 573 session->num = session->ctrl.cnr; 574 575 BT_DBG("session %p num %d", session, session->num); 576 577 capimsg_setu32(buf, 0, 1); 578 579 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session), 580 CAPI_FUNCTION_GET_MANUFACTURER, buf, 4); 581 582 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session), 583 CAPI_FUNCTION_GET_VERSION, buf, 4); 584 585 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session), 586 CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4); 587 588 cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session), 589 CAPI_FUNCTION_GET_PROFILE, buf, 4); 590 591 return 0; 592 } 593 594 void cmtp_detach_device(struct cmtp_session *session) 595 { 596 BT_DBG("session %p", session); 597 598 detach_capi_ctr(&session->ctrl); 599 } 600