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