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