97 (struct socket *so, void *arg, int waitflag); 98static void ng_btsocket_rfcomm_sessions_task 99 (void *ctx, int pending); 100static void ng_btsocket_rfcomm_session_task 101 (ng_btsocket_rfcomm_session_p s); 102#define ng_btsocket_rfcomm_task_wakeup() \ 103 taskqueue_enqueue(taskqueue_swi_giant, &ng_btsocket_rfcomm_task) 104 105static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_connect_ind 106 (ng_btsocket_rfcomm_session_p s, int channel); 107static void ng_btsocket_rfcomm_connect_cfm 108 (ng_btsocket_rfcomm_session_p s); 109 110static int ng_btsocket_rfcomm_session_create 111 (ng_btsocket_rfcomm_session_p *sp, struct socket *l2so, 112 bdaddr_p src, bdaddr_p dst, struct thread *td); 113static int ng_btsocket_rfcomm_session_accept 114 (ng_btsocket_rfcomm_session_p s0); 115static int ng_btsocket_rfcomm_session_connect 116 (ng_btsocket_rfcomm_session_p s); 117static int ng_btsocket_rfcomm_session_receive 118 (ng_btsocket_rfcomm_session_p s); 119static int ng_btsocket_rfcomm_session_send 120 (ng_btsocket_rfcomm_session_p s); 121static void ng_btsocket_rfcomm_session_clean 122 (ng_btsocket_rfcomm_session_p s); 123static void ng_btsocket_rfcomm_session_process_pcb 124 (ng_btsocket_rfcomm_session_p s); 125static ng_btsocket_rfcomm_session_p ng_btsocket_rfcomm_session_by_addr 126 (bdaddr_p src, bdaddr_p dst); 127 128static int ng_btsocket_rfcomm_receive_frame 129 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 130static int ng_btsocket_rfcomm_receive_sabm 131 (ng_btsocket_rfcomm_session_p s, int dlci); 132static int ng_btsocket_rfcomm_receive_disc 133 (ng_btsocket_rfcomm_session_p s, int dlci); 134static int ng_btsocket_rfcomm_receive_ua 135 (ng_btsocket_rfcomm_session_p s, int dlci); 136static int ng_btsocket_rfcomm_receive_dm 137 (ng_btsocket_rfcomm_session_p s, int dlci); 138static int ng_btsocket_rfcomm_receive_uih 139 (ng_btsocket_rfcomm_session_p s, int dlci, int pf, struct mbuf *m0); 140static int ng_btsocket_rfcomm_receive_mcc 141 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 142static int ng_btsocket_rfcomm_receive_test 143 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 144static int ng_btsocket_rfcomm_receive_fc 145 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 146static int ng_btsocket_rfcomm_receive_msc 147 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 148static int ng_btsocket_rfcomm_receive_rpn 149 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 150static int ng_btsocket_rfcomm_receive_rls 151 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 152static int ng_btsocket_rfcomm_receive_pn 153 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 154static void ng_btsocket_rfcomm_set_pn 155 (ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr, u_int8_t flow_control, 156 u_int8_t credits, u_int16_t mtu); 157 158static int ng_btsocket_rfcomm_send_command 159 (ng_btsocket_rfcomm_session_p s, u_int8_t type, u_int8_t dlci); 160static int ng_btsocket_rfcomm_send_uih 161 (ng_btsocket_rfcomm_session_p s, u_int8_t address, u_int8_t pf, 162 u_int8_t credits, struct mbuf *data); 163static int ng_btsocket_rfcomm_send_msc 164 (ng_btsocket_rfcomm_pcb_p pcb); 165static int ng_btsocket_rfcomm_send_pn 166 (ng_btsocket_rfcomm_pcb_p pcb); 167static int ng_btsocket_rfcomm_send_credits 168 (ng_btsocket_rfcomm_pcb_p pcb); 169 170static int ng_btsocket_rfcomm_pcb_send 171 (ng_btsocket_rfcomm_pcb_p pcb, int limit); 172static void ng_btsocket_rfcomm_pcb_kill 173 (ng_btsocket_rfcomm_pcb_p pcb, int error); 174static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_by_dlci 175 (ng_btsocket_rfcomm_session_p s, int dlci); 176static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_listener 177 (bdaddr_p src, int channel); 178 179static void ng_btsocket_rfcomm_timeout 180 (ng_btsocket_rfcomm_pcb_p pcb); 181static void ng_btsocket_rfcomm_untimeout 182 (ng_btsocket_rfcomm_pcb_p pcb); 183static void ng_btsocket_rfcomm_process_timeout 184 (void *xpcb); 185 186static struct mbuf * ng_btsocket_rfcomm_prepare_packet 187 (struct sockbuf *sb, int length); 188 189/* Globals */ 190extern int ifqmaxlen; 191static u_int32_t ng_btsocket_rfcomm_debug_level; 192static u_int32_t ng_btsocket_rfcomm_timo; 193struct task ng_btsocket_rfcomm_task; 194static LIST_HEAD(, ng_btsocket_rfcomm_session) ng_btsocket_rfcomm_sessions; 195static struct mtx ng_btsocket_rfcomm_sessions_mtx; 196static LIST_HEAD(, ng_btsocket_rfcomm_pcb) ng_btsocket_rfcomm_sockets; 197static struct mtx ng_btsocket_rfcomm_sockets_mtx; 198static struct timeval ng_btsocket_rfcomm_lasttime; 199static int ng_btsocket_rfcomm_curpps; 200 201/* Sysctl tree */ 202SYSCTL_DECL(_net_bluetooth_rfcomm_sockets); 203SYSCTL_NODE(_net_bluetooth_rfcomm_sockets, OID_AUTO, stream, CTLFLAG_RW, 204 0, "Bluetooth STREAM RFCOMM sockets family"); 205SYSCTL_INT(_net_bluetooth_rfcomm_sockets_stream, OID_AUTO, debug_level, 206 CTLFLAG_RW, 207 &ng_btsocket_rfcomm_debug_level, NG_BTSOCKET_INFO_LEVEL, 208 "Bluetooth STREAM RFCOMM sockets debug level"); 209SYSCTL_INT(_net_bluetooth_rfcomm_sockets_stream, OID_AUTO, timeout, 210 CTLFLAG_RW, 211 &ng_btsocket_rfcomm_timo, 60, 212 "Bluetooth STREAM RFCOMM sockets timeout"); 213 214/***************************************************************************** 215 ***************************************************************************** 216 ** RFCOMM CRC 217 ***************************************************************************** 218 *****************************************************************************/ 219 220static u_int8_t ng_btsocket_rfcomm_crc_table[256] = { 221 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75, 222 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b, 223 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69, 224 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67, 225 226 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d, 227 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43, 228 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51, 229 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f, 230 231 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05, 232 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b, 233 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19, 234 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17, 235 236 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d, 237 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33, 238 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21, 239 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f, 240 241 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95, 242 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b, 243 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89, 244 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87, 245 246 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad, 247 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3, 248 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1, 249 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf, 250 251 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5, 252 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb, 253 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9, 254 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7, 255 256 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd, 257 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3, 258 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1, 259 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf 260}; 261 262/* CRC */ 263static u_int8_t 264ng_btsocket_rfcomm_crc(u_int8_t *data, int length) 265{ 266 u_int8_t crc = 0xff; 267 268 while (length --) 269 crc = ng_btsocket_rfcomm_crc_table[crc ^ *data++]; 270 271 return (crc); 272} /* ng_btsocket_rfcomm_crc */ 273 274/* FCS on 2 bytes */ 275static u_int8_t 276ng_btsocket_rfcomm_fcs2(u_int8_t *data) 277{ 278 return (0xff - ng_btsocket_rfcomm_crc(data, 2)); 279} /* ng_btsocket_rfcomm_fcs2 */ 280 281/* FCS on 3 bytes */ 282static u_int8_t 283ng_btsocket_rfcomm_fcs3(u_int8_t *data) 284{ 285 return (0xff - ng_btsocket_rfcomm_crc(data, 3)); 286} /* ng_btsocket_rfcomm_fcs3 */ 287 288/* 289 * Check FCS 290 * 291 * From Bluetooth spec 292 * 293 * "... In 07.10, the frame check sequence (FCS) is calculated on different 294 * sets of fields for different frame types. These are the fields that the 295 * FCS are calculated on: 296 * 297 * For SABM, DISC, UA, DM frames: on Address, Control and length field. 298 * For UIH frames: on Address and Control field. 299 * 300 * (This is stated here for clarification, and to set the standard for RFCOMM; 301 * the fields included in FCS calculation have actually changed in version 302 * 7.0.0 of TS 07.10, but RFCOMM will not change the FCS calculation scheme 303 * from the one above.) ..." 304 */ 305 306static int 307ng_btsocket_rfcomm_check_fcs(u_int8_t *data, int type, u_int8_t fcs) 308{ 309 if (type != RFCOMM_FRAME_UIH) 310 return (ng_btsocket_rfcomm_fcs3(data) != fcs); 311 312 return (ng_btsocket_rfcomm_fcs2(data) != fcs); 313} /* ng_btsocket_rfcomm_check_fcs */ 314 315/***************************************************************************** 316 ***************************************************************************** 317 ** Socket interface 318 ***************************************************************************** 319 *****************************************************************************/ 320 321/* 322 * Initialize everything 323 */ 324 325void 326ng_btsocket_rfcomm_init(void) 327{ 328 ng_btsocket_rfcomm_debug_level = NG_BTSOCKET_WARN_LEVEL; 329 ng_btsocket_rfcomm_timo = 60; 330 331 /* RFCOMM task */ 332 TASK_INIT(&ng_btsocket_rfcomm_task, 0, 333 ng_btsocket_rfcomm_sessions_task, NULL); 334 335 /* RFCOMM sessions list */ 336 LIST_INIT(&ng_btsocket_rfcomm_sessions); 337 mtx_init(&ng_btsocket_rfcomm_sessions_mtx, 338 "btsocks_rfcomm_sessions_mtx", NULL, MTX_DEF); 339 340 /* RFCOMM sockets list */ 341 LIST_INIT(&ng_btsocket_rfcomm_sockets); 342 mtx_init(&ng_btsocket_rfcomm_sockets_mtx, 343 "btsocks_rfcomm_sockets_mtx", NULL, MTX_DEF); 344} /* ng_btsocket_rfcomm_init */ 345 346/* 347 * Abort connection on socket 348 */ 349 350void 351ng_btsocket_rfcomm_abort(struct socket *so) 352{ 353 354 so->so_error = ECONNABORTED; 355 (void)ng_btsocket_rfcomm_disconnect(so); 356} /* ng_btsocket_rfcomm_abort */ 357 358void 359ng_btsocket_rfcomm_close(struct socket *so) 360{ 361 362 (void)ng_btsocket_rfcomm_disconnect(so); 363} /* ng_btsocket_rfcomm_close */ 364 365/* 366 * Accept connection on socket. Nothing to do here, socket must be connected 367 * and ready, so just return peer address and be done with it. 368 */ 369 370int 371ng_btsocket_rfcomm_accept(struct socket *so, struct sockaddr **nam) 372{ 373 return (ng_btsocket_rfcomm_peeraddr(so, nam)); 374} /* ng_btsocket_rfcomm_accept */ 375 376/* 377 * Create and attach new socket 378 */ 379 380int 381ng_btsocket_rfcomm_attach(struct socket *so, int proto, struct thread *td) 382{ 383 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 384 int error; 385 386 /* Check socket and protocol */ 387 if (so->so_type != SOCK_STREAM) 388 return (ESOCKTNOSUPPORT); 389 390#if 0 /* XXX sonewconn() calls "pru_attach" with proto == 0 */ 391 if (proto != 0) 392 if (proto != BLUETOOTH_PROTO_RFCOMM) 393 return (EPROTONOSUPPORT); 394#endif /* XXX */ 395 396 if (pcb != NULL) 397 return (EISCONN); 398 399 /* Reserve send and receive space if it is not reserved yet */ 400 if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) { 401 error = soreserve(so, NG_BTSOCKET_RFCOMM_SENDSPACE, 402 NG_BTSOCKET_RFCOMM_RECVSPACE); 403 if (error != 0) 404 return (error); 405 } 406 407 /* Allocate the PCB */ 408 pcb = malloc(sizeof(*pcb), 409 M_NETGRAPH_BTSOCKET_RFCOMM, M_NOWAIT | M_ZERO); 410 if (pcb == NULL) 411 return (ENOMEM); 412 413 /* Link the PCB and the socket */ 414 so->so_pcb = (caddr_t) pcb; 415 pcb->so = so; 416 417 /* Initialize PCB */ 418 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED; 419 pcb->flags = NG_BTSOCKET_RFCOMM_DLC_CFC; 420 421 pcb->lmodem = 422 pcb->rmodem = (RFCOMM_MODEM_RTC | RFCOMM_MODEM_RTR | RFCOMM_MODEM_DV); 423 424 pcb->mtu = RFCOMM_DEFAULT_MTU; 425 pcb->tx_cred = 0; 426 pcb->rx_cred = RFCOMM_DEFAULT_CREDITS; 427 428 mtx_init(&pcb->pcb_mtx, "btsocks_rfcomm_pcb_mtx", NULL, MTX_DEF); 429 callout_handle_init(&pcb->timo); 430 431 /* Add the PCB to the list */ 432 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 433 LIST_INSERT_HEAD(&ng_btsocket_rfcomm_sockets, pcb, next); 434 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 435 436 return (0); 437} /* ng_btsocket_rfcomm_attach */ 438 439/* 440 * Bind socket 441 */ 442 443int 444ng_btsocket_rfcomm_bind(struct socket *so, struct sockaddr *nam, 445 struct thread *td) 446{ 447 ng_btsocket_rfcomm_pcb_t *pcb = so2rfcomm_pcb(so), *pcb1; 448 struct sockaddr_rfcomm *sa = (struct sockaddr_rfcomm *) nam; 449 450 if (pcb == NULL) 451 return (EINVAL); 452 453 /* Verify address */ 454 if (sa == NULL) 455 return (EINVAL); 456 if (sa->rfcomm_family != AF_BLUETOOTH) 457 return (EAFNOSUPPORT); 458 if (sa->rfcomm_len != sizeof(*sa)) 459 return (EINVAL); 460 if (sa->rfcomm_channel > 30) 461 return (EINVAL); 462 463 mtx_lock(&pcb->pcb_mtx); 464 465 if (sa->rfcomm_channel != 0) { 466 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 467 468 LIST_FOREACH(pcb1, &ng_btsocket_rfcomm_sockets, next) { 469 if (pcb1->channel == sa->rfcomm_channel && 470 bcmp(&pcb1->src, &sa->rfcomm_bdaddr, 471 sizeof(pcb1->src)) == 0) { 472 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 473 mtx_unlock(&pcb->pcb_mtx); 474 475 return (EADDRINUSE); 476 } 477 } 478 479 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 480 } 481 482 bcopy(&sa->rfcomm_bdaddr, &pcb->src, sizeof(pcb->src)); 483 pcb->channel = sa->rfcomm_channel; 484 485 mtx_unlock(&pcb->pcb_mtx); 486 487 return (0); 488} /* ng_btsocket_rfcomm_bind */ 489 490/* 491 * Connect socket 492 */ 493 494int 495ng_btsocket_rfcomm_connect(struct socket *so, struct sockaddr *nam, 496 struct thread *td) 497{ 498 ng_btsocket_rfcomm_pcb_t *pcb = so2rfcomm_pcb(so); 499 struct sockaddr_rfcomm *sa = (struct sockaddr_rfcomm *) nam; 500 ng_btsocket_rfcomm_session_t *s = NULL; 501 struct socket *l2so = NULL; 502 int dlci, error = 0; 503 504 if (pcb == NULL) 505 return (EINVAL); 506 507 /* Verify address */ 508 if (sa == NULL) 509 return (EINVAL); 510 if (sa->rfcomm_family != AF_BLUETOOTH) 511 return (EAFNOSUPPORT); 512 if (sa->rfcomm_len != sizeof(*sa)) 513 return (EINVAL); 514 if (sa->rfcomm_channel > 30) 515 return (EINVAL); 516 if (sa->rfcomm_channel == 0 || 517 bcmp(&sa->rfcomm_bdaddr, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0) 518 return (EDESTADDRREQ); 519 520 /* 521 * Note that we will not check for errors in socreate() because 522 * if we failed to create L2CAP socket at this point we still 523 * might have already open session. 524 */ 525 526 error = socreate(PF_BLUETOOTH, &l2so, SOCK_SEQPACKET, 527 BLUETOOTH_PROTO_L2CAP, td->td_ucred, td); 528 529 /* 530 * Look for session between "pcb->src" and "sa->rfcomm_bdaddr" (dst) 531 */ 532 533 mtx_lock(&ng_btsocket_rfcomm_sessions_mtx); 534 535 s = ng_btsocket_rfcomm_session_by_addr(&pcb->src, &sa->rfcomm_bdaddr); 536 if (s == NULL) { 537 /* 538 * We need to create new RFCOMM session. Check if we have L2CAP 539 * socket. If l2so == NULL then error has the error code from 540 * socreate() 541 */ 542 543 if (l2so == NULL) { 544 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 545 return (error); 546 } 547 548 error = ng_btsocket_rfcomm_session_create(&s, l2so, 549 &pcb->src, &sa->rfcomm_bdaddr, td); 550 if (error != 0) { 551 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 552 soclose(l2so); 553 554 return (error); 555 } 556 } else if (l2so != NULL) 557 soclose(l2so); /* we don't need new L2CAP socket */ 558 559 /* 560 * Check if we already have the same DLCI the the same session 561 */ 562 563 mtx_lock(&s->session_mtx); 564 mtx_lock(&pcb->pcb_mtx); 565 566 dlci = RFCOMM_MKDLCI(!INITIATOR(s), sa->rfcomm_channel); 567 568 if (ng_btsocket_rfcomm_pcb_by_dlci(s, dlci) != NULL) { 569 mtx_unlock(&pcb->pcb_mtx); 570 mtx_unlock(&s->session_mtx); 571 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 572 573 return (EBUSY); 574 } 575 576 /* 577 * Check session state and if its not acceptable then refuse connection 578 */ 579 580 switch (s->state) { 581 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING: 582 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 583 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 584 /* 585 * Update destination address and channel and attach 586 * DLC to the session 587 */ 588 589 bcopy(&sa->rfcomm_bdaddr, &pcb->dst, sizeof(pcb->dst)); 590 pcb->channel = sa->rfcomm_channel; 591 pcb->dlci = dlci; 592 593 LIST_INSERT_HEAD(&s->dlcs, pcb, session_next); 594 pcb->session = s; 595 596 ng_btsocket_rfcomm_timeout(pcb); 597 soisconnecting(pcb->so); 598 599 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_OPEN) { 600 pcb->mtu = s->mtu; 601 bcopy(&so2l2cap_pcb(s->l2so)->src, &pcb->src, 602 sizeof(pcb->src)); 603 604 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONFIGURING; 605 606 error = ng_btsocket_rfcomm_send_pn(pcb); 607 if (error == 0) 608 error = ng_btsocket_rfcomm_task_wakeup(); 609 } else 610 pcb->state = NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT; 611 break; 612 613 default: 614 error = ECONNRESET; 615 break; 616 } 617 618 mtx_unlock(&pcb->pcb_mtx); 619 mtx_unlock(&s->session_mtx); 620 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 621 622 return (error); 623} /* ng_btsocket_rfcomm_connect */ 624 625/* 626 * Process ioctl's calls on socket. 627 * XXX FIXME this should provide interface to the RFCOMM multiplexor channel 628 */ 629 630int 631ng_btsocket_rfcomm_control(struct socket *so, u_long cmd, caddr_t data, 632 struct ifnet *ifp, struct thread *td) 633{ 634 return (EINVAL); 635} /* ng_btsocket_rfcomm_control */ 636 637/* 638 * Process getsockopt/setsockopt system calls 639 */ 640 641int 642ng_btsocket_rfcomm_ctloutput(struct socket *so, struct sockopt *sopt) 643{ 644 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 645 struct ng_btsocket_rfcomm_fc_info fcinfo; 646 int error = 0; 647 648 if (pcb == NULL) 649 return (EINVAL); 650 if (sopt->sopt_level != SOL_RFCOMM) 651 return (0); 652 653 mtx_lock(&pcb->pcb_mtx); 654 655 switch (sopt->sopt_dir) { 656 case SOPT_GET: 657 switch (sopt->sopt_name) { 658 case SO_RFCOMM_MTU: 659 error = sooptcopyout(sopt, &pcb->mtu, sizeof(pcb->mtu)); 660 break; 661 662 case SO_RFCOMM_FC_INFO: 663 fcinfo.lmodem = pcb->lmodem; 664 fcinfo.rmodem = pcb->rmodem; 665 fcinfo.tx_cred = pcb->tx_cred; 666 fcinfo.rx_cred = pcb->rx_cred; 667 fcinfo.cfc = (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)? 668 1 : 0; 669 fcinfo.reserved = 0; 670 671 error = sooptcopyout(sopt, &fcinfo, sizeof(fcinfo)); 672 break; 673 674 default: 675 error = ENOPROTOOPT; 676 break; 677 } 678 break; 679 680 case SOPT_SET: 681 switch (sopt->sopt_name) { 682 default: 683 error = ENOPROTOOPT; 684 break; 685 } 686 break; 687 688 default: 689 error = EINVAL; 690 break; 691 } 692 693 mtx_unlock(&pcb->pcb_mtx); 694 695 return (error); 696} /* ng_btsocket_rfcomm_ctloutput */ 697 698/* 699 * Detach and destroy socket 700 */ 701 702void 703ng_btsocket_rfcomm_detach(struct socket *so) 704{ 705 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 706 707 KASSERT(pcb != NULL, ("ng_btsocket_rfcomm_detach: pcb == NULL")); 708 709 mtx_lock(&pcb->pcb_mtx); 710 711 switch (pcb->state) { 712 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 713 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 714 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 715 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 716 /* XXX What to do with pending request? */ 717 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 718 ng_btsocket_rfcomm_untimeout(pcb); 719 720 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT) 721 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_DETACHED; 722 else 723 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 724 725 ng_btsocket_rfcomm_task_wakeup(); 726 break; 727 728 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 729 ng_btsocket_rfcomm_task_wakeup(); 730 break; 731 } 732 733 while (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CLOSED) 734 msleep(&pcb->state, &pcb->pcb_mtx, PZERO, "rf_det", 0); 735 736 if (pcb->session != NULL) 737 panic("%s: pcb->session != NULL\n", __func__); 738 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 739 panic("%s: timeout on closed DLC, flags=%#x\n", 740 __func__, pcb->flags); 741 742 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 743 LIST_REMOVE(pcb, next); 744 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 745 746 mtx_unlock(&pcb->pcb_mtx); 747 748 mtx_destroy(&pcb->pcb_mtx); 749 bzero(pcb, sizeof(*pcb)); 750 free(pcb, M_NETGRAPH_BTSOCKET_RFCOMM); 751 752 soisdisconnected(so); 753 so->so_pcb = NULL; 754} /* ng_btsocket_rfcomm_detach */ 755 756/* 757 * Disconnect socket 758 */ 759 760int 761ng_btsocket_rfcomm_disconnect(struct socket *so) 762{ 763 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 764 765 if (pcb == NULL) 766 return (EINVAL); 767 768 mtx_lock(&pcb->pcb_mtx); 769 770 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING) { 771 mtx_unlock(&pcb->pcb_mtx); 772 return (EINPROGRESS); 773 } 774 775 /* XXX What to do with pending request? */ 776 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 777 ng_btsocket_rfcomm_untimeout(pcb); 778 779 switch (pcb->state) { 780 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: /* XXX can we get here? */ 781 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: /* XXX can we get here? */ 782 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 783 784 /* 785 * Just change DLC state and enqueue RFCOMM task. It will 786 * queue and send DISC on the DLC. 787 */ 788 789 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 790 soisdisconnecting(so); 791 792 ng_btsocket_rfcomm_task_wakeup(); 793 break; 794 795 case NG_BTSOCKET_RFCOMM_DLC_CLOSED: 796 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 797 break; 798 799 default: 800 panic("%s: Invalid DLC state=%d, flags=%#x\n", 801 __func__, pcb->state, pcb->flags); 802 break; 803 } 804 805 mtx_unlock(&pcb->pcb_mtx); 806 807 return (0); 808} /* ng_btsocket_rfcomm_disconnect */ 809 810/* 811 * Listen on socket. First call to listen() will create listening RFCOMM session 812 */ 813 814int 815ng_btsocket_rfcomm_listen(struct socket *so, int backlog, struct thread *td) 816{ 817 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so), pcb1; 818 ng_btsocket_rfcomm_session_p s = NULL; 819 struct socket *l2so = NULL; 820 int error, socreate_error, usedchannels; 821 822 if (pcb == NULL) 823 return (EINVAL); 824 if (pcb->channel > 30) 825 return (EADDRNOTAVAIL); 826 827 usedchannels = 0; 828 829 mtx_lock(&pcb->pcb_mtx); 830 831 if (pcb->channel == 0) { 832 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 833 834 LIST_FOREACH(pcb1, &ng_btsocket_rfcomm_sockets, next) 835 if (pcb1->channel != 0 && 836 bcmp(&pcb1->src, &pcb->src, sizeof(pcb->src)) == 0) 837 usedchannels |= (1 << (pcb1->channel - 1)); 838 839 for (pcb->channel = 30; pcb->channel > 0; pcb->channel --) 840 if (!(usedchannels & (1 << (pcb->channel - 1)))) 841 break; 842 843 if (pcb->channel == 0) { 844 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 845 mtx_unlock(&pcb->pcb_mtx); 846 847 return (EADDRNOTAVAIL); 848 } 849 850 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 851 } 852 853 mtx_unlock(&pcb->pcb_mtx); 854 855 /* 856 * Note that we will not check for errors in socreate() because 857 * if we failed to create L2CAP socket at this point we still 858 * might have already open session. 859 */ 860 861 socreate_error = socreate(PF_BLUETOOTH, &l2so, SOCK_SEQPACKET, 862 BLUETOOTH_PROTO_L2CAP, td->td_ucred, td); 863 864 /* 865 * Transition the socket and session into the LISTENING state. Check 866 * for collisions first, as there can only be one. 867 */ 868 mtx_lock(&ng_btsocket_rfcomm_sessions_mtx); 869 SOCK_LOCK(so); 870 error = solisten_proto_check(so); 871 SOCK_UNLOCK(so); 872 if (error != 0) 873 goto out; 874 875 LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next) 876 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_LISTENING) 877 break; 878 879 if (s == NULL) { 880 /* 881 * We need to create default RFCOMM session. Check if we have 882 * L2CAP socket. If l2so == NULL then error has the error code 883 * from socreate() 884 */ 885 if (l2so == NULL) { 886 error = socreate_error; 887 goto out; 888 } 889 890 /* 891 * Create default listen RFCOMM session. The default RFCOMM 892 * session will listen on ANY address. 893 * 894 * XXX FIXME Note that currently there is no way to adjust MTU 895 * for the default session. 896 */ 897 error = ng_btsocket_rfcomm_session_create(&s, l2so, 898 NG_HCI_BDADDR_ANY, NULL, td); 899 if (error != 0) 900 goto out; 901 l2so = NULL; 902 } 903 SOCK_LOCK(so); 904 solisten_proto(so, backlog); 905 SOCK_UNLOCK(so); 906out: 907 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 908 /* 909 * If we still have an l2so reference here, it's unneeded, so release 910 * it. 911 */ 912 if (l2so != NULL) 913 soclose(l2so); 914 return (error); 915} /* ng_btsocket_listen */ 916 917/* 918 * Get peer address 919 */ 920 921int 922ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam) 923{ 924 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 925 struct sockaddr_rfcomm sa; 926 927 if (pcb == NULL) 928 return (EINVAL); 929 930 bcopy(&pcb->dst, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr)); 931 sa.rfcomm_channel = pcb->channel; 932 sa.rfcomm_len = sizeof(sa); 933 sa.rfcomm_family = AF_BLUETOOTH; 934 935 *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); 936 937 return ((*nam == NULL)? ENOMEM : 0); 938} /* ng_btsocket_rfcomm_peeraddr */ 939 940/* 941 * Send data to socket 942 */ 943 944int 945ng_btsocket_rfcomm_send(struct socket *so, int flags, struct mbuf *m, 946 struct sockaddr *nam, struct mbuf *control, struct thread *td) 947{ 948 ng_btsocket_rfcomm_pcb_t *pcb = so2rfcomm_pcb(so); 949 int error = 0; 950 951 /* Check socket and input */ 952 if (pcb == NULL || m == NULL || control != NULL) { 953 error = EINVAL; 954 goto drop; 955 } 956 957 mtx_lock(&pcb->pcb_mtx); 958 959 /* Make sure DLC is connected */ 960 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 961 mtx_unlock(&pcb->pcb_mtx); 962 error = ENOTCONN; 963 goto drop; 964 } 965 966 /* Put the packet on the socket's send queue and wakeup RFCOMM task */ 967 sbappend(&pcb->so->so_snd, m); 968 m = NULL; 969 970 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_SENDING)) { 971 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_SENDING; 972 error = ng_btsocket_rfcomm_task_wakeup(); 973 } 974 975 mtx_unlock(&pcb->pcb_mtx); 976drop: 977 NG_FREE_M(m); /* checks for != NULL */ 978 NG_FREE_M(control); 979 980 return (error); 981} /* ng_btsocket_rfcomm_send */ 982 983/* 984 * Get socket address 985 */ 986 987int 988ng_btsocket_rfcomm_sockaddr(struct socket *so, struct sockaddr **nam) 989{ 990 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 991 struct sockaddr_rfcomm sa; 992 993 if (pcb == NULL) 994 return (EINVAL); 995 996 bcopy(&pcb->src, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr)); 997 sa.rfcomm_channel = pcb->channel; 998 sa.rfcomm_len = sizeof(sa); 999 sa.rfcomm_family = AF_BLUETOOTH; 1000 1001 *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); 1002 1003 return ((*nam == NULL)? ENOMEM : 0); 1004} /* ng_btsocket_rfcomm_sockaddr */ 1005 1006/* 1007 * Upcall function for L2CAP sockets. Enqueue RFCOMM task. 1008 */ 1009
| 97 (struct socket *so, void *arg, int waitflag); 98static void ng_btsocket_rfcomm_sessions_task 99 (void *ctx, int pending); 100static void ng_btsocket_rfcomm_session_task 101 (ng_btsocket_rfcomm_session_p s); 102#define ng_btsocket_rfcomm_task_wakeup() \ 103 taskqueue_enqueue(taskqueue_swi_giant, &ng_btsocket_rfcomm_task) 104 105static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_connect_ind 106 (ng_btsocket_rfcomm_session_p s, int channel); 107static void ng_btsocket_rfcomm_connect_cfm 108 (ng_btsocket_rfcomm_session_p s); 109 110static int ng_btsocket_rfcomm_session_create 111 (ng_btsocket_rfcomm_session_p *sp, struct socket *l2so, 112 bdaddr_p src, bdaddr_p dst, struct thread *td); 113static int ng_btsocket_rfcomm_session_accept 114 (ng_btsocket_rfcomm_session_p s0); 115static int ng_btsocket_rfcomm_session_connect 116 (ng_btsocket_rfcomm_session_p s); 117static int ng_btsocket_rfcomm_session_receive 118 (ng_btsocket_rfcomm_session_p s); 119static int ng_btsocket_rfcomm_session_send 120 (ng_btsocket_rfcomm_session_p s); 121static void ng_btsocket_rfcomm_session_clean 122 (ng_btsocket_rfcomm_session_p s); 123static void ng_btsocket_rfcomm_session_process_pcb 124 (ng_btsocket_rfcomm_session_p s); 125static ng_btsocket_rfcomm_session_p ng_btsocket_rfcomm_session_by_addr 126 (bdaddr_p src, bdaddr_p dst); 127 128static int ng_btsocket_rfcomm_receive_frame 129 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 130static int ng_btsocket_rfcomm_receive_sabm 131 (ng_btsocket_rfcomm_session_p s, int dlci); 132static int ng_btsocket_rfcomm_receive_disc 133 (ng_btsocket_rfcomm_session_p s, int dlci); 134static int ng_btsocket_rfcomm_receive_ua 135 (ng_btsocket_rfcomm_session_p s, int dlci); 136static int ng_btsocket_rfcomm_receive_dm 137 (ng_btsocket_rfcomm_session_p s, int dlci); 138static int ng_btsocket_rfcomm_receive_uih 139 (ng_btsocket_rfcomm_session_p s, int dlci, int pf, struct mbuf *m0); 140static int ng_btsocket_rfcomm_receive_mcc 141 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 142static int ng_btsocket_rfcomm_receive_test 143 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 144static int ng_btsocket_rfcomm_receive_fc 145 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 146static int ng_btsocket_rfcomm_receive_msc 147 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 148static int ng_btsocket_rfcomm_receive_rpn 149 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 150static int ng_btsocket_rfcomm_receive_rls 151 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 152static int ng_btsocket_rfcomm_receive_pn 153 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 154static void ng_btsocket_rfcomm_set_pn 155 (ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr, u_int8_t flow_control, 156 u_int8_t credits, u_int16_t mtu); 157 158static int ng_btsocket_rfcomm_send_command 159 (ng_btsocket_rfcomm_session_p s, u_int8_t type, u_int8_t dlci); 160static int ng_btsocket_rfcomm_send_uih 161 (ng_btsocket_rfcomm_session_p s, u_int8_t address, u_int8_t pf, 162 u_int8_t credits, struct mbuf *data); 163static int ng_btsocket_rfcomm_send_msc 164 (ng_btsocket_rfcomm_pcb_p pcb); 165static int ng_btsocket_rfcomm_send_pn 166 (ng_btsocket_rfcomm_pcb_p pcb); 167static int ng_btsocket_rfcomm_send_credits 168 (ng_btsocket_rfcomm_pcb_p pcb); 169 170static int ng_btsocket_rfcomm_pcb_send 171 (ng_btsocket_rfcomm_pcb_p pcb, int limit); 172static void ng_btsocket_rfcomm_pcb_kill 173 (ng_btsocket_rfcomm_pcb_p pcb, int error); 174static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_by_dlci 175 (ng_btsocket_rfcomm_session_p s, int dlci); 176static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_listener 177 (bdaddr_p src, int channel); 178 179static void ng_btsocket_rfcomm_timeout 180 (ng_btsocket_rfcomm_pcb_p pcb); 181static void ng_btsocket_rfcomm_untimeout 182 (ng_btsocket_rfcomm_pcb_p pcb); 183static void ng_btsocket_rfcomm_process_timeout 184 (void *xpcb); 185 186static struct mbuf * ng_btsocket_rfcomm_prepare_packet 187 (struct sockbuf *sb, int length); 188 189/* Globals */ 190extern int ifqmaxlen; 191static u_int32_t ng_btsocket_rfcomm_debug_level; 192static u_int32_t ng_btsocket_rfcomm_timo; 193struct task ng_btsocket_rfcomm_task; 194static LIST_HEAD(, ng_btsocket_rfcomm_session) ng_btsocket_rfcomm_sessions; 195static struct mtx ng_btsocket_rfcomm_sessions_mtx; 196static LIST_HEAD(, ng_btsocket_rfcomm_pcb) ng_btsocket_rfcomm_sockets; 197static struct mtx ng_btsocket_rfcomm_sockets_mtx; 198static struct timeval ng_btsocket_rfcomm_lasttime; 199static int ng_btsocket_rfcomm_curpps; 200 201/* Sysctl tree */ 202SYSCTL_DECL(_net_bluetooth_rfcomm_sockets); 203SYSCTL_NODE(_net_bluetooth_rfcomm_sockets, OID_AUTO, stream, CTLFLAG_RW, 204 0, "Bluetooth STREAM RFCOMM sockets family"); 205SYSCTL_INT(_net_bluetooth_rfcomm_sockets_stream, OID_AUTO, debug_level, 206 CTLFLAG_RW, 207 &ng_btsocket_rfcomm_debug_level, NG_BTSOCKET_INFO_LEVEL, 208 "Bluetooth STREAM RFCOMM sockets debug level"); 209SYSCTL_INT(_net_bluetooth_rfcomm_sockets_stream, OID_AUTO, timeout, 210 CTLFLAG_RW, 211 &ng_btsocket_rfcomm_timo, 60, 212 "Bluetooth STREAM RFCOMM sockets timeout"); 213 214/***************************************************************************** 215 ***************************************************************************** 216 ** RFCOMM CRC 217 ***************************************************************************** 218 *****************************************************************************/ 219 220static u_int8_t ng_btsocket_rfcomm_crc_table[256] = { 221 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75, 222 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b, 223 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69, 224 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67, 225 226 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d, 227 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43, 228 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51, 229 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f, 230 231 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05, 232 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b, 233 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19, 234 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17, 235 236 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d, 237 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33, 238 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21, 239 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f, 240 241 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95, 242 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b, 243 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89, 244 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87, 245 246 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad, 247 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3, 248 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1, 249 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf, 250 251 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5, 252 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb, 253 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9, 254 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7, 255 256 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd, 257 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3, 258 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1, 259 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf 260}; 261 262/* CRC */ 263static u_int8_t 264ng_btsocket_rfcomm_crc(u_int8_t *data, int length) 265{ 266 u_int8_t crc = 0xff; 267 268 while (length --) 269 crc = ng_btsocket_rfcomm_crc_table[crc ^ *data++]; 270 271 return (crc); 272} /* ng_btsocket_rfcomm_crc */ 273 274/* FCS on 2 bytes */ 275static u_int8_t 276ng_btsocket_rfcomm_fcs2(u_int8_t *data) 277{ 278 return (0xff - ng_btsocket_rfcomm_crc(data, 2)); 279} /* ng_btsocket_rfcomm_fcs2 */ 280 281/* FCS on 3 bytes */ 282static u_int8_t 283ng_btsocket_rfcomm_fcs3(u_int8_t *data) 284{ 285 return (0xff - ng_btsocket_rfcomm_crc(data, 3)); 286} /* ng_btsocket_rfcomm_fcs3 */ 287 288/* 289 * Check FCS 290 * 291 * From Bluetooth spec 292 * 293 * "... In 07.10, the frame check sequence (FCS) is calculated on different 294 * sets of fields for different frame types. These are the fields that the 295 * FCS are calculated on: 296 * 297 * For SABM, DISC, UA, DM frames: on Address, Control and length field. 298 * For UIH frames: on Address and Control field. 299 * 300 * (This is stated here for clarification, and to set the standard for RFCOMM; 301 * the fields included in FCS calculation have actually changed in version 302 * 7.0.0 of TS 07.10, but RFCOMM will not change the FCS calculation scheme 303 * from the one above.) ..." 304 */ 305 306static int 307ng_btsocket_rfcomm_check_fcs(u_int8_t *data, int type, u_int8_t fcs) 308{ 309 if (type != RFCOMM_FRAME_UIH) 310 return (ng_btsocket_rfcomm_fcs3(data) != fcs); 311 312 return (ng_btsocket_rfcomm_fcs2(data) != fcs); 313} /* ng_btsocket_rfcomm_check_fcs */ 314 315/***************************************************************************** 316 ***************************************************************************** 317 ** Socket interface 318 ***************************************************************************** 319 *****************************************************************************/ 320 321/* 322 * Initialize everything 323 */ 324 325void 326ng_btsocket_rfcomm_init(void) 327{ 328 ng_btsocket_rfcomm_debug_level = NG_BTSOCKET_WARN_LEVEL; 329 ng_btsocket_rfcomm_timo = 60; 330 331 /* RFCOMM task */ 332 TASK_INIT(&ng_btsocket_rfcomm_task, 0, 333 ng_btsocket_rfcomm_sessions_task, NULL); 334 335 /* RFCOMM sessions list */ 336 LIST_INIT(&ng_btsocket_rfcomm_sessions); 337 mtx_init(&ng_btsocket_rfcomm_sessions_mtx, 338 "btsocks_rfcomm_sessions_mtx", NULL, MTX_DEF); 339 340 /* RFCOMM sockets list */ 341 LIST_INIT(&ng_btsocket_rfcomm_sockets); 342 mtx_init(&ng_btsocket_rfcomm_sockets_mtx, 343 "btsocks_rfcomm_sockets_mtx", NULL, MTX_DEF); 344} /* ng_btsocket_rfcomm_init */ 345 346/* 347 * Abort connection on socket 348 */ 349 350void 351ng_btsocket_rfcomm_abort(struct socket *so) 352{ 353 354 so->so_error = ECONNABORTED; 355 (void)ng_btsocket_rfcomm_disconnect(so); 356} /* ng_btsocket_rfcomm_abort */ 357 358void 359ng_btsocket_rfcomm_close(struct socket *so) 360{ 361 362 (void)ng_btsocket_rfcomm_disconnect(so); 363} /* ng_btsocket_rfcomm_close */ 364 365/* 366 * Accept connection on socket. Nothing to do here, socket must be connected 367 * and ready, so just return peer address and be done with it. 368 */ 369 370int 371ng_btsocket_rfcomm_accept(struct socket *so, struct sockaddr **nam) 372{ 373 return (ng_btsocket_rfcomm_peeraddr(so, nam)); 374} /* ng_btsocket_rfcomm_accept */ 375 376/* 377 * Create and attach new socket 378 */ 379 380int 381ng_btsocket_rfcomm_attach(struct socket *so, int proto, struct thread *td) 382{ 383 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 384 int error; 385 386 /* Check socket and protocol */ 387 if (so->so_type != SOCK_STREAM) 388 return (ESOCKTNOSUPPORT); 389 390#if 0 /* XXX sonewconn() calls "pru_attach" with proto == 0 */ 391 if (proto != 0) 392 if (proto != BLUETOOTH_PROTO_RFCOMM) 393 return (EPROTONOSUPPORT); 394#endif /* XXX */ 395 396 if (pcb != NULL) 397 return (EISCONN); 398 399 /* Reserve send and receive space if it is not reserved yet */ 400 if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) { 401 error = soreserve(so, NG_BTSOCKET_RFCOMM_SENDSPACE, 402 NG_BTSOCKET_RFCOMM_RECVSPACE); 403 if (error != 0) 404 return (error); 405 } 406 407 /* Allocate the PCB */ 408 pcb = malloc(sizeof(*pcb), 409 M_NETGRAPH_BTSOCKET_RFCOMM, M_NOWAIT | M_ZERO); 410 if (pcb == NULL) 411 return (ENOMEM); 412 413 /* Link the PCB and the socket */ 414 so->so_pcb = (caddr_t) pcb; 415 pcb->so = so; 416 417 /* Initialize PCB */ 418 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED; 419 pcb->flags = NG_BTSOCKET_RFCOMM_DLC_CFC; 420 421 pcb->lmodem = 422 pcb->rmodem = (RFCOMM_MODEM_RTC | RFCOMM_MODEM_RTR | RFCOMM_MODEM_DV); 423 424 pcb->mtu = RFCOMM_DEFAULT_MTU; 425 pcb->tx_cred = 0; 426 pcb->rx_cred = RFCOMM_DEFAULT_CREDITS; 427 428 mtx_init(&pcb->pcb_mtx, "btsocks_rfcomm_pcb_mtx", NULL, MTX_DEF); 429 callout_handle_init(&pcb->timo); 430 431 /* Add the PCB to the list */ 432 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 433 LIST_INSERT_HEAD(&ng_btsocket_rfcomm_sockets, pcb, next); 434 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 435 436 return (0); 437} /* ng_btsocket_rfcomm_attach */ 438 439/* 440 * Bind socket 441 */ 442 443int 444ng_btsocket_rfcomm_bind(struct socket *so, struct sockaddr *nam, 445 struct thread *td) 446{ 447 ng_btsocket_rfcomm_pcb_t *pcb = so2rfcomm_pcb(so), *pcb1; 448 struct sockaddr_rfcomm *sa = (struct sockaddr_rfcomm *) nam; 449 450 if (pcb == NULL) 451 return (EINVAL); 452 453 /* Verify address */ 454 if (sa == NULL) 455 return (EINVAL); 456 if (sa->rfcomm_family != AF_BLUETOOTH) 457 return (EAFNOSUPPORT); 458 if (sa->rfcomm_len != sizeof(*sa)) 459 return (EINVAL); 460 if (sa->rfcomm_channel > 30) 461 return (EINVAL); 462 463 mtx_lock(&pcb->pcb_mtx); 464 465 if (sa->rfcomm_channel != 0) { 466 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 467 468 LIST_FOREACH(pcb1, &ng_btsocket_rfcomm_sockets, next) { 469 if (pcb1->channel == sa->rfcomm_channel && 470 bcmp(&pcb1->src, &sa->rfcomm_bdaddr, 471 sizeof(pcb1->src)) == 0) { 472 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 473 mtx_unlock(&pcb->pcb_mtx); 474 475 return (EADDRINUSE); 476 } 477 } 478 479 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 480 } 481 482 bcopy(&sa->rfcomm_bdaddr, &pcb->src, sizeof(pcb->src)); 483 pcb->channel = sa->rfcomm_channel; 484 485 mtx_unlock(&pcb->pcb_mtx); 486 487 return (0); 488} /* ng_btsocket_rfcomm_bind */ 489 490/* 491 * Connect socket 492 */ 493 494int 495ng_btsocket_rfcomm_connect(struct socket *so, struct sockaddr *nam, 496 struct thread *td) 497{ 498 ng_btsocket_rfcomm_pcb_t *pcb = so2rfcomm_pcb(so); 499 struct sockaddr_rfcomm *sa = (struct sockaddr_rfcomm *) nam; 500 ng_btsocket_rfcomm_session_t *s = NULL; 501 struct socket *l2so = NULL; 502 int dlci, error = 0; 503 504 if (pcb == NULL) 505 return (EINVAL); 506 507 /* Verify address */ 508 if (sa == NULL) 509 return (EINVAL); 510 if (sa->rfcomm_family != AF_BLUETOOTH) 511 return (EAFNOSUPPORT); 512 if (sa->rfcomm_len != sizeof(*sa)) 513 return (EINVAL); 514 if (sa->rfcomm_channel > 30) 515 return (EINVAL); 516 if (sa->rfcomm_channel == 0 || 517 bcmp(&sa->rfcomm_bdaddr, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0) 518 return (EDESTADDRREQ); 519 520 /* 521 * Note that we will not check for errors in socreate() because 522 * if we failed to create L2CAP socket at this point we still 523 * might have already open session. 524 */ 525 526 error = socreate(PF_BLUETOOTH, &l2so, SOCK_SEQPACKET, 527 BLUETOOTH_PROTO_L2CAP, td->td_ucred, td); 528 529 /* 530 * Look for session between "pcb->src" and "sa->rfcomm_bdaddr" (dst) 531 */ 532 533 mtx_lock(&ng_btsocket_rfcomm_sessions_mtx); 534 535 s = ng_btsocket_rfcomm_session_by_addr(&pcb->src, &sa->rfcomm_bdaddr); 536 if (s == NULL) { 537 /* 538 * We need to create new RFCOMM session. Check if we have L2CAP 539 * socket. If l2so == NULL then error has the error code from 540 * socreate() 541 */ 542 543 if (l2so == NULL) { 544 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 545 return (error); 546 } 547 548 error = ng_btsocket_rfcomm_session_create(&s, l2so, 549 &pcb->src, &sa->rfcomm_bdaddr, td); 550 if (error != 0) { 551 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 552 soclose(l2so); 553 554 return (error); 555 } 556 } else if (l2so != NULL) 557 soclose(l2so); /* we don't need new L2CAP socket */ 558 559 /* 560 * Check if we already have the same DLCI the the same session 561 */ 562 563 mtx_lock(&s->session_mtx); 564 mtx_lock(&pcb->pcb_mtx); 565 566 dlci = RFCOMM_MKDLCI(!INITIATOR(s), sa->rfcomm_channel); 567 568 if (ng_btsocket_rfcomm_pcb_by_dlci(s, dlci) != NULL) { 569 mtx_unlock(&pcb->pcb_mtx); 570 mtx_unlock(&s->session_mtx); 571 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 572 573 return (EBUSY); 574 } 575 576 /* 577 * Check session state and if its not acceptable then refuse connection 578 */ 579 580 switch (s->state) { 581 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING: 582 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 583 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 584 /* 585 * Update destination address and channel and attach 586 * DLC to the session 587 */ 588 589 bcopy(&sa->rfcomm_bdaddr, &pcb->dst, sizeof(pcb->dst)); 590 pcb->channel = sa->rfcomm_channel; 591 pcb->dlci = dlci; 592 593 LIST_INSERT_HEAD(&s->dlcs, pcb, session_next); 594 pcb->session = s; 595 596 ng_btsocket_rfcomm_timeout(pcb); 597 soisconnecting(pcb->so); 598 599 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_OPEN) { 600 pcb->mtu = s->mtu; 601 bcopy(&so2l2cap_pcb(s->l2so)->src, &pcb->src, 602 sizeof(pcb->src)); 603 604 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONFIGURING; 605 606 error = ng_btsocket_rfcomm_send_pn(pcb); 607 if (error == 0) 608 error = ng_btsocket_rfcomm_task_wakeup(); 609 } else 610 pcb->state = NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT; 611 break; 612 613 default: 614 error = ECONNRESET; 615 break; 616 } 617 618 mtx_unlock(&pcb->pcb_mtx); 619 mtx_unlock(&s->session_mtx); 620 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 621 622 return (error); 623} /* ng_btsocket_rfcomm_connect */ 624 625/* 626 * Process ioctl's calls on socket. 627 * XXX FIXME this should provide interface to the RFCOMM multiplexor channel 628 */ 629 630int 631ng_btsocket_rfcomm_control(struct socket *so, u_long cmd, caddr_t data, 632 struct ifnet *ifp, struct thread *td) 633{ 634 return (EINVAL); 635} /* ng_btsocket_rfcomm_control */ 636 637/* 638 * Process getsockopt/setsockopt system calls 639 */ 640 641int 642ng_btsocket_rfcomm_ctloutput(struct socket *so, struct sockopt *sopt) 643{ 644 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 645 struct ng_btsocket_rfcomm_fc_info fcinfo; 646 int error = 0; 647 648 if (pcb == NULL) 649 return (EINVAL); 650 if (sopt->sopt_level != SOL_RFCOMM) 651 return (0); 652 653 mtx_lock(&pcb->pcb_mtx); 654 655 switch (sopt->sopt_dir) { 656 case SOPT_GET: 657 switch (sopt->sopt_name) { 658 case SO_RFCOMM_MTU: 659 error = sooptcopyout(sopt, &pcb->mtu, sizeof(pcb->mtu)); 660 break; 661 662 case SO_RFCOMM_FC_INFO: 663 fcinfo.lmodem = pcb->lmodem; 664 fcinfo.rmodem = pcb->rmodem; 665 fcinfo.tx_cred = pcb->tx_cred; 666 fcinfo.rx_cred = pcb->rx_cred; 667 fcinfo.cfc = (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)? 668 1 : 0; 669 fcinfo.reserved = 0; 670 671 error = sooptcopyout(sopt, &fcinfo, sizeof(fcinfo)); 672 break; 673 674 default: 675 error = ENOPROTOOPT; 676 break; 677 } 678 break; 679 680 case SOPT_SET: 681 switch (sopt->sopt_name) { 682 default: 683 error = ENOPROTOOPT; 684 break; 685 } 686 break; 687 688 default: 689 error = EINVAL; 690 break; 691 } 692 693 mtx_unlock(&pcb->pcb_mtx); 694 695 return (error); 696} /* ng_btsocket_rfcomm_ctloutput */ 697 698/* 699 * Detach and destroy socket 700 */ 701 702void 703ng_btsocket_rfcomm_detach(struct socket *so) 704{ 705 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 706 707 KASSERT(pcb != NULL, ("ng_btsocket_rfcomm_detach: pcb == NULL")); 708 709 mtx_lock(&pcb->pcb_mtx); 710 711 switch (pcb->state) { 712 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 713 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 714 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 715 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 716 /* XXX What to do with pending request? */ 717 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 718 ng_btsocket_rfcomm_untimeout(pcb); 719 720 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT) 721 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_DETACHED; 722 else 723 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 724 725 ng_btsocket_rfcomm_task_wakeup(); 726 break; 727 728 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 729 ng_btsocket_rfcomm_task_wakeup(); 730 break; 731 } 732 733 while (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CLOSED) 734 msleep(&pcb->state, &pcb->pcb_mtx, PZERO, "rf_det", 0); 735 736 if (pcb->session != NULL) 737 panic("%s: pcb->session != NULL\n", __func__); 738 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 739 panic("%s: timeout on closed DLC, flags=%#x\n", 740 __func__, pcb->flags); 741 742 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 743 LIST_REMOVE(pcb, next); 744 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 745 746 mtx_unlock(&pcb->pcb_mtx); 747 748 mtx_destroy(&pcb->pcb_mtx); 749 bzero(pcb, sizeof(*pcb)); 750 free(pcb, M_NETGRAPH_BTSOCKET_RFCOMM); 751 752 soisdisconnected(so); 753 so->so_pcb = NULL; 754} /* ng_btsocket_rfcomm_detach */ 755 756/* 757 * Disconnect socket 758 */ 759 760int 761ng_btsocket_rfcomm_disconnect(struct socket *so) 762{ 763 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 764 765 if (pcb == NULL) 766 return (EINVAL); 767 768 mtx_lock(&pcb->pcb_mtx); 769 770 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING) { 771 mtx_unlock(&pcb->pcb_mtx); 772 return (EINPROGRESS); 773 } 774 775 /* XXX What to do with pending request? */ 776 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 777 ng_btsocket_rfcomm_untimeout(pcb); 778 779 switch (pcb->state) { 780 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: /* XXX can we get here? */ 781 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: /* XXX can we get here? */ 782 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 783 784 /* 785 * Just change DLC state and enqueue RFCOMM task. It will 786 * queue and send DISC on the DLC. 787 */ 788 789 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 790 soisdisconnecting(so); 791 792 ng_btsocket_rfcomm_task_wakeup(); 793 break; 794 795 case NG_BTSOCKET_RFCOMM_DLC_CLOSED: 796 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 797 break; 798 799 default: 800 panic("%s: Invalid DLC state=%d, flags=%#x\n", 801 __func__, pcb->state, pcb->flags); 802 break; 803 } 804 805 mtx_unlock(&pcb->pcb_mtx); 806 807 return (0); 808} /* ng_btsocket_rfcomm_disconnect */ 809 810/* 811 * Listen on socket. First call to listen() will create listening RFCOMM session 812 */ 813 814int 815ng_btsocket_rfcomm_listen(struct socket *so, int backlog, struct thread *td) 816{ 817 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so), pcb1; 818 ng_btsocket_rfcomm_session_p s = NULL; 819 struct socket *l2so = NULL; 820 int error, socreate_error, usedchannels; 821 822 if (pcb == NULL) 823 return (EINVAL); 824 if (pcb->channel > 30) 825 return (EADDRNOTAVAIL); 826 827 usedchannels = 0; 828 829 mtx_lock(&pcb->pcb_mtx); 830 831 if (pcb->channel == 0) { 832 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 833 834 LIST_FOREACH(pcb1, &ng_btsocket_rfcomm_sockets, next) 835 if (pcb1->channel != 0 && 836 bcmp(&pcb1->src, &pcb->src, sizeof(pcb->src)) == 0) 837 usedchannels |= (1 << (pcb1->channel - 1)); 838 839 for (pcb->channel = 30; pcb->channel > 0; pcb->channel --) 840 if (!(usedchannels & (1 << (pcb->channel - 1)))) 841 break; 842 843 if (pcb->channel == 0) { 844 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 845 mtx_unlock(&pcb->pcb_mtx); 846 847 return (EADDRNOTAVAIL); 848 } 849 850 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 851 } 852 853 mtx_unlock(&pcb->pcb_mtx); 854 855 /* 856 * Note that we will not check for errors in socreate() because 857 * if we failed to create L2CAP socket at this point we still 858 * might have already open session. 859 */ 860 861 socreate_error = socreate(PF_BLUETOOTH, &l2so, SOCK_SEQPACKET, 862 BLUETOOTH_PROTO_L2CAP, td->td_ucred, td); 863 864 /* 865 * Transition the socket and session into the LISTENING state. Check 866 * for collisions first, as there can only be one. 867 */ 868 mtx_lock(&ng_btsocket_rfcomm_sessions_mtx); 869 SOCK_LOCK(so); 870 error = solisten_proto_check(so); 871 SOCK_UNLOCK(so); 872 if (error != 0) 873 goto out; 874 875 LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next) 876 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_LISTENING) 877 break; 878 879 if (s == NULL) { 880 /* 881 * We need to create default RFCOMM session. Check if we have 882 * L2CAP socket. If l2so == NULL then error has the error code 883 * from socreate() 884 */ 885 if (l2so == NULL) { 886 error = socreate_error; 887 goto out; 888 } 889 890 /* 891 * Create default listen RFCOMM session. The default RFCOMM 892 * session will listen on ANY address. 893 * 894 * XXX FIXME Note that currently there is no way to adjust MTU 895 * for the default session. 896 */ 897 error = ng_btsocket_rfcomm_session_create(&s, l2so, 898 NG_HCI_BDADDR_ANY, NULL, td); 899 if (error != 0) 900 goto out; 901 l2so = NULL; 902 } 903 SOCK_LOCK(so); 904 solisten_proto(so, backlog); 905 SOCK_UNLOCK(so); 906out: 907 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 908 /* 909 * If we still have an l2so reference here, it's unneeded, so release 910 * it. 911 */ 912 if (l2so != NULL) 913 soclose(l2so); 914 return (error); 915} /* ng_btsocket_listen */ 916 917/* 918 * Get peer address 919 */ 920 921int 922ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam) 923{ 924 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 925 struct sockaddr_rfcomm sa; 926 927 if (pcb == NULL) 928 return (EINVAL); 929 930 bcopy(&pcb->dst, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr)); 931 sa.rfcomm_channel = pcb->channel; 932 sa.rfcomm_len = sizeof(sa); 933 sa.rfcomm_family = AF_BLUETOOTH; 934 935 *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); 936 937 return ((*nam == NULL)? ENOMEM : 0); 938} /* ng_btsocket_rfcomm_peeraddr */ 939 940/* 941 * Send data to socket 942 */ 943 944int 945ng_btsocket_rfcomm_send(struct socket *so, int flags, struct mbuf *m, 946 struct sockaddr *nam, struct mbuf *control, struct thread *td) 947{ 948 ng_btsocket_rfcomm_pcb_t *pcb = so2rfcomm_pcb(so); 949 int error = 0; 950 951 /* Check socket and input */ 952 if (pcb == NULL || m == NULL || control != NULL) { 953 error = EINVAL; 954 goto drop; 955 } 956 957 mtx_lock(&pcb->pcb_mtx); 958 959 /* Make sure DLC is connected */ 960 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 961 mtx_unlock(&pcb->pcb_mtx); 962 error = ENOTCONN; 963 goto drop; 964 } 965 966 /* Put the packet on the socket's send queue and wakeup RFCOMM task */ 967 sbappend(&pcb->so->so_snd, m); 968 m = NULL; 969 970 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_SENDING)) { 971 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_SENDING; 972 error = ng_btsocket_rfcomm_task_wakeup(); 973 } 974 975 mtx_unlock(&pcb->pcb_mtx); 976drop: 977 NG_FREE_M(m); /* checks for != NULL */ 978 NG_FREE_M(control); 979 980 return (error); 981} /* ng_btsocket_rfcomm_send */ 982 983/* 984 * Get socket address 985 */ 986 987int 988ng_btsocket_rfcomm_sockaddr(struct socket *so, struct sockaddr **nam) 989{ 990 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 991 struct sockaddr_rfcomm sa; 992 993 if (pcb == NULL) 994 return (EINVAL); 995 996 bcopy(&pcb->src, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr)); 997 sa.rfcomm_channel = pcb->channel; 998 sa.rfcomm_len = sizeof(sa); 999 sa.rfcomm_family = AF_BLUETOOTH; 1000 1001 *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); 1002 1003 return ((*nam == NULL)? ENOMEM : 0); 1004} /* ng_btsocket_rfcomm_sockaddr */ 1005 1006/* 1007 * Upcall function for L2CAP sockets. Enqueue RFCOMM task. 1008 */ 1009
|
1380 SOCKBUF_UNLOCK(&l2so->so_snd); 1381 l2so->so_state &= ~SS_NBIO; 1382 1383 mtx_destroy(&s->session_mtx); 1384 bzero(s, sizeof(*s)); 1385 free(s, M_NETGRAPH_BTSOCKET_RFCOMM); 1386 1387 return (error); 1388} /* ng_btsocket_rfcomm_session_create */ 1389 1390/* 1391 * Process accept() on RFCOMM session 1392 * XXX FIXME locking for "l2so"? 1393 */ 1394 1395static int 1396ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0) 1397{ 1398 struct socket *l2so = NULL; 1399 struct sockaddr_l2cap *l2sa = NULL; 1400 ng_btsocket_l2cap_pcb_t *l2pcb = NULL; 1401 ng_btsocket_rfcomm_session_p s = NULL; 1402 int error = 0; 1403 1404 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1405 mtx_assert(&s0->session_mtx, MA_OWNED); 1406 1407 /* Check if there is a complete L2CAP connection in the queue */ 1408 if ((error = s0->l2so->so_error) != 0) { 1409 NG_BTSOCKET_RFCOMM_ERR( 1410"%s: Could not accept connection on L2CAP socket, error=%d\n", __func__, error); 1411 s0->l2so->so_error = 0; 1412 1413 return (error); 1414 } 1415 1416 ACCEPT_LOCK(); 1417 if (TAILQ_EMPTY(&s0->l2so->so_comp)) { 1418 ACCEPT_UNLOCK(); 1419 if (s0->l2so->so_rcv.sb_state & SBS_CANTRCVMORE) 1420 return (ECONNABORTED); 1421 return (EWOULDBLOCK); 1422 } 1423 1424 /* Accept incoming L2CAP connection */ 1425 l2so = TAILQ_FIRST(&s0->l2so->so_comp); 1426 if (l2so == NULL) 1427 panic("%s: l2so == NULL\n", __func__); 1428 1429 TAILQ_REMOVE(&s0->l2so->so_comp, l2so, so_list); 1430 s0->l2so->so_qlen --; 1431 l2so->so_qstate &= ~SQ_COMP; 1432 l2so->so_head = NULL; 1433 SOCK_LOCK(l2so); 1434 soref(l2so); 1435 l2so->so_state |= SS_NBIO; 1436 SOCK_UNLOCK(l2so); 1437 ACCEPT_UNLOCK(); 1438 1439 error = soaccept(l2so, (struct sockaddr **) &l2sa); 1440 if (error != 0) { 1441 NG_BTSOCKET_RFCOMM_ERR( 1442"%s: soaccept() on L2CAP socket failed, error=%d\n", __func__, error); 1443 soclose(l2so); 1444 1445 return (error); 1446 } 1447 1448 /* 1449 * Check if there is already active RFCOMM session between two devices. 1450 * If so then close L2CAP connection. We only support one RFCOMM session 1451 * between each pair of devices. Note that here we assume session in any 1452 * state. The session even could be in the middle of disconnecting. 1453 */ 1454 1455 l2pcb = so2l2cap_pcb(l2so); 1456 s = ng_btsocket_rfcomm_session_by_addr(&l2pcb->src, &l2pcb->dst); 1457 if (s == NULL) { 1458 /* Create a new RFCOMM session */ 1459 error = ng_btsocket_rfcomm_session_create(&s, l2so, NULL, NULL, 1460 curthread /* XXX */); 1461 if (error == 0) { 1462 mtx_lock(&s->session_mtx); 1463 1464 s->flags = 0; 1465 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED; 1466 1467 /* 1468 * Adjust MTU on incomming connection. Reserve 5 bytes: 1469 * RFCOMM frame header, one extra byte for length and 1470 * one extra byte for credits. 1471 */ 1472 1473 s->mtu = min(l2pcb->imtu, l2pcb->omtu) - 1474 sizeof(struct rfcomm_frame_hdr) - 1 - 1; 1475 1476 mtx_unlock(&s->session_mtx); 1477 } else { 1478 NG_BTSOCKET_RFCOMM_ALERT( 1479"%s: Failed to create new RFCOMM session, error=%d\n", __func__, error); 1480 1481 soclose(l2so); 1482 } 1483 } else { 1484 NG_BTSOCKET_RFCOMM_WARN( 1485"%s: Rejecting duplicating RFCOMM session between src=%x:%x:%x:%x:%x:%x and " \ 1486"dst=%x:%x:%x:%x:%x:%x, state=%d, flags=%#x\n", __func__, 1487 l2pcb->src.b[5], l2pcb->src.b[4], l2pcb->src.b[3], 1488 l2pcb->src.b[2], l2pcb->src.b[1], l2pcb->src.b[0], 1489 l2pcb->dst.b[5], l2pcb->dst.b[4], l2pcb->dst.b[3], 1490 l2pcb->dst.b[2], l2pcb->dst.b[1], l2pcb->dst.b[0], 1491 s->state, s->flags); 1492 1493 error = EBUSY; 1494 soclose(l2so); 1495 } 1496 1497 return (error); 1498} /* ng_btsocket_rfcomm_session_accept */ 1499 1500/* 1501 * Process connect() on RFCOMM session 1502 * XXX FIXME locking for "l2so"? 1503 */ 1504 1505static int 1506ng_btsocket_rfcomm_session_connect(ng_btsocket_rfcomm_session_p s) 1507{ 1508 ng_btsocket_l2cap_pcb_p l2pcb = so2l2cap_pcb(s->l2so); 1509 int error; 1510 1511 mtx_assert(&s->session_mtx, MA_OWNED); 1512 1513 /* First check if connection has failed */ 1514 if ((error = s->l2so->so_error) != 0) { 1515 s->l2so->so_error = 0; 1516 1517 NG_BTSOCKET_RFCOMM_ERR( 1518"%s: Could not connect RFCOMM session, error=%d, state=%d, flags=%#x\n", 1519 __func__, error, s->state, s->flags); 1520 1521 return (error); 1522 } 1523 1524 /* Is connection still in progress? */ 1525 if (s->l2so->so_state & SS_ISCONNECTING) 1526 return (0); 1527 1528 /* 1529 * If we got here then we are connected. Send SABM on DLCI 0 to 1530 * open multiplexor channel. 1531 */ 1532 1533 if (error == 0) { 1534 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED; 1535 1536 /* 1537 * Adjust MTU on outgoing connection. Reserve 5 bytes: RFCOMM 1538 * frame header, one extra byte for length and one extra byte 1539 * for credits. 1540 */ 1541 1542 s->mtu = min(l2pcb->imtu, l2pcb->omtu) - 1543 sizeof(struct rfcomm_frame_hdr) - 1 - 1; 1544 1545 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_SABM,0); 1546 if (error == 0) 1547 error = ng_btsocket_rfcomm_task_wakeup(); 1548 } 1549 1550 return (error); 1551}/* ng_btsocket_rfcomm_session_connect */ 1552 1553/* 1554 * Receive data on RFCOMM session 1555 * XXX FIXME locking for "l2so"? 1556 */ 1557 1558static int 1559ng_btsocket_rfcomm_session_receive(ng_btsocket_rfcomm_session_p s) 1560{ 1561 struct mbuf *m = NULL; 1562 struct uio uio; 1563 int more, flags, error; 1564 1565 mtx_assert(&s->session_mtx, MA_OWNED); 1566 1567 /* Can we read from the L2CAP socket? */ 1568 if (!soreadable(s->l2so)) 1569 return (0); 1570 1571 /* First check for error on L2CAP socket */ 1572 if ((error = s->l2so->so_error) != 0) { 1573 s->l2so->so_error = 0; 1574 1575 NG_BTSOCKET_RFCOMM_ERR( 1576"%s: Could not receive data from L2CAP socket, error=%d, state=%d, flags=%#x\n", 1577 __func__, error, s->state, s->flags); 1578 1579 return (error); 1580 } 1581 1582 /* 1583 * Read all packets from the L2CAP socket. 1584 * XXX FIXME/VERIFY is that correct? For now use m->m_nextpkt as 1585 * indication that there is more packets on the socket's buffer. 1586 * Also what should we use in uio.uio_resid? 1587 * May be s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1? 1588 */ 1589 1590 for (more = 1; more; ) { 1591 /* Try to get next packet from socket */ 1592 bzero(&uio, sizeof(uio)); 1593/* uio.uio_td = NULL; */ 1594 uio.uio_resid = 1000000000; 1595 flags = MSG_DONTWAIT; 1596 1597 m = NULL; 1598 error = soreceive(s->l2so, NULL, &uio, &m, 1599 (struct mbuf **) NULL, &flags); 1600 if (error != 0) { 1601 if (error == EWOULDBLOCK) 1602 return (0); /* XXX can happen? */ 1603 1604 NG_BTSOCKET_RFCOMM_ERR( 1605"%s: Could not receive data from L2CAP socket, error=%d\n", __func__, error); 1606 1607 return (error); 1608 } 1609 1610 more = (m->m_nextpkt != NULL); 1611 m->m_nextpkt = NULL; 1612 1613 ng_btsocket_rfcomm_receive_frame(s, m); 1614 } 1615 1616 return (0); 1617} /* ng_btsocket_rfcomm_session_receive */ 1618 1619/* 1620 * Send data on RFCOMM session 1621 * XXX FIXME locking for "l2so"? 1622 */ 1623 1624static int 1625ng_btsocket_rfcomm_session_send(ng_btsocket_rfcomm_session_p s) 1626{ 1627 struct mbuf *m = NULL; 1628 int error; 1629 1630 mtx_assert(&s->session_mtx, MA_OWNED); 1631 1632 /* Send as much as we can from the session queue */ 1633 while (sowriteable(s->l2so)) { 1634 /* Check if socket still OK */ 1635 if ((error = s->l2so->so_error) != 0) { 1636 s->l2so->so_error = 0; 1637 1638 NG_BTSOCKET_RFCOMM_ERR( 1639"%s: Detected error=%d on L2CAP socket, state=%d, flags=%#x\n", 1640 __func__, error, s->state, s->flags); 1641 1642 return (error); 1643 } 1644 1645 NG_BT_MBUFQ_DEQUEUE(&s->outq, m); 1646 if (m == NULL) 1647 return (0); /* we are done */ 1648 1649 /* Call send function on the L2CAP socket */ 1650 error = (*s->l2so->so_proto->pr_usrreqs->pru_send)(s->l2so, 1651 0, m, NULL, NULL, curthread /* XXX */); 1652 if (error != 0) { 1653 NG_BTSOCKET_RFCOMM_ERR( 1654"%s: Could not send data to L2CAP socket, error=%d\n", __func__, error); 1655 1656 return (error); 1657 } 1658 } 1659 1660 return (0); 1661} /* ng_btsocket_rfcomm_session_send */ 1662 1663/* 1664 * Close and disconnect all DLCs for the given session. Caller must hold 1665 * s->sesson_mtx. Will wakeup session. 1666 */ 1667 1668static void 1669ng_btsocket_rfcomm_session_clean(ng_btsocket_rfcomm_session_p s) 1670{ 1671 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1672 int error; 1673 1674 mtx_assert(&s->session_mtx, MA_OWNED); 1675 1676 /* 1677 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1678 * will unlink DLC from the session 1679 */ 1680 1681 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1682 mtx_lock(&pcb->pcb_mtx); 1683 pcb_next = LIST_NEXT(pcb, session_next); 1684 1685 NG_BTSOCKET_RFCOMM_INFO( 1686"%s: Disconnecting dlci=%d, state=%d, flags=%#x\n", 1687 __func__, pcb->dlci, pcb->state, pcb->flags); 1688 1689 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 1690 error = ECONNRESET; 1691 else 1692 error = ECONNREFUSED; 1693 1694 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1695 1696 mtx_unlock(&pcb->pcb_mtx); 1697 pcb = pcb_next; 1698 } 1699} /* ng_btsocket_rfcomm_session_clean */ 1700 1701/* 1702 * Process all DLCs on the session. Caller MUST hold s->session_mtx. 1703 */ 1704 1705static void 1706ng_btsocket_rfcomm_session_process_pcb(ng_btsocket_rfcomm_session_p s) 1707{ 1708 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1709 int error; 1710 1711 mtx_assert(&s->session_mtx, MA_OWNED); 1712 1713 /* 1714 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1715 * will unlink DLC from the session 1716 */ 1717 1718 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1719 mtx_lock(&pcb->pcb_mtx); 1720 pcb_next = LIST_NEXT(pcb, session_next); 1721 1722 switch (pcb->state) { 1723 1724 /* 1725 * If DLC in W4_CONNECT state then we should check for both 1726 * timeout and detach. 1727 */ 1728 1729 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 1730 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_DETACHED) 1731 ng_btsocket_rfcomm_pcb_kill(pcb, 0); 1732 else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1733 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1734 break; 1735 1736 /* 1737 * If DLC in CONFIGURING or CONNECTING state then we only 1738 * should check for timeout. If detach() was called then 1739 * DLC will be moved into DISCONNECTING state. 1740 */ 1741 1742 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 1743 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 1744 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1745 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1746 break; 1747 1748 /* 1749 * If DLC in CONNECTED state then we need to send data (if any) 1750 * from the socket's send queue. Note that we will send data 1751 * from either all sockets or none. This may overload session's 1752 * outgoing queue (but we do not check for that). 1753 * 1754 * XXX FIXME need scheduler for RFCOMM sockets 1755 */ 1756 1757 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 1758 error = ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 1759 if (error != 0) 1760 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1761 break; 1762 1763 /* 1764 * If DLC in DISCONNECTING state then we must send DISC frame. 1765 * Note that if DLC has timeout set then we do not need to 1766 * resend DISC frame. 1767 * 1768 * XXX FIXME need to drain all data from the socket's queue 1769 * if LINGER option was set 1770 */ 1771 1772 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 1773 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) { 1774 error = ng_btsocket_rfcomm_send_command( 1775 pcb->session, RFCOMM_FRAME_DISC, 1776 pcb->dlci); 1777 if (error == 0) 1778 ng_btsocket_rfcomm_timeout(pcb); 1779 else 1780 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1781 } else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1782 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1783 break; 1784 1785/* case NG_BTSOCKET_RFCOMM_DLC_CLOSED: */ 1786 default: 1787 panic("%s: Invalid DLC state=%d, flags=%#x\n", 1788 __func__, pcb->state, pcb->flags); 1789 break; 1790 } 1791 1792 mtx_unlock(&pcb->pcb_mtx); 1793 pcb = pcb_next; 1794 } 1795} /* ng_btsocket_rfcomm_session_process_pcb */ 1796 1797/* 1798 * Find RFCOMM session between "src" and "dst". 1799 * Caller MUST hold ng_btsocket_rfcomm_sessions_mtx. 1800 */ 1801 1802static ng_btsocket_rfcomm_session_p 1803ng_btsocket_rfcomm_session_by_addr(bdaddr_p src, bdaddr_p dst) 1804{ 1805 ng_btsocket_rfcomm_session_p s = NULL; 1806 ng_btsocket_l2cap_pcb_p l2pcb = NULL; 1807 int any_src; 1808 1809 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1810 1811 any_src = (bcmp(src, NG_HCI_BDADDR_ANY, sizeof(*src)) == 0); 1812 1813 LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next) { 1814 l2pcb = so2l2cap_pcb(s->l2so); 1815 1816 if ((any_src || bcmp(&l2pcb->src, src, sizeof(*src)) == 0) && 1817 bcmp(&l2pcb->dst, dst, sizeof(*dst)) == 0) 1818 break; 1819 } 1820 1821 return (s); 1822} /* ng_btsocket_rfcomm_session_by_addr */ 1823 1824/***************************************************************************** 1825 ***************************************************************************** 1826 ** RFCOMM 1827 ***************************************************************************** 1828 *****************************************************************************/ 1829 1830/* 1831 * Process incoming RFCOMM frame. Caller must hold s->session_mtx. 1832 * XXX FIXME check frame length 1833 */ 1834 1835static int 1836ng_btsocket_rfcomm_receive_frame(ng_btsocket_rfcomm_session_p s, 1837 struct mbuf *m0) 1838{ 1839 struct rfcomm_frame_hdr *hdr = NULL; 1840 struct mbuf *m = NULL; 1841 u_int16_t length; 1842 u_int8_t dlci, type; 1843 int error = 0; 1844 1845 mtx_assert(&s->session_mtx, MA_OWNED); 1846 1847 /* Pullup as much as we can into first mbuf (for direct access) */ 1848 length = min(m0->m_pkthdr.len, MHLEN); 1849 if (m0->m_len < length) { 1850 if ((m0 = m_pullup(m0, length)) == NULL) { 1851 NG_BTSOCKET_RFCOMM_ALERT( 1852"%s: m_pullup(%d) failed\n", __func__, length); 1853 1854 return (ENOBUFS); 1855 } 1856 } 1857 1858 hdr = mtod(m0, struct rfcomm_frame_hdr *); 1859 dlci = RFCOMM_DLCI(hdr->address); 1860 type = RFCOMM_TYPE(hdr->control); 1861 1862 /* Test EA bit in length. If not set then we have 2 bytes of length */ 1863 if (!RFCOMM_EA(hdr->length)) { 1864 bcopy(&hdr->length, &length, sizeof(length)); 1865 length = le16toh(length) >> 1; 1866 m_adj(m0, sizeof(*hdr) + 1); 1867 } else { 1868 length = hdr->length >> 1; 1869 m_adj(m0, sizeof(*hdr)); 1870 } 1871 1872 NG_BTSOCKET_RFCOMM_INFO( 1873"%s: Got frame type=%#x, dlci=%d, length=%d, cr=%d, pf=%d, len=%d\n", 1874 __func__, type, dlci, length, RFCOMM_CR(hdr->address), 1875 RFCOMM_PF(hdr->control), m0->m_pkthdr.len); 1876 1877 /* 1878 * Get FCS (the last byte in the frame) 1879 * XXX this will not work if mbuf chain ends with empty mbuf. 1880 * XXX let's hope it never happens :) 1881 */ 1882 1883 for (m = m0; m->m_next != NULL; m = m->m_next) 1884 ; 1885 if (m->m_len <= 0) 1886 panic("%s: Empty mbuf at the end of the chain, len=%d\n", 1887 __func__, m->m_len); 1888 1889 /* 1890 * Check FCS. We only need to calculate FCS on first 2 or 3 bytes 1891 * and already m_pullup'ed mbuf chain, so it should be safe. 1892 */ 1893 1894 if (ng_btsocket_rfcomm_check_fcs((u_int8_t *) hdr, type, m->m_data[m->m_len - 1])) { 1895 NG_BTSOCKET_RFCOMM_ERR( 1896"%s: Invalid RFCOMM packet. Bad checksum\n", __func__); 1897 NG_FREE_M(m0); 1898 1899 return (EINVAL); 1900 } 1901 1902 m_adj(m0, -1); /* Trim FCS byte */ 1903 1904 /* 1905 * Process RFCOMM frame. 1906 * 1907 * From TS 07.10 spec 1908 * 1909 * "... In the case where a SABM or DISC command with the P bit set 1910 * to 0 is received then the received frame shall be discarded..." 1911 * 1912 * "... If a unsolicited DM response is received then the frame shall 1913 * be processed irrespective of the P/F setting... " 1914 * 1915 * "... The station may transmit response frames with the F bit set 1916 * to 0 at any opportunity on an asynchronous basis. However, in the 1917 * case where a UA response is received with the F bit set to 0 then 1918 * the received frame shall be discarded..." 1919 * 1920 * From Bluetooth spec 1921 * 1922 * "... When credit based flow control is being used, the meaning of 1923 * the P/F bit in the control field of the RFCOMM header is redefined 1924 * for UIH frames..." 1925 */ 1926 1927 switch (type) { 1928 case RFCOMM_FRAME_SABM: 1929 if (RFCOMM_PF(hdr->control)) 1930 error = ng_btsocket_rfcomm_receive_sabm(s, dlci); 1931 break; 1932 1933 case RFCOMM_FRAME_DISC: 1934 if (RFCOMM_PF(hdr->control)) 1935 error = ng_btsocket_rfcomm_receive_disc(s, dlci); 1936 break; 1937 1938 case RFCOMM_FRAME_UA: 1939 if (RFCOMM_PF(hdr->control)) 1940 error = ng_btsocket_rfcomm_receive_ua(s, dlci); 1941 break; 1942 1943 case RFCOMM_FRAME_DM: 1944 error = ng_btsocket_rfcomm_receive_dm(s, dlci); 1945 break; 1946 1947 case RFCOMM_FRAME_UIH: 1948 if (dlci == 0) 1949 error = ng_btsocket_rfcomm_receive_mcc(s, m0); 1950 else 1951 error = ng_btsocket_rfcomm_receive_uih(s, dlci, 1952 RFCOMM_PF(hdr->control), m0); 1953 1954 return (error); 1955 /* NOT REACHED */ 1956 1957 default: 1958 NG_BTSOCKET_RFCOMM_ERR( 1959"%s: Invalid RFCOMM packet. Unknown type=%#x\n", __func__, type); 1960 error = EINVAL; 1961 break; 1962 } 1963 1964 NG_FREE_M(m0); 1965 1966 return (error); 1967} /* ng_btsocket_rfcomm_receive_frame */ 1968 1969/* 1970 * Process RFCOMM SABM frame 1971 */ 1972 1973static int 1974ng_btsocket_rfcomm_receive_sabm(ng_btsocket_rfcomm_session_p s, int dlci) 1975{ 1976 ng_btsocket_rfcomm_pcb_p pcb = NULL; 1977 int error = 0; 1978 1979 mtx_assert(&s->session_mtx, MA_OWNED); 1980 1981 NG_BTSOCKET_RFCOMM_INFO( 1982"%s: Got SABM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 1983 __func__, s->state, s->flags, s->mtu, dlci); 1984 1985 /* DLCI == 0 means open multiplexor channel */ 1986 if (dlci == 0) { 1987 switch (s->state) { 1988 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 1989 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 1990 error = ng_btsocket_rfcomm_send_command(s, 1991 RFCOMM_FRAME_UA, dlci); 1992 if (error == 0) { 1993 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 1994 ng_btsocket_rfcomm_connect_cfm(s); 1995 } else { 1996 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1997 ng_btsocket_rfcomm_session_clean(s); 1998 } 1999 break; 2000 2001 default: 2002 NG_BTSOCKET_RFCOMM_WARN( 2003"%s: Got SABM for session in invalid state state=%d, flags=%#x\n", 2004 __func__, s->state, s->flags); 2005 error = EINVAL; 2006 break; 2007 } 2008 2009 return (error); 2010 } 2011 2012 /* Make sure multiplexor channel is open */ 2013 if (s->state != NG_BTSOCKET_RFCOMM_SESSION_OPEN) { 2014 NG_BTSOCKET_RFCOMM_ERR( 2015"%s: Got SABM for dlci=%d with mulitplexor channel closed, state=%d, " \ 2016"flags=%#x\n", __func__, dlci, s->state, s->flags); 2017 2018 return (EINVAL); 2019 } 2020 2021 /* 2022 * Check if we have this DLCI. This might happen when remote 2023 * peer uses PN command before actual open (SABM) happens. 2024 */ 2025 2026 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2027 if (pcb != NULL) { 2028 mtx_lock(&pcb->pcb_mtx); 2029 2030 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING) { 2031 NG_BTSOCKET_RFCOMM_ERR( 2032"%s: Got SABM for dlci=%d in invalid state=%d, flags=%#x\n", 2033 __func__, dlci, pcb->state, pcb->flags); 2034 mtx_unlock(&pcb->pcb_mtx); 2035 2036 return (ENOENT); 2037 } 2038 2039 ng_btsocket_rfcomm_untimeout(pcb); 2040 2041 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci); 2042 if (error == 0) 2043 error = ng_btsocket_rfcomm_send_msc(pcb); 2044 2045 if (error == 0) { 2046 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2047 soisconnected(pcb->so); 2048 } else 2049 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2050 2051 mtx_unlock(&pcb->pcb_mtx); 2052 2053 return (error); 2054 } 2055 2056 /* 2057 * We do not have requested DLCI, so it must be an incoming connection 2058 * with default parameters. Try to accept it. 2059 */ 2060 2061 pcb = ng_btsocket_rfcomm_connect_ind(s, RFCOMM_SRVCHANNEL(dlci)); 2062 if (pcb != NULL) { 2063 mtx_lock(&pcb->pcb_mtx); 2064 2065 pcb->dlci = dlci; 2066 2067 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci); 2068 if (error == 0) 2069 error = ng_btsocket_rfcomm_send_msc(pcb); 2070 2071 if (error == 0) { 2072 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2073 soisconnected(pcb->so); 2074 } else 2075 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2076 2077 mtx_unlock(&pcb->pcb_mtx); 2078 } else 2079 /* Nobody is listen()ing on the requested DLCI */ 2080 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2081 2082 return (error); 2083} /* ng_btsocket_rfcomm_receive_sabm */ 2084 2085/* 2086 * Process RFCOMM DISC frame 2087 */ 2088 2089static int 2090ng_btsocket_rfcomm_receive_disc(ng_btsocket_rfcomm_session_p s, int dlci) 2091{ 2092 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2093 int error = 0; 2094 2095 mtx_assert(&s->session_mtx, MA_OWNED); 2096 2097 NG_BTSOCKET_RFCOMM_INFO( 2098"%s: Got DISC, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2099 __func__, s->state, s->flags, s->mtu, dlci); 2100 2101 /* DLCI == 0 means close multiplexor channel */ 2102 if (dlci == 0) { 2103 /* XXX FIXME assume that remote side will close the socket */ 2104 error = ng_btsocket_rfcomm_send_command(s, RFCOMM_FRAME_UA, 0); 2105 if (error == 0) { 2106 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING) 2107 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2108 else 2109 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 2110 } else 2111 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2112 2113 ng_btsocket_rfcomm_session_clean(s); 2114 } else { 2115 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2116 if (pcb != NULL) { 2117 int err; 2118 2119 mtx_lock(&pcb->pcb_mtx); 2120 2121 NG_BTSOCKET_RFCOMM_INFO( 2122"%s: Got DISC for dlci=%d, state=%d, flags=%#x\n", 2123 __func__, dlci, pcb->state, pcb->flags); 2124 2125 error = ng_btsocket_rfcomm_send_command(s, 2126 RFCOMM_FRAME_UA, dlci); 2127 2128 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2129 err = 0; 2130 else 2131 err = ECONNREFUSED; 2132 2133 ng_btsocket_rfcomm_pcb_kill(pcb, err); 2134 2135 mtx_unlock(&pcb->pcb_mtx); 2136 } else { 2137 NG_BTSOCKET_RFCOMM_WARN( 2138"%s: Got DISC for non-existing dlci=%d\n", __func__, dlci); 2139 2140 error = ng_btsocket_rfcomm_send_command(s, 2141 RFCOMM_FRAME_DM, dlci); 2142 } 2143 } 2144 2145 return (error); 2146} /* ng_btsocket_rfcomm_receive_disc */ 2147 2148/* 2149 * Process RFCOMM UA frame 2150 */ 2151 2152static int 2153ng_btsocket_rfcomm_receive_ua(ng_btsocket_rfcomm_session_p s, int dlci) 2154{ 2155 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2156 int error = 0; 2157 2158 mtx_assert(&s->session_mtx, MA_OWNED); 2159 2160 NG_BTSOCKET_RFCOMM_INFO( 2161"%s: Got UA, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2162 __func__, s->state, s->flags, s->mtu, dlci); 2163 2164 /* dlci == 0 means multiplexor channel */ 2165 if (dlci == 0) { 2166 switch (s->state) { 2167 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 2168 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 2169 ng_btsocket_rfcomm_connect_cfm(s); 2170 break; 2171 2172 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 2173 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2174 ng_btsocket_rfcomm_session_clean(s); 2175 break; 2176 2177 default: 2178 NG_BTSOCKET_RFCOMM_WARN( 2179"%s: Got UA for session in invalid state=%d(%d), flags=%#x, mtu=%d\n", 2180 __func__, s->state, INITIATOR(s), s->flags, 2181 s->mtu); 2182 error = ENOENT; 2183 break; 2184 } 2185 2186 return (error); 2187 } 2188 2189 /* Check if we have this DLCI */ 2190 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2191 if (pcb != NULL) { 2192 mtx_lock(&pcb->pcb_mtx); 2193 2194 NG_BTSOCKET_RFCOMM_INFO( 2195"%s: Got UA for dlci=%d, state=%d, flags=%#x\n", 2196 __func__, dlci, pcb->state, pcb->flags); 2197 2198 switch (pcb->state) { 2199 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 2200 ng_btsocket_rfcomm_untimeout(pcb); 2201 2202 error = ng_btsocket_rfcomm_send_msc(pcb); 2203 if (error == 0) { 2204 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2205 soisconnected(pcb->so); 2206 } 2207 break; 2208 2209 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 2210 ng_btsocket_rfcomm_pcb_kill(pcb, 0); 2211 break; 2212 2213 default: 2214 NG_BTSOCKET_RFCOMM_WARN( 2215"%s: Got UA for dlci=%d in invalid state=%d, flags=%#x\n", 2216 __func__, dlci, pcb->state, pcb->flags); 2217 error = ENOENT; 2218 break; 2219 } 2220 2221 mtx_unlock(&pcb->pcb_mtx); 2222 } else { 2223 NG_BTSOCKET_RFCOMM_WARN( 2224"%s: Got UA for non-existing dlci=%d\n", __func__, dlci); 2225 2226 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2227 } 2228 2229 return (error); 2230} /* ng_btsocket_rfcomm_receive_ua */ 2231 2232/* 2233 * Process RFCOMM DM frame 2234 */ 2235 2236static int 2237ng_btsocket_rfcomm_receive_dm(ng_btsocket_rfcomm_session_p s, int dlci) 2238{ 2239 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2240 int error; 2241 2242 mtx_assert(&s->session_mtx, MA_OWNED); 2243 2244 NG_BTSOCKET_RFCOMM_INFO( 2245"%s: Got DM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2246 __func__, s->state, s->flags, s->mtu, dlci); 2247 2248 /* DLCI == 0 means multiplexor channel */ 2249 if (dlci == 0) { 2250 /* Disconnect all dlc's on the session */ 2251 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2252 ng_btsocket_rfcomm_session_clean(s); 2253 } else { 2254 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2255 if (pcb != NULL) { 2256 mtx_lock(&pcb->pcb_mtx); 2257 2258 NG_BTSOCKET_RFCOMM_INFO( 2259"%s: Got DM for dlci=%d, state=%d, flags=%#x\n", 2260 __func__, dlci, pcb->state, pcb->flags); 2261 2262 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2263 error = ECONNRESET; 2264 else 2265 error = ECONNREFUSED; 2266 2267 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2268 2269 mtx_unlock(&pcb->pcb_mtx); 2270 } else 2271 NG_BTSOCKET_RFCOMM_WARN( 2272"%s: Got DM for non-existing dlci=%d\n", __func__, dlci); 2273 } 2274 2275 return (0); 2276} /* ng_btsocket_rfcomm_receive_dm */ 2277 2278/* 2279 * Process RFCOMM UIH frame (data) 2280 */ 2281 2282static int 2283ng_btsocket_rfcomm_receive_uih(ng_btsocket_rfcomm_session_p s, int dlci, 2284 int pf, struct mbuf *m0) 2285{ 2286 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2287 int error = 0; 2288 2289 mtx_assert(&s->session_mtx, MA_OWNED); 2290 2291 NG_BTSOCKET_RFCOMM_INFO( 2292"%s: Got UIH, session state=%d, flags=%#x, mtu=%d, dlci=%d, pf=%d, len=%d\n", 2293 __func__, s->state, s->flags, s->mtu, dlci, pf, 2294 m0->m_pkthdr.len); 2295 2296 /* XXX should we do it here? Check for session flow control */ 2297 if (s->flags & NG_BTSOCKET_RFCOMM_SESSION_LFC) { 2298 NG_BTSOCKET_RFCOMM_WARN( 2299"%s: Got UIH with session flow control asserted, state=%d, flags=%#x\n", 2300 __func__, s->state, s->flags); 2301 goto drop; 2302 } 2303 2304 /* Check if we have this dlci */ 2305 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2306 if (pcb == NULL) { 2307 NG_BTSOCKET_RFCOMM_WARN( 2308"%s: Got UIH for non-existing dlci=%d\n", __func__, dlci); 2309 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2310 goto drop; 2311 } 2312 2313 mtx_lock(&pcb->pcb_mtx); 2314 2315 /* Check dlci state */ 2316 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2317 NG_BTSOCKET_RFCOMM_WARN( 2318"%s: Got UIH for dlci=%d in invalid state=%d, flags=%#x\n", 2319 __func__, dlci, pcb->state, pcb->flags); 2320 error = EINVAL; 2321 goto drop1; 2322 } 2323 2324 /* Check dlci flow control */ 2325 if (((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pcb->rx_cred <= 0) || 2326 (pcb->lmodem & RFCOMM_MODEM_FC)) { 2327 NG_BTSOCKET_RFCOMM_ERR( 2328"%s: Got UIH for dlci=%d with asserted flow control, state=%d, " \ 2329"flags=%#x, rx_cred=%d, lmodem=%#x\n", 2330 __func__, dlci, pcb->state, pcb->flags, 2331 pcb->rx_cred, pcb->lmodem); 2332 goto drop1; 2333 } 2334 2335 /* Did we get any credits? */ 2336 if ((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pf) { 2337 NG_BTSOCKET_RFCOMM_INFO( 2338"%s: Got %d more credits for dlci=%d, state=%d, flags=%#x, " \ 2339"rx_cred=%d, tx_cred=%d\n", 2340 __func__, *mtod(m0, u_int8_t *), dlci, pcb->state, 2341 pcb->flags, pcb->rx_cred, pcb->tx_cred); 2342 2343 pcb->tx_cred += *mtod(m0, u_int8_t *); 2344 m_adj(m0, 1); 2345 2346 /* Send more from the DLC. XXX check for errors? */ 2347 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2348 } 2349 2350 /* OK the of the rest of the mbuf is the data */ 2351 if (m0->m_pkthdr.len > 0) { 2352 /* If we are using credit flow control decrease rx_cred here */ 2353 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2354 /* Give remote peer more credits (if needed) */ 2355 if (-- pcb->rx_cred <= RFCOMM_MAX_CREDITS / 2) 2356 ng_btsocket_rfcomm_send_credits(pcb); 2357 else 2358 NG_BTSOCKET_RFCOMM_INFO( 2359"%s: Remote side still has credits, dlci=%d, state=%d, flags=%#x, " \ 2360"rx_cred=%d, tx_cred=%d\n", __func__, dlci, pcb->state, pcb->flags, 2361 pcb->rx_cred, pcb->tx_cred); 2362 } 2363 2364 /* Check packet against mtu on dlci */ 2365 if (m0->m_pkthdr.len > pcb->mtu) { 2366 NG_BTSOCKET_RFCOMM_ERR( 2367"%s: Got oversized UIH for dlci=%d, state=%d, flags=%#x, mtu=%d, len=%d\n", 2368 __func__, dlci, pcb->state, pcb->flags, 2369 pcb->mtu, m0->m_pkthdr.len); 2370 2371 error = EMSGSIZE; 2372 } else if (m0->m_pkthdr.len > sbspace(&pcb->so->so_rcv)) { 2373 2374 /* 2375 * This is really bad. Receive queue on socket does 2376 * not have enough space for the packet. We do not 2377 * have any other choice but drop the packet. 2378 */ 2379 2380 NG_BTSOCKET_RFCOMM_ERR( 2381"%s: Not enough space in socket receive queue. Dropping UIH for dlci=%d, " \ 2382"state=%d, flags=%#x, len=%d, space=%ld\n", 2383 __func__, dlci, pcb->state, pcb->flags, 2384 m0->m_pkthdr.len, sbspace(&pcb->so->so_rcv)); 2385 2386 error = ENOBUFS; 2387 } else { 2388 /* Append packet to the socket receive queue */ 2389 sbappend(&pcb->so->so_rcv, m0); 2390 m0 = NULL; 2391 2392 sorwakeup(pcb->so); 2393 } 2394 } 2395drop1: 2396 mtx_unlock(&pcb->pcb_mtx); 2397drop: 2398 NG_FREE_M(m0); /* checks for != NULL */ 2399 2400 return (error); 2401} /* ng_btsocket_rfcomm_receive_uih */ 2402 2403/* 2404 * Process RFCOMM MCC command (Multiplexor) 2405 * 2406 * From TS 07.10 spec 2407 * 2408 * "5.4.3.1 Information Data 2409 * 2410 * ...The frames (UIH) sent by the initiating station have the C/R bit set 2411 * to 1 and those sent by the responding station have the C/R bit set to 0..." 2412 * 2413 * "5.4.6.2 Operating procedures 2414 * 2415 * Messages always exist in pairs; a command message and a corresponding 2416 * response message. If the C/R bit is set to 1 the message is a command, 2417 * if it is set to 0 the message is a response... 2418 * 2419 * ... 2420 * 2421 * NOTE: Notice that when UIH frames are used to convey information on DLCI 0 2422 * there are at least two different fields that contain a C/R bit, and the 2423 * bits are set of different form. The C/R bit in the Type field shall be set 2424 * as it is stated above, while the C/R bit in the Address field (see subclause 2425 * 5.2.1.2) shall be set as it is described in subclause 5.4.3.1." 2426 */ 2427 2428static int 2429ng_btsocket_rfcomm_receive_mcc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2430{ 2431 struct rfcomm_mcc_hdr *hdr = NULL; 2432 u_int8_t cr, type, length; 2433 2434 mtx_assert(&s->session_mtx, MA_OWNED); 2435 2436 /* 2437 * We can access data directly in the first mbuf, because we have 2438 * m_pullup()'ed mbuf chain in ng_btsocket_rfcomm_receive_frame(). 2439 * All MCC commands should fit into single mbuf (except probably TEST). 2440 */ 2441 2442 hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2443 cr = RFCOMM_CR(hdr->type); 2444 type = RFCOMM_MCC_TYPE(hdr->type); 2445 length = RFCOMM_MCC_LENGTH(hdr->length); 2446 2447 /* Check MCC frame length */ 2448 if (sizeof(*hdr) + length != m0->m_pkthdr.len) { 2449 NG_BTSOCKET_RFCOMM_ERR( 2450"%s: Invalid MCC frame length=%d, len=%d\n", 2451 __func__, length, m0->m_pkthdr.len); 2452 NG_FREE_M(m0); 2453 2454 return (EMSGSIZE); 2455 } 2456 2457 switch (type) { 2458 case RFCOMM_MCC_TEST: 2459 return (ng_btsocket_rfcomm_receive_test(s, m0)); 2460 /* NOT REACHED */ 2461 2462 case RFCOMM_MCC_FCON: 2463 case RFCOMM_MCC_FCOFF: 2464 return (ng_btsocket_rfcomm_receive_fc(s, m0)); 2465 /* NOT REACHED */ 2466 2467 case RFCOMM_MCC_MSC: 2468 return (ng_btsocket_rfcomm_receive_msc(s, m0)); 2469 /* NOT REACHED */ 2470 2471 case RFCOMM_MCC_RPN: 2472 return (ng_btsocket_rfcomm_receive_rpn(s, m0)); 2473 /* NOT REACHED */ 2474 2475 case RFCOMM_MCC_RLS: 2476 return (ng_btsocket_rfcomm_receive_rls(s, m0)); 2477 /* NOT REACHED */ 2478 2479 case RFCOMM_MCC_PN: 2480 return (ng_btsocket_rfcomm_receive_pn(s, m0)); 2481 /* NOT REACHED */ 2482 2483 case RFCOMM_MCC_NSC: 2484 NG_BTSOCKET_RFCOMM_ERR( 2485"%s: Got MCC NSC, type=%#x, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2486"mtu=%d, len=%d\n", __func__, RFCOMM_MCC_TYPE(*((u_int8_t *)(hdr + 1))), cr, 2487 length, s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2488 NG_FREE_M(m0); 2489 break; 2490 2491 default: 2492 NG_BTSOCKET_RFCOMM_ERR( 2493"%s: Got unknown MCC, type=%#x, cr=%d, length=%d, session state=%d, " \ 2494"flags=%#x, mtu=%d, len=%d\n", 2495 __func__, type, cr, length, s->state, s->flags, 2496 s->mtu, m0->m_pkthdr.len); 2497 2498 /* Reuse mbuf to send NSC */ 2499 hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2500 m0->m_pkthdr.len = m0->m_len = sizeof(*hdr); 2501 2502 /* Create MCC NSC header */ 2503 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_NSC); 2504 hdr->length = RFCOMM_MKLEN8(1); 2505 2506 /* Put back MCC command type we did not like */ 2507 m0->m_data[m0->m_len] = RFCOMM_MKMCC_TYPE(cr, type); 2508 m0->m_pkthdr.len ++; 2509 m0->m_len ++; 2510 2511 /* Send UIH frame */ 2512 return (ng_btsocket_rfcomm_send_uih(s, 2513 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0)); 2514 /* NOT REACHED */ 2515 } 2516 2517 return (0); 2518} /* ng_btsocket_rfcomm_receive_mcc */ 2519 2520/* 2521 * Receive RFCOMM TEST MCC command 2522 */ 2523 2524static int 2525ng_btsocket_rfcomm_receive_test(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2526{ 2527 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2528 int error = 0; 2529 2530 mtx_assert(&s->session_mtx, MA_OWNED); 2531 2532 NG_BTSOCKET_RFCOMM_INFO( 2533"%s: Got MCC TEST, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \ 2534"len=%d\n", __func__, RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2535 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2536 2537 if (RFCOMM_CR(hdr->type)) { 2538 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_TEST); 2539 error = ng_btsocket_rfcomm_send_uih(s, 2540 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2541 } else 2542 NG_FREE_M(m0); /* XXX ignore response */ 2543 2544 return (error); 2545} /* ng_btsocket_rfcomm_receive_test */ 2546 2547/* 2548 * Receive RFCOMM FCON/FCOFF MCC command 2549 */ 2550 2551static int 2552ng_btsocket_rfcomm_receive_fc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2553{ 2554 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2555 u_int8_t type = RFCOMM_MCC_TYPE(hdr->type); 2556 int error = 0; 2557 2558 mtx_assert(&s->session_mtx, MA_OWNED); 2559 2560 /* 2561 * Turn ON/OFF aggregate flow on the entire session. When remote peer 2562 * asserted flow control no transmission shall occur except on dlci 0 2563 * (control channel). 2564 */ 2565 2566 NG_BTSOCKET_RFCOMM_INFO( 2567"%s: Got MCC FC%s, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \ 2568"len=%d\n", __func__, (type == RFCOMM_MCC_FCON)? "ON" : "OFF", 2569 RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2570 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2571 2572 if (RFCOMM_CR(hdr->type)) { 2573 if (type == RFCOMM_MCC_FCON) 2574 s->flags &= ~NG_BTSOCKET_RFCOMM_SESSION_RFC; 2575 else 2576 s->flags |= NG_BTSOCKET_RFCOMM_SESSION_RFC; 2577 2578 hdr->type = RFCOMM_MKMCC_TYPE(0, type); 2579 error = ng_btsocket_rfcomm_send_uih(s, 2580 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2581 } else 2582 NG_FREE_M(m0); /* XXX ignore response */ 2583 2584 return (error); 2585} /* ng_btsocket_rfcomm_receive_fc */ 2586 2587/* 2588 * Receive RFCOMM MSC MCC command 2589 */ 2590 2591static int 2592ng_btsocket_rfcomm_receive_msc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2593{ 2594 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr*); 2595 struct rfcomm_mcc_msc *msc = (struct rfcomm_mcc_msc *)(hdr+1); 2596 ng_btsocket_rfcomm_pcb_t *pcb = NULL; 2597 int error = 0; 2598 2599 mtx_assert(&s->session_mtx, MA_OWNED); 2600 2601 NG_BTSOCKET_RFCOMM_INFO( 2602"%s: Got MCC MSC, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2603"mtu=%d, len=%d\n", 2604 __func__, RFCOMM_DLCI(msc->address), RFCOMM_CR(hdr->type), 2605 RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags, 2606 s->mtu, m0->m_pkthdr.len); 2607 2608 if (RFCOMM_CR(hdr->type)) { 2609 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, RFCOMM_DLCI(msc->address)); 2610 if (pcb == NULL) { 2611 NG_BTSOCKET_RFCOMM_WARN( 2612"%s: Got MSC command for non-existing dlci=%d\n", 2613 __func__, RFCOMM_DLCI(msc->address)); 2614 NG_FREE_M(m0); 2615 2616 return (ENOENT); 2617 } 2618 2619 mtx_lock(&pcb->pcb_mtx); 2620 2621 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING && 2622 pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2623 NG_BTSOCKET_RFCOMM_WARN( 2624"%s: Got MSC on dlci=%d in invalid state=%d\n", 2625 __func__, RFCOMM_DLCI(msc->address), 2626 pcb->state); 2627 2628 mtx_unlock(&pcb->pcb_mtx); 2629 NG_FREE_M(m0); 2630 2631 return (EINVAL); 2632 } 2633 2634 pcb->rmodem = msc->modem; /* Update remote port signals */ 2635 2636 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_MSC); 2637 error = ng_btsocket_rfcomm_send_uih(s, 2638 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2639 2640#if 0 /* YYY */ 2641 /* Send more data from DLC. XXX check for errors? */ 2642 if (!(pcb->rmodem & RFCOMM_MODEM_FC) && 2643 !(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)) 2644 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2645#endif /* YYY */ 2646 2647 mtx_unlock(&pcb->pcb_mtx); 2648 } else 2649 NG_FREE_M(m0); /* XXX ignore response */ 2650 2651 return (error); 2652} /* ng_btsocket_rfcomm_receive_msc */ 2653 2654/* 2655 * Receive RFCOMM RPN MCC command 2656 * XXX FIXME do we need htole16/le16toh for RPN param_mask? 2657 */ 2658 2659static int 2660ng_btsocket_rfcomm_receive_rpn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2661{ 2662 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2663 struct rfcomm_mcc_rpn *rpn = (struct rfcomm_mcc_rpn *)(hdr + 1); 2664 int error = 0; 2665 u_int16_t param_mask; 2666 u_int8_t bit_rate, data_bits, stop_bits, parity, 2667 flow_control, xon_char, xoff_char; 2668 2669 mtx_assert(&s->session_mtx, MA_OWNED); 2670 2671 NG_BTSOCKET_RFCOMM_INFO( 2672"%s: Got MCC RPN, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2673"mtu=%d, len=%d\n", 2674 __func__, RFCOMM_DLCI(rpn->dlci), RFCOMM_CR(hdr->type), 2675 RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags, 2676 s->mtu, m0->m_pkthdr.len); 2677 2678 if (RFCOMM_CR(hdr->type)) { 2679 param_mask = RFCOMM_RPN_PM_ALL; 2680 2681 if (RFCOMM_MCC_LENGTH(hdr->length) == 1) { 2682 /* Request - return default setting */ 2683 bit_rate = RFCOMM_RPN_BR_115200; 2684 data_bits = RFCOMM_RPN_DATA_8; 2685 stop_bits = RFCOMM_RPN_STOP_1; 2686 parity = RFCOMM_RPN_PARITY_NONE; 2687 flow_control = RFCOMM_RPN_FLOW_NONE; 2688 xon_char = RFCOMM_RPN_XON_CHAR; 2689 xoff_char = RFCOMM_RPN_XOFF_CHAR; 2690 } else { 2691 /* 2692 * Ignore/accept bit_rate, 8 bits, 1 stop bit, no 2693 * parity, no flow control lines, default XON/XOFF 2694 * chars. 2695 */ 2696 2697 bit_rate = rpn->bit_rate; 2698 rpn->param_mask = le16toh(rpn->param_mask); /* XXX */ 2699 2700 data_bits = RFCOMM_RPN_DATA_BITS(rpn->line_settings); 2701 if (rpn->param_mask & RFCOMM_RPN_PM_DATA && 2702 data_bits != RFCOMM_RPN_DATA_8) { 2703 data_bits = RFCOMM_RPN_DATA_8; 2704 param_mask ^= RFCOMM_RPN_PM_DATA; 2705 } 2706 2707 stop_bits = RFCOMM_RPN_STOP_BITS(rpn->line_settings); 2708 if (rpn->param_mask & RFCOMM_RPN_PM_STOP && 2709 stop_bits != RFCOMM_RPN_STOP_1) { 2710 stop_bits = RFCOMM_RPN_STOP_1; 2711 param_mask ^= RFCOMM_RPN_PM_STOP; 2712 } 2713 2714 parity = RFCOMM_RPN_PARITY(rpn->line_settings); 2715 if (rpn->param_mask & RFCOMM_RPN_PM_PARITY && 2716 parity != RFCOMM_RPN_PARITY_NONE) { 2717 parity = RFCOMM_RPN_PARITY_NONE; 2718 param_mask ^= RFCOMM_RPN_PM_PARITY; 2719 } 2720 2721 flow_control = rpn->flow_control; 2722 if (rpn->param_mask & RFCOMM_RPN_PM_FLOW && 2723 flow_control != RFCOMM_RPN_FLOW_NONE) { 2724 flow_control = RFCOMM_RPN_FLOW_NONE; 2725 param_mask ^= RFCOMM_RPN_PM_FLOW; 2726 } 2727 2728 xon_char = rpn->xon_char; 2729 if (rpn->param_mask & RFCOMM_RPN_PM_XON && 2730 xon_char != RFCOMM_RPN_XON_CHAR) { 2731 xon_char = RFCOMM_RPN_XON_CHAR; 2732 param_mask ^= RFCOMM_RPN_PM_XON; 2733 } 2734 2735 xoff_char = rpn->xoff_char; 2736 if (rpn->param_mask & RFCOMM_RPN_PM_XOFF && 2737 xoff_char != RFCOMM_RPN_XOFF_CHAR) { 2738 xoff_char = RFCOMM_RPN_XOFF_CHAR; 2739 param_mask ^= RFCOMM_RPN_PM_XOFF; 2740 } 2741 } 2742 2743 rpn->bit_rate = bit_rate; 2744 rpn->line_settings = RFCOMM_MKRPN_LINE_SETTINGS(data_bits, 2745 stop_bits, parity); 2746 rpn->flow_control = flow_control; 2747 rpn->xon_char = xon_char; 2748 rpn->xoff_char = xoff_char; 2749 rpn->param_mask = htole16(param_mask); /* XXX */ 2750 2751 m0->m_pkthdr.len = m0->m_len = sizeof(*hdr) + sizeof(*rpn); 2752 2753 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RPN); 2754 error = ng_btsocket_rfcomm_send_uih(s, 2755 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2756 } else 2757 NG_FREE_M(m0); /* XXX ignore response */ 2758 2759 return (error); 2760} /* ng_btsocket_rfcomm_receive_rpn */ 2761 2762/* 2763 * Receive RFCOMM RLS MCC command 2764 */ 2765 2766static int 2767ng_btsocket_rfcomm_receive_rls(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2768{ 2769 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2770 struct rfcomm_mcc_rls *rls = (struct rfcomm_mcc_rls *)(hdr + 1); 2771 int error = 0; 2772 2773 mtx_assert(&s->session_mtx, MA_OWNED); 2774 2775 /* 2776 * XXX FIXME Do we have to do anything else here? Remote peer tries to 2777 * tell us something about DLCI. Just report what we have received and 2778 * return back received values as required by TS 07.10 spec. 2779 */ 2780 2781 NG_BTSOCKET_RFCOMM_INFO( 2782"%s: Got MCC RLS, dlci=%d, status=%#x, cr=%d, length=%d, session state=%d, " \ 2783"flags=%#x, mtu=%d, len=%d\n", 2784 __func__, RFCOMM_DLCI(rls->address), rls->status, 2785 RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2786 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2787 2788 if (RFCOMM_CR(hdr->type)) { 2789 if (rls->status & 0x1) 2790 NG_BTSOCKET_RFCOMM_ERR( 2791"%s: Got RLS dlci=%d, error=%#x\n", __func__, RFCOMM_DLCI(rls->address), 2792 rls->status >> 1); 2793 2794 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RLS); 2795 error = ng_btsocket_rfcomm_send_uih(s, 2796 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2797 } else 2798 NG_FREE_M(m0); /* XXX ignore responses */ 2799 2800 return (error); 2801} /* ng_btsocket_rfcomm_receive_rls */ 2802 2803/* 2804 * Receive RFCOMM PN MCC command 2805 */ 2806 2807static int 2808ng_btsocket_rfcomm_receive_pn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2809{ 2810 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr*); 2811 struct rfcomm_mcc_pn *pn = (struct rfcomm_mcc_pn *)(hdr+1); 2812 ng_btsocket_rfcomm_pcb_t *pcb = NULL; 2813 int error = 0; 2814 2815 mtx_assert(&s->session_mtx, MA_OWNED); 2816 2817 NG_BTSOCKET_RFCOMM_INFO( 2818"%s: Got MCC PN, dlci=%d, cr=%d, length=%d, flow_control=%#x, priority=%d, " \ 2819"ack_timer=%d, mtu=%d, max_retrans=%d, credits=%d, session state=%d, " \ 2820"flags=%#x, session mtu=%d, len=%d\n", 2821 __func__, pn->dlci, RFCOMM_CR(hdr->type), 2822 RFCOMM_MCC_LENGTH(hdr->length), pn->flow_control, pn->priority, 2823 pn->ack_timer, le16toh(pn->mtu), pn->max_retrans, pn->credits, 2824 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2825 2826 if (pn->dlci == 0) { 2827 NG_BTSOCKET_RFCOMM_ERR("%s: Zero dlci in MCC PN\n", __func__); 2828 NG_FREE_M(m0); 2829 2830 return (EINVAL); 2831 } 2832 2833 /* Check if we have this dlci */ 2834 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, pn->dlci); 2835 if (pcb != NULL) { 2836 mtx_lock(&pcb->pcb_mtx); 2837 2838 if (RFCOMM_CR(hdr->type)) { 2839 /* PN Request */ 2840 ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control, 2841 pn->credits, pn->mtu); 2842 2843 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2844 pn->flow_control = 0xe0; 2845 pn->credits = RFCOMM_DEFAULT_CREDITS; 2846 } else { 2847 pn->flow_control = 0; 2848 pn->credits = 0; 2849 } 2850 2851 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN); 2852 error = ng_btsocket_rfcomm_send_uih(s, 2853 RFCOMM_MKADDRESS(INITIATOR(s), 0), 2854 0, 0, m0); 2855 } else { 2856 /* PN Response - proceed with SABM. Timeout still set */ 2857 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONFIGURING) { 2858 ng_btsocket_rfcomm_set_pn(pcb, 0, 2859 pn->flow_control, pn->credits, pn->mtu); 2860 2861 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING; 2862 error = ng_btsocket_rfcomm_send_command(s, 2863 RFCOMM_FRAME_SABM, pn->dlci); 2864 } else 2865 NG_BTSOCKET_RFCOMM_WARN( 2866"%s: Got PN response for dlci=%d in invalid state=%d\n", 2867 __func__, pn->dlci, pcb->state); 2868 2869 NG_FREE_M(m0); 2870 } 2871 2872 mtx_unlock(&pcb->pcb_mtx); 2873 } else if (RFCOMM_CR(hdr->type)) { 2874 /* PN request to non-existing dlci - incomming connection */ 2875 pcb = ng_btsocket_rfcomm_connect_ind(s, 2876 RFCOMM_SRVCHANNEL(pn->dlci)); 2877 if (pcb != NULL) { 2878 mtx_lock(&pcb->pcb_mtx); 2879 2880 pcb->dlci = pn->dlci; 2881 2882 ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control, 2883 pn->credits, pn->mtu); 2884 2885 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2886 pn->flow_control = 0xe0; 2887 pn->credits = RFCOMM_DEFAULT_CREDITS; 2888 } else { 2889 pn->flow_control = 0; 2890 pn->credits = 0; 2891 } 2892 2893 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN); 2894 error = ng_btsocket_rfcomm_send_uih(s, 2895 RFCOMM_MKADDRESS(INITIATOR(s), 0), 2896 0, 0, m0); 2897 2898 if (error == 0) { 2899 ng_btsocket_rfcomm_timeout(pcb); 2900 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING; 2901 soisconnecting(pcb->so); 2902 } else 2903 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2904 2905 mtx_unlock(&pcb->pcb_mtx); 2906 } else { 2907 /* Nobody is listen()ing on this channel */ 2908 error = ng_btsocket_rfcomm_send_command(s, 2909 RFCOMM_FRAME_DM, pn->dlci); 2910 NG_FREE_M(m0); 2911 } 2912 } else 2913 NG_FREE_M(m0); /* XXX ignore response to non-existing dlci */ 2914 2915 return (error); 2916} /* ng_btsocket_rfcomm_receive_pn */ 2917 2918/* 2919 * Set PN parameters for dlci. Caller must hold pcb->pcb_mtx. 2920 * 2921 * From Bluetooth spec. 2922 * 2923 * "... The CL1 - CL4 field is completely redefined. (In TS07.10 this defines 2924 * the convergence layer to use, which is not applicable to RFCOMM. In RFCOMM, 2925 * in Bluetooth versions up to 1.0B, this field was forced to 0). 2926 * 2927 * In the PN request sent prior to a DLC establishment, this field must contain 2928 * the value 15 (0xF), indicating support of credit based flow control in the 2929 * sender. See Table 5.3 below. If the PN response contains any other value 2930 * than 14 (0xE) in this field, it is inferred that the peer RFCOMM entity is 2931 * not supporting the credit based flow control feature. (This is only possible 2932 * if the peer RFCOMM implementation is only conforming to Bluetooth version 2933 * 1.0B.) If a PN request is sent on an already open DLC, then this field must 2934 * contain the value zero; it is not possible to set initial credits more 2935 * than once per DLC activation. A responding implementation must set this 2936 * field in the PN response to 14 (0xE), if (and only if) the value in the PN 2937 * request was 15..." 2938 */ 2939 2940static void 2941ng_btsocket_rfcomm_set_pn(ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr, 2942 u_int8_t flow_control, u_int8_t credits, u_int16_t mtu) 2943{ 2944 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 2945 2946 pcb->mtu = le16toh(mtu); 2947 2948 if (cr) { 2949 if (flow_control == 0xf0) { 2950 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC; 2951 pcb->tx_cred = credits; 2952 } else { 2953 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC; 2954 pcb->tx_cred = 0; 2955 } 2956 } else { 2957 if (flow_control == 0xe0) { 2958 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC; 2959 pcb->tx_cred = credits; 2960 } else { 2961 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC; 2962 pcb->tx_cred = 0; 2963 } 2964 } 2965 2966 NG_BTSOCKET_RFCOMM_INFO( 2967"%s: cr=%d, dlci=%d, state=%d, flags=%#x, mtu=%d, rx_cred=%d, tx_cred=%d\n", 2968 __func__, cr, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 2969 pcb->rx_cred, pcb->tx_cred); 2970} /* ng_btsocket_rfcomm_set_pn */ 2971 2972/* 2973 * Send RFCOMM SABM/DISC/UA/DM frames. Caller must hold s->session_mtx 2974 */ 2975 2976static int 2977ng_btsocket_rfcomm_send_command(ng_btsocket_rfcomm_session_p s, 2978 u_int8_t type, u_int8_t dlci) 2979{ 2980 struct rfcomm_cmd_hdr *hdr = NULL; 2981 struct mbuf *m = NULL; 2982 int cr; 2983 2984 mtx_assert(&s->session_mtx, MA_OWNED); 2985 2986 NG_BTSOCKET_RFCOMM_INFO( 2987"%s: Sending command type %#x, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2988 __func__, type, s->state, s->flags, s->mtu, dlci); 2989 2990 switch (type) { 2991 case RFCOMM_FRAME_SABM: 2992 case RFCOMM_FRAME_DISC: 2993 cr = INITIATOR(s); 2994 break; 2995 2996 case RFCOMM_FRAME_UA: 2997 case RFCOMM_FRAME_DM: 2998 cr = !INITIATOR(s); 2999 break; 3000 3001 default: 3002 panic("%s: Invalid frame type=%#x\n", __func__, type); 3003 return (EINVAL); 3004 /* NOT REACHED */ 3005 } 3006 3007 MGETHDR(m, M_DONTWAIT, MT_DATA); 3008 if (m == NULL) 3009 return (ENOBUFS); 3010 3011 m->m_pkthdr.len = m->m_len = sizeof(*hdr); 3012 3013 hdr = mtod(m, struct rfcomm_cmd_hdr *); 3014 hdr->address = RFCOMM_MKADDRESS(cr, dlci); 3015 hdr->control = RFCOMM_MKCONTROL(type, 1); 3016 hdr->length = RFCOMM_MKLEN8(0); 3017 hdr->fcs = ng_btsocket_rfcomm_fcs3((u_int8_t *) hdr); 3018 3019 NG_BT_MBUFQ_ENQUEUE(&s->outq, m); 3020 3021 return (0); 3022} /* ng_btsocket_rfcomm_send_command */ 3023 3024/* 3025 * Send RFCOMM UIH frame. Caller must hold s->session_mtx 3026 */ 3027 3028static int 3029ng_btsocket_rfcomm_send_uih(ng_btsocket_rfcomm_session_p s, u_int8_t address, 3030 u_int8_t pf, u_int8_t credits, struct mbuf *data) 3031{ 3032 struct rfcomm_frame_hdr *hdr = NULL; 3033 struct mbuf *m = NULL, *mcrc = NULL; 3034 u_int16_t length; 3035 3036 mtx_assert(&s->session_mtx, MA_OWNED); 3037 3038 MGETHDR(m, M_DONTWAIT, MT_DATA); 3039 if (m == NULL) { 3040 NG_FREE_M(data); 3041 return (ENOBUFS); 3042 } 3043 m->m_pkthdr.len = m->m_len = sizeof(*hdr); 3044 3045 MGET(mcrc, M_DONTWAIT, MT_DATA); 3046 if (mcrc == NULL) { 3047 NG_FREE_M(data); 3048 return (ENOBUFS); 3049 } 3050 mcrc->m_len = 1; 3051 3052 /* Fill UIH frame header */ 3053 hdr = mtod(m, struct rfcomm_frame_hdr *); 3054 hdr->address = address; 3055 hdr->control = RFCOMM_MKCONTROL(RFCOMM_FRAME_UIH, pf); 3056 3057 /* Calculate FCS */ 3058 mcrc->m_data[0] = ng_btsocket_rfcomm_fcs2((u_int8_t *) hdr); 3059 3060 /* Put length back */ 3061 length = (data != NULL)? data->m_pkthdr.len : 0; 3062 if (length > 127) { 3063 u_int16_t l = htole16(RFCOMM_MKLEN16(length)); 3064 3065 bcopy(&l, &hdr->length, sizeof(l)); 3066 m->m_pkthdr.len ++; 3067 m->m_len ++; 3068 } else 3069 hdr->length = RFCOMM_MKLEN8(length); 3070 3071 if (pf) { 3072 m->m_data[m->m_len] = credits; 3073 m->m_pkthdr.len ++; 3074 m->m_len ++; 3075 } 3076 3077 /* Add payload */ 3078 if (data != NULL) { 3079 m_cat(m, data); 3080 m->m_pkthdr.len += length; 3081 } 3082 3083 /* Put FCS back */ 3084 m_cat(m, mcrc); 3085 m->m_pkthdr.len ++; 3086 3087 NG_BTSOCKET_RFCOMM_INFO( 3088"%s: Sending UIH state=%d, flags=%#x, address=%d, length=%d, pf=%d, " \ 3089"credits=%d, len=%d\n", 3090 __func__, s->state, s->flags, address, length, pf, credits, 3091 m->m_pkthdr.len); 3092 3093 NG_BT_MBUFQ_ENQUEUE(&s->outq, m); 3094 3095 return (0); 3096} /* ng_btsocket_rfcomm_send_uih */ 3097 3098/* 3099 * Send MSC request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3100 */ 3101 3102static int 3103ng_btsocket_rfcomm_send_msc(ng_btsocket_rfcomm_pcb_p pcb) 3104{ 3105 struct mbuf *m = NULL; 3106 struct rfcomm_mcc_hdr *hdr = NULL; 3107 struct rfcomm_mcc_msc *msc = NULL; 3108 3109 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3110 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3111 3112 MGETHDR(m, M_DONTWAIT, MT_DATA); 3113 if (m == NULL) 3114 return (ENOBUFS); 3115 3116 m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*msc); 3117 3118 hdr = mtod(m, struct rfcomm_mcc_hdr *); 3119 msc = (struct rfcomm_mcc_msc *)(hdr + 1); 3120 3121 hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_MSC); 3122 hdr->length = RFCOMM_MKLEN8(sizeof(*msc)); 3123 3124 msc->address = RFCOMM_MKADDRESS(1, pcb->dlci); 3125 msc->modem = pcb->lmodem; 3126 3127 NG_BTSOCKET_RFCOMM_INFO( 3128"%s: Sending MSC dlci=%d, state=%d, flags=%#x, address=%d, modem=%#x\n", 3129 __func__, pcb->dlci, pcb->state, pcb->flags, msc->address, 3130 msc->modem); 3131 3132 return (ng_btsocket_rfcomm_send_uih(pcb->session, 3133 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m)); 3134} /* ng_btsocket_rfcomm_send_msc */ 3135 3136/* 3137 * Send PN request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3138 */ 3139 3140static int 3141ng_btsocket_rfcomm_send_pn(ng_btsocket_rfcomm_pcb_p pcb) 3142{ 3143 struct mbuf *m = NULL; 3144 struct rfcomm_mcc_hdr *hdr = NULL; 3145 struct rfcomm_mcc_pn *pn = NULL; 3146 3147 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3148 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3149 3150 MGETHDR(m, M_DONTWAIT, MT_DATA); 3151 if (m == NULL) 3152 return (ENOBUFS); 3153 3154 m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*pn); 3155 3156 hdr = mtod(m, struct rfcomm_mcc_hdr *); 3157 pn = (struct rfcomm_mcc_pn *)(hdr + 1); 3158 3159 hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_PN); 3160 hdr->length = RFCOMM_MKLEN8(sizeof(*pn)); 3161 3162 pn->dlci = pcb->dlci; 3163 3164 /* 3165 * Set default DLCI priority as described in GSM 07.10 3166 * (ETSI TS 101 369) clause 5.6 page 42 3167 */ 3168 3169 pn->priority = (pcb->dlci < 56)? (((pcb->dlci >> 3) << 3) + 7) : 61; 3170 pn->ack_timer = 0; 3171 pn->mtu = htole16(pcb->mtu); 3172 pn->max_retrans = 0; 3173 3174 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 3175 pn->flow_control = 0xf0; 3176 pn->credits = pcb->rx_cred; 3177 } else { 3178 pn->flow_control = 0; 3179 pn->credits = 0; 3180 } 3181 3182 NG_BTSOCKET_RFCOMM_INFO( 3183"%s: Sending PN dlci=%d, state=%d, flags=%#x, mtu=%d, flow_control=%#x, " \ 3184"credits=%d\n", __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 3185 pn->flow_control, pn->credits); 3186 3187 return (ng_btsocket_rfcomm_send_uih(pcb->session, 3188 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m)); 3189} /* ng_btsocket_rfcomm_send_pn */ 3190 3191/* 3192 * Calculate and send credits based on available space in receive buffer 3193 */ 3194 3195static int 3196ng_btsocket_rfcomm_send_credits(ng_btsocket_rfcomm_pcb_p pcb) 3197{ 3198 int error = 0; 3199 u_int8_t credits; 3200 3201 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3202 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3203 3204 NG_BTSOCKET_RFCOMM_INFO( 3205"%s: Sending more credits, dlci=%d, state=%d, flags=%#x, mtu=%d, " \ 3206"space=%ld, tx_cred=%d, rx_cred=%d\n", 3207 __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 3208 sbspace(&pcb->so->so_rcv), pcb->tx_cred, pcb->rx_cred); 3209 3210 credits = sbspace(&pcb->so->so_rcv) / pcb->mtu; 3211 if (credits > 0) { 3212 if (pcb->rx_cred + credits > RFCOMM_MAX_CREDITS) 3213 credits = RFCOMM_MAX_CREDITS - pcb->rx_cred; 3214 3215 error = ng_btsocket_rfcomm_send_uih( 3216 pcb->session, 3217 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 3218 pcb->dlci), 1, credits, NULL); 3219 if (error == 0) { 3220 pcb->rx_cred += credits; 3221 3222 NG_BTSOCKET_RFCOMM_INFO( 3223"%s: Gave remote side %d more credits, dlci=%d, state=%d, flags=%#x, " \ 3224"rx_cred=%d, tx_cred=%d\n", __func__, credits, pcb->dlci, pcb->state, 3225 pcb->flags, pcb->rx_cred, pcb->tx_cred); 3226 } else 3227 NG_BTSOCKET_RFCOMM_ERR( 3228"%s: Could not send credits, error=%d, dlci=%d, state=%d, flags=%#x, " \ 3229"mtu=%d, space=%ld, tx_cred=%d, rx_cred=%d\n", 3230 __func__, error, pcb->dlci, pcb->state, 3231 pcb->flags, pcb->mtu, sbspace(&pcb->so->so_rcv), 3232 pcb->tx_cred, pcb->rx_cred); 3233 } 3234 3235 return (error); 3236} /* ng_btsocket_rfcomm_send_credits */ 3237 3238/***************************************************************************** 3239 ***************************************************************************** 3240 ** RFCOMM DLCs 3241 ***************************************************************************** 3242 *****************************************************************************/ 3243 3244/* 3245 * Send data from socket send buffer 3246 * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3247 */ 3248 3249static int 3250ng_btsocket_rfcomm_pcb_send(ng_btsocket_rfcomm_pcb_p pcb, int limit) 3251{ 3252 struct mbuf *m = NULL; 3253 int sent, length, error; 3254 3255 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3256 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3257 3258 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) 3259 limit = min(limit, pcb->tx_cred); 3260 else if (!(pcb->rmodem & RFCOMM_MODEM_FC)) 3261 limit = min(limit, RFCOMM_MAX_CREDITS); /* XXX ??? */ 3262 else 3263 limit = 0; 3264 3265 if (limit == 0) { 3266 NG_BTSOCKET_RFCOMM_INFO( 3267"%s: Could not send - remote flow control asserted, dlci=%d, flags=%#x, " \ 3268"rmodem=%#x, tx_cred=%d\n", 3269 __func__, pcb->dlci, pcb->flags, pcb->rmodem, 3270 pcb->tx_cred); 3271 3272 return (0); 3273 } 3274 3275 for (error = 0, sent = 0; sent < limit; sent ++) { 3276 length = min(pcb->mtu, pcb->so->so_snd.sb_cc); 3277 if (length == 0) 3278 break; 3279 3280 /* Get the chunk from the socket's send buffer */ 3281 m = ng_btsocket_rfcomm_prepare_packet(&pcb->so->so_snd, length); 3282 if (m == NULL) { 3283 error = ENOBUFS; 3284 break; 3285 } 3286 3287 sbdrop(&pcb->so->so_snd, length); 3288 3289 error = ng_btsocket_rfcomm_send_uih(pcb->session, 3290 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 3291 pcb->dlci), 0, 0, m); 3292 if (error != 0) 3293 break; 3294 } 3295 3296 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) 3297 pcb->tx_cred -= sent; 3298 3299 if (error == 0 && sent > 0) { 3300 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_SENDING; 3301 sowwakeup(pcb->so); 3302 } 3303 3304 return (error); 3305} /* ng_btsocket_rfcomm_pcb_send */ 3306 3307/* 3308 * Unlink and disconnect DLC. If ng_btsocket_rfcomm_pcb_kill() returns 3309 * non zero value than socket has no reference and has to be detached. 3310 * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3311 */ 3312 3313static void 3314ng_btsocket_rfcomm_pcb_kill(ng_btsocket_rfcomm_pcb_p pcb, int error) 3315{ 3316 ng_btsocket_rfcomm_session_p s = pcb->session; 3317 3318 NG_BTSOCKET_RFCOMM_INFO( 3319"%s: Killing DLC, so=%p, dlci=%d, state=%d, flags=%#x, error=%d\n", 3320 __func__, pcb->so, pcb->dlci, pcb->state, pcb->flags, error); 3321 3322 if (pcb->session == NULL) 3323 panic("%s: DLC without session, pcb=%p, state=%d, flags=%#x\n", 3324 __func__, pcb, pcb->state, pcb->flags); 3325 3326 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3327 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3328 3329 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 3330 ng_btsocket_rfcomm_untimeout(pcb); 3331 3332 /* Detach DLC from the session. Does not matter which state DLC in */ 3333 LIST_REMOVE(pcb, session_next); 3334 pcb->session = NULL; 3335 3336 /* Change DLC state and wakeup all sleepers */ 3337 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED; 3338 pcb->so->so_error = error; 3339 soisdisconnected(pcb->so); 3340 wakeup(&pcb->state); 3341 3342 /* Check if we have any DLCs left on the session */ 3343 if (LIST_EMPTY(&s->dlcs) && INITIATOR(s)) { 3344 NG_BTSOCKET_RFCOMM_INFO( 3345"%s: Disconnecting session, state=%d, flags=%#x, mtu=%d\n", 3346 __func__, s->state, s->flags, s->mtu); 3347 3348 switch (s->state) { 3349 case NG_BTSOCKET_RFCOMM_SESSION_CLOSED: 3350 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 3351 /* 3352 * Do not have to do anything here. We can get here 3353 * when L2CAP connection was terminated or we have 3354 * received DISC on multiplexor channel 3355 */ 3356 break; 3357 3358 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 3359 /* Send DISC on multiplexor channel */ 3360 error = ng_btsocket_rfcomm_send_command(s, 3361 RFCOMM_FRAME_DISC, 0); 3362 if (error == 0) { 3363 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 3364 break; 3365 } 3366 /* FALL THROUGH */ 3367 3368 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING: 3369 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 3370 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 3371 break; 3372 3373/* case NG_BTSOCKET_RFCOMM_SESSION_LISTENING: */ 3374 default: 3375 panic("%s: Invalid session state=%d, flags=%#x\n", 3376 __func__, s->state, s->flags); 3377 break; 3378 } 3379 3380 ng_btsocket_rfcomm_task_wakeup(); 3381 } 3382} /* ng_btsocket_rfcomm_pcb_kill */ 3383 3384/* 3385 * Look for given dlci for given RFCOMM session. Caller must hold s->session_mtx 3386 */ 3387 3388static ng_btsocket_rfcomm_pcb_p 3389ng_btsocket_rfcomm_pcb_by_dlci(ng_btsocket_rfcomm_session_p s, int dlci) 3390{ 3391 ng_btsocket_rfcomm_pcb_p pcb = NULL; 3392 3393 mtx_assert(&s->session_mtx, MA_OWNED); 3394 3395 LIST_FOREACH(pcb, &s->dlcs, session_next) 3396 if (pcb->dlci == dlci) 3397 break; 3398 3399 return (pcb); 3400} /* ng_btsocket_rfcomm_pcb_by_dlci */ 3401 3402/* 3403 * Look for socket that listens on given src address and given channel 3404 */ 3405 3406static ng_btsocket_rfcomm_pcb_p 3407ng_btsocket_rfcomm_pcb_listener(bdaddr_p src, int channel) 3408{ 3409 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb1 = NULL; 3410 3411 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 3412 3413 LIST_FOREACH(pcb, &ng_btsocket_rfcomm_sockets, next) { 3414 if (pcb->channel != channel || 3415 !(pcb->so->so_options & SO_ACCEPTCONN)) 3416 continue; 3417 3418 if (bcmp(&pcb->src, src, sizeof(*src)) == 0) 3419 break; 3420 3421 if (bcmp(&pcb->src, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0) 3422 pcb1 = pcb; 3423 } 3424 3425 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 3426 3427 return ((pcb != NULL)? pcb : pcb1); 3428} /* ng_btsocket_rfcomm_pcb_listener */ 3429 3430/***************************************************************************** 3431 ***************************************************************************** 3432 ** Misc. functions 3433 ***************************************************************************** 3434 *****************************************************************************/ 3435 3436/* 3437 * Set timeout. Caller MUST hold pcb_mtx 3438 */ 3439 3440static void 3441ng_btsocket_rfcomm_timeout(ng_btsocket_rfcomm_pcb_p pcb) 3442{ 3443 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3444 3445 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) { 3446 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMO; 3447 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3448 pcb->timo = timeout(ng_btsocket_rfcomm_process_timeout, pcb, 3449 ng_btsocket_rfcomm_timo * hz); 3450 } else 3451 panic("%s: Duplicated socket timeout?!\n", __func__); 3452} /* ng_btsocket_rfcomm_timeout */ 3453 3454/* 3455 * Unset pcb timeout. Caller MUST hold pcb_mtx 3456 */ 3457 3458static void 3459ng_btsocket_rfcomm_untimeout(ng_btsocket_rfcomm_pcb_p pcb) 3460{ 3461 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3462 3463 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) { 3464 untimeout(ng_btsocket_rfcomm_process_timeout, pcb, pcb->timo); 3465 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO; 3466 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3467 } else 3468 panic("%s: No socket timeout?!\n", __func__); 3469} /* ng_btsocket_rfcomm_timeout */ 3470 3471/* 3472 * Process pcb timeout 3473 */ 3474 3475static void 3476ng_btsocket_rfcomm_process_timeout(void *xpcb) 3477{ 3478 ng_btsocket_rfcomm_pcb_p pcb = (ng_btsocket_rfcomm_pcb_p) xpcb; 3479 3480 mtx_lock(&pcb->pcb_mtx); 3481 3482 NG_BTSOCKET_RFCOMM_INFO( 3483"%s: Timeout, so=%p, dlci=%d, state=%d, flags=%#x\n", 3484 __func__, pcb->so, pcb->dlci, pcb->state, pcb->flags); 3485 3486 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO; 3487 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3488 3489 switch (pcb->state) { 3490 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 3491 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 3492 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 3493 break; 3494 3495 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 3496 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 3497 break; 3498 3499 default: 3500 panic( 3501"%s: DLC timeout in invalid state, dlci=%d, state=%d, flags=%#x\n", 3502 __func__, pcb->dlci, pcb->state, pcb->flags); 3503 break; 3504 } 3505 3506 ng_btsocket_rfcomm_task_wakeup(); 3507 3508 mtx_unlock(&pcb->pcb_mtx); 3509} /* ng_btsocket_rfcomm_process_timeout */ 3510 3511/* 3512 * Get up to length bytes from the socket buffer 3513 */ 3514 3515static struct mbuf * 3516ng_btsocket_rfcomm_prepare_packet(struct sockbuf *sb, int length) 3517{ 3518 struct mbuf *top = NULL, *m = NULL, *n = NULL, *nextpkt = NULL; 3519 int mlen, noff, len; 3520 3521 MGETHDR(top, M_DONTWAIT, MT_DATA); 3522 if (top == NULL) 3523 return (NULL); 3524 3525 top->m_pkthdr.len = length; 3526 top->m_len = 0; 3527 mlen = MHLEN; 3528 3529 m = top; 3530 n = sb->sb_mb; 3531 nextpkt = n->m_nextpkt; 3532 noff = 0; 3533 3534 while (length > 0 && n != NULL) { 3535 len = min(mlen - m->m_len, n->m_len - noff); 3536 if (len > length) 3537 len = length; 3538 3539 bcopy(mtod(n, caddr_t)+noff, mtod(m, caddr_t)+m->m_len, len); 3540 m->m_len += len; 3541 noff += len; 3542 length -= len; 3543 3544 if (length > 0 && m->m_len == mlen) { 3545 MGET(m->m_next, M_DONTWAIT, MT_DATA); 3546 if (m->m_next == NULL) { 3547 NG_FREE_M(top); 3548 return (NULL); 3549 } 3550 3551 m = m->m_next; 3552 m->m_len = 0; 3553 mlen = MLEN; 3554 } 3555 3556 if (noff == n->m_len) { 3557 noff = 0; 3558 n = n->m_next; 3559 3560 if (n == NULL) 3561 n = nextpkt; 3562 3563 nextpkt = (n != NULL)? n->m_nextpkt : NULL; 3564 } 3565 } 3566 3567 if (length < 0) 3568 panic("%s: length=%d\n", __func__, length); 3569 if (length > 0 && n == NULL) 3570 panic("%s: bogus length=%d, n=%p\n", __func__, length, n); 3571 3572 return (top); 3573} /* ng_btsocket_rfcomm_prepare_packet */ 3574
| 1375 SOCKBUF_UNLOCK(&l2so->so_snd); 1376 l2so->so_state &= ~SS_NBIO; 1377 1378 mtx_destroy(&s->session_mtx); 1379 bzero(s, sizeof(*s)); 1380 free(s, M_NETGRAPH_BTSOCKET_RFCOMM); 1381 1382 return (error); 1383} /* ng_btsocket_rfcomm_session_create */ 1384 1385/* 1386 * Process accept() on RFCOMM session 1387 * XXX FIXME locking for "l2so"? 1388 */ 1389 1390static int 1391ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0) 1392{ 1393 struct socket *l2so = NULL; 1394 struct sockaddr_l2cap *l2sa = NULL; 1395 ng_btsocket_l2cap_pcb_t *l2pcb = NULL; 1396 ng_btsocket_rfcomm_session_p s = NULL; 1397 int error = 0; 1398 1399 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1400 mtx_assert(&s0->session_mtx, MA_OWNED); 1401 1402 /* Check if there is a complete L2CAP connection in the queue */ 1403 if ((error = s0->l2so->so_error) != 0) { 1404 NG_BTSOCKET_RFCOMM_ERR( 1405"%s: Could not accept connection on L2CAP socket, error=%d\n", __func__, error); 1406 s0->l2so->so_error = 0; 1407 1408 return (error); 1409 } 1410 1411 ACCEPT_LOCK(); 1412 if (TAILQ_EMPTY(&s0->l2so->so_comp)) { 1413 ACCEPT_UNLOCK(); 1414 if (s0->l2so->so_rcv.sb_state & SBS_CANTRCVMORE) 1415 return (ECONNABORTED); 1416 return (EWOULDBLOCK); 1417 } 1418 1419 /* Accept incoming L2CAP connection */ 1420 l2so = TAILQ_FIRST(&s0->l2so->so_comp); 1421 if (l2so == NULL) 1422 panic("%s: l2so == NULL\n", __func__); 1423 1424 TAILQ_REMOVE(&s0->l2so->so_comp, l2so, so_list); 1425 s0->l2so->so_qlen --; 1426 l2so->so_qstate &= ~SQ_COMP; 1427 l2so->so_head = NULL; 1428 SOCK_LOCK(l2so); 1429 soref(l2so); 1430 l2so->so_state |= SS_NBIO; 1431 SOCK_UNLOCK(l2so); 1432 ACCEPT_UNLOCK(); 1433 1434 error = soaccept(l2so, (struct sockaddr **) &l2sa); 1435 if (error != 0) { 1436 NG_BTSOCKET_RFCOMM_ERR( 1437"%s: soaccept() on L2CAP socket failed, error=%d\n", __func__, error); 1438 soclose(l2so); 1439 1440 return (error); 1441 } 1442 1443 /* 1444 * Check if there is already active RFCOMM session between two devices. 1445 * If so then close L2CAP connection. We only support one RFCOMM session 1446 * between each pair of devices. Note that here we assume session in any 1447 * state. The session even could be in the middle of disconnecting. 1448 */ 1449 1450 l2pcb = so2l2cap_pcb(l2so); 1451 s = ng_btsocket_rfcomm_session_by_addr(&l2pcb->src, &l2pcb->dst); 1452 if (s == NULL) { 1453 /* Create a new RFCOMM session */ 1454 error = ng_btsocket_rfcomm_session_create(&s, l2so, NULL, NULL, 1455 curthread /* XXX */); 1456 if (error == 0) { 1457 mtx_lock(&s->session_mtx); 1458 1459 s->flags = 0; 1460 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED; 1461 1462 /* 1463 * Adjust MTU on incomming connection. Reserve 5 bytes: 1464 * RFCOMM frame header, one extra byte for length and 1465 * one extra byte for credits. 1466 */ 1467 1468 s->mtu = min(l2pcb->imtu, l2pcb->omtu) - 1469 sizeof(struct rfcomm_frame_hdr) - 1 - 1; 1470 1471 mtx_unlock(&s->session_mtx); 1472 } else { 1473 NG_BTSOCKET_RFCOMM_ALERT( 1474"%s: Failed to create new RFCOMM session, error=%d\n", __func__, error); 1475 1476 soclose(l2so); 1477 } 1478 } else { 1479 NG_BTSOCKET_RFCOMM_WARN( 1480"%s: Rejecting duplicating RFCOMM session between src=%x:%x:%x:%x:%x:%x and " \ 1481"dst=%x:%x:%x:%x:%x:%x, state=%d, flags=%#x\n", __func__, 1482 l2pcb->src.b[5], l2pcb->src.b[4], l2pcb->src.b[3], 1483 l2pcb->src.b[2], l2pcb->src.b[1], l2pcb->src.b[0], 1484 l2pcb->dst.b[5], l2pcb->dst.b[4], l2pcb->dst.b[3], 1485 l2pcb->dst.b[2], l2pcb->dst.b[1], l2pcb->dst.b[0], 1486 s->state, s->flags); 1487 1488 error = EBUSY; 1489 soclose(l2so); 1490 } 1491 1492 return (error); 1493} /* ng_btsocket_rfcomm_session_accept */ 1494 1495/* 1496 * Process connect() on RFCOMM session 1497 * XXX FIXME locking for "l2so"? 1498 */ 1499 1500static int 1501ng_btsocket_rfcomm_session_connect(ng_btsocket_rfcomm_session_p s) 1502{ 1503 ng_btsocket_l2cap_pcb_p l2pcb = so2l2cap_pcb(s->l2so); 1504 int error; 1505 1506 mtx_assert(&s->session_mtx, MA_OWNED); 1507 1508 /* First check if connection has failed */ 1509 if ((error = s->l2so->so_error) != 0) { 1510 s->l2so->so_error = 0; 1511 1512 NG_BTSOCKET_RFCOMM_ERR( 1513"%s: Could not connect RFCOMM session, error=%d, state=%d, flags=%#x\n", 1514 __func__, error, s->state, s->flags); 1515 1516 return (error); 1517 } 1518 1519 /* Is connection still in progress? */ 1520 if (s->l2so->so_state & SS_ISCONNECTING) 1521 return (0); 1522 1523 /* 1524 * If we got here then we are connected. Send SABM on DLCI 0 to 1525 * open multiplexor channel. 1526 */ 1527 1528 if (error == 0) { 1529 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED; 1530 1531 /* 1532 * Adjust MTU on outgoing connection. Reserve 5 bytes: RFCOMM 1533 * frame header, one extra byte for length and one extra byte 1534 * for credits. 1535 */ 1536 1537 s->mtu = min(l2pcb->imtu, l2pcb->omtu) - 1538 sizeof(struct rfcomm_frame_hdr) - 1 - 1; 1539 1540 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_SABM,0); 1541 if (error == 0) 1542 error = ng_btsocket_rfcomm_task_wakeup(); 1543 } 1544 1545 return (error); 1546}/* ng_btsocket_rfcomm_session_connect */ 1547 1548/* 1549 * Receive data on RFCOMM session 1550 * XXX FIXME locking for "l2so"? 1551 */ 1552 1553static int 1554ng_btsocket_rfcomm_session_receive(ng_btsocket_rfcomm_session_p s) 1555{ 1556 struct mbuf *m = NULL; 1557 struct uio uio; 1558 int more, flags, error; 1559 1560 mtx_assert(&s->session_mtx, MA_OWNED); 1561 1562 /* Can we read from the L2CAP socket? */ 1563 if (!soreadable(s->l2so)) 1564 return (0); 1565 1566 /* First check for error on L2CAP socket */ 1567 if ((error = s->l2so->so_error) != 0) { 1568 s->l2so->so_error = 0; 1569 1570 NG_BTSOCKET_RFCOMM_ERR( 1571"%s: Could not receive data from L2CAP socket, error=%d, state=%d, flags=%#x\n", 1572 __func__, error, s->state, s->flags); 1573 1574 return (error); 1575 } 1576 1577 /* 1578 * Read all packets from the L2CAP socket. 1579 * XXX FIXME/VERIFY is that correct? For now use m->m_nextpkt as 1580 * indication that there is more packets on the socket's buffer. 1581 * Also what should we use in uio.uio_resid? 1582 * May be s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1? 1583 */ 1584 1585 for (more = 1; more; ) { 1586 /* Try to get next packet from socket */ 1587 bzero(&uio, sizeof(uio)); 1588/* uio.uio_td = NULL; */ 1589 uio.uio_resid = 1000000000; 1590 flags = MSG_DONTWAIT; 1591 1592 m = NULL; 1593 error = soreceive(s->l2so, NULL, &uio, &m, 1594 (struct mbuf **) NULL, &flags); 1595 if (error != 0) { 1596 if (error == EWOULDBLOCK) 1597 return (0); /* XXX can happen? */ 1598 1599 NG_BTSOCKET_RFCOMM_ERR( 1600"%s: Could not receive data from L2CAP socket, error=%d\n", __func__, error); 1601 1602 return (error); 1603 } 1604 1605 more = (m->m_nextpkt != NULL); 1606 m->m_nextpkt = NULL; 1607 1608 ng_btsocket_rfcomm_receive_frame(s, m); 1609 } 1610 1611 return (0); 1612} /* ng_btsocket_rfcomm_session_receive */ 1613 1614/* 1615 * Send data on RFCOMM session 1616 * XXX FIXME locking for "l2so"? 1617 */ 1618 1619static int 1620ng_btsocket_rfcomm_session_send(ng_btsocket_rfcomm_session_p s) 1621{ 1622 struct mbuf *m = NULL; 1623 int error; 1624 1625 mtx_assert(&s->session_mtx, MA_OWNED); 1626 1627 /* Send as much as we can from the session queue */ 1628 while (sowriteable(s->l2so)) { 1629 /* Check if socket still OK */ 1630 if ((error = s->l2so->so_error) != 0) { 1631 s->l2so->so_error = 0; 1632 1633 NG_BTSOCKET_RFCOMM_ERR( 1634"%s: Detected error=%d on L2CAP socket, state=%d, flags=%#x\n", 1635 __func__, error, s->state, s->flags); 1636 1637 return (error); 1638 } 1639 1640 NG_BT_MBUFQ_DEQUEUE(&s->outq, m); 1641 if (m == NULL) 1642 return (0); /* we are done */ 1643 1644 /* Call send function on the L2CAP socket */ 1645 error = (*s->l2so->so_proto->pr_usrreqs->pru_send)(s->l2so, 1646 0, m, NULL, NULL, curthread /* XXX */); 1647 if (error != 0) { 1648 NG_BTSOCKET_RFCOMM_ERR( 1649"%s: Could not send data to L2CAP socket, error=%d\n", __func__, error); 1650 1651 return (error); 1652 } 1653 } 1654 1655 return (0); 1656} /* ng_btsocket_rfcomm_session_send */ 1657 1658/* 1659 * Close and disconnect all DLCs for the given session. Caller must hold 1660 * s->sesson_mtx. Will wakeup session. 1661 */ 1662 1663static void 1664ng_btsocket_rfcomm_session_clean(ng_btsocket_rfcomm_session_p s) 1665{ 1666 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1667 int error; 1668 1669 mtx_assert(&s->session_mtx, MA_OWNED); 1670 1671 /* 1672 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1673 * will unlink DLC from the session 1674 */ 1675 1676 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1677 mtx_lock(&pcb->pcb_mtx); 1678 pcb_next = LIST_NEXT(pcb, session_next); 1679 1680 NG_BTSOCKET_RFCOMM_INFO( 1681"%s: Disconnecting dlci=%d, state=%d, flags=%#x\n", 1682 __func__, pcb->dlci, pcb->state, pcb->flags); 1683 1684 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 1685 error = ECONNRESET; 1686 else 1687 error = ECONNREFUSED; 1688 1689 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1690 1691 mtx_unlock(&pcb->pcb_mtx); 1692 pcb = pcb_next; 1693 } 1694} /* ng_btsocket_rfcomm_session_clean */ 1695 1696/* 1697 * Process all DLCs on the session. Caller MUST hold s->session_mtx. 1698 */ 1699 1700static void 1701ng_btsocket_rfcomm_session_process_pcb(ng_btsocket_rfcomm_session_p s) 1702{ 1703 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1704 int error; 1705 1706 mtx_assert(&s->session_mtx, MA_OWNED); 1707 1708 /* 1709 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1710 * will unlink DLC from the session 1711 */ 1712 1713 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1714 mtx_lock(&pcb->pcb_mtx); 1715 pcb_next = LIST_NEXT(pcb, session_next); 1716 1717 switch (pcb->state) { 1718 1719 /* 1720 * If DLC in W4_CONNECT state then we should check for both 1721 * timeout and detach. 1722 */ 1723 1724 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 1725 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_DETACHED) 1726 ng_btsocket_rfcomm_pcb_kill(pcb, 0); 1727 else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1728 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1729 break; 1730 1731 /* 1732 * If DLC in CONFIGURING or CONNECTING state then we only 1733 * should check for timeout. If detach() was called then 1734 * DLC will be moved into DISCONNECTING state. 1735 */ 1736 1737 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 1738 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 1739 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1740 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1741 break; 1742 1743 /* 1744 * If DLC in CONNECTED state then we need to send data (if any) 1745 * from the socket's send queue. Note that we will send data 1746 * from either all sockets or none. This may overload session's 1747 * outgoing queue (but we do not check for that). 1748 * 1749 * XXX FIXME need scheduler for RFCOMM sockets 1750 */ 1751 1752 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 1753 error = ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 1754 if (error != 0) 1755 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1756 break; 1757 1758 /* 1759 * If DLC in DISCONNECTING state then we must send DISC frame. 1760 * Note that if DLC has timeout set then we do not need to 1761 * resend DISC frame. 1762 * 1763 * XXX FIXME need to drain all data from the socket's queue 1764 * if LINGER option was set 1765 */ 1766 1767 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 1768 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) { 1769 error = ng_btsocket_rfcomm_send_command( 1770 pcb->session, RFCOMM_FRAME_DISC, 1771 pcb->dlci); 1772 if (error == 0) 1773 ng_btsocket_rfcomm_timeout(pcb); 1774 else 1775 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1776 } else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1777 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1778 break; 1779 1780/* case NG_BTSOCKET_RFCOMM_DLC_CLOSED: */ 1781 default: 1782 panic("%s: Invalid DLC state=%d, flags=%#x\n", 1783 __func__, pcb->state, pcb->flags); 1784 break; 1785 } 1786 1787 mtx_unlock(&pcb->pcb_mtx); 1788 pcb = pcb_next; 1789 } 1790} /* ng_btsocket_rfcomm_session_process_pcb */ 1791 1792/* 1793 * Find RFCOMM session between "src" and "dst". 1794 * Caller MUST hold ng_btsocket_rfcomm_sessions_mtx. 1795 */ 1796 1797static ng_btsocket_rfcomm_session_p 1798ng_btsocket_rfcomm_session_by_addr(bdaddr_p src, bdaddr_p dst) 1799{ 1800 ng_btsocket_rfcomm_session_p s = NULL; 1801 ng_btsocket_l2cap_pcb_p l2pcb = NULL; 1802 int any_src; 1803 1804 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1805 1806 any_src = (bcmp(src, NG_HCI_BDADDR_ANY, sizeof(*src)) == 0); 1807 1808 LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next) { 1809 l2pcb = so2l2cap_pcb(s->l2so); 1810 1811 if ((any_src || bcmp(&l2pcb->src, src, sizeof(*src)) == 0) && 1812 bcmp(&l2pcb->dst, dst, sizeof(*dst)) == 0) 1813 break; 1814 } 1815 1816 return (s); 1817} /* ng_btsocket_rfcomm_session_by_addr */ 1818 1819/***************************************************************************** 1820 ***************************************************************************** 1821 ** RFCOMM 1822 ***************************************************************************** 1823 *****************************************************************************/ 1824 1825/* 1826 * Process incoming RFCOMM frame. Caller must hold s->session_mtx. 1827 * XXX FIXME check frame length 1828 */ 1829 1830static int 1831ng_btsocket_rfcomm_receive_frame(ng_btsocket_rfcomm_session_p s, 1832 struct mbuf *m0) 1833{ 1834 struct rfcomm_frame_hdr *hdr = NULL; 1835 struct mbuf *m = NULL; 1836 u_int16_t length; 1837 u_int8_t dlci, type; 1838 int error = 0; 1839 1840 mtx_assert(&s->session_mtx, MA_OWNED); 1841 1842 /* Pullup as much as we can into first mbuf (for direct access) */ 1843 length = min(m0->m_pkthdr.len, MHLEN); 1844 if (m0->m_len < length) { 1845 if ((m0 = m_pullup(m0, length)) == NULL) { 1846 NG_BTSOCKET_RFCOMM_ALERT( 1847"%s: m_pullup(%d) failed\n", __func__, length); 1848 1849 return (ENOBUFS); 1850 } 1851 } 1852 1853 hdr = mtod(m0, struct rfcomm_frame_hdr *); 1854 dlci = RFCOMM_DLCI(hdr->address); 1855 type = RFCOMM_TYPE(hdr->control); 1856 1857 /* Test EA bit in length. If not set then we have 2 bytes of length */ 1858 if (!RFCOMM_EA(hdr->length)) { 1859 bcopy(&hdr->length, &length, sizeof(length)); 1860 length = le16toh(length) >> 1; 1861 m_adj(m0, sizeof(*hdr) + 1); 1862 } else { 1863 length = hdr->length >> 1; 1864 m_adj(m0, sizeof(*hdr)); 1865 } 1866 1867 NG_BTSOCKET_RFCOMM_INFO( 1868"%s: Got frame type=%#x, dlci=%d, length=%d, cr=%d, pf=%d, len=%d\n", 1869 __func__, type, dlci, length, RFCOMM_CR(hdr->address), 1870 RFCOMM_PF(hdr->control), m0->m_pkthdr.len); 1871 1872 /* 1873 * Get FCS (the last byte in the frame) 1874 * XXX this will not work if mbuf chain ends with empty mbuf. 1875 * XXX let's hope it never happens :) 1876 */ 1877 1878 for (m = m0; m->m_next != NULL; m = m->m_next) 1879 ; 1880 if (m->m_len <= 0) 1881 panic("%s: Empty mbuf at the end of the chain, len=%d\n", 1882 __func__, m->m_len); 1883 1884 /* 1885 * Check FCS. We only need to calculate FCS on first 2 or 3 bytes 1886 * and already m_pullup'ed mbuf chain, so it should be safe. 1887 */ 1888 1889 if (ng_btsocket_rfcomm_check_fcs((u_int8_t *) hdr, type, m->m_data[m->m_len - 1])) { 1890 NG_BTSOCKET_RFCOMM_ERR( 1891"%s: Invalid RFCOMM packet. Bad checksum\n", __func__); 1892 NG_FREE_M(m0); 1893 1894 return (EINVAL); 1895 } 1896 1897 m_adj(m0, -1); /* Trim FCS byte */ 1898 1899 /* 1900 * Process RFCOMM frame. 1901 * 1902 * From TS 07.10 spec 1903 * 1904 * "... In the case where a SABM or DISC command with the P bit set 1905 * to 0 is received then the received frame shall be discarded..." 1906 * 1907 * "... If a unsolicited DM response is received then the frame shall 1908 * be processed irrespective of the P/F setting... " 1909 * 1910 * "... The station may transmit response frames with the F bit set 1911 * to 0 at any opportunity on an asynchronous basis. However, in the 1912 * case where a UA response is received with the F bit set to 0 then 1913 * the received frame shall be discarded..." 1914 * 1915 * From Bluetooth spec 1916 * 1917 * "... When credit based flow control is being used, the meaning of 1918 * the P/F bit in the control field of the RFCOMM header is redefined 1919 * for UIH frames..." 1920 */ 1921 1922 switch (type) { 1923 case RFCOMM_FRAME_SABM: 1924 if (RFCOMM_PF(hdr->control)) 1925 error = ng_btsocket_rfcomm_receive_sabm(s, dlci); 1926 break; 1927 1928 case RFCOMM_FRAME_DISC: 1929 if (RFCOMM_PF(hdr->control)) 1930 error = ng_btsocket_rfcomm_receive_disc(s, dlci); 1931 break; 1932 1933 case RFCOMM_FRAME_UA: 1934 if (RFCOMM_PF(hdr->control)) 1935 error = ng_btsocket_rfcomm_receive_ua(s, dlci); 1936 break; 1937 1938 case RFCOMM_FRAME_DM: 1939 error = ng_btsocket_rfcomm_receive_dm(s, dlci); 1940 break; 1941 1942 case RFCOMM_FRAME_UIH: 1943 if (dlci == 0) 1944 error = ng_btsocket_rfcomm_receive_mcc(s, m0); 1945 else 1946 error = ng_btsocket_rfcomm_receive_uih(s, dlci, 1947 RFCOMM_PF(hdr->control), m0); 1948 1949 return (error); 1950 /* NOT REACHED */ 1951 1952 default: 1953 NG_BTSOCKET_RFCOMM_ERR( 1954"%s: Invalid RFCOMM packet. Unknown type=%#x\n", __func__, type); 1955 error = EINVAL; 1956 break; 1957 } 1958 1959 NG_FREE_M(m0); 1960 1961 return (error); 1962} /* ng_btsocket_rfcomm_receive_frame */ 1963 1964/* 1965 * Process RFCOMM SABM frame 1966 */ 1967 1968static int 1969ng_btsocket_rfcomm_receive_sabm(ng_btsocket_rfcomm_session_p s, int dlci) 1970{ 1971 ng_btsocket_rfcomm_pcb_p pcb = NULL; 1972 int error = 0; 1973 1974 mtx_assert(&s->session_mtx, MA_OWNED); 1975 1976 NG_BTSOCKET_RFCOMM_INFO( 1977"%s: Got SABM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 1978 __func__, s->state, s->flags, s->mtu, dlci); 1979 1980 /* DLCI == 0 means open multiplexor channel */ 1981 if (dlci == 0) { 1982 switch (s->state) { 1983 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 1984 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 1985 error = ng_btsocket_rfcomm_send_command(s, 1986 RFCOMM_FRAME_UA, dlci); 1987 if (error == 0) { 1988 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 1989 ng_btsocket_rfcomm_connect_cfm(s); 1990 } else { 1991 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1992 ng_btsocket_rfcomm_session_clean(s); 1993 } 1994 break; 1995 1996 default: 1997 NG_BTSOCKET_RFCOMM_WARN( 1998"%s: Got SABM for session in invalid state state=%d, flags=%#x\n", 1999 __func__, s->state, s->flags); 2000 error = EINVAL; 2001 break; 2002 } 2003 2004 return (error); 2005 } 2006 2007 /* Make sure multiplexor channel is open */ 2008 if (s->state != NG_BTSOCKET_RFCOMM_SESSION_OPEN) { 2009 NG_BTSOCKET_RFCOMM_ERR( 2010"%s: Got SABM for dlci=%d with mulitplexor channel closed, state=%d, " \ 2011"flags=%#x\n", __func__, dlci, s->state, s->flags); 2012 2013 return (EINVAL); 2014 } 2015 2016 /* 2017 * Check if we have this DLCI. This might happen when remote 2018 * peer uses PN command before actual open (SABM) happens. 2019 */ 2020 2021 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2022 if (pcb != NULL) { 2023 mtx_lock(&pcb->pcb_mtx); 2024 2025 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING) { 2026 NG_BTSOCKET_RFCOMM_ERR( 2027"%s: Got SABM for dlci=%d in invalid state=%d, flags=%#x\n", 2028 __func__, dlci, pcb->state, pcb->flags); 2029 mtx_unlock(&pcb->pcb_mtx); 2030 2031 return (ENOENT); 2032 } 2033 2034 ng_btsocket_rfcomm_untimeout(pcb); 2035 2036 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci); 2037 if (error == 0) 2038 error = ng_btsocket_rfcomm_send_msc(pcb); 2039 2040 if (error == 0) { 2041 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2042 soisconnected(pcb->so); 2043 } else 2044 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2045 2046 mtx_unlock(&pcb->pcb_mtx); 2047 2048 return (error); 2049 } 2050 2051 /* 2052 * We do not have requested DLCI, so it must be an incoming connection 2053 * with default parameters. Try to accept it. 2054 */ 2055 2056 pcb = ng_btsocket_rfcomm_connect_ind(s, RFCOMM_SRVCHANNEL(dlci)); 2057 if (pcb != NULL) { 2058 mtx_lock(&pcb->pcb_mtx); 2059 2060 pcb->dlci = dlci; 2061 2062 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci); 2063 if (error == 0) 2064 error = ng_btsocket_rfcomm_send_msc(pcb); 2065 2066 if (error == 0) { 2067 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2068 soisconnected(pcb->so); 2069 } else 2070 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2071 2072 mtx_unlock(&pcb->pcb_mtx); 2073 } else 2074 /* Nobody is listen()ing on the requested DLCI */ 2075 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2076 2077 return (error); 2078} /* ng_btsocket_rfcomm_receive_sabm */ 2079 2080/* 2081 * Process RFCOMM DISC frame 2082 */ 2083 2084static int 2085ng_btsocket_rfcomm_receive_disc(ng_btsocket_rfcomm_session_p s, int dlci) 2086{ 2087 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2088 int error = 0; 2089 2090 mtx_assert(&s->session_mtx, MA_OWNED); 2091 2092 NG_BTSOCKET_RFCOMM_INFO( 2093"%s: Got DISC, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2094 __func__, s->state, s->flags, s->mtu, dlci); 2095 2096 /* DLCI == 0 means close multiplexor channel */ 2097 if (dlci == 0) { 2098 /* XXX FIXME assume that remote side will close the socket */ 2099 error = ng_btsocket_rfcomm_send_command(s, RFCOMM_FRAME_UA, 0); 2100 if (error == 0) { 2101 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING) 2102 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2103 else 2104 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 2105 } else 2106 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2107 2108 ng_btsocket_rfcomm_session_clean(s); 2109 } else { 2110 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2111 if (pcb != NULL) { 2112 int err; 2113 2114 mtx_lock(&pcb->pcb_mtx); 2115 2116 NG_BTSOCKET_RFCOMM_INFO( 2117"%s: Got DISC for dlci=%d, state=%d, flags=%#x\n", 2118 __func__, dlci, pcb->state, pcb->flags); 2119 2120 error = ng_btsocket_rfcomm_send_command(s, 2121 RFCOMM_FRAME_UA, dlci); 2122 2123 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2124 err = 0; 2125 else 2126 err = ECONNREFUSED; 2127 2128 ng_btsocket_rfcomm_pcb_kill(pcb, err); 2129 2130 mtx_unlock(&pcb->pcb_mtx); 2131 } else { 2132 NG_BTSOCKET_RFCOMM_WARN( 2133"%s: Got DISC for non-existing dlci=%d\n", __func__, dlci); 2134 2135 error = ng_btsocket_rfcomm_send_command(s, 2136 RFCOMM_FRAME_DM, dlci); 2137 } 2138 } 2139 2140 return (error); 2141} /* ng_btsocket_rfcomm_receive_disc */ 2142 2143/* 2144 * Process RFCOMM UA frame 2145 */ 2146 2147static int 2148ng_btsocket_rfcomm_receive_ua(ng_btsocket_rfcomm_session_p s, int dlci) 2149{ 2150 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2151 int error = 0; 2152 2153 mtx_assert(&s->session_mtx, MA_OWNED); 2154 2155 NG_BTSOCKET_RFCOMM_INFO( 2156"%s: Got UA, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2157 __func__, s->state, s->flags, s->mtu, dlci); 2158 2159 /* dlci == 0 means multiplexor channel */ 2160 if (dlci == 0) { 2161 switch (s->state) { 2162 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 2163 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 2164 ng_btsocket_rfcomm_connect_cfm(s); 2165 break; 2166 2167 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 2168 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2169 ng_btsocket_rfcomm_session_clean(s); 2170 break; 2171 2172 default: 2173 NG_BTSOCKET_RFCOMM_WARN( 2174"%s: Got UA for session in invalid state=%d(%d), flags=%#x, mtu=%d\n", 2175 __func__, s->state, INITIATOR(s), s->flags, 2176 s->mtu); 2177 error = ENOENT; 2178 break; 2179 } 2180 2181 return (error); 2182 } 2183 2184 /* Check if we have this DLCI */ 2185 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2186 if (pcb != NULL) { 2187 mtx_lock(&pcb->pcb_mtx); 2188 2189 NG_BTSOCKET_RFCOMM_INFO( 2190"%s: Got UA for dlci=%d, state=%d, flags=%#x\n", 2191 __func__, dlci, pcb->state, pcb->flags); 2192 2193 switch (pcb->state) { 2194 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 2195 ng_btsocket_rfcomm_untimeout(pcb); 2196 2197 error = ng_btsocket_rfcomm_send_msc(pcb); 2198 if (error == 0) { 2199 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2200 soisconnected(pcb->so); 2201 } 2202 break; 2203 2204 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 2205 ng_btsocket_rfcomm_pcb_kill(pcb, 0); 2206 break; 2207 2208 default: 2209 NG_BTSOCKET_RFCOMM_WARN( 2210"%s: Got UA for dlci=%d in invalid state=%d, flags=%#x\n", 2211 __func__, dlci, pcb->state, pcb->flags); 2212 error = ENOENT; 2213 break; 2214 } 2215 2216 mtx_unlock(&pcb->pcb_mtx); 2217 } else { 2218 NG_BTSOCKET_RFCOMM_WARN( 2219"%s: Got UA for non-existing dlci=%d\n", __func__, dlci); 2220 2221 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2222 } 2223 2224 return (error); 2225} /* ng_btsocket_rfcomm_receive_ua */ 2226 2227/* 2228 * Process RFCOMM DM frame 2229 */ 2230 2231static int 2232ng_btsocket_rfcomm_receive_dm(ng_btsocket_rfcomm_session_p s, int dlci) 2233{ 2234 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2235 int error; 2236 2237 mtx_assert(&s->session_mtx, MA_OWNED); 2238 2239 NG_BTSOCKET_RFCOMM_INFO( 2240"%s: Got DM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2241 __func__, s->state, s->flags, s->mtu, dlci); 2242 2243 /* DLCI == 0 means multiplexor channel */ 2244 if (dlci == 0) { 2245 /* Disconnect all dlc's on the session */ 2246 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2247 ng_btsocket_rfcomm_session_clean(s); 2248 } else { 2249 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2250 if (pcb != NULL) { 2251 mtx_lock(&pcb->pcb_mtx); 2252 2253 NG_BTSOCKET_RFCOMM_INFO( 2254"%s: Got DM for dlci=%d, state=%d, flags=%#x\n", 2255 __func__, dlci, pcb->state, pcb->flags); 2256 2257 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2258 error = ECONNRESET; 2259 else 2260 error = ECONNREFUSED; 2261 2262 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2263 2264 mtx_unlock(&pcb->pcb_mtx); 2265 } else 2266 NG_BTSOCKET_RFCOMM_WARN( 2267"%s: Got DM for non-existing dlci=%d\n", __func__, dlci); 2268 } 2269 2270 return (0); 2271} /* ng_btsocket_rfcomm_receive_dm */ 2272 2273/* 2274 * Process RFCOMM UIH frame (data) 2275 */ 2276 2277static int 2278ng_btsocket_rfcomm_receive_uih(ng_btsocket_rfcomm_session_p s, int dlci, 2279 int pf, struct mbuf *m0) 2280{ 2281 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2282 int error = 0; 2283 2284 mtx_assert(&s->session_mtx, MA_OWNED); 2285 2286 NG_BTSOCKET_RFCOMM_INFO( 2287"%s: Got UIH, session state=%d, flags=%#x, mtu=%d, dlci=%d, pf=%d, len=%d\n", 2288 __func__, s->state, s->flags, s->mtu, dlci, pf, 2289 m0->m_pkthdr.len); 2290 2291 /* XXX should we do it here? Check for session flow control */ 2292 if (s->flags & NG_BTSOCKET_RFCOMM_SESSION_LFC) { 2293 NG_BTSOCKET_RFCOMM_WARN( 2294"%s: Got UIH with session flow control asserted, state=%d, flags=%#x\n", 2295 __func__, s->state, s->flags); 2296 goto drop; 2297 } 2298 2299 /* Check if we have this dlci */ 2300 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2301 if (pcb == NULL) { 2302 NG_BTSOCKET_RFCOMM_WARN( 2303"%s: Got UIH for non-existing dlci=%d\n", __func__, dlci); 2304 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2305 goto drop; 2306 } 2307 2308 mtx_lock(&pcb->pcb_mtx); 2309 2310 /* Check dlci state */ 2311 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2312 NG_BTSOCKET_RFCOMM_WARN( 2313"%s: Got UIH for dlci=%d in invalid state=%d, flags=%#x\n", 2314 __func__, dlci, pcb->state, pcb->flags); 2315 error = EINVAL; 2316 goto drop1; 2317 } 2318 2319 /* Check dlci flow control */ 2320 if (((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pcb->rx_cred <= 0) || 2321 (pcb->lmodem & RFCOMM_MODEM_FC)) { 2322 NG_BTSOCKET_RFCOMM_ERR( 2323"%s: Got UIH for dlci=%d with asserted flow control, state=%d, " \ 2324"flags=%#x, rx_cred=%d, lmodem=%#x\n", 2325 __func__, dlci, pcb->state, pcb->flags, 2326 pcb->rx_cred, pcb->lmodem); 2327 goto drop1; 2328 } 2329 2330 /* Did we get any credits? */ 2331 if ((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pf) { 2332 NG_BTSOCKET_RFCOMM_INFO( 2333"%s: Got %d more credits for dlci=%d, state=%d, flags=%#x, " \ 2334"rx_cred=%d, tx_cred=%d\n", 2335 __func__, *mtod(m0, u_int8_t *), dlci, pcb->state, 2336 pcb->flags, pcb->rx_cred, pcb->tx_cred); 2337 2338 pcb->tx_cred += *mtod(m0, u_int8_t *); 2339 m_adj(m0, 1); 2340 2341 /* Send more from the DLC. XXX check for errors? */ 2342 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2343 } 2344 2345 /* OK the of the rest of the mbuf is the data */ 2346 if (m0->m_pkthdr.len > 0) { 2347 /* If we are using credit flow control decrease rx_cred here */ 2348 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2349 /* Give remote peer more credits (if needed) */ 2350 if (-- pcb->rx_cred <= RFCOMM_MAX_CREDITS / 2) 2351 ng_btsocket_rfcomm_send_credits(pcb); 2352 else 2353 NG_BTSOCKET_RFCOMM_INFO( 2354"%s: Remote side still has credits, dlci=%d, state=%d, flags=%#x, " \ 2355"rx_cred=%d, tx_cred=%d\n", __func__, dlci, pcb->state, pcb->flags, 2356 pcb->rx_cred, pcb->tx_cred); 2357 } 2358 2359 /* Check packet against mtu on dlci */ 2360 if (m0->m_pkthdr.len > pcb->mtu) { 2361 NG_BTSOCKET_RFCOMM_ERR( 2362"%s: Got oversized UIH for dlci=%d, state=%d, flags=%#x, mtu=%d, len=%d\n", 2363 __func__, dlci, pcb->state, pcb->flags, 2364 pcb->mtu, m0->m_pkthdr.len); 2365 2366 error = EMSGSIZE; 2367 } else if (m0->m_pkthdr.len > sbspace(&pcb->so->so_rcv)) { 2368 2369 /* 2370 * This is really bad. Receive queue on socket does 2371 * not have enough space for the packet. We do not 2372 * have any other choice but drop the packet. 2373 */ 2374 2375 NG_BTSOCKET_RFCOMM_ERR( 2376"%s: Not enough space in socket receive queue. Dropping UIH for dlci=%d, " \ 2377"state=%d, flags=%#x, len=%d, space=%ld\n", 2378 __func__, dlci, pcb->state, pcb->flags, 2379 m0->m_pkthdr.len, sbspace(&pcb->so->so_rcv)); 2380 2381 error = ENOBUFS; 2382 } else { 2383 /* Append packet to the socket receive queue */ 2384 sbappend(&pcb->so->so_rcv, m0); 2385 m0 = NULL; 2386 2387 sorwakeup(pcb->so); 2388 } 2389 } 2390drop1: 2391 mtx_unlock(&pcb->pcb_mtx); 2392drop: 2393 NG_FREE_M(m0); /* checks for != NULL */ 2394 2395 return (error); 2396} /* ng_btsocket_rfcomm_receive_uih */ 2397 2398/* 2399 * Process RFCOMM MCC command (Multiplexor) 2400 * 2401 * From TS 07.10 spec 2402 * 2403 * "5.4.3.1 Information Data 2404 * 2405 * ...The frames (UIH) sent by the initiating station have the C/R bit set 2406 * to 1 and those sent by the responding station have the C/R bit set to 0..." 2407 * 2408 * "5.4.6.2 Operating procedures 2409 * 2410 * Messages always exist in pairs; a command message and a corresponding 2411 * response message. If the C/R bit is set to 1 the message is a command, 2412 * if it is set to 0 the message is a response... 2413 * 2414 * ... 2415 * 2416 * NOTE: Notice that when UIH frames are used to convey information on DLCI 0 2417 * there are at least two different fields that contain a C/R bit, and the 2418 * bits are set of different form. The C/R bit in the Type field shall be set 2419 * as it is stated above, while the C/R bit in the Address field (see subclause 2420 * 5.2.1.2) shall be set as it is described in subclause 5.4.3.1." 2421 */ 2422 2423static int 2424ng_btsocket_rfcomm_receive_mcc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2425{ 2426 struct rfcomm_mcc_hdr *hdr = NULL; 2427 u_int8_t cr, type, length; 2428 2429 mtx_assert(&s->session_mtx, MA_OWNED); 2430 2431 /* 2432 * We can access data directly in the first mbuf, because we have 2433 * m_pullup()'ed mbuf chain in ng_btsocket_rfcomm_receive_frame(). 2434 * All MCC commands should fit into single mbuf (except probably TEST). 2435 */ 2436 2437 hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2438 cr = RFCOMM_CR(hdr->type); 2439 type = RFCOMM_MCC_TYPE(hdr->type); 2440 length = RFCOMM_MCC_LENGTH(hdr->length); 2441 2442 /* Check MCC frame length */ 2443 if (sizeof(*hdr) + length != m0->m_pkthdr.len) { 2444 NG_BTSOCKET_RFCOMM_ERR( 2445"%s: Invalid MCC frame length=%d, len=%d\n", 2446 __func__, length, m0->m_pkthdr.len); 2447 NG_FREE_M(m0); 2448 2449 return (EMSGSIZE); 2450 } 2451 2452 switch (type) { 2453 case RFCOMM_MCC_TEST: 2454 return (ng_btsocket_rfcomm_receive_test(s, m0)); 2455 /* NOT REACHED */ 2456 2457 case RFCOMM_MCC_FCON: 2458 case RFCOMM_MCC_FCOFF: 2459 return (ng_btsocket_rfcomm_receive_fc(s, m0)); 2460 /* NOT REACHED */ 2461 2462 case RFCOMM_MCC_MSC: 2463 return (ng_btsocket_rfcomm_receive_msc(s, m0)); 2464 /* NOT REACHED */ 2465 2466 case RFCOMM_MCC_RPN: 2467 return (ng_btsocket_rfcomm_receive_rpn(s, m0)); 2468 /* NOT REACHED */ 2469 2470 case RFCOMM_MCC_RLS: 2471 return (ng_btsocket_rfcomm_receive_rls(s, m0)); 2472 /* NOT REACHED */ 2473 2474 case RFCOMM_MCC_PN: 2475 return (ng_btsocket_rfcomm_receive_pn(s, m0)); 2476 /* NOT REACHED */ 2477 2478 case RFCOMM_MCC_NSC: 2479 NG_BTSOCKET_RFCOMM_ERR( 2480"%s: Got MCC NSC, type=%#x, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2481"mtu=%d, len=%d\n", __func__, RFCOMM_MCC_TYPE(*((u_int8_t *)(hdr + 1))), cr, 2482 length, s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2483 NG_FREE_M(m0); 2484 break; 2485 2486 default: 2487 NG_BTSOCKET_RFCOMM_ERR( 2488"%s: Got unknown MCC, type=%#x, cr=%d, length=%d, session state=%d, " \ 2489"flags=%#x, mtu=%d, len=%d\n", 2490 __func__, type, cr, length, s->state, s->flags, 2491 s->mtu, m0->m_pkthdr.len); 2492 2493 /* Reuse mbuf to send NSC */ 2494 hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2495 m0->m_pkthdr.len = m0->m_len = sizeof(*hdr); 2496 2497 /* Create MCC NSC header */ 2498 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_NSC); 2499 hdr->length = RFCOMM_MKLEN8(1); 2500 2501 /* Put back MCC command type we did not like */ 2502 m0->m_data[m0->m_len] = RFCOMM_MKMCC_TYPE(cr, type); 2503 m0->m_pkthdr.len ++; 2504 m0->m_len ++; 2505 2506 /* Send UIH frame */ 2507 return (ng_btsocket_rfcomm_send_uih(s, 2508 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0)); 2509 /* NOT REACHED */ 2510 } 2511 2512 return (0); 2513} /* ng_btsocket_rfcomm_receive_mcc */ 2514 2515/* 2516 * Receive RFCOMM TEST MCC command 2517 */ 2518 2519static int 2520ng_btsocket_rfcomm_receive_test(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2521{ 2522 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2523 int error = 0; 2524 2525 mtx_assert(&s->session_mtx, MA_OWNED); 2526 2527 NG_BTSOCKET_RFCOMM_INFO( 2528"%s: Got MCC TEST, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \ 2529"len=%d\n", __func__, RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2530 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2531 2532 if (RFCOMM_CR(hdr->type)) { 2533 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_TEST); 2534 error = ng_btsocket_rfcomm_send_uih(s, 2535 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2536 } else 2537 NG_FREE_M(m0); /* XXX ignore response */ 2538 2539 return (error); 2540} /* ng_btsocket_rfcomm_receive_test */ 2541 2542/* 2543 * Receive RFCOMM FCON/FCOFF MCC command 2544 */ 2545 2546static int 2547ng_btsocket_rfcomm_receive_fc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2548{ 2549 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2550 u_int8_t type = RFCOMM_MCC_TYPE(hdr->type); 2551 int error = 0; 2552 2553 mtx_assert(&s->session_mtx, MA_OWNED); 2554 2555 /* 2556 * Turn ON/OFF aggregate flow on the entire session. When remote peer 2557 * asserted flow control no transmission shall occur except on dlci 0 2558 * (control channel). 2559 */ 2560 2561 NG_BTSOCKET_RFCOMM_INFO( 2562"%s: Got MCC FC%s, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \ 2563"len=%d\n", __func__, (type == RFCOMM_MCC_FCON)? "ON" : "OFF", 2564 RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2565 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2566 2567 if (RFCOMM_CR(hdr->type)) { 2568 if (type == RFCOMM_MCC_FCON) 2569 s->flags &= ~NG_BTSOCKET_RFCOMM_SESSION_RFC; 2570 else 2571 s->flags |= NG_BTSOCKET_RFCOMM_SESSION_RFC; 2572 2573 hdr->type = RFCOMM_MKMCC_TYPE(0, type); 2574 error = ng_btsocket_rfcomm_send_uih(s, 2575 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2576 } else 2577 NG_FREE_M(m0); /* XXX ignore response */ 2578 2579 return (error); 2580} /* ng_btsocket_rfcomm_receive_fc */ 2581 2582/* 2583 * Receive RFCOMM MSC MCC command 2584 */ 2585 2586static int 2587ng_btsocket_rfcomm_receive_msc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2588{ 2589 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr*); 2590 struct rfcomm_mcc_msc *msc = (struct rfcomm_mcc_msc *)(hdr+1); 2591 ng_btsocket_rfcomm_pcb_t *pcb = NULL; 2592 int error = 0; 2593 2594 mtx_assert(&s->session_mtx, MA_OWNED); 2595 2596 NG_BTSOCKET_RFCOMM_INFO( 2597"%s: Got MCC MSC, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2598"mtu=%d, len=%d\n", 2599 __func__, RFCOMM_DLCI(msc->address), RFCOMM_CR(hdr->type), 2600 RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags, 2601 s->mtu, m0->m_pkthdr.len); 2602 2603 if (RFCOMM_CR(hdr->type)) { 2604 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, RFCOMM_DLCI(msc->address)); 2605 if (pcb == NULL) { 2606 NG_BTSOCKET_RFCOMM_WARN( 2607"%s: Got MSC command for non-existing dlci=%d\n", 2608 __func__, RFCOMM_DLCI(msc->address)); 2609 NG_FREE_M(m0); 2610 2611 return (ENOENT); 2612 } 2613 2614 mtx_lock(&pcb->pcb_mtx); 2615 2616 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING && 2617 pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2618 NG_BTSOCKET_RFCOMM_WARN( 2619"%s: Got MSC on dlci=%d in invalid state=%d\n", 2620 __func__, RFCOMM_DLCI(msc->address), 2621 pcb->state); 2622 2623 mtx_unlock(&pcb->pcb_mtx); 2624 NG_FREE_M(m0); 2625 2626 return (EINVAL); 2627 } 2628 2629 pcb->rmodem = msc->modem; /* Update remote port signals */ 2630 2631 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_MSC); 2632 error = ng_btsocket_rfcomm_send_uih(s, 2633 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2634 2635#if 0 /* YYY */ 2636 /* Send more data from DLC. XXX check for errors? */ 2637 if (!(pcb->rmodem & RFCOMM_MODEM_FC) && 2638 !(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)) 2639 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2640#endif /* YYY */ 2641 2642 mtx_unlock(&pcb->pcb_mtx); 2643 } else 2644 NG_FREE_M(m0); /* XXX ignore response */ 2645 2646 return (error); 2647} /* ng_btsocket_rfcomm_receive_msc */ 2648 2649/* 2650 * Receive RFCOMM RPN MCC command 2651 * XXX FIXME do we need htole16/le16toh for RPN param_mask? 2652 */ 2653 2654static int 2655ng_btsocket_rfcomm_receive_rpn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2656{ 2657 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2658 struct rfcomm_mcc_rpn *rpn = (struct rfcomm_mcc_rpn *)(hdr + 1); 2659 int error = 0; 2660 u_int16_t param_mask; 2661 u_int8_t bit_rate, data_bits, stop_bits, parity, 2662 flow_control, xon_char, xoff_char; 2663 2664 mtx_assert(&s->session_mtx, MA_OWNED); 2665 2666 NG_BTSOCKET_RFCOMM_INFO( 2667"%s: Got MCC RPN, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2668"mtu=%d, len=%d\n", 2669 __func__, RFCOMM_DLCI(rpn->dlci), RFCOMM_CR(hdr->type), 2670 RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags, 2671 s->mtu, m0->m_pkthdr.len); 2672 2673 if (RFCOMM_CR(hdr->type)) { 2674 param_mask = RFCOMM_RPN_PM_ALL; 2675 2676 if (RFCOMM_MCC_LENGTH(hdr->length) == 1) { 2677 /* Request - return default setting */ 2678 bit_rate = RFCOMM_RPN_BR_115200; 2679 data_bits = RFCOMM_RPN_DATA_8; 2680 stop_bits = RFCOMM_RPN_STOP_1; 2681 parity = RFCOMM_RPN_PARITY_NONE; 2682 flow_control = RFCOMM_RPN_FLOW_NONE; 2683 xon_char = RFCOMM_RPN_XON_CHAR; 2684 xoff_char = RFCOMM_RPN_XOFF_CHAR; 2685 } else { 2686 /* 2687 * Ignore/accept bit_rate, 8 bits, 1 stop bit, no 2688 * parity, no flow control lines, default XON/XOFF 2689 * chars. 2690 */ 2691 2692 bit_rate = rpn->bit_rate; 2693 rpn->param_mask = le16toh(rpn->param_mask); /* XXX */ 2694 2695 data_bits = RFCOMM_RPN_DATA_BITS(rpn->line_settings); 2696 if (rpn->param_mask & RFCOMM_RPN_PM_DATA && 2697 data_bits != RFCOMM_RPN_DATA_8) { 2698 data_bits = RFCOMM_RPN_DATA_8; 2699 param_mask ^= RFCOMM_RPN_PM_DATA; 2700 } 2701 2702 stop_bits = RFCOMM_RPN_STOP_BITS(rpn->line_settings); 2703 if (rpn->param_mask & RFCOMM_RPN_PM_STOP && 2704 stop_bits != RFCOMM_RPN_STOP_1) { 2705 stop_bits = RFCOMM_RPN_STOP_1; 2706 param_mask ^= RFCOMM_RPN_PM_STOP; 2707 } 2708 2709 parity = RFCOMM_RPN_PARITY(rpn->line_settings); 2710 if (rpn->param_mask & RFCOMM_RPN_PM_PARITY && 2711 parity != RFCOMM_RPN_PARITY_NONE) { 2712 parity = RFCOMM_RPN_PARITY_NONE; 2713 param_mask ^= RFCOMM_RPN_PM_PARITY; 2714 } 2715 2716 flow_control = rpn->flow_control; 2717 if (rpn->param_mask & RFCOMM_RPN_PM_FLOW && 2718 flow_control != RFCOMM_RPN_FLOW_NONE) { 2719 flow_control = RFCOMM_RPN_FLOW_NONE; 2720 param_mask ^= RFCOMM_RPN_PM_FLOW; 2721 } 2722 2723 xon_char = rpn->xon_char; 2724 if (rpn->param_mask & RFCOMM_RPN_PM_XON && 2725 xon_char != RFCOMM_RPN_XON_CHAR) { 2726 xon_char = RFCOMM_RPN_XON_CHAR; 2727 param_mask ^= RFCOMM_RPN_PM_XON; 2728 } 2729 2730 xoff_char = rpn->xoff_char; 2731 if (rpn->param_mask & RFCOMM_RPN_PM_XOFF && 2732 xoff_char != RFCOMM_RPN_XOFF_CHAR) { 2733 xoff_char = RFCOMM_RPN_XOFF_CHAR; 2734 param_mask ^= RFCOMM_RPN_PM_XOFF; 2735 } 2736 } 2737 2738 rpn->bit_rate = bit_rate; 2739 rpn->line_settings = RFCOMM_MKRPN_LINE_SETTINGS(data_bits, 2740 stop_bits, parity); 2741 rpn->flow_control = flow_control; 2742 rpn->xon_char = xon_char; 2743 rpn->xoff_char = xoff_char; 2744 rpn->param_mask = htole16(param_mask); /* XXX */ 2745 2746 m0->m_pkthdr.len = m0->m_len = sizeof(*hdr) + sizeof(*rpn); 2747 2748 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RPN); 2749 error = ng_btsocket_rfcomm_send_uih(s, 2750 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2751 } else 2752 NG_FREE_M(m0); /* XXX ignore response */ 2753 2754 return (error); 2755} /* ng_btsocket_rfcomm_receive_rpn */ 2756 2757/* 2758 * Receive RFCOMM RLS MCC command 2759 */ 2760 2761static int 2762ng_btsocket_rfcomm_receive_rls(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2763{ 2764 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2765 struct rfcomm_mcc_rls *rls = (struct rfcomm_mcc_rls *)(hdr + 1); 2766 int error = 0; 2767 2768 mtx_assert(&s->session_mtx, MA_OWNED); 2769 2770 /* 2771 * XXX FIXME Do we have to do anything else here? Remote peer tries to 2772 * tell us something about DLCI. Just report what we have received and 2773 * return back received values as required by TS 07.10 spec. 2774 */ 2775 2776 NG_BTSOCKET_RFCOMM_INFO( 2777"%s: Got MCC RLS, dlci=%d, status=%#x, cr=%d, length=%d, session state=%d, " \ 2778"flags=%#x, mtu=%d, len=%d\n", 2779 __func__, RFCOMM_DLCI(rls->address), rls->status, 2780 RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2781 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2782 2783 if (RFCOMM_CR(hdr->type)) { 2784 if (rls->status & 0x1) 2785 NG_BTSOCKET_RFCOMM_ERR( 2786"%s: Got RLS dlci=%d, error=%#x\n", __func__, RFCOMM_DLCI(rls->address), 2787 rls->status >> 1); 2788 2789 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RLS); 2790 error = ng_btsocket_rfcomm_send_uih(s, 2791 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2792 } else 2793 NG_FREE_M(m0); /* XXX ignore responses */ 2794 2795 return (error); 2796} /* ng_btsocket_rfcomm_receive_rls */ 2797 2798/* 2799 * Receive RFCOMM PN MCC command 2800 */ 2801 2802static int 2803ng_btsocket_rfcomm_receive_pn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2804{ 2805 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr*); 2806 struct rfcomm_mcc_pn *pn = (struct rfcomm_mcc_pn *)(hdr+1); 2807 ng_btsocket_rfcomm_pcb_t *pcb = NULL; 2808 int error = 0; 2809 2810 mtx_assert(&s->session_mtx, MA_OWNED); 2811 2812 NG_BTSOCKET_RFCOMM_INFO( 2813"%s: Got MCC PN, dlci=%d, cr=%d, length=%d, flow_control=%#x, priority=%d, " \ 2814"ack_timer=%d, mtu=%d, max_retrans=%d, credits=%d, session state=%d, " \ 2815"flags=%#x, session mtu=%d, len=%d\n", 2816 __func__, pn->dlci, RFCOMM_CR(hdr->type), 2817 RFCOMM_MCC_LENGTH(hdr->length), pn->flow_control, pn->priority, 2818 pn->ack_timer, le16toh(pn->mtu), pn->max_retrans, pn->credits, 2819 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2820 2821 if (pn->dlci == 0) { 2822 NG_BTSOCKET_RFCOMM_ERR("%s: Zero dlci in MCC PN\n", __func__); 2823 NG_FREE_M(m0); 2824 2825 return (EINVAL); 2826 } 2827 2828 /* Check if we have this dlci */ 2829 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, pn->dlci); 2830 if (pcb != NULL) { 2831 mtx_lock(&pcb->pcb_mtx); 2832 2833 if (RFCOMM_CR(hdr->type)) { 2834 /* PN Request */ 2835 ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control, 2836 pn->credits, pn->mtu); 2837 2838 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2839 pn->flow_control = 0xe0; 2840 pn->credits = RFCOMM_DEFAULT_CREDITS; 2841 } else { 2842 pn->flow_control = 0; 2843 pn->credits = 0; 2844 } 2845 2846 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN); 2847 error = ng_btsocket_rfcomm_send_uih(s, 2848 RFCOMM_MKADDRESS(INITIATOR(s), 0), 2849 0, 0, m0); 2850 } else { 2851 /* PN Response - proceed with SABM. Timeout still set */ 2852 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONFIGURING) { 2853 ng_btsocket_rfcomm_set_pn(pcb, 0, 2854 pn->flow_control, pn->credits, pn->mtu); 2855 2856 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING; 2857 error = ng_btsocket_rfcomm_send_command(s, 2858 RFCOMM_FRAME_SABM, pn->dlci); 2859 } else 2860 NG_BTSOCKET_RFCOMM_WARN( 2861"%s: Got PN response for dlci=%d in invalid state=%d\n", 2862 __func__, pn->dlci, pcb->state); 2863 2864 NG_FREE_M(m0); 2865 } 2866 2867 mtx_unlock(&pcb->pcb_mtx); 2868 } else if (RFCOMM_CR(hdr->type)) { 2869 /* PN request to non-existing dlci - incomming connection */ 2870 pcb = ng_btsocket_rfcomm_connect_ind(s, 2871 RFCOMM_SRVCHANNEL(pn->dlci)); 2872 if (pcb != NULL) { 2873 mtx_lock(&pcb->pcb_mtx); 2874 2875 pcb->dlci = pn->dlci; 2876 2877 ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control, 2878 pn->credits, pn->mtu); 2879 2880 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2881 pn->flow_control = 0xe0; 2882 pn->credits = RFCOMM_DEFAULT_CREDITS; 2883 } else { 2884 pn->flow_control = 0; 2885 pn->credits = 0; 2886 } 2887 2888 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN); 2889 error = ng_btsocket_rfcomm_send_uih(s, 2890 RFCOMM_MKADDRESS(INITIATOR(s), 0), 2891 0, 0, m0); 2892 2893 if (error == 0) { 2894 ng_btsocket_rfcomm_timeout(pcb); 2895 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING; 2896 soisconnecting(pcb->so); 2897 } else 2898 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2899 2900 mtx_unlock(&pcb->pcb_mtx); 2901 } else { 2902 /* Nobody is listen()ing on this channel */ 2903 error = ng_btsocket_rfcomm_send_command(s, 2904 RFCOMM_FRAME_DM, pn->dlci); 2905 NG_FREE_M(m0); 2906 } 2907 } else 2908 NG_FREE_M(m0); /* XXX ignore response to non-existing dlci */ 2909 2910 return (error); 2911} /* ng_btsocket_rfcomm_receive_pn */ 2912 2913/* 2914 * Set PN parameters for dlci. Caller must hold pcb->pcb_mtx. 2915 * 2916 * From Bluetooth spec. 2917 * 2918 * "... The CL1 - CL4 field is completely redefined. (In TS07.10 this defines 2919 * the convergence layer to use, which is not applicable to RFCOMM. In RFCOMM, 2920 * in Bluetooth versions up to 1.0B, this field was forced to 0). 2921 * 2922 * In the PN request sent prior to a DLC establishment, this field must contain 2923 * the value 15 (0xF), indicating support of credit based flow control in the 2924 * sender. See Table 5.3 below. If the PN response contains any other value 2925 * than 14 (0xE) in this field, it is inferred that the peer RFCOMM entity is 2926 * not supporting the credit based flow control feature. (This is only possible 2927 * if the peer RFCOMM implementation is only conforming to Bluetooth version 2928 * 1.0B.) If a PN request is sent on an already open DLC, then this field must 2929 * contain the value zero; it is not possible to set initial credits more 2930 * than once per DLC activation. A responding implementation must set this 2931 * field in the PN response to 14 (0xE), if (and only if) the value in the PN 2932 * request was 15..." 2933 */ 2934 2935static void 2936ng_btsocket_rfcomm_set_pn(ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr, 2937 u_int8_t flow_control, u_int8_t credits, u_int16_t mtu) 2938{ 2939 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 2940 2941 pcb->mtu = le16toh(mtu); 2942 2943 if (cr) { 2944 if (flow_control == 0xf0) { 2945 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC; 2946 pcb->tx_cred = credits; 2947 } else { 2948 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC; 2949 pcb->tx_cred = 0; 2950 } 2951 } else { 2952 if (flow_control == 0xe0) { 2953 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC; 2954 pcb->tx_cred = credits; 2955 } else { 2956 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC; 2957 pcb->tx_cred = 0; 2958 } 2959 } 2960 2961 NG_BTSOCKET_RFCOMM_INFO( 2962"%s: cr=%d, dlci=%d, state=%d, flags=%#x, mtu=%d, rx_cred=%d, tx_cred=%d\n", 2963 __func__, cr, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 2964 pcb->rx_cred, pcb->tx_cred); 2965} /* ng_btsocket_rfcomm_set_pn */ 2966 2967/* 2968 * Send RFCOMM SABM/DISC/UA/DM frames. Caller must hold s->session_mtx 2969 */ 2970 2971static int 2972ng_btsocket_rfcomm_send_command(ng_btsocket_rfcomm_session_p s, 2973 u_int8_t type, u_int8_t dlci) 2974{ 2975 struct rfcomm_cmd_hdr *hdr = NULL; 2976 struct mbuf *m = NULL; 2977 int cr; 2978 2979 mtx_assert(&s->session_mtx, MA_OWNED); 2980 2981 NG_BTSOCKET_RFCOMM_INFO( 2982"%s: Sending command type %#x, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2983 __func__, type, s->state, s->flags, s->mtu, dlci); 2984 2985 switch (type) { 2986 case RFCOMM_FRAME_SABM: 2987 case RFCOMM_FRAME_DISC: 2988 cr = INITIATOR(s); 2989 break; 2990 2991 case RFCOMM_FRAME_UA: 2992 case RFCOMM_FRAME_DM: 2993 cr = !INITIATOR(s); 2994 break; 2995 2996 default: 2997 panic("%s: Invalid frame type=%#x\n", __func__, type); 2998 return (EINVAL); 2999 /* NOT REACHED */ 3000 } 3001 3002 MGETHDR(m, M_DONTWAIT, MT_DATA); 3003 if (m == NULL) 3004 return (ENOBUFS); 3005 3006 m->m_pkthdr.len = m->m_len = sizeof(*hdr); 3007 3008 hdr = mtod(m, struct rfcomm_cmd_hdr *); 3009 hdr->address = RFCOMM_MKADDRESS(cr, dlci); 3010 hdr->control = RFCOMM_MKCONTROL(type, 1); 3011 hdr->length = RFCOMM_MKLEN8(0); 3012 hdr->fcs = ng_btsocket_rfcomm_fcs3((u_int8_t *) hdr); 3013 3014 NG_BT_MBUFQ_ENQUEUE(&s->outq, m); 3015 3016 return (0); 3017} /* ng_btsocket_rfcomm_send_command */ 3018 3019/* 3020 * Send RFCOMM UIH frame. Caller must hold s->session_mtx 3021 */ 3022 3023static int 3024ng_btsocket_rfcomm_send_uih(ng_btsocket_rfcomm_session_p s, u_int8_t address, 3025 u_int8_t pf, u_int8_t credits, struct mbuf *data) 3026{ 3027 struct rfcomm_frame_hdr *hdr = NULL; 3028 struct mbuf *m = NULL, *mcrc = NULL; 3029 u_int16_t length; 3030 3031 mtx_assert(&s->session_mtx, MA_OWNED); 3032 3033 MGETHDR(m, M_DONTWAIT, MT_DATA); 3034 if (m == NULL) { 3035 NG_FREE_M(data); 3036 return (ENOBUFS); 3037 } 3038 m->m_pkthdr.len = m->m_len = sizeof(*hdr); 3039 3040 MGET(mcrc, M_DONTWAIT, MT_DATA); 3041 if (mcrc == NULL) { 3042 NG_FREE_M(data); 3043 return (ENOBUFS); 3044 } 3045 mcrc->m_len = 1; 3046 3047 /* Fill UIH frame header */ 3048 hdr = mtod(m, struct rfcomm_frame_hdr *); 3049 hdr->address = address; 3050 hdr->control = RFCOMM_MKCONTROL(RFCOMM_FRAME_UIH, pf); 3051 3052 /* Calculate FCS */ 3053 mcrc->m_data[0] = ng_btsocket_rfcomm_fcs2((u_int8_t *) hdr); 3054 3055 /* Put length back */ 3056 length = (data != NULL)? data->m_pkthdr.len : 0; 3057 if (length > 127) { 3058 u_int16_t l = htole16(RFCOMM_MKLEN16(length)); 3059 3060 bcopy(&l, &hdr->length, sizeof(l)); 3061 m->m_pkthdr.len ++; 3062 m->m_len ++; 3063 } else 3064 hdr->length = RFCOMM_MKLEN8(length); 3065 3066 if (pf) { 3067 m->m_data[m->m_len] = credits; 3068 m->m_pkthdr.len ++; 3069 m->m_len ++; 3070 } 3071 3072 /* Add payload */ 3073 if (data != NULL) { 3074 m_cat(m, data); 3075 m->m_pkthdr.len += length; 3076 } 3077 3078 /* Put FCS back */ 3079 m_cat(m, mcrc); 3080 m->m_pkthdr.len ++; 3081 3082 NG_BTSOCKET_RFCOMM_INFO( 3083"%s: Sending UIH state=%d, flags=%#x, address=%d, length=%d, pf=%d, " \ 3084"credits=%d, len=%d\n", 3085 __func__, s->state, s->flags, address, length, pf, credits, 3086 m->m_pkthdr.len); 3087 3088 NG_BT_MBUFQ_ENQUEUE(&s->outq, m); 3089 3090 return (0); 3091} /* ng_btsocket_rfcomm_send_uih */ 3092 3093/* 3094 * Send MSC request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3095 */ 3096 3097static int 3098ng_btsocket_rfcomm_send_msc(ng_btsocket_rfcomm_pcb_p pcb) 3099{ 3100 struct mbuf *m = NULL; 3101 struct rfcomm_mcc_hdr *hdr = NULL; 3102 struct rfcomm_mcc_msc *msc = NULL; 3103 3104 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3105 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3106 3107 MGETHDR(m, M_DONTWAIT, MT_DATA); 3108 if (m == NULL) 3109 return (ENOBUFS); 3110 3111 m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*msc); 3112 3113 hdr = mtod(m, struct rfcomm_mcc_hdr *); 3114 msc = (struct rfcomm_mcc_msc *)(hdr + 1); 3115 3116 hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_MSC); 3117 hdr->length = RFCOMM_MKLEN8(sizeof(*msc)); 3118 3119 msc->address = RFCOMM_MKADDRESS(1, pcb->dlci); 3120 msc->modem = pcb->lmodem; 3121 3122 NG_BTSOCKET_RFCOMM_INFO( 3123"%s: Sending MSC dlci=%d, state=%d, flags=%#x, address=%d, modem=%#x\n", 3124 __func__, pcb->dlci, pcb->state, pcb->flags, msc->address, 3125 msc->modem); 3126 3127 return (ng_btsocket_rfcomm_send_uih(pcb->session, 3128 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m)); 3129} /* ng_btsocket_rfcomm_send_msc */ 3130 3131/* 3132 * Send PN request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3133 */ 3134 3135static int 3136ng_btsocket_rfcomm_send_pn(ng_btsocket_rfcomm_pcb_p pcb) 3137{ 3138 struct mbuf *m = NULL; 3139 struct rfcomm_mcc_hdr *hdr = NULL; 3140 struct rfcomm_mcc_pn *pn = NULL; 3141 3142 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3143 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3144 3145 MGETHDR(m, M_DONTWAIT, MT_DATA); 3146 if (m == NULL) 3147 return (ENOBUFS); 3148 3149 m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*pn); 3150 3151 hdr = mtod(m, struct rfcomm_mcc_hdr *); 3152 pn = (struct rfcomm_mcc_pn *)(hdr + 1); 3153 3154 hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_PN); 3155 hdr->length = RFCOMM_MKLEN8(sizeof(*pn)); 3156 3157 pn->dlci = pcb->dlci; 3158 3159 /* 3160 * Set default DLCI priority as described in GSM 07.10 3161 * (ETSI TS 101 369) clause 5.6 page 42 3162 */ 3163 3164 pn->priority = (pcb->dlci < 56)? (((pcb->dlci >> 3) << 3) + 7) : 61; 3165 pn->ack_timer = 0; 3166 pn->mtu = htole16(pcb->mtu); 3167 pn->max_retrans = 0; 3168 3169 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 3170 pn->flow_control = 0xf0; 3171 pn->credits = pcb->rx_cred; 3172 } else { 3173 pn->flow_control = 0; 3174 pn->credits = 0; 3175 } 3176 3177 NG_BTSOCKET_RFCOMM_INFO( 3178"%s: Sending PN dlci=%d, state=%d, flags=%#x, mtu=%d, flow_control=%#x, " \ 3179"credits=%d\n", __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 3180 pn->flow_control, pn->credits); 3181 3182 return (ng_btsocket_rfcomm_send_uih(pcb->session, 3183 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m)); 3184} /* ng_btsocket_rfcomm_send_pn */ 3185 3186/* 3187 * Calculate and send credits based on available space in receive buffer 3188 */ 3189 3190static int 3191ng_btsocket_rfcomm_send_credits(ng_btsocket_rfcomm_pcb_p pcb) 3192{ 3193 int error = 0; 3194 u_int8_t credits; 3195 3196 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3197 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3198 3199 NG_BTSOCKET_RFCOMM_INFO( 3200"%s: Sending more credits, dlci=%d, state=%d, flags=%#x, mtu=%d, " \ 3201"space=%ld, tx_cred=%d, rx_cred=%d\n", 3202 __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 3203 sbspace(&pcb->so->so_rcv), pcb->tx_cred, pcb->rx_cred); 3204 3205 credits = sbspace(&pcb->so->so_rcv) / pcb->mtu; 3206 if (credits > 0) { 3207 if (pcb->rx_cred + credits > RFCOMM_MAX_CREDITS) 3208 credits = RFCOMM_MAX_CREDITS - pcb->rx_cred; 3209 3210 error = ng_btsocket_rfcomm_send_uih( 3211 pcb->session, 3212 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 3213 pcb->dlci), 1, credits, NULL); 3214 if (error == 0) { 3215 pcb->rx_cred += credits; 3216 3217 NG_BTSOCKET_RFCOMM_INFO( 3218"%s: Gave remote side %d more credits, dlci=%d, state=%d, flags=%#x, " \ 3219"rx_cred=%d, tx_cred=%d\n", __func__, credits, pcb->dlci, pcb->state, 3220 pcb->flags, pcb->rx_cred, pcb->tx_cred); 3221 } else 3222 NG_BTSOCKET_RFCOMM_ERR( 3223"%s: Could not send credits, error=%d, dlci=%d, state=%d, flags=%#x, " \ 3224"mtu=%d, space=%ld, tx_cred=%d, rx_cred=%d\n", 3225 __func__, error, pcb->dlci, pcb->state, 3226 pcb->flags, pcb->mtu, sbspace(&pcb->so->so_rcv), 3227 pcb->tx_cred, pcb->rx_cred); 3228 } 3229 3230 return (error); 3231} /* ng_btsocket_rfcomm_send_credits */ 3232 3233/***************************************************************************** 3234 ***************************************************************************** 3235 ** RFCOMM DLCs 3236 ***************************************************************************** 3237 *****************************************************************************/ 3238 3239/* 3240 * Send data from socket send buffer 3241 * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3242 */ 3243 3244static int 3245ng_btsocket_rfcomm_pcb_send(ng_btsocket_rfcomm_pcb_p pcb, int limit) 3246{ 3247 struct mbuf *m = NULL; 3248 int sent, length, error; 3249 3250 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3251 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3252 3253 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) 3254 limit = min(limit, pcb->tx_cred); 3255 else if (!(pcb->rmodem & RFCOMM_MODEM_FC)) 3256 limit = min(limit, RFCOMM_MAX_CREDITS); /* XXX ??? */ 3257 else 3258 limit = 0; 3259 3260 if (limit == 0) { 3261 NG_BTSOCKET_RFCOMM_INFO( 3262"%s: Could not send - remote flow control asserted, dlci=%d, flags=%#x, " \ 3263"rmodem=%#x, tx_cred=%d\n", 3264 __func__, pcb->dlci, pcb->flags, pcb->rmodem, 3265 pcb->tx_cred); 3266 3267 return (0); 3268 } 3269 3270 for (error = 0, sent = 0; sent < limit; sent ++) { 3271 length = min(pcb->mtu, pcb->so->so_snd.sb_cc); 3272 if (length == 0) 3273 break; 3274 3275 /* Get the chunk from the socket's send buffer */ 3276 m = ng_btsocket_rfcomm_prepare_packet(&pcb->so->so_snd, length); 3277 if (m == NULL) { 3278 error = ENOBUFS; 3279 break; 3280 } 3281 3282 sbdrop(&pcb->so->so_snd, length); 3283 3284 error = ng_btsocket_rfcomm_send_uih(pcb->session, 3285 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 3286 pcb->dlci), 0, 0, m); 3287 if (error != 0) 3288 break; 3289 } 3290 3291 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) 3292 pcb->tx_cred -= sent; 3293 3294 if (error == 0 && sent > 0) { 3295 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_SENDING; 3296 sowwakeup(pcb->so); 3297 } 3298 3299 return (error); 3300} /* ng_btsocket_rfcomm_pcb_send */ 3301 3302/* 3303 * Unlink and disconnect DLC. If ng_btsocket_rfcomm_pcb_kill() returns 3304 * non zero value than socket has no reference and has to be detached. 3305 * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3306 */ 3307 3308static void 3309ng_btsocket_rfcomm_pcb_kill(ng_btsocket_rfcomm_pcb_p pcb, int error) 3310{ 3311 ng_btsocket_rfcomm_session_p s = pcb->session; 3312 3313 NG_BTSOCKET_RFCOMM_INFO( 3314"%s: Killing DLC, so=%p, dlci=%d, state=%d, flags=%#x, error=%d\n", 3315 __func__, pcb->so, pcb->dlci, pcb->state, pcb->flags, error); 3316 3317 if (pcb->session == NULL) 3318 panic("%s: DLC without session, pcb=%p, state=%d, flags=%#x\n", 3319 __func__, pcb, pcb->state, pcb->flags); 3320 3321 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3322 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3323 3324 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 3325 ng_btsocket_rfcomm_untimeout(pcb); 3326 3327 /* Detach DLC from the session. Does not matter which state DLC in */ 3328 LIST_REMOVE(pcb, session_next); 3329 pcb->session = NULL; 3330 3331 /* Change DLC state and wakeup all sleepers */ 3332 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED; 3333 pcb->so->so_error = error; 3334 soisdisconnected(pcb->so); 3335 wakeup(&pcb->state); 3336 3337 /* Check if we have any DLCs left on the session */ 3338 if (LIST_EMPTY(&s->dlcs) && INITIATOR(s)) { 3339 NG_BTSOCKET_RFCOMM_INFO( 3340"%s: Disconnecting session, state=%d, flags=%#x, mtu=%d\n", 3341 __func__, s->state, s->flags, s->mtu); 3342 3343 switch (s->state) { 3344 case NG_BTSOCKET_RFCOMM_SESSION_CLOSED: 3345 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 3346 /* 3347 * Do not have to do anything here. We can get here 3348 * when L2CAP connection was terminated or we have 3349 * received DISC on multiplexor channel 3350 */ 3351 break; 3352 3353 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 3354 /* Send DISC on multiplexor channel */ 3355 error = ng_btsocket_rfcomm_send_command(s, 3356 RFCOMM_FRAME_DISC, 0); 3357 if (error == 0) { 3358 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 3359 break; 3360 } 3361 /* FALL THROUGH */ 3362 3363 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING: 3364 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 3365 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 3366 break; 3367 3368/* case NG_BTSOCKET_RFCOMM_SESSION_LISTENING: */ 3369 default: 3370 panic("%s: Invalid session state=%d, flags=%#x\n", 3371 __func__, s->state, s->flags); 3372 break; 3373 } 3374 3375 ng_btsocket_rfcomm_task_wakeup(); 3376 } 3377} /* ng_btsocket_rfcomm_pcb_kill */ 3378 3379/* 3380 * Look for given dlci for given RFCOMM session. Caller must hold s->session_mtx 3381 */ 3382 3383static ng_btsocket_rfcomm_pcb_p 3384ng_btsocket_rfcomm_pcb_by_dlci(ng_btsocket_rfcomm_session_p s, int dlci) 3385{ 3386 ng_btsocket_rfcomm_pcb_p pcb = NULL; 3387 3388 mtx_assert(&s->session_mtx, MA_OWNED); 3389 3390 LIST_FOREACH(pcb, &s->dlcs, session_next) 3391 if (pcb->dlci == dlci) 3392 break; 3393 3394 return (pcb); 3395} /* ng_btsocket_rfcomm_pcb_by_dlci */ 3396 3397/* 3398 * Look for socket that listens on given src address and given channel 3399 */ 3400 3401static ng_btsocket_rfcomm_pcb_p 3402ng_btsocket_rfcomm_pcb_listener(bdaddr_p src, int channel) 3403{ 3404 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb1 = NULL; 3405 3406 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 3407 3408 LIST_FOREACH(pcb, &ng_btsocket_rfcomm_sockets, next) { 3409 if (pcb->channel != channel || 3410 !(pcb->so->so_options & SO_ACCEPTCONN)) 3411 continue; 3412 3413 if (bcmp(&pcb->src, src, sizeof(*src)) == 0) 3414 break; 3415 3416 if (bcmp(&pcb->src, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0) 3417 pcb1 = pcb; 3418 } 3419 3420 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 3421 3422 return ((pcb != NULL)? pcb : pcb1); 3423} /* ng_btsocket_rfcomm_pcb_listener */ 3424 3425/***************************************************************************** 3426 ***************************************************************************** 3427 ** Misc. functions 3428 ***************************************************************************** 3429 *****************************************************************************/ 3430 3431/* 3432 * Set timeout. Caller MUST hold pcb_mtx 3433 */ 3434 3435static void 3436ng_btsocket_rfcomm_timeout(ng_btsocket_rfcomm_pcb_p pcb) 3437{ 3438 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3439 3440 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) { 3441 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMO; 3442 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3443 pcb->timo = timeout(ng_btsocket_rfcomm_process_timeout, pcb, 3444 ng_btsocket_rfcomm_timo * hz); 3445 } else 3446 panic("%s: Duplicated socket timeout?!\n", __func__); 3447} /* ng_btsocket_rfcomm_timeout */ 3448 3449/* 3450 * Unset pcb timeout. Caller MUST hold pcb_mtx 3451 */ 3452 3453static void 3454ng_btsocket_rfcomm_untimeout(ng_btsocket_rfcomm_pcb_p pcb) 3455{ 3456 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3457 3458 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) { 3459 untimeout(ng_btsocket_rfcomm_process_timeout, pcb, pcb->timo); 3460 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO; 3461 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3462 } else 3463 panic("%s: No socket timeout?!\n", __func__); 3464} /* ng_btsocket_rfcomm_timeout */ 3465 3466/* 3467 * Process pcb timeout 3468 */ 3469 3470static void 3471ng_btsocket_rfcomm_process_timeout(void *xpcb) 3472{ 3473 ng_btsocket_rfcomm_pcb_p pcb = (ng_btsocket_rfcomm_pcb_p) xpcb; 3474 3475 mtx_lock(&pcb->pcb_mtx); 3476 3477 NG_BTSOCKET_RFCOMM_INFO( 3478"%s: Timeout, so=%p, dlci=%d, state=%d, flags=%#x\n", 3479 __func__, pcb->so, pcb->dlci, pcb->state, pcb->flags); 3480 3481 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO; 3482 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3483 3484 switch (pcb->state) { 3485 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 3486 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 3487 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 3488 break; 3489 3490 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 3491 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 3492 break; 3493 3494 default: 3495 panic( 3496"%s: DLC timeout in invalid state, dlci=%d, state=%d, flags=%#x\n", 3497 __func__, pcb->dlci, pcb->state, pcb->flags); 3498 break; 3499 } 3500 3501 ng_btsocket_rfcomm_task_wakeup(); 3502 3503 mtx_unlock(&pcb->pcb_mtx); 3504} /* ng_btsocket_rfcomm_process_timeout */ 3505 3506/* 3507 * Get up to length bytes from the socket buffer 3508 */ 3509 3510static struct mbuf * 3511ng_btsocket_rfcomm_prepare_packet(struct sockbuf *sb, int length) 3512{ 3513 struct mbuf *top = NULL, *m = NULL, *n = NULL, *nextpkt = NULL; 3514 int mlen, noff, len; 3515 3516 MGETHDR(top, M_DONTWAIT, MT_DATA); 3517 if (top == NULL) 3518 return (NULL); 3519 3520 top->m_pkthdr.len = length; 3521 top->m_len = 0; 3522 mlen = MHLEN; 3523 3524 m = top; 3525 n = sb->sb_mb; 3526 nextpkt = n->m_nextpkt; 3527 noff = 0; 3528 3529 while (length > 0 && n != NULL) { 3530 len = min(mlen - m->m_len, n->m_len - noff); 3531 if (len > length) 3532 len = length; 3533 3534 bcopy(mtod(n, caddr_t)+noff, mtod(m, caddr_t)+m->m_len, len); 3535 m->m_len += len; 3536 noff += len; 3537 length -= len; 3538 3539 if (length > 0 && m->m_len == mlen) { 3540 MGET(m->m_next, M_DONTWAIT, MT_DATA); 3541 if (m->m_next == NULL) { 3542 NG_FREE_M(top); 3543 return (NULL); 3544 } 3545 3546 m = m->m_next; 3547 m->m_len = 0; 3548 mlen = MLEN; 3549 } 3550 3551 if (noff == n->m_len) { 3552 noff = 0; 3553 n = n->m_next; 3554 3555 if (n == NULL) 3556 n = nextpkt; 3557 3558 nextpkt = (n != NULL)? n->m_nextpkt : NULL; 3559 } 3560 } 3561 3562 if (length < 0) 3563 panic("%s: length=%d\n", __func__, length); 3564 if (length > 0 && n == NULL) 3565 panic("%s: bogus length=%d, n=%p\n", __func__, length, n); 3566 3567 return (top); 3568} /* ng_btsocket_rfcomm_prepare_packet */ 3569
|