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