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