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