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