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