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