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 error = socreate_error; 898 goto out; 899 } 900 901 /* 902 * Create default listen RFCOMM session. The default RFCOMM 903 * session will listen on ANY address. 904 * 905 * XXX FIXME Note that currently there is no way to adjust MTU 906 * for the default session. 907 */ 908 error = ng_btsocket_rfcomm_session_create(&s, l2so, 909 NG_HCI_BDADDR_ANY, NULL, td); 910 if (error != 0) 911 goto out; 912 l2so = NULL; 913 } 914 SOCK_LOCK(so); 915 solisten_proto(so, backlog); 916 SOCK_UNLOCK(so); 917 out: 918 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 919 /* 920 * If we still have an l2so reference here, it's unneeded, so release 921 * it. 922 */ 923 if (l2so != NULL) 924 soclose(l2so); 925 return (error); 926 } /* ng_btsocket_listen */ 927 928 /* 929 * Get peer address 930 */ 931 932 int 933 ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam) 934 { 935 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 936 struct sockaddr_rfcomm sa; 937 938 if (pcb == NULL) 939 return (EINVAL); 940 941 bcopy(&pcb->dst, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr)); 942 sa.rfcomm_channel = pcb->channel; 943 sa.rfcomm_len = sizeof(sa); 944 sa.rfcomm_family = AF_BLUETOOTH; 945 946 *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); 947 948 return ((*nam == NULL)? ENOMEM : 0); 949 } /* ng_btsocket_rfcomm_peeraddr */ 950 951 /* 952 * Send data to socket 953 */ 954 955 int 956 ng_btsocket_rfcomm_send(struct socket *so, int flags, struct mbuf *m, 957 struct sockaddr *nam, struct mbuf *control, struct thread *td) 958 { 959 ng_btsocket_rfcomm_pcb_t *pcb = so2rfcomm_pcb(so); 960 int error = 0; 961 962 /* Check socket and input */ 963 if (pcb == NULL || m == NULL || control != NULL) { 964 error = EINVAL; 965 goto drop; 966 } 967 968 mtx_lock(&pcb->pcb_mtx); 969 970 /* Make sure DLC is connected */ 971 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 972 mtx_unlock(&pcb->pcb_mtx); 973 error = ENOTCONN; 974 goto drop; 975 } 976 977 /* Put the packet on the socket's send queue and wakeup RFCOMM task */ 978 sbappend(&pcb->so->so_snd, m, flags); 979 m = NULL; 980 981 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_SENDING)) { 982 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_SENDING; 983 error = ng_btsocket_rfcomm_task_wakeup(); 984 } 985 986 mtx_unlock(&pcb->pcb_mtx); 987 drop: 988 NG_FREE_M(m); /* checks for != NULL */ 989 NG_FREE_M(control); 990 991 return (error); 992 } /* ng_btsocket_rfcomm_send */ 993 994 /* 995 * Get socket address 996 */ 997 998 int 999 ng_btsocket_rfcomm_sockaddr(struct socket *so, struct sockaddr **nam) 1000 { 1001 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 1002 struct sockaddr_rfcomm sa; 1003 1004 if (pcb == NULL) 1005 return (EINVAL); 1006 1007 bcopy(&pcb->src, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr)); 1008 sa.rfcomm_channel = pcb->channel; 1009 sa.rfcomm_len = sizeof(sa); 1010 sa.rfcomm_family = AF_BLUETOOTH; 1011 1012 *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); 1013 1014 return ((*nam == NULL)? ENOMEM : 0); 1015 } /* ng_btsocket_rfcomm_sockaddr */ 1016 1017 /* 1018 * Upcall function for L2CAP sockets. Enqueue RFCOMM task. 1019 */ 1020 1021 static int 1022 ng_btsocket_rfcomm_upcall(struct socket *so, void *arg, int waitflag) 1023 { 1024 int error; 1025 1026 if (so == NULL) 1027 panic("%s: so == NULL\n", __func__); 1028 1029 if ((error = ng_btsocket_rfcomm_task_wakeup()) != 0) 1030 NG_BTSOCKET_RFCOMM_ALERT( 1031 "%s: Could not enqueue RFCOMM task, error=%d\n", __func__, error); 1032 return (SU_OK); 1033 } /* ng_btsocket_rfcomm_upcall */ 1034 1035 /* 1036 * RFCOMM task. Will handle all RFCOMM sessions in one pass. 1037 * XXX FIXME does not scale very well 1038 */ 1039 1040 static void 1041 ng_btsocket_rfcomm_sessions_task(void *ctx, int pending) 1042 { 1043 ng_btsocket_rfcomm_session_p s = NULL, s_next = NULL; 1044 1045 mtx_lock(&ng_btsocket_rfcomm_sessions_mtx); 1046 1047 for (s = LIST_FIRST(&ng_btsocket_rfcomm_sessions); s != NULL; ) { 1048 mtx_lock(&s->session_mtx); 1049 s_next = LIST_NEXT(s, next); 1050 1051 ng_btsocket_rfcomm_session_task(s); 1052 1053 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_CLOSED) { 1054 /* Unlink and clean the session */ 1055 LIST_REMOVE(s, next); 1056 1057 NG_BT_MBUFQ_DRAIN(&s->outq); 1058 if (!LIST_EMPTY(&s->dlcs)) 1059 panic("%s: DLC list is not empty\n", __func__); 1060 1061 /* Close L2CAP socket */ 1062 SOCKBUF_LOCK(&s->l2so->so_rcv); 1063 soupcall_clear(s->l2so, SO_RCV); 1064 SOCKBUF_UNLOCK(&s->l2so->so_rcv); 1065 SOCKBUF_LOCK(&s->l2so->so_snd); 1066 soupcall_clear(s->l2so, SO_SND); 1067 SOCKBUF_UNLOCK(&s->l2so->so_snd); 1068 soclose(s->l2so); 1069 1070 mtx_unlock(&s->session_mtx); 1071 1072 mtx_destroy(&s->session_mtx); 1073 bzero(s, sizeof(*s)); 1074 free(s, M_NETGRAPH_BTSOCKET_RFCOMM); 1075 } else 1076 mtx_unlock(&s->session_mtx); 1077 1078 s = s_next; 1079 } 1080 1081 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 1082 } /* ng_btsocket_rfcomm_sessions_task */ 1083 1084 /* 1085 * Process RFCOMM session. Will handle all RFCOMM sockets in one pass. 1086 */ 1087 1088 static void 1089 ng_btsocket_rfcomm_session_task(ng_btsocket_rfcomm_session_p s) 1090 { 1091 mtx_assert(&s->session_mtx, MA_OWNED); 1092 1093 if (s->l2so->so_rcv.sb_state & SBS_CANTRCVMORE) { 1094 NG_BTSOCKET_RFCOMM_INFO( 1095 "%s: L2CAP connection has been terminated, so=%p, so_state=%#x, so_count=%d, " \ 1096 "state=%d, flags=%#x\n", __func__, s->l2so, s->l2so->so_state, 1097 s->l2so->so_count, s->state, s->flags); 1098 1099 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1100 ng_btsocket_rfcomm_session_clean(s); 1101 } 1102 1103 /* Now process upcall */ 1104 switch (s->state) { 1105 /* Try to accept new L2CAP connection(s) */ 1106 case NG_BTSOCKET_RFCOMM_SESSION_LISTENING: 1107 while (ng_btsocket_rfcomm_session_accept(s) == 0) 1108 ; 1109 break; 1110 1111 /* Process the results of the L2CAP connect */ 1112 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING: 1113 ng_btsocket_rfcomm_session_process_pcb(s); 1114 1115 if (ng_btsocket_rfcomm_session_connect(s) != 0) { 1116 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1117 ng_btsocket_rfcomm_session_clean(s); 1118 } 1119 break; 1120 1121 /* Try to receive/send more data */ 1122 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 1123 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 1124 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 1125 ng_btsocket_rfcomm_session_process_pcb(s); 1126 1127 if (ng_btsocket_rfcomm_session_receive(s) != 0) { 1128 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1129 ng_btsocket_rfcomm_session_clean(s); 1130 } else if (ng_btsocket_rfcomm_session_send(s) != 0) { 1131 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1132 ng_btsocket_rfcomm_session_clean(s); 1133 } 1134 break; 1135 1136 case NG_BTSOCKET_RFCOMM_SESSION_CLOSED: 1137 break; 1138 1139 default: 1140 panic("%s: Invalid session state=%d, flags=%#x\n", 1141 __func__, s->state, s->flags); 1142 break; 1143 } 1144 } /* ng_btsocket_rfcomm_session_task */ 1145 1146 /* 1147 * Process RFCOMM connection indicator. Caller must hold s->session_mtx 1148 */ 1149 1150 static ng_btsocket_rfcomm_pcb_p 1151 ng_btsocket_rfcomm_connect_ind(ng_btsocket_rfcomm_session_p s, int channel) 1152 { 1153 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb1 = NULL; 1154 ng_btsocket_l2cap_pcb_p l2pcb = NULL; 1155 struct socket *so1; 1156 1157 mtx_assert(&s->session_mtx, MA_OWNED); 1158 1159 /* 1160 * Try to find RFCOMM socket that listens on given source address 1161 * and channel. This will return the best possible match. 1162 */ 1163 1164 l2pcb = so2l2cap_pcb(s->l2so); 1165 pcb = ng_btsocket_rfcomm_pcb_listener(&l2pcb->src, channel); 1166 if (pcb == NULL) 1167 return (NULL); 1168 1169 /* 1170 * Check the pending connections queue and if we have space then 1171 * create new socket and set proper source and destination address, 1172 * and channel. 1173 */ 1174 1175 mtx_lock(&pcb->pcb_mtx); 1176 1177 CURVNET_SET(pcb->so->so_vnet); 1178 so1 = sonewconn(pcb->so, 0); 1179 CURVNET_RESTORE(); 1180 1181 mtx_unlock(&pcb->pcb_mtx); 1182 1183 if (so1 == NULL) 1184 return (NULL); 1185 1186 /* 1187 * If we got here than we have created new socket. So complete the 1188 * connection. Set source and destination address from the session. 1189 */ 1190 1191 pcb1 = so2rfcomm_pcb(so1); 1192 if (pcb1 == NULL) 1193 panic("%s: pcb1 == NULL\n", __func__); 1194 1195 mtx_lock(&pcb1->pcb_mtx); 1196 1197 bcopy(&l2pcb->src, &pcb1->src, sizeof(pcb1->src)); 1198 bcopy(&l2pcb->dst, &pcb1->dst, sizeof(pcb1->dst)); 1199 pcb1->channel = channel; 1200 1201 /* Link new DLC to the session. We already hold s->session_mtx */ 1202 LIST_INSERT_HEAD(&s->dlcs, pcb1, session_next); 1203 pcb1->session = s; 1204 1205 mtx_unlock(&pcb1->pcb_mtx); 1206 1207 return (pcb1); 1208 } /* ng_btsocket_rfcomm_connect_ind */ 1209 1210 /* 1211 * Process RFCOMM connect confirmation. Caller must hold s->session_mtx. 1212 */ 1213 1214 static void 1215 ng_btsocket_rfcomm_connect_cfm(ng_btsocket_rfcomm_session_p s) 1216 { 1217 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1218 int error; 1219 1220 mtx_assert(&s->session_mtx, MA_OWNED); 1221 1222 /* 1223 * Wake up all waiting sockets and send PN request for each of them. 1224 * Note that timeout already been set in ng_btsocket_rfcomm_connect() 1225 * 1226 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1227 * will unlink DLC from the session 1228 */ 1229 1230 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1231 mtx_lock(&pcb->pcb_mtx); 1232 pcb_next = LIST_NEXT(pcb, session_next); 1233 1234 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT) { 1235 pcb->mtu = s->mtu; 1236 bcopy(&so2l2cap_pcb(s->l2so)->src, &pcb->src, 1237 sizeof(pcb->src)); 1238 1239 error = ng_btsocket_rfcomm_send_pn(pcb); 1240 if (error == 0) 1241 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONFIGURING; 1242 else 1243 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1244 } 1245 1246 mtx_unlock(&pcb->pcb_mtx); 1247 pcb = pcb_next; 1248 } 1249 } /* ng_btsocket_rfcomm_connect_cfm */ 1250 1251 /***************************************************************************** 1252 ***************************************************************************** 1253 ** RFCOMM sessions 1254 ***************************************************************************** 1255 *****************************************************************************/ 1256 1257 /* 1258 * Create new RFCOMM session. That function WILL NOT take ownership over l2so. 1259 * Caller MUST free l2so if function failed. 1260 */ 1261 1262 static int 1263 ng_btsocket_rfcomm_session_create(ng_btsocket_rfcomm_session_p *sp, 1264 struct socket *l2so, bdaddr_p src, bdaddr_p dst, 1265 struct thread *td) 1266 { 1267 ng_btsocket_rfcomm_session_p s = NULL; 1268 struct sockaddr_l2cap l2sa; 1269 struct sockopt l2sopt; 1270 int error; 1271 u_int16_t mtu; 1272 1273 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1274 1275 /* Allocate the RFCOMM session */ 1276 s = malloc(sizeof(*s), 1277 M_NETGRAPH_BTSOCKET_RFCOMM, M_NOWAIT | M_ZERO); 1278 if (s == NULL) 1279 return (ENOMEM); 1280 1281 /* Set defaults */ 1282 s->mtu = RFCOMM_DEFAULT_MTU; 1283 s->flags = 0; 1284 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1285 NG_BT_MBUFQ_INIT(&s->outq, ifqmaxlen); 1286 1287 /* 1288 * XXX Mark session mutex as DUPOK to prevent "duplicated lock of 1289 * the same type" message. When accepting new L2CAP connection 1290 * ng_btsocket_rfcomm_session_accept() holds both session mutexes 1291 * for "old" (accepting) session and "new" (created) session. 1292 */ 1293 1294 mtx_init(&s->session_mtx, "btsocks_rfcomm_session_mtx", NULL, 1295 MTX_DEF|MTX_DUPOK); 1296 1297 LIST_INIT(&s->dlcs); 1298 1299 /* Prepare L2CAP socket */ 1300 SOCKBUF_LOCK(&l2so->so_rcv); 1301 soupcall_set(l2so, SO_RCV, ng_btsocket_rfcomm_upcall, NULL); 1302 SOCKBUF_UNLOCK(&l2so->so_rcv); 1303 SOCKBUF_LOCK(&l2so->so_snd); 1304 soupcall_set(l2so, SO_SND, ng_btsocket_rfcomm_upcall, NULL); 1305 SOCKBUF_UNLOCK(&l2so->so_snd); 1306 l2so->so_state |= SS_NBIO; 1307 s->l2so = l2so; 1308 1309 mtx_lock(&s->session_mtx); 1310 1311 /* 1312 * "src" == NULL and "dst" == NULL means just create session. 1313 * caller must do the rest 1314 */ 1315 1316 if (src == NULL && dst == NULL) 1317 goto done; 1318 1319 /* 1320 * Set incoming MTU on L2CAP socket. It is RFCOMM session default MTU 1321 * plus 5 bytes: RFCOMM frame header, one extra byte for length and one 1322 * extra byte for credits. 1323 */ 1324 1325 mtu = s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1; 1326 1327 l2sopt.sopt_dir = SOPT_SET; 1328 l2sopt.sopt_level = SOL_L2CAP; 1329 l2sopt.sopt_name = SO_L2CAP_IMTU; 1330 l2sopt.sopt_val = (void *) &mtu; 1331 l2sopt.sopt_valsize = sizeof(mtu); 1332 l2sopt.sopt_td = NULL; 1333 1334 error = sosetopt(s->l2so, &l2sopt); 1335 if (error != 0) 1336 goto bad; 1337 1338 /* Bind socket to "src" address */ 1339 l2sa.l2cap_len = sizeof(l2sa); 1340 l2sa.l2cap_family = AF_BLUETOOTH; 1341 l2sa.l2cap_psm = (dst == NULL)? htole16(NG_L2CAP_PSM_RFCOMM) : 0; 1342 bcopy(src, &l2sa.l2cap_bdaddr, sizeof(l2sa.l2cap_bdaddr)); 1343 l2sa.l2cap_cid = 0; 1344 l2sa.l2cap_bdaddr_type = BDADDR_BREDR; 1345 1346 error = sobind(s->l2so, (struct sockaddr *) &l2sa, td); 1347 if (error != 0) 1348 goto bad; 1349 1350 /* If "dst" is not NULL then initiate connect(), otherwise listen() */ 1351 if (dst == NULL) { 1352 s->flags = 0; 1353 s->state = NG_BTSOCKET_RFCOMM_SESSION_LISTENING; 1354 1355 error = solisten(s->l2so, 10, td); 1356 if (error != 0) 1357 goto bad; 1358 } else { 1359 s->flags = NG_BTSOCKET_RFCOMM_SESSION_INITIATOR; 1360 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTING; 1361 1362 l2sa.l2cap_len = sizeof(l2sa); 1363 l2sa.l2cap_family = AF_BLUETOOTH; 1364 l2sa.l2cap_psm = htole16(NG_L2CAP_PSM_RFCOMM); 1365 bcopy(dst, &l2sa.l2cap_bdaddr, sizeof(l2sa.l2cap_bdaddr)); 1366 l2sa.l2cap_cid = 0; 1367 l2sa.l2cap_bdaddr_type = BDADDR_BREDR; 1368 1369 error = soconnect(s->l2so, (struct sockaddr *) &l2sa, td); 1370 if (error != 0) 1371 goto bad; 1372 } 1373 1374 done: 1375 LIST_INSERT_HEAD(&ng_btsocket_rfcomm_sessions, s, next); 1376 *sp = s; 1377 1378 mtx_unlock(&s->session_mtx); 1379 1380 return (0); 1381 1382 bad: 1383 mtx_unlock(&s->session_mtx); 1384 1385 /* Return L2CAP socket back to its original state */ 1386 SOCKBUF_LOCK(&l2so->so_rcv); 1387 soupcall_clear(s->l2so, SO_RCV); 1388 SOCKBUF_UNLOCK(&l2so->so_rcv); 1389 SOCKBUF_LOCK(&l2so->so_snd); 1390 soupcall_clear(s->l2so, SO_SND); 1391 SOCKBUF_UNLOCK(&l2so->so_snd); 1392 l2so->so_state &= ~SS_NBIO; 1393 1394 mtx_destroy(&s->session_mtx); 1395 bzero(s, sizeof(*s)); 1396 free(s, M_NETGRAPH_BTSOCKET_RFCOMM); 1397 1398 return (error); 1399 } /* ng_btsocket_rfcomm_session_create */ 1400 1401 /* 1402 * Process accept() on RFCOMM session 1403 * XXX FIXME locking for "l2so"? 1404 */ 1405 1406 static int 1407 ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0) 1408 { 1409 struct socket *l2so; 1410 struct sockaddr_l2cap *l2sa = NULL; 1411 ng_btsocket_l2cap_pcb_t *l2pcb = NULL; 1412 ng_btsocket_rfcomm_session_p s = NULL; 1413 int error; 1414 1415 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1416 mtx_assert(&s0->session_mtx, MA_OWNED); 1417 1418 SOLISTEN_LOCK(s0->l2so); 1419 error = solisten_dequeue(s0->l2so, &l2so, 0); 1420 if (error == EWOULDBLOCK) 1421 return (error); 1422 if (error) { 1423 NG_BTSOCKET_RFCOMM_ERR( 1424 "%s: Could not accept connection on L2CAP socket, error=%d\n", __func__, error); 1425 return (error); 1426 } 1427 1428 error = soaccept(l2so, (struct sockaddr **) &l2sa); 1429 if (error != 0) { 1430 NG_BTSOCKET_RFCOMM_ERR( 1431 "%s: soaccept() on L2CAP socket failed, error=%d\n", __func__, error); 1432 soclose(l2so); 1433 1434 return (error); 1435 } 1436 1437 /* 1438 * Check if there is already active RFCOMM session between two devices. 1439 * If so then close L2CAP connection. We only support one RFCOMM session 1440 * between each pair of devices. Note that here we assume session in any 1441 * state. The session even could be in the middle of disconnecting. 1442 */ 1443 1444 l2pcb = so2l2cap_pcb(l2so); 1445 s = ng_btsocket_rfcomm_session_by_addr(&l2pcb->src, &l2pcb->dst); 1446 if (s == NULL) { 1447 /* Create a new RFCOMM session */ 1448 error = ng_btsocket_rfcomm_session_create(&s, l2so, NULL, NULL, 1449 curthread /* XXX */); 1450 if (error == 0) { 1451 mtx_lock(&s->session_mtx); 1452 1453 s->flags = 0; 1454 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED; 1455 1456 /* 1457 * Adjust MTU on incoming connection. Reserve 5 bytes: 1458 * RFCOMM frame header, one extra byte for length and 1459 * one extra byte for credits. 1460 */ 1461 1462 s->mtu = min(l2pcb->imtu, l2pcb->omtu) - 1463 sizeof(struct rfcomm_frame_hdr) - 1 - 1; 1464 1465 mtx_unlock(&s->session_mtx); 1466 } else { 1467 NG_BTSOCKET_RFCOMM_ALERT( 1468 "%s: Failed to create new RFCOMM session, error=%d\n", __func__, error); 1469 1470 soclose(l2so); 1471 } 1472 } else { 1473 NG_BTSOCKET_RFCOMM_WARN( 1474 "%s: Rejecting duplicating RFCOMM session between src=%x:%x:%x:%x:%x:%x and " \ 1475 "dst=%x:%x:%x:%x:%x:%x, state=%d, flags=%#x\n", __func__, 1476 l2pcb->src.b[5], l2pcb->src.b[4], l2pcb->src.b[3], 1477 l2pcb->src.b[2], l2pcb->src.b[1], l2pcb->src.b[0], 1478 l2pcb->dst.b[5], l2pcb->dst.b[4], l2pcb->dst.b[3], 1479 l2pcb->dst.b[2], l2pcb->dst.b[1], l2pcb->dst.b[0], 1480 s->state, s->flags); 1481 1482 error = EBUSY; 1483 soclose(l2so); 1484 } 1485 1486 return (error); 1487 } /* ng_btsocket_rfcomm_session_accept */ 1488 1489 /* 1490 * Process connect() on RFCOMM session 1491 * XXX FIXME locking for "l2so"? 1492 */ 1493 1494 static int 1495 ng_btsocket_rfcomm_session_connect(ng_btsocket_rfcomm_session_p s) 1496 { 1497 ng_btsocket_l2cap_pcb_p l2pcb = so2l2cap_pcb(s->l2so); 1498 int error; 1499 1500 mtx_assert(&s->session_mtx, MA_OWNED); 1501 1502 /* First check if connection has failed */ 1503 if ((error = s->l2so->so_error) != 0) { 1504 s->l2so->so_error = 0; 1505 1506 NG_BTSOCKET_RFCOMM_ERR( 1507 "%s: Could not connect RFCOMM session, error=%d, state=%d, flags=%#x\n", 1508 __func__, error, s->state, s->flags); 1509 1510 return (error); 1511 } 1512 1513 /* Is connection still in progress? */ 1514 if (s->l2so->so_state & SS_ISCONNECTING) 1515 return (0); 1516 1517 /* 1518 * If we got here then we are connected. Send SABM on DLCI 0 to 1519 * open multiplexor channel. 1520 */ 1521 1522 if (error == 0) { 1523 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED; 1524 1525 /* 1526 * Adjust MTU on outgoing connection. Reserve 5 bytes: RFCOMM 1527 * frame header, one extra byte for length and one extra byte 1528 * for credits. 1529 */ 1530 1531 s->mtu = min(l2pcb->imtu, l2pcb->omtu) - 1532 sizeof(struct rfcomm_frame_hdr) - 1 - 1; 1533 1534 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_SABM,0); 1535 if (error == 0) 1536 error = ng_btsocket_rfcomm_task_wakeup(); 1537 } 1538 1539 return (error); 1540 }/* ng_btsocket_rfcomm_session_connect */ 1541 1542 /* 1543 * Receive data on RFCOMM session 1544 * XXX FIXME locking for "l2so"? 1545 */ 1546 1547 static int 1548 ng_btsocket_rfcomm_session_receive(ng_btsocket_rfcomm_session_p s) 1549 { 1550 struct mbuf *m = NULL; 1551 struct uio uio; 1552 int more, flags, error; 1553 1554 mtx_assert(&s->session_mtx, MA_OWNED); 1555 1556 /* Can we read from the L2CAP socket? */ 1557 if (!soreadable(s->l2so)) 1558 return (0); 1559 1560 /* First check for error on L2CAP socket */ 1561 if ((error = s->l2so->so_error) != 0) { 1562 s->l2so->so_error = 0; 1563 1564 NG_BTSOCKET_RFCOMM_ERR( 1565 "%s: Could not receive data from L2CAP socket, error=%d, state=%d, flags=%#x\n", 1566 __func__, error, s->state, s->flags); 1567 1568 return (error); 1569 } 1570 1571 /* 1572 * Read all packets from the L2CAP socket. 1573 * XXX FIXME/VERIFY is that correct? For now use m->m_nextpkt as 1574 * indication that there is more packets on the socket's buffer. 1575 * Also what should we use in uio.uio_resid? 1576 * May be s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1? 1577 */ 1578 1579 for (more = 1; more; ) { 1580 /* Try to get next packet from socket */ 1581 bzero(&uio, sizeof(uio)); 1582 /* uio.uio_td = NULL; */ 1583 uio.uio_resid = 1000000000; 1584 flags = MSG_DONTWAIT; 1585 1586 m = NULL; 1587 error = soreceive(s->l2so, NULL, &uio, &m, 1588 (struct mbuf **) NULL, &flags); 1589 if (error != 0) { 1590 if (error == EWOULDBLOCK) 1591 return (0); /* XXX can happen? */ 1592 1593 NG_BTSOCKET_RFCOMM_ERR( 1594 "%s: Could not receive data from L2CAP socket, error=%d\n", __func__, error); 1595 1596 return (error); 1597 } 1598 1599 more = (m->m_nextpkt != NULL); 1600 m->m_nextpkt = NULL; 1601 1602 ng_btsocket_rfcomm_receive_frame(s, m); 1603 } 1604 1605 return (0); 1606 } /* ng_btsocket_rfcomm_session_receive */ 1607 1608 /* 1609 * Send data on RFCOMM session 1610 * XXX FIXME locking for "l2so"? 1611 */ 1612 1613 static int 1614 ng_btsocket_rfcomm_session_send(ng_btsocket_rfcomm_session_p s) 1615 { 1616 struct mbuf *m = NULL; 1617 int error; 1618 1619 mtx_assert(&s->session_mtx, MA_OWNED); 1620 1621 /* Send as much as we can from the session queue */ 1622 while (sowriteable(s->l2so)) { 1623 /* Check if socket still OK */ 1624 if ((error = s->l2so->so_error) != 0) { 1625 s->l2so->so_error = 0; 1626 1627 NG_BTSOCKET_RFCOMM_ERR( 1628 "%s: Detected error=%d on L2CAP socket, state=%d, flags=%#x\n", 1629 __func__, error, s->state, s->flags); 1630 1631 return (error); 1632 } 1633 1634 NG_BT_MBUFQ_DEQUEUE(&s->outq, m); 1635 if (m == NULL) 1636 return (0); /* we are done */ 1637 1638 /* Call send function on the L2CAP socket */ 1639 error = (*s->l2so->so_proto->pr_usrreqs->pru_send)(s->l2so, 1640 0, m, NULL, NULL, curthread /* XXX */); 1641 if (error != 0) { 1642 NG_BTSOCKET_RFCOMM_ERR( 1643 "%s: Could not send data to L2CAP socket, error=%d\n", __func__, error); 1644 1645 return (error); 1646 } 1647 } 1648 1649 return (0); 1650 } /* ng_btsocket_rfcomm_session_send */ 1651 1652 /* 1653 * Close and disconnect all DLCs for the given session. Caller must hold 1654 * s->sesson_mtx. Will wakeup session. 1655 */ 1656 1657 static void 1658 ng_btsocket_rfcomm_session_clean(ng_btsocket_rfcomm_session_p s) 1659 { 1660 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1661 int error; 1662 1663 mtx_assert(&s->session_mtx, MA_OWNED); 1664 1665 /* 1666 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1667 * will unlink DLC from the session 1668 */ 1669 1670 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1671 mtx_lock(&pcb->pcb_mtx); 1672 pcb_next = LIST_NEXT(pcb, session_next); 1673 1674 NG_BTSOCKET_RFCOMM_INFO( 1675 "%s: Disconnecting dlci=%d, state=%d, flags=%#x\n", 1676 __func__, pcb->dlci, pcb->state, pcb->flags); 1677 1678 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 1679 error = ECONNRESET; 1680 else 1681 error = ECONNREFUSED; 1682 1683 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1684 1685 mtx_unlock(&pcb->pcb_mtx); 1686 pcb = pcb_next; 1687 } 1688 } /* ng_btsocket_rfcomm_session_clean */ 1689 1690 /* 1691 * Process all DLCs on the session. Caller MUST hold s->session_mtx. 1692 */ 1693 1694 static void 1695 ng_btsocket_rfcomm_session_process_pcb(ng_btsocket_rfcomm_session_p s) 1696 { 1697 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1698 int error; 1699 1700 mtx_assert(&s->session_mtx, MA_OWNED); 1701 1702 /* 1703 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1704 * will unlink DLC from the session 1705 */ 1706 1707 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1708 mtx_lock(&pcb->pcb_mtx); 1709 pcb_next = LIST_NEXT(pcb, session_next); 1710 1711 switch (pcb->state) { 1712 1713 /* 1714 * If DLC in W4_CONNECT state then we should check for both 1715 * timeout and detach. 1716 */ 1717 1718 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 1719 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_DETACHED) 1720 ng_btsocket_rfcomm_pcb_kill(pcb, 0); 1721 else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1722 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1723 break; 1724 1725 /* 1726 * If DLC in CONFIGURING or CONNECTING state then we only 1727 * should check for timeout. If detach() was called then 1728 * DLC will be moved into DISCONNECTING state. 1729 */ 1730 1731 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 1732 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 1733 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1734 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1735 break; 1736 1737 /* 1738 * If DLC in CONNECTED state then we need to send data (if any) 1739 * from the socket's send queue. Note that we will send data 1740 * from either all sockets or none. This may overload session's 1741 * outgoing queue (but we do not check for that). 1742 * 1743 * XXX FIXME need scheduler for RFCOMM sockets 1744 */ 1745 1746 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 1747 error = ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 1748 if (error != 0) 1749 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1750 break; 1751 1752 /* 1753 * If DLC in DISCONNECTING state then we must send DISC frame. 1754 * Note that if DLC has timeout set then we do not need to 1755 * resend DISC frame. 1756 * 1757 * XXX FIXME need to drain all data from the socket's queue 1758 * if LINGER option was set 1759 */ 1760 1761 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 1762 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) { 1763 error = ng_btsocket_rfcomm_send_command( 1764 pcb->session, RFCOMM_FRAME_DISC, 1765 pcb->dlci); 1766 if (error == 0) 1767 ng_btsocket_rfcomm_timeout(pcb); 1768 else 1769 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1770 } else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1771 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1772 break; 1773 1774 /* case NG_BTSOCKET_RFCOMM_DLC_CLOSED: */ 1775 default: 1776 panic("%s: Invalid DLC state=%d, flags=%#x\n", 1777 __func__, pcb->state, pcb->flags); 1778 break; 1779 } 1780 1781 mtx_unlock(&pcb->pcb_mtx); 1782 pcb = pcb_next; 1783 } 1784 } /* ng_btsocket_rfcomm_session_process_pcb */ 1785 1786 /* 1787 * Find RFCOMM session between "src" and "dst". 1788 * Caller MUST hold ng_btsocket_rfcomm_sessions_mtx. 1789 */ 1790 1791 static ng_btsocket_rfcomm_session_p 1792 ng_btsocket_rfcomm_session_by_addr(bdaddr_p src, bdaddr_p dst) 1793 { 1794 ng_btsocket_rfcomm_session_p s = NULL; 1795 ng_btsocket_l2cap_pcb_p l2pcb = NULL; 1796 int any_src; 1797 1798 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1799 1800 any_src = (bcmp(src, NG_HCI_BDADDR_ANY, sizeof(*src)) == 0); 1801 1802 LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next) { 1803 l2pcb = so2l2cap_pcb(s->l2so); 1804 1805 if ((any_src || bcmp(&l2pcb->src, src, sizeof(*src)) == 0) && 1806 bcmp(&l2pcb->dst, dst, sizeof(*dst)) == 0) 1807 break; 1808 } 1809 1810 return (s); 1811 } /* ng_btsocket_rfcomm_session_by_addr */ 1812 1813 /***************************************************************************** 1814 ***************************************************************************** 1815 ** RFCOMM 1816 ***************************************************************************** 1817 *****************************************************************************/ 1818 1819 /* 1820 * Process incoming RFCOMM frame. Caller must hold s->session_mtx. 1821 * XXX FIXME check frame length 1822 */ 1823 1824 static int 1825 ng_btsocket_rfcomm_receive_frame(ng_btsocket_rfcomm_session_p s, 1826 struct mbuf *m0) 1827 { 1828 struct rfcomm_frame_hdr *hdr = NULL; 1829 struct mbuf *m = NULL; 1830 u_int16_t length; 1831 u_int8_t dlci, type; 1832 int error = 0; 1833 1834 mtx_assert(&s->session_mtx, MA_OWNED); 1835 1836 /* Pullup as much as we can into first mbuf (for direct access) */ 1837 length = min(m0->m_pkthdr.len, MHLEN); 1838 if (m0->m_len < length) { 1839 if ((m0 = m_pullup(m0, length)) == NULL) { 1840 NG_BTSOCKET_RFCOMM_ALERT( 1841 "%s: m_pullup(%d) failed\n", __func__, length); 1842 1843 return (ENOBUFS); 1844 } 1845 } 1846 1847 hdr = mtod(m0, struct rfcomm_frame_hdr *); 1848 dlci = RFCOMM_DLCI(hdr->address); 1849 type = RFCOMM_TYPE(hdr->control); 1850 1851 /* Test EA bit in length. If not set then we have 2 bytes of length */ 1852 if (!RFCOMM_EA(hdr->length)) { 1853 bcopy(&hdr->length, &length, sizeof(length)); 1854 length = le16toh(length) >> 1; 1855 m_adj(m0, sizeof(*hdr) + 1); 1856 } else { 1857 length = hdr->length >> 1; 1858 m_adj(m0, sizeof(*hdr)); 1859 } 1860 1861 NG_BTSOCKET_RFCOMM_INFO( 1862 "%s: Got frame type=%#x, dlci=%d, length=%d, cr=%d, pf=%d, len=%d\n", 1863 __func__, type, dlci, length, RFCOMM_CR(hdr->address), 1864 RFCOMM_PF(hdr->control), m0->m_pkthdr.len); 1865 1866 /* 1867 * Get FCS (the last byte in the frame) 1868 * XXX this will not work if mbuf chain ends with empty mbuf. 1869 * XXX let's hope it never happens :) 1870 */ 1871 1872 for (m = m0; m->m_next != NULL; m = m->m_next) 1873 ; 1874 if (m->m_len <= 0) 1875 panic("%s: Empty mbuf at the end of the chain, len=%d\n", 1876 __func__, m->m_len); 1877 1878 /* 1879 * Check FCS. We only need to calculate FCS on first 2 or 3 bytes 1880 * and already m_pullup'ed mbuf chain, so it should be safe. 1881 */ 1882 1883 if (ng_btsocket_rfcomm_check_fcs((u_int8_t *) hdr, type, m->m_data[m->m_len - 1])) { 1884 NG_BTSOCKET_RFCOMM_ERR( 1885 "%s: Invalid RFCOMM packet. Bad checksum\n", __func__); 1886 NG_FREE_M(m0); 1887 1888 return (EINVAL); 1889 } 1890 1891 m_adj(m0, -1); /* Trim FCS byte */ 1892 1893 /* 1894 * Process RFCOMM frame. 1895 * 1896 * From TS 07.10 spec 1897 * 1898 * "... In the case where a SABM or DISC command with the P bit set 1899 * to 0 is received then the received frame shall be discarded..." 1900 * 1901 * "... If a unsolicited DM response is received then the frame shall 1902 * be processed irrespective of the P/F setting... " 1903 * 1904 * "... The station may transmit response frames with the F bit set 1905 * to 0 at any opportunity on an asynchronous basis. However, in the 1906 * case where a UA response is received with the F bit set to 0 then 1907 * the received frame shall be discarded..." 1908 * 1909 * From Bluetooth spec 1910 * 1911 * "... When credit based flow control is being used, the meaning of 1912 * the P/F bit in the control field of the RFCOMM header is redefined 1913 * for UIH frames..." 1914 */ 1915 1916 switch (type) { 1917 case RFCOMM_FRAME_SABM: 1918 if (RFCOMM_PF(hdr->control)) 1919 error = ng_btsocket_rfcomm_receive_sabm(s, dlci); 1920 break; 1921 1922 case RFCOMM_FRAME_DISC: 1923 if (RFCOMM_PF(hdr->control)) 1924 error = ng_btsocket_rfcomm_receive_disc(s, dlci); 1925 break; 1926 1927 case RFCOMM_FRAME_UA: 1928 if (RFCOMM_PF(hdr->control)) 1929 error = ng_btsocket_rfcomm_receive_ua(s, dlci); 1930 break; 1931 1932 case RFCOMM_FRAME_DM: 1933 error = ng_btsocket_rfcomm_receive_dm(s, dlci); 1934 break; 1935 1936 case RFCOMM_FRAME_UIH: 1937 if (dlci == 0) 1938 error = ng_btsocket_rfcomm_receive_mcc(s, m0); 1939 else 1940 error = ng_btsocket_rfcomm_receive_uih(s, dlci, 1941 RFCOMM_PF(hdr->control), m0); 1942 1943 return (error); 1944 /* NOT REACHED */ 1945 1946 default: 1947 NG_BTSOCKET_RFCOMM_ERR( 1948 "%s: Invalid RFCOMM packet. Unknown type=%#x\n", __func__, type); 1949 error = EINVAL; 1950 break; 1951 } 1952 1953 NG_FREE_M(m0); 1954 1955 return (error); 1956 } /* ng_btsocket_rfcomm_receive_frame */ 1957 1958 /* 1959 * Process RFCOMM SABM frame 1960 */ 1961 1962 static int 1963 ng_btsocket_rfcomm_receive_sabm(ng_btsocket_rfcomm_session_p s, int dlci) 1964 { 1965 ng_btsocket_rfcomm_pcb_p pcb = NULL; 1966 int error = 0; 1967 1968 mtx_assert(&s->session_mtx, MA_OWNED); 1969 1970 NG_BTSOCKET_RFCOMM_INFO( 1971 "%s: Got SABM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 1972 __func__, s->state, s->flags, s->mtu, dlci); 1973 1974 /* DLCI == 0 means open multiplexor channel */ 1975 if (dlci == 0) { 1976 switch (s->state) { 1977 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 1978 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 1979 error = ng_btsocket_rfcomm_send_command(s, 1980 RFCOMM_FRAME_UA, dlci); 1981 if (error == 0) { 1982 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 1983 ng_btsocket_rfcomm_connect_cfm(s); 1984 } else { 1985 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1986 ng_btsocket_rfcomm_session_clean(s); 1987 } 1988 break; 1989 1990 default: 1991 NG_BTSOCKET_RFCOMM_WARN( 1992 "%s: Got SABM for session in invalid state state=%d, flags=%#x\n", 1993 __func__, s->state, s->flags); 1994 error = EINVAL; 1995 break; 1996 } 1997 1998 return (error); 1999 } 2000 2001 /* Make sure multiplexor channel is open */ 2002 if (s->state != NG_BTSOCKET_RFCOMM_SESSION_OPEN) { 2003 NG_BTSOCKET_RFCOMM_ERR( 2004 "%s: Got SABM for dlci=%d with mulitplexor channel closed, state=%d, " \ 2005 "flags=%#x\n", __func__, dlci, s->state, s->flags); 2006 2007 return (EINVAL); 2008 } 2009 2010 /* 2011 * Check if we have this DLCI. This might happen when remote 2012 * peer uses PN command before actual open (SABM) happens. 2013 */ 2014 2015 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2016 if (pcb != NULL) { 2017 mtx_lock(&pcb->pcb_mtx); 2018 2019 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING) { 2020 NG_BTSOCKET_RFCOMM_ERR( 2021 "%s: Got SABM for dlci=%d in invalid state=%d, flags=%#x\n", 2022 __func__, dlci, pcb->state, pcb->flags); 2023 mtx_unlock(&pcb->pcb_mtx); 2024 2025 return (ENOENT); 2026 } 2027 2028 ng_btsocket_rfcomm_untimeout(pcb); 2029 2030 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci); 2031 if (error == 0) 2032 error = ng_btsocket_rfcomm_send_msc(pcb); 2033 2034 if (error == 0) { 2035 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2036 soisconnected(pcb->so); 2037 } else 2038 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2039 2040 mtx_unlock(&pcb->pcb_mtx); 2041 2042 return (error); 2043 } 2044 2045 /* 2046 * We do not have requested DLCI, so it must be an incoming connection 2047 * with default parameters. Try to accept it. 2048 */ 2049 2050 pcb = ng_btsocket_rfcomm_connect_ind(s, RFCOMM_SRVCHANNEL(dlci)); 2051 if (pcb != NULL) { 2052 mtx_lock(&pcb->pcb_mtx); 2053 2054 pcb->dlci = dlci; 2055 2056 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci); 2057 if (error == 0) 2058 error = ng_btsocket_rfcomm_send_msc(pcb); 2059 2060 if (error == 0) { 2061 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2062 soisconnected(pcb->so); 2063 } else 2064 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2065 2066 mtx_unlock(&pcb->pcb_mtx); 2067 } else 2068 /* Nobody is listen()ing on the requested DLCI */ 2069 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2070 2071 return (error); 2072 } /* ng_btsocket_rfcomm_receive_sabm */ 2073 2074 /* 2075 * Process RFCOMM DISC frame 2076 */ 2077 2078 static int 2079 ng_btsocket_rfcomm_receive_disc(ng_btsocket_rfcomm_session_p s, int dlci) 2080 { 2081 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2082 int error = 0; 2083 2084 mtx_assert(&s->session_mtx, MA_OWNED); 2085 2086 NG_BTSOCKET_RFCOMM_INFO( 2087 "%s: Got DISC, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2088 __func__, s->state, s->flags, s->mtu, dlci); 2089 2090 /* DLCI == 0 means close multiplexor channel */ 2091 if (dlci == 0) { 2092 /* XXX FIXME assume that remote side will close the socket */ 2093 error = ng_btsocket_rfcomm_send_command(s, RFCOMM_FRAME_UA, 0); 2094 if (error == 0) { 2095 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING) 2096 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2097 else 2098 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 2099 } else 2100 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2101 2102 ng_btsocket_rfcomm_session_clean(s); 2103 } else { 2104 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2105 if (pcb != NULL) { 2106 int err; 2107 2108 mtx_lock(&pcb->pcb_mtx); 2109 2110 NG_BTSOCKET_RFCOMM_INFO( 2111 "%s: Got DISC for dlci=%d, state=%d, flags=%#x\n", 2112 __func__, dlci, pcb->state, pcb->flags); 2113 2114 error = ng_btsocket_rfcomm_send_command(s, 2115 RFCOMM_FRAME_UA, dlci); 2116 2117 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2118 err = 0; 2119 else 2120 err = ECONNREFUSED; 2121 2122 ng_btsocket_rfcomm_pcb_kill(pcb, err); 2123 2124 mtx_unlock(&pcb->pcb_mtx); 2125 } else { 2126 NG_BTSOCKET_RFCOMM_WARN( 2127 "%s: Got DISC for non-existing dlci=%d\n", __func__, dlci); 2128 2129 error = ng_btsocket_rfcomm_send_command(s, 2130 RFCOMM_FRAME_DM, dlci); 2131 } 2132 } 2133 2134 return (error); 2135 } /* ng_btsocket_rfcomm_receive_disc */ 2136 2137 /* 2138 * Process RFCOMM UA frame 2139 */ 2140 2141 static int 2142 ng_btsocket_rfcomm_receive_ua(ng_btsocket_rfcomm_session_p s, int dlci) 2143 { 2144 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2145 int error = 0; 2146 2147 mtx_assert(&s->session_mtx, MA_OWNED); 2148 2149 NG_BTSOCKET_RFCOMM_INFO( 2150 "%s: Got UA, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2151 __func__, s->state, s->flags, s->mtu, dlci); 2152 2153 /* dlci == 0 means multiplexor channel */ 2154 if (dlci == 0) { 2155 switch (s->state) { 2156 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 2157 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 2158 ng_btsocket_rfcomm_connect_cfm(s); 2159 break; 2160 2161 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 2162 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2163 ng_btsocket_rfcomm_session_clean(s); 2164 break; 2165 2166 default: 2167 NG_BTSOCKET_RFCOMM_WARN( 2168 "%s: Got UA for session in invalid state=%d(%d), flags=%#x, mtu=%d\n", 2169 __func__, s->state, INITIATOR(s), s->flags, 2170 s->mtu); 2171 error = ENOENT; 2172 break; 2173 } 2174 2175 return (error); 2176 } 2177 2178 /* Check if we have this DLCI */ 2179 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2180 if (pcb != NULL) { 2181 mtx_lock(&pcb->pcb_mtx); 2182 2183 NG_BTSOCKET_RFCOMM_INFO( 2184 "%s: Got UA for dlci=%d, state=%d, flags=%#x\n", 2185 __func__, dlci, pcb->state, pcb->flags); 2186 2187 switch (pcb->state) { 2188 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 2189 ng_btsocket_rfcomm_untimeout(pcb); 2190 2191 error = ng_btsocket_rfcomm_send_msc(pcb); 2192 if (error == 0) { 2193 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2194 soisconnected(pcb->so); 2195 } 2196 break; 2197 2198 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 2199 ng_btsocket_rfcomm_pcb_kill(pcb, 0); 2200 break; 2201 2202 default: 2203 NG_BTSOCKET_RFCOMM_WARN( 2204 "%s: Got UA for dlci=%d in invalid state=%d, flags=%#x\n", 2205 __func__, dlci, pcb->state, pcb->flags); 2206 error = ENOENT; 2207 break; 2208 } 2209 2210 mtx_unlock(&pcb->pcb_mtx); 2211 } else { 2212 NG_BTSOCKET_RFCOMM_WARN( 2213 "%s: Got UA for non-existing dlci=%d\n", __func__, dlci); 2214 2215 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2216 } 2217 2218 return (error); 2219 } /* ng_btsocket_rfcomm_receive_ua */ 2220 2221 /* 2222 * Process RFCOMM DM frame 2223 */ 2224 2225 static int 2226 ng_btsocket_rfcomm_receive_dm(ng_btsocket_rfcomm_session_p s, int dlci) 2227 { 2228 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2229 int error; 2230 2231 mtx_assert(&s->session_mtx, MA_OWNED); 2232 2233 NG_BTSOCKET_RFCOMM_INFO( 2234 "%s: Got DM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2235 __func__, s->state, s->flags, s->mtu, dlci); 2236 2237 /* DLCI == 0 means multiplexor channel */ 2238 if (dlci == 0) { 2239 /* Disconnect all dlc's on the session */ 2240 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2241 ng_btsocket_rfcomm_session_clean(s); 2242 } else { 2243 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2244 if (pcb != NULL) { 2245 mtx_lock(&pcb->pcb_mtx); 2246 2247 NG_BTSOCKET_RFCOMM_INFO( 2248 "%s: Got DM for dlci=%d, state=%d, flags=%#x\n", 2249 __func__, dlci, pcb->state, pcb->flags); 2250 2251 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2252 error = ECONNRESET; 2253 else 2254 error = ECONNREFUSED; 2255 2256 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2257 2258 mtx_unlock(&pcb->pcb_mtx); 2259 } else 2260 NG_BTSOCKET_RFCOMM_WARN( 2261 "%s: Got DM for non-existing dlci=%d\n", __func__, dlci); 2262 } 2263 2264 return (0); 2265 } /* ng_btsocket_rfcomm_receive_dm */ 2266 2267 /* 2268 * Process RFCOMM UIH frame (data) 2269 */ 2270 2271 static int 2272 ng_btsocket_rfcomm_receive_uih(ng_btsocket_rfcomm_session_p s, int dlci, 2273 int pf, struct mbuf *m0) 2274 { 2275 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2276 int error = 0; 2277 2278 mtx_assert(&s->session_mtx, MA_OWNED); 2279 2280 NG_BTSOCKET_RFCOMM_INFO( 2281 "%s: Got UIH, session state=%d, flags=%#x, mtu=%d, dlci=%d, pf=%d, len=%d\n", 2282 __func__, s->state, s->flags, s->mtu, dlci, pf, 2283 m0->m_pkthdr.len); 2284 2285 /* XXX should we do it here? Check for session flow control */ 2286 if (s->flags & NG_BTSOCKET_RFCOMM_SESSION_LFC) { 2287 NG_BTSOCKET_RFCOMM_WARN( 2288 "%s: Got UIH with session flow control asserted, state=%d, flags=%#x\n", 2289 __func__, s->state, s->flags); 2290 goto drop; 2291 } 2292 2293 /* Check if we have this dlci */ 2294 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2295 if (pcb == NULL) { 2296 NG_BTSOCKET_RFCOMM_WARN( 2297 "%s: Got UIH for non-existing dlci=%d\n", __func__, dlci); 2298 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2299 goto drop; 2300 } 2301 2302 mtx_lock(&pcb->pcb_mtx); 2303 2304 /* Check dlci state */ 2305 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2306 NG_BTSOCKET_RFCOMM_WARN( 2307 "%s: Got UIH for dlci=%d in invalid state=%d, flags=%#x\n", 2308 __func__, dlci, pcb->state, pcb->flags); 2309 error = EINVAL; 2310 goto drop1; 2311 } 2312 2313 /* Check dlci flow control */ 2314 if (((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pcb->rx_cred <= 0) || 2315 (pcb->lmodem & RFCOMM_MODEM_FC)) { 2316 NG_BTSOCKET_RFCOMM_ERR( 2317 "%s: Got UIH for dlci=%d with asserted flow control, state=%d, " \ 2318 "flags=%#x, rx_cred=%d, lmodem=%#x\n", 2319 __func__, dlci, pcb->state, pcb->flags, 2320 pcb->rx_cred, pcb->lmodem); 2321 goto drop1; 2322 } 2323 2324 /* Did we get any credits? */ 2325 if ((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pf) { 2326 NG_BTSOCKET_RFCOMM_INFO( 2327 "%s: Got %d more credits for dlci=%d, state=%d, flags=%#x, " \ 2328 "rx_cred=%d, tx_cred=%d\n", 2329 __func__, *mtod(m0, u_int8_t *), dlci, pcb->state, 2330 pcb->flags, pcb->rx_cred, pcb->tx_cred); 2331 2332 pcb->tx_cred += *mtod(m0, u_int8_t *); 2333 m_adj(m0, 1); 2334 2335 /* Send more from the DLC. XXX check for errors? */ 2336 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2337 } 2338 2339 /* OK the of the rest of the mbuf is the data */ 2340 if (m0->m_pkthdr.len > 0) { 2341 /* If we are using credit flow control decrease rx_cred here */ 2342 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2343 /* Give remote peer more credits (if needed) */ 2344 if (-- pcb->rx_cred <= RFCOMM_MAX_CREDITS / 2) 2345 ng_btsocket_rfcomm_send_credits(pcb); 2346 else 2347 NG_BTSOCKET_RFCOMM_INFO( 2348 "%s: Remote side still has credits, dlci=%d, state=%d, flags=%#x, " \ 2349 "rx_cred=%d, tx_cred=%d\n", __func__, dlci, pcb->state, pcb->flags, 2350 pcb->rx_cred, pcb->tx_cred); 2351 } 2352 2353 /* Check packet against mtu on dlci */ 2354 if (m0->m_pkthdr.len > pcb->mtu) { 2355 NG_BTSOCKET_RFCOMM_ERR( 2356 "%s: Got oversized UIH for dlci=%d, state=%d, flags=%#x, mtu=%d, len=%d\n", 2357 __func__, dlci, pcb->state, pcb->flags, 2358 pcb->mtu, m0->m_pkthdr.len); 2359 2360 error = EMSGSIZE; 2361 } else if (m0->m_pkthdr.len > sbspace(&pcb->so->so_rcv)) { 2362 2363 /* 2364 * This is really bad. Receive queue on socket does 2365 * not have enough space for the packet. We do not 2366 * have any other choice but drop the packet. 2367 */ 2368 2369 NG_BTSOCKET_RFCOMM_ERR( 2370 "%s: Not enough space in socket receive queue. Dropping UIH for dlci=%d, " \ 2371 "state=%d, flags=%#x, len=%d, space=%ld\n", 2372 __func__, dlci, pcb->state, pcb->flags, 2373 m0->m_pkthdr.len, sbspace(&pcb->so->so_rcv)); 2374 2375 error = ENOBUFS; 2376 } else { 2377 /* Append packet to the socket receive queue */ 2378 sbappend(&pcb->so->so_rcv, m0, 0); 2379 m0 = NULL; 2380 2381 sorwakeup(pcb->so); 2382 } 2383 } 2384 drop1: 2385 mtx_unlock(&pcb->pcb_mtx); 2386 drop: 2387 NG_FREE_M(m0); /* checks for != NULL */ 2388 2389 return (error); 2390 } /* ng_btsocket_rfcomm_receive_uih */ 2391 2392 /* 2393 * Process RFCOMM MCC command (Multiplexor) 2394 * 2395 * From TS 07.10 spec 2396 * 2397 * "5.4.3.1 Information Data 2398 * 2399 * ...The frames (UIH) sent by the initiating station have the C/R bit set 2400 * to 1 and those sent by the responding station have the C/R bit set to 0..." 2401 * 2402 * "5.4.6.2 Operating procedures 2403 * 2404 * Messages always exist in pairs; a command message and a corresponding 2405 * response message. If the C/R bit is set to 1 the message is a command, 2406 * if it is set to 0 the message is a response... 2407 * 2408 * ... 2409 * 2410 * NOTE: Notice that when UIH frames are used to convey information on DLCI 0 2411 * there are at least two different fields that contain a C/R bit, and the 2412 * bits are set of different form. The C/R bit in the Type field shall be set 2413 * as it is stated above, while the C/R bit in the Address field (see subclause 2414 * 5.2.1.2) shall be set as it is described in subclause 5.4.3.1." 2415 */ 2416 2417 static int 2418 ng_btsocket_rfcomm_receive_mcc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2419 { 2420 struct rfcomm_mcc_hdr *hdr = NULL; 2421 u_int8_t cr, type, length; 2422 2423 mtx_assert(&s->session_mtx, MA_OWNED); 2424 2425 /* 2426 * We can access data directly in the first mbuf, because we have 2427 * m_pullup()'ed mbuf chain in ng_btsocket_rfcomm_receive_frame(). 2428 * All MCC commands should fit into single mbuf (except probably TEST). 2429 */ 2430 2431 hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2432 cr = RFCOMM_CR(hdr->type); 2433 type = RFCOMM_MCC_TYPE(hdr->type); 2434 length = RFCOMM_MCC_LENGTH(hdr->length); 2435 2436 /* Check MCC frame length */ 2437 if (sizeof(*hdr) + length != m0->m_pkthdr.len) { 2438 NG_BTSOCKET_RFCOMM_ERR( 2439 "%s: Invalid MCC frame length=%d, len=%d\n", 2440 __func__, length, m0->m_pkthdr.len); 2441 NG_FREE_M(m0); 2442 2443 return (EMSGSIZE); 2444 } 2445 2446 switch (type) { 2447 case RFCOMM_MCC_TEST: 2448 return (ng_btsocket_rfcomm_receive_test(s, m0)); 2449 /* NOT REACHED */ 2450 2451 case RFCOMM_MCC_FCON: 2452 case RFCOMM_MCC_FCOFF: 2453 return (ng_btsocket_rfcomm_receive_fc(s, m0)); 2454 /* NOT REACHED */ 2455 2456 case RFCOMM_MCC_MSC: 2457 return (ng_btsocket_rfcomm_receive_msc(s, m0)); 2458 /* NOT REACHED */ 2459 2460 case RFCOMM_MCC_RPN: 2461 return (ng_btsocket_rfcomm_receive_rpn(s, m0)); 2462 /* NOT REACHED */ 2463 2464 case RFCOMM_MCC_RLS: 2465 return (ng_btsocket_rfcomm_receive_rls(s, m0)); 2466 /* NOT REACHED */ 2467 2468 case RFCOMM_MCC_PN: 2469 return (ng_btsocket_rfcomm_receive_pn(s, m0)); 2470 /* NOT REACHED */ 2471 2472 case RFCOMM_MCC_NSC: 2473 NG_BTSOCKET_RFCOMM_ERR( 2474 "%s: Got MCC NSC, type=%#x, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2475 "mtu=%d, len=%d\n", __func__, RFCOMM_MCC_TYPE(*((u_int8_t *)(hdr + 1))), cr, 2476 length, s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2477 NG_FREE_M(m0); 2478 break; 2479 2480 default: 2481 NG_BTSOCKET_RFCOMM_ERR( 2482 "%s: Got unknown MCC, type=%#x, cr=%d, length=%d, session state=%d, " \ 2483 "flags=%#x, mtu=%d, len=%d\n", 2484 __func__, type, cr, length, s->state, s->flags, 2485 s->mtu, m0->m_pkthdr.len); 2486 2487 /* Reuse mbuf to send NSC */ 2488 hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2489 m0->m_pkthdr.len = m0->m_len = sizeof(*hdr); 2490 2491 /* Create MCC NSC header */ 2492 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_NSC); 2493 hdr->length = RFCOMM_MKLEN8(1); 2494 2495 /* Put back MCC command type we did not like */ 2496 m0->m_data[m0->m_len] = RFCOMM_MKMCC_TYPE(cr, type); 2497 m0->m_pkthdr.len ++; 2498 m0->m_len ++; 2499 2500 /* Send UIH frame */ 2501 return (ng_btsocket_rfcomm_send_uih(s, 2502 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0)); 2503 /* NOT REACHED */ 2504 } 2505 2506 return (0); 2507 } /* ng_btsocket_rfcomm_receive_mcc */ 2508 2509 /* 2510 * Receive RFCOMM TEST MCC command 2511 */ 2512 2513 static int 2514 ng_btsocket_rfcomm_receive_test(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2515 { 2516 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2517 int error = 0; 2518 2519 mtx_assert(&s->session_mtx, MA_OWNED); 2520 2521 NG_BTSOCKET_RFCOMM_INFO( 2522 "%s: Got MCC TEST, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \ 2523 "len=%d\n", __func__, RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2524 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2525 2526 if (RFCOMM_CR(hdr->type)) { 2527 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_TEST); 2528 error = ng_btsocket_rfcomm_send_uih(s, 2529 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2530 } else 2531 NG_FREE_M(m0); /* XXX ignore response */ 2532 2533 return (error); 2534 } /* ng_btsocket_rfcomm_receive_test */ 2535 2536 /* 2537 * Receive RFCOMM FCON/FCOFF MCC command 2538 */ 2539 2540 static int 2541 ng_btsocket_rfcomm_receive_fc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2542 { 2543 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2544 u_int8_t type = RFCOMM_MCC_TYPE(hdr->type); 2545 int error = 0; 2546 2547 mtx_assert(&s->session_mtx, MA_OWNED); 2548 2549 /* 2550 * Turn ON/OFF aggregate flow on the entire session. When remote peer 2551 * asserted flow control no transmission shall occur except on dlci 0 2552 * (control channel). 2553 */ 2554 2555 NG_BTSOCKET_RFCOMM_INFO( 2556 "%s: Got MCC FC%s, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \ 2557 "len=%d\n", __func__, (type == RFCOMM_MCC_FCON)? "ON" : "OFF", 2558 RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2559 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2560 2561 if (RFCOMM_CR(hdr->type)) { 2562 if (type == RFCOMM_MCC_FCON) 2563 s->flags &= ~NG_BTSOCKET_RFCOMM_SESSION_RFC; 2564 else 2565 s->flags |= NG_BTSOCKET_RFCOMM_SESSION_RFC; 2566 2567 hdr->type = RFCOMM_MKMCC_TYPE(0, type); 2568 error = ng_btsocket_rfcomm_send_uih(s, 2569 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2570 } else 2571 NG_FREE_M(m0); /* XXX ignore response */ 2572 2573 return (error); 2574 } /* ng_btsocket_rfcomm_receive_fc */ 2575 2576 /* 2577 * Receive RFCOMM MSC MCC command 2578 */ 2579 2580 static int 2581 ng_btsocket_rfcomm_receive_msc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2582 { 2583 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr*); 2584 struct rfcomm_mcc_msc *msc = (struct rfcomm_mcc_msc *)(hdr+1); 2585 ng_btsocket_rfcomm_pcb_t *pcb = NULL; 2586 int error = 0; 2587 2588 mtx_assert(&s->session_mtx, MA_OWNED); 2589 2590 NG_BTSOCKET_RFCOMM_INFO( 2591 "%s: Got MCC MSC, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2592 "mtu=%d, len=%d\n", 2593 __func__, RFCOMM_DLCI(msc->address), RFCOMM_CR(hdr->type), 2594 RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags, 2595 s->mtu, m0->m_pkthdr.len); 2596 2597 if (RFCOMM_CR(hdr->type)) { 2598 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, RFCOMM_DLCI(msc->address)); 2599 if (pcb == NULL) { 2600 NG_BTSOCKET_RFCOMM_WARN( 2601 "%s: Got MSC command for non-existing dlci=%d\n", 2602 __func__, RFCOMM_DLCI(msc->address)); 2603 NG_FREE_M(m0); 2604 2605 return (ENOENT); 2606 } 2607 2608 mtx_lock(&pcb->pcb_mtx); 2609 2610 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING && 2611 pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2612 NG_BTSOCKET_RFCOMM_WARN( 2613 "%s: Got MSC on dlci=%d in invalid state=%d\n", 2614 __func__, RFCOMM_DLCI(msc->address), 2615 pcb->state); 2616 2617 mtx_unlock(&pcb->pcb_mtx); 2618 NG_FREE_M(m0); 2619 2620 return (EINVAL); 2621 } 2622 2623 pcb->rmodem = msc->modem; /* Update remote port signals */ 2624 2625 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_MSC); 2626 error = ng_btsocket_rfcomm_send_uih(s, 2627 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2628 2629 #if 0 /* YYY */ 2630 /* Send more data from DLC. XXX check for errors? */ 2631 if (!(pcb->rmodem & RFCOMM_MODEM_FC) && 2632 !(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)) 2633 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2634 #endif /* YYY */ 2635 2636 mtx_unlock(&pcb->pcb_mtx); 2637 } else 2638 NG_FREE_M(m0); /* XXX ignore response */ 2639 2640 return (error); 2641 } /* ng_btsocket_rfcomm_receive_msc */ 2642 2643 /* 2644 * Receive RFCOMM RPN MCC command 2645 * XXX FIXME do we need htole16/le16toh for RPN param_mask? 2646 */ 2647 2648 static int 2649 ng_btsocket_rfcomm_receive_rpn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2650 { 2651 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2652 struct rfcomm_mcc_rpn *rpn = (struct rfcomm_mcc_rpn *)(hdr + 1); 2653 int error = 0; 2654 u_int16_t param_mask; 2655 u_int8_t bit_rate, data_bits, stop_bits, parity, 2656 flow_control, xon_char, xoff_char; 2657 2658 mtx_assert(&s->session_mtx, MA_OWNED); 2659 2660 NG_BTSOCKET_RFCOMM_INFO( 2661 "%s: Got MCC RPN, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2662 "mtu=%d, len=%d\n", 2663 __func__, RFCOMM_DLCI(rpn->dlci), RFCOMM_CR(hdr->type), 2664 RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags, 2665 s->mtu, m0->m_pkthdr.len); 2666 2667 if (RFCOMM_CR(hdr->type)) { 2668 param_mask = RFCOMM_RPN_PM_ALL; 2669 2670 if (RFCOMM_MCC_LENGTH(hdr->length) == 1) { 2671 /* Request - return default setting */ 2672 bit_rate = RFCOMM_RPN_BR_115200; 2673 data_bits = RFCOMM_RPN_DATA_8; 2674 stop_bits = RFCOMM_RPN_STOP_1; 2675 parity = RFCOMM_RPN_PARITY_NONE; 2676 flow_control = RFCOMM_RPN_FLOW_NONE; 2677 xon_char = RFCOMM_RPN_XON_CHAR; 2678 xoff_char = RFCOMM_RPN_XOFF_CHAR; 2679 } else { 2680 /* 2681 * Ignore/accept bit_rate, 8 bits, 1 stop bit, no 2682 * parity, no flow control lines, default XON/XOFF 2683 * chars. 2684 */ 2685 2686 bit_rate = rpn->bit_rate; 2687 rpn->param_mask = le16toh(rpn->param_mask); /* XXX */ 2688 2689 data_bits = RFCOMM_RPN_DATA_BITS(rpn->line_settings); 2690 if (rpn->param_mask & RFCOMM_RPN_PM_DATA && 2691 data_bits != RFCOMM_RPN_DATA_8) { 2692 data_bits = RFCOMM_RPN_DATA_8; 2693 param_mask ^= RFCOMM_RPN_PM_DATA; 2694 } 2695 2696 stop_bits = RFCOMM_RPN_STOP_BITS(rpn->line_settings); 2697 if (rpn->param_mask & RFCOMM_RPN_PM_STOP && 2698 stop_bits != RFCOMM_RPN_STOP_1) { 2699 stop_bits = RFCOMM_RPN_STOP_1; 2700 param_mask ^= RFCOMM_RPN_PM_STOP; 2701 } 2702 2703 parity = RFCOMM_RPN_PARITY(rpn->line_settings); 2704 if (rpn->param_mask & RFCOMM_RPN_PM_PARITY && 2705 parity != RFCOMM_RPN_PARITY_NONE) { 2706 parity = RFCOMM_RPN_PARITY_NONE; 2707 param_mask ^= RFCOMM_RPN_PM_PARITY; 2708 } 2709 2710 flow_control = rpn->flow_control; 2711 if (rpn->param_mask & RFCOMM_RPN_PM_FLOW && 2712 flow_control != RFCOMM_RPN_FLOW_NONE) { 2713 flow_control = RFCOMM_RPN_FLOW_NONE; 2714 param_mask ^= RFCOMM_RPN_PM_FLOW; 2715 } 2716 2717 xon_char = rpn->xon_char; 2718 if (rpn->param_mask & RFCOMM_RPN_PM_XON && 2719 xon_char != RFCOMM_RPN_XON_CHAR) { 2720 xon_char = RFCOMM_RPN_XON_CHAR; 2721 param_mask ^= RFCOMM_RPN_PM_XON; 2722 } 2723 2724 xoff_char = rpn->xoff_char; 2725 if (rpn->param_mask & RFCOMM_RPN_PM_XOFF && 2726 xoff_char != RFCOMM_RPN_XOFF_CHAR) { 2727 xoff_char = RFCOMM_RPN_XOFF_CHAR; 2728 param_mask ^= RFCOMM_RPN_PM_XOFF; 2729 } 2730 } 2731 2732 rpn->bit_rate = bit_rate; 2733 rpn->line_settings = RFCOMM_MKRPN_LINE_SETTINGS(data_bits, 2734 stop_bits, parity); 2735 rpn->flow_control = flow_control; 2736 rpn->xon_char = xon_char; 2737 rpn->xoff_char = xoff_char; 2738 rpn->param_mask = htole16(param_mask); /* XXX */ 2739 2740 m0->m_pkthdr.len = m0->m_len = sizeof(*hdr) + sizeof(*rpn); 2741 2742 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RPN); 2743 error = ng_btsocket_rfcomm_send_uih(s, 2744 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2745 } else 2746 NG_FREE_M(m0); /* XXX ignore response */ 2747 2748 return (error); 2749 } /* ng_btsocket_rfcomm_receive_rpn */ 2750 2751 /* 2752 * Receive RFCOMM RLS MCC command 2753 */ 2754 2755 static int 2756 ng_btsocket_rfcomm_receive_rls(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2757 { 2758 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2759 struct rfcomm_mcc_rls *rls = (struct rfcomm_mcc_rls *)(hdr + 1); 2760 int error = 0; 2761 2762 mtx_assert(&s->session_mtx, MA_OWNED); 2763 2764 /* 2765 * XXX FIXME Do we have to do anything else here? Remote peer tries to 2766 * tell us something about DLCI. Just report what we have received and 2767 * return back received values as required by TS 07.10 spec. 2768 */ 2769 2770 NG_BTSOCKET_RFCOMM_INFO( 2771 "%s: Got MCC RLS, dlci=%d, status=%#x, cr=%d, length=%d, session state=%d, " \ 2772 "flags=%#x, mtu=%d, len=%d\n", 2773 __func__, RFCOMM_DLCI(rls->address), rls->status, 2774 RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2775 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2776 2777 if (RFCOMM_CR(hdr->type)) { 2778 if (rls->status & 0x1) 2779 NG_BTSOCKET_RFCOMM_ERR( 2780 "%s: Got RLS dlci=%d, error=%#x\n", __func__, RFCOMM_DLCI(rls->address), 2781 rls->status >> 1); 2782 2783 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RLS); 2784 error = ng_btsocket_rfcomm_send_uih(s, 2785 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2786 } else 2787 NG_FREE_M(m0); /* XXX ignore responses */ 2788 2789 return (error); 2790 } /* ng_btsocket_rfcomm_receive_rls */ 2791 2792 /* 2793 * Receive RFCOMM PN MCC command 2794 */ 2795 2796 static int 2797 ng_btsocket_rfcomm_receive_pn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2798 { 2799 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr*); 2800 struct rfcomm_mcc_pn *pn = (struct rfcomm_mcc_pn *)(hdr+1); 2801 ng_btsocket_rfcomm_pcb_t *pcb = NULL; 2802 int error = 0; 2803 2804 mtx_assert(&s->session_mtx, MA_OWNED); 2805 2806 NG_BTSOCKET_RFCOMM_INFO( 2807 "%s: Got MCC PN, dlci=%d, cr=%d, length=%d, flow_control=%#x, priority=%d, " \ 2808 "ack_timer=%d, mtu=%d, max_retrans=%d, credits=%d, session state=%d, " \ 2809 "flags=%#x, session mtu=%d, len=%d\n", 2810 __func__, pn->dlci, RFCOMM_CR(hdr->type), 2811 RFCOMM_MCC_LENGTH(hdr->length), pn->flow_control, pn->priority, 2812 pn->ack_timer, le16toh(pn->mtu), pn->max_retrans, pn->credits, 2813 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2814 2815 if (pn->dlci == 0) { 2816 NG_BTSOCKET_RFCOMM_ERR("%s: Zero dlci in MCC PN\n", __func__); 2817 NG_FREE_M(m0); 2818 2819 return (EINVAL); 2820 } 2821 2822 /* Check if we have this dlci */ 2823 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, pn->dlci); 2824 if (pcb != NULL) { 2825 mtx_lock(&pcb->pcb_mtx); 2826 2827 if (RFCOMM_CR(hdr->type)) { 2828 /* PN Request */ 2829 ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control, 2830 pn->credits, pn->mtu); 2831 2832 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2833 pn->flow_control = 0xe0; 2834 pn->credits = RFCOMM_DEFAULT_CREDITS; 2835 } else { 2836 pn->flow_control = 0; 2837 pn->credits = 0; 2838 } 2839 2840 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN); 2841 error = ng_btsocket_rfcomm_send_uih(s, 2842 RFCOMM_MKADDRESS(INITIATOR(s), 0), 2843 0, 0, m0); 2844 } else { 2845 /* PN Response - proceed with SABM. Timeout still set */ 2846 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONFIGURING) { 2847 ng_btsocket_rfcomm_set_pn(pcb, 0, 2848 pn->flow_control, pn->credits, pn->mtu); 2849 2850 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING; 2851 error = ng_btsocket_rfcomm_send_command(s, 2852 RFCOMM_FRAME_SABM, pn->dlci); 2853 } else 2854 NG_BTSOCKET_RFCOMM_WARN( 2855 "%s: Got PN response for dlci=%d in invalid state=%d\n", 2856 __func__, pn->dlci, pcb->state); 2857 2858 NG_FREE_M(m0); 2859 } 2860 2861 mtx_unlock(&pcb->pcb_mtx); 2862 } else if (RFCOMM_CR(hdr->type)) { 2863 /* PN request to non-existing dlci - incoming connection */ 2864 pcb = ng_btsocket_rfcomm_connect_ind(s, 2865 RFCOMM_SRVCHANNEL(pn->dlci)); 2866 if (pcb != NULL) { 2867 mtx_lock(&pcb->pcb_mtx); 2868 2869 pcb->dlci = pn->dlci; 2870 2871 ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control, 2872 pn->credits, pn->mtu); 2873 2874 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2875 pn->flow_control = 0xe0; 2876 pn->credits = RFCOMM_DEFAULT_CREDITS; 2877 } else { 2878 pn->flow_control = 0; 2879 pn->credits = 0; 2880 } 2881 2882 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN); 2883 error = ng_btsocket_rfcomm_send_uih(s, 2884 RFCOMM_MKADDRESS(INITIATOR(s), 0), 2885 0, 0, m0); 2886 2887 if (error == 0) { 2888 ng_btsocket_rfcomm_timeout(pcb); 2889 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING; 2890 soisconnecting(pcb->so); 2891 } else 2892 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2893 2894 mtx_unlock(&pcb->pcb_mtx); 2895 } else { 2896 /* Nobody is listen()ing on this channel */ 2897 error = ng_btsocket_rfcomm_send_command(s, 2898 RFCOMM_FRAME_DM, pn->dlci); 2899 NG_FREE_M(m0); 2900 } 2901 } else 2902 NG_FREE_M(m0); /* XXX ignore response to non-existing dlci */ 2903 2904 return (error); 2905 } /* ng_btsocket_rfcomm_receive_pn */ 2906 2907 /* 2908 * Set PN parameters for dlci. Caller must hold pcb->pcb_mtx. 2909 * 2910 * From Bluetooth spec. 2911 * 2912 * "... The CL1 - CL4 field is completely redefined. (In TS07.10 this defines 2913 * the convergence layer to use, which is not applicable to RFCOMM. In RFCOMM, 2914 * in Bluetooth versions up to 1.0B, this field was forced to 0). 2915 * 2916 * In the PN request sent prior to a DLC establishment, this field must contain 2917 * the value 15 (0xF), indicating support of credit based flow control in the 2918 * sender. See Table 5.3 below. If the PN response contains any other value 2919 * than 14 (0xE) in this field, it is inferred that the peer RFCOMM entity is 2920 * not supporting the credit based flow control feature. (This is only possible 2921 * if the peer RFCOMM implementation is only conforming to Bluetooth version 2922 * 1.0B.) If a PN request is sent on an already open DLC, then this field must 2923 * contain the value zero; it is not possible to set initial credits more 2924 * than once per DLC activation. A responding implementation must set this 2925 * field in the PN response to 14 (0xE), if (and only if) the value in the PN 2926 * request was 15..." 2927 */ 2928 2929 static void 2930 ng_btsocket_rfcomm_set_pn(ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr, 2931 u_int8_t flow_control, u_int8_t credits, u_int16_t mtu) 2932 { 2933 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 2934 2935 pcb->mtu = le16toh(mtu); 2936 2937 if (cr) { 2938 if (flow_control == 0xf0) { 2939 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC; 2940 pcb->tx_cred = credits; 2941 } else { 2942 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC; 2943 pcb->tx_cred = 0; 2944 } 2945 } else { 2946 if (flow_control == 0xe0) { 2947 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC; 2948 pcb->tx_cred = credits; 2949 } else { 2950 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC; 2951 pcb->tx_cred = 0; 2952 } 2953 } 2954 2955 NG_BTSOCKET_RFCOMM_INFO( 2956 "%s: cr=%d, dlci=%d, state=%d, flags=%#x, mtu=%d, rx_cred=%d, tx_cred=%d\n", 2957 __func__, cr, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 2958 pcb->rx_cred, pcb->tx_cred); 2959 } /* ng_btsocket_rfcomm_set_pn */ 2960 2961 /* 2962 * Send RFCOMM SABM/DISC/UA/DM frames. Caller must hold s->session_mtx 2963 */ 2964 2965 static int 2966 ng_btsocket_rfcomm_send_command(ng_btsocket_rfcomm_session_p s, 2967 u_int8_t type, u_int8_t dlci) 2968 { 2969 struct rfcomm_cmd_hdr *hdr = NULL; 2970 struct mbuf *m = NULL; 2971 int cr; 2972 2973 mtx_assert(&s->session_mtx, MA_OWNED); 2974 2975 NG_BTSOCKET_RFCOMM_INFO( 2976 "%s: Sending command type %#x, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2977 __func__, type, s->state, s->flags, s->mtu, dlci); 2978 2979 switch (type) { 2980 case RFCOMM_FRAME_SABM: 2981 case RFCOMM_FRAME_DISC: 2982 cr = INITIATOR(s); 2983 break; 2984 2985 case RFCOMM_FRAME_UA: 2986 case RFCOMM_FRAME_DM: 2987 cr = !INITIATOR(s); 2988 break; 2989 2990 default: 2991 panic("%s: Invalid frame type=%#x\n", __func__, type); 2992 return (EINVAL); 2993 /* NOT REACHED */ 2994 } 2995 2996 MGETHDR(m, M_NOWAIT, MT_DATA); 2997 if (m == NULL) 2998 return (ENOBUFS); 2999 3000 m->m_pkthdr.len = m->m_len = sizeof(*hdr); 3001 3002 hdr = mtod(m, struct rfcomm_cmd_hdr *); 3003 hdr->address = RFCOMM_MKADDRESS(cr, dlci); 3004 hdr->control = RFCOMM_MKCONTROL(type, 1); 3005 hdr->length = RFCOMM_MKLEN8(0); 3006 hdr->fcs = ng_btsocket_rfcomm_fcs3((u_int8_t *) hdr); 3007 3008 NG_BT_MBUFQ_ENQUEUE(&s->outq, m); 3009 3010 return (0); 3011 } /* ng_btsocket_rfcomm_send_command */ 3012 3013 /* 3014 * Send RFCOMM UIH frame. Caller must hold s->session_mtx 3015 */ 3016 3017 static int 3018 ng_btsocket_rfcomm_send_uih(ng_btsocket_rfcomm_session_p s, u_int8_t address, 3019 u_int8_t pf, u_int8_t credits, struct mbuf *data) 3020 { 3021 struct rfcomm_frame_hdr *hdr = NULL; 3022 struct mbuf *m = NULL, *mcrc = NULL; 3023 u_int16_t length; 3024 3025 mtx_assert(&s->session_mtx, MA_OWNED); 3026 3027 MGETHDR(m, M_NOWAIT, MT_DATA); 3028 if (m == NULL) { 3029 NG_FREE_M(data); 3030 return (ENOBUFS); 3031 } 3032 m->m_pkthdr.len = m->m_len = sizeof(*hdr); 3033 3034 MGET(mcrc, M_NOWAIT, MT_DATA); 3035 if (mcrc == NULL) { 3036 NG_FREE_M(data); 3037 return (ENOBUFS); 3038 } 3039 mcrc->m_len = 1; 3040 3041 /* Fill UIH frame header */ 3042 hdr = mtod(m, struct rfcomm_frame_hdr *); 3043 hdr->address = address; 3044 hdr->control = RFCOMM_MKCONTROL(RFCOMM_FRAME_UIH, pf); 3045 3046 /* Calculate FCS */ 3047 mcrc->m_data[0] = ng_btsocket_rfcomm_fcs2((u_int8_t *) hdr); 3048 3049 /* Put length back */ 3050 length = (data != NULL)? data->m_pkthdr.len : 0; 3051 if (length > 127) { 3052 u_int16_t l = htole16(RFCOMM_MKLEN16(length)); 3053 3054 bcopy(&l, &hdr->length, sizeof(l)); 3055 m->m_pkthdr.len ++; 3056 m->m_len ++; 3057 } else 3058 hdr->length = RFCOMM_MKLEN8(length); 3059 3060 if (pf) { 3061 m->m_data[m->m_len] = credits; 3062 m->m_pkthdr.len ++; 3063 m->m_len ++; 3064 } 3065 3066 /* Add payload */ 3067 if (data != NULL) { 3068 m_cat(m, data); 3069 m->m_pkthdr.len += length; 3070 } 3071 3072 /* Put FCS back */ 3073 m_cat(m, mcrc); 3074 m->m_pkthdr.len ++; 3075 3076 NG_BTSOCKET_RFCOMM_INFO( 3077 "%s: Sending UIH state=%d, flags=%#x, address=%d, length=%d, pf=%d, " \ 3078 "credits=%d, len=%d\n", 3079 __func__, s->state, s->flags, address, length, pf, credits, 3080 m->m_pkthdr.len); 3081 3082 NG_BT_MBUFQ_ENQUEUE(&s->outq, m); 3083 3084 return (0); 3085 } /* ng_btsocket_rfcomm_send_uih */ 3086 3087 /* 3088 * Send MSC request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3089 */ 3090 3091 static int 3092 ng_btsocket_rfcomm_send_msc(ng_btsocket_rfcomm_pcb_p pcb) 3093 { 3094 struct mbuf *m = NULL; 3095 struct rfcomm_mcc_hdr *hdr = NULL; 3096 struct rfcomm_mcc_msc *msc = NULL; 3097 3098 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3099 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3100 3101 MGETHDR(m, M_NOWAIT, MT_DATA); 3102 if (m == NULL) 3103 return (ENOBUFS); 3104 3105 m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*msc); 3106 3107 hdr = mtod(m, struct rfcomm_mcc_hdr *); 3108 msc = (struct rfcomm_mcc_msc *)(hdr + 1); 3109 3110 hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_MSC); 3111 hdr->length = RFCOMM_MKLEN8(sizeof(*msc)); 3112 3113 msc->address = RFCOMM_MKADDRESS(1, pcb->dlci); 3114 msc->modem = pcb->lmodem; 3115 3116 NG_BTSOCKET_RFCOMM_INFO( 3117 "%s: Sending MSC dlci=%d, state=%d, flags=%#x, address=%d, modem=%#x\n", 3118 __func__, pcb->dlci, pcb->state, pcb->flags, msc->address, 3119 msc->modem); 3120 3121 return (ng_btsocket_rfcomm_send_uih(pcb->session, 3122 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m)); 3123 } /* ng_btsocket_rfcomm_send_msc */ 3124 3125 /* 3126 * Send PN request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3127 */ 3128 3129 static int 3130 ng_btsocket_rfcomm_send_pn(ng_btsocket_rfcomm_pcb_p pcb) 3131 { 3132 struct mbuf *m = NULL; 3133 struct rfcomm_mcc_hdr *hdr = NULL; 3134 struct rfcomm_mcc_pn *pn = NULL; 3135 3136 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3137 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3138 3139 MGETHDR(m, M_NOWAIT, MT_DATA); 3140 if (m == NULL) 3141 return (ENOBUFS); 3142 3143 m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*pn); 3144 3145 hdr = mtod(m, struct rfcomm_mcc_hdr *); 3146 pn = (struct rfcomm_mcc_pn *)(hdr + 1); 3147 3148 hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_PN); 3149 hdr->length = RFCOMM_MKLEN8(sizeof(*pn)); 3150 3151 pn->dlci = pcb->dlci; 3152 3153 /* 3154 * Set default DLCI priority as described in GSM 07.10 3155 * (ETSI TS 101 369) clause 5.6 page 42 3156 */ 3157 3158 pn->priority = (pcb->dlci < 56)? (((pcb->dlci >> 3) << 3) + 7) : 61; 3159 pn->ack_timer = 0; 3160 pn->mtu = htole16(pcb->mtu); 3161 pn->max_retrans = 0; 3162 3163 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 3164 pn->flow_control = 0xf0; 3165 pn->credits = pcb->rx_cred; 3166 } else { 3167 pn->flow_control = 0; 3168 pn->credits = 0; 3169 } 3170 3171 NG_BTSOCKET_RFCOMM_INFO( 3172 "%s: Sending PN dlci=%d, state=%d, flags=%#x, mtu=%d, flow_control=%#x, " \ 3173 "credits=%d\n", __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 3174 pn->flow_control, pn->credits); 3175 3176 return (ng_btsocket_rfcomm_send_uih(pcb->session, 3177 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m)); 3178 } /* ng_btsocket_rfcomm_send_pn */ 3179 3180 /* 3181 * Calculate and send credits based on available space in receive buffer 3182 */ 3183 3184 static int 3185 ng_btsocket_rfcomm_send_credits(ng_btsocket_rfcomm_pcb_p pcb) 3186 { 3187 int error = 0; 3188 u_int8_t credits; 3189 3190 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3191 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3192 3193 NG_BTSOCKET_RFCOMM_INFO( 3194 "%s: Sending more credits, dlci=%d, state=%d, flags=%#x, mtu=%d, " \ 3195 "space=%ld, tx_cred=%d, rx_cred=%d\n", 3196 __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 3197 sbspace(&pcb->so->so_rcv), pcb->tx_cred, pcb->rx_cred); 3198 3199 credits = sbspace(&pcb->so->so_rcv) / pcb->mtu; 3200 if (credits > 0) { 3201 if (pcb->rx_cred + credits > RFCOMM_MAX_CREDITS) 3202 credits = RFCOMM_MAX_CREDITS - pcb->rx_cred; 3203 3204 error = ng_btsocket_rfcomm_send_uih( 3205 pcb->session, 3206 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 3207 pcb->dlci), 1, credits, NULL); 3208 if (error == 0) { 3209 pcb->rx_cred += credits; 3210 3211 NG_BTSOCKET_RFCOMM_INFO( 3212 "%s: Gave remote side %d more credits, dlci=%d, state=%d, flags=%#x, " \ 3213 "rx_cred=%d, tx_cred=%d\n", __func__, credits, pcb->dlci, pcb->state, 3214 pcb->flags, pcb->rx_cred, pcb->tx_cred); 3215 } else 3216 NG_BTSOCKET_RFCOMM_ERR( 3217 "%s: Could not send credits, error=%d, dlci=%d, state=%d, flags=%#x, " \ 3218 "mtu=%d, space=%ld, tx_cred=%d, rx_cred=%d\n", 3219 __func__, error, pcb->dlci, pcb->state, 3220 pcb->flags, pcb->mtu, sbspace(&pcb->so->so_rcv), 3221 pcb->tx_cred, pcb->rx_cred); 3222 } 3223 3224 return (error); 3225 } /* ng_btsocket_rfcomm_send_credits */ 3226 3227 /***************************************************************************** 3228 ***************************************************************************** 3229 ** RFCOMM DLCs 3230 ***************************************************************************** 3231 *****************************************************************************/ 3232 3233 /* 3234 * Send data from socket send buffer 3235 * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3236 */ 3237 3238 static int 3239 ng_btsocket_rfcomm_pcb_send(ng_btsocket_rfcomm_pcb_p pcb, int limit) 3240 { 3241 struct mbuf *m = NULL; 3242 int sent, length, error; 3243 3244 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3245 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3246 3247 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) 3248 limit = min(limit, pcb->tx_cred); 3249 else if (!(pcb->rmodem & RFCOMM_MODEM_FC)) 3250 limit = min(limit, RFCOMM_MAX_CREDITS); /* XXX ??? */ 3251 else 3252 limit = 0; 3253 3254 if (limit == 0) { 3255 NG_BTSOCKET_RFCOMM_INFO( 3256 "%s: Could not send - remote flow control asserted, dlci=%d, flags=%#x, " \ 3257 "rmodem=%#x, tx_cred=%d\n", 3258 __func__, pcb->dlci, pcb->flags, pcb->rmodem, 3259 pcb->tx_cred); 3260 3261 return (0); 3262 } 3263 3264 for (error = 0, sent = 0; sent < limit; sent ++) { 3265 length = min(pcb->mtu, sbavail(&pcb->so->so_snd)); 3266 if (length == 0) 3267 break; 3268 3269 /* Get the chunk from the socket's send buffer */ 3270 m = ng_btsocket_rfcomm_prepare_packet(&pcb->so->so_snd, length); 3271 if (m == NULL) { 3272 error = ENOBUFS; 3273 break; 3274 } 3275 3276 sbdrop(&pcb->so->so_snd, length); 3277 3278 error = ng_btsocket_rfcomm_send_uih(pcb->session, 3279 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 3280 pcb->dlci), 0, 0, m); 3281 if (error != 0) 3282 break; 3283 } 3284 3285 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) 3286 pcb->tx_cred -= sent; 3287 3288 if (error == 0 && sent > 0) { 3289 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_SENDING; 3290 sowwakeup(pcb->so); 3291 } 3292 3293 return (error); 3294 } /* ng_btsocket_rfcomm_pcb_send */ 3295 3296 /* 3297 * Unlink and disconnect DLC. If ng_btsocket_rfcomm_pcb_kill() returns 3298 * non zero value than socket has no reference and has to be detached. 3299 * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3300 */ 3301 3302 static void 3303 ng_btsocket_rfcomm_pcb_kill(ng_btsocket_rfcomm_pcb_p pcb, int error) 3304 { 3305 ng_btsocket_rfcomm_session_p s = pcb->session; 3306 3307 NG_BTSOCKET_RFCOMM_INFO( 3308 "%s: Killing DLC, so=%p, dlci=%d, state=%d, flags=%#x, error=%d\n", 3309 __func__, pcb->so, pcb->dlci, pcb->state, pcb->flags, error); 3310 3311 if (pcb->session == NULL) 3312 panic("%s: DLC without session, pcb=%p, state=%d, flags=%#x\n", 3313 __func__, pcb, pcb->state, pcb->flags); 3314 3315 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3316 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3317 3318 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 3319 ng_btsocket_rfcomm_untimeout(pcb); 3320 3321 /* Detach DLC from the session. Does not matter which state DLC in */ 3322 LIST_REMOVE(pcb, session_next); 3323 pcb->session = NULL; 3324 3325 /* Change DLC state and wakeup all sleepers */ 3326 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED; 3327 pcb->so->so_error = error; 3328 soisdisconnected(pcb->so); 3329 wakeup(&pcb->state); 3330 3331 /* Check if we have any DLCs left on the session */ 3332 if (LIST_EMPTY(&s->dlcs) && INITIATOR(s)) { 3333 NG_BTSOCKET_RFCOMM_INFO( 3334 "%s: Disconnecting session, state=%d, flags=%#x, mtu=%d\n", 3335 __func__, s->state, s->flags, s->mtu); 3336 3337 switch (s->state) { 3338 case NG_BTSOCKET_RFCOMM_SESSION_CLOSED: 3339 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 3340 /* 3341 * Do not have to do anything here. We can get here 3342 * when L2CAP connection was terminated or we have 3343 * received DISC on multiplexor channel 3344 */ 3345 break; 3346 3347 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 3348 /* Send DISC on multiplexor channel */ 3349 error = ng_btsocket_rfcomm_send_command(s, 3350 RFCOMM_FRAME_DISC, 0); 3351 if (error == 0) { 3352 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 3353 break; 3354 } 3355 /* FALL THROUGH */ 3356 3357 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING: 3358 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 3359 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 3360 break; 3361 3362 /* case NG_BTSOCKET_RFCOMM_SESSION_LISTENING: */ 3363 default: 3364 panic("%s: Invalid session state=%d, flags=%#x\n", 3365 __func__, s->state, s->flags); 3366 break; 3367 } 3368 3369 ng_btsocket_rfcomm_task_wakeup(); 3370 } 3371 } /* ng_btsocket_rfcomm_pcb_kill */ 3372 3373 /* 3374 * Look for given dlci for given RFCOMM session. Caller must hold s->session_mtx 3375 */ 3376 3377 static ng_btsocket_rfcomm_pcb_p 3378 ng_btsocket_rfcomm_pcb_by_dlci(ng_btsocket_rfcomm_session_p s, int dlci) 3379 { 3380 ng_btsocket_rfcomm_pcb_p pcb = NULL; 3381 3382 mtx_assert(&s->session_mtx, MA_OWNED); 3383 3384 LIST_FOREACH(pcb, &s->dlcs, session_next) 3385 if (pcb->dlci == dlci) 3386 break; 3387 3388 return (pcb); 3389 } /* ng_btsocket_rfcomm_pcb_by_dlci */ 3390 3391 /* 3392 * Look for socket that listens on given src address and given channel 3393 */ 3394 3395 static ng_btsocket_rfcomm_pcb_p 3396 ng_btsocket_rfcomm_pcb_listener(bdaddr_p src, int channel) 3397 { 3398 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb1 = NULL; 3399 3400 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 3401 3402 LIST_FOREACH(pcb, &ng_btsocket_rfcomm_sockets, next) { 3403 if (pcb->channel != channel || 3404 !(pcb->so->so_options & SO_ACCEPTCONN)) 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 3562