1 /* $NetBSD: l2cap_upper.c,v 1.10 2009/09/25 19:44:57 plunky Exp $ */
4 * Copyright (c) 2005 Iain Hibbert.
5 * Copyright (c) 2006 Itronix Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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.
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.10 2009/09/25 19:44:57 plunky Exp $");
36 #include <sys/param.h>
37 #include <sys/kernel.h>
40 #include <sys/queue.h>
41 #include <sys/socket.h>
42 #include <sys/socketvar.h>
43 #include <sys/systm.h>
45 #include <netbt/bluetooth.h>
46 #include <netbt/hci.h>
47 #include <netbt/l2cap.h>
49 /*******************************************************************************
51 * L2CAP Channel - Upper Protocol API
55 * l2cap_attach(handle, btproto, upper)
57 * attach new l2cap_channel to handle, populate
58 * with reasonable defaults
61 l2cap_attach(struct l2cap_channel
**handle
,
62 const struct btproto
*proto
, void *upper
)
64 struct l2cap_channel
*chan
;
66 KASSERT(handle
!= NULL
);
67 KASSERT(proto
!= NULL
);
68 KASSERT(upper
!= NULL
);
70 chan
= malloc(sizeof(struct l2cap_channel
), M_BLUETOOTH
,
75 chan
->lc_proto
= proto
;
76 chan
->lc_upper
= upper
;
78 chan
->lc_state
= L2CAP_CLOSED
;
80 chan
->lc_lcid
= L2CAP_NULL_CID
;
81 chan
->lc_rcid
= L2CAP_NULL_CID
;
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
;
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
;
91 chan
->lc_imtu
= L2CAP_MTU_DEFAULT
;
92 chan
->lc_omtu
= L2CAP_MTU_DEFAULT
;
93 chan
->lc_flush
= L2CAP_FLUSH_TIMO_DEFAULT
;
95 memcpy(&chan
->lc_iqos
, &l2cap_default_qos
, sizeof(l2cap_qos_t
));
96 memcpy(&chan
->lc_oqos
, &l2cap_default_qos
, sizeof(l2cap_qos_t
));
98 MBUFQ_INIT(&chan
->lc_txq
);
105 * l2cap_bind(l2cap_channel, sockaddr)
107 * set local address of channel
110 l2cap_bind(struct l2cap_channel
*chan
, struct sockaddr_bt
*addr
)
113 if (chan
->lc_lcid
!= L2CAP_NULL_CID
)
116 memcpy(&chan
->lc_laddr
, addr
, sizeof(struct sockaddr_bt
));
121 * l2cap_sockaddr(l2cap_channel, sockaddr)
123 * get local address of channel
126 l2cap_sockaddr(struct l2cap_channel
*chan
, struct sockaddr_bt
*addr
)
129 memcpy(addr
, &chan
->lc_laddr
, sizeof(struct sockaddr_bt
));
134 * l2cap_connect(l2cap_channel, sockaddr)
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:
140 * proto->connected(upper)
141 * proto->disconnected(upper, error)
144 * proto->connecting(upper)
147 l2cap_connect(struct l2cap_channel
*chan
, struct sockaddr_bt
*dest
)
149 struct hci_unit
*unit
;
152 memcpy(&chan
->lc_raddr
, dest
, sizeof(struct sockaddr_bt
));
154 if (L2CAP_PSM_INVALID(chan
->lc_raddr
.bt_psm
))
157 if (bdaddr_any(&chan
->lc_raddr
.bt_bdaddr
))
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
);
168 unit
= hci_unit_lookup(&chan
->lc_laddr
.bt_bdaddr
);
172 /* attach to active list */
173 err
= l2cap_cid_alloc(chan
);
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
)
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
);
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.
197 chan
->lc_state
= L2CAP_WAIT_RECV_CONNECT_RSP
;
198 err
= l2cap_send_connect_req(chan
);
205 chan
->lc_state
= L2CAP_CLOSED
;
206 hci_acl_close(chan
->lc_link
, err
);
207 chan
->lc_link
= NULL
;
212 * l2cap_peeraddr(l2cap_channel, sockaddr)
214 * get remote address of channel
217 l2cap_peeraddr(struct l2cap_channel
*chan
, struct sockaddr_bt
*addr
)
220 memcpy(addr
, &chan
->lc_raddr
, sizeof(struct sockaddr_bt
));
225 * l2cap_disconnect(l2cap_channel, linger)
227 * Initiate L2CAP disconnection. This corresponds to
228 * "Close Channel Request" in the L2CAP specification
229 * and will result in a call to
231 * proto->disconnected(upper, error)
233 * when the disconnection is complete. If linger is set,
234 * the call will not be made until data has flushed from
238 l2cap_disconnect(struct l2cap_channel
*chan
, int linger
)
242 if (chan
->lc_state
== L2CAP_CLOSED
243 || chan
->lc_state
== L2CAP_WAIT_DISCONNECT
)
246 chan
->lc_flags
|= L2CAP_SHUTDOWN
;
249 * no need to do anything unless the queue is empty or
250 * we are not lingering..
252 if ((MBUFQ_FIRST(&chan
->lc_txq
) == NULL
&& chan
->lc_pending
== 0)
254 chan
->lc_state
= L2CAP_WAIT_DISCONNECT
;
255 err
= l2cap_send_disconnect_req(chan
);
257 l2cap_close(chan
, err
);
263 * l2cap_detach(handle)
265 * Detach l2cap channel from handle & close it down
268 l2cap_detach(struct l2cap_channel
**handle
)
270 struct l2cap_channel
*chan
;
275 if (chan
->lc_state
!= L2CAP_CLOSED
)
276 l2cap_close(chan
, 0);
278 if (chan
->lc_lcid
!= L2CAP_NULL_CID
) {
279 LIST_REMOVE(chan
, lc_ncid
);
280 chan
->lc_lcid
= L2CAP_NULL_CID
;
283 MBUFQ_DRAIN(&chan
->lc_txq
);
286 * Could implement some kind of delayed expunge to make sure that the
287 * CID is really dead before it becomes available for reuse?
290 free(chan
, M_BLUETOOTH
);
295 * l2cap_listen(l2cap_channel)
297 * Use this channel as a listening post (until detached). This will
298 * result in calls to:
300 * proto->newconn(upper, laddr, raddr)
302 * for incoming connections matching the psm and local address of
303 * the channel. NULL address is permitted and matches any device.
304 * If L2CAP_PSM_ANY is bound the next higher unused value from the
305 * dynamic range (above 0x1001) will be selected.
307 * The upper layer should create and return a new channel.
309 * You cannot use this channel for anything else subsequent to this call
312 l2cap_listen(struct l2cap_channel
*chan
)
314 struct l2cap_channel
*used
, *prev
= NULL
;
317 if (chan
->lc_lcid
!= L2CAP_NULL_CID
)
321 * This is simplistic but its not really worth spending a
322 * lot of time looking for an unused PSM..
324 if (chan
->lc_laddr
.bt_psm
== L2CAP_PSM_ANY
) {
326 used
= LIST_FIRST(&l2cap_listen_list
);
328 if (used
!= NULL
&& used
->lc_laddr
.bt_psm
>= psm
) {
329 psm
= used
->lc_laddr
.bt_psm
+ 0x0002;
330 if ((psm
& 0x0100) != 0)
333 if (psm
> UINT16_MAX
)
334 return EADDRNOTAVAIL
;
337 chan
->lc_laddr
.bt_psm
= psm
;
338 } else if (L2CAP_PSM_INVALID(chan
->lc_laddr
.bt_psm
))
342 * This CID is irrelevant, as the channel is not stored on the active
343 * list and the socket code does not allow operations on listening
344 * sockets, but we set it so the detach code knows to LIST_REMOVE the
347 chan
->lc_lcid
= L2CAP_SIGNAL_CID
;
350 * The list of listening channels is stored in an order such that new
351 * listeners dont usurp current listeners, but that specific listening
352 * takes precedence over promiscuous, and the connect request code can
353 * easily use the first matching entry.
355 LIST_FOREACH(used
, &l2cap_listen_list
, lc_ncid
) {
356 if (used
->lc_laddr
.bt_psm
< chan
->lc_laddr
.bt_psm
)
359 if (used
->lc_laddr
.bt_psm
== chan
->lc_laddr
.bt_psm
360 && bdaddr_any(&used
->lc_laddr
.bt_bdaddr
)
361 && !bdaddr_any(&chan
->lc_laddr
.bt_bdaddr
))
368 LIST_INSERT_HEAD(&l2cap_listen_list
, chan
, lc_ncid
);
370 LIST_INSERT_AFTER(prev
, chan
, lc_ncid
);
376 * l2cap_send(l2cap_channel, mbuf)
378 * Output SDU on channel described by channel. This corresponds
379 * to "Send Data Request" in the L2CAP specification. The upper
380 * layer will be notified when SDU's have completed sending by a
383 * proto->complete(upper, n)
387 * Note: I'm not sure how this will work out, but I think that
388 * if outgoing Retransmission Mode or Flow Control Mode is
389 * negotiated then this call will not be made until the SDU has
390 * been acknowleged by the peer L2CAP entity. For 'Best Effort'
391 * it will be made when the packet has cleared the controller
394 * We only support Basic mode so far, so encapsulate with a
395 * B-Frame header and start sending if we are not already
398 l2cap_send(struct l2cap_channel
*chan
, struct mbuf
*m
)
403 if (chan
->lc_state
== L2CAP_CLOSED
) {
408 plen
= m
->m_pkthdr
.len
;
410 DPRINTFN(5, "send %d bytes on CID #%d (pending = %d)\n",
411 plen
, chan
->lc_lcid
, chan
->lc_pending
);
413 /* Encapsulate with B-Frame */
414 M_PREPEND(m
, sizeof(l2cap_hdr_t
), M_DONTWAIT
);
418 hdr
= mtod(m
, l2cap_hdr_t
*);
419 hdr
->length
= htole16(plen
);
420 hdr
->dcid
= htole16(chan
->lc_rcid
);
422 /* Queue it on our list */
423 MBUFQ_ENQUEUE(&chan
->lc_txq
, m
);
425 /* If we are not sending, then start doing so */
426 if (chan
->lc_pending
== 0)
427 return l2cap_start(chan
);
433 * l2cap_setopt(l2cap_channel, sopt)
435 * Apply configuration options to channel. This corresponds to
436 * "Configure Channel Request" in the L2CAP specification.
438 * for SO_L2CAP_LM, the settings will take effect when the
439 * channel is established. If the channel is already open,
441 * proto->linkmode(upper, new)
443 * will be made when the change is complete.
446 l2cap_setopt(struct l2cap_channel
*chan
, const struct sockopt
*sopt
)
451 switch (sopt
->sopt_name
) {
452 case SO_L2CAP_IMTU
: /* set Incoming MTU */
453 err
= sockopt_get(sopt
, &mtu
, sizeof(mtu
));
457 if (mtu
< L2CAP_MTU_MINIMUM
)
459 else if (chan
->lc_state
== L2CAP_CLOSED
)
466 case SO_L2CAP_LM
: /* set link mode */
467 err
= sockopt_getint(sopt
, &mode
);
471 mode
&= (L2CAP_LM_SECURE
| L2CAP_LM_ENCRYPT
| L2CAP_LM_AUTH
);
473 if (mode
& L2CAP_LM_SECURE
)
474 mode
|= L2CAP_LM_ENCRYPT
;
476 if (mode
& L2CAP_LM_ENCRYPT
)
477 mode
|= L2CAP_LM_AUTH
;
479 chan
->lc_mode
= mode
;
481 if (chan
->lc_state
== L2CAP_OPEN
)
482 err
= l2cap_setmode(chan
);
486 case SO_L2CAP_OQOS
: /* set Outgoing QoS flow spec */
487 case SO_L2CAP_FLUSH
: /* set Outgoing Flush Timeout */
497 * l2cap_getopt(l2cap_channel, sopt)
499 * Return configuration parameters.
502 l2cap_getopt(struct l2cap_channel
*chan
, struct sockopt
*sopt
)
505 switch (sopt
->sopt_name
) {
506 case SO_L2CAP_IMTU
: /* get Incoming MTU */
507 return sockopt_set(sopt
, &chan
->lc_imtu
, sizeof(uint16_t));
509 case SO_L2CAP_OMTU
: /* get Outgoing MTU */
510 return sockopt_set(sopt
, &chan
->lc_omtu
, sizeof(uint16_t));
512 case SO_L2CAP_IQOS
: /* get Incoming QoS flow spec */
513 return sockopt_set(sopt
, &chan
->lc_iqos
, sizeof(l2cap_qos_t
));
515 case SO_L2CAP_OQOS
: /* get Outgoing QoS flow spec */
516 return sockopt_set(sopt
, &chan
->lc_oqos
, sizeof(l2cap_qos_t
));
518 case SO_L2CAP_FLUSH
: /* get Flush Timeout */
519 return sockopt_set(sopt
, &chan
->lc_flush
, sizeof(uint16_t));
521 case SO_L2CAP_LM
: /* get link mode */
522 return sockopt_setint(sopt
, chan
->lc_mode
);