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