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