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