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