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