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