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