1 1.37 rin /* $NetBSD: l2cap_socket.c,v 1.37 2024/07/05 04:31:53 rin Exp $ */ 2 1.1 gdamore 3 1.1 gdamore /*- 4 1.1 gdamore * Copyright (c) 2005 Iain Hibbert. 5 1.1 gdamore * Copyright (c) 2006 Itronix Inc. 6 1.1 gdamore * All rights reserved. 7 1.1 gdamore * 8 1.1 gdamore * Redistribution and use in source and binary forms, with or without 9 1.1 gdamore * modification, are permitted provided that the following conditions 10 1.1 gdamore * are met: 11 1.1 gdamore * 1. Redistributions of source code must retain the above copyright 12 1.1 gdamore * notice, this list of conditions and the following disclaimer. 13 1.1 gdamore * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 gdamore * notice, this list of conditions and the following disclaimer in the 15 1.1 gdamore * documentation and/or other materials provided with the distribution. 16 1.1 gdamore * 3. The name of Itronix Inc. may not be used to endorse 17 1.1 gdamore * or promote products derived from this software without specific 18 1.1 gdamore * prior written permission. 19 1.1 gdamore * 20 1.1 gdamore * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 21 1.1 gdamore * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.1 gdamore * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.1 gdamore * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 24 1.1 gdamore * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 1.1 gdamore * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 1.1 gdamore * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 1.1 gdamore * ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.1 gdamore * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.1 gdamore * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.1 gdamore * POSSIBILITY OF SUCH DAMAGE. 31 1.1 gdamore */ 32 1.1 gdamore 33 1.1 gdamore #include <sys/cdefs.h> 34 1.37 rin __KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.37 2024/07/05 04:31:53 rin Exp $"); 35 1.6 plunky 36 1.6 plunky /* load symbolic names */ 37 1.6 plunky #ifdef BLUETOOTH_DEBUG 38 1.6 plunky #define PRUREQUESTS 39 1.6 plunky #define PRCOREQUESTS 40 1.6 plunky #endif 41 1.1 gdamore 42 1.1 gdamore #include <sys/param.h> 43 1.1 gdamore #include <sys/domain.h> 44 1.1 gdamore #include <sys/kernel.h> 45 1.1 gdamore #include <sys/mbuf.h> 46 1.1 gdamore #include <sys/proc.h> 47 1.1 gdamore #include <sys/protosw.h> 48 1.1 gdamore #include <sys/socket.h> 49 1.1 gdamore #include <sys/socketvar.h> 50 1.1 gdamore #include <sys/systm.h> 51 1.1 gdamore 52 1.1 gdamore #include <netbt/bluetooth.h> 53 1.1 gdamore #include <netbt/l2cap.h> 54 1.1 gdamore 55 1.1 gdamore /* 56 1.1 gdamore * L2CAP Sockets 57 1.1 gdamore * 58 1.1 gdamore * SOCK_SEQPACKET - normal L2CAP connection 59 1.1 gdamore * 60 1.1 gdamore * SOCK_DGRAM - connectionless L2CAP - XXX not yet 61 1.1 gdamore */ 62 1.1 gdamore 63 1.1 gdamore static void l2cap_connecting(void *); 64 1.1 gdamore static void l2cap_connected(void *); 65 1.1 gdamore static void l2cap_disconnected(void *, int); 66 1.1 gdamore static void *l2cap_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); 67 1.1 gdamore static void l2cap_complete(void *, int); 68 1.7 plunky static void l2cap_linkmode(void *, int); 69 1.1 gdamore static void l2cap_input(void *, struct mbuf *); 70 1.1 gdamore 71 1.1 gdamore static const struct btproto l2cap_proto = { 72 1.1 gdamore l2cap_connecting, 73 1.1 gdamore l2cap_connected, 74 1.1 gdamore l2cap_disconnected, 75 1.1 gdamore l2cap_newconn, 76 1.1 gdamore l2cap_complete, 77 1.7 plunky l2cap_linkmode, 78 1.7 plunky l2cap_input, 79 1.1 gdamore }; 80 1.1 gdamore 81 1.1 gdamore /* sysctl variables */ 82 1.1 gdamore int l2cap_sendspace = 4096; 83 1.1 gdamore int l2cap_recvspace = 4096; 84 1.1 gdamore 85 1.12 rmind static int 86 1.14 rmind l2cap_attach(struct socket *so, int proto) 87 1.12 rmind { 88 1.12 rmind int error; 89 1.12 rmind 90 1.12 rmind KASSERT(so->so_pcb == NULL); 91 1.12 rmind 92 1.12 rmind if (so->so_lock == NULL) { 93 1.12 rmind mutex_obj_hold(bt_lock); 94 1.12 rmind so->so_lock = bt_lock; 95 1.12 rmind solock(so); 96 1.12 rmind } 97 1.12 rmind KASSERT(solocked(so)); 98 1.12 rmind 99 1.12 rmind /* 100 1.12 rmind * For L2CAP socket PCB we just use an l2cap_channel structure 101 1.12 rmind * since we have nothing to add.. 102 1.12 rmind */ 103 1.12 rmind error = soreserve(so, l2cap_sendspace, l2cap_recvspace); 104 1.12 rmind if (error) 105 1.12 rmind return error; 106 1.12 rmind 107 1.14 rmind return l2cap_attach_pcb((struct l2cap_channel **)&so->so_pcb, 108 1.12 rmind &l2cap_proto, so); 109 1.12 rmind } 110 1.12 rmind 111 1.12 rmind static void 112 1.14 rmind l2cap_detach(struct socket *so) 113 1.12 rmind { 114 1.13 rmind KASSERT(so->so_pcb != NULL); 115 1.14 rmind l2cap_detach_pcb((struct l2cap_channel **)&so->so_pcb); 116 1.12 rmind KASSERT(so->so_pcb == NULL); 117 1.12 rmind } 118 1.12 rmind 119 1.16 rtr static int 120 1.33 rtr l2cap_accept(struct socket *so, struct sockaddr *nam) 121 1.23 rtr { 122 1.23 rtr struct l2cap_channel *pcb = so->so_pcb; 123 1.23 rtr 124 1.23 rtr KASSERT(solocked(so)); 125 1.23 rtr KASSERT(nam != NULL); 126 1.23 rtr 127 1.23 rtr if (pcb == NULL) 128 1.23 rtr return EINVAL; 129 1.23 rtr 130 1.33 rtr return l2cap_peeraddr_pcb(pcb, (struct sockaddr_bt *)nam); 131 1.23 rtr } 132 1.23 rtr 133 1.23 rtr static int 134 1.32 rtr l2cap_bind(struct socket *so, struct sockaddr *nam, struct lwp *l) 135 1.25 rtr { 136 1.25 rtr struct l2cap_channel *pcb = so->so_pcb; 137 1.32 rtr struct sockaddr_bt *sa = (struct sockaddr_bt *)nam; 138 1.25 rtr 139 1.25 rtr KASSERT(solocked(so)); 140 1.25 rtr KASSERT(nam != NULL); 141 1.25 rtr 142 1.25 rtr if (pcb == NULL) 143 1.25 rtr return EINVAL; 144 1.25 rtr 145 1.25 rtr if (sa->bt_len != sizeof(struct sockaddr_bt)) 146 1.25 rtr return EINVAL; 147 1.25 rtr 148 1.25 rtr if (sa->bt_family != AF_BLUETOOTH) 149 1.25 rtr return EAFNOSUPPORT; 150 1.25 rtr 151 1.25 rtr return l2cap_bind_pcb(pcb, sa); 152 1.25 rtr } 153 1.25 rtr 154 1.25 rtr static int 155 1.28 rtr l2cap_listen(struct socket *so, struct lwp *l) 156 1.25 rtr { 157 1.25 rtr struct l2cap_channel *pcb = so->so_pcb; 158 1.25 rtr 159 1.25 rtr KASSERT(solocked(so)); 160 1.25 rtr 161 1.25 rtr if (pcb == NULL) 162 1.25 rtr return EINVAL; 163 1.25 rtr 164 1.25 rtr return l2cap_listen_pcb(pcb); 165 1.25 rtr } 166 1.25 rtr 167 1.25 rtr static int 168 1.35 rtr l2cap_connect(struct socket *so, struct sockaddr *nam, struct lwp *l) 169 1.26 rtr { 170 1.26 rtr struct l2cap_channel *pcb = so->so_pcb; 171 1.35 rtr struct sockaddr_bt *sa = (struct sockaddr_bt *)nam; 172 1.26 rtr 173 1.26 rtr KASSERT(solocked(so)); 174 1.26 rtr KASSERT(nam != NULL); 175 1.26 rtr 176 1.26 rtr if (pcb == NULL) 177 1.26 rtr return EINVAL; 178 1.26 rtr 179 1.26 rtr if (sa->bt_len != sizeof(struct sockaddr_bt)) 180 1.26 rtr return EINVAL; 181 1.26 rtr 182 1.26 rtr if (sa->bt_family != AF_BLUETOOTH) 183 1.26 rtr return EAFNOSUPPORT; 184 1.26 rtr 185 1.26 rtr soisconnecting(so); 186 1.26 rtr return l2cap_connect_pcb(pcb, sa); 187 1.26 rtr } 188 1.26 rtr 189 1.26 rtr static int 190 1.31 rtr l2cap_connect2(struct socket *so, struct socket *so2) 191 1.31 rtr { 192 1.31 rtr KASSERT(solocked(so)); 193 1.31 rtr 194 1.31 rtr if (so->so_pcb == NULL) 195 1.31 rtr return EINVAL; 196 1.31 rtr 197 1.31 rtr return EOPNOTSUPP; 198 1.31 rtr } 199 1.31 rtr 200 1.31 rtr static int 201 1.27 rtr l2cap_disconnect(struct socket *so) 202 1.27 rtr { 203 1.27 rtr struct l2cap_channel *pcb = so->so_pcb; 204 1.27 rtr 205 1.27 rtr KASSERT(solocked(so)); 206 1.27 rtr 207 1.27 rtr if (pcb == NULL) 208 1.27 rtr return EINVAL; 209 1.27 rtr 210 1.27 rtr soisdisconnecting(so); 211 1.27 rtr return l2cap_disconnect_pcb(pcb, so->so_linger); 212 1.27 rtr } 213 1.27 rtr 214 1.27 rtr static int 215 1.27 rtr l2cap_shutdown(struct socket *so) 216 1.27 rtr { 217 1.27 rtr KASSERT(solocked(so)); 218 1.27 rtr 219 1.27 rtr socantsendmore(so); 220 1.27 rtr return 0; 221 1.27 rtr } 222 1.27 rtr 223 1.27 rtr static int 224 1.27 rtr l2cap_abort(struct socket *so) 225 1.27 rtr { 226 1.27 rtr struct l2cap_channel *pcb = so->so_pcb; 227 1.27 rtr 228 1.27 rtr KASSERT(solocked(so)); 229 1.27 rtr 230 1.27 rtr if (pcb == NULL) 231 1.27 rtr return EINVAL; 232 1.27 rtr 233 1.27 rtr l2cap_disconnect_pcb(pcb, 0); 234 1.27 rtr soisdisconnected(so); 235 1.27 rtr l2cap_detach(so); 236 1.27 rtr return 0; 237 1.27 rtr } 238 1.27 rtr 239 1.27 rtr static int 240 1.21 rtr l2cap_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp) 241 1.16 rtr { 242 1.16 rtr return EPASSTHROUGH; 243 1.16 rtr } 244 1.16 rtr 245 1.18 rtr static int 246 1.18 rtr l2cap_stat(struct socket *so, struct stat *ub) 247 1.18 rtr { 248 1.21 rtr KASSERT(solocked(so)); 249 1.21 rtr 250 1.20 rtr return 0; 251 1.18 rtr } 252 1.18 rtr 253 1.22 rtr static int 254 1.33 rtr l2cap_peeraddr(struct socket *so, struct sockaddr *nam) 255 1.22 rtr { 256 1.22 rtr struct l2cap_channel *pcb = so->so_pcb; 257 1.22 rtr 258 1.22 rtr KASSERT(solocked(so)); 259 1.22 rtr KASSERT(pcb != NULL); 260 1.22 rtr KASSERT(nam != NULL); 261 1.22 rtr 262 1.33 rtr return l2cap_peeraddr_pcb(pcb, (struct sockaddr_bt *)nam); 263 1.22 rtr } 264 1.22 rtr 265 1.22 rtr static int 266 1.33 rtr l2cap_sockaddr(struct socket *so, struct sockaddr *nam) 267 1.22 rtr { 268 1.22 rtr struct l2cap_channel *pcb = so->so_pcb; 269 1.22 rtr 270 1.22 rtr KASSERT(solocked(so)); 271 1.22 rtr KASSERT(pcb != NULL); 272 1.22 rtr KASSERT(nam != NULL); 273 1.22 rtr 274 1.33 rtr return l2cap_sockaddr_pcb(pcb, (struct sockaddr_bt *)nam); 275 1.22 rtr } 276 1.22 rtr 277 1.24 rtr static int 278 1.30 rtr l2cap_rcvd(struct socket *so, int flags, struct lwp *l) 279 1.30 rtr { 280 1.30 rtr KASSERT(solocked(so)); 281 1.30 rtr 282 1.30 rtr return EOPNOTSUPP; 283 1.30 rtr } 284 1.30 rtr 285 1.30 rtr static int 286 1.24 rtr l2cap_recvoob(struct socket *so, struct mbuf *m, int flags) 287 1.24 rtr { 288 1.24 rtr KASSERT(solocked(so)); 289 1.24 rtr 290 1.24 rtr return EOPNOTSUPP; 291 1.24 rtr } 292 1.24 rtr 293 1.24 rtr static int 294 1.35 rtr l2cap_send(struct socket *so, struct mbuf *m, struct sockaddr *nam, 295 1.29 rtr struct mbuf *control, struct lwp *l) 296 1.29 rtr { 297 1.29 rtr struct l2cap_channel *pcb = so->so_pcb; 298 1.29 rtr struct mbuf *m0; 299 1.29 rtr int error = 0; 300 1.29 rtr 301 1.29 rtr KASSERT(solocked(so)); 302 1.29 rtr KASSERT(m != NULL); 303 1.29 rtr 304 1.37 rin m_freem(control); 305 1.29 rtr 306 1.29 rtr if (pcb == NULL) { 307 1.29 rtr error = EINVAL; 308 1.29 rtr goto release; 309 1.29 rtr } 310 1.29 rtr 311 1.29 rtr if (m->m_pkthdr.len == 0) 312 1.29 rtr goto release; 313 1.29 rtr 314 1.29 rtr if (m->m_pkthdr.len > pcb->lc_omtu) { 315 1.29 rtr error = EMSGSIZE; 316 1.29 rtr goto release; 317 1.29 rtr } 318 1.29 rtr 319 1.29 rtr m0 = m_copypacket(m, M_DONTWAIT); 320 1.29 rtr if (m0 == NULL) { 321 1.29 rtr error = ENOMEM; 322 1.29 rtr goto release; 323 1.29 rtr } 324 1.29 rtr 325 1.29 rtr sbappendrecord(&so->so_snd, m); 326 1.29 rtr return l2cap_send_pcb(pcb, m0); 327 1.29 rtr 328 1.29 rtr release: 329 1.37 rin m_freem(m); 330 1.29 rtr 331 1.29 rtr return error; 332 1.29 rtr } 333 1.29 rtr 334 1.29 rtr static int 335 1.24 rtr l2cap_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control) 336 1.24 rtr { 337 1.24 rtr KASSERT(solocked(so)); 338 1.24 rtr 339 1.36 martin m_freem(m); 340 1.36 martin m_freem(control); 341 1.24 rtr 342 1.24 rtr return EOPNOTSUPP; 343 1.24 rtr } 344 1.24 rtr 345 1.31 rtr static int 346 1.31 rtr l2cap_purgeif(struct socket *so, struct ifnet *ifp) 347 1.31 rtr { 348 1.31 rtr 349 1.31 rtr return EOPNOTSUPP; 350 1.31 rtr } 351 1.31 rtr 352 1.1 gdamore /* 353 1.9 plunky * l2cap_ctloutput(req, socket, sockopt) 354 1.1 gdamore * 355 1.1 gdamore * Apply configuration commands to channel. This corresponds to 356 1.1 gdamore * "Reconfigure Channel Request" in the L2CAP specification. 357 1.1 gdamore */ 358 1.1 gdamore int 359 1.9 plunky l2cap_ctloutput(int req, struct socket *so, struct sockopt *sopt) 360 1.1 gdamore { 361 1.1 gdamore struct l2cap_channel *pcb = so->so_pcb; 362 1.1 gdamore int err = 0; 363 1.1 gdamore 364 1.1 gdamore DPRINTFN(2, "%s\n", prcorequests[req]); 365 1.1 gdamore 366 1.4 plunky if (pcb == NULL) 367 1.4 plunky return EINVAL; 368 1.4 plunky 369 1.9 plunky if (sopt->sopt_level != BTPROTO_L2CAP) 370 1.4 plunky return ENOPROTOOPT; 371 1.1 gdamore 372 1.1 gdamore switch(req) { 373 1.1 gdamore case PRCO_GETOPT: 374 1.9 plunky err = l2cap_getopt(pcb, sopt); 375 1.1 gdamore break; 376 1.1 gdamore 377 1.1 gdamore case PRCO_SETOPT: 378 1.9 plunky err = l2cap_setopt(pcb, sopt); 379 1.1 gdamore break; 380 1.1 gdamore 381 1.1 gdamore default: 382 1.4 plunky err = ENOPROTOOPT; 383 1.1 gdamore break; 384 1.1 gdamore } 385 1.1 gdamore 386 1.1 gdamore return err; 387 1.1 gdamore } 388 1.1 gdamore 389 1.1 gdamore /********************************************************************** 390 1.1 gdamore * 391 1.1 gdamore * L2CAP Protocol socket callbacks 392 1.1 gdamore * 393 1.1 gdamore */ 394 1.1 gdamore 395 1.1 gdamore static void 396 1.1 gdamore l2cap_connecting(void *arg) 397 1.1 gdamore { 398 1.1 gdamore struct socket *so = arg; 399 1.1 gdamore 400 1.1 gdamore DPRINTF("Connecting\n"); 401 1.1 gdamore soisconnecting(so); 402 1.1 gdamore } 403 1.1 gdamore 404 1.1 gdamore static void 405 1.1 gdamore l2cap_connected(void *arg) 406 1.1 gdamore { 407 1.1 gdamore struct socket *so = arg; 408 1.1 gdamore 409 1.1 gdamore DPRINTF("Connected\n"); 410 1.1 gdamore soisconnected(so); 411 1.1 gdamore } 412 1.1 gdamore 413 1.1 gdamore static void 414 1.1 gdamore l2cap_disconnected(void *arg, int err) 415 1.1 gdamore { 416 1.1 gdamore struct socket *so = arg; 417 1.1 gdamore 418 1.1 gdamore DPRINTF("Disconnected (%d)\n", err); 419 1.1 gdamore 420 1.1 gdamore so->so_error = err; 421 1.1 gdamore soisdisconnected(so); 422 1.1 gdamore } 423 1.1 gdamore 424 1.1 gdamore static void * 425 1.3 christos l2cap_newconn(void *arg, struct sockaddr_bt *laddr, 426 1.3 christos struct sockaddr_bt *raddr) 427 1.1 gdamore { 428 1.1 gdamore struct socket *so = arg; 429 1.1 gdamore 430 1.1 gdamore DPRINTF("New Connection\n"); 431 1.10 rmind so = sonewconn(so, false); 432 1.1 gdamore if (so == NULL) 433 1.1 gdamore return NULL; 434 1.1 gdamore 435 1.1 gdamore soisconnecting(so); 436 1.1 gdamore 437 1.1 gdamore return so->so_pcb; 438 1.1 gdamore } 439 1.1 gdamore 440 1.1 gdamore static void 441 1.1 gdamore l2cap_complete(void *arg, int count) 442 1.1 gdamore { 443 1.1 gdamore struct socket *so = arg; 444 1.1 gdamore 445 1.1 gdamore while (count-- > 0) 446 1.1 gdamore sbdroprecord(&so->so_snd); 447 1.1 gdamore 448 1.1 gdamore sowwakeup(so); 449 1.1 gdamore } 450 1.1 gdamore 451 1.1 gdamore static void 452 1.7 plunky l2cap_linkmode(void *arg, int new) 453 1.7 plunky { 454 1.7 plunky struct socket *so = arg; 455 1.9 plunky struct sockopt sopt; 456 1.7 plunky int mode; 457 1.7 plunky 458 1.7 plunky DPRINTF("auth %s, encrypt %s, secure %s\n", 459 1.7 plunky (new & L2CAP_LM_AUTH ? "on" : "off"), 460 1.7 plunky (new & L2CAP_LM_ENCRYPT ? "on" : "off"), 461 1.7 plunky (new & L2CAP_LM_SECURE ? "on" : "off")); 462 1.7 plunky 463 1.9 plunky sockopt_init(&sopt, BTPROTO_L2CAP, SO_L2CAP_LM, 0); 464 1.9 plunky (void)l2cap_getopt(so->so_pcb, &sopt); 465 1.9 plunky (void)sockopt_getint(&sopt, &mode); 466 1.9 plunky sockopt_destroy(&sopt); 467 1.9 plunky 468 1.7 plunky if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH)) 469 1.7 plunky || ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT)) 470 1.7 plunky || ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE))) 471 1.27 rtr l2cap_disconnect_pcb(so->so_pcb, 0); 472 1.7 plunky } 473 1.7 plunky 474 1.7 plunky static void 475 1.1 gdamore l2cap_input(void *arg, struct mbuf *m) 476 1.1 gdamore { 477 1.1 gdamore struct socket *so = arg; 478 1.1 gdamore 479 1.1 gdamore if (m->m_pkthdr.len > sbspace(&so->so_rcv)) { 480 1.1 gdamore printf("%s: packet (%d bytes) dropped (socket buffer full)\n", 481 1.1 gdamore __func__, m->m_pkthdr.len); 482 1.1 gdamore m_freem(m); 483 1.1 gdamore return; 484 1.1 gdamore } 485 1.1 gdamore 486 1.1 gdamore DPRINTFN(10, "received %d bytes\n", m->m_pkthdr.len); 487 1.1 gdamore 488 1.1 gdamore sbappendrecord(&so->so_rcv, m); 489 1.1 gdamore sorwakeup(so); 490 1.1 gdamore } 491 1.11 rmind 492 1.15 rmind PR_WRAP_USRREQS(l2cap) 493 1.11 rmind 494 1.15 rmind #define l2cap_attach l2cap_attach_wrapper 495 1.15 rmind #define l2cap_detach l2cap_detach_wrapper 496 1.23 rtr #define l2cap_accept l2cap_accept_wrapper 497 1.25 rtr #define l2cap_bind l2cap_bind_wrapper 498 1.25 rtr #define l2cap_listen l2cap_listen_wrapper 499 1.26 rtr #define l2cap_connect l2cap_connect_wrapper 500 1.31 rtr #define l2cap_connect2 l2cap_connect2_wrapper 501 1.27 rtr #define l2cap_disconnect l2cap_disconnect_wrapper 502 1.27 rtr #define l2cap_shutdown l2cap_shutdown_wrapper 503 1.27 rtr #define l2cap_abort l2cap_abort_wrapper 504 1.16 rtr #define l2cap_ioctl l2cap_ioctl_wrapper 505 1.18 rtr #define l2cap_stat l2cap_stat_wrapper 506 1.22 rtr #define l2cap_peeraddr l2cap_peeraddr_wrapper 507 1.22 rtr #define l2cap_sockaddr l2cap_sockaddr_wrapper 508 1.30 rtr #define l2cap_rcvd l2cap_rcvd_wrapper 509 1.24 rtr #define l2cap_recvoob l2cap_recvoob_wrapper 510 1.29 rtr #define l2cap_send l2cap_send_wrapper 511 1.24 rtr #define l2cap_sendoob l2cap_sendoob_wrapper 512 1.31 rtr #define l2cap_purgeif l2cap_purgeif_wrapper 513 1.11 rmind 514 1.11 rmind const struct pr_usrreqs l2cap_usrreqs = { 515 1.14 rmind .pr_attach = l2cap_attach, 516 1.14 rmind .pr_detach = l2cap_detach, 517 1.23 rtr .pr_accept = l2cap_accept, 518 1.25 rtr .pr_bind = l2cap_bind, 519 1.25 rtr .pr_listen = l2cap_listen, 520 1.26 rtr .pr_connect = l2cap_connect, 521 1.31 rtr .pr_connect2 = l2cap_connect2, 522 1.27 rtr .pr_disconnect = l2cap_disconnect, 523 1.27 rtr .pr_shutdown = l2cap_shutdown, 524 1.27 rtr .pr_abort = l2cap_abort, 525 1.16 rtr .pr_ioctl = l2cap_ioctl, 526 1.18 rtr .pr_stat = l2cap_stat, 527 1.22 rtr .pr_peeraddr = l2cap_peeraddr, 528 1.22 rtr .pr_sockaddr = l2cap_sockaddr, 529 1.30 rtr .pr_rcvd = l2cap_rcvd, 530 1.24 rtr .pr_recvoob = l2cap_recvoob, 531 1.29 rtr .pr_send = l2cap_send, 532 1.24 rtr .pr_sendoob = l2cap_sendoob, 533 1.31 rtr .pr_purgeif = l2cap_purgeif, 534 1.11 rmind }; 535