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); 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 1343 error = sobind(s->l2so, (struct sockaddr *) &l2sa, td); 1344 if (error != 0) 1345 goto bad; 1346 1347 /* If "dst" is not NULL then initiate connect(), otherwise listen() */ 1348 if (dst == NULL) { 1349 s->flags = 0; 1350 s->state = NG_BTSOCKET_RFCOMM_SESSION_LISTENING; 1351 1352 error = solisten(s->l2so, 10, td); 1353 if (error != 0) 1354 goto bad; 1355 } else { 1356 s->flags = NG_BTSOCKET_RFCOMM_SESSION_INITIATOR; 1357 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTING; 1358 1359 l2sa.l2cap_len = sizeof(l2sa); 1360 l2sa.l2cap_family = AF_BLUETOOTH; 1361 l2sa.l2cap_psm = htole16(NG_L2CAP_PSM_RFCOMM); 1362 bcopy(dst, &l2sa.l2cap_bdaddr, sizeof(l2sa.l2cap_bdaddr)); 1363 1364 error = soconnect(s->l2so, (struct sockaddr *) &l2sa, td); 1365 if (error != 0) 1366 goto bad; 1367 } 1368 1369 done: 1370 LIST_INSERT_HEAD(&ng_btsocket_rfcomm_sessions, s, next); 1371 *sp = s; 1372 1373 mtx_unlock(&s->session_mtx); 1374 1375 return (0); 1376 1377 bad: 1378 mtx_unlock(&s->session_mtx); 1379 1380 /* Return L2CAP socket back to its original state */ 1381 SOCKBUF_LOCK(&l2so->so_rcv); 1382 soupcall_clear(s->l2so, SO_RCV); 1383 SOCKBUF_UNLOCK(&l2so->so_rcv); 1384 SOCKBUF_LOCK(&l2so->so_snd); 1385 soupcall_clear(s->l2so, SO_SND); 1386 SOCKBUF_UNLOCK(&l2so->so_snd); 1387 l2so->so_state &= ~SS_NBIO; 1388 1389 mtx_destroy(&s->session_mtx); 1390 bzero(s, sizeof(*s)); 1391 free(s, M_NETGRAPH_BTSOCKET_RFCOMM); 1392 1393 return (error); 1394 } /* ng_btsocket_rfcomm_session_create */ 1395 1396 /* 1397 * Process accept() on RFCOMM session 1398 * XXX FIXME locking for "l2so"? 1399 */ 1400 1401 static int 1402 ng_btsocket_rfcomm_session_accept(ng_btsocket_rfcomm_session_p s0) 1403 { 1404 struct socket *l2so = NULL; 1405 struct sockaddr_l2cap *l2sa = NULL; 1406 ng_btsocket_l2cap_pcb_t *l2pcb = NULL; 1407 ng_btsocket_rfcomm_session_p s = NULL; 1408 int error = 0; 1409 1410 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1411 mtx_assert(&s0->session_mtx, MA_OWNED); 1412 1413 /* Check if there is a complete L2CAP connection in the queue */ 1414 if ((error = s0->l2so->so_error) != 0) { 1415 NG_BTSOCKET_RFCOMM_ERR( 1416 "%s: Could not accept connection on L2CAP socket, error=%d\n", __func__, error); 1417 s0->l2so->so_error = 0; 1418 1419 return (error); 1420 } 1421 1422 ACCEPT_LOCK(); 1423 if (TAILQ_EMPTY(&s0->l2so->so_comp)) { 1424 ACCEPT_UNLOCK(); 1425 if (s0->l2so->so_rcv.sb_state & SBS_CANTRCVMORE) 1426 return (ECONNABORTED); 1427 return (EWOULDBLOCK); 1428 } 1429 1430 /* Accept incoming L2CAP connection */ 1431 l2so = TAILQ_FIRST(&s0->l2so->so_comp); 1432 if (l2so == NULL) 1433 panic("%s: l2so == NULL\n", __func__); 1434 1435 TAILQ_REMOVE(&s0->l2so->so_comp, l2so, so_list); 1436 s0->l2so->so_qlen --; 1437 l2so->so_qstate &= ~SQ_COMP; 1438 l2so->so_head = NULL; 1439 SOCK_LOCK(l2so); 1440 soref(l2so); 1441 l2so->so_state |= SS_NBIO; 1442 SOCK_UNLOCK(l2so); 1443 ACCEPT_UNLOCK(); 1444 1445 error = soaccept(l2so, (struct sockaddr **) &l2sa); 1446 if (error != 0) { 1447 NG_BTSOCKET_RFCOMM_ERR( 1448 "%s: soaccept() on L2CAP socket failed, error=%d\n", __func__, error); 1449 soclose(l2so); 1450 1451 return (error); 1452 } 1453 1454 /* 1455 * Check if there is already active RFCOMM session between two devices. 1456 * If so then close L2CAP connection. We only support one RFCOMM session 1457 * between each pair of devices. Note that here we assume session in any 1458 * state. The session even could be in the middle of disconnecting. 1459 */ 1460 1461 l2pcb = so2l2cap_pcb(l2so); 1462 s = ng_btsocket_rfcomm_session_by_addr(&l2pcb->src, &l2pcb->dst); 1463 if (s == NULL) { 1464 /* Create a new RFCOMM session */ 1465 error = ng_btsocket_rfcomm_session_create(&s, l2so, NULL, NULL, 1466 curthread /* XXX */); 1467 if (error == 0) { 1468 mtx_lock(&s->session_mtx); 1469 1470 s->flags = 0; 1471 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED; 1472 1473 /* 1474 * Adjust MTU on incomming connection. Reserve 5 bytes: 1475 * RFCOMM frame header, one extra byte for length and 1476 * one extra byte for credits. 1477 */ 1478 1479 s->mtu = min(l2pcb->imtu, l2pcb->omtu) - 1480 sizeof(struct rfcomm_frame_hdr) - 1 - 1; 1481 1482 mtx_unlock(&s->session_mtx); 1483 } else { 1484 NG_BTSOCKET_RFCOMM_ALERT( 1485 "%s: Failed to create new RFCOMM session, error=%d\n", __func__, error); 1486 1487 soclose(l2so); 1488 } 1489 } else { 1490 NG_BTSOCKET_RFCOMM_WARN( 1491 "%s: Rejecting duplicating RFCOMM session between src=%x:%x:%x:%x:%x:%x and " \ 1492 "dst=%x:%x:%x:%x:%x:%x, state=%d, flags=%#x\n", __func__, 1493 l2pcb->src.b[5], l2pcb->src.b[4], l2pcb->src.b[3], 1494 l2pcb->src.b[2], l2pcb->src.b[1], l2pcb->src.b[0], 1495 l2pcb->dst.b[5], l2pcb->dst.b[4], l2pcb->dst.b[3], 1496 l2pcb->dst.b[2], l2pcb->dst.b[1], l2pcb->dst.b[0], 1497 s->state, s->flags); 1498 1499 error = EBUSY; 1500 soclose(l2so); 1501 } 1502 1503 return (error); 1504 } /* ng_btsocket_rfcomm_session_accept */ 1505 1506 /* 1507 * Process connect() on RFCOMM session 1508 * XXX FIXME locking for "l2so"? 1509 */ 1510 1511 static int 1512 ng_btsocket_rfcomm_session_connect(ng_btsocket_rfcomm_session_p s) 1513 { 1514 ng_btsocket_l2cap_pcb_p l2pcb = so2l2cap_pcb(s->l2so); 1515 int error; 1516 1517 mtx_assert(&s->session_mtx, MA_OWNED); 1518 1519 /* First check if connection has failed */ 1520 if ((error = s->l2so->so_error) != 0) { 1521 s->l2so->so_error = 0; 1522 1523 NG_BTSOCKET_RFCOMM_ERR( 1524 "%s: Could not connect RFCOMM session, error=%d, state=%d, flags=%#x\n", 1525 __func__, error, s->state, s->flags); 1526 1527 return (error); 1528 } 1529 1530 /* Is connection still in progress? */ 1531 if (s->l2so->so_state & SS_ISCONNECTING) 1532 return (0); 1533 1534 /* 1535 * If we got here then we are connected. Send SABM on DLCI 0 to 1536 * open multiplexor channel. 1537 */ 1538 1539 if (error == 0) { 1540 s->state = NG_BTSOCKET_RFCOMM_SESSION_CONNECTED; 1541 1542 /* 1543 * Adjust MTU on outgoing connection. Reserve 5 bytes: RFCOMM 1544 * frame header, one extra byte for length and one extra byte 1545 * for credits. 1546 */ 1547 1548 s->mtu = min(l2pcb->imtu, l2pcb->omtu) - 1549 sizeof(struct rfcomm_frame_hdr) - 1 - 1; 1550 1551 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_SABM,0); 1552 if (error == 0) 1553 error = ng_btsocket_rfcomm_task_wakeup(); 1554 } 1555 1556 return (error); 1557 }/* ng_btsocket_rfcomm_session_connect */ 1558 1559 /* 1560 * Receive data on RFCOMM session 1561 * XXX FIXME locking for "l2so"? 1562 */ 1563 1564 static int 1565 ng_btsocket_rfcomm_session_receive(ng_btsocket_rfcomm_session_p s) 1566 { 1567 struct mbuf *m = NULL; 1568 struct uio uio; 1569 int more, flags, error; 1570 1571 mtx_assert(&s->session_mtx, MA_OWNED); 1572 1573 /* Can we read from the L2CAP socket? */ 1574 if (!soreadable(s->l2so)) 1575 return (0); 1576 1577 /* First check for error on L2CAP socket */ 1578 if ((error = s->l2so->so_error) != 0) { 1579 s->l2so->so_error = 0; 1580 1581 NG_BTSOCKET_RFCOMM_ERR( 1582 "%s: Could not receive data from L2CAP socket, error=%d, state=%d, flags=%#x\n", 1583 __func__, error, s->state, s->flags); 1584 1585 return (error); 1586 } 1587 1588 /* 1589 * Read all packets from the L2CAP socket. 1590 * XXX FIXME/VERIFY is that correct? For now use m->m_nextpkt as 1591 * indication that there is more packets on the socket's buffer. 1592 * Also what should we use in uio.uio_resid? 1593 * May be s->mtu + sizeof(struct rfcomm_frame_hdr) + 1 + 1? 1594 */ 1595 1596 for (more = 1; more; ) { 1597 /* Try to get next packet from socket */ 1598 bzero(&uio, sizeof(uio)); 1599 /* uio.uio_td = NULL; */ 1600 uio.uio_resid = 1000000000; 1601 flags = MSG_DONTWAIT; 1602 1603 m = NULL; 1604 error = soreceive(s->l2so, NULL, &uio, &m, 1605 (struct mbuf **) NULL, &flags); 1606 if (error != 0) { 1607 if (error == EWOULDBLOCK) 1608 return (0); /* XXX can happen? */ 1609 1610 NG_BTSOCKET_RFCOMM_ERR( 1611 "%s: Could not receive data from L2CAP socket, error=%d\n", __func__, error); 1612 1613 return (error); 1614 } 1615 1616 more = (m->m_nextpkt != NULL); 1617 m->m_nextpkt = NULL; 1618 1619 ng_btsocket_rfcomm_receive_frame(s, m); 1620 } 1621 1622 return (0); 1623 } /* ng_btsocket_rfcomm_session_receive */ 1624 1625 /* 1626 * Send data on RFCOMM session 1627 * XXX FIXME locking for "l2so"? 1628 */ 1629 1630 static int 1631 ng_btsocket_rfcomm_session_send(ng_btsocket_rfcomm_session_p s) 1632 { 1633 struct mbuf *m = NULL; 1634 int error; 1635 1636 mtx_assert(&s->session_mtx, MA_OWNED); 1637 1638 /* Send as much as we can from the session queue */ 1639 while (sowriteable(s->l2so)) { 1640 /* Check if socket still OK */ 1641 if ((error = s->l2so->so_error) != 0) { 1642 s->l2so->so_error = 0; 1643 1644 NG_BTSOCKET_RFCOMM_ERR( 1645 "%s: Detected error=%d on L2CAP socket, state=%d, flags=%#x\n", 1646 __func__, error, s->state, s->flags); 1647 1648 return (error); 1649 } 1650 1651 NG_BT_MBUFQ_DEQUEUE(&s->outq, m); 1652 if (m == NULL) 1653 return (0); /* we are done */ 1654 1655 /* Call send function on the L2CAP socket */ 1656 error = (*s->l2so->so_proto->pr_usrreqs->pru_send)(s->l2so, 1657 0, m, NULL, NULL, curthread /* XXX */); 1658 if (error != 0) { 1659 NG_BTSOCKET_RFCOMM_ERR( 1660 "%s: Could not send data to L2CAP socket, error=%d\n", __func__, error); 1661 1662 return (error); 1663 } 1664 } 1665 1666 return (0); 1667 } /* ng_btsocket_rfcomm_session_send */ 1668 1669 /* 1670 * Close and disconnect all DLCs for the given session. Caller must hold 1671 * s->sesson_mtx. Will wakeup session. 1672 */ 1673 1674 static void 1675 ng_btsocket_rfcomm_session_clean(ng_btsocket_rfcomm_session_p s) 1676 { 1677 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1678 int error; 1679 1680 mtx_assert(&s->session_mtx, MA_OWNED); 1681 1682 /* 1683 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1684 * will unlink DLC from the session 1685 */ 1686 1687 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1688 mtx_lock(&pcb->pcb_mtx); 1689 pcb_next = LIST_NEXT(pcb, session_next); 1690 1691 NG_BTSOCKET_RFCOMM_INFO( 1692 "%s: Disconnecting dlci=%d, state=%d, flags=%#x\n", 1693 __func__, pcb->dlci, pcb->state, pcb->flags); 1694 1695 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 1696 error = ECONNRESET; 1697 else 1698 error = ECONNREFUSED; 1699 1700 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1701 1702 mtx_unlock(&pcb->pcb_mtx); 1703 pcb = pcb_next; 1704 } 1705 } /* ng_btsocket_rfcomm_session_clean */ 1706 1707 /* 1708 * Process all DLCs on the session. Caller MUST hold s->session_mtx. 1709 */ 1710 1711 static void 1712 ng_btsocket_rfcomm_session_process_pcb(ng_btsocket_rfcomm_session_p s) 1713 { 1714 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb_next = NULL; 1715 int error; 1716 1717 mtx_assert(&s->session_mtx, MA_OWNED); 1718 1719 /* 1720 * Note: cannot use LIST_FOREACH because ng_btsocket_rfcomm_pcb_kill 1721 * will unlink DLC from the session 1722 */ 1723 1724 for (pcb = LIST_FIRST(&s->dlcs); pcb != NULL; ) { 1725 mtx_lock(&pcb->pcb_mtx); 1726 pcb_next = LIST_NEXT(pcb, session_next); 1727 1728 switch (pcb->state) { 1729 1730 /* 1731 * If DLC in W4_CONNECT state then we should check for both 1732 * timeout and detach. 1733 */ 1734 1735 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 1736 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_DETACHED) 1737 ng_btsocket_rfcomm_pcb_kill(pcb, 0); 1738 else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1739 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1740 break; 1741 1742 /* 1743 * If DLC in CONFIGURING or CONNECTING state then we only 1744 * should check for timeout. If detach() was called then 1745 * DLC will be moved into DISCONNECTING state. 1746 */ 1747 1748 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 1749 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 1750 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1751 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1752 break; 1753 1754 /* 1755 * If DLC in CONNECTED state then we need to send data (if any) 1756 * from the socket's send queue. Note that we will send data 1757 * from either all sockets or none. This may overload session's 1758 * outgoing queue (but we do not check for that). 1759 * 1760 * XXX FIXME need scheduler for RFCOMM sockets 1761 */ 1762 1763 case NG_BTSOCKET_RFCOMM_DLC_CONNECTED: 1764 error = ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 1765 if (error != 0) 1766 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1767 break; 1768 1769 /* 1770 * If DLC in DISCONNECTING state then we must send DISC frame. 1771 * Note that if DLC has timeout set then we do not need to 1772 * resend DISC frame. 1773 * 1774 * XXX FIXME need to drain all data from the socket's queue 1775 * if LINGER option was set 1776 */ 1777 1778 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 1779 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) { 1780 error = ng_btsocket_rfcomm_send_command( 1781 pcb->session, RFCOMM_FRAME_DISC, 1782 pcb->dlci); 1783 if (error == 0) 1784 ng_btsocket_rfcomm_timeout(pcb); 1785 else 1786 ng_btsocket_rfcomm_pcb_kill(pcb, error); 1787 } else if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT) 1788 ng_btsocket_rfcomm_pcb_kill(pcb, ETIMEDOUT); 1789 break; 1790 1791 /* case NG_BTSOCKET_RFCOMM_DLC_CLOSED: */ 1792 default: 1793 panic("%s: Invalid DLC state=%d, flags=%#x\n", 1794 __func__, pcb->state, pcb->flags); 1795 break; 1796 } 1797 1798 mtx_unlock(&pcb->pcb_mtx); 1799 pcb = pcb_next; 1800 } 1801 } /* ng_btsocket_rfcomm_session_process_pcb */ 1802 1803 /* 1804 * Find RFCOMM session between "src" and "dst". 1805 * Caller MUST hold ng_btsocket_rfcomm_sessions_mtx. 1806 */ 1807 1808 static ng_btsocket_rfcomm_session_p 1809 ng_btsocket_rfcomm_session_by_addr(bdaddr_p src, bdaddr_p dst) 1810 { 1811 ng_btsocket_rfcomm_session_p s = NULL; 1812 ng_btsocket_l2cap_pcb_p l2pcb = NULL; 1813 int any_src; 1814 1815 mtx_assert(&ng_btsocket_rfcomm_sessions_mtx, MA_OWNED); 1816 1817 any_src = (bcmp(src, NG_HCI_BDADDR_ANY, sizeof(*src)) == 0); 1818 1819 LIST_FOREACH(s, &ng_btsocket_rfcomm_sessions, next) { 1820 l2pcb = so2l2cap_pcb(s->l2so); 1821 1822 if ((any_src || bcmp(&l2pcb->src, src, sizeof(*src)) == 0) && 1823 bcmp(&l2pcb->dst, dst, sizeof(*dst)) == 0) 1824 break; 1825 } 1826 1827 return (s); 1828 } /* ng_btsocket_rfcomm_session_by_addr */ 1829 1830 /***************************************************************************** 1831 ***************************************************************************** 1832 ** RFCOMM 1833 ***************************************************************************** 1834 *****************************************************************************/ 1835 1836 /* 1837 * Process incoming RFCOMM frame. Caller must hold s->session_mtx. 1838 * XXX FIXME check frame length 1839 */ 1840 1841 static int 1842 ng_btsocket_rfcomm_receive_frame(ng_btsocket_rfcomm_session_p s, 1843 struct mbuf *m0) 1844 { 1845 struct rfcomm_frame_hdr *hdr = NULL; 1846 struct mbuf *m = NULL; 1847 u_int16_t length; 1848 u_int8_t dlci, type; 1849 int error = 0; 1850 1851 mtx_assert(&s->session_mtx, MA_OWNED); 1852 1853 /* Pullup as much as we can into first mbuf (for direct access) */ 1854 length = min(m0->m_pkthdr.len, MHLEN); 1855 if (m0->m_len < length) { 1856 if ((m0 = m_pullup(m0, length)) == NULL) { 1857 NG_BTSOCKET_RFCOMM_ALERT( 1858 "%s: m_pullup(%d) failed\n", __func__, length); 1859 1860 return (ENOBUFS); 1861 } 1862 } 1863 1864 hdr = mtod(m0, struct rfcomm_frame_hdr *); 1865 dlci = RFCOMM_DLCI(hdr->address); 1866 type = RFCOMM_TYPE(hdr->control); 1867 1868 /* Test EA bit in length. If not set then we have 2 bytes of length */ 1869 if (!RFCOMM_EA(hdr->length)) { 1870 bcopy(&hdr->length, &length, sizeof(length)); 1871 length = le16toh(length) >> 1; 1872 m_adj(m0, sizeof(*hdr) + 1); 1873 } else { 1874 length = hdr->length >> 1; 1875 m_adj(m0, sizeof(*hdr)); 1876 } 1877 1878 NG_BTSOCKET_RFCOMM_INFO( 1879 "%s: Got frame type=%#x, dlci=%d, length=%d, cr=%d, pf=%d, len=%d\n", 1880 __func__, type, dlci, length, RFCOMM_CR(hdr->address), 1881 RFCOMM_PF(hdr->control), m0->m_pkthdr.len); 1882 1883 /* 1884 * Get FCS (the last byte in the frame) 1885 * XXX this will not work if mbuf chain ends with empty mbuf. 1886 * XXX let's hope it never happens :) 1887 */ 1888 1889 for (m = m0; m->m_next != NULL; m = m->m_next) 1890 ; 1891 if (m->m_len <= 0) 1892 panic("%s: Empty mbuf at the end of the chain, len=%d\n", 1893 __func__, m->m_len); 1894 1895 /* 1896 * Check FCS. We only need to calculate FCS on first 2 or 3 bytes 1897 * and already m_pullup'ed mbuf chain, so it should be safe. 1898 */ 1899 1900 if (ng_btsocket_rfcomm_check_fcs((u_int8_t *) hdr, type, m->m_data[m->m_len - 1])) { 1901 NG_BTSOCKET_RFCOMM_ERR( 1902 "%s: Invalid RFCOMM packet. Bad checksum\n", __func__); 1903 NG_FREE_M(m0); 1904 1905 return (EINVAL); 1906 } 1907 1908 m_adj(m0, -1); /* Trim FCS byte */ 1909 1910 /* 1911 * Process RFCOMM frame. 1912 * 1913 * From TS 07.10 spec 1914 * 1915 * "... In the case where a SABM or DISC command with the P bit set 1916 * to 0 is received then the received frame shall be discarded..." 1917 * 1918 * "... If a unsolicited DM response is received then the frame shall 1919 * be processed irrespective of the P/F setting... " 1920 * 1921 * "... The station may transmit response frames with the F bit set 1922 * to 0 at any opportunity on an asynchronous basis. However, in the 1923 * case where a UA response is received with the F bit set to 0 then 1924 * the received frame shall be discarded..." 1925 * 1926 * From Bluetooth spec 1927 * 1928 * "... When credit based flow control is being used, the meaning of 1929 * the P/F bit in the control field of the RFCOMM header is redefined 1930 * for UIH frames..." 1931 */ 1932 1933 switch (type) { 1934 case RFCOMM_FRAME_SABM: 1935 if (RFCOMM_PF(hdr->control)) 1936 error = ng_btsocket_rfcomm_receive_sabm(s, dlci); 1937 break; 1938 1939 case RFCOMM_FRAME_DISC: 1940 if (RFCOMM_PF(hdr->control)) 1941 error = ng_btsocket_rfcomm_receive_disc(s, dlci); 1942 break; 1943 1944 case RFCOMM_FRAME_UA: 1945 if (RFCOMM_PF(hdr->control)) 1946 error = ng_btsocket_rfcomm_receive_ua(s, dlci); 1947 break; 1948 1949 case RFCOMM_FRAME_DM: 1950 error = ng_btsocket_rfcomm_receive_dm(s, dlci); 1951 break; 1952 1953 case RFCOMM_FRAME_UIH: 1954 if (dlci == 0) 1955 error = ng_btsocket_rfcomm_receive_mcc(s, m0); 1956 else 1957 error = ng_btsocket_rfcomm_receive_uih(s, dlci, 1958 RFCOMM_PF(hdr->control), m0); 1959 1960 return (error); 1961 /* NOT REACHED */ 1962 1963 default: 1964 NG_BTSOCKET_RFCOMM_ERR( 1965 "%s: Invalid RFCOMM packet. Unknown type=%#x\n", __func__, type); 1966 error = EINVAL; 1967 break; 1968 } 1969 1970 NG_FREE_M(m0); 1971 1972 return (error); 1973 } /* ng_btsocket_rfcomm_receive_frame */ 1974 1975 /* 1976 * Process RFCOMM SABM frame 1977 */ 1978 1979 static int 1980 ng_btsocket_rfcomm_receive_sabm(ng_btsocket_rfcomm_session_p s, int dlci) 1981 { 1982 ng_btsocket_rfcomm_pcb_p pcb = NULL; 1983 int error = 0; 1984 1985 mtx_assert(&s->session_mtx, MA_OWNED); 1986 1987 NG_BTSOCKET_RFCOMM_INFO( 1988 "%s: Got SABM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 1989 __func__, s->state, s->flags, s->mtu, dlci); 1990 1991 /* DLCI == 0 means open multiplexor channel */ 1992 if (dlci == 0) { 1993 switch (s->state) { 1994 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 1995 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 1996 error = ng_btsocket_rfcomm_send_command(s, 1997 RFCOMM_FRAME_UA, dlci); 1998 if (error == 0) { 1999 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 2000 ng_btsocket_rfcomm_connect_cfm(s); 2001 } else { 2002 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2003 ng_btsocket_rfcomm_session_clean(s); 2004 } 2005 break; 2006 2007 default: 2008 NG_BTSOCKET_RFCOMM_WARN( 2009 "%s: Got SABM for session in invalid state state=%d, flags=%#x\n", 2010 __func__, s->state, s->flags); 2011 error = EINVAL; 2012 break; 2013 } 2014 2015 return (error); 2016 } 2017 2018 /* Make sure multiplexor channel is open */ 2019 if (s->state != NG_BTSOCKET_RFCOMM_SESSION_OPEN) { 2020 NG_BTSOCKET_RFCOMM_ERR( 2021 "%s: Got SABM for dlci=%d with mulitplexor channel closed, state=%d, " \ 2022 "flags=%#x\n", __func__, dlci, s->state, s->flags); 2023 2024 return (EINVAL); 2025 } 2026 2027 /* 2028 * Check if we have this DLCI. This might happen when remote 2029 * peer uses PN command before actual open (SABM) happens. 2030 */ 2031 2032 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2033 if (pcb != NULL) { 2034 mtx_lock(&pcb->pcb_mtx); 2035 2036 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING) { 2037 NG_BTSOCKET_RFCOMM_ERR( 2038 "%s: Got SABM for dlci=%d in invalid state=%d, flags=%#x\n", 2039 __func__, dlci, pcb->state, pcb->flags); 2040 mtx_unlock(&pcb->pcb_mtx); 2041 2042 return (ENOENT); 2043 } 2044 2045 ng_btsocket_rfcomm_untimeout(pcb); 2046 2047 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci); 2048 if (error == 0) 2049 error = ng_btsocket_rfcomm_send_msc(pcb); 2050 2051 if (error == 0) { 2052 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2053 soisconnected(pcb->so); 2054 } else 2055 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2056 2057 mtx_unlock(&pcb->pcb_mtx); 2058 2059 return (error); 2060 } 2061 2062 /* 2063 * We do not have requested DLCI, so it must be an incoming connection 2064 * with default parameters. Try to accept it. 2065 */ 2066 2067 pcb = ng_btsocket_rfcomm_connect_ind(s, RFCOMM_SRVCHANNEL(dlci)); 2068 if (pcb != NULL) { 2069 mtx_lock(&pcb->pcb_mtx); 2070 2071 pcb->dlci = dlci; 2072 2073 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_UA,dlci); 2074 if (error == 0) 2075 error = ng_btsocket_rfcomm_send_msc(pcb); 2076 2077 if (error == 0) { 2078 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2079 soisconnected(pcb->so); 2080 } else 2081 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2082 2083 mtx_unlock(&pcb->pcb_mtx); 2084 } else 2085 /* Nobody is listen()ing on the requested DLCI */ 2086 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2087 2088 return (error); 2089 } /* ng_btsocket_rfcomm_receive_sabm */ 2090 2091 /* 2092 * Process RFCOMM DISC frame 2093 */ 2094 2095 static int 2096 ng_btsocket_rfcomm_receive_disc(ng_btsocket_rfcomm_session_p s, int dlci) 2097 { 2098 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2099 int error = 0; 2100 2101 mtx_assert(&s->session_mtx, MA_OWNED); 2102 2103 NG_BTSOCKET_RFCOMM_INFO( 2104 "%s: Got DISC, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2105 __func__, s->state, s->flags, s->mtu, dlci); 2106 2107 /* DLCI == 0 means close multiplexor channel */ 2108 if (dlci == 0) { 2109 /* XXX FIXME assume that remote side will close the socket */ 2110 error = ng_btsocket_rfcomm_send_command(s, RFCOMM_FRAME_UA, 0); 2111 if (error == 0) { 2112 if (s->state == NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING) 2113 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2114 else 2115 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 2116 } else 2117 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2118 2119 ng_btsocket_rfcomm_session_clean(s); 2120 } else { 2121 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2122 if (pcb != NULL) { 2123 int err; 2124 2125 mtx_lock(&pcb->pcb_mtx); 2126 2127 NG_BTSOCKET_RFCOMM_INFO( 2128 "%s: Got DISC for dlci=%d, state=%d, flags=%#x\n", 2129 __func__, dlci, pcb->state, pcb->flags); 2130 2131 error = ng_btsocket_rfcomm_send_command(s, 2132 RFCOMM_FRAME_UA, dlci); 2133 2134 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2135 err = 0; 2136 else 2137 err = ECONNREFUSED; 2138 2139 ng_btsocket_rfcomm_pcb_kill(pcb, err); 2140 2141 mtx_unlock(&pcb->pcb_mtx); 2142 } else { 2143 NG_BTSOCKET_RFCOMM_WARN( 2144 "%s: Got DISC for non-existing dlci=%d\n", __func__, dlci); 2145 2146 error = ng_btsocket_rfcomm_send_command(s, 2147 RFCOMM_FRAME_DM, dlci); 2148 } 2149 } 2150 2151 return (error); 2152 } /* ng_btsocket_rfcomm_receive_disc */ 2153 2154 /* 2155 * Process RFCOMM UA frame 2156 */ 2157 2158 static int 2159 ng_btsocket_rfcomm_receive_ua(ng_btsocket_rfcomm_session_p s, int dlci) 2160 { 2161 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2162 int error = 0; 2163 2164 mtx_assert(&s->session_mtx, MA_OWNED); 2165 2166 NG_BTSOCKET_RFCOMM_INFO( 2167 "%s: Got UA, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2168 __func__, s->state, s->flags, s->mtu, dlci); 2169 2170 /* dlci == 0 means multiplexor channel */ 2171 if (dlci == 0) { 2172 switch (s->state) { 2173 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 2174 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 2175 ng_btsocket_rfcomm_connect_cfm(s); 2176 break; 2177 2178 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 2179 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2180 ng_btsocket_rfcomm_session_clean(s); 2181 break; 2182 2183 default: 2184 NG_BTSOCKET_RFCOMM_WARN( 2185 "%s: Got UA for session in invalid state=%d(%d), flags=%#x, mtu=%d\n", 2186 __func__, s->state, INITIATOR(s), s->flags, 2187 s->mtu); 2188 error = ENOENT; 2189 break; 2190 } 2191 2192 return (error); 2193 } 2194 2195 /* Check if we have this DLCI */ 2196 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2197 if (pcb != NULL) { 2198 mtx_lock(&pcb->pcb_mtx); 2199 2200 NG_BTSOCKET_RFCOMM_INFO( 2201 "%s: Got UA for dlci=%d, state=%d, flags=%#x\n", 2202 __func__, dlci, pcb->state, pcb->flags); 2203 2204 switch (pcb->state) { 2205 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 2206 ng_btsocket_rfcomm_untimeout(pcb); 2207 2208 error = ng_btsocket_rfcomm_send_msc(pcb); 2209 if (error == 0) { 2210 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2211 soisconnected(pcb->so); 2212 } 2213 break; 2214 2215 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 2216 ng_btsocket_rfcomm_pcb_kill(pcb, 0); 2217 break; 2218 2219 default: 2220 NG_BTSOCKET_RFCOMM_WARN( 2221 "%s: Got UA for dlci=%d in invalid state=%d, flags=%#x\n", 2222 __func__, dlci, pcb->state, pcb->flags); 2223 error = ENOENT; 2224 break; 2225 } 2226 2227 mtx_unlock(&pcb->pcb_mtx); 2228 } else { 2229 NG_BTSOCKET_RFCOMM_WARN( 2230 "%s: Got UA for non-existing dlci=%d\n", __func__, dlci); 2231 2232 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2233 } 2234 2235 return (error); 2236 } /* ng_btsocket_rfcomm_receive_ua */ 2237 2238 /* 2239 * Process RFCOMM DM frame 2240 */ 2241 2242 static int 2243 ng_btsocket_rfcomm_receive_dm(ng_btsocket_rfcomm_session_p s, int dlci) 2244 { 2245 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2246 int error; 2247 2248 mtx_assert(&s->session_mtx, MA_OWNED); 2249 2250 NG_BTSOCKET_RFCOMM_INFO( 2251 "%s: Got DM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2252 __func__, s->state, s->flags, s->mtu, dlci); 2253 2254 /* DLCI == 0 means multiplexor channel */ 2255 if (dlci == 0) { 2256 /* Disconnect all dlc's on the session */ 2257 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2258 ng_btsocket_rfcomm_session_clean(s); 2259 } else { 2260 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2261 if (pcb != NULL) { 2262 mtx_lock(&pcb->pcb_mtx); 2263 2264 NG_BTSOCKET_RFCOMM_INFO( 2265 "%s: Got DM for dlci=%d, state=%d, flags=%#x\n", 2266 __func__, dlci, pcb->state, pcb->flags); 2267 2268 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2269 error = ECONNRESET; 2270 else 2271 error = ECONNREFUSED; 2272 2273 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2274 2275 mtx_unlock(&pcb->pcb_mtx); 2276 } else 2277 NG_BTSOCKET_RFCOMM_WARN( 2278 "%s: Got DM for non-existing dlci=%d\n", __func__, dlci); 2279 } 2280 2281 return (0); 2282 } /* ng_btsocket_rfcomm_receive_dm */ 2283 2284 /* 2285 * Process RFCOMM UIH frame (data) 2286 */ 2287 2288 static int 2289 ng_btsocket_rfcomm_receive_uih(ng_btsocket_rfcomm_session_p s, int dlci, 2290 int pf, struct mbuf *m0) 2291 { 2292 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2293 int error = 0; 2294 2295 mtx_assert(&s->session_mtx, MA_OWNED); 2296 2297 NG_BTSOCKET_RFCOMM_INFO( 2298 "%s: Got UIH, session state=%d, flags=%#x, mtu=%d, dlci=%d, pf=%d, len=%d\n", 2299 __func__, s->state, s->flags, s->mtu, dlci, pf, 2300 m0->m_pkthdr.len); 2301 2302 /* XXX should we do it here? Check for session flow control */ 2303 if (s->flags & NG_BTSOCKET_RFCOMM_SESSION_LFC) { 2304 NG_BTSOCKET_RFCOMM_WARN( 2305 "%s: Got UIH with session flow control asserted, state=%d, flags=%#x\n", 2306 __func__, s->state, s->flags); 2307 goto drop; 2308 } 2309 2310 /* Check if we have this dlci */ 2311 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2312 if (pcb == NULL) { 2313 NG_BTSOCKET_RFCOMM_WARN( 2314 "%s: Got UIH for non-existing dlci=%d\n", __func__, dlci); 2315 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2316 goto drop; 2317 } 2318 2319 mtx_lock(&pcb->pcb_mtx); 2320 2321 /* Check dlci state */ 2322 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2323 NG_BTSOCKET_RFCOMM_WARN( 2324 "%s: Got UIH for dlci=%d in invalid state=%d, flags=%#x\n", 2325 __func__, dlci, pcb->state, pcb->flags); 2326 error = EINVAL; 2327 goto drop1; 2328 } 2329 2330 /* Check dlci flow control */ 2331 if (((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pcb->rx_cred <= 0) || 2332 (pcb->lmodem & RFCOMM_MODEM_FC)) { 2333 NG_BTSOCKET_RFCOMM_ERR( 2334 "%s: Got UIH for dlci=%d with asserted flow control, state=%d, " \ 2335 "flags=%#x, rx_cred=%d, lmodem=%#x\n", 2336 __func__, dlci, pcb->state, pcb->flags, 2337 pcb->rx_cred, pcb->lmodem); 2338 goto drop1; 2339 } 2340 2341 /* Did we get any credits? */ 2342 if ((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pf) { 2343 NG_BTSOCKET_RFCOMM_INFO( 2344 "%s: Got %d more credits for dlci=%d, state=%d, flags=%#x, " \ 2345 "rx_cred=%d, tx_cred=%d\n", 2346 __func__, *mtod(m0, u_int8_t *), dlci, pcb->state, 2347 pcb->flags, pcb->rx_cred, pcb->tx_cred); 2348 2349 pcb->tx_cred += *mtod(m0, u_int8_t *); 2350 m_adj(m0, 1); 2351 2352 /* Send more from the DLC. XXX check for errors? */ 2353 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2354 } 2355 2356 /* OK the of the rest of the mbuf is the data */ 2357 if (m0->m_pkthdr.len > 0) { 2358 /* If we are using credit flow control decrease rx_cred here */ 2359 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2360 /* Give remote peer more credits (if needed) */ 2361 if (-- pcb->rx_cred <= RFCOMM_MAX_CREDITS / 2) 2362 ng_btsocket_rfcomm_send_credits(pcb); 2363 else 2364 NG_BTSOCKET_RFCOMM_INFO( 2365 "%s: Remote side still has credits, dlci=%d, state=%d, flags=%#x, " \ 2366 "rx_cred=%d, tx_cred=%d\n", __func__, dlci, pcb->state, pcb->flags, 2367 pcb->rx_cred, pcb->tx_cred); 2368 } 2369 2370 /* Check packet against mtu on dlci */ 2371 if (m0->m_pkthdr.len > pcb->mtu) { 2372 NG_BTSOCKET_RFCOMM_ERR( 2373 "%s: Got oversized UIH for dlci=%d, state=%d, flags=%#x, mtu=%d, len=%d\n", 2374 __func__, dlci, pcb->state, pcb->flags, 2375 pcb->mtu, m0->m_pkthdr.len); 2376 2377 error = EMSGSIZE; 2378 } else if (m0->m_pkthdr.len > sbspace(&pcb->so->so_rcv)) { 2379 2380 /* 2381 * This is really bad. Receive queue on socket does 2382 * not have enough space for the packet. We do not 2383 * have any other choice but drop the packet. 2384 */ 2385 2386 NG_BTSOCKET_RFCOMM_ERR( 2387 "%s: Not enough space in socket receive queue. Dropping UIH for dlci=%d, " \ 2388 "state=%d, flags=%#x, len=%d, space=%ld\n", 2389 __func__, dlci, pcb->state, pcb->flags, 2390 m0->m_pkthdr.len, sbspace(&pcb->so->so_rcv)); 2391 2392 error = ENOBUFS; 2393 } else { 2394 /* Append packet to the socket receive queue */ 2395 sbappend(&pcb->so->so_rcv, m0); 2396 m0 = NULL; 2397 2398 sorwakeup(pcb->so); 2399 } 2400 } 2401 drop1: 2402 mtx_unlock(&pcb->pcb_mtx); 2403 drop: 2404 NG_FREE_M(m0); /* checks for != NULL */ 2405 2406 return (error); 2407 } /* ng_btsocket_rfcomm_receive_uih */ 2408 2409 /* 2410 * Process RFCOMM MCC command (Multiplexor) 2411 * 2412 * From TS 07.10 spec 2413 * 2414 * "5.4.3.1 Information Data 2415 * 2416 * ...The frames (UIH) sent by the initiating station have the C/R bit set 2417 * to 1 and those sent by the responding station have the C/R bit set to 0..." 2418 * 2419 * "5.4.6.2 Operating procedures 2420 * 2421 * Messages always exist in pairs; a command message and a corresponding 2422 * response message. If the C/R bit is set to 1 the message is a command, 2423 * if it is set to 0 the message is a response... 2424 * 2425 * ... 2426 * 2427 * NOTE: Notice that when UIH frames are used to convey information on DLCI 0 2428 * there are at least two different fields that contain a C/R bit, and the 2429 * bits are set of different form. The C/R bit in the Type field shall be set 2430 * as it is stated above, while the C/R bit in the Address field (see subclause 2431 * 5.2.1.2) shall be set as it is described in subclause 5.4.3.1." 2432 */ 2433 2434 static int 2435 ng_btsocket_rfcomm_receive_mcc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2436 { 2437 struct rfcomm_mcc_hdr *hdr = NULL; 2438 u_int8_t cr, type, length; 2439 2440 mtx_assert(&s->session_mtx, MA_OWNED); 2441 2442 /* 2443 * We can access data directly in the first mbuf, because we have 2444 * m_pullup()'ed mbuf chain in ng_btsocket_rfcomm_receive_frame(). 2445 * All MCC commands should fit into single mbuf (except probably TEST). 2446 */ 2447 2448 hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2449 cr = RFCOMM_CR(hdr->type); 2450 type = RFCOMM_MCC_TYPE(hdr->type); 2451 length = RFCOMM_MCC_LENGTH(hdr->length); 2452 2453 /* Check MCC frame length */ 2454 if (sizeof(*hdr) + length != m0->m_pkthdr.len) { 2455 NG_BTSOCKET_RFCOMM_ERR( 2456 "%s: Invalid MCC frame length=%d, len=%d\n", 2457 __func__, length, m0->m_pkthdr.len); 2458 NG_FREE_M(m0); 2459 2460 return (EMSGSIZE); 2461 } 2462 2463 switch (type) { 2464 case RFCOMM_MCC_TEST: 2465 return (ng_btsocket_rfcomm_receive_test(s, m0)); 2466 /* NOT REACHED */ 2467 2468 case RFCOMM_MCC_FCON: 2469 case RFCOMM_MCC_FCOFF: 2470 return (ng_btsocket_rfcomm_receive_fc(s, m0)); 2471 /* NOT REACHED */ 2472 2473 case RFCOMM_MCC_MSC: 2474 return (ng_btsocket_rfcomm_receive_msc(s, m0)); 2475 /* NOT REACHED */ 2476 2477 case RFCOMM_MCC_RPN: 2478 return (ng_btsocket_rfcomm_receive_rpn(s, m0)); 2479 /* NOT REACHED */ 2480 2481 case RFCOMM_MCC_RLS: 2482 return (ng_btsocket_rfcomm_receive_rls(s, m0)); 2483 /* NOT REACHED */ 2484 2485 case RFCOMM_MCC_PN: 2486 return (ng_btsocket_rfcomm_receive_pn(s, m0)); 2487 /* NOT REACHED */ 2488 2489 case RFCOMM_MCC_NSC: 2490 NG_BTSOCKET_RFCOMM_ERR( 2491 "%s: Got MCC NSC, type=%#x, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2492 "mtu=%d, len=%d\n", __func__, RFCOMM_MCC_TYPE(*((u_int8_t *)(hdr + 1))), cr, 2493 length, s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2494 NG_FREE_M(m0); 2495 break; 2496 2497 default: 2498 NG_BTSOCKET_RFCOMM_ERR( 2499 "%s: Got unknown MCC, type=%#x, cr=%d, length=%d, session state=%d, " \ 2500 "flags=%#x, mtu=%d, len=%d\n", 2501 __func__, type, cr, length, s->state, s->flags, 2502 s->mtu, m0->m_pkthdr.len); 2503 2504 /* Reuse mbuf to send NSC */ 2505 hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2506 m0->m_pkthdr.len = m0->m_len = sizeof(*hdr); 2507 2508 /* Create MCC NSC header */ 2509 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_NSC); 2510 hdr->length = RFCOMM_MKLEN8(1); 2511 2512 /* Put back MCC command type we did not like */ 2513 m0->m_data[m0->m_len] = RFCOMM_MKMCC_TYPE(cr, type); 2514 m0->m_pkthdr.len ++; 2515 m0->m_len ++; 2516 2517 /* Send UIH frame */ 2518 return (ng_btsocket_rfcomm_send_uih(s, 2519 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0)); 2520 /* NOT REACHED */ 2521 } 2522 2523 return (0); 2524 } /* ng_btsocket_rfcomm_receive_mcc */ 2525 2526 /* 2527 * Receive RFCOMM TEST MCC command 2528 */ 2529 2530 static int 2531 ng_btsocket_rfcomm_receive_test(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2532 { 2533 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2534 int error = 0; 2535 2536 mtx_assert(&s->session_mtx, MA_OWNED); 2537 2538 NG_BTSOCKET_RFCOMM_INFO( 2539 "%s: Got MCC TEST, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \ 2540 "len=%d\n", __func__, RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2541 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2542 2543 if (RFCOMM_CR(hdr->type)) { 2544 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_TEST); 2545 error = ng_btsocket_rfcomm_send_uih(s, 2546 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2547 } else 2548 NG_FREE_M(m0); /* XXX ignore response */ 2549 2550 return (error); 2551 } /* ng_btsocket_rfcomm_receive_test */ 2552 2553 /* 2554 * Receive RFCOMM FCON/FCOFF MCC command 2555 */ 2556 2557 static int 2558 ng_btsocket_rfcomm_receive_fc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2559 { 2560 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2561 u_int8_t type = RFCOMM_MCC_TYPE(hdr->type); 2562 int error = 0; 2563 2564 mtx_assert(&s->session_mtx, MA_OWNED); 2565 2566 /* 2567 * Turn ON/OFF aggregate flow on the entire session. When remote peer 2568 * asserted flow control no transmission shall occur except on dlci 0 2569 * (control channel). 2570 */ 2571 2572 NG_BTSOCKET_RFCOMM_INFO( 2573 "%s: Got MCC FC%s, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \ 2574 "len=%d\n", __func__, (type == RFCOMM_MCC_FCON)? "ON" : "OFF", 2575 RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2576 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2577 2578 if (RFCOMM_CR(hdr->type)) { 2579 if (type == RFCOMM_MCC_FCON) 2580 s->flags &= ~NG_BTSOCKET_RFCOMM_SESSION_RFC; 2581 else 2582 s->flags |= NG_BTSOCKET_RFCOMM_SESSION_RFC; 2583 2584 hdr->type = RFCOMM_MKMCC_TYPE(0, type); 2585 error = ng_btsocket_rfcomm_send_uih(s, 2586 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2587 } else 2588 NG_FREE_M(m0); /* XXX ignore response */ 2589 2590 return (error); 2591 } /* ng_btsocket_rfcomm_receive_fc */ 2592 2593 /* 2594 * Receive RFCOMM MSC MCC command 2595 */ 2596 2597 static int 2598 ng_btsocket_rfcomm_receive_msc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2599 { 2600 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr*); 2601 struct rfcomm_mcc_msc *msc = (struct rfcomm_mcc_msc *)(hdr+1); 2602 ng_btsocket_rfcomm_pcb_t *pcb = NULL; 2603 int error = 0; 2604 2605 mtx_assert(&s->session_mtx, MA_OWNED); 2606 2607 NG_BTSOCKET_RFCOMM_INFO( 2608 "%s: Got MCC MSC, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2609 "mtu=%d, len=%d\n", 2610 __func__, RFCOMM_DLCI(msc->address), RFCOMM_CR(hdr->type), 2611 RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags, 2612 s->mtu, m0->m_pkthdr.len); 2613 2614 if (RFCOMM_CR(hdr->type)) { 2615 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, RFCOMM_DLCI(msc->address)); 2616 if (pcb == NULL) { 2617 NG_BTSOCKET_RFCOMM_WARN( 2618 "%s: Got MSC command for non-existing dlci=%d\n", 2619 __func__, RFCOMM_DLCI(msc->address)); 2620 NG_FREE_M(m0); 2621 2622 return (ENOENT); 2623 } 2624 2625 mtx_lock(&pcb->pcb_mtx); 2626 2627 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING && 2628 pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2629 NG_BTSOCKET_RFCOMM_WARN( 2630 "%s: Got MSC on dlci=%d in invalid state=%d\n", 2631 __func__, RFCOMM_DLCI(msc->address), 2632 pcb->state); 2633 2634 mtx_unlock(&pcb->pcb_mtx); 2635 NG_FREE_M(m0); 2636 2637 return (EINVAL); 2638 } 2639 2640 pcb->rmodem = msc->modem; /* Update remote port signals */ 2641 2642 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_MSC); 2643 error = ng_btsocket_rfcomm_send_uih(s, 2644 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2645 2646 #if 0 /* YYY */ 2647 /* Send more data from DLC. XXX check for errors? */ 2648 if (!(pcb->rmodem & RFCOMM_MODEM_FC) && 2649 !(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)) 2650 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2651 #endif /* YYY */ 2652 2653 mtx_unlock(&pcb->pcb_mtx); 2654 } else 2655 NG_FREE_M(m0); /* XXX ignore response */ 2656 2657 return (error); 2658 } /* ng_btsocket_rfcomm_receive_msc */ 2659 2660 /* 2661 * Receive RFCOMM RPN MCC command 2662 * XXX FIXME do we need htole16/le16toh for RPN param_mask? 2663 */ 2664 2665 static int 2666 ng_btsocket_rfcomm_receive_rpn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2667 { 2668 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2669 struct rfcomm_mcc_rpn *rpn = (struct rfcomm_mcc_rpn *)(hdr + 1); 2670 int error = 0; 2671 u_int16_t param_mask; 2672 u_int8_t bit_rate, data_bits, stop_bits, parity, 2673 flow_control, xon_char, xoff_char; 2674 2675 mtx_assert(&s->session_mtx, MA_OWNED); 2676 2677 NG_BTSOCKET_RFCOMM_INFO( 2678 "%s: Got MCC RPN, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2679 "mtu=%d, len=%d\n", 2680 __func__, RFCOMM_DLCI(rpn->dlci), RFCOMM_CR(hdr->type), 2681 RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags, 2682 s->mtu, m0->m_pkthdr.len); 2683 2684 if (RFCOMM_CR(hdr->type)) { 2685 param_mask = RFCOMM_RPN_PM_ALL; 2686 2687 if (RFCOMM_MCC_LENGTH(hdr->length) == 1) { 2688 /* Request - return default setting */ 2689 bit_rate = RFCOMM_RPN_BR_115200; 2690 data_bits = RFCOMM_RPN_DATA_8; 2691 stop_bits = RFCOMM_RPN_STOP_1; 2692 parity = RFCOMM_RPN_PARITY_NONE; 2693 flow_control = RFCOMM_RPN_FLOW_NONE; 2694 xon_char = RFCOMM_RPN_XON_CHAR; 2695 xoff_char = RFCOMM_RPN_XOFF_CHAR; 2696 } else { 2697 /* 2698 * Ignore/accept bit_rate, 8 bits, 1 stop bit, no 2699 * parity, no flow control lines, default XON/XOFF 2700 * chars. 2701 */ 2702 2703 bit_rate = rpn->bit_rate; 2704 rpn->param_mask = le16toh(rpn->param_mask); /* XXX */ 2705 2706 data_bits = RFCOMM_RPN_DATA_BITS(rpn->line_settings); 2707 if (rpn->param_mask & RFCOMM_RPN_PM_DATA && 2708 data_bits != RFCOMM_RPN_DATA_8) { 2709 data_bits = RFCOMM_RPN_DATA_8; 2710 param_mask ^= RFCOMM_RPN_PM_DATA; 2711 } 2712 2713 stop_bits = RFCOMM_RPN_STOP_BITS(rpn->line_settings); 2714 if (rpn->param_mask & RFCOMM_RPN_PM_STOP && 2715 stop_bits != RFCOMM_RPN_STOP_1) { 2716 stop_bits = RFCOMM_RPN_STOP_1; 2717 param_mask ^= RFCOMM_RPN_PM_STOP; 2718 } 2719 2720 parity = RFCOMM_RPN_PARITY(rpn->line_settings); 2721 if (rpn->param_mask & RFCOMM_RPN_PM_PARITY && 2722 parity != RFCOMM_RPN_PARITY_NONE) { 2723 parity = RFCOMM_RPN_PARITY_NONE; 2724 param_mask ^= RFCOMM_RPN_PM_PARITY; 2725 } 2726 2727 flow_control = rpn->flow_control; 2728 if (rpn->param_mask & RFCOMM_RPN_PM_FLOW && 2729 flow_control != RFCOMM_RPN_FLOW_NONE) { 2730 flow_control = RFCOMM_RPN_FLOW_NONE; 2731 param_mask ^= RFCOMM_RPN_PM_FLOW; 2732 } 2733 2734 xon_char = rpn->xon_char; 2735 if (rpn->param_mask & RFCOMM_RPN_PM_XON && 2736 xon_char != RFCOMM_RPN_XON_CHAR) { 2737 xon_char = RFCOMM_RPN_XON_CHAR; 2738 param_mask ^= RFCOMM_RPN_PM_XON; 2739 } 2740 2741 xoff_char = rpn->xoff_char; 2742 if (rpn->param_mask & RFCOMM_RPN_PM_XOFF && 2743 xoff_char != RFCOMM_RPN_XOFF_CHAR) { 2744 xoff_char = RFCOMM_RPN_XOFF_CHAR; 2745 param_mask ^= RFCOMM_RPN_PM_XOFF; 2746 } 2747 } 2748 2749 rpn->bit_rate = bit_rate; 2750 rpn->line_settings = RFCOMM_MKRPN_LINE_SETTINGS(data_bits, 2751 stop_bits, parity); 2752 rpn->flow_control = flow_control; 2753 rpn->xon_char = xon_char; 2754 rpn->xoff_char = xoff_char; 2755 rpn->param_mask = htole16(param_mask); /* XXX */ 2756 2757 m0->m_pkthdr.len = m0->m_len = sizeof(*hdr) + sizeof(*rpn); 2758 2759 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RPN); 2760 error = ng_btsocket_rfcomm_send_uih(s, 2761 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2762 } else 2763 NG_FREE_M(m0); /* XXX ignore response */ 2764 2765 return (error); 2766 } /* ng_btsocket_rfcomm_receive_rpn */ 2767 2768 /* 2769 * Receive RFCOMM RLS MCC command 2770 */ 2771 2772 static int 2773 ng_btsocket_rfcomm_receive_rls(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2774 { 2775 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2776 struct rfcomm_mcc_rls *rls = (struct rfcomm_mcc_rls *)(hdr + 1); 2777 int error = 0; 2778 2779 mtx_assert(&s->session_mtx, MA_OWNED); 2780 2781 /* 2782 * XXX FIXME Do we have to do anything else here? Remote peer tries to 2783 * tell us something about DLCI. Just report what we have received and 2784 * return back received values as required by TS 07.10 spec. 2785 */ 2786 2787 NG_BTSOCKET_RFCOMM_INFO( 2788 "%s: Got MCC RLS, dlci=%d, status=%#x, cr=%d, length=%d, session state=%d, " \ 2789 "flags=%#x, mtu=%d, len=%d\n", 2790 __func__, RFCOMM_DLCI(rls->address), rls->status, 2791 RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2792 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2793 2794 if (RFCOMM_CR(hdr->type)) { 2795 if (rls->status & 0x1) 2796 NG_BTSOCKET_RFCOMM_ERR( 2797 "%s: Got RLS dlci=%d, error=%#x\n", __func__, RFCOMM_DLCI(rls->address), 2798 rls->status >> 1); 2799 2800 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RLS); 2801 error = ng_btsocket_rfcomm_send_uih(s, 2802 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2803 } else 2804 NG_FREE_M(m0); /* XXX ignore responses */ 2805 2806 return (error); 2807 } /* ng_btsocket_rfcomm_receive_rls */ 2808 2809 /* 2810 * Receive RFCOMM PN MCC command 2811 */ 2812 2813 static int 2814 ng_btsocket_rfcomm_receive_pn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2815 { 2816 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr*); 2817 struct rfcomm_mcc_pn *pn = (struct rfcomm_mcc_pn *)(hdr+1); 2818 ng_btsocket_rfcomm_pcb_t *pcb = NULL; 2819 int error = 0; 2820 2821 mtx_assert(&s->session_mtx, MA_OWNED); 2822 2823 NG_BTSOCKET_RFCOMM_INFO( 2824 "%s: Got MCC PN, dlci=%d, cr=%d, length=%d, flow_control=%#x, priority=%d, " \ 2825 "ack_timer=%d, mtu=%d, max_retrans=%d, credits=%d, session state=%d, " \ 2826 "flags=%#x, session mtu=%d, len=%d\n", 2827 __func__, pn->dlci, RFCOMM_CR(hdr->type), 2828 RFCOMM_MCC_LENGTH(hdr->length), pn->flow_control, pn->priority, 2829 pn->ack_timer, le16toh(pn->mtu), pn->max_retrans, pn->credits, 2830 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2831 2832 if (pn->dlci == 0) { 2833 NG_BTSOCKET_RFCOMM_ERR("%s: Zero dlci in MCC PN\n", __func__); 2834 NG_FREE_M(m0); 2835 2836 return (EINVAL); 2837 } 2838 2839 /* Check if we have this dlci */ 2840 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, pn->dlci); 2841 if (pcb != NULL) { 2842 mtx_lock(&pcb->pcb_mtx); 2843 2844 if (RFCOMM_CR(hdr->type)) { 2845 /* PN Request */ 2846 ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control, 2847 pn->credits, pn->mtu); 2848 2849 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2850 pn->flow_control = 0xe0; 2851 pn->credits = RFCOMM_DEFAULT_CREDITS; 2852 } else { 2853 pn->flow_control = 0; 2854 pn->credits = 0; 2855 } 2856 2857 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN); 2858 error = ng_btsocket_rfcomm_send_uih(s, 2859 RFCOMM_MKADDRESS(INITIATOR(s), 0), 2860 0, 0, m0); 2861 } else { 2862 /* PN Response - proceed with SABM. Timeout still set */ 2863 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONFIGURING) { 2864 ng_btsocket_rfcomm_set_pn(pcb, 0, 2865 pn->flow_control, pn->credits, pn->mtu); 2866 2867 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING; 2868 error = ng_btsocket_rfcomm_send_command(s, 2869 RFCOMM_FRAME_SABM, pn->dlci); 2870 } else 2871 NG_BTSOCKET_RFCOMM_WARN( 2872 "%s: Got PN response for dlci=%d in invalid state=%d\n", 2873 __func__, pn->dlci, pcb->state); 2874 2875 NG_FREE_M(m0); 2876 } 2877 2878 mtx_unlock(&pcb->pcb_mtx); 2879 } else if (RFCOMM_CR(hdr->type)) { 2880 /* PN request to non-existing dlci - incomming connection */ 2881 pcb = ng_btsocket_rfcomm_connect_ind(s, 2882 RFCOMM_SRVCHANNEL(pn->dlci)); 2883 if (pcb != NULL) { 2884 mtx_lock(&pcb->pcb_mtx); 2885 2886 pcb->dlci = pn->dlci; 2887 2888 ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control, 2889 pn->credits, pn->mtu); 2890 2891 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2892 pn->flow_control = 0xe0; 2893 pn->credits = RFCOMM_DEFAULT_CREDITS; 2894 } else { 2895 pn->flow_control = 0; 2896 pn->credits = 0; 2897 } 2898 2899 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN); 2900 error = ng_btsocket_rfcomm_send_uih(s, 2901 RFCOMM_MKADDRESS(INITIATOR(s), 0), 2902 0, 0, m0); 2903 2904 if (error == 0) { 2905 ng_btsocket_rfcomm_timeout(pcb); 2906 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING; 2907 soisconnecting(pcb->so); 2908 } else 2909 ng_btsocket_rfcomm_pcb_kill(pcb, error); 2910 2911 mtx_unlock(&pcb->pcb_mtx); 2912 } else { 2913 /* Nobody is listen()ing on this channel */ 2914 error = ng_btsocket_rfcomm_send_command(s, 2915 RFCOMM_FRAME_DM, pn->dlci); 2916 NG_FREE_M(m0); 2917 } 2918 } else 2919 NG_FREE_M(m0); /* XXX ignore response to non-existing dlci */ 2920 2921 return (error); 2922 } /* ng_btsocket_rfcomm_receive_pn */ 2923 2924 /* 2925 * Set PN parameters for dlci. Caller must hold pcb->pcb_mtx. 2926 * 2927 * From Bluetooth spec. 2928 * 2929 * "... The CL1 - CL4 field is completely redefined. (In TS07.10 this defines 2930 * the convergence layer to use, which is not applicable to RFCOMM. In RFCOMM, 2931 * in Bluetooth versions up to 1.0B, this field was forced to 0). 2932 * 2933 * In the PN request sent prior to a DLC establishment, this field must contain 2934 * the value 15 (0xF), indicating support of credit based flow control in the 2935 * sender. See Table 5.3 below. If the PN response contains any other value 2936 * than 14 (0xE) in this field, it is inferred that the peer RFCOMM entity is 2937 * not supporting the credit based flow control feature. (This is only possible 2938 * if the peer RFCOMM implementation is only conforming to Bluetooth version 2939 * 1.0B.) If a PN request is sent on an already open DLC, then this field must 2940 * contain the value zero; it is not possible to set initial credits more 2941 * than once per DLC activation. A responding implementation must set this 2942 * field in the PN response to 14 (0xE), if (and only if) the value in the PN 2943 * request was 15..." 2944 */ 2945 2946 static void 2947 ng_btsocket_rfcomm_set_pn(ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr, 2948 u_int8_t flow_control, u_int8_t credits, u_int16_t mtu) 2949 { 2950 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 2951 2952 pcb->mtu = le16toh(mtu); 2953 2954 if (cr) { 2955 if (flow_control == 0xf0) { 2956 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC; 2957 pcb->tx_cred = credits; 2958 } else { 2959 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC; 2960 pcb->tx_cred = 0; 2961 } 2962 } else { 2963 if (flow_control == 0xe0) { 2964 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC; 2965 pcb->tx_cred = credits; 2966 } else { 2967 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC; 2968 pcb->tx_cred = 0; 2969 } 2970 } 2971 2972 NG_BTSOCKET_RFCOMM_INFO( 2973 "%s: cr=%d, dlci=%d, state=%d, flags=%#x, mtu=%d, rx_cred=%d, tx_cred=%d\n", 2974 __func__, cr, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 2975 pcb->rx_cred, pcb->tx_cred); 2976 } /* ng_btsocket_rfcomm_set_pn */ 2977 2978 /* 2979 * Send RFCOMM SABM/DISC/UA/DM frames. Caller must hold s->session_mtx 2980 */ 2981 2982 static int 2983 ng_btsocket_rfcomm_send_command(ng_btsocket_rfcomm_session_p s, 2984 u_int8_t type, u_int8_t dlci) 2985 { 2986 struct rfcomm_cmd_hdr *hdr = NULL; 2987 struct mbuf *m = NULL; 2988 int cr; 2989 2990 mtx_assert(&s->session_mtx, MA_OWNED); 2991 2992 NG_BTSOCKET_RFCOMM_INFO( 2993 "%s: Sending command type %#x, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2994 __func__, type, s->state, s->flags, s->mtu, dlci); 2995 2996 switch (type) { 2997 case RFCOMM_FRAME_SABM: 2998 case RFCOMM_FRAME_DISC: 2999 cr = INITIATOR(s); 3000 break; 3001 3002 case RFCOMM_FRAME_UA: 3003 case RFCOMM_FRAME_DM: 3004 cr = !INITIATOR(s); 3005 break; 3006 3007 default: 3008 panic("%s: Invalid frame type=%#x\n", __func__, type); 3009 return (EINVAL); 3010 /* NOT REACHED */ 3011 } 3012 3013 MGETHDR(m, M_NOWAIT, MT_DATA); 3014 if (m == NULL) 3015 return (ENOBUFS); 3016 3017 m->m_pkthdr.len = m->m_len = sizeof(*hdr); 3018 3019 hdr = mtod(m, struct rfcomm_cmd_hdr *); 3020 hdr->address = RFCOMM_MKADDRESS(cr, dlci); 3021 hdr->control = RFCOMM_MKCONTROL(type, 1); 3022 hdr->length = RFCOMM_MKLEN8(0); 3023 hdr->fcs = ng_btsocket_rfcomm_fcs3((u_int8_t *) hdr); 3024 3025 NG_BT_MBUFQ_ENQUEUE(&s->outq, m); 3026 3027 return (0); 3028 } /* ng_btsocket_rfcomm_send_command */ 3029 3030 /* 3031 * Send RFCOMM UIH frame. Caller must hold s->session_mtx 3032 */ 3033 3034 static int 3035 ng_btsocket_rfcomm_send_uih(ng_btsocket_rfcomm_session_p s, u_int8_t address, 3036 u_int8_t pf, u_int8_t credits, struct mbuf *data) 3037 { 3038 struct rfcomm_frame_hdr *hdr = NULL; 3039 struct mbuf *m = NULL, *mcrc = NULL; 3040 u_int16_t length; 3041 3042 mtx_assert(&s->session_mtx, MA_OWNED); 3043 3044 MGETHDR(m, M_NOWAIT, MT_DATA); 3045 if (m == NULL) { 3046 NG_FREE_M(data); 3047 return (ENOBUFS); 3048 } 3049 m->m_pkthdr.len = m->m_len = sizeof(*hdr); 3050 3051 MGET(mcrc, M_NOWAIT, MT_DATA); 3052 if (mcrc == NULL) { 3053 NG_FREE_M(data); 3054 return (ENOBUFS); 3055 } 3056 mcrc->m_len = 1; 3057 3058 /* Fill UIH frame header */ 3059 hdr = mtod(m, struct rfcomm_frame_hdr *); 3060 hdr->address = address; 3061 hdr->control = RFCOMM_MKCONTROL(RFCOMM_FRAME_UIH, pf); 3062 3063 /* Calculate FCS */ 3064 mcrc->m_data[0] = ng_btsocket_rfcomm_fcs2((u_int8_t *) hdr); 3065 3066 /* Put length back */ 3067 length = (data != NULL)? data->m_pkthdr.len : 0; 3068 if (length > 127) { 3069 u_int16_t l = htole16(RFCOMM_MKLEN16(length)); 3070 3071 bcopy(&l, &hdr->length, sizeof(l)); 3072 m->m_pkthdr.len ++; 3073 m->m_len ++; 3074 } else 3075 hdr->length = RFCOMM_MKLEN8(length); 3076 3077 if (pf) { 3078 m->m_data[m->m_len] = credits; 3079 m->m_pkthdr.len ++; 3080 m->m_len ++; 3081 } 3082 3083 /* Add payload */ 3084 if (data != NULL) { 3085 m_cat(m, data); 3086 m->m_pkthdr.len += length; 3087 } 3088 3089 /* Put FCS back */ 3090 m_cat(m, mcrc); 3091 m->m_pkthdr.len ++; 3092 3093 NG_BTSOCKET_RFCOMM_INFO( 3094 "%s: Sending UIH state=%d, flags=%#x, address=%d, length=%d, pf=%d, " \ 3095 "credits=%d, len=%d\n", 3096 __func__, s->state, s->flags, address, length, pf, credits, 3097 m->m_pkthdr.len); 3098 3099 NG_BT_MBUFQ_ENQUEUE(&s->outq, m); 3100 3101 return (0); 3102 } /* ng_btsocket_rfcomm_send_uih */ 3103 3104 /* 3105 * Send MSC request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3106 */ 3107 3108 static int 3109 ng_btsocket_rfcomm_send_msc(ng_btsocket_rfcomm_pcb_p pcb) 3110 { 3111 struct mbuf *m = NULL; 3112 struct rfcomm_mcc_hdr *hdr = NULL; 3113 struct rfcomm_mcc_msc *msc = NULL; 3114 3115 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3116 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3117 3118 MGETHDR(m, M_NOWAIT, MT_DATA); 3119 if (m == NULL) 3120 return (ENOBUFS); 3121 3122 m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*msc); 3123 3124 hdr = mtod(m, struct rfcomm_mcc_hdr *); 3125 msc = (struct rfcomm_mcc_msc *)(hdr + 1); 3126 3127 hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_MSC); 3128 hdr->length = RFCOMM_MKLEN8(sizeof(*msc)); 3129 3130 msc->address = RFCOMM_MKADDRESS(1, pcb->dlci); 3131 msc->modem = pcb->lmodem; 3132 3133 NG_BTSOCKET_RFCOMM_INFO( 3134 "%s: Sending MSC dlci=%d, state=%d, flags=%#x, address=%d, modem=%#x\n", 3135 __func__, pcb->dlci, pcb->state, pcb->flags, msc->address, 3136 msc->modem); 3137 3138 return (ng_btsocket_rfcomm_send_uih(pcb->session, 3139 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m)); 3140 } /* ng_btsocket_rfcomm_send_msc */ 3141 3142 /* 3143 * Send PN request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3144 */ 3145 3146 static int 3147 ng_btsocket_rfcomm_send_pn(ng_btsocket_rfcomm_pcb_p pcb) 3148 { 3149 struct mbuf *m = NULL; 3150 struct rfcomm_mcc_hdr *hdr = NULL; 3151 struct rfcomm_mcc_pn *pn = NULL; 3152 3153 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3154 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3155 3156 MGETHDR(m, M_NOWAIT, MT_DATA); 3157 if (m == NULL) 3158 return (ENOBUFS); 3159 3160 m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*pn); 3161 3162 hdr = mtod(m, struct rfcomm_mcc_hdr *); 3163 pn = (struct rfcomm_mcc_pn *)(hdr + 1); 3164 3165 hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_PN); 3166 hdr->length = RFCOMM_MKLEN8(sizeof(*pn)); 3167 3168 pn->dlci = pcb->dlci; 3169 3170 /* 3171 * Set default DLCI priority as described in GSM 07.10 3172 * (ETSI TS 101 369) clause 5.6 page 42 3173 */ 3174 3175 pn->priority = (pcb->dlci < 56)? (((pcb->dlci >> 3) << 3) + 7) : 61; 3176 pn->ack_timer = 0; 3177 pn->mtu = htole16(pcb->mtu); 3178 pn->max_retrans = 0; 3179 3180 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 3181 pn->flow_control = 0xf0; 3182 pn->credits = pcb->rx_cred; 3183 } else { 3184 pn->flow_control = 0; 3185 pn->credits = 0; 3186 } 3187 3188 NG_BTSOCKET_RFCOMM_INFO( 3189 "%s: Sending PN dlci=%d, state=%d, flags=%#x, mtu=%d, flow_control=%#x, " \ 3190 "credits=%d\n", __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 3191 pn->flow_control, pn->credits); 3192 3193 return (ng_btsocket_rfcomm_send_uih(pcb->session, 3194 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m)); 3195 } /* ng_btsocket_rfcomm_send_pn */ 3196 3197 /* 3198 * Calculate and send credits based on available space in receive buffer 3199 */ 3200 3201 static int 3202 ng_btsocket_rfcomm_send_credits(ng_btsocket_rfcomm_pcb_p pcb) 3203 { 3204 int error = 0; 3205 u_int8_t credits; 3206 3207 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3208 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3209 3210 NG_BTSOCKET_RFCOMM_INFO( 3211 "%s: Sending more credits, dlci=%d, state=%d, flags=%#x, mtu=%d, " \ 3212 "space=%ld, tx_cred=%d, rx_cred=%d\n", 3213 __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 3214 sbspace(&pcb->so->so_rcv), pcb->tx_cred, pcb->rx_cred); 3215 3216 credits = sbspace(&pcb->so->so_rcv) / pcb->mtu; 3217 if (credits > 0) { 3218 if (pcb->rx_cred + credits > RFCOMM_MAX_CREDITS) 3219 credits = RFCOMM_MAX_CREDITS - pcb->rx_cred; 3220 3221 error = ng_btsocket_rfcomm_send_uih( 3222 pcb->session, 3223 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 3224 pcb->dlci), 1, credits, NULL); 3225 if (error == 0) { 3226 pcb->rx_cred += credits; 3227 3228 NG_BTSOCKET_RFCOMM_INFO( 3229 "%s: Gave remote side %d more credits, dlci=%d, state=%d, flags=%#x, " \ 3230 "rx_cred=%d, tx_cred=%d\n", __func__, credits, pcb->dlci, pcb->state, 3231 pcb->flags, pcb->rx_cred, pcb->tx_cred); 3232 } else 3233 NG_BTSOCKET_RFCOMM_ERR( 3234 "%s: Could not send credits, error=%d, dlci=%d, state=%d, flags=%#x, " \ 3235 "mtu=%d, space=%ld, tx_cred=%d, rx_cred=%d\n", 3236 __func__, error, pcb->dlci, pcb->state, 3237 pcb->flags, pcb->mtu, sbspace(&pcb->so->so_rcv), 3238 pcb->tx_cred, pcb->rx_cred); 3239 } 3240 3241 return (error); 3242 } /* ng_btsocket_rfcomm_send_credits */ 3243 3244 /***************************************************************************** 3245 ***************************************************************************** 3246 ** RFCOMM DLCs 3247 ***************************************************************************** 3248 *****************************************************************************/ 3249 3250 /* 3251 * Send data from socket send buffer 3252 * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3253 */ 3254 3255 static int 3256 ng_btsocket_rfcomm_pcb_send(ng_btsocket_rfcomm_pcb_p pcb, int limit) 3257 { 3258 struct mbuf *m = NULL; 3259 int sent, length, error; 3260 3261 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3262 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3263 3264 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) 3265 limit = min(limit, pcb->tx_cred); 3266 else if (!(pcb->rmodem & RFCOMM_MODEM_FC)) 3267 limit = min(limit, RFCOMM_MAX_CREDITS); /* XXX ??? */ 3268 else 3269 limit = 0; 3270 3271 if (limit == 0) { 3272 NG_BTSOCKET_RFCOMM_INFO( 3273 "%s: Could not send - remote flow control asserted, dlci=%d, flags=%#x, " \ 3274 "rmodem=%#x, tx_cred=%d\n", 3275 __func__, pcb->dlci, pcb->flags, pcb->rmodem, 3276 pcb->tx_cred); 3277 3278 return (0); 3279 } 3280 3281 for (error = 0, sent = 0; sent < limit; sent ++) { 3282 length = min(pcb->mtu, pcb->so->so_snd.sb_cc); 3283 if (length == 0) 3284 break; 3285 3286 /* Get the chunk from the socket's send buffer */ 3287 m = ng_btsocket_rfcomm_prepare_packet(&pcb->so->so_snd, length); 3288 if (m == NULL) { 3289 error = ENOBUFS; 3290 break; 3291 } 3292 3293 sbdrop(&pcb->so->so_snd, length); 3294 3295 error = ng_btsocket_rfcomm_send_uih(pcb->session, 3296 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 3297 pcb->dlci), 0, 0, m); 3298 if (error != 0) 3299 break; 3300 } 3301 3302 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) 3303 pcb->tx_cred -= sent; 3304 3305 if (error == 0 && sent > 0) { 3306 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_SENDING; 3307 sowwakeup(pcb->so); 3308 } 3309 3310 return (error); 3311 } /* ng_btsocket_rfcomm_pcb_send */ 3312 3313 /* 3314 * Unlink and disconnect DLC. If ng_btsocket_rfcomm_pcb_kill() returns 3315 * non zero value than socket has no reference and has to be detached. 3316 * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3317 */ 3318 3319 static void 3320 ng_btsocket_rfcomm_pcb_kill(ng_btsocket_rfcomm_pcb_p pcb, int error) 3321 { 3322 ng_btsocket_rfcomm_session_p s = pcb->session; 3323 3324 NG_BTSOCKET_RFCOMM_INFO( 3325 "%s: Killing DLC, so=%p, dlci=%d, state=%d, flags=%#x, error=%d\n", 3326 __func__, pcb->so, pcb->dlci, pcb->state, pcb->flags, error); 3327 3328 if (pcb->session == NULL) 3329 panic("%s: DLC without session, pcb=%p, state=%d, flags=%#x\n", 3330 __func__, pcb, pcb->state, pcb->flags); 3331 3332 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3333 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3334 3335 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 3336 ng_btsocket_rfcomm_untimeout(pcb); 3337 3338 /* Detach DLC from the session. Does not matter which state DLC in */ 3339 LIST_REMOVE(pcb, session_next); 3340 pcb->session = NULL; 3341 3342 /* Change DLC state and wakeup all sleepers */ 3343 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED; 3344 pcb->so->so_error = error; 3345 soisdisconnected(pcb->so); 3346 wakeup(&pcb->state); 3347 3348 /* Check if we have any DLCs left on the session */ 3349 if (LIST_EMPTY(&s->dlcs) && INITIATOR(s)) { 3350 NG_BTSOCKET_RFCOMM_INFO( 3351 "%s: Disconnecting session, state=%d, flags=%#x, mtu=%d\n", 3352 __func__, s->state, s->flags, s->mtu); 3353 3354 switch (s->state) { 3355 case NG_BTSOCKET_RFCOMM_SESSION_CLOSED: 3356 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 3357 /* 3358 * Do not have to do anything here. We can get here 3359 * when L2CAP connection was terminated or we have 3360 * received DISC on multiplexor channel 3361 */ 3362 break; 3363 3364 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 3365 /* Send DISC on multiplexor channel */ 3366 error = ng_btsocket_rfcomm_send_command(s, 3367 RFCOMM_FRAME_DISC, 0); 3368 if (error == 0) { 3369 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 3370 break; 3371 } 3372 /* FALL THROUGH */ 3373 3374 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING: 3375 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 3376 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 3377 break; 3378 3379 /* case NG_BTSOCKET_RFCOMM_SESSION_LISTENING: */ 3380 default: 3381 panic("%s: Invalid session state=%d, flags=%#x\n", 3382 __func__, s->state, s->flags); 3383 break; 3384 } 3385 3386 ng_btsocket_rfcomm_task_wakeup(); 3387 } 3388 } /* ng_btsocket_rfcomm_pcb_kill */ 3389 3390 /* 3391 * Look for given dlci for given RFCOMM session. Caller must hold s->session_mtx 3392 */ 3393 3394 static ng_btsocket_rfcomm_pcb_p 3395 ng_btsocket_rfcomm_pcb_by_dlci(ng_btsocket_rfcomm_session_p s, int dlci) 3396 { 3397 ng_btsocket_rfcomm_pcb_p pcb = NULL; 3398 3399 mtx_assert(&s->session_mtx, MA_OWNED); 3400 3401 LIST_FOREACH(pcb, &s->dlcs, session_next) 3402 if (pcb->dlci == dlci) 3403 break; 3404 3405 return (pcb); 3406 } /* ng_btsocket_rfcomm_pcb_by_dlci */ 3407 3408 /* 3409 * Look for socket that listens on given src address and given channel 3410 */ 3411 3412 static ng_btsocket_rfcomm_pcb_p 3413 ng_btsocket_rfcomm_pcb_listener(bdaddr_p src, int channel) 3414 { 3415 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb1 = NULL; 3416 3417 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 3418 3419 LIST_FOREACH(pcb, &ng_btsocket_rfcomm_sockets, next) { 3420 if (pcb->channel != channel || 3421 !(pcb->so->so_options & SO_ACCEPTCONN)) 3422 continue; 3423 3424 if (bcmp(&pcb->src, src, sizeof(*src)) == 0) 3425 break; 3426 3427 if (bcmp(&pcb->src, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0) 3428 pcb1 = pcb; 3429 } 3430 3431 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 3432 3433 return ((pcb != NULL)? pcb : pcb1); 3434 } /* ng_btsocket_rfcomm_pcb_listener */ 3435 3436 /***************************************************************************** 3437 ***************************************************************************** 3438 ** Misc. functions 3439 ***************************************************************************** 3440 *****************************************************************************/ 3441 3442 /* 3443 * Set timeout. Caller MUST hold pcb_mtx 3444 */ 3445 3446 static void 3447 ng_btsocket_rfcomm_timeout(ng_btsocket_rfcomm_pcb_p pcb) 3448 { 3449 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3450 3451 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) { 3452 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMO; 3453 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3454 callout_reset(&pcb->timo, ng_btsocket_rfcomm_timo * hz, 3455 ng_btsocket_rfcomm_process_timeout, pcb); 3456 } else 3457 panic("%s: Duplicated socket timeout?!\n", __func__); 3458 } /* ng_btsocket_rfcomm_timeout */ 3459 3460 /* 3461 * Unset pcb timeout. Caller MUST hold pcb_mtx 3462 */ 3463 3464 static void 3465 ng_btsocket_rfcomm_untimeout(ng_btsocket_rfcomm_pcb_p pcb) 3466 { 3467 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3468 3469 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) { 3470 callout_stop(&pcb->timo); 3471 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO; 3472 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3473 } else 3474 panic("%s: No socket timeout?!\n", __func__); 3475 } /* ng_btsocket_rfcomm_timeout */ 3476 3477 /* 3478 * Process pcb timeout 3479 */ 3480 3481 static void 3482 ng_btsocket_rfcomm_process_timeout(void *xpcb) 3483 { 3484 ng_btsocket_rfcomm_pcb_p pcb = (ng_btsocket_rfcomm_pcb_p) xpcb; 3485 3486 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3487 3488 NG_BTSOCKET_RFCOMM_INFO( 3489 "%s: Timeout, so=%p, dlci=%d, state=%d, flags=%#x\n", 3490 __func__, pcb->so, pcb->dlci, pcb->state, pcb->flags); 3491 3492 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO; 3493 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3494 3495 switch (pcb->state) { 3496 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 3497 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 3498 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 3499 break; 3500 3501 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 3502 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 3503 break; 3504 3505 default: 3506 panic( 3507 "%s: DLC timeout in invalid state, dlci=%d, state=%d, flags=%#x\n", 3508 __func__, pcb->dlci, pcb->state, pcb->flags); 3509 break; 3510 } 3511 3512 ng_btsocket_rfcomm_task_wakeup(); 3513 } /* ng_btsocket_rfcomm_process_timeout */ 3514 3515 /* 3516 * Get up to length bytes from the socket buffer 3517 */ 3518 3519 static struct mbuf * 3520 ng_btsocket_rfcomm_prepare_packet(struct sockbuf *sb, int length) 3521 { 3522 struct mbuf *top = NULL, *m = NULL, *n = NULL, *nextpkt = NULL; 3523 int mlen, noff, len; 3524 3525 MGETHDR(top, M_NOWAIT, MT_DATA); 3526 if (top == NULL) 3527 return (NULL); 3528 3529 top->m_pkthdr.len = length; 3530 top->m_len = 0; 3531 mlen = MHLEN; 3532 3533 m = top; 3534 n = sb->sb_mb; 3535 nextpkt = n->m_nextpkt; 3536 noff = 0; 3537 3538 while (length > 0 && n != NULL) { 3539 len = min(mlen - m->m_len, n->m_len - noff); 3540 if (len > length) 3541 len = length; 3542 3543 bcopy(mtod(n, caddr_t)+noff, mtod(m, caddr_t)+m->m_len, len); 3544 m->m_len += len; 3545 noff += len; 3546 length -= len; 3547 3548 if (length > 0 && m->m_len == mlen) { 3549 MGET(m->m_next, M_NOWAIT, MT_DATA); 3550 if (m->m_next == NULL) { 3551 NG_FREE_M(top); 3552 return (NULL); 3553 } 3554 3555 m = m->m_next; 3556 m->m_len = 0; 3557 mlen = MLEN; 3558 } 3559 3560 if (noff == n->m_len) { 3561 noff = 0; 3562 n = n->m_next; 3563 3564 if (n == NULL) 3565 n = nextpkt; 3566 3567 nextpkt = (n != NULL)? n->m_nextpkt : NULL; 3568 } 3569 } 3570 3571 if (length < 0) 3572 panic("%s: length=%d\n", __func__, length); 3573 if (length > 0 && n == NULL) 3574 panic("%s: bogus length=%d, n=%p\n", __func__, length, n); 3575 3576 return (top); 3577 } /* ng_btsocket_rfcomm_prepare_packet */ 3578 3579