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