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.24 2003/04/07 01:37:05 max Exp $ 29 * $FreeBSD$ 30 */ 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/domain.h> 35 #include <sys/endian.h> 36 #include <sys/errno.h> 37 #include <sys/filedesc.h> 38 #include <sys/ioccom.h> 39 #include <sys/kernel.h> 40 #include <sys/lock.h> 41 #include <sys/malloc.h> 42 #include <sys/mbuf.h> 43 #include <sys/mutex.h> 44 #include <sys/proc.h> 45 #include <sys/protosw.h> 46 #include <sys/queue.h> 47 #include <sys/socket.h> 48 #include <sys/socketvar.h> 49 #include <sys/sysctl.h> 50 #include <sys/taskqueue.h> 51 #include <sys/uio.h> 52 #include <netgraph/ng_message.h> 53 #include <netgraph/netgraph.h> 54 #include <sys/bitstring.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 = dup_sockaddr((struct sockaddr *) &sa, 0); 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 = dup_sockaddr((struct sockaddr *) &sa, 0); 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 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2030 soisconnected(pcb->so); 2031 } else if (ng_btsocket_rfcomm_pcb_kill(pcb, error)) 2032 so = pcb->so; 2033 2034 mtx_unlock(&pcb->pcb_mtx); 2035 2036 if (so != NULL) 2037 ng_btsocket_rfcomm_detach(so); 2038 } else 2039 /* Nobody is listen()ing on the requested DLCI */ 2040 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2041 2042 return (error); 2043 } /* ng_btsocket_rfcomm_receive_sabm */ 2044 2045 /* 2046 * Process RFCOMM DISC frame 2047 */ 2048 2049 static int 2050 ng_btsocket_rfcomm_receive_disc(ng_btsocket_rfcomm_session_p s, int dlci) 2051 { 2052 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2053 int error = 0; 2054 2055 mtx_assert(&s->session_mtx, MA_OWNED); 2056 2057 NG_BTSOCKET_RFCOMM_INFO( 2058 "%s: Got DISC, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2059 __func__, s->state, s->flags, s->mtu, dlci); 2060 2061 /* DLCI == 0 means close multiplexor channel */ 2062 if (dlci == 0) { 2063 /* XXX FIXME assume that remote side will close the socket */ 2064 error = ng_btsocket_rfcomm_send_command(s, RFCOMM_FRAME_UA, 0); 2065 if (error == 0) 2066 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 2067 else 2068 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; /* XXX */ 2069 2070 ng_btsocket_rfcomm_session_clean(s); 2071 } else { 2072 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2073 if (pcb != NULL) { 2074 struct socket *so = NULL; 2075 int err; 2076 2077 mtx_lock(&pcb->pcb_mtx); 2078 2079 NG_BTSOCKET_RFCOMM_INFO( 2080 "%s: Got DISC for dlci=%d, state=%d, flags=%#x\n", 2081 __func__, dlci, pcb->state, pcb->flags); 2082 2083 error = ng_btsocket_rfcomm_send_command(s, 2084 RFCOMM_FRAME_UA, dlci); 2085 2086 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2087 err = 0; 2088 else 2089 err = ECONNREFUSED; 2090 2091 if (ng_btsocket_rfcomm_pcb_kill(pcb, err)) 2092 so = pcb->so; 2093 2094 mtx_unlock(&pcb->pcb_mtx); 2095 2096 if (so != NULL) 2097 ng_btsocket_rfcomm_detach(so); 2098 } else { 2099 NG_BTSOCKET_RFCOMM_WARN( 2100 "%s: Got DISC for non-existing dlci=%d\n", __func__, dlci); 2101 2102 error = ng_btsocket_rfcomm_send_command(s, 2103 RFCOMM_FRAME_DM, dlci); 2104 } 2105 } 2106 2107 return (error); 2108 } /* ng_btsocket_rfcomm_receive_disc */ 2109 2110 /* 2111 * Process RFCOMM UA frame 2112 */ 2113 2114 static int 2115 ng_btsocket_rfcomm_receive_ua(ng_btsocket_rfcomm_session_p s, int dlci) 2116 { 2117 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2118 int error = 0; 2119 2120 mtx_assert(&s->session_mtx, MA_OWNED); 2121 2122 NG_BTSOCKET_RFCOMM_INFO( 2123 "%s: Got UA, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2124 __func__, s->state, s->flags, s->mtu, dlci); 2125 2126 /* dlci == 0 means multiplexor channel */ 2127 if (dlci == 0) { 2128 switch (s->state) { 2129 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 2130 s->state = NG_BTSOCKET_RFCOMM_SESSION_OPEN; 2131 ng_btsocket_rfcomm_connect_cfm(s); 2132 break; 2133 2134 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 2135 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2136 ng_btsocket_rfcomm_session_clean(s); 2137 break; 2138 2139 default: 2140 NG_BTSOCKET_RFCOMM_WARN( 2141 "%s: Got UA for session in invalid state=%d(%d), flags=%#x, mtu=%d\n", 2142 __func__, s->state, INITIATOR(s), s->flags, 2143 s->mtu); 2144 error = ENOENT; 2145 break; 2146 } 2147 2148 return (error); 2149 } 2150 2151 /* Check if we have this DLCI */ 2152 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2153 if (pcb != NULL) { 2154 struct socket *so = NULL; 2155 2156 mtx_lock(&pcb->pcb_mtx); 2157 2158 NG_BTSOCKET_RFCOMM_INFO( 2159 "%s: Got UA for dlci=%d, state=%d, flags=%#x\n", 2160 __func__, dlci, pcb->state, pcb->flags); 2161 2162 switch (pcb->state) { 2163 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 2164 ng_btsocket_rfcomm_untimeout(pcb); 2165 2166 error = ng_btsocket_rfcomm_send_msc(pcb); 2167 if (error == 0) { 2168 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTED; 2169 soisconnected(pcb->so); 2170 } 2171 break; 2172 2173 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 2174 if (ng_btsocket_rfcomm_pcb_kill(pcb, 0)) 2175 so = pcb->so; 2176 break; 2177 2178 default: 2179 NG_BTSOCKET_RFCOMM_WARN( 2180 "%s: Got UA for dlci=%d in invalid state=%d, flags=%#x\n", 2181 __func__, dlci, pcb->state, pcb->flags); 2182 error = ENOENT; 2183 break; 2184 } 2185 2186 mtx_unlock(&pcb->pcb_mtx); 2187 2188 if (so != NULL) 2189 ng_btsocket_rfcomm_detach(so); 2190 } else { 2191 NG_BTSOCKET_RFCOMM_WARN( 2192 "%s: Got UA for non-existing dlci=%d\n", __func__, dlci); 2193 2194 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2195 } 2196 2197 return (error); 2198 } /* ng_btsocket_rfcomm_receive_ua */ 2199 2200 /* 2201 * Process RFCOMM DM frame 2202 */ 2203 2204 static int 2205 ng_btsocket_rfcomm_receive_dm(ng_btsocket_rfcomm_session_p s, int dlci) 2206 { 2207 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2208 int error; 2209 2210 mtx_assert(&s->session_mtx, MA_OWNED); 2211 2212 NG_BTSOCKET_RFCOMM_INFO( 2213 "%s: Got DM, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2214 __func__, s->state, s->flags, s->mtu, dlci); 2215 2216 /* DLCI == 0 means multiplexor channel */ 2217 if (dlci == 0) { 2218 /* Disconnect all dlc's on the session */ 2219 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 2220 ng_btsocket_rfcomm_session_clean(s); 2221 } else { 2222 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2223 if (pcb != NULL) { 2224 struct socket *so = NULL; 2225 2226 mtx_lock(&pcb->pcb_mtx); 2227 2228 NG_BTSOCKET_RFCOMM_INFO( 2229 "%s: Got DM for dlci=%d, state=%d, flags=%#x\n", 2230 __func__, dlci, pcb->state, pcb->flags); 2231 2232 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONNECTED) 2233 error = ECONNRESET; 2234 else 2235 error = ECONNREFUSED; 2236 2237 if (ng_btsocket_rfcomm_pcb_kill(pcb, error)) 2238 so = pcb->so; 2239 2240 mtx_unlock(&pcb->pcb_mtx); 2241 2242 if (so != NULL) 2243 ng_btsocket_rfcomm_detach(so); 2244 } else 2245 NG_BTSOCKET_RFCOMM_WARN( 2246 "%s: Got DM for non-existing dlci=%d\n", __func__, dlci); 2247 } 2248 2249 return (0); 2250 } /* ng_btsocket_rfcomm_receive_dm */ 2251 2252 /* 2253 * Process RFCOMM UIH frame (data) 2254 */ 2255 2256 static int 2257 ng_btsocket_rfcomm_receive_uih(ng_btsocket_rfcomm_session_p s, int dlci, 2258 int pf, struct mbuf *m0) 2259 { 2260 ng_btsocket_rfcomm_pcb_p pcb = NULL; 2261 int error = 0; 2262 2263 mtx_assert(&s->session_mtx, MA_OWNED); 2264 2265 NG_BTSOCKET_RFCOMM_INFO( 2266 "%s: Got UIH, session state=%d, flags=%#x, mtu=%d, dlci=%d, pf=%d, len=%d\n", 2267 __func__, s->state, s->flags, s->mtu, dlci, pf, 2268 m0->m_pkthdr.len); 2269 2270 /* XXX should we do it here? Check for session flow control */ 2271 if (s->flags & NG_BTSOCKET_RFCOMM_SESSION_LFC) { 2272 NG_BTSOCKET_RFCOMM_WARN( 2273 "%s: Got UIH with session flow control asserted, state=%d, flags=%#x\n", 2274 __func__, s->state, s->flags); 2275 goto drop; 2276 } 2277 2278 /* Check if we have this dlci */ 2279 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, dlci); 2280 if (pcb == NULL) { 2281 NG_BTSOCKET_RFCOMM_WARN( 2282 "%s: Got UIH for non-existing dlci=%d\n", __func__, dlci); 2283 error = ng_btsocket_rfcomm_send_command(s,RFCOMM_FRAME_DM,dlci); 2284 goto drop; 2285 } 2286 2287 mtx_lock(&pcb->pcb_mtx); 2288 2289 /* Check dlci state */ 2290 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2291 NG_BTSOCKET_RFCOMM_WARN( 2292 "%s: Got UIH for dlci=%d in invalid state=%d, flags=%#x\n", 2293 __func__, dlci, pcb->state, pcb->flags); 2294 error = EINVAL; 2295 goto drop1; 2296 } 2297 2298 /* Check dlci flow control */ 2299 if (((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pcb->rx_cred <= 0) || 2300 (pcb->lmodem & RFCOMM_MODEM_FC)) { 2301 NG_BTSOCKET_RFCOMM_ERR( 2302 "%s: Got UIH for dlci=%d with asserted flow control, state=%d, " \ 2303 "flags=%#x, rx_cred=%d, lmodem=%#x\n", 2304 __func__, dlci, pcb->state, pcb->flags, 2305 pcb->rx_cred, pcb->lmodem); 2306 goto drop1; 2307 } 2308 2309 /* Did we get any credits? */ 2310 if ((pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) && pf) { 2311 NG_BTSOCKET_RFCOMM_INFO( 2312 "%s: Got %d more credits for dlci=%d, state=%d, flags=%#x, " \ 2313 "rx_cred=%d, tx_cred=%d\n", 2314 __func__, *mtod(m0, u_int8_t *), dlci, pcb->state, 2315 pcb->flags, pcb->rx_cred, pcb->tx_cred); 2316 2317 pcb->tx_cred += *mtod(m0, u_int8_t *); 2318 m_adj(m0, 1); 2319 2320 /* Send more from the DLC. XXX check for errors? */ 2321 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2322 } 2323 2324 /* OK the of the rest of the mbuf is the data */ 2325 if (m0->m_pkthdr.len > 0) { 2326 /* If we are using credit flow control decrease rx_cred here */ 2327 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2328 /* Give remote peer more credits (if needed) */ 2329 if (-- pcb->rx_cred <= RFCOMM_MAX_CREDITS / 2) 2330 ng_btsocket_rfcomm_send_credits(pcb); 2331 else 2332 NG_BTSOCKET_RFCOMM_INFO( 2333 "%s: Remote side still has credits, dlci=%d, state=%d, flags=%#x, " \ 2334 "rx_cred=%d, tx_cred=%d\n", __func__, dlci, pcb->state, pcb->flags, 2335 pcb->rx_cred, pcb->tx_cred); 2336 } 2337 2338 /* Check packet against mtu on dlci */ 2339 if (m0->m_pkthdr.len > pcb->mtu) { 2340 NG_BTSOCKET_RFCOMM_ERR( 2341 "%s: Got oversized UIH for dlci=%d, state=%d, flags=%#x, mtu=%d, len=%d\n", 2342 __func__, dlci, pcb->state, pcb->flags, 2343 pcb->mtu, m0->m_pkthdr.len); 2344 2345 error = EMSGSIZE; 2346 } else if (m0->m_pkthdr.len > sbspace(&pcb->so->so_rcv)) { 2347 2348 /* 2349 * This is really bad. Receive queue on socket does 2350 * not have enough space for the packet. We do not 2351 * have any other choice but drop the packet. 2352 */ 2353 2354 NG_BTSOCKET_RFCOMM_ERR( 2355 "%s: Not enough space in socket receive queue. Dropping UIH for dlci=%d, " \ 2356 "state=%d, flags=%#x, len=%d, space=%ld\n", 2357 __func__, dlci, pcb->state, pcb->flags, 2358 m0->m_pkthdr.len, sbspace(&pcb->so->so_rcv)); 2359 2360 error = ENOBUFS; 2361 } else { 2362 /* Append packet to the socket receive queue */ 2363 sbappend(&pcb->so->so_rcv, m0); 2364 m0 = NULL; 2365 2366 sorwakeup(pcb->so); 2367 } 2368 } 2369 drop1: 2370 mtx_unlock(&pcb->pcb_mtx); 2371 drop: 2372 NG_FREE_M(m0); /* checks for != NULL */ 2373 2374 return (error); 2375 } /* ng_btsocket_rfcomm_receive_uih */ 2376 2377 /* 2378 * Process RFCOMM MCC command (Multiplexor) 2379 * 2380 * From TS 07.10 spec 2381 * 2382 * "5.4.3.1 Information Data 2383 * 2384 * ...The frames (UIH) sent by the initiating station have the C/R bit set 2385 * to 1 and those sent by the responding station have the C/R bit set to 0..." 2386 * 2387 * "5.4.6.2 Operating procedures 2388 * 2389 * Messages always exist in pairs; a command message and a corresponding 2390 * response message. If the C/R bit is set to 1 the message is a command, 2391 * if it is set to 0 the message is a response... 2392 * 2393 * ... 2394 * 2395 * NOTE: Notice that when UIH frames are used to convey information on DLCI 0 2396 * there are at least two different fields that contain a C/R bit, and the 2397 * bits are set of different form. The C/R bit in the Type field shall be set 2398 * as it is stated above, while the C/R bit in the Address field (see subclause 2399 * 5.2.1.2) shall be set as it is described in subclause 5.4.3.1." 2400 */ 2401 2402 static int 2403 ng_btsocket_rfcomm_receive_mcc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2404 { 2405 struct rfcomm_mcc_hdr *hdr = NULL; 2406 u_int8_t cr, type, length; 2407 2408 mtx_assert(&s->session_mtx, MA_OWNED); 2409 2410 /* 2411 * We can access data directly in the first mbuf, because we have 2412 * m_pullup()'ed mbuf chain in ng_btsocket_rfcomm_receive_frame(). 2413 * All MCC commands should fit into single mbuf (except probably TEST). 2414 */ 2415 2416 hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2417 cr = RFCOMM_CR(hdr->type); 2418 type = RFCOMM_MCC_TYPE(hdr->type); 2419 length = RFCOMM_MCC_LENGTH(hdr->length); 2420 2421 /* Check MCC frame length */ 2422 if (sizeof(*hdr) + length != m0->m_pkthdr.len) { 2423 NG_BTSOCKET_RFCOMM_ERR( 2424 "%s: Invalid MCC frame length=%d, len=%d\n", 2425 __func__, length, m0->m_pkthdr.len); 2426 NG_FREE_M(m0); 2427 2428 return (EMSGSIZE); 2429 } 2430 2431 switch (type) { 2432 case RFCOMM_MCC_TEST: 2433 return (ng_btsocket_rfcomm_receive_test(s, m0)); 2434 /* NOT REACHED */ 2435 2436 case RFCOMM_MCC_FCON: 2437 case RFCOMM_MCC_FCOFF: 2438 return (ng_btsocket_rfcomm_receive_fc(s, m0)); 2439 /* NOT REACHED */ 2440 2441 case RFCOMM_MCC_MSC: 2442 return (ng_btsocket_rfcomm_receive_msc(s, m0)); 2443 /* NOT REACHED */ 2444 2445 case RFCOMM_MCC_RPN: 2446 return (ng_btsocket_rfcomm_receive_rpn(s, m0)); 2447 /* NOT REACHED */ 2448 2449 case RFCOMM_MCC_RLS: 2450 return (ng_btsocket_rfcomm_receive_rls(s, m0)); 2451 /* NOT REACHED */ 2452 2453 case RFCOMM_MCC_PN: 2454 return (ng_btsocket_rfcomm_receive_pn(s, m0)); 2455 /* NOT REACHED */ 2456 2457 case RFCOMM_MCC_NSC: 2458 NG_BTSOCKET_RFCOMM_ERR( 2459 "%s: Got MCC NSC, type=%#x, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2460 "mtu=%d, len=%d\n", __func__, RFCOMM_MCC_TYPE(*((u_int8_t *)(hdr + 1))), cr, 2461 length, s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2462 NG_FREE_M(m0); 2463 break; 2464 2465 default: 2466 NG_BTSOCKET_RFCOMM_ERR( 2467 "%s: Got unknown MCC, type=%#x, cr=%d, length=%d, session state=%d, " \ 2468 "flags=%#x, mtu=%d, len=%d\n", 2469 __func__, type, cr, length, s->state, s->flags, 2470 s->mtu, m0->m_pkthdr.len); 2471 2472 /* Reuse mbuf to send NSC */ 2473 hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2474 m0->m_pkthdr.len = m0->m_len = sizeof(*hdr); 2475 2476 /* Create MCC NSC header */ 2477 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_NSC); 2478 hdr->length = RFCOMM_MKLEN8(1); 2479 2480 /* Put back MCC command type we did not like */ 2481 m0->m_data[m0->m_len] = RFCOMM_MKMCC_TYPE(cr, type); 2482 m0->m_pkthdr.len ++; 2483 m0->m_len ++; 2484 2485 /* Send UIH frame */ 2486 return (ng_btsocket_rfcomm_send_uih(s, 2487 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0)); 2488 /* NOT REACHED */ 2489 } 2490 2491 return (0); 2492 } /* ng_btsocket_rfcomm_receive_mcc */ 2493 2494 /* 2495 * Receive RFCOMM TEST MCC command 2496 */ 2497 2498 static int 2499 ng_btsocket_rfcomm_receive_test(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2500 { 2501 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2502 int error = 0; 2503 2504 mtx_assert(&s->session_mtx, MA_OWNED); 2505 2506 NG_BTSOCKET_RFCOMM_INFO( 2507 "%s: Got MCC TEST, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \ 2508 "len=%d\n", __func__, RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2509 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2510 2511 if (RFCOMM_CR(hdr->type)) { 2512 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_TEST); 2513 error = ng_btsocket_rfcomm_send_uih(s, 2514 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2515 } else 2516 NG_FREE_M(m0); /* XXX ignore response */ 2517 2518 return (error); 2519 } /* ng_btsocket_rfcomm_receive_test */ 2520 2521 /* 2522 * Receive RFCOMM FCON/FCOFF MCC command 2523 */ 2524 2525 static int 2526 ng_btsocket_rfcomm_receive_fc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2527 { 2528 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2529 u_int8_t type = RFCOMM_MCC_TYPE(hdr->type); 2530 int error = 0; 2531 2532 mtx_assert(&s->session_mtx, MA_OWNED); 2533 2534 /* 2535 * Turn ON/OFF aggregate flow on the entire session. When remote peer 2536 * asserted flow control no transmission shall occur except on dlci 0 2537 * (control channel). 2538 */ 2539 2540 NG_BTSOCKET_RFCOMM_INFO( 2541 "%s: Got MCC FC%s, cr=%d, length=%d, session state=%d, flags=%#x, mtu=%d, " \ 2542 "len=%d\n", __func__, (type == RFCOMM_MCC_FCON)? "ON" : "OFF", 2543 RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2544 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2545 2546 if (RFCOMM_CR(hdr->type)) { 2547 if (type == RFCOMM_MCC_FCON) 2548 s->flags &= ~NG_BTSOCKET_RFCOMM_SESSION_RFC; 2549 else 2550 s->flags |= NG_BTSOCKET_RFCOMM_SESSION_RFC; 2551 2552 hdr->type = RFCOMM_MKMCC_TYPE(0, type); 2553 error = ng_btsocket_rfcomm_send_uih(s, 2554 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2555 } else 2556 NG_FREE_M(m0); /* XXX ignore response */ 2557 2558 return (error); 2559 } /* ng_btsocket_rfcomm_receive_fc */ 2560 2561 /* 2562 * Receive RFCOMM MSC MCC command 2563 */ 2564 2565 static int 2566 ng_btsocket_rfcomm_receive_msc(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2567 { 2568 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr*); 2569 struct rfcomm_mcc_msc *msc = (struct rfcomm_mcc_msc *)(hdr+1); 2570 ng_btsocket_rfcomm_pcb_t *pcb = NULL; 2571 int error = 0; 2572 2573 mtx_assert(&s->session_mtx, MA_OWNED); 2574 2575 NG_BTSOCKET_RFCOMM_INFO( 2576 "%s: Got MCC MSC, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2577 "mtu=%d, len=%d\n", 2578 __func__, RFCOMM_DLCI(msc->address), RFCOMM_CR(hdr->type), 2579 RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags, 2580 s->mtu, m0->m_pkthdr.len); 2581 2582 if (RFCOMM_CR(hdr->type)) { 2583 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, RFCOMM_DLCI(msc->address)); 2584 if (pcb == NULL) { 2585 NG_BTSOCKET_RFCOMM_WARN( 2586 "%s: Got MSC command for non-existing dlci=%d\n", 2587 __func__, RFCOMM_DLCI(msc->address)); 2588 NG_FREE_M(m0); 2589 2590 return (ENOENT); 2591 } 2592 2593 mtx_lock(&pcb->pcb_mtx); 2594 2595 if (pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTING && 2596 pcb->state != NG_BTSOCKET_RFCOMM_DLC_CONNECTED) { 2597 NG_BTSOCKET_RFCOMM_WARN( 2598 "%s: Got MSC on dlci=%d in invalid state=%d\n", 2599 __func__, RFCOMM_DLCI(msc->address), 2600 pcb->state); 2601 2602 mtx_unlock(&pcb->pcb_mtx); 2603 NG_FREE_M(m0); 2604 2605 return (EINVAL); 2606 } 2607 2608 pcb->rmodem = msc->modem; /* Update remote port signals */ 2609 2610 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_MSC); 2611 error = ng_btsocket_rfcomm_send_uih(s, 2612 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2613 2614 #if 0 /* YYY */ 2615 /* Send more data from DLC. XXX check for errors? */ 2616 if (!(pcb->rmodem & RFCOMM_MODEM_FC) && 2617 !(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC)) 2618 ng_btsocket_rfcomm_pcb_send(pcb, ALOT); 2619 #endif /* YYY */ 2620 2621 mtx_unlock(&pcb->pcb_mtx); 2622 } else 2623 NG_FREE_M(m0); /* XXX ignore response */ 2624 2625 return (error); 2626 } /* ng_btsocket_rfcomm_receive_msc */ 2627 2628 /* 2629 * Receive RFCOMM RPN MCC command 2630 * XXX FIXME do we need htole16/le16toh for RPN param_mask? 2631 */ 2632 2633 static int 2634 ng_btsocket_rfcomm_receive_rpn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2635 { 2636 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2637 struct rfcomm_mcc_rpn *rpn = (struct rfcomm_mcc_rpn *)(hdr + 1); 2638 int error = 0; 2639 u_int16_t param_mask; 2640 u_int8_t bit_rate, data_bits, stop_bits, parity, 2641 flow_control, xon_char, xoff_char; 2642 2643 mtx_assert(&s->session_mtx, MA_OWNED); 2644 2645 NG_BTSOCKET_RFCOMM_INFO( 2646 "%s: Got MCC RPN, dlci=%d, cr=%d, length=%d, session state=%d, flags=%#x, " \ 2647 "mtu=%d, len=%d\n", 2648 __func__, RFCOMM_DLCI(rpn->dlci), RFCOMM_CR(hdr->type), 2649 RFCOMM_MCC_LENGTH(hdr->length), s->state, s->flags, 2650 s->mtu, m0->m_pkthdr.len); 2651 2652 if (RFCOMM_CR(hdr->type)) { 2653 param_mask = RFCOMM_RPN_PM_ALL; 2654 2655 if (RFCOMM_MCC_LENGTH(hdr->length) == 1) { 2656 /* Request - return default setting */ 2657 bit_rate = RFCOMM_RPN_BR_115200; 2658 data_bits = RFCOMM_RPN_DATA_8; 2659 stop_bits = RFCOMM_RPN_STOP_1; 2660 parity = RFCOMM_RPN_PARITY_NONE; 2661 flow_control = RFCOMM_RPN_FLOW_NONE; 2662 xon_char = RFCOMM_RPN_XON_CHAR; 2663 xoff_char = RFCOMM_RPN_XOFF_CHAR; 2664 } else { 2665 /* 2666 * Ignore/accept bit_rate, 8 bits, 1 stop bit, no 2667 * parity, no flow control lines, default XON/XOFF 2668 * chars. 2669 */ 2670 2671 bit_rate = rpn->bit_rate; 2672 rpn->param_mask = le16toh(rpn->param_mask); /* XXX */ 2673 2674 data_bits = RFCOMM_RPN_DATA_BITS(rpn->line_settings); 2675 if (rpn->param_mask & RFCOMM_RPN_PM_DATA && 2676 data_bits != RFCOMM_RPN_DATA_8) { 2677 data_bits = RFCOMM_RPN_DATA_8; 2678 param_mask ^= RFCOMM_RPN_PM_DATA; 2679 } 2680 2681 stop_bits = RFCOMM_RPN_STOP_BITS(rpn->line_settings); 2682 if (rpn->param_mask & RFCOMM_RPN_PM_STOP && 2683 stop_bits != RFCOMM_RPN_STOP_1) { 2684 stop_bits = RFCOMM_RPN_STOP_1; 2685 param_mask ^= RFCOMM_RPN_PM_STOP; 2686 } 2687 2688 parity = RFCOMM_RPN_PARITY(rpn->line_settings); 2689 if (rpn->param_mask & RFCOMM_RPN_PM_PARITY && 2690 parity != RFCOMM_RPN_PARITY_NONE) { 2691 parity = RFCOMM_RPN_PARITY_NONE; 2692 param_mask ^= RFCOMM_RPN_PM_PARITY; 2693 } 2694 2695 flow_control = rpn->flow_control; 2696 if (rpn->param_mask & RFCOMM_RPN_PM_FLOW && 2697 flow_control != RFCOMM_RPN_FLOW_NONE) { 2698 flow_control = RFCOMM_RPN_FLOW_NONE; 2699 param_mask ^= RFCOMM_RPN_PM_FLOW; 2700 } 2701 2702 xon_char = rpn->xon_char; 2703 if (rpn->param_mask & RFCOMM_RPN_PM_XON && 2704 xon_char != RFCOMM_RPN_XON_CHAR) { 2705 xon_char = RFCOMM_RPN_XON_CHAR; 2706 param_mask ^= RFCOMM_RPN_PM_XON; 2707 } 2708 2709 xoff_char = rpn->xoff_char; 2710 if (rpn->param_mask & RFCOMM_RPN_PM_XOFF && 2711 xoff_char != RFCOMM_RPN_XOFF_CHAR) { 2712 xoff_char = RFCOMM_RPN_XOFF_CHAR; 2713 param_mask ^= RFCOMM_RPN_PM_XOFF; 2714 } 2715 } 2716 2717 rpn->bit_rate = bit_rate; 2718 rpn->line_settings = RFCOMM_MKRPN_LINE_SETTINGS(data_bits, 2719 stop_bits, parity); 2720 rpn->flow_control = flow_control; 2721 rpn->xon_char = xon_char; 2722 rpn->xoff_char = xoff_char; 2723 rpn->param_mask = htole16(param_mask); /* XXX */ 2724 2725 m0->m_pkthdr.len = m0->m_len = sizeof(*hdr) + sizeof(*rpn); 2726 2727 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RPN); 2728 error = ng_btsocket_rfcomm_send_uih(s, 2729 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2730 } else 2731 NG_FREE_M(m0); /* XXX ignore response */ 2732 2733 return (error); 2734 } /* ng_btsocket_rfcomm_receive_rpn */ 2735 2736 /* 2737 * Receive RFCOMM RLS MCC command 2738 */ 2739 2740 static int 2741 ng_btsocket_rfcomm_receive_rls(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2742 { 2743 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr *); 2744 struct rfcomm_mcc_rls *rls = (struct rfcomm_mcc_rls *)(hdr + 1); 2745 int error = 0; 2746 2747 mtx_assert(&s->session_mtx, MA_OWNED); 2748 2749 /* 2750 * XXX FIXME Do we have to do anything else here? Remote peer tries to 2751 * tell us something about DLCI. Just report what we have received and 2752 * return back received values as required by TS 07.10 spec. 2753 */ 2754 2755 NG_BTSOCKET_RFCOMM_INFO( 2756 "%s: Got MCC RLS, dlci=%d, status=%#x, cr=%d, length=%d, session state=%d, " \ 2757 "flags=%#x, mtu=%d, len=%d\n", 2758 __func__, RFCOMM_DLCI(rls->address), rls->status, 2759 RFCOMM_CR(hdr->type), RFCOMM_MCC_LENGTH(hdr->length), 2760 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2761 2762 if (RFCOMM_CR(hdr->type)) { 2763 if (rls->status & 0x1) 2764 NG_BTSOCKET_RFCOMM_ERR( 2765 "%s: Got RLS dlci=%d, error=%#x\n", __func__, RFCOMM_DLCI(rls->address), 2766 rls->status >> 1); 2767 2768 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_RLS); 2769 error = ng_btsocket_rfcomm_send_uih(s, 2770 RFCOMM_MKADDRESS(INITIATOR(s), 0), 0, 0, m0); 2771 } else 2772 NG_FREE_M(m0); /* XXX ignore responses */ 2773 2774 return (error); 2775 } /* ng_btsocket_rfcomm_receive_rls */ 2776 2777 /* 2778 * Receive RFCOMM PN MCC command 2779 */ 2780 2781 static int 2782 ng_btsocket_rfcomm_receive_pn(ng_btsocket_rfcomm_session_p s, struct mbuf *m0) 2783 { 2784 struct rfcomm_mcc_hdr *hdr = mtod(m0, struct rfcomm_mcc_hdr*); 2785 struct rfcomm_mcc_pn *pn = (struct rfcomm_mcc_pn *)(hdr+1); 2786 ng_btsocket_rfcomm_pcb_t *pcb = NULL; 2787 int error = 0; 2788 2789 mtx_assert(&s->session_mtx, MA_OWNED); 2790 2791 NG_BTSOCKET_RFCOMM_INFO( 2792 "%s: Got MCC PN, dlci=%d, cr=%d, length=%d, flow_control=%#x, priority=%d, " \ 2793 "ack_timer=%d, mtu=%d, max_retrans=%d, credits=%d, session state=%d, " \ 2794 "flags=%#x, session mtu=%d, len=%d\n", 2795 __func__, pn->dlci, RFCOMM_CR(hdr->type), 2796 RFCOMM_MCC_LENGTH(hdr->length), pn->flow_control, pn->priority, 2797 pn->ack_timer, le16toh(pn->mtu), pn->max_retrans, pn->credits, 2798 s->state, s->flags, s->mtu, m0->m_pkthdr.len); 2799 2800 if (pn->dlci == 0) { 2801 NG_BTSOCKET_RFCOMM_ERR("%s: Zero dlci in MCC PN\n", __func__); 2802 NG_FREE_M(m0); 2803 2804 return (EINVAL); 2805 } 2806 2807 /* Check if we have this dlci */ 2808 pcb = ng_btsocket_rfcomm_pcb_by_dlci(s, pn->dlci); 2809 if (pcb != NULL) { 2810 mtx_lock(&pcb->pcb_mtx); 2811 2812 if (RFCOMM_CR(hdr->type)) { 2813 /* PN Request */ 2814 ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control, 2815 pn->credits, pn->mtu); 2816 2817 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2818 pn->flow_control = 0xe0; 2819 pn->credits = RFCOMM_DEFAULT_CREDITS; 2820 } else { 2821 pn->flow_control = 0; 2822 pn->credits = 0; 2823 } 2824 2825 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN); 2826 error = ng_btsocket_rfcomm_send_uih(s, 2827 RFCOMM_MKADDRESS(INITIATOR(s), 0), 2828 0, 0, m0); 2829 } else { 2830 /* PN Response - proceed with SABM. Timeout still set */ 2831 if (pcb->state == NG_BTSOCKET_RFCOMM_DLC_CONFIGURING) { 2832 ng_btsocket_rfcomm_set_pn(pcb, 0, 2833 pn->flow_control, pn->credits, pn->mtu); 2834 2835 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING; 2836 error = ng_btsocket_rfcomm_send_command(s, 2837 RFCOMM_FRAME_SABM, pn->dlci); 2838 } else 2839 NG_BTSOCKET_RFCOMM_WARN( 2840 "%s: Got PN response for dlci=%d in invalid state=%d\n", 2841 __func__, pn->dlci, pcb->state); 2842 2843 NG_FREE_M(m0); 2844 } 2845 2846 mtx_unlock(&pcb->pcb_mtx); 2847 } else if (RFCOMM_CR(hdr->type)) { 2848 /* PN request to non-existing dlci - incomming connection */ 2849 pcb = ng_btsocket_rfcomm_connect_ind(s, 2850 RFCOMM_SRVCHANNEL(pn->dlci)); 2851 if (pcb != NULL) { 2852 struct socket *so = NULL; 2853 2854 mtx_lock(&pcb->pcb_mtx); 2855 2856 pcb->dlci = pn->dlci; 2857 2858 ng_btsocket_rfcomm_set_pn(pcb, 1, pn->flow_control, 2859 pn->credits, pn->mtu); 2860 2861 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 2862 pn->flow_control = 0xe0; 2863 pn->credits = RFCOMM_DEFAULT_CREDITS; 2864 } else { 2865 pn->flow_control = 0; 2866 pn->credits = 0; 2867 } 2868 2869 hdr->type = RFCOMM_MKMCC_TYPE(0, RFCOMM_MCC_PN); 2870 error = ng_btsocket_rfcomm_send_uih(s, 2871 RFCOMM_MKADDRESS(INITIATOR(s), 0), 2872 0, 0, m0); 2873 2874 if (error == 0) { 2875 ng_btsocket_rfcomm_timeout(pcb); 2876 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CONNECTING; 2877 soisconnecting(pcb->so); 2878 } else if (ng_btsocket_rfcomm_pcb_kill(pcb, error)) 2879 so = pcb->so; 2880 2881 mtx_unlock(&pcb->pcb_mtx); 2882 2883 if (so != NULL) 2884 ng_btsocket_rfcomm_detach(so); 2885 } else { 2886 /* Nobody is listen()ing on this channel */ 2887 error = ng_btsocket_rfcomm_send_command(s, 2888 RFCOMM_FRAME_DM, pn->dlci); 2889 NG_FREE_M(m0); 2890 } 2891 } else 2892 NG_FREE_M(m0); /* XXX ignore response to non-existing dlci */ 2893 2894 return (error); 2895 } /* ng_btsocket_rfcomm_receive_pn */ 2896 2897 /* 2898 * Set PN parameters for dlci. Caller must hold pcb->pcb_mtx. 2899 * 2900 * From Bluetooth spec. 2901 * 2902 * "... The CL1 - CL4 field is completely redefined. (In TS07.10 this defines 2903 * the convergence layer to use, which is not applicable to RFCOMM. In RFCOMM, 2904 * in Bluetooth versions up to 1.0B, this field was forced to 0). 2905 * 2906 * In the PN request sent prior to a DLC establishment, this field must contain 2907 * the value 15 (0xF), indicating support of credit based flow control in the 2908 * sender. See Table 5.3 below. If the PN response contains any other value 2909 * than 14 (0xE) in this field, it is inferred that the peer RFCOMM entity is 2910 * not supporting the credit based flow control feature. (This is only possible 2911 * if the peer RFCOMM implementation is only conforming to Bluetooth version 2912 * 1.0B.) If a PN request is sent on an already open DLC, then this field must 2913 * contain the value zero; it is not possible to set initial credits more 2914 * than once per DLC activation. A responding implementation must set this 2915 * field in the PN response to 14 (0xE), if (and only if) the value in the PN 2916 * request was 15..." 2917 */ 2918 2919 static void 2920 ng_btsocket_rfcomm_set_pn(ng_btsocket_rfcomm_pcb_p pcb, u_int8_t cr, 2921 u_int8_t flow_control, u_int8_t credits, u_int16_t mtu) 2922 { 2923 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 2924 2925 pcb->mtu = le16toh(mtu); 2926 2927 if (cr) { 2928 if (flow_control == 0xf0) { 2929 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC; 2930 pcb->tx_cred = credits; 2931 } else { 2932 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC; 2933 pcb->tx_cred = 0; 2934 } 2935 } else { 2936 if (flow_control == 0xe0) { 2937 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_CFC; 2938 pcb->tx_cred = credits; 2939 } else { 2940 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_CFC; 2941 pcb->tx_cred = 0; 2942 } 2943 } 2944 2945 NG_BTSOCKET_RFCOMM_INFO( 2946 "%s: cr=%d, dlci=%d, state=%d, flags=%#x, mtu=%d, rx_cred=%d, tx_cred=%d\n", 2947 __func__, cr, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 2948 pcb->rx_cred, pcb->tx_cred); 2949 } /* ng_btsocket_rfcomm_set_pn */ 2950 2951 /* 2952 * Send RFCOMM SABM/DISC/UA/DM frames. Caller must hold s->session_mtx 2953 */ 2954 2955 static int 2956 ng_btsocket_rfcomm_send_command(ng_btsocket_rfcomm_session_p s, 2957 u_int8_t type, u_int8_t dlci) 2958 { 2959 struct rfcomm_cmd_hdr *hdr = NULL; 2960 struct mbuf *m = NULL; 2961 int cr; 2962 2963 mtx_assert(&s->session_mtx, MA_OWNED); 2964 2965 NG_BTSOCKET_RFCOMM_INFO( 2966 "%s: Sending command type %#x, session state=%d, flags=%#x, mtu=%d, dlci=%d\n", 2967 __func__, type, s->state, s->flags, s->mtu, dlci); 2968 2969 switch (type) { 2970 case RFCOMM_FRAME_SABM: 2971 case RFCOMM_FRAME_DISC: 2972 cr = INITIATOR(s); 2973 break; 2974 2975 case RFCOMM_FRAME_UA: 2976 case RFCOMM_FRAME_DM: 2977 cr = !INITIATOR(s); 2978 break; 2979 2980 default: 2981 panic("%s: Invalid frame type=%#x\n", __func__, type); 2982 return (EINVAL); 2983 /* NOT REACHED */ 2984 } 2985 2986 MGETHDR(m, M_DONTWAIT, MT_DATA); 2987 if (m == NULL) 2988 return (ENOBUFS); 2989 2990 m->m_pkthdr.len = m->m_len = sizeof(*hdr); 2991 2992 hdr = mtod(m, struct rfcomm_cmd_hdr *); 2993 hdr->address = RFCOMM_MKADDRESS(cr, dlci); 2994 hdr->control = RFCOMM_MKCONTROL(type, 1); 2995 hdr->length = RFCOMM_MKLEN8(0); 2996 hdr->fcs = ng_btsocket_rfcomm_fcs3((u_int8_t *) hdr); 2997 2998 NG_BT_MBUFQ_ENQUEUE(&s->outq, m); 2999 3000 return (0); 3001 } /* ng_btsocket_rfcomm_send_command */ 3002 3003 /* 3004 * Send RFCOMM UIH frame. Caller must hold s->session_mtx 3005 */ 3006 3007 static int 3008 ng_btsocket_rfcomm_send_uih(ng_btsocket_rfcomm_session_p s, u_int8_t address, 3009 u_int8_t pf, u_int8_t credits, struct mbuf *data) 3010 { 3011 struct rfcomm_frame_hdr *hdr = NULL; 3012 struct mbuf *m = NULL, *mcrc = NULL; 3013 u_int16_t length; 3014 3015 mtx_assert(&s->session_mtx, MA_OWNED); 3016 3017 MGETHDR(m, M_DONTWAIT, MT_DATA); 3018 if (m == NULL) { 3019 NG_FREE_M(data); 3020 return (ENOBUFS); 3021 } 3022 m->m_pkthdr.len = m->m_len = sizeof(*hdr); 3023 3024 MGET(mcrc, M_DONTWAIT, MT_DATA); 3025 if (mcrc == NULL) { 3026 NG_FREE_M(data); 3027 return (ENOBUFS); 3028 } 3029 mcrc->m_len = 1; 3030 3031 /* Fill UIH frame header */ 3032 hdr = mtod(m, struct rfcomm_frame_hdr *); 3033 hdr->address = address; 3034 hdr->control = RFCOMM_MKCONTROL(RFCOMM_FRAME_UIH, pf); 3035 3036 /* Calculate FCS */ 3037 mcrc->m_data[0] = ng_btsocket_rfcomm_fcs2((u_int8_t *) hdr); 3038 3039 /* Put length back */ 3040 length = (data != NULL)? data->m_pkthdr.len : 0; 3041 if (length > 127) { 3042 u_int16_t l = htole16(RFCOMM_MKLEN16(length)); 3043 3044 bcopy(&l, &hdr->length, sizeof(l)); 3045 m->m_pkthdr.len ++; 3046 m->m_len ++; 3047 } else 3048 hdr->length = RFCOMM_MKLEN8(length); 3049 3050 if (pf) { 3051 m->m_data[m->m_len] = credits; 3052 m->m_pkthdr.len ++; 3053 m->m_len ++; 3054 } 3055 3056 /* Add payload */ 3057 if (data != NULL) { 3058 m_cat(m, data); 3059 m->m_pkthdr.len += length; 3060 } 3061 3062 /* Put FCS back */ 3063 m_cat(m, mcrc); 3064 m->m_pkthdr.len ++; 3065 3066 NG_BTSOCKET_RFCOMM_INFO( 3067 "%s: Sending UIH state=%d, flags=%#x, address=%d, length=%d, pf=%d, " \ 3068 "credits=%d, len=%d\n", 3069 __func__, s->state, s->flags, address, length, pf, credits, 3070 m->m_pkthdr.len); 3071 3072 NG_BT_MBUFQ_ENQUEUE(&s->outq, m); 3073 3074 return (0); 3075 } /* ng_btsocket_rfcomm_send_uih */ 3076 3077 /* 3078 * Send MSC request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3079 */ 3080 3081 static int 3082 ng_btsocket_rfcomm_send_msc(ng_btsocket_rfcomm_pcb_p pcb) 3083 { 3084 struct mbuf *m = NULL; 3085 struct rfcomm_mcc_hdr *hdr = NULL; 3086 struct rfcomm_mcc_msc *msc = NULL; 3087 3088 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3089 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3090 3091 MGETHDR(m, M_DONTWAIT, MT_DATA); 3092 if (m == NULL) 3093 return (ENOBUFS); 3094 3095 m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*msc); 3096 3097 hdr = mtod(m, struct rfcomm_mcc_hdr *); 3098 msc = (struct rfcomm_mcc_msc *)(hdr + 1); 3099 3100 hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_MSC); 3101 hdr->length = RFCOMM_MKLEN8(sizeof(*msc)); 3102 3103 msc->address = RFCOMM_MKADDRESS(1, pcb->dlci); 3104 msc->modem = pcb->lmodem; 3105 3106 NG_BTSOCKET_RFCOMM_INFO( 3107 "%s: Sending MSC dlci=%d, state=%d, flags=%#x, address=%d, modem=%#x\n", 3108 __func__, pcb->dlci, pcb->state, pcb->flags, msc->address, 3109 msc->modem); 3110 3111 return (ng_btsocket_rfcomm_send_uih(pcb->session, 3112 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m)); 3113 } /* ng_btsocket_rfcomm_send_msc */ 3114 3115 /* 3116 * Send PN request. Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3117 */ 3118 3119 static int 3120 ng_btsocket_rfcomm_send_pn(ng_btsocket_rfcomm_pcb_p pcb) 3121 { 3122 struct mbuf *m = NULL; 3123 struct rfcomm_mcc_hdr *hdr = NULL; 3124 struct rfcomm_mcc_pn *pn = NULL; 3125 3126 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3127 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3128 3129 MGETHDR(m, M_DONTWAIT, MT_DATA); 3130 if (m == NULL) 3131 return (ENOBUFS); 3132 3133 m->m_pkthdr.len = m->m_len = sizeof(*hdr) + sizeof(*pn); 3134 3135 hdr = mtod(m, struct rfcomm_mcc_hdr *); 3136 pn = (struct rfcomm_mcc_pn *)(hdr + 1); 3137 3138 hdr->type = RFCOMM_MKMCC_TYPE(1, RFCOMM_MCC_PN); 3139 hdr->length = RFCOMM_MKLEN8(sizeof(*pn)); 3140 3141 pn->dlci = pcb->dlci; 3142 pn->priority = 0; 3143 pn->ack_timer = 0; 3144 pn->mtu = htole16(pcb->mtu); 3145 pn->max_retrans = 0; 3146 3147 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) { 3148 pn->flow_control = 0xf0; 3149 pn->credits = pcb->rx_cred; 3150 } else { 3151 pn->flow_control = 0; 3152 pn->credits = 0; 3153 } 3154 3155 NG_BTSOCKET_RFCOMM_INFO( 3156 "%s: Sending PN dlci=%d, state=%d, flags=%#x, mtu=%d, flow_control=%#x, " \ 3157 "credits=%d\n", __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 3158 pn->flow_control, pn->credits); 3159 3160 return (ng_btsocket_rfcomm_send_uih(pcb->session, 3161 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 0), 0, 0, m)); 3162 } /* ng_btsocket_rfcomm_send_pn */ 3163 3164 /* 3165 * Calculate and send credits based on available space in receive buffer 3166 */ 3167 3168 static int 3169 ng_btsocket_rfcomm_send_credits(ng_btsocket_rfcomm_pcb_p pcb) 3170 { 3171 int error = 0; 3172 u_int8_t credits; 3173 3174 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3175 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3176 3177 NG_BTSOCKET_RFCOMM_INFO( 3178 "%s: Sending more credits, dlci=%d, state=%d, flags=%#x, mtu=%d, " \ 3179 "space=%ld, tx_cred=%d, rx_cred=%d\n", 3180 __func__, pcb->dlci, pcb->state, pcb->flags, pcb->mtu, 3181 sbspace(&pcb->so->so_rcv), pcb->tx_cred, pcb->rx_cred); 3182 3183 credits = sbspace(&pcb->so->so_rcv) / pcb->mtu; 3184 if (credits > 0) { 3185 if (pcb->rx_cred + credits > RFCOMM_MAX_CREDITS) 3186 credits = RFCOMM_MAX_CREDITS - pcb->rx_cred; 3187 3188 error = ng_btsocket_rfcomm_send_uih( 3189 pcb->session, 3190 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 3191 pcb->dlci), 1, credits, NULL); 3192 if (error == 0) { 3193 pcb->rx_cred += credits; 3194 3195 NG_BTSOCKET_RFCOMM_INFO( 3196 "%s: Gave remote side %d more credits, dlci=%d, state=%d, flags=%#x, " \ 3197 "rx_cred=%d, tx_cred=%d\n", __func__, credits, pcb->dlci, pcb->state, 3198 pcb->flags, pcb->rx_cred, pcb->tx_cred); 3199 } else 3200 NG_BTSOCKET_RFCOMM_ERR( 3201 "%s: Could not send credits, error=%d, dlci=%d, state=%d, flags=%#x, " \ 3202 "mtu=%d, space=%ld, tx_cred=%d, rx_cred=%d\n", 3203 __func__, error, pcb->dlci, pcb->state, 3204 pcb->flags, pcb->mtu, sbspace(&pcb->so->so_rcv), 3205 pcb->tx_cred, pcb->rx_cred); 3206 } 3207 3208 return (error); 3209 } /* ng_btsocket_rfcomm_send_credits */ 3210 3211 /***************************************************************************** 3212 ***************************************************************************** 3213 ** RFCOMM DLCs 3214 ***************************************************************************** 3215 *****************************************************************************/ 3216 3217 /* 3218 * Send data from socket send buffer 3219 * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3220 */ 3221 3222 static int 3223 ng_btsocket_rfcomm_pcb_send(ng_btsocket_rfcomm_pcb_p pcb, int limit) 3224 { 3225 struct mbuf *m = NULL; 3226 int sent, length, error; 3227 3228 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3229 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3230 3231 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) 3232 limit = min(limit, pcb->tx_cred); 3233 else if (!(pcb->rmodem & RFCOMM_MODEM_FC)) 3234 limit = min(limit, RFCOMM_MAX_CREDITS); /* XXX ??? */ 3235 else 3236 limit = 0; 3237 3238 if (limit == 0) { 3239 NG_BTSOCKET_RFCOMM_INFO( 3240 "%s: Could not send - remote flow control asserted, dlci=%d, flags=%#x, " \ 3241 "rmodem=%#x, tx_cred=%d\n", 3242 __func__, pcb->dlci, pcb->flags, pcb->rmodem, 3243 pcb->tx_cred); 3244 3245 return (0); 3246 } 3247 3248 for (error = 0, sent = 0; sent < limit; sent ++) { 3249 length = min(pcb->mtu, pcb->so->so_snd.sb_cc); 3250 if (length == 0) 3251 break; 3252 3253 /* Get the chunk from the socket's send buffer */ 3254 m = ng_btsocket_rfcomm_prepare_packet(&pcb->so->so_snd, length); 3255 if (m == NULL) { 3256 error = ENOBUFS; 3257 break; 3258 } 3259 3260 sbdrop(&pcb->so->so_snd, length); 3261 3262 error = ng_btsocket_rfcomm_send_uih(pcb->session, 3263 RFCOMM_MKADDRESS(INITIATOR(pcb->session), 3264 pcb->dlci), 0, 0, m); 3265 if (error != 0) 3266 break; 3267 } 3268 3269 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_CFC) 3270 pcb->tx_cred -= sent; 3271 3272 if (error == 0 && sent > 0) { 3273 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_SENDING; 3274 sowwakeup(pcb->so); 3275 } 3276 3277 return (error); 3278 } /* ng_btsocket_rfcomm_pcb_send */ 3279 3280 /* 3281 * Unlink and disconnect DLC. If ng_btsocket_rfcomm_pcb_kill() returns 3282 * non zero value than socket has no reference and has to be detached. 3283 * Caller must hold pcb->pcb_mtx and pcb->session->session_mtx 3284 */ 3285 3286 static int 3287 ng_btsocket_rfcomm_pcb_kill(ng_btsocket_rfcomm_pcb_p pcb, int error) 3288 { 3289 ng_btsocket_rfcomm_session_p s = pcb->session; 3290 3291 mtx_assert(&pcb->session->session_mtx, MA_OWNED); 3292 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3293 3294 NG_BTSOCKET_RFCOMM_INFO( 3295 "%s: Killing DLC, so=%p, dlci=%d, state=%d, flags=%#x, error=%d\n", 3296 __func__, pcb->so, pcb->dlci, pcb->state, pcb->flags, error); 3297 3298 if (pcb->session == NULL) 3299 panic("%s: DLC without session, pcb=%p, state=%d, flags=%#x\n", 3300 __func__, pcb, pcb->state, pcb->flags); 3301 3302 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) 3303 ng_btsocket_rfcomm_untimeout(pcb); 3304 3305 /* Detach DLC from the session. Does not matter which state DLC in */ 3306 LIST_REMOVE(pcb, session_next); 3307 pcb->session = NULL; 3308 3309 /* Change DLC state and wakeup all sleepers */ 3310 pcb->state = NG_BTSOCKET_RFCOMM_DLC_CLOSED; 3311 pcb->so->so_error = error; 3312 soisdisconnected(pcb->so); 3313 wakeup(&pcb->state); 3314 3315 /* Check if we have any DLCs left on the session */ 3316 if (LIST_EMPTY(&s->dlcs) && INITIATOR(s)) { 3317 NG_BTSOCKET_RFCOMM_INFO( 3318 "%s: Disconnecting session, state=%d, flags=%#x, mtu=%d\n", 3319 __func__, s->state, s->flags, s->mtu); 3320 3321 switch (s->state) { 3322 case NG_BTSOCKET_RFCOMM_SESSION_CLOSED: 3323 case NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING: 3324 /* 3325 * Do not have to do anything here. We can get here 3326 * when L2CAP connection was terminated or we have 3327 * received DISC on multiplexor channel 3328 */ 3329 break; 3330 3331 case NG_BTSOCKET_RFCOMM_SESSION_OPEN: 3332 /* Send DISC on multiplexor channel */ 3333 error = ng_btsocket_rfcomm_send_command(s, 3334 RFCOMM_FRAME_DISC, 0); 3335 if (error == 0) { 3336 s->state = NG_BTSOCKET_RFCOMM_SESSION_DISCONNECTING; 3337 break; 3338 } 3339 /* FALL THROUGH */ 3340 3341 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTING: 3342 case NG_BTSOCKET_RFCOMM_SESSION_CONNECTED: 3343 s->state = NG_BTSOCKET_RFCOMM_SESSION_CLOSED; 3344 break; 3345 3346 /* case NG_BTSOCKET_RFCOMM_SESSION_LISTENING: */ 3347 default: 3348 panic("%s: Invalid session state=%d, flags=%#x\n", 3349 __func__, s->state, s->flags); 3350 break; 3351 } 3352 3353 ng_btsocket_rfcomm_task_wakeup(); 3354 } 3355 3356 return (pcb->so->so_state & SS_NOFDREF); 3357 } /* ng_btsocket_rfcomm_pcb_kill */ 3358 3359 /* 3360 * Look for RFCOMM socket with given channel and source address 3361 */ 3362 3363 static ng_btsocket_rfcomm_pcb_p 3364 ng_btsocket_rfcomm_pcb_by_channel(bdaddr_p src, int channel) 3365 { 3366 ng_btsocket_rfcomm_pcb_p pcb = NULL; 3367 3368 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 3369 3370 LIST_FOREACH(pcb, &ng_btsocket_rfcomm_sockets, next) 3371 if (pcb->channel == channel && 3372 bcmp(&pcb->src, src, sizeof(*src)) == 0) 3373 break; 3374 3375 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 3376 3377 return (pcb); 3378 } /* ng_btsocket_rfcomm_pcb_by_channel */ 3379 3380 /* 3381 * Look for given dlci for given RFCOMM session. Caller must hold s->session_mtx 3382 */ 3383 3384 static ng_btsocket_rfcomm_pcb_p 3385 ng_btsocket_rfcomm_pcb_by_dlci(ng_btsocket_rfcomm_session_p s, int dlci) 3386 { 3387 ng_btsocket_rfcomm_pcb_p pcb = NULL; 3388 3389 mtx_assert(&s->session_mtx, MA_OWNED); 3390 3391 LIST_FOREACH(pcb, &s->dlcs, session_next) 3392 if (pcb->dlci == dlci) 3393 break; 3394 3395 return (pcb); 3396 } /* ng_btsocket_rfcomm_pcb_by_dlci */ 3397 3398 /* 3399 * Look for socket that listens on given src address and given channel 3400 */ 3401 3402 static ng_btsocket_rfcomm_pcb_p 3403 ng_btsocket_rfcomm_pcb_listener(bdaddr_p src, int channel) 3404 { 3405 ng_btsocket_rfcomm_pcb_p pcb = NULL, pcb1 = NULL; 3406 3407 mtx_lock(&ng_btsocket_rfcomm_sockets_mtx); 3408 3409 LIST_FOREACH(pcb, &ng_btsocket_rfcomm_sockets, next) { 3410 if (pcb->channel != channel || 3411 !(pcb->so->so_options & SO_ACCEPTCONN)) 3412 continue; 3413 3414 if (bcmp(&pcb->src, src, sizeof(*src)) == 0) 3415 break; 3416 3417 if (bcmp(&pcb->src, NG_HCI_BDADDR_ANY, sizeof(bdaddr_t)) == 0) 3418 pcb1 = pcb; 3419 } 3420 3421 mtx_unlock(&ng_btsocket_rfcomm_sockets_mtx); 3422 3423 return ((pcb != NULL)? pcb : pcb1); 3424 } /* ng_btsocket_rfcomm_pcb_listener */ 3425 3426 /***************************************************************************** 3427 ***************************************************************************** 3428 ** Misc. functions 3429 ***************************************************************************** 3430 *****************************************************************************/ 3431 3432 /* 3433 * Set timeout. Caller MUST hold pcb_mtx 3434 */ 3435 3436 static void 3437 ng_btsocket_rfcomm_timeout(ng_btsocket_rfcomm_pcb_p pcb) 3438 { 3439 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3440 3441 if (!(pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO)) { 3442 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMO; 3443 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3444 pcb->timo = timeout(ng_btsocket_rfcomm_process_timeout, pcb, 3445 ng_btsocket_rfcomm_timo * hz); 3446 } else 3447 panic("%s: Duplicated socket timeout?!\n", __func__); 3448 } /* ng_btsocket_rfcomm_timeout */ 3449 3450 /* 3451 * Unset pcb timeout. Caller MUST hold pcb_mtx 3452 */ 3453 3454 static void 3455 ng_btsocket_rfcomm_untimeout(ng_btsocket_rfcomm_pcb_p pcb) 3456 { 3457 mtx_assert(&pcb->pcb_mtx, MA_OWNED); 3458 3459 if (pcb->flags & NG_BTSOCKET_RFCOMM_DLC_TIMO) { 3460 untimeout(ng_btsocket_rfcomm_process_timeout, pcb, pcb->timo); 3461 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO; 3462 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3463 } else 3464 panic("%s: No socket timeout?!\n", __func__); 3465 } /* ng_btsocket_rfcomm_timeout */ 3466 3467 /* 3468 * Process pcb timeout 3469 */ 3470 3471 static void 3472 ng_btsocket_rfcomm_process_timeout(void *xpcb) 3473 { 3474 ng_btsocket_rfcomm_pcb_p pcb = (ng_btsocket_rfcomm_pcb_p) xpcb; 3475 3476 mtx_lock(&pcb->pcb_mtx); 3477 3478 NG_BTSOCKET_RFCOMM_INFO( 3479 "%s: Timeout, so=%p, dlci=%d, state=%d, flags=%#x\n", 3480 __func__, pcb->so, pcb->dlci, pcb->state, pcb->flags); 3481 3482 pcb->flags &= ~NG_BTSOCKET_RFCOMM_DLC_TIMO; 3483 pcb->flags |= NG_BTSOCKET_RFCOMM_DLC_TIMEDOUT; 3484 3485 switch (pcb->state) { 3486 case NG_BTSOCKET_RFCOMM_DLC_CONFIGURING: 3487 case NG_BTSOCKET_RFCOMM_DLC_CONNECTING: 3488 pcb->state = NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING; 3489 break; 3490 3491 case NG_BTSOCKET_RFCOMM_DLC_W4_CONNECT: 3492 case NG_BTSOCKET_RFCOMM_DLC_DISCONNECTING: 3493 break; 3494 3495 default: 3496 panic( 3497 "%s: DLC timeout in invalid state, dlci=%d, state=%d, flags=%#x\n", 3498 __func__, pcb->dlci, pcb->state, pcb->flags); 3499 break; 3500 } 3501 3502 ng_btsocket_rfcomm_task_wakeup(); 3503 3504 mtx_unlock(&pcb->pcb_mtx); 3505 } /* ng_btsocket_rfcomm_process_timeout */ 3506 3507 /* 3508 * Get up to length bytes from the socket buffer 3509 */ 3510 3511 static struct mbuf * 3512 ng_btsocket_rfcomm_prepare_packet(struct sockbuf *sb, int length) 3513 { 3514 struct mbuf *top = NULL, *m = NULL, *n = NULL, *nextpkt = NULL; 3515 int mlen, noff, len; 3516 3517 MGETHDR(top, M_DONTWAIT, MT_DATA); 3518 if (top == NULL) 3519 return (NULL); 3520 3521 top->m_pkthdr.len = length; 3522 top->m_len = 0; 3523 mlen = MHLEN; 3524 3525 m = top; 3526 n = sb->sb_mb; 3527 nextpkt = n->m_nextpkt; 3528 noff = 0; 3529 3530 while (length > 0 && n != NULL) { 3531 len = min(mlen - m->m_len, n->m_len - noff); 3532 if (len > length) 3533 len = length; 3534 3535 bcopy(mtod(n, caddr_t)+noff, mtod(m, caddr_t)+m->m_len, len); 3536 m->m_len += len; 3537 noff += len; 3538 length -= len; 3539 3540 if (length > 0 && m->m_len == mlen) { 3541 MGET(m->m_next, M_DONTWAIT, MT_DATA); 3542 if (m->m_next == NULL) { 3543 NG_FREE_M(top); 3544 return (NULL); 3545 } 3546 3547 m = m->m_next; 3548 m->m_len = 0; 3549 mlen = MLEN; 3550 } 3551 3552 if (noff == n->m_len) { 3553 noff = 0; 3554 n = n->m_next; 3555 3556 if (n == NULL) 3557 n = nextpkt; 3558 3559 nextpkt = (n != NULL)? n->m_nextpkt : NULL; 3560 } 3561 } 3562 3563 if (length < 0) 3564 panic("%s: length=%d\n", __func__, length); 3565 if (length > 0 && n == NULL) 3566 panic("%s: bogus length=%d, n=%p\n", __func__, length, n); 3567 3568 return (top); 3569 } /* ng_btsocket_rfcomm_prepare_packet */ 3570 3571