1 /* 2 * ng_btsocket_rfcomm.c 3 */ 4 5 /*- 6 * SPDX-License-Identifier: BSD-2-Clause 7 * 8 * Copyright (c) 2001-2003 Maksim Yevmenkin <m_evmenkin@yahoo.com> 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $Id: ng_btsocket_rfcomm.c,v 1.28 2003/09/14 23:29:06 max Exp $ 33 * $FreeBSD$ 34 */ 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/bitstring.h> 39 #include <sys/domain.h> 40 #include <sys/endian.h> 41 #include <sys/errno.h> 42 #include <sys/filedesc.h> 43 #include <sys/ioccom.h> 44 #include <sys/kernel.h> 45 #include <sys/lock.h> 46 #include <sys/malloc.h> 47 #include <sys/mbuf.h> 48 #include <sys/mutex.h> 49 #include <sys/proc.h> 50 #include <sys/protosw.h> 51 #include <sys/queue.h> 52 #include <sys/socket.h> 53 #include <sys/socketvar.h> 54 #include <sys/sysctl.h> 55 #include <sys/taskqueue.h> 56 #include <sys/uio.h> 57 58 #include <net/vnet.h> 59 60 #include <netgraph/ng_message.h> 61 #include <netgraph/netgraph.h> 62 #include <netgraph/bluetooth/include/ng_bluetooth.h> 63 #include <netgraph/bluetooth/include/ng_hci.h> 64 #include <netgraph/bluetooth/include/ng_l2cap.h> 65 #include <netgraph/bluetooth/include/ng_btsocket.h> 66 #include <netgraph/bluetooth/include/ng_btsocket_l2cap.h> 67 #include <netgraph/bluetooth/include/ng_btsocket_rfcomm.h> 68 69 /* MALLOC define */ 70 #ifdef NG_SEPARATE_MALLOC 71 static MALLOC_DEFINE(M_NETGRAPH_BTSOCKET_RFCOMM, "netgraph_btsocks_rfcomm", 72 "Netgraph Bluetooth RFCOMM sockets"); 73 #else 74 #define M_NETGRAPH_BTSOCKET_RFCOMM M_NETGRAPH 75 #endif /* NG_SEPARATE_MALLOC */ 76 77 /* Debug */ 78 #define NG_BTSOCKET_RFCOMM_INFO \ 79 if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_INFO_LEVEL && \ 80 ppsratecheck(&ng_btsocket_rfcomm_lasttime, &ng_btsocket_rfcomm_curpps, 1)) \ 81 printf 82 83 #define NG_BTSOCKET_RFCOMM_WARN \ 84 if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_WARN_LEVEL && \ 85 ppsratecheck(&ng_btsocket_rfcomm_lasttime, &ng_btsocket_rfcomm_curpps, 1)) \ 86 printf 87 88 #define NG_BTSOCKET_RFCOMM_ERR \ 89 if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_ERR_LEVEL && \ 90 ppsratecheck(&ng_btsocket_rfcomm_lasttime, &ng_btsocket_rfcomm_curpps, 1)) \ 91 printf 92 93 #define NG_BTSOCKET_RFCOMM_ALERT \ 94 if (ng_btsocket_rfcomm_debug_level >= NG_BTSOCKET_ALERT_LEVEL && \ 95 ppsratecheck(&ng_btsocket_rfcomm_lasttime, &ng_btsocket_rfcomm_curpps, 1)) \ 96 printf 97 98 #define ALOT 0x7fff 99 100 /* Local prototypes */ 101 static int ng_btsocket_rfcomm_upcall 102 (struct socket *so, void *arg, int waitflag); 103 static void ng_btsocket_rfcomm_sessions_task 104 (void *ctx, int pending); 105 static void ng_btsocket_rfcomm_session_task 106 (ng_btsocket_rfcomm_session_p s); 107 #define ng_btsocket_rfcomm_task_wakeup() \ 108 taskqueue_enqueue(taskqueue_swi_giant, &ng_btsocket_rfcomm_task) 109 110 static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_connect_ind 111 (ng_btsocket_rfcomm_session_p s, int channel); 112 static void ng_btsocket_rfcomm_connect_cfm 113 (ng_btsocket_rfcomm_session_p s); 114 115 static int ng_btsocket_rfcomm_session_create 116 (ng_btsocket_rfcomm_session_p *sp, struct socket *l2so, 117 bdaddr_p src, bdaddr_p dst, struct thread *td); 118 static int ng_btsocket_rfcomm_session_accept 119 (ng_btsocket_rfcomm_session_p s0); 120 static int ng_btsocket_rfcomm_session_connect 121 (ng_btsocket_rfcomm_session_p s); 122 static int ng_btsocket_rfcomm_session_receive 123 (ng_btsocket_rfcomm_session_p s); 124 static int ng_btsocket_rfcomm_session_send 125 (ng_btsocket_rfcomm_session_p s); 126 static void ng_btsocket_rfcomm_session_clean 127 (ng_btsocket_rfcomm_session_p s); 128 static void ng_btsocket_rfcomm_session_process_pcb 129 (ng_btsocket_rfcomm_session_p s); 130 static ng_btsocket_rfcomm_session_p ng_btsocket_rfcomm_session_by_addr 131 (bdaddr_p src, bdaddr_p dst); 132 133 static int ng_btsocket_rfcomm_receive_frame 134 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 135 static int ng_btsocket_rfcomm_receive_sabm 136 (ng_btsocket_rfcomm_session_p s, int dlci); 137 static int ng_btsocket_rfcomm_receive_disc 138 (ng_btsocket_rfcomm_session_p s, int dlci); 139 static int ng_btsocket_rfcomm_receive_ua 140 (ng_btsocket_rfcomm_session_p s, int dlci); 141 static int ng_btsocket_rfcomm_receive_dm 142 (ng_btsocket_rfcomm_session_p s, int dlci); 143 static int ng_btsocket_rfcomm_receive_uih 144 (ng_btsocket_rfcomm_session_p s, int dlci, int pf, struct mbuf *m0); 145 static int ng_btsocket_rfcomm_receive_mcc 146 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 147 static int ng_btsocket_rfcomm_receive_test 148 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 149 static int ng_btsocket_rfcomm_receive_fc 150 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 151 static int ng_btsocket_rfcomm_receive_msc 152 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 153 static int ng_btsocket_rfcomm_receive_rpn 154 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 155 static int ng_btsocket_rfcomm_receive_rls 156 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 157 static int ng_btsocket_rfcomm_receive_pn 158 (ng_btsocket_rfcomm_session_p s, struct mbuf *m0); 159 static void ng_btsocket_rfcomm_set_pn 160 (ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr, u_int8_t flow_control, 161 u_int8_t credits, u_int16_t mtu); 162 163 static int ng_btsocket_rfcomm_send_command 164 (ng_btsocket_rfcomm_session_p s, u_int8_t type, u_int8_t dlci); 165 static int ng_btsocket_rfcomm_send_uih 166 (ng_btsocket_rfcomm_session_p s, u_int8_t address, u_int8_t pf, 167 u_int8_t credits, struct mbuf *data); 168 static int ng_btsocket_rfcomm_send_msc 169 (ng_btsocket_rfcomm_pcb_p pcb); 170 static int ng_btsocket_rfcomm_send_pn 171 (ng_btsocket_rfcomm_pcb_p pcb); 172 static int ng_btsocket_rfcomm_send_credits 173 (ng_btsocket_rfcomm_pcb_p pcb); 174 175 static int ng_btsocket_rfcomm_pcb_send 176 (ng_btsocket_rfcomm_pcb_p pcb, int limit); 177 static void ng_btsocket_rfcomm_pcb_kill 178 (ng_btsocket_rfcomm_pcb_p pcb, int error); 179 static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_by_dlci 180 (ng_btsocket_rfcomm_session_p s, int dlci); 181 static ng_btsocket_rfcomm_pcb_p ng_btsocket_rfcomm_pcb_listener 182 (bdaddr_p src, int channel); 183 184 static void ng_btsocket_rfcomm_timeout 185 (ng_btsocket_rfcomm_pcb_p pcb); 186 static void ng_btsocket_rfcomm_untimeout 187 (ng_btsocket_rfcomm_pcb_p pcb); 188 static void ng_btsocket_rfcomm_process_timeout 189 (void *xpcb); 190 191 static struct mbuf * ng_btsocket_rfcomm_prepare_packet 192 (struct sockbuf *sb, int length); 193 194 /* Globals */ 195 extern int ifqmaxlen; 196 static u_int32_t ng_btsocket_rfcomm_debug_level; 197 static u_int32_t ng_btsocket_rfcomm_timo; 198 struct task ng_btsocket_rfcomm_task; 199 static LIST_HEAD(, ng_btsocket_rfcomm_session) ng_btsocket_rfcomm_sessions; 200 static struct mtx ng_btsocket_rfcomm_sessions_mtx; 201 static LIST_HEAD(, ng_btsocket_rfcomm_pcb) ng_btsocket_rfcomm_sockets; 202 static struct mtx ng_btsocket_rfcomm_sockets_mtx; 203 static struct timeval ng_btsocket_rfcomm_lasttime; 204 static int ng_btsocket_rfcomm_curpps; 205 206 /* Sysctl tree */ 207 SYSCTL_DECL(_net_bluetooth_rfcomm_sockets); 208 static SYSCTL_NODE(_net_bluetooth_rfcomm_sockets, OID_AUTO, stream, 209 CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 210 "Bluetooth STREAM RFCOMM sockets family"); 211 SYSCTL_UINT(_net_bluetooth_rfcomm_sockets_stream, OID_AUTO, debug_level, 212 CTLFLAG_RW, 213 &ng_btsocket_rfcomm_debug_level, NG_BTSOCKET_INFO_LEVEL, 214 "Bluetooth STREAM RFCOMM sockets debug level"); 215 SYSCTL_UINT(_net_bluetooth_rfcomm_sockets_stream, OID_AUTO, timeout, 216 CTLFLAG_RW, 217 &ng_btsocket_rfcomm_timo, 60, 218 "Bluetooth STREAM RFCOMM sockets timeout"); 219 220 /***************************************************************************** 221 ***************************************************************************** 222 ** RFCOMM CRC 223 ***************************************************************************** 224 *****************************************************************************/ 225 226 static u_int8_t ng_btsocket_rfcomm_crc_table[256] = { 227 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75, 228 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b, 229 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69, 230 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67, 231 232 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d, 233 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43, 234 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51, 235 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f, 236 237 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05, 238 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b, 239 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19, 240 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17, 241 242 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d, 243 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33, 244 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21, 245 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f, 246 247 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95, 248 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b, 249 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89, 250 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87, 251 252 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad, 253 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3, 254 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1, 255 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf, 256 257 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5, 258 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb, 259 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9, 260 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7, 261 262 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd, 263 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3, 264 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1, 265 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf 266 }; 267 268 /* CRC */ 269 static u_int8_t 270 ng_btsocket_rfcomm_crc(u_int8_t *data, int length) 271 { 272 u_int8_t crc = 0xff; 273 274 while (length --) 275 crc = ng_btsocket_rfcomm_crc_table[crc ^ *data++]; 276 277 return (crc); 278 } /* ng_btsocket_rfcomm_crc */ 279 280 /* FCS on 2 bytes */ 281 static u_int8_t 282 ng_btsocket_rfcomm_fcs2(u_int8_t *data) 283 { 284 return (0xff - ng_btsocket_rfcomm_crc(data, 2)); 285 } /* ng_btsocket_rfcomm_fcs2 */ 286 287 /* FCS on 3 bytes */ 288 static u_int8_t 289 ng_btsocket_rfcomm_fcs3(u_int8_t *data) 290 { 291 return (0xff - ng_btsocket_rfcomm_crc(data, 3)); 292 } /* ng_btsocket_rfcomm_fcs3 */ 293 294 /* 295 * Check FCS 296 * 297 * From Bluetooth spec 298 * 299 * "... In 07.10, the frame check sequence (FCS) is calculated on different 300 * sets of fields for different frame types. These are the fields that the 301 * FCS are calculated on: 302 * 303 * For SABM, DISC, UA, DM frames: on Address, Control and length field. 304 * For UIH frames: on Address and Control field. 305 * 306 * (This is stated here for clarification, and to set the standard for RFCOMM; 307 * the fields included in FCS calculation have actually changed in version 308 * 7.0.0 of TS 07.10, but RFCOMM will not change the FCS calculation scheme 309 * from the one above.) ..." 310 */ 311 312 static int 313 ng_btsocket_rfcomm_check_fcs(u_int8_t *data, int type, u_int8_t fcs) 314 { 315 if (type != RFCOMM_FRAME_UIH) 316 return (ng_btsocket_rfcomm_fcs3(data) != fcs); 317 318 return (ng_btsocket_rfcomm_fcs2(data) != fcs); 319 } /* ng_btsocket_rfcomm_check_fcs */ 320 321 /***************************************************************************** 322 ***************************************************************************** 323 ** Socket interface 324 ***************************************************************************** 325 *****************************************************************************/ 326 327 /* 328 * Initialize everything 329 */ 330 331 static void 332 ng_btsocket_rfcomm_init(void *arg __unused) 333 { 334 335 ng_btsocket_rfcomm_debug_level = NG_BTSOCKET_WARN_LEVEL; 336 ng_btsocket_rfcomm_timo = 60; 337 338 /* RFCOMM task */ 339 TASK_INIT(&ng_btsocket_rfcomm_task, 0, 340 ng_btsocket_rfcomm_sessions_task, NULL); 341 342 /* RFCOMM sessions list */ 343 LIST_INIT(&ng_btsocket_rfcomm_sessions); 344 mtx_init(&ng_btsocket_rfcomm_sessions_mtx, 345 "btsocks_rfcomm_sessions_mtx", NULL, MTX_DEF); 346 347 /* RFCOMM sockets list */ 348 LIST_INIT(&ng_btsocket_rfcomm_sockets); 349 mtx_init(&ng_btsocket_rfcomm_sockets_mtx, 350 "btsocks_rfcomm_sockets_mtx", NULL, MTX_DEF); 351 } /* ng_btsocket_rfcomm_init */ 352 SYSINIT(ng_btsocket_rfcomm_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, 353 ng_btsocket_rfcomm_init, NULL); 354 355 /* 356 * Abort connection on socket 357 */ 358 359 void 360 ng_btsocket_rfcomm_abort(struct socket *so) 361 { 362 363 so->so_error = ECONNABORTED; 364 (void)ng_btsocket_rfcomm_disconnect(so); 365 } /* ng_btsocket_rfcomm_abort */ 366 367 void 368 ng_btsocket_rfcomm_close(struct socket *so) 369 { 370 371 (void)ng_btsocket_rfcomm_disconnect(so); 372 } /* ng_btsocket_rfcomm_close */ 373 374 /* 375 * Accept connection on socket. Nothing to do here, socket must be connected 376 * and ready, so just return peer address and be done with it. 377 */ 378 379 int 380 ng_btsocket_rfcomm_accept(struct socket *so, struct sockaddr **nam) 381 { 382 return (ng_btsocket_rfcomm_peeraddr(so, nam)); 383 } /* ng_btsocket_rfcomm_accept */ 384 385 /* 386 * Create and attach new socket 387 */ 388 389 int 390 ng_btsocket_rfcomm_attach(struct socket *so, int proto, struct thread *td) 391 { 392 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 393 int error; 394 395 /* Check socket and protocol */ 396 if (so->so_type != SOCK_STREAM) 397 return (ESOCKTNOSUPPORT); 398 399 #if 0 /* XXX sonewconn() calls "pru_attach" with proto == 0 */ 400 if (proto != 0) 401 if (proto != BLUETOOTH_PROTO_RFCOMM) 402 return (EPROTONOSUPPORT); 403 #endif /* XXX */ 404 405 if (pcb != NULL) 406 return (EISCONN); 407 408 /* Reserve send and receive space if it is not reserved yet */ 409 if ((so->so_snd.sb_hiwat == 0) || (so->so_rcv.sb_hiwat == 0)) { 410 error = soreserve(so, NG_BTSOCKET_RFCOMM_SENDSPACE, 411 NG_BTSOCKET_RFCOMM_RECVSPACE); 412 if (error != 0) 413 return (error); 414 } 415 416 /* Allocate the PCB */ 417 pcb = malloc(sizeof(*pcb), 418 M_NETGRAPH_BTSOCKET_RFCOMM, M_NOWAIT | M_ZERO); 419 if (pcb == NULL) 420 return (ENOMEM); 421 422 /* Link the PCB and the socket */ 423 so->so_pcb = (caddr_t) pcb; 424 pcb->so = so; 425 426 /* Initialize PCB */ 427 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED; 428 pcb->flags = NG_BTSOCKET_RFCOMM_DLC_CFC; 429 430 pcb->lmodem = 431 pcb->rmodem = (RFCOMM_MODEM_RTC | RFCOMM_MODEM_RTR | RFCOMM_MODEM_DV); 432 433 pcb->mtu = RFCOMM_DEFAULT_MTU; 434 pcb->tx_cred = 0; 435 pcb->rx_cred = RFCOMM_DEFAULT_CREDITS; 436 437 mtx_init(&pcb->pcb_mtx, "btsocks_rfcomm_pcb_mtx", NULL, MTX_DEF); 438 callout_init_mtx(&pcb->timo, &pcb->pcb_mtx, 0); 439 440 /* Add the PCB to the list */ 441 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 442 LIST_INSERT_HEAD(&ng_btsocket_rfcomm_sockets, pcb, next); 443 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 444 445 return (0); 446 } /* ng_btsocket_rfcomm_attach */ 447 448 /* 449 * Bind socket 450 */ 451 452 int 453 ng_btsocket_rfcomm_bind(struct socket *so, struct sockaddr *nam, 454 struct thread *td) 455 { 456 ng_btsocket_rfcomm_pcb_t *pcb = so2rfcomm_pcb(so), *pcb1; 457 struct sockaddr_rfcomm *sa = (struct sockaddr_rfcomm *) nam; 458 459 if (pcb == NULL) 460 return (EINVAL); 461 462 /* Verify address */ 463 if (sa == NULL) 464 return (EINVAL); 465 if (sa->rfcomm_family != AF_BLUETOOTH) 466 return (EAFNOSUPPORT); 467 if (sa->rfcomm_len != sizeof(*sa)) 468 return (EINVAL); 469 if (sa->rfcomm_channel > 30) 470 return (EINVAL); 471 472 mtx_lock(&pcb->pcb_mtx); 473 474 if (sa->rfcomm_channel != 0) { 475 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 476 477 LIST_FOREACH(pcb1, &ng_btsocket_rfcomm_sockets, next) { 478 if (pcb1->channel == sa->rfcomm_channel && 479 bcmp(&pcb1->src, &sa->rfcomm_bdaddr, 480 sizeof(pcb1->src)) == 0) { 481 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 482 mtx_unlock(&pcb->pcb_mtx); 483 484 return (EADDRINUSE); 485 } 486 } 487 488 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 489 } 490 491 bcopy(&sa->rfcomm_bdaddr, &pcb->src, sizeof(pcb->src)); 492 pcb->channel = sa->rfcomm_channel; 493 494 mtx_unlock(&pcb->pcb_mtx); 495 496 return (0); 497 } /* ng_btsocket_rfcomm_bind */ 498 499 /* 500 * Connect socket 501 */ 502 503 int 504 ng_btsocket_rfcomm_connect(struct socket *so, struct sockaddr *nam, 505 struct thread *td) 506 { 507 ng_btsocket_rfcomm_pcb_t *pcb = so2rfcomm_pcb(so); 508 struct sockaddr_rfcomm *sa = (struct sockaddr_rfcomm *) nam; 509 ng_btsocket_rfcomm_session_t *s = NULL; 510 struct socket *l2so = NULL; 511 int dlci, error = 0; 512 513 if (pcb == NULL) 514 return (EINVAL); 515 516 /* Verify address */ 517 if (sa == NULL) 518 return (EINVAL); 519 if (sa->rfcomm_family != AF_BLUETOOTH) 520 return (EAFNOSUPPORT); 521 if (sa->rfcomm_len != sizeof(*sa)) 522 return (EINVAL); 523 if (sa->rfcomm_channel > 30) 524 return (EINVAL); 525 if (sa->rfcomm_channel == 0 || 526 bcmp(&sa->rfcomm_bdaddr, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0) 527 return (EDESTADDRREQ); 528 529 /* 530 * Note that we will not check for errors in socreate() because 531 * if we failed to create L2CAP socket at this point we still 532 * might have already open session. 533 */ 534 535 error = socreate(PF_BLUETOOTH, &l2so, SOCK_SEQPACKET, 536 BLUETOOTH_PROTO_L2CAP, td->td_ucred, td); 537 538 /* 539 * Look for session between "pcb->src" and "sa->rfcomm_bdaddr" (dst) 540 */ 541 542 mtx_lock(&ng_btsocket_rfcomm_sessions_mtx); 543 544 s = ng_btsocket_rfcomm_session_by_addr(&pcb->src, &sa->rfcomm_bdaddr); 545 if (s == NULL) { 546 /* 547 * We need to create new RFCOMM session. Check if we have L2CAP 548 * socket. If l2so == NULL then error has the error code from 549 * socreate() 550 */ 551 552 if (l2so == NULL) { 553 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 554 return (error); 555 } 556 557 error = ng_btsocket_rfcomm_session_create(&s, l2so, 558 &pcb->src, &sa->rfcomm_bdaddr, td); 559 if (error != 0) { 560 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 561 soclose(l2so); 562 563 return (error); 564 } 565 } else if (l2so != NULL) 566 soclose(l2so); /* we don't need new L2CAP socket */ 567 568 /* 569 * Check if we already have the same DLCI the same session 570 */ 571 572 mtx_lock(&s->session_mtx); 573 mtx_lock(&pcb->pcb_mtx); 574 575 dlci = RFCOMM_MKDLCI(!INITIATOR(s), sa->rfcomm_channel); 576 577 if (ng_btsocket_rfcomm_pcb_by_dlci(s, dlci) != NULL) { 578 mtx_unlock(&pcb->pcb_mtx); 579 mtx_unlock(&s->session_mtx); 580 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 581 582 return (EBUSY); 583 } 584 585 /* 586 * Check session state and if its not acceptable then refuse connection 587 */ 588 589 switch (s->state) { 590 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING: 591 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 592 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 593 /* 594 * Update destination address and channel and attach 595 * DLC to the session 596 */ 597 598 bcopy(&sa->rfcomm_bdaddr, &pcb->dst, sizeof(pcb->dst)); 599 pcb->channel = sa->rfcomm_channel; 600 pcb->dlci = dlci; 601 602 LIST_INSERT_HEAD(&s->dlcs, pcb, session_next); 603 pcb->session = s; 604 605 ng_btsocket_rfcomm_timeout(pcb); 606 soisconnecting(pcb->so); 607 608 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_OPEN) { 609 pcb->mtu = s->mtu; 610 bcopy(&so2l2cap_pcb(s->l2so)->src, &pcb->src, 611 sizeof(pcb->src)); 612 613 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONFIGURING; 614 615 error = ng_btsocket_rfcomm_send_pn(pcb); 616 if (error == 0) 617 error = ng_btsocket_rfcomm_task_wakeup(); 618 } else 619 pcb->state = NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT; 620 break; 621 622 default: 623 error = ECONNRESET; 624 break; 625 } 626 627 mtx_unlock(&pcb->pcb_mtx); 628 mtx_unlock(&s->session_mtx); 629 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 630 631 return (error); 632 } /* ng_btsocket_rfcomm_connect */ 633 634 /* 635 * Process ioctl's calls on socket. 636 * XXX FIXME this should provide interface to the RFCOMM multiplexor channel 637 */ 638 639 int 640 ng_btsocket_rfcomm_control(struct socket *so, u_long cmd, void *data, 641 struct ifnet *ifp, struct thread *td) 642 { 643 return (EINVAL); 644 } /* ng_btsocket_rfcomm_control */ 645 646 /* 647 * Process getsockopt/setsockopt system calls 648 */ 649 650 int 651 ng_btsocket_rfcomm_ctloutput(struct socket *so, struct sockopt *sopt) 652 { 653 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 654 struct ng_btsocket_rfcomm_fc_info fcinfo; 655 int error = 0; 656 657 if (pcb == NULL) 658 return (EINVAL); 659 if (sopt->sopt_level != SOL_RFCOMM) 660 return (0); 661 662 mtx_lock(&pcb->pcb_mtx); 663 664 switch (sopt->sopt_dir) { 665 case SOPT_GET: 666 switch (sopt->sopt_name) { 667 case SO_RFCOMM_MTU: 668 error = sooptcopyout(sopt, &pcb->mtu, sizeof(pcb->mtu)); 669 break; 670 671 case SO_RFCOMM_FC_INFO: 672 fcinfo.lmodem = pcb->lmodem; 673 fcinfo.rmodem = pcb->rmodem; 674 fcinfo.tx_cred = pcb->tx_cred; 675 fcinfo.rx_cred = pcb->rx_cred; 676 fcinfo.cfc = (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)? 677 1 : 0; 678 fcinfo.reserved = 0; 679 680 error = sooptcopyout(sopt, &fcinfo, sizeof(fcinfo)); 681 break; 682 683 default: 684 error = ENOPROTOOPT; 685 break; 686 } 687 break; 688 689 case SOPT_SET: 690 switch (sopt->sopt_name) { 691 default: 692 error = ENOPROTOOPT; 693 break; 694 } 695 break; 696 697 default: 698 error = EINVAL; 699 break; 700 } 701 702 mtx_unlock(&pcb->pcb_mtx); 703 704 return (error); 705 } /* ng_btsocket_rfcomm_ctloutput */ 706 707 /* 708 * Detach and destroy socket 709 */ 710 711 void 712 ng_btsocket_rfcomm_detach(struct socket *so) 713 { 714 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 715 716 KASSERT(pcb != NULL, ("ng_btsocket_rfcomm_detach: pcb == NULL")); 717 718 mtx_lock(&pcb->pcb_mtx); 719 720 switch (pcb->state) { 721 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 722 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 723 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 724 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 725 /* XXX What to do with pending request? */ 726 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 727 ng_btsocket_rfcomm_untimeout(pcb); 728 729 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT) 730 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_DETACHED; 731 else 732 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 733 734 ng_btsocket_rfcomm_task_wakeup(); 735 break; 736 737 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 738 ng_btsocket_rfcomm_task_wakeup(); 739 break; 740 } 741 742 while (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CLOSED) 743 msleep(&pcb->state, &pcb->pcb_mtx, PZERO, "rf_det", 0); 744 745 if (pcb->session != NULL) 746 panic("%s: pcb->session != NULL\n", __func__); 747 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 748 panic("%s: timeout on closed DLC, flags=%#x\n", 749 __func__, pcb->flags); 750 751 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 752 LIST_REMOVE(pcb, next); 753 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 754 755 mtx_unlock(&pcb->pcb_mtx); 756 757 mtx_destroy(&pcb->pcb_mtx); 758 bzero(pcb, sizeof(*pcb)); 759 free(pcb, M_NETGRAPH_BTSOCKET_RFCOMM); 760 761 soisdisconnected(so); 762 so->so_pcb = NULL; 763 } /* ng_btsocket_rfcomm_detach */ 764 765 /* 766 * Disconnect socket 767 */ 768 769 int 770 ng_btsocket_rfcomm_disconnect(struct socket *so) 771 { 772 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 773 774 if (pcb == NULL) 775 return (EINVAL); 776 777 mtx_lock(&pcb->pcb_mtx); 778 779 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING) { 780 mtx_unlock(&pcb->pcb_mtx); 781 return (EINPROGRESS); 782 } 783 784 /* XXX What to do with pending request? */ 785 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 786 ng_btsocket_rfcomm_untimeout(pcb); 787 788 switch (pcb->state) { 789 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: /* XXX can we get here? */ 790 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: /* XXX can we get here? */ 791 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 792 793 /* 794 * Just change DLC state and enqueue RFCOMM task. It will 795 * queue and send DISC on the DLC. 796 */ 797 798 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 799 soisdisconnecting(so); 800 801 ng_btsocket_rfcomm_task_wakeup(); 802 break; 803 804 case NG_BTSOCKET_RFCOMM_DLC_CLOSED: 805 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 806 break; 807 808 default: 809 panic("%s: Invalid DLC state=%d, flags=%#x\n", 810 __func__, pcb->state, pcb->flags); 811 break; 812 } 813 814 mtx_unlock(&pcb->pcb_mtx); 815 816 return (0); 817 } /* ng_btsocket_rfcomm_disconnect */ 818 819 /* 820 * Listen on socket. First call to listen() will create listening RFCOMM session 821 */ 822 823 int 824 ng_btsocket_rfcomm_listen(struct socket *so, int backlog, struct thread *td) 825 { 826 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so), pcb1; 827 ng_btsocket_rfcomm_session_p s = NULL; 828 struct socket *l2so = NULL; 829 int error, socreate_error, usedchannels; 830 831 if (pcb == NULL) 832 return (EINVAL); 833 if (pcb->channel > 30) 834 return (EADDRNOTAVAIL); 835 836 usedchannels = 0; 837 838 mtx_lock(&pcb->pcb_mtx); 839 840 if (pcb->channel == 0) { 841 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 842 843 LIST_FOREACH(pcb1, &ng_btsocket_rfcomm_sockets, next) 844 if (pcb1->channel != 0 && 845 bcmp(&pcb1->src, &pcb->src, sizeof(pcb->src)) == 0) 846 usedchannels |= (1 << (pcb1->channel - 1)); 847 848 for (pcb->channel = 30; pcb->channel > 0; pcb->channel --) 849 if (!(usedchannels & (1 << (pcb->channel - 1)))) 850 break; 851 852 if (pcb->channel == 0) { 853 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 854 mtx_unlock(&pcb->pcb_mtx); 855 856 return (EADDRNOTAVAIL); 857 } 858 859 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 860 } 861 862 mtx_unlock(&pcb->pcb_mtx); 863 864 /* 865 * Note that we will not check for errors in socreate() because 866 * if we failed to create L2CAP socket at this point we still 867 * might have already open session. 868 */ 869 870 socreate_error = socreate(PF_BLUETOOTH, &l2so, SOCK_SEQPACKET, 871 BLUETOOTH_PROTO_L2CAP, td->td_ucred, td); 872 873 /* 874 * Transition the socket and session into the LISTENING state. Check 875 * for collisions first, as there can only be one. 876 */ 877 mtx_lock(&ng_btsocket_rfcomm_sessions_mtx); 878 SOCK_LOCK(so); 879 error = solisten_proto_check(so); 880 SOCK_UNLOCK(so); 881 if (error != 0) 882 goto out; 883 884 LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next) 885 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_LISTENING) 886 break; 887 888 if (s == NULL) { 889 /* 890 * We need to create default RFCOMM session. Check if we have 891 * L2CAP socket. If l2so == NULL then error has the error code 892 * from socreate() 893 */ 894 if (l2so == NULL) { 895 solisten_proto_abort(so); 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 solisten_proto_abort(so); 911 goto out; 912 } 913 l2so = NULL; 914 } 915 SOCK_LOCK(so); 916 solisten_proto(so, backlog); 917 SOCK_UNLOCK(so); 918 out: 919 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 920 /* 921 * If we still have an l2so reference here, it's unneeded, so release 922 * it. 923 */ 924 if (l2so != NULL) 925 soclose(l2so); 926 return (error); 927 } /* ng_btsocket_listen */ 928 929 /* 930 * Get peer address 931 */ 932 933 int 934 ng_btsocket_rfcomm_peeraddr(struct socket *so, struct sockaddr **nam) 935 { 936 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 937 struct sockaddr_rfcomm sa; 938 939 if (pcb == NULL) 940 return (EINVAL); 941 942 bcopy(&pcb->dst, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr)); 943 sa.rfcomm_channel = pcb->channel; 944 sa.rfcomm_len = sizeof(sa); 945 sa.rfcomm_family = AF_BLUETOOTH; 946 947 *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); 948 949 return ((*nam == NULL)? ENOMEM : 0); 950 } /* ng_btsocket_rfcomm_peeraddr */ 951 952 /* 953 * Send data to socket 954 */ 955 956 int 957 ng_btsocket_rfcomm_send(struct socket *so, int flags, struct mbuf *m, 958 struct sockaddr *nam, struct mbuf *control, struct thread *td) 959 { 960 ng_btsocket_rfcomm_pcb_t *pcb = so2rfcomm_pcb(so); 961 int error = 0; 962 963 /* Check socket and input */ 964 if (pcb == NULL || m == NULL || control != NULL) { 965 error = EINVAL; 966 goto drop; 967 } 968 969 mtx_lock(&pcb->pcb_mtx); 970 971 /* Make sure DLC is connected */ 972 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 973 mtx_unlock(&pcb->pcb_mtx); 974 error = ENOTCONN; 975 goto drop; 976 } 977 978 /* Put the packet on the socket's send queue and wakeup RFCOMM task */ 979 sbappend(&pcb->so->so_snd, m, flags); 980 m = NULL; 981 982 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_SENDING)) { 983 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_SENDING; 984 error = ng_btsocket_rfcomm_task_wakeup(); 985 } 986 987 mtx_unlock(&pcb->pcb_mtx); 988 drop: 989 NG_FREE_M(m); /* checks for != NULL */ 990 NG_FREE_M(control); 991 992 return (error); 993 } /* ng_btsocket_rfcomm_send */ 994 995 /* 996 * Get socket address 997 */ 998 999 int 1000 ng_btsocket_rfcomm_sockaddr(struct socket *so, struct sockaddr **nam) 1001 { 1002 ng_btsocket_rfcomm_pcb_p pcb = so2rfcomm_pcb(so); 1003 struct sockaddr_rfcomm sa; 1004 1005 if (pcb == NULL) 1006 return (EINVAL); 1007 1008 bcopy(&pcb->src, &sa.rfcomm_bdaddr, sizeof(sa.rfcomm_bdaddr)); 1009 sa.rfcomm_channel = pcb->channel; 1010 sa.rfcomm_len = sizeof(sa); 1011 sa.rfcomm_family = AF_BLUETOOTH; 1012 1013 *nam = sodupsockaddr((struct sockaddr *) &sa, M_NOWAIT); 1014 1015 return ((*nam == NULL)? ENOMEM : 0); 1016 } /* ng_btsocket_rfcomm_sockaddr */ 1017 1018 /* 1019 * Upcall function for L2CAP sockets. Enqueue RFCOMM task. 1020 */ 1021 1022 static int 1023 ng_btsocket_rfcomm_upcall(struct socket *so, void *arg, int waitflag) 1024 { 1025 int error; 1026 1027 if (so == NULL) 1028 panic("%s: so == NULL\n", __func__); 1029 1030 if ((error = ng_btsocket_rfcomm_task_wakeup()) != 0) 1031 NG_BTSOCKET_RFCOMM_ALERT( 1032 "%s: Could not enqueue RFCOMM task, error=%d\n", __func__, error); 1033 return (SU_OK); 1034 } /* ng_btsocket_rfcomm_upcall */ 1035 1036 /* 1037 * RFCOMM task. Will handle all RFCOMM sessions in one pass. 1038 * XXX FIXME does not scale very well 1039 */ 1040 1041 static void 1042 ng_btsocket_rfcomm_sessions_task(void *ctx, int pending) 1043 { 1044 ng_btsocket_rfcomm_session_p s = NULL, s_next = NULL; 1045 1046 mtx_lock(&ng_btsocket_rfcomm_sessions_mtx); 1047 1048 for (s = LIST_FIRST(&ng_btsocket_rfcomm_sessions); s != NULL; ) { 1049 mtx_lock(&s->session_mtx); 1050 s_next = LIST_NEXT(s, next); 1051 1052 ng_btsocket_rfcomm_session_task(s); 1053 1054 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_CLOSED) { 1055 /* Unlink and clean the session */ 1056 LIST_REMOVE(s, next); 1057 1058 NG_BT_MBUFQ_DRAIN(&s->outq); 1059 if (!LIST_EMPTY(&s->dlcs)) 1060 panic("%s: DLC list is not empty\n", __func__); 1061 1062 /* Close L2CAP socket */ 1063 SOCKBUF_LOCK(&s->l2so->so_rcv); 1064 soupcall_clear(s->l2so, SO_RCV); 1065 SOCKBUF_UNLOCK(&s->l2so->so_rcv); 1066 SOCKBUF_LOCK(&s->l2so->so_snd); 1067 soupcall_clear(s->l2so, SO_SND); 1068 SOCKBUF_UNLOCK(&s->l2so->so_snd); 1069 soclose(s->l2so); 1070 1071 mtx_unlock(&s->session_mtx); 1072 1073 mtx_destroy(&s->session_mtx); 1074 bzero(s, sizeof(*s)); 1075 free(s, M_NETGRAPH_BTSOCKET_RFCOMM); 1076 } else 1077 mtx_unlock(&s->session_mtx); 1078 1079 s = s_next; 1080 } 1081 1082 mtx_unlock(&ng_btsocket_rfcomm_sessions_mtx); 1083 } /* ng_btsocket_rfcomm_sessions_task */ 1084 1085 /* 1086 * Process RFCOMM session. Will handle all RFCOMM sockets in one pass. 1087 */ 1088 1089 static void 1090 ng_btsocket_rfcomm_session_task(ng_btsocket_rfcomm_session_p s) 1091 { 1092 mtx_assert(&s->session_mtx, MA_OWNED); 1093 1094 if (s->l2so->so_rcv.sb_state & SBS_CANTRCVMORE) { 1095 NG_BTSOCKET_RFCOMM_INFO( 1096 "%s: L2CAP connection has been terminated, so=%p, so_state=%#x, so_count=%d, " \ 1097 "state=%d, flags=%#x\n", __func__, s->l2so, s->l2so->so_state, 1098 s->l2so->so_count, s->state, s->flags); 1099 1100 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1101 ng_btsocket_rfcomm_session_clean(s); 1102 } 1103 1104 /* Now process upcall */ 1105 switch (s->state) { 1106 /* Try to accept new L2CAP connection(s) */ 1107 case NG_BTSOCKET_RFCOMM_SESSION_LISTENING: 1108 while (ng_btsocket_rfcomm_session_accept(s) == 0) 1109 ; 1110 break; 1111 1112 /* Process the results of the L2CAP connect */ 1113 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING: 1114 ng_btsocket_rfcomm_session_process_pcb(s); 1115 1116 if (ng_btsocket_rfcomm_session_connect(s) != 0) { 1117 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1118 ng_btsocket_rfcomm_session_clean(s); 1119 } 1120 break; 1121 1122 /* Try to receive/send more data */ 1123 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 1124 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 1125 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 1126 ng_btsocket_rfcomm_session_process_pcb(s); 1127 1128 if (ng_btsocket_rfcomm_session_receive(s) != 0) { 1129 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1130 ng_btsocket_rfcomm_session_clean(s); 1131 } else if (ng_btsocket_rfcomm_session_send(s) != 0) { 1132 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1133 ng_btsocket_rfcomm_session_clean(s); 1134 } 1135 break; 1136 1137 case NG_BTSOCKET_RFCOMM_SESSION_CLOSED: 1138 break; 1139 1140 default: 1141 panic("%s: Invalid session state=%d, flags=%#x\n", 1142 __func__, s->state, s->flags); 1143 break; 1144 } 1145 } /* ng_btsocket_rfcomm_session_task */ 1146 1147 /* 1148 * Process RFCOMM connection indicator. Caller must hold s->session_mtx 1149 */ 1150 1151 static ng_btsocket_rfcomm_pcb_p 1152 ng_btsocket_rfcomm_connect_ind(ng_btsocket_rfcomm_session_p s, int channel) 1153 { 1154 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb1 = NULL; 1155 ng_btsocket_l2cap_pcb_p l2pcb = NULL; 1156 struct socket *so1; 1157 1158 mtx_assert(&s->session_mtx, MA_OWNED); 1159 1160 /* 1161 * Try to find RFCOMM socket that listens on given source address 1162 * and channel. This will return the best possible match. 1163 */ 1164 1165 l2pcb = so2l2cap_pcb(s->l2so); 1166 pcb = ng_btsocket_rfcomm_pcb_listener(&l2pcb->src, channel); 1167 if (pcb == NULL) 1168 return (NULL); 1169 1170 /* 1171 * Check the pending connections queue and if we have space then 1172 * create new socket and set proper source and destination address, 1173 * and channel. 1174 */ 1175 1176 mtx_lock(&pcb->pcb_mtx); 1177 1178 CURVNET_SET(pcb->so->so_vnet); 1179 so1 = sonewconn(pcb->so, 0); 1180 CURVNET_RESTORE(); 1181 1182 mtx_unlock(&pcb->pcb_mtx); 1183 1184 if (so1 == NULL) 1185 return (NULL); 1186 1187 /* 1188 * If we got here than we have created new socket. So complete the 1189 * connection. Set source and destination address from the session. 1190 */ 1191 1192 pcb1 = so2rfcomm_pcb(so1); 1193 if (pcb1 == NULL) 1194 panic("%s: pcb1 == NULL\n", __func__); 1195 1196 mtx_lock(&pcb1->pcb_mtx); 1197 1198 bcopy(&l2pcb->src, &pcb1->src, sizeof(pcb1->src)); 1199 bcopy(&l2pcb->dst, &pcb1->dst, sizeof(pcb1->dst)); 1200 pcb1->channel = channel; 1201 1202 /* Link new DLC to the session. We already hold s->session_mtx */ 1203 LIST_INSERT_HEAD(&s->dlcs, pcb1, session_next); 1204 pcb1->session = s; 1205 1206 mtx_unlock(&pcb1->pcb_mtx); 1207 1208 return (pcb1); 1209 } /* ng_btsocket_rfcomm_connect_ind */ 1210 1211 /* 1212 * Process RFCOMM connect confirmation. Caller must hold s->session_mtx. 1213 */ 1214 1215 static void 1216 ng_btsocket_rfcomm_connect_cfm(ng_btsocket_rfcomm_session_p s) 1217 { 1218 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1219 int error; 1220 1221 mtx_assert(&s->session_mtx, MA_OWNED); 1222 1223 /* 1224 * Wake up all waiting sockets and send PN request for each of them. 1225 * Note that timeout already been set in ng_btsocket_rfcomm_connect() 1226 * 1227 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1228 * will unlink DLC from the session 1229 */ 1230 1231 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1232 mtx_lock(&pcb->pcb_mtx); 1233 pcb_next = LIST_NEXT(pcb, session_next); 1234 1235 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT) { 1236 pcb->mtu = s->mtu; 1237 bcopy(&so2l2cap_pcb(s->l2so)->src, &pcb->src, 1238 sizeof(pcb->src)); 1239 1240 error = ng_btsocket_rfcomm_send_pn(pcb); 1241 if (error == 0) 1242 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONFIGURING; 1243 else 1244 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1245 } 1246 1247 mtx_unlock(&pcb->pcb_mtx); 1248 pcb = pcb_next; 1249 } 1250 } /* ng_btsocket_rfcomm_connect_cfm */ 1251 1252 /***************************************************************************** 1253 ***************************************************************************** 1254 ** RFCOMM sessions 1255 ***************************************************************************** 1256 *****************************************************************************/ 1257 1258 /* 1259 * Create new RFCOMM session. That function WILL NOT take ownership over l2so. 1260 * Caller MUST free l2so if function failed. 1261 */ 1262 1263 static int 1264 ng_btsocket_rfcomm_session_create(ng_btsocket_rfcomm_session_p *sp, 1265 struct socket *l2so, bdaddr_p src, bdaddr_p dst, 1266 struct thread *td) 1267 { 1268 ng_btsocket_rfcomm_session_p s = NULL; 1269 struct sockaddr_l2cap l2sa; 1270 struct sockopt l2sopt; 1271 int error; 1272 u_int16_t mtu; 1273 1274 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1275 1276 /* Allocate the RFCOMM session */ 1277 s = malloc(sizeof(*s), 1278 M_NETGRAPH_BTSOCKET_RFCOMM, M_NOWAIT | M_ZERO); 1279 if (s == NULL) 1280 return (ENOMEM); 1281 1282 /* Set defaults */ 1283 s->mtu = RFCOMM_DEFAULT_MTU; 1284 s->flags = 0; 1285 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1286 NG_BT_MBUFQ_INIT(&s->outq, ifqmaxlen); 1287 1288 /* 1289 * XXX Mark session mutex as DUPOK to prevent "duplicated lock of 1290 * the same type" message. When accepting new L2CAP connection 1291 * ng_btsocket_rfcomm_session_accept() holds both session mutexes 1292 * for "old" (accepting) session and "new" (created) session. 1293 */ 1294 1295 mtx_init(&s->session_mtx, "btsocks_rfcomm_session_mtx", NULL, 1296 MTX_DEF|MTX_DUPOK); 1297 1298 LIST_INIT(&s->dlcs); 1299 1300 /* Prepare L2CAP socket */ 1301 SOCKBUF_LOCK(&l2so->so_rcv); 1302 soupcall_set(l2so, SO_RCV, ng_btsocket_rfcomm_upcall, NULL); 1303 SOCKBUF_UNLOCK(&l2so->so_rcv); 1304 SOCKBUF_LOCK(&l2so->so_snd); 1305 soupcall_set(l2so, SO_SND, ng_btsocket_rfcomm_upcall, NULL); 1306 SOCKBUF_UNLOCK(&l2so->so_snd); 1307 l2so->so_state |= SS_NBIO; 1308 s->l2so = l2so; 1309 1310 mtx_lock(&s->session_mtx); 1311 1312 /* 1313 * "src" == NULL and "dst" == NULL means just create session. 1314 * caller must do the rest 1315 */ 1316 1317 if (src == NULL && dst == NULL) 1318 goto done; 1319 1320 /* 1321 * Set incoming MTU on L2CAP socket. It is RFCOMM session default MTU 1322 * plus 5 bytes: RFCOMM frame header, one extra byte for length and one 1323 * extra byte for credits. 1324 */ 1325 1326 mtu = s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1; 1327 1328 l2sopt.sopt_dir = SOPT_SET; 1329 l2sopt.sopt_level = SOL_L2CAP; 1330 l2sopt.sopt_name = SO_L2CAP_IMTU; 1331 l2sopt.sopt_val = (void *) &mtu; 1332 l2sopt.sopt_valsize = sizeof(mtu); 1333 l2sopt.sopt_td = NULL; 1334 1335 error = sosetopt(s->l2so, &l2sopt); 1336 if (error != 0) 1337 goto bad; 1338 1339 /* Bind socket to "src" address */ 1340 l2sa.l2cap_len = sizeof(l2sa); 1341 l2sa.l2cap_family = AF_BLUETOOTH; 1342 l2sa.l2cap_psm = (dst == NULL)? htole16(NG_L2CAP_PSM_RFCOMM) : 0; 1343 bcopy(src, &l2sa.l2cap_bdaddr, sizeof(l2sa.l2cap_bdaddr)); 1344 l2sa.l2cap_cid = 0; 1345 l2sa.l2cap_bdaddr_type = BDADDR_BREDR; 1346 1347 error = sobind(s->l2so, (struct sockaddr *) &l2sa, td); 1348 if (error != 0) 1349 goto bad; 1350 1351 /* If "dst" is not NULL then initiate connect(), otherwise listen() */ 1352 if (dst == NULL) { 1353 s->flags = 0; 1354 s->state = NG_BTSOCKET_RFCOMM_SESSION_LISTENING; 1355 1356 error = solisten(s->l2so, 10, td); 1357 if (error != 0) 1358 goto bad; 1359 } else { 1360 s->flags = NG_BTSOCKET_RFCOMM_SESSION_INITIATOR; 1361 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTING; 1362 1363 l2sa.l2cap_len = sizeof(l2sa); 1364 l2sa.l2cap_family = AF_BLUETOOTH; 1365 l2sa.l2cap_psm = htole16(NG_L2CAP_PSM_RFCOMM); 1366 bcopy(dst, &l2sa.l2cap_bdaddr, sizeof(l2sa.l2cap_bdaddr)); 1367 l2sa.l2cap_cid = 0; 1368 l2sa.l2cap_bdaddr_type = BDADDR_BREDR; 1369 1370 error = soconnect(s->l2so, (struct sockaddr *) &l2sa, td); 1371 if (error != 0) 1372 goto bad; 1373 } 1374 1375 done: 1376 LIST_INSERT_HEAD(&ng_btsocket_rfcomm_sessions, s, next); 1377 *sp = s; 1378 1379 mtx_unlock(&s->session_mtx); 1380 1381 return (0); 1382 1383 bad: 1384 mtx_unlock(&s->session_mtx); 1385 1386 /* Return L2CAP socket back to its original state */ 1387 SOCKBUF_LOCK(&l2so->so_rcv); 1388 soupcall_clear(s->l2so, SO_RCV); 1389 SOCKBUF_UNLOCK(&l2so->so_rcv); 1390 SOCKBUF_LOCK(&l2so->so_snd); 1391 soupcall_clear(s->l2so, SO_SND); 1392 SOCKBUF_UNLOCK(&l2so->so_snd); 1393 l2so->so_state &= ~SS_NBIO; 1394 1395 mtx_destroy(&s->session_mtx); 1396 bzero(s, sizeof(*s)); 1397 free(s, M_NETGRAPH_BTSOCKET_RFCOMM); 1398 1399 return (error); 1400 } /* ng_btsocket_rfcomm_session_create */ 1401 1402 /* 1403 * Process accept() on RFCOMM session 1404 * XXX FIXME locking for "l2so"? 1405 */ 1406 1407 static int 1408 ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0) 1409 { 1410 struct socket *l2so; 1411 struct sockaddr_l2cap *l2sa = NULL; 1412 ng_btsocket_l2cap_pcb_t *l2pcb = NULL; 1413 ng_btsocket_rfcomm_session_p s = NULL; 1414 int error; 1415 1416 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1417 mtx_assert(&s0->session_mtx, MA_OWNED); 1418 1419 SOLISTEN_LOCK(s0->l2so); 1420 error = solisten_dequeue(s0->l2so, &l2so, 0); 1421 if (error == EWOULDBLOCK) 1422 return (error); 1423 if (error) { 1424 NG_BTSOCKET_RFCOMM_ERR( 1425 "%s: Could not accept connection on L2CAP socket, error=%d\n", __func__, error); 1426 return (error); 1427 } 1428 1429 error = soaccept(l2so, (struct sockaddr **) &l2sa); 1430 if (error != 0) { 1431 NG_BTSOCKET_RFCOMM_ERR( 1432 "%s: soaccept() on L2CAP socket failed, error=%d\n", __func__, error); 1433 soclose(l2so); 1434 1435 return (error); 1436 } 1437 1438 /* 1439 * Check if there is already active RFCOMM session between two devices. 1440 * If so then close L2CAP connection. We only support one RFCOMM session 1441 * between each pair of devices. Note that here we assume session in any 1442 * state. The session even could be in the middle of disconnecting. 1443 */ 1444 1445 l2pcb = so2l2cap_pcb(l2so); 1446 s = ng_btsocket_rfcomm_session_by_addr(&l2pcb->src, &l2pcb->dst); 1447 if (s == NULL) { 1448 /* Create a new RFCOMM session */ 1449 error = ng_btsocket_rfcomm_session_create(&s, l2so, NULL, NULL, 1450 curthread /* XXX */); 1451 if (error == 0) { 1452 mtx_lock(&s->session_mtx); 1453 1454 s->flags = 0; 1455 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED; 1456 1457 /* 1458 * Adjust MTU on incoming connection. Reserve 5 bytes: 1459 * RFCOMM frame header, one extra byte for length and 1460 * one extra byte for credits. 1461 */ 1462 1463 s->mtu = min(l2pcb->imtu, l2pcb->omtu) - 1464 sizeof(struct rfcomm_frame_hdr) - 1 - 1; 1465 1466 mtx_unlock(&s->session_mtx); 1467 } else { 1468 NG_BTSOCKET_RFCOMM_ALERT( 1469 "%s: Failed to create new RFCOMM session, error=%d\n", __func__, error); 1470 1471 soclose(l2so); 1472 } 1473 } else { 1474 NG_BTSOCKET_RFCOMM_WARN( 1475 "%s: Rejecting duplicating RFCOMM session between src=%x:%x:%x:%x:%x:%x and " \ 1476 "dst=%x:%x:%x:%x:%x:%x, state=%d, flags=%#x\n", __func__, 1477 l2pcb->src.b[5], l2pcb->src.b[4], l2pcb->src.b[3], 1478 l2pcb->src.b[2], l2pcb->src.b[1], l2pcb->src.b[0], 1479 l2pcb->dst.b[5], l2pcb->dst.b[4], l2pcb->dst.b[3], 1480 l2pcb->dst.b[2], l2pcb->dst.b[1], l2pcb->dst.b[0], 1481 s->state, s->flags); 1482 1483 error = EBUSY; 1484 soclose(l2so); 1485 } 1486 1487 return (error); 1488 } /* ng_btsocket_rfcomm_session_accept */ 1489 1490 /* 1491 * Process connect() on RFCOMM session 1492 * XXX FIXME locking for "l2so"? 1493 */ 1494 1495 static int 1496 ng_btsocket_rfcomm_session_connect(ng_btsocket_rfcomm_session_p s) 1497 { 1498 ng_btsocket_l2cap_pcb_p l2pcb = so2l2cap_pcb(s->l2so); 1499 int error; 1500 1501 mtx_assert(&s->session_mtx, MA_OWNED); 1502 1503 /* First check if connection has failed */ 1504 if ((error = s->l2so->so_error) != 0) { 1505 s->l2so->so_error = 0; 1506 1507 NG_BTSOCKET_RFCOMM_ERR( 1508 "%s: Could not connect RFCOMM session, error=%d, state=%d, flags=%#x\n", 1509 __func__, error, s->state, s->flags); 1510 1511 return (error); 1512 } 1513 1514 /* Is connection still in progress? */ 1515 if (s->l2so->so_state & SS_ISCONNECTING) 1516 return (0); 1517 1518 /* 1519 * If we got here then we are connected. Send SABM on DLCI 0 to 1520 * open multiplexor channel. 1521 */ 1522 1523 if (error == 0) { 1524 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED; 1525 1526 /* 1527 * Adjust MTU on outgoing connection. Reserve 5 bytes: RFCOMM 1528 * frame header, one extra byte for length and one extra byte 1529 * for credits. 1530 */ 1531 1532 s->mtu = min(l2pcb->imtu, l2pcb->omtu) - 1533 sizeof(struct rfcomm_frame_hdr) - 1 - 1; 1534 1535 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_SABM,0); 1536 if (error == 0) 1537 error = ng_btsocket_rfcomm_task_wakeup(); 1538 } 1539 1540 return (error); 1541 }/* ng_btsocket_rfcomm_session_connect */ 1542 1543 /* 1544 * Receive data on RFCOMM session 1545 * XXX FIXME locking for "l2so"? 1546 */ 1547 1548 static int 1549 ng_btsocket_rfcomm_session_receive(ng_btsocket_rfcomm_session_p s) 1550 { 1551 struct mbuf *m = NULL; 1552 struct uio uio; 1553 int more, flags, error; 1554 1555 mtx_assert(&s->session_mtx, MA_OWNED); 1556 1557 /* Can we read from the L2CAP socket? */ 1558 if (!soreadable(s->l2so)) 1559 return (0); 1560 1561 /* First check for error on L2CAP socket */ 1562 if ((error = s->l2so->so_error) != 0) { 1563 s->l2so->so_error = 0; 1564 1565 NG_BTSOCKET_RFCOMM_ERR( 1566 "%s: Could not receive data from L2CAP socket, error=%d, state=%d, flags=%#x\n", 1567 __func__, error, s->state, s->flags); 1568 1569 return (error); 1570 } 1571 1572 /* 1573 * Read all packets from the L2CAP socket. 1574 * XXX FIXME/VERIFY is that correct? For now use m->m_nextpkt as 1575 * indication that there is more packets on the socket's buffer. 1576 * Also what should we use in uio.uio_resid? 1577 * May be s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1? 1578 */ 1579 1580 for (more = 1; more; ) { 1581 /* Try to get next packet from socket */ 1582 bzero(&uio, sizeof(uio)); 1583 /* uio.uio_td = NULL; */ 1584 uio.uio_resid = 1000000000; 1585 flags = MSG_DONTWAIT; 1586 1587 m = NULL; 1588 error = soreceive(s->l2so, NULL, &uio, &m, 1589 (struct mbuf **) NULL, &flags); 1590 if (error != 0) { 1591 if (error == EWOULDBLOCK) 1592 return (0); /* XXX can happen? */ 1593 1594 NG_BTSOCKET_RFCOMM_ERR( 1595 "%s: Could not receive data from L2CAP socket, error=%d\n", __func__, error); 1596 1597 return (error); 1598 } 1599 1600 more = (m->m_nextpkt != NULL); 1601 m->m_nextpkt = NULL; 1602 1603 ng_btsocket_rfcomm_receive_frame(s, m); 1604 } 1605 1606 return (0); 1607 } /* ng_btsocket_rfcomm_session_receive */ 1608 1609 /* 1610 * Send data on RFCOMM session 1611 * XXX FIXME locking for "l2so"? 1612 */ 1613 1614 static int 1615 ng_btsocket_rfcomm_session_send(ng_btsocket_rfcomm_session_p s) 1616 { 1617 struct mbuf *m = NULL; 1618 int error; 1619 1620 mtx_assert(&s->session_mtx, MA_OWNED); 1621 1622 /* Send as much as we can from the session queue */ 1623 while (sowriteable(s->l2so)) { 1624 /* Check if socket still OK */ 1625 if ((error = s->l2so->so_error) != 0) { 1626 s->l2so->so_error = 0; 1627 1628 NG_BTSOCKET_RFCOMM_ERR( 1629 "%s: Detected error=%d on L2CAP socket, state=%d, flags=%#x\n", 1630 __func__, error, s->state, s->flags); 1631 1632 return (error); 1633 } 1634 1635 NG_BT_MBUFQ_DEQUEUE(&s->outq, m); 1636 if (m == NULL) 1637 return (0); /* we are done */ 1638 1639 /* Call send function on the L2CAP socket */ 1640 error = s->l2so->so_proto->pr_send(s->l2so, 0, m, NULL, NULL, 1641 curthread /* XXX */); 1642 if (error != 0) { 1643 NG_BTSOCKET_RFCOMM_ERR( 1644 "%s: Could not send data to L2CAP socket, error=%d\n", __func__, error); 1645 1646 return (error); 1647 } 1648 } 1649 1650 return (0); 1651 } /* ng_btsocket_rfcomm_session_send */ 1652 1653 /* 1654 * Close and disconnect all DLCs for the given session. Caller must hold 1655 * s->sesson_mtx. Will wakeup session. 1656 */ 1657 1658 static void 1659 ng_btsocket_rfcomm_session_clean(ng_btsocket_rfcomm_session_p s) 1660 { 1661 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1662 int error; 1663 1664 mtx_assert(&s->session_mtx, MA_OWNED); 1665 1666 /* 1667 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1668 * will unlink DLC from the session 1669 */ 1670 1671 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1672 mtx_lock(&pcb->pcb_mtx); 1673 pcb_next = LIST_NEXT(pcb, session_next); 1674 1675 NG_BTSOCKET_RFCOMM_INFO( 1676 "%s: Disconnecting dlci=%d, state=%d, flags=%#x\n", 1677 __func__, pcb->dlci, pcb->state, pcb->flags); 1678 1679 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 1680 error = ECONNRESET; 1681 else 1682 error = ECONNREFUSED; 1683 1684 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1685 1686 mtx_unlock(&pcb->pcb_mtx); 1687 pcb = pcb_next; 1688 } 1689 } /* ng_btsocket_rfcomm_session_clean */ 1690 1691 /* 1692 * Process all DLCs on the session. Caller MUST hold s->session_mtx. 1693 */ 1694 1695 static void 1696 ng_btsocket_rfcomm_session_process_pcb(ng_btsocket_rfcomm_session_p s) 1697 { 1698 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1699 int error; 1700 1701 mtx_assert(&s->session_mtx, MA_OWNED); 1702 1703 /* 1704 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1705 * will unlink DLC from the session 1706 */ 1707 1708 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1709 mtx_lock(&pcb->pcb_mtx); 1710 pcb_next = LIST_NEXT(pcb, session_next); 1711 1712 switch (pcb->state) { 1713 /* 1714 * If DLC in W4_CONNECT state then we should check for both 1715 * timeout and detach. 1716 */ 1717 1718 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 1719 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_DETACHED) 1720 ng_btsocket_rfcomm_pcb_kill(pcb, 0); 1721 else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1722 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1723 break; 1724 1725 /* 1726 * If DLC in CONFIGURING or CONNECTING state then we only 1727 * should check for timeout. If detach() was called then 1728 * DLC will be moved into DISCONNECTING state. 1729 */ 1730 1731 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 1732 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 1733 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1734 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1735 break; 1736 1737 /* 1738 * If DLC in CONNECTED state then we need to send data (if any) 1739 * from the socket's send queue. Note that we will send data 1740 * from either all sockets or none. This may overload session's 1741 * outgoing queue (but we do not check for that). 1742 * 1743 * XXX FIXME need scheduler for RFCOMM sockets 1744 */ 1745 1746 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 1747 error = ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 1748 if (error != 0) 1749 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1750 break; 1751 1752 /* 1753 * If DLC in DISCONNECTING state then we must send DISC frame. 1754 * Note that if DLC has timeout set then we do not need to 1755 * resend DISC frame. 1756 * 1757 * XXX FIXME need to drain all data from the socket's queue 1758 * if LINGER option was set 1759 */ 1760 1761 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 1762 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) { 1763 error = ng_btsocket_rfcomm_send_command( 1764 pcb->session, RFCOMM_FRAME_DISC, 1765 pcb->dlci); 1766 if (error == 0) 1767 ng_btsocket_rfcomm_timeout(pcb); 1768 else 1769 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1770 } else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1771 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1772 break; 1773 1774 /* case NG_BTSOCKET_RFCOMM_DLC_CLOSED: */ 1775 default: 1776 panic("%s: Invalid DLC state=%d, flags=%#x\n", 1777 __func__, pcb->state, pcb->flags); 1778 break; 1779 } 1780 1781 mtx_unlock(&pcb->pcb_mtx); 1782 pcb = pcb_next; 1783 } 1784 } /* ng_btsocket_rfcomm_session_process_pcb */ 1785 1786 /* 1787 * Find RFCOMM session between "src" and "dst". 1788 * Caller MUST hold ng_btsocket_rfcomm_sessions_mtx. 1789 */ 1790 1791 static ng_btsocket_rfcomm_session_p 1792 ng_btsocket_rfcomm_session_by_addr(bdaddr_p src, bdaddr_p dst) 1793 { 1794 ng_btsocket_rfcomm_session_p s = NULL; 1795 ng_btsocket_l2cap_pcb_p l2pcb = NULL; 1796 int any_src; 1797 1798 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1799 1800 any_src = (bcmp(src, NG_HCI_BDADDR_ANY, sizeof(*src)) == 0); 1801 1802 LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next) { 1803 l2pcb = so2l2cap_pcb(s->l2so); 1804 1805 if ((any_src || bcmp(&l2pcb->src, src, sizeof(*src)) == 0) && 1806 bcmp(&l2pcb->dst, dst, sizeof(*dst)) == 0) 1807 break; 1808 } 1809 1810 return (s); 1811 } /* ng_btsocket_rfcomm_session_by_addr */ 1812 1813 /***************************************************************************** 1814 ***************************************************************************** 1815 ** RFCOMM 1816 ***************************************************************************** 1817 *****************************************************************************/ 1818 1819 /* 1820 * Process incoming RFCOMM frame. Caller must hold s->session_mtx. 1821 * XXX FIXME check frame length 1822 */ 1823 1824 static int 1825 ng_btsocket_rfcomm_receive_frame(ng_btsocket_rfcomm_session_p s, 1826 struct mbuf *m0) 1827 { 1828 struct rfcomm_frame_hdr *hdr = NULL; 1829 struct mbuf *m = NULL; 1830 u_int16_t length; 1831 u_int8_t dlci, type; 1832 int error = 0; 1833 1834 mtx_assert(&s->session_mtx, MA_OWNED); 1835 1836 /* Pullup as much as we can into first mbuf (for direct access) */ 1837 length = min(m0->m_pkthdr.len, MHLEN); 1838 if (m0->m_len < length) { 1839 if ((m0 = m_pullup(m0, length)) == NULL) { 1840 NG_BTSOCKET_RFCOMM_ALERT( 1841 "%s: m_pullup(%d) failed\n", __func__, length); 1842 1843 return (ENOBUFS); 1844 } 1845 } 1846 1847 hdr = mtod(m0, struct rfcomm_frame_hdr *); 1848 dlci = RFCOMM_DLCI(hdr->address); 1849 type = RFCOMM_TYPE(hdr->control); 1850 1851 /* Test EA bit in length. If not set then we have 2 bytes of length */ 1852 if (!RFCOMM_EA(hdr->length)) { 1853 bcopy(&hdr->length, &length, sizeof(length)); 1854 length = le16toh(length) >> 1; 1855 m_adj(m0, sizeof(*hdr) + 1); 1856 } else { 1857 length = hdr->length >> 1; 1858 m_adj(m0, sizeof(*hdr)); 1859 } 1860 1861 NG_BTSOCKET_RFCOMM_INFO( 1862 "%s: Got frame type=%#x, dlci=%d, length=%d, cr=%d, pf=%d, len=%d\n", 1863 __func__, type, dlci, length, RFCOMM_CR(hdr->address), 1864 RFCOMM_PF(hdr->control), m0->m_pkthdr.len); 1865 1866 /* 1867 * Get FCS (the last byte in the frame) 1868 * XXX this will not work if mbuf chain ends with empty mbuf. 1869 * XXX let's hope it never happens :) 1870 */ 1871 1872 for (m = m0; m->m_next != NULL; m = m->m_next) 1873 ; 1874 if (m->m_len <= 0) 1875 panic("%s: Empty mbuf at the end of the chain, len=%d\n", 1876 __func__, m->m_len); 1877 1878 /* 1879 * Check FCS. We only need to calculate FCS on first 2 or 3 bytes 1880 * and already m_pullup'ed mbuf chain, so it should be safe. 1881 */ 1882 1883 if (ng_btsocket_rfcomm_check_fcs((u_int8_t *) hdr, type, m->m_data[m->m_len - 1])) { 1884 NG_BTSOCKET_RFCOMM_ERR( 1885 "%s: Invalid RFCOMM packet. Bad checksum\n", __func__); 1886 NG_FREE_M(m0); 1887 1888 return (EINVAL); 1889 } 1890 1891 m_adj(m0, -1); /* Trim FCS byte */ 1892 1893 /* 1894 * Process RFCOMM frame. 1895 * 1896 * From TS 07.10 spec 1897 * 1898 * "... In the case where a SABM or DISC command with the P bit set 1899 * to 0 is received then the received frame shall be discarded..." 1900 * 1901 * "... If a unsolicited DM response is received then the frame shall 1902 * be processed irrespective of the P/F setting... " 1903 * 1904 * "... The station may transmit response frames with the F bit set 1905 * to 0 at any opportunity on an asynchronous basis. However, in the 1906 * case where a UA response is received with the F bit set to 0 then 1907 * the received frame shall be discarded..." 1908 * 1909 * From Bluetooth spec 1910 * 1911 * "... When credit based flow control is being used, the meaning of 1912 * the P/F bit in the control field of the RFCOMM header is redefined 1913 * for UIH frames..." 1914 */ 1915 1916 switch (type) { 1917 case RFCOMM_FRAME_SABM: 1918 if (RFCOMM_PF(hdr->control)) 1919 error = ng_btsocket_rfcomm_receive_sabm(s, dlci); 1920 break; 1921 1922 case RFCOMM_FRAME_DISC: 1923 if (RFCOMM_PF(hdr->control)) 1924 error = ng_btsocket_rfcomm_receive_disc(s, dlci); 1925 break; 1926 1927 case RFCOMM_FRAME_UA: 1928 if (RFCOMM_PF(hdr->control)) 1929 error = ng_btsocket_rfcomm_receive_ua(s, dlci); 1930 break; 1931 1932 case RFCOMM_FRAME_DM: 1933 error = ng_btsocket_rfcomm_receive_dm(s, dlci); 1934 break; 1935 1936 case RFCOMM_FRAME_UIH: 1937 if (dlci == 0) 1938 error = ng_btsocket_rfcomm_receive_mcc(s, m0); 1939 else 1940 error = ng_btsocket_rfcomm_receive_uih(s, dlci, 1941 RFCOMM_PF(hdr->control), m0); 1942 1943 return (error); 1944 /* NOT REACHED */ 1945 1946 default: 1947 NG_BTSOCKET_RFCOMM_ERR( 1948 "%s: Invalid RFCOMM packet. Unknown type=%#x\n", __func__, type); 1949 error = EINVAL; 1950 break; 1951 } 1952 1953 NG_FREE_M(m0); 1954 1955 return (error); 1956 } /* ng_btsocket_rfcomm_receive_frame */ 1957 1958 /* 1959 * Process RFCOMM SABM frame 1960 */ 1961 1962 static int 1963 ng_btsocket_rfcomm_receive_sabm(ng_btsocket_rfcomm_session_p s, int dlci) 1964 { 1965 ng_btsocket_rfcomm_pcb_p pcb = NULL; 1966 int error = 0; 1967 1968 mtx_assert(&s->session_mtx, MA_OWNED); 1969 1970 NG_BTSOCKET_RFCOMM_INFO( 1971 "%s: Got SABM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 1972 __func__, s->state, s->flags, s->mtu, dlci); 1973 1974 /* DLCI == 0 means open multiplexor channel */ 1975 if (dlci == 0) { 1976 switch (s->state) { 1977 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 1978 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 1979 error = ng_btsocket_rfcomm_send_command(s, 1980 RFCOMM_FRAME_UA, dlci); 1981 if (error == 0) { 1982 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 1983 ng_btsocket_rfcomm_connect_cfm(s); 1984 } else { 1985 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 1986 ng_btsocket_rfcomm_session_clean(s); 1987 } 1988 break; 1989 1990 default: 1991 NG_BTSOCKET_RFCOMM_WARN( 1992 "%s: Got SABM for session in invalid state state=%d, flags=%#x\n", 1993 __func__, s->state, s->flags); 1994 error = EINVAL; 1995 break; 1996 } 1997 1998 return (error); 1999 } 2000 2001 /* Make sure multiplexor channel is open */ 2002 if (s->state != NG_BTSOCKET_RFCOMM_SESSION_OPEN) { 2003 NG_BTSOCKET_RFCOMM_ERR( 2004 "%s: Got SABM for dlci=%d with multiplexor channel closed, state=%d, " \ 2005 "flags=%#x\n", __func__, dlci, s->state, s->flags); 2006 2007 return (EINVAL); 2008 } 2009 2010 /* 2011 * Check if we have this DLCI. This might happen when remote 2012 * peer uses PN command before actual open (SABM) happens. 2013 */ 2014 2015 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2016 if (pcb != NULL) { 2017 mtx_lock(&pcb->pcb_mtx); 2018 2019 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING) { 2020 NG_BTSOCKET_RFCOMM_ERR( 2021 "%s: Got SABM for dlci=%d in invalid state=%d, flags=%#x\n", 2022 __func__, dlci, pcb->state, pcb->flags); 2023 mtx_unlock(&pcb->pcb_mtx); 2024 2025 return (ENOENT); 2026 } 2027 2028 ng_btsocket_rfcomm_untimeout(pcb); 2029 2030 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci); 2031 if (error == 0) 2032 error = ng_btsocket_rfcomm_send_msc(pcb); 2033 2034 if (error == 0) { 2035 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2036 soisconnected(pcb->so); 2037 } else 2038 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2039 2040 mtx_unlock(&pcb->pcb_mtx); 2041 2042 return (error); 2043 } 2044 2045 /* 2046 * We do not have requested DLCI, so it must be an incoming connection 2047 * with default parameters. Try to accept it. 2048 */ 2049 2050 pcb = ng_btsocket_rfcomm_connect_ind(s, RFCOMM_SRVCHANNEL(dlci)); 2051 if (pcb != NULL) { 2052 mtx_lock(&pcb->pcb_mtx); 2053 2054 pcb->dlci = dlci; 2055 2056 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci); 2057 if (error == 0) 2058 error = ng_btsocket_rfcomm_send_msc(pcb); 2059 2060 if (error == 0) { 2061 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2062 soisconnected(pcb->so); 2063 } else 2064 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2065 2066 mtx_unlock(&pcb->pcb_mtx); 2067 } else 2068 /* Nobody is listen()ing on the requested DLCI */ 2069 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2070 2071 return (error); 2072 } /* ng_btsocket_rfcomm_receive_sabm */ 2073 2074 /* 2075 * Process RFCOMM DISC frame 2076 */ 2077 2078 static int 2079 ng_btsocket_rfcomm_receive_disc(ng_btsocket_rfcomm_session_p s, int dlci) 2080 { 2081 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2082 int error = 0; 2083 2084 mtx_assert(&s->session_mtx, MA_OWNED); 2085 2086 NG_BTSOCKET_RFCOMM_INFO( 2087 "%s: Got DISC, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2088 __func__, s->state, s->flags, s->mtu, dlci); 2089 2090 /* DLCI == 0 means close multiplexor channel */ 2091 if (dlci == 0) { 2092 /* XXX FIXME assume that remote side will close the socket */ 2093 error = ng_btsocket_rfcomm_send_command(s, RFCOMM_FRAME_UA, 0); 2094 if (error == 0) { 2095 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING) 2096 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2097 else 2098 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 2099 } else 2100 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2101 2102 ng_btsocket_rfcomm_session_clean(s); 2103 } else { 2104 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2105 if (pcb != NULL) { 2106 int err; 2107 2108 mtx_lock(&pcb->pcb_mtx); 2109 2110 NG_BTSOCKET_RFCOMM_INFO( 2111 "%s: Got DISC for dlci=%d, state=%d, flags=%#x\n", 2112 __func__, dlci, pcb->state, pcb->flags); 2113 2114 error = ng_btsocket_rfcomm_send_command(s, 2115 RFCOMM_FRAME_UA, dlci); 2116 2117 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2118 err = 0; 2119 else 2120 err = ECONNREFUSED; 2121 2122 ng_btsocket_rfcomm_pcb_kill(pcb, err); 2123 2124 mtx_unlock(&pcb->pcb_mtx); 2125 } else { 2126 NG_BTSOCKET_RFCOMM_WARN( 2127 "%s: Got DISC for non-existing dlci=%d\n", __func__, dlci); 2128 2129 error = ng_btsocket_rfcomm_send_command(s, 2130 RFCOMM_FRAME_DM, dlci); 2131 } 2132 } 2133 2134 return (error); 2135 } /* ng_btsocket_rfcomm_receive_disc */ 2136 2137 /* 2138 * Process RFCOMM UA frame 2139 */ 2140 2141 static int 2142 ng_btsocket_rfcomm_receive_ua(ng_btsocket_rfcomm_session_p s, int dlci) 2143 { 2144 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2145 int error = 0; 2146 2147 mtx_assert(&s->session_mtx, MA_OWNED); 2148 2149 NG_BTSOCKET_RFCOMM_INFO( 2150 "%s: Got UA, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2151 __func__, s->state, s->flags, s->mtu, dlci); 2152 2153 /* dlci == 0 means multiplexor channel */ 2154 if (dlci == 0) { 2155 switch (s->state) { 2156 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 2157 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 2158 ng_btsocket_rfcomm_connect_cfm(s); 2159 break; 2160 2161 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 2162 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2163 ng_btsocket_rfcomm_session_clean(s); 2164 break; 2165 2166 default: 2167 NG_BTSOCKET_RFCOMM_WARN( 2168 "%s: Got UA for session in invalid state=%d(%d), flags=%#x, mtu=%d\n", 2169 __func__, s->state, INITIATOR(s), s->flags, 2170 s->mtu); 2171 error = ENOENT; 2172 break; 2173 } 2174 2175 return (error); 2176 } 2177 2178 /* Check if we have this DLCI */ 2179 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2180 if (pcb != NULL) { 2181 mtx_lock(&pcb->pcb_mtx); 2182 2183 NG_BTSOCKET_RFCOMM_INFO( 2184 "%s: Got UA for dlci=%d, state=%d, flags=%#x\n", 2185 __func__, dlci, pcb->state, pcb->flags); 2186 2187 switch (pcb->state) { 2188 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 2189 ng_btsocket_rfcomm_untimeout(pcb); 2190 2191 error = ng_btsocket_rfcomm_send_msc(pcb); 2192 if (error == 0) { 2193 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2194 soisconnected(pcb->so); 2195 } 2196 break; 2197 2198 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 2199 ng_btsocket_rfcomm_pcb_kill(pcb, 0); 2200 break; 2201 2202 default: 2203 NG_BTSOCKET_RFCOMM_WARN( 2204 "%s: Got UA for dlci=%d in invalid state=%d, flags=%#x\n", 2205 __func__, dlci, pcb->state, pcb->flags); 2206 error = ENOENT; 2207 break; 2208 } 2209 2210 mtx_unlock(&pcb->pcb_mtx); 2211 } else { 2212 NG_BTSOCKET_RFCOMM_WARN( 2213 "%s: Got UA for non-existing dlci=%d\n", __func__, dlci); 2214 2215 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2216 } 2217 2218 return (error); 2219 } /* ng_btsocket_rfcomm_receive_ua */ 2220 2221 /* 2222 * Process RFCOMM DM frame 2223 */ 2224 2225 static int 2226 ng_btsocket_rfcomm_receive_dm(ng_btsocket_rfcomm_session_p s, int dlci) 2227 { 2228 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2229 int error; 2230 2231 mtx_assert(&s->session_mtx, MA_OWNED); 2232 2233 NG_BTSOCKET_RFCOMM_INFO( 2234 "%s: Got DM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2235 __func__, s->state, s->flags, s->mtu, dlci); 2236 2237 /* DLCI == 0 means multiplexor channel */ 2238 if (dlci == 0) { 2239 /* Disconnect all dlc's on the session */ 2240 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2241 ng_btsocket_rfcomm_session_clean(s); 2242 } else { 2243 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2244 if (pcb != NULL) { 2245 mtx_lock(&pcb->pcb_mtx); 2246 2247 NG_BTSOCKET_RFCOMM_INFO( 2248 "%s: Got DM for dlci=%d, state=%d, flags=%#x\n", 2249 __func__, dlci, pcb->state, pcb->flags); 2250 2251 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2252 error = ECONNRESET; 2253 else 2254 error = ECONNREFUSED; 2255 2256 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2257 2258 mtx_unlock(&pcb->pcb_mtx); 2259 } else 2260 NG_BTSOCKET_RFCOMM_WARN( 2261 "%s: Got DM for non-existing dlci=%d\n", __func__, dlci); 2262 } 2263 2264 return (0); 2265 } /* ng_btsocket_rfcomm_receive_dm */ 2266 2267 /* 2268 * Process RFCOMM UIH frame (data) 2269 */ 2270 2271 static int 2272 ng_btsocket_rfcomm_receive_uih(ng_btsocket_rfcomm_session_p s, int dlci, 2273 int pf, struct mbuf *m0) 2274 { 2275 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2276 int error = 0; 2277 2278 mtx_assert(&s->session_mtx, MA_OWNED); 2279 2280 NG_BTSOCKET_RFCOMM_INFO( 2281 "%s: Got UIH, session state=%d, flags=%#x, mtu=%d, dlci=%d, pf=%d, len=%d\n", 2282 __func__, s->state, s->flags, s->mtu, dlci, pf, 2283 m0->m_pkthdr.len); 2284 2285 /* XXX should we do it here? Check for session flow control */ 2286 if (s->flags & NG_BTSOCKET_RFCOMM_SESSION_LFC) { 2287 NG_BTSOCKET_RFCOMM_WARN( 2288 "%s: Got UIH with session flow control asserted, state=%d, flags=%#x\n", 2289 __func__, s->state, s->flags); 2290 goto drop; 2291 } 2292 2293 /* Check if we have this dlci */ 2294 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2295 if (pcb == NULL) { 2296 NG_BTSOCKET_RFCOMM_WARN( 2297 "%s: Got UIH for non-existing dlci=%d\n", __func__, dlci); 2298 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2299 goto drop; 2300 } 2301 2302 mtx_lock(&pcb->pcb_mtx); 2303 2304 /* Check dlci state */ 2305 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2306 NG_BTSOCKET_RFCOMM_WARN( 2307 "%s: Got UIH for dlci=%d in invalid state=%d, flags=%#x\n", 2308 __func__, dlci, pcb->state, pcb->flags); 2309 error = EINVAL; 2310 goto drop1; 2311 } 2312 2313 /* Check dlci flow control */ 2314 if (((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pcb->rx_cred <= 0) || 2315 (pcb->lmodem & RFCOMM_MODEM_FC)) { 2316 NG_BTSOCKET_RFCOMM_ERR( 2317 "%s: Got UIH for dlci=%d with asserted flow control, state=%d, " \ 2318 "flags=%#x, rx_cred=%d, lmodem=%#x\n", 2319 __func__, dlci, pcb->state, pcb->flags, 2320 pcb->rx_cred, pcb->lmodem); 2321 goto drop1; 2322 } 2323 2324 /* Did we get any credits? */ 2325 if ((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pf) { 2326 NG_BTSOCKET_RFCOMM_INFO( 2327 "%s: Got %d more credits for dlci=%d, state=%d, flags=%#x, " \ 2328 "rx_cred=%d, tx_cred=%d\n", 2329 __func__, *mtod(m0, u_int8_t *), dlci, pcb->state, 2330 pcb->flags, pcb->rx_cred, pcb->tx_cred); 2331 2332 pcb->tx_cred += *mtod(m0, u_int8_t *); 2333 m_adj(m0, 1); 2334 2335 /* Send more from the DLC. XXX check for errors? */ 2336 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2337 } 2338 2339 /* OK the of the rest of the mbuf is the data */ 2340 if (m0->m_pkthdr.len > 0) { 2341 /* If we are using credit flow control decrease rx_cred here */ 2342 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2343 /* Give remote peer more credits (if needed) */ 2344 if (-- pcb->rx_cred <= RFCOMM_MAX_CREDITS / 2) 2345 ng_btsocket_rfcomm_send_credits(pcb); 2346 else 2347 NG_BTSOCKET_RFCOMM_INFO( 2348 "%s: Remote side still has credits, dlci=%d, state=%d, flags=%#x, " \ 2349 "rx_cred=%d, tx_cred=%d\n", __func__, dlci, pcb->state, pcb->flags, 2350 pcb->rx_cred, pcb->tx_cred); 2351 } 2352 2353 /* Check packet against mtu on dlci */ 2354 if (m0->m_pkthdr.len > pcb->mtu) { 2355 NG_BTSOCKET_RFCOMM_ERR( 2356 "%s: Got oversized UIH for dlci=%d, state=%d, flags=%#x, mtu=%d, len=%d\n", 2357 __func__, dlci, pcb->state, pcb->flags, 2358 pcb->mtu, m0->m_pkthdr.len); 2359 2360 error = EMSGSIZE; 2361 } else if (m0->m_pkthdr.len > sbspace(&pcb->so->so_rcv)) { 2362 /* 2363 * 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 || !SOLISTENING(pcb->so)) 3403 continue; 3404 3405 if (bcmp(&pcb->src, src, sizeof(*src)) == 0) 3406 break; 3407 3408 if (bcmp(&pcb->src, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0) 3409 pcb1 = pcb; 3410 } 3411 3412 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 3413 3414 return ((pcb != NULL)? pcb : pcb1); 3415 } /* ng_btsocket_rfcomm_pcb_listener */ 3416 3417 /***************************************************************************** 3418 ***************************************************************************** 3419 ** Misc. functions 3420 ***************************************************************************** 3421 *****************************************************************************/ 3422 3423 /* 3424 * Set timeout. Caller MUST hold pcb_mtx 3425 */ 3426 3427 static void 3428 ng_btsocket_rfcomm_timeout(ng_btsocket_rfcomm_pcb_p pcb) 3429 { 3430 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3431 3432 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) { 3433 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMO; 3434 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3435 callout_reset(&pcb->timo, ng_btsocket_rfcomm_timo * hz, 3436 ng_btsocket_rfcomm_process_timeout, pcb); 3437 } else 3438 panic("%s: Duplicated socket timeout?!\n", __func__); 3439 } /* ng_btsocket_rfcomm_timeout */ 3440 3441 /* 3442 * Unset pcb timeout. Caller MUST hold pcb_mtx 3443 */ 3444 3445 static void 3446 ng_btsocket_rfcomm_untimeout(ng_btsocket_rfcomm_pcb_p pcb) 3447 { 3448 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3449 3450 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) { 3451 callout_stop(&pcb->timo); 3452 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO; 3453 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3454 } else 3455 panic("%s: No socket timeout?!\n", __func__); 3456 } /* ng_btsocket_rfcomm_timeout */ 3457 3458 /* 3459 * Process pcb timeout 3460 */ 3461 3462 static void 3463 ng_btsocket_rfcomm_process_timeout(void *xpcb) 3464 { 3465 ng_btsocket_rfcomm_pcb_p pcb = (ng_btsocket_rfcomm_pcb_p) xpcb; 3466 3467 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3468 3469 NG_BTSOCKET_RFCOMM_INFO( 3470 "%s: Timeout, so=%p, dlci=%d, state=%d, flags=%#x\n", 3471 __func__, pcb->so, pcb->dlci, pcb->state, pcb->flags); 3472 3473 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO; 3474 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3475 3476 switch (pcb->state) { 3477 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 3478 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 3479 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 3480 break; 3481 3482 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 3483 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 3484 break; 3485 3486 default: 3487 panic( 3488 "%s: DLC timeout in invalid state, dlci=%d, state=%d, flags=%#x\n", 3489 __func__, pcb->dlci, pcb->state, pcb->flags); 3490 break; 3491 } 3492 3493 ng_btsocket_rfcomm_task_wakeup(); 3494 } /* ng_btsocket_rfcomm_process_timeout */ 3495 3496 /* 3497 * Get up to length bytes from the socket buffer 3498 */ 3499 3500 static struct mbuf * 3501 ng_btsocket_rfcomm_prepare_packet(struct sockbuf *sb, int length) 3502 { 3503 struct mbuf *top = NULL, *m = NULL, *n = NULL, *nextpkt = NULL; 3504 int mlen, noff, len; 3505 3506 MGETHDR(top, M_NOWAIT, MT_DATA); 3507 if (top == NULL) 3508 return (NULL); 3509 3510 top->m_pkthdr.len = length; 3511 top->m_len = 0; 3512 mlen = MHLEN; 3513 3514 m = top; 3515 n = sb->sb_mb; 3516 nextpkt = n->m_nextpkt; 3517 noff = 0; 3518 3519 while (length > 0 && n != NULL) { 3520 len = min(mlen - m->m_len, n->m_len - noff); 3521 if (len > length) 3522 len = length; 3523 3524 bcopy(mtod(n, caddr_t)+noff, mtod(m, caddr_t)+m->m_len, len); 3525 m->m_len += len; 3526 noff += len; 3527 length -= len; 3528 3529 if (length > 0 && m->m_len == mlen) { 3530 MGET(m->m_next, M_NOWAIT, MT_DATA); 3531 if (m->m_next == NULL) { 3532 NG_FREE_M(top); 3533 return (NULL); 3534 } 3535 3536 m = m->m_next; 3537 m->m_len = 0; 3538 mlen = MLEN; 3539 } 3540 3541 if (noff == n->m_len) { 3542 noff = 0; 3543 n = n->m_next; 3544 3545 if (n == NULL) 3546 n = nextpkt; 3547 3548 nextpkt = (n != NULL)? n->m_nextpkt : NULL; 3549 } 3550 } 3551 3552 if (length < 0) 3553 panic("%s: length=%d\n", __func__, length); 3554 if (length > 0 && n == NULL) 3555 panic("%s: bogus length=%d, n=%p\n", __func__, length, n); 3556 3557 return (top); 3558 } /* ng_btsocket_rfcomm_prepare_packet */ 3559