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