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