1 /* $OpenBSD: l2cap_upper.c,v 1.2 2007/10/01 16:39:30 krw Exp $ */
2 /* $NetBSD: l2cap_upper.c,v 1.8 2007/04/29 20:23:36 msaitoh Exp $ */
5 * Copyright (c) 2005 Iain Hibbert.
6 * Copyright (c) 2006 Itronix Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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 * 3. The name of Itronix Inc. may not be used to endorse
18 * or promote products derived from this software without specific
19 * prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/param.h>
35 #include <sys/kernel.h>
38 #include <sys/queue.h>
39 #include <sys/socket.h>
40 #include <sys/socketvar.h>
41 #include <sys/systm.h>
42 #include <sys/endian.h>
44 #include <netbt/bluetooth.h>
45 #include <netbt/hci.h>
46 #include <netbt/l2cap.h>
48 /*******************************************************************************
50 * L2CAP Channel - Upper Protocol API
54 * l2cap_attach(handle, btproto, upper)
56 * attach new l2cap_channel to handle, populate
57 * with reasonable defaults
60 l2cap_attach(struct l2cap_channel **handle,
61 const struct btproto *proto, void *upper)
63 struct l2cap_channel *chan;
65 KKASSERT(handle != NULL);
66 KKASSERT(proto != NULL);
67 KKASSERT(upper != NULL);
69 chan = kmalloc(sizeof(*chan), M_BLUETOOTH, M_NOWAIT | M_ZERO);
73 chan->lc_proto = proto;
74 chan->lc_upper = upper;
76 chan->lc_state = L2CAP_CLOSED;
78 chan->lc_lcid = L2CAP_NULL_CID;
79 chan->lc_rcid = L2CAP_NULL_CID;
81 chan->lc_laddr.bt_len = sizeof(struct sockaddr_bt);
82 chan->lc_laddr.bt_family = AF_BLUETOOTH;
83 chan->lc_laddr.bt_psm = L2CAP_PSM_ANY;
85 chan->lc_raddr.bt_len = sizeof(struct sockaddr_bt);
86 chan->lc_raddr.bt_family = AF_BLUETOOTH;
87 chan->lc_raddr.bt_psm = L2CAP_PSM_ANY;
89 chan->lc_imtu = L2CAP_MTU_DEFAULT;
90 chan->lc_omtu = L2CAP_MTU_DEFAULT;
91 chan->lc_flush = L2CAP_FLUSH_TIMO_DEFAULT;
93 memcpy(&chan->lc_iqos, &l2cap_default_qos, sizeof(l2cap_qos_t));
94 memcpy(&chan->lc_oqos, &l2cap_default_qos, sizeof(l2cap_qos_t));
101 * l2cap_bind(l2cap_channel, sockaddr)
103 * set local address of channel
106 l2cap_bind(struct l2cap_channel *chan, struct sockaddr_bt *addr)
109 memcpy(&chan->lc_laddr, addr, sizeof(struct sockaddr_bt));
114 * l2cap_sockaddr(l2cap_channel, sockaddr)
116 * get local address of channel
119 l2cap_sockaddr(struct l2cap_channel *chan, struct sockaddr_bt *addr)
121 memcpy(addr, &chan->lc_laddr, sizeof(struct sockaddr_bt));
126 * l2cap_connect(l2cap_channel, sockaddr)
128 * Initiate a connection to destination. This corresponds to
129 * "Open Channel Request" in the L2CAP specification and will
130 * result in one of the following:
132 * proto->connected(upper)
133 * proto->disconnected(upper, error)
136 * proto->connecting(upper)
139 l2cap_connect(struct l2cap_channel *chan, struct sockaddr_bt *dest)
141 struct hci_unit *unit;
144 memcpy(&chan->lc_raddr, dest, sizeof(struct sockaddr_bt));
146 if (L2CAP_PSM_INVALID(chan->lc_raddr.bt_psm))
149 if (bdaddr_any(&chan->lc_raddr.bt_bdaddr))
152 /* set local address if it needs setting */
153 if (bdaddr_any(&chan->lc_laddr.bt_bdaddr)) {
154 err = hci_route_lookup(&chan->lc_laddr.bt_bdaddr,
155 &chan->lc_raddr.bt_bdaddr);
160 unit = hci_unit_lookup(&chan->lc_laddr.bt_bdaddr);
164 /* attach to active list */
165 err = l2cap_cid_alloc(chan);
169 /* open link to remote device */
170 chan->lc_link = hci_acl_open(unit, &chan->lc_raddr.bt_bdaddr);
171 if (chan->lc_link == NULL)
174 /* set the link mode */
175 err = l2cap_setmode(chan);
176 if (err == EINPROGRESS) {
177 chan->lc_state = L2CAP_WAIT_SEND_CONNECT_REQ;
178 (*chan->lc_proto->connecting)(chan->lc_upper);
185 * We can queue a connect request now even though the link may
186 * not yet be open; Our mode setting is assured, and the queue
187 * will be started automatically at the right time.
189 chan->lc_state = L2CAP_WAIT_RECV_CONNECT_RSP;
190 err = l2cap_send_connect_req(chan);
197 chan->lc_state = L2CAP_CLOSED;
198 hci_acl_close(chan->lc_link, err);
199 chan->lc_link = NULL;
204 * l2cap_peeraddr(l2cap_channel, sockaddr)
206 * get remote address of channel
209 l2cap_peeraddr(struct l2cap_channel *chan, struct sockaddr_bt *addr)
211 memcpy(addr, &chan->lc_raddr, sizeof(struct sockaddr_bt));
216 * l2cap_disconnect(l2cap_channel, linger)
218 * Initiate L2CAP disconnection. This corresponds to
219 * "Close Channel Request" in the L2CAP specification
220 * and will result in a call to
222 * proto->disconnected(upper, error)
224 * when the disconnection is complete. If linger is set,
225 * the call will not be made until data has flushed from
229 l2cap_disconnect(struct l2cap_channel *chan, int linger)
233 if (chan->lc_state == L2CAP_CLOSED
234 || chan->lc_state == L2CAP_WAIT_DISCONNECT)
237 chan->lc_flags |= L2CAP_SHUTDOWN;
240 * no need to do anything unless the queue is empty or
241 * we are not lingering..
243 if ((IF_QEMPTY(&chan->lc_txq) && chan->lc_pending == 0)
245 chan->lc_state = L2CAP_WAIT_DISCONNECT;
246 err = l2cap_send_disconnect_req(chan);
248 l2cap_close(chan, err);
254 * l2cap_detach(handle)
256 * Detach l2cap channel from handle & close it down
259 l2cap_detach(struct l2cap_channel **handle)
261 struct l2cap_channel *chan;
266 if (chan->lc_state != L2CAP_CLOSED)
267 l2cap_close(chan, 0);
269 if (chan->lc_lcid != L2CAP_NULL_CID) {
270 LIST_REMOVE(chan, lc_ncid);
271 chan->lc_lcid = L2CAP_NULL_CID;
274 IF_DRAIN(&chan->lc_txq);
277 * Could implement some kind of delayed expunge to make sure that the
278 * CID is really dead before it becomes available for reuse?
281 kfree(chan, M_BLUETOOTH);
286 * l2cap_listen(l2cap_channel)
288 * Use this channel as a listening post (until detached). This will
289 * result in calls to:
291 * proto->newconn(upper, laddr, raddr)
293 * for incoming connections matching the psm and local address of the
294 * channel (NULL psm/address are permitted and match any protocol/device).
296 * The upper layer should create and return a new channel.
298 * You cannot use this channel for anything else subsequent to this call
301 l2cap_listen(struct l2cap_channel *chan)
303 struct l2cap_channel *used, *prev = NULL;
305 if (chan->lc_lcid != L2CAP_NULL_CID)
308 if (chan->lc_laddr.bt_psm != L2CAP_PSM_ANY
309 && L2CAP_PSM_INVALID(chan->lc_laddr.bt_psm))
310 return EADDRNOTAVAIL;
313 * This CID is irrelevant, as the channel is not stored on the active
314 * list and the socket code does not allow operations on listening
315 * sockets, but we set it so the detach code knows to LIST_REMOVE the
318 chan->lc_lcid = L2CAP_SIGNAL_CID;
321 * The list of listening channels is stored in an order such that new
322 * listeners dont usurp current listeners, but that specific listening
323 * takes precedence over promiscuous, and the connect request code can
324 * easily use the first matching entry.
326 LIST_FOREACH(used, &l2cap_listen_list, lc_ncid) {
327 if (used->lc_laddr.bt_psm < chan->lc_laddr.bt_psm)
330 if (used->lc_laddr.bt_psm == chan->lc_laddr.bt_psm
331 && bdaddr_any(&used->lc_laddr.bt_bdaddr)
332 && !bdaddr_any(&chan->lc_laddr.bt_bdaddr))
339 LIST_INSERT_HEAD(&l2cap_listen_list, chan, lc_ncid);
341 LIST_INSERT_AFTER(prev, chan, lc_ncid);
347 * l2cap_send(l2cap_channel, mbuf)
349 * Output SDU on channel described by channel. This corresponds
350 * to "Send Data Request" in the L2CAP specification. The upper
351 * layer will be notified when SDU's have completed sending by a
354 * proto->complete(upper, n)
358 * Note: I'm not sure how this will work out, but I think that
359 * if outgoing Retransmission Mode or Flow Control Mode is
360 * negotiated then this call will not be made until the SDU has
361 * been acknowleged by the peer L2CAP entity. For 'Best Effort'
362 * it will be made when the packet has cleared the controller
365 * We only support Basic mode so far, so encapsulate with a
366 * B-Frame header and start sending if we are not already
369 l2cap_send(struct l2cap_channel *chan, struct mbuf *m)
374 if (chan->lc_state == L2CAP_CLOSED) {
379 plen = m->m_pkthdr.len;
381 DPRINTFN(5, "send %d bytes on CID #%d (pending = %d)\n",
382 plen, chan->lc_lcid, chan->lc_pending);
384 /* Encapsulate with B-Frame */
385 M_PREPEND(m, sizeof(l2cap_hdr_t), M_NOWAIT);
389 hdr = mtod(m, l2cap_hdr_t *);
390 hdr->length = htole16(plen);
391 hdr->dcid = htole16(chan->lc_rcid);
393 /* Queue it on our list */
394 IF_ENQUEUE(&chan->lc_txq, m);
396 /* If we are not sending, then start doing so */
397 if (chan->lc_pending == 0)
398 return l2cap_start(chan);
404 * l2cap_setopt(l2cap_channel, opt, addr)
406 * Apply configuration options to channel. This corresponds to
407 * "Configure Channel Request" in the L2CAP specification.
409 * for SO_L2CAP_LM, the settings will take effect when the
410 * channel is established. If the channel is already open,
412 * proto->linkmode(upper, new)
414 * will be made when the change is complete.
417 l2cap_setopt(struct l2cap_channel *chan, int opt, void *addr)
423 case SO_L2CAP_IMTU: /* set Incoming MTU */
424 mtu = *(uint16_t *)addr;
425 if (mtu < L2CAP_MTU_MINIMUM)
427 else if (chan->lc_state == L2CAP_CLOSED)
434 case SO_L2CAP_LM: /* set link mode */
436 mode &= (L2CAP_LM_SECURE | L2CAP_LM_ENCRYPT | L2CAP_LM_AUTH);
438 if (mode & L2CAP_LM_SECURE)
439 mode |= L2CAP_LM_ENCRYPT;
441 if (mode & L2CAP_LM_ENCRYPT)
442 mode |= L2CAP_LM_AUTH;
444 chan->lc_mode = mode;
446 if (chan->lc_state == L2CAP_OPEN)
447 err = l2cap_setmode(chan);
451 case SO_L2CAP_OQOS: /* set Outgoing QoS flow spec */
452 case SO_L2CAP_FLUSH: /* set Outgoing Flush Timeout */
463 * Used in l2cap_socket for set options, coming from socket.
466 l2cap_setopt2(struct l2cap_channel *chan, int opt, struct socket *so,
467 struct sockopt *sopt)
473 case SO_L2CAP_IMTU: /* set Incoming MTU */
474 err = soopt_to_kbuf(sopt, &mtu, sizeof(uint16_t),
479 if (mtu < L2CAP_MTU_MINIMUM)
481 else if (chan->lc_state == L2CAP_CLOSED)
488 case SO_L2CAP_LM: /* set link mode */
489 err = soopt_to_kbuf(sopt, &mode, sizeof(int), sizeof(int));
493 mode &= (L2CAP_LM_SECURE | L2CAP_LM_ENCRYPT | L2CAP_LM_AUTH);
495 if (mode & L2CAP_LM_SECURE)
496 mode |= L2CAP_LM_ENCRYPT;
497 if (mode & L2CAP_LM_ENCRYPT)
498 mode |= L2CAP_LM_AUTH;
499 chan->lc_mode = mode;
501 if (chan->lc_state == L2CAP_OPEN)
502 err = l2cap_setmode(chan);
506 case SO_L2CAP_OQOS: /* set Outgoing QoS flow spec */
507 case SO_L2CAP_FLUSH: /* set Outgoing Flush Timeout */
516 * l2cap_getopt(l2cap_channel, opt, addr)
518 * Return configuration parameters.
521 l2cap_getopt(struct l2cap_channel *chan, int opt, void *addr)
525 case SO_L2CAP_IMTU: /* get Incoming MTU */
526 *(uint16_t *)addr = chan->lc_imtu;
527 return sizeof(uint16_t);
529 case SO_L2CAP_OMTU: /* get Outgoing MTU */
530 *(uint16_t *)addr = chan->lc_omtu;
531 return sizeof(uint16_t);
533 case SO_L2CAP_IQOS: /* get Incoming QoS flow spec */
534 memcpy(addr, &chan->lc_iqos, sizeof(l2cap_qos_t));
535 return sizeof(l2cap_qos_t);
537 case SO_L2CAP_OQOS: /* get Outgoing QoS flow spec */
538 memcpy(addr, &chan->lc_oqos, sizeof(l2cap_qos_t));
539 return sizeof(l2cap_qos_t);
541 case SO_L2CAP_FLUSH: /* get Flush Timeout */
542 *(uint16_t *)addr = chan->lc_flush;
543 return sizeof(uint16_t);
545 case SO_L2CAP_LM: /* get link mode */
546 *(int *)addr = chan->lc_mode;