| 1 | /* $NetBSD: l2cap_upper.c,v 1.18 2014/08/05 07:55:32 rtr Exp $ */ |
| 2 | |
| 3 | /*- |
| 4 | * Copyright (c) 2005 Iain Hibbert. |
| 5 | * Copyright (c) 2006 Itronix Inc. |
| 6 | * All rights reserved. |
| 7 | * |
| 8 | * Redistribution and use in source and binary forms, with or without |
| 9 | * modification, are permitted provided that the following conditions |
| 10 | * are met: |
| 11 | * 1. Redistributions of source code must retain the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer. |
| 13 | * 2. Redistributions in binary form must reproduce the above copyright |
| 14 | * notice, this list of conditions and the following disclaimer in the |
| 15 | * documentation and/or other materials provided with the distribution. |
| 16 | * 3. The name of Itronix Inc. may not be used to endorse |
| 17 | * or promote products derived from this software without specific |
| 18 | * prior written permission. |
| 19 | * |
| 20 | * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND |
| 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
| 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY |
| 24 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 25 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 26 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 27 | * ON ANY THEORY OF LIABILITY, WHETHER IN |
| 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 30 | * POSSIBILITY OF SUCH DAMAGE. |
| 31 | */ |
| 32 | |
| 33 | #include <sys/cdefs.h> |
| 34 | __KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.18 2014/08/05 07:55:32 rtr Exp $" ); |
| 35 | |
| 36 | #include <sys/param.h> |
| 37 | #include <sys/kernel.h> |
| 38 | #include <sys/mbuf.h> |
| 39 | #include <sys/proc.h> |
| 40 | #include <sys/queue.h> |
| 41 | #include <sys/socket.h> |
| 42 | #include <sys/socketvar.h> |
| 43 | #include <sys/systm.h> |
| 44 | |
| 45 | #include <netbt/bluetooth.h> |
| 46 | #include <netbt/hci.h> |
| 47 | #include <netbt/l2cap.h> |
| 48 | |
| 49 | /******************************************************************************* |
| 50 | * |
| 51 | * L2CAP Channel - Upper Protocol API |
| 52 | */ |
| 53 | |
| 54 | /* |
| 55 | * l2cap_attach_pcb(handle, btproto, upper) |
| 56 | * |
| 57 | * attach new l2cap_channel to handle, populate |
| 58 | * with reasonable defaults |
| 59 | */ |
| 60 | int |
| 61 | l2cap_attach_pcb(struct l2cap_channel **handle, |
| 62 | const struct btproto *proto, void *upper) |
| 63 | { |
| 64 | struct l2cap_channel *chan; |
| 65 | |
| 66 | KASSERT(handle != NULL); |
| 67 | KASSERT(proto != NULL); |
| 68 | KASSERT(upper != NULL); |
| 69 | |
| 70 | chan = malloc(sizeof(struct l2cap_channel), M_BLUETOOTH, |
| 71 | M_NOWAIT | M_ZERO); |
| 72 | if (chan == NULL) |
| 73 | return ENOMEM; |
| 74 | |
| 75 | chan->lc_proto = proto; |
| 76 | chan->lc_upper = upper; |
| 77 | |
| 78 | chan->lc_state = L2CAP_CLOSED; |
| 79 | |
| 80 | chan->lc_lcid = L2CAP_NULL_CID; |
| 81 | chan->lc_rcid = L2CAP_NULL_CID; |
| 82 | |
| 83 | chan->lc_laddr.bt_len = sizeof(struct sockaddr_bt); |
| 84 | chan->lc_laddr.bt_family = AF_BLUETOOTH; |
| 85 | chan->lc_laddr.bt_psm = L2CAP_PSM_ANY; |
| 86 | |
| 87 | chan->lc_raddr.bt_len = sizeof(struct sockaddr_bt); |
| 88 | chan->lc_raddr.bt_family = AF_BLUETOOTH; |
| 89 | chan->lc_raddr.bt_psm = L2CAP_PSM_ANY; |
| 90 | |
| 91 | chan->lc_imtu = L2CAP_MTU_DEFAULT; |
| 92 | chan->lc_omtu = L2CAP_MTU_DEFAULT; |
| 93 | chan->lc_flush = L2CAP_FLUSH_TIMO_DEFAULT; |
| 94 | |
| 95 | memcpy(&chan->lc_iqos, &l2cap_default_qos, sizeof(l2cap_qos_t)); |
| 96 | memcpy(&chan->lc_oqos, &l2cap_default_qos, sizeof(l2cap_qos_t)); |
| 97 | |
| 98 | MBUFQ_INIT(&chan->lc_txq); |
| 99 | |
| 100 | *handle = chan; |
| 101 | return 0; |
| 102 | } |
| 103 | |
| 104 | /* |
| 105 | * l2cap_bind_pcb(l2cap_channel, sockaddr) |
| 106 | * |
| 107 | * set local address of channel |
| 108 | */ |
| 109 | int |
| 110 | l2cap_bind_pcb(struct l2cap_channel *chan, struct sockaddr_bt *addr) |
| 111 | { |
| 112 | |
| 113 | if (chan->lc_lcid != L2CAP_NULL_CID) |
| 114 | return EINVAL; |
| 115 | |
| 116 | memcpy(&chan->lc_laddr, addr, sizeof(struct sockaddr_bt)); |
| 117 | return 0; |
| 118 | } |
| 119 | |
| 120 | /* |
| 121 | * l2cap_sockaddr_pcb(l2cap_channel, sockaddr) |
| 122 | * |
| 123 | * get local address of channel |
| 124 | */ |
| 125 | int |
| 126 | l2cap_sockaddr_pcb(struct l2cap_channel *chan, struct sockaddr_bt *addr) |
| 127 | { |
| 128 | |
| 129 | memcpy(addr, &chan->lc_laddr, sizeof(struct sockaddr_bt)); |
| 130 | return 0; |
| 131 | } |
| 132 | |
| 133 | /* |
| 134 | * l2cap_connect_pcb(l2cap_channel, sockaddr) |
| 135 | * |
| 136 | * Initiate a connection to destination. This corresponds to |
| 137 | * "Open Channel Request" in the L2CAP specification and will |
| 138 | * result in one of the following: |
| 139 | * |
| 140 | * proto->connected(upper) |
| 141 | * proto->disconnected(upper, error) |
| 142 | * |
| 143 | * and, optionally |
| 144 | * proto->connecting(upper) |
| 145 | */ |
| 146 | int |
| 147 | l2cap_connect_pcb(struct l2cap_channel *chan, struct sockaddr_bt *dest) |
| 148 | { |
| 149 | struct hci_unit *unit; |
| 150 | int err; |
| 151 | |
| 152 | memcpy(&chan->lc_raddr, dest, sizeof(struct sockaddr_bt)); |
| 153 | |
| 154 | if (L2CAP_PSM_INVALID(chan->lc_raddr.bt_psm)) |
| 155 | return EINVAL; |
| 156 | |
| 157 | if (bdaddr_any(&chan->lc_raddr.bt_bdaddr)) |
| 158 | return EDESTADDRREQ; |
| 159 | |
| 160 | /* set local address if it needs setting */ |
| 161 | if (bdaddr_any(&chan->lc_laddr.bt_bdaddr)) { |
| 162 | err = hci_route_lookup(&chan->lc_laddr.bt_bdaddr, |
| 163 | &chan->lc_raddr.bt_bdaddr); |
| 164 | if (err) |
| 165 | return err; |
| 166 | } |
| 167 | |
| 168 | unit = hci_unit_lookup(&chan->lc_laddr.bt_bdaddr); |
| 169 | if (unit == NULL) |
| 170 | return EHOSTUNREACH; |
| 171 | |
| 172 | /* attach to active list */ |
| 173 | err = l2cap_cid_alloc(chan); |
| 174 | if (err) |
| 175 | return err; |
| 176 | |
| 177 | /* open link to remote device */ |
| 178 | chan->lc_link = hci_acl_open(unit, &chan->lc_raddr.bt_bdaddr); |
| 179 | if (chan->lc_link == NULL) |
| 180 | return EHOSTUNREACH; |
| 181 | |
| 182 | /* set the link mode */ |
| 183 | err = l2cap_setmode(chan); |
| 184 | if (err == EINPROGRESS) { |
| 185 | chan->lc_state = L2CAP_WAIT_SEND_CONNECT_REQ; |
| 186 | (*chan->lc_proto->connecting)(chan->lc_upper); |
| 187 | return 0; |
| 188 | } |
| 189 | if (err) |
| 190 | goto fail; |
| 191 | |
| 192 | /* |
| 193 | * We can queue a connect request now even though the link may |
| 194 | * not yet be open; Our mode setting is assured, and the queue |
| 195 | * will be started automatically at the right time. |
| 196 | */ |
| 197 | chan->lc_state = L2CAP_WAIT_RECV_CONNECT_RSP; |
| 198 | err = l2cap_send_connect_req(chan); |
| 199 | if (err) |
| 200 | goto fail; |
| 201 | |
| 202 | return 0; |
| 203 | |
| 204 | fail: |
| 205 | chan->lc_state = L2CAP_CLOSED; |
| 206 | hci_acl_close(chan->lc_link, err); |
| 207 | chan->lc_link = NULL; |
| 208 | return err; |
| 209 | } |
| 210 | |
| 211 | /* |
| 212 | * l2cap_peeraddr_pcb(l2cap_channel, sockaddr) |
| 213 | * |
| 214 | * get remote address of channel |
| 215 | */ |
| 216 | int |
| 217 | l2cap_peeraddr_pcb(struct l2cap_channel *chan, struct sockaddr_bt *addr) |
| 218 | { |
| 219 | |
| 220 | memcpy(addr, &chan->lc_raddr, sizeof(struct sockaddr_bt)); |
| 221 | return 0; |
| 222 | } |
| 223 | |
| 224 | /* |
| 225 | * l2cap_disconnect_pcb(l2cap_channel, linger) |
| 226 | * |
| 227 | * Initiate L2CAP disconnection. This corresponds to |
| 228 | * "Close Channel Request" in the L2CAP specification |
| 229 | * and will result in a call to |
| 230 | * |
| 231 | * proto->disconnected(upper, error) |
| 232 | * |
| 233 | * when the disconnection is complete. If linger is set, |
| 234 | * the call will not be made until data has flushed from |
| 235 | * the queue. |
| 236 | */ |
| 237 | int |
| 238 | l2cap_disconnect_pcb(struct l2cap_channel *chan, int linger) |
| 239 | { |
| 240 | int err = 0; |
| 241 | |
| 242 | if (chan->lc_state == L2CAP_CLOSED |
| 243 | || chan->lc_state == L2CAP_WAIT_DISCONNECT) |
| 244 | return EINVAL; |
| 245 | |
| 246 | chan->lc_flags |= L2CAP_SHUTDOWN; |
| 247 | |
| 248 | /* |
| 249 | * no need to do anything unless the queue is empty or |
| 250 | * we are not lingering.. |
| 251 | */ |
| 252 | if ((MBUFQ_FIRST(&chan->lc_txq) == NULL && chan->lc_pending == 0) |
| 253 | || linger == 0) { |
| 254 | chan->lc_state = L2CAP_WAIT_DISCONNECT; |
| 255 | err = l2cap_send_disconnect_req(chan); |
| 256 | if (err) |
| 257 | l2cap_close(chan, err); |
| 258 | } |
| 259 | return err; |
| 260 | } |
| 261 | |
| 262 | /* |
| 263 | * l2cap_detach_pcb(handle) |
| 264 | * |
| 265 | * Detach l2cap channel from handle & close it down |
| 266 | */ |
| 267 | void |
| 268 | l2cap_detach_pcb(struct l2cap_channel **handle) |
| 269 | { |
| 270 | struct l2cap_channel *chan; |
| 271 | |
| 272 | chan = *handle; |
| 273 | *handle = NULL; |
| 274 | |
| 275 | if (chan->lc_state != L2CAP_CLOSED) |
| 276 | l2cap_close(chan, 0); |
| 277 | |
| 278 | if (chan->lc_lcid != L2CAP_NULL_CID) { |
| 279 | LIST_REMOVE(chan, lc_ncid); |
| 280 | chan->lc_lcid = L2CAP_NULL_CID; |
| 281 | } |
| 282 | |
| 283 | MBUFQ_DRAIN(&chan->lc_txq); |
| 284 | |
| 285 | /* |
| 286 | * Could implement some kind of delayed expunge to make sure that the |
| 287 | * CID is really dead before it becomes available for reuse? |
| 288 | */ |
| 289 | |
| 290 | free(chan, M_BLUETOOTH); |
| 291 | } |
| 292 | |
| 293 | /* |
| 294 | * l2cap_listen_pcb(l2cap_channel) |
| 295 | * |
| 296 | * Use this channel as a listening post (until detached). This will |
| 297 | * result in calls to: |
| 298 | * |
| 299 | * proto->newconn(upper, laddr, raddr) |
| 300 | * |
| 301 | * for incoming connections matching the psm and local address of |
| 302 | * the channel. NULL address is permitted and matches any device. |
| 303 | * If L2CAP_PSM_ANY is bound the next higher unused value from the |
| 304 | * dynamic range (above 0x1001) will be selected. |
| 305 | * |
| 306 | * The upper layer should create and return a new channel. |
| 307 | * |
| 308 | * You cannot use this channel for anything else subsequent to this call |
| 309 | */ |
| 310 | int |
| 311 | l2cap_listen_pcb(struct l2cap_channel *chan) |
| 312 | { |
| 313 | struct l2cap_channel *used, *prev = NULL; |
| 314 | uint32_t psm; |
| 315 | |
| 316 | if (chan->lc_lcid != L2CAP_NULL_CID) |
| 317 | return EINVAL; |
| 318 | |
| 319 | /* |
| 320 | * This is simplistic but its not really worth spending a |
| 321 | * lot of time looking for an unused PSM.. |
| 322 | */ |
| 323 | if (chan->lc_laddr.bt_psm == L2CAP_PSM_ANY) { |
| 324 | psm = 0x1001; |
| 325 | used = LIST_FIRST(&l2cap_listen_list); |
| 326 | |
| 327 | if (used != NULL && used->lc_laddr.bt_psm >= psm) { |
| 328 | psm = used->lc_laddr.bt_psm + 0x0002; |
| 329 | if ((psm & 0x0100) != 0) |
| 330 | psm += 0x0100; |
| 331 | |
| 332 | if (psm > UINT16_MAX) |
| 333 | return EADDRNOTAVAIL; |
| 334 | } |
| 335 | |
| 336 | chan->lc_laddr.bt_psm = psm; |
| 337 | } else if (L2CAP_PSM_INVALID(chan->lc_laddr.bt_psm)) |
| 338 | return EINVAL; |
| 339 | |
| 340 | /* |
| 341 | * This CID is irrelevant, as the channel is not stored on the active |
| 342 | * list and the socket code does not allow operations on listening |
| 343 | * sockets, but we set it so the detach code knows to LIST_REMOVE the |
| 344 | * channel. |
| 345 | */ |
| 346 | chan->lc_lcid = L2CAP_SIGNAL_CID; |
| 347 | |
| 348 | /* |
| 349 | * The list of listening channels is stored in an order such that new |
| 350 | * listeners dont usurp current listeners, but that specific listening |
| 351 | * takes precedence over promiscuous, and the connect request code can |
| 352 | * easily use the first matching entry. |
| 353 | */ |
| 354 | LIST_FOREACH(used, &l2cap_listen_list, lc_ncid) { |
| 355 | if (used->lc_laddr.bt_psm < chan->lc_laddr.bt_psm) |
| 356 | break; |
| 357 | |
| 358 | if (used->lc_laddr.bt_psm == chan->lc_laddr.bt_psm |
| 359 | && bdaddr_any(&used->lc_laddr.bt_bdaddr) |
| 360 | && !bdaddr_any(&chan->lc_laddr.bt_bdaddr)) |
| 361 | break; |
| 362 | |
| 363 | prev = used; |
| 364 | } |
| 365 | |
| 366 | if (prev == NULL) |
| 367 | LIST_INSERT_HEAD(&l2cap_listen_list, chan, lc_ncid); |
| 368 | else |
| 369 | LIST_INSERT_AFTER(prev, chan, lc_ncid); |
| 370 | |
| 371 | return 0; |
| 372 | } |
| 373 | |
| 374 | /* |
| 375 | * l2cap_send_pcb(l2cap_channel, mbuf) |
| 376 | * |
| 377 | * Output SDU on channel described by channel. This corresponds |
| 378 | * to "Send Data Request" in the L2CAP specification. The upper |
| 379 | * layer will be notified when SDU's have completed sending by a |
| 380 | * call to: |
| 381 | * |
| 382 | * proto->complete(upper, n) |
| 383 | * |
| 384 | * (currently n == 1) |
| 385 | * |
| 386 | * Note: I'm not sure how this will work out, but I think that |
| 387 | * if outgoing Retransmission Mode or Flow Control Mode is |
| 388 | * negotiated then this call will not be made until the SDU has |
| 389 | * been acknowleged by the peer L2CAP entity. For 'Best Effort' |
| 390 | * it will be made when the packet has cleared the controller |
| 391 | * buffers. |
| 392 | * |
| 393 | * We only support Basic mode so far, so encapsulate with a |
| 394 | * B-Frame header and start sending if we are not already |
| 395 | */ |
| 396 | int |
| 397 | l2cap_send_pcb(struct l2cap_channel *chan, struct mbuf *m) |
| 398 | { |
| 399 | l2cap_hdr_t *hdr; |
| 400 | int plen; |
| 401 | |
| 402 | if (chan->lc_state == L2CAP_CLOSED) { |
| 403 | m_freem(m); |
| 404 | return ENOTCONN; |
| 405 | } |
| 406 | |
| 407 | plen = m->m_pkthdr.len; |
| 408 | |
| 409 | DPRINTFN(5, "send %d bytes on CID #%d (pending = %d)\n" , |
| 410 | plen, chan->lc_lcid, chan->lc_pending); |
| 411 | |
| 412 | /* Encapsulate with B-Frame */ |
| 413 | M_PREPEND(m, sizeof(l2cap_hdr_t), M_DONTWAIT); |
| 414 | if (m == NULL) |
| 415 | return ENOMEM; |
| 416 | |
| 417 | hdr = mtod(m, l2cap_hdr_t *); |
| 418 | hdr->length = htole16(plen); |
| 419 | hdr->dcid = htole16(chan->lc_rcid); |
| 420 | |
| 421 | /* Queue it on our list */ |
| 422 | MBUFQ_ENQUEUE(&chan->lc_txq, m); |
| 423 | |
| 424 | /* If we are not sending, then start doing so */ |
| 425 | if (chan->lc_pending == 0) |
| 426 | return l2cap_start(chan); |
| 427 | |
| 428 | return 0; |
| 429 | } |
| 430 | |
| 431 | /* |
| 432 | * l2cap_setopt(l2cap_channel, sopt) |
| 433 | * |
| 434 | * Apply configuration options to channel. This corresponds to |
| 435 | * "Configure Channel Request" in the L2CAP specification. |
| 436 | * |
| 437 | * for SO_L2CAP_LM, the settings will take effect when the |
| 438 | * channel is established. If the channel is already open, |
| 439 | * a call to |
| 440 | * proto->linkmode(upper, new) |
| 441 | * |
| 442 | * will be made when the change is complete. |
| 443 | */ |
| 444 | int |
| 445 | l2cap_setopt(struct l2cap_channel *chan, const struct sockopt *sopt) |
| 446 | { |
| 447 | int mode, err = 0; |
| 448 | uint16_t mtu; |
| 449 | |
| 450 | switch (sopt->sopt_name) { |
| 451 | case SO_L2CAP_IMTU: /* set Incoming MTU */ |
| 452 | err = sockopt_get(sopt, &mtu, sizeof(mtu)); |
| 453 | if (err) |
| 454 | break; |
| 455 | |
| 456 | if (mtu < L2CAP_MTU_MINIMUM) |
| 457 | err = EINVAL; |
| 458 | else if (chan->lc_state == L2CAP_CLOSED) |
| 459 | chan->lc_imtu = mtu; |
| 460 | else |
| 461 | err = EBUSY; |
| 462 | |
| 463 | break; |
| 464 | |
| 465 | case SO_L2CAP_LM: /* set link mode */ |
| 466 | err = sockopt_getint(sopt, &mode); |
| 467 | if (err) |
| 468 | break; |
| 469 | |
| 470 | mode &= (L2CAP_LM_SECURE | L2CAP_LM_ENCRYPT | L2CAP_LM_AUTH); |
| 471 | |
| 472 | if (mode & L2CAP_LM_SECURE) |
| 473 | mode |= L2CAP_LM_ENCRYPT; |
| 474 | |
| 475 | if (mode & L2CAP_LM_ENCRYPT) |
| 476 | mode |= L2CAP_LM_AUTH; |
| 477 | |
| 478 | chan->lc_mode = mode; |
| 479 | |
| 480 | if (chan->lc_state == L2CAP_OPEN) |
| 481 | err = l2cap_setmode(chan); |
| 482 | |
| 483 | break; |
| 484 | |
| 485 | case SO_L2CAP_OQOS: /* set Outgoing QoS flow spec */ |
| 486 | case SO_L2CAP_FLUSH: /* set Outgoing Flush Timeout */ |
| 487 | default: |
| 488 | err = ENOPROTOOPT; |
| 489 | break; |
| 490 | } |
| 491 | |
| 492 | return err; |
| 493 | } |
| 494 | |
| 495 | /* |
| 496 | * l2cap_getopt(l2cap_channel, sopt) |
| 497 | * |
| 498 | * Return configuration parameters. |
| 499 | */ |
| 500 | int |
| 501 | l2cap_getopt(struct l2cap_channel *chan, struct sockopt *sopt) |
| 502 | { |
| 503 | |
| 504 | switch (sopt->sopt_name) { |
| 505 | case SO_L2CAP_IMTU: /* get Incoming MTU */ |
| 506 | return sockopt_set(sopt, &chan->lc_imtu, sizeof(uint16_t)); |
| 507 | |
| 508 | case SO_L2CAP_OMTU: /* get Outgoing MTU */ |
| 509 | return sockopt_set(sopt, &chan->lc_omtu, sizeof(uint16_t)); |
| 510 | |
| 511 | case SO_L2CAP_IQOS: /* get Incoming QoS flow spec */ |
| 512 | return sockopt_set(sopt, &chan->lc_iqos, sizeof(l2cap_qos_t)); |
| 513 | |
| 514 | case SO_L2CAP_OQOS: /* get Outgoing QoS flow spec */ |
| 515 | return sockopt_set(sopt, &chan->lc_oqos, sizeof(l2cap_qos_t)); |
| 516 | |
| 517 | case SO_L2CAP_FLUSH: /* get Flush Timeout */ |
| 518 | return sockopt_set(sopt, &chan->lc_flush, sizeof(uint16_t)); |
| 519 | |
| 520 | case SO_L2CAP_LM: /* get link mode */ |
| 521 | return sockopt_setint(sopt, chan->lc_mode); |
| 522 | |
| 523 | default: |
| 524 | break; |
| 525 | } |
| 526 | |
| 527 | return ENOPROTOOPT; |
| 528 | } |
| 529 | |