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