l2cap_upper.c revision 1.2 1 /* $NetBSD: l2cap_upper.c,v 1.2 2007/03/05 19:11:54 plunky 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.2 2007/03/05 19:11:54 plunky 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(handle, btproto, upper)
56 *
57 * attach new l2cap_channel to handle, populate
58 * with with reasonable defaults
59 */
60 int
61 l2cap_attach(struct l2cap_channel **handle,
62 const struct btproto *proto, void *upper)
63 {
64 struct l2cap_channel *chan;
65
66 KASSERT(handle);
67 KASSERT(proto);
68 KASSERT(upper);
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(l2cap_channel, sockaddr)
106 *
107 * set local address of channel
108 */
109 int
110 l2cap_bind(struct l2cap_channel *chan, struct sockaddr_bt *addr)
111 {
112
113 memcpy(&chan->lc_laddr, addr, sizeof(struct sockaddr_bt));
114 return 0;
115 }
116
117 /*
118 * l2cap_sockaddr(l2cap_channel, sockaddr)
119 *
120 * get local address of channel
121 */
122 int
123 l2cap_sockaddr(struct l2cap_channel *chan, struct sockaddr_bt *addr)
124 {
125
126 memcpy(addr, &chan->lc_laddr, sizeof(struct sockaddr_bt));
127 return 0;
128 }
129
130 /*
131 * l2cap_connect(l2cap_channel, sockaddr)
132 *
133 * Initiate a connection to destination. This corresponds to
134 * "Open Channel Request" in the L2CAP specification and will
135 * result in one of the following:
136 *
137 * proto->connected(upper)
138 * proto->disconnected(upper, error)
139 *
140 * and, optionally
141 * proto->connecting(upper)
142 */
143 int
144 l2cap_connect(struct l2cap_channel *chan, struct sockaddr_bt *dest)
145 {
146 struct hci_unit *unit;
147 int err;
148
149 memcpy(&chan->lc_raddr, dest, sizeof(struct sockaddr_bt));
150
151 if (L2CAP_PSM_INVALID(chan->lc_raddr.bt_psm))
152 return EINVAL;
153
154 if (bdaddr_any(&chan->lc_raddr.bt_bdaddr))
155 return EDESTADDRREQ;
156
157 /* set local address if it needs setting */
158 if (bdaddr_any(&chan->lc_laddr.bt_bdaddr)) {
159 err = hci_route_lookup(&chan->lc_laddr.bt_bdaddr,
160 &chan->lc_raddr.bt_bdaddr);
161 if (err)
162 return err;
163 }
164
165 unit = hci_unit_lookup(&chan->lc_laddr.bt_bdaddr);
166 if (unit == NULL)
167 return EHOSTUNREACH;
168
169 /* attach to active list */
170 err = l2cap_cid_alloc(chan);
171 if (err)
172 return err;
173
174 /* open link to remote device */
175 chan->lc_link = hci_acl_open(unit, &chan->lc_raddr.bt_bdaddr);
176 if (chan->lc_link == NULL)
177 return EHOSTUNREACH;
178
179 /*
180 * We queue a connect request right away even though the link
181 * may not yet be open; the queue will be started automatically
182 * at the right time.
183 */
184 chan->lc_state = L2CAP_WAIT_CONNECT_RSP;
185 err = l2cap_send_connect_req(chan);
186 if (err) {
187 chan->lc_state = L2CAP_CLOSED;
188 hci_acl_close(chan->lc_link, err);
189 chan->lc_link = NULL;
190 return err;
191 }
192
193 return 0;
194 }
195
196 /*
197 * l2cap_peeraddr(l2cap_channel, sockaddr)
198 *
199 * get remote address of channel
200 */
201 int
202 l2cap_peeraddr(struct l2cap_channel *chan, struct sockaddr_bt *addr)
203 {
204
205 memcpy(addr, &chan->lc_raddr, sizeof(struct sockaddr_bt));
206 return 0;
207 }
208
209 /*
210 * l2cap_disconnect(l2cap_channel, linger)
211 *
212 * Initiate L2CAP disconnection. This corresponds to
213 * "Close Channel Request" in the L2CAP specification
214 * and will result in a call to
215 *
216 * proto->disconnected(upper, error)
217 *
218 * when the disconnection is complete. If linger is set,
219 * the call will not be made until data has flushed from
220 * the queue.
221 */
222 int
223 l2cap_disconnect(struct l2cap_channel *chan, int linger)
224 {
225 int err = 0;
226
227 if (chan->lc_state & (L2CAP_CLOSED | L2CAP_WAIT_DISCONNECT))
228 return EINVAL;
229
230 chan->lc_flags |= L2CAP_SHUTDOWN;
231
232 /*
233 * no need to do anything unless the queue is empty or
234 * we are not lingering..
235 */
236 if ((MBUFQ_FIRST(&chan->lc_txq) == NULL && chan->lc_pending == 0)
237 || linger == 0) {
238 chan->lc_state = L2CAP_WAIT_DISCONNECT;
239 err = l2cap_send_disconnect_req(chan);
240 if (err)
241 l2cap_close(chan, err);
242 }
243 return err;
244 }
245
246 /*
247 * l2cap_detach(handle)
248 *
249 * Detach l2cap channel from handle & close it down
250 */
251 int
252 l2cap_detach(struct l2cap_channel **handle)
253 {
254 struct l2cap_channel *chan;
255
256 chan = *handle;
257 *handle = NULL;
258
259 if (chan->lc_state != L2CAP_CLOSED)
260 l2cap_close(chan, 0);
261
262 if (chan->lc_lcid != L2CAP_NULL_CID) {
263 LIST_REMOVE(chan, lc_ncid);
264 chan->lc_lcid = L2CAP_NULL_CID;
265 }
266
267 MBUFQ_DRAIN(&chan->lc_txq);
268
269 /*
270 * Could implement some kind of delayed expunge to make sure that the
271 * CID is really dead before it becomes available for reuse?
272 */
273
274 free(chan, M_BLUETOOTH);
275 return 0;
276 }
277
278 /*
279 * l2cap_listen(l2cap_channel)
280 *
281 * Use this channel as a listening post (until detached). This will
282 * result in calls to:
283 *
284 * proto->newconn(upper, laddr, raddr)
285 *
286 * for incoming connections matching the psm and local address of the
287 * channel (NULL psm/address are permitted and match any protocol/device).
288 *
289 * The upper layer should create and return a new channel.
290 *
291 * You cannot use this channel for anything else subsequent to this call
292 */
293 int
294 l2cap_listen(struct l2cap_channel *chan)
295 {
296 struct l2cap_channel *used, *prev = NULL;
297
298 if (chan->lc_lcid != L2CAP_NULL_CID)
299 return EINVAL;
300
301 if (chan->lc_laddr.bt_psm != L2CAP_PSM_ANY
302 && L2CAP_PSM_INVALID(chan->lc_laddr.bt_psm))
303 return EADDRNOTAVAIL;
304
305 /*
306 * This CID is irrelevant, as the channel is not stored on the active
307 * list and the socket code does not allow operations on listening
308 * sockets, but we set it so the detach code knows to LIST_REMOVE the
309 * channel.
310 */
311 chan->lc_lcid = L2CAP_SIGNAL_CID;
312
313 /*
314 * The list of listening channels is stored in an order such that new
315 * listeners dont usurp current listeners, but that specific listening
316 * takes precedence over promiscuous, and the connect request code can
317 * easily use the first matching entry.
318 */
319 LIST_FOREACH(used, &l2cap_listen_list, lc_ncid) {
320 if (used->lc_laddr.bt_psm < chan->lc_laddr.bt_psm)
321 break;
322
323 if (used->lc_laddr.bt_psm == chan->lc_laddr.bt_psm
324 && bdaddr_any(&used->lc_laddr.bt_bdaddr)
325 && !bdaddr_any(&chan->lc_laddr.bt_bdaddr))
326 break;
327
328 prev = used;
329 }
330
331 if (prev == NULL)
332 LIST_INSERT_HEAD(&l2cap_listen_list, chan, lc_ncid);
333 else
334 LIST_INSERT_AFTER(prev, chan, lc_ncid);
335
336 return 0;
337 }
338
339 /*
340 * l2cap_send(l2cap_channel, mbuf)
341 *
342 * Output SDU on channel described by channel. This corresponds
343 * to "Send Data Request" in the L2CAP specification. The upper
344 * layer will be notified when SDU's have completed sending by a
345 * call to:
346 *
347 * proto->complete(upper, n)
348 *
349 * (currently n == 1)
350 *
351 * Note: I'm not sure how this will work out, but I think that
352 * if outgoing Retransmission Mode or Flow Control Mode is
353 * negotiated then this call will not be made until the SDU has
354 * been acknowleged by the peer L2CAP entity. For 'Best Effort'
355 * it will be made when the packet has cleared the controller
356 * buffers.
357 *
358 * We only support Basic mode so far, so encapsulate with a
359 * B-Frame header and start sending if we are not already
360 */
361 int
362 l2cap_send(struct l2cap_channel *chan, struct mbuf *m)
363 {
364 l2cap_hdr_t *hdr;
365 int plen;
366
367 if (chan->lc_state == L2CAP_CLOSED) {
368 m_freem(m);
369 return ENOTCONN;
370 }
371
372 plen = m->m_pkthdr.len;
373
374 DPRINTFN(5, "send %d bytes on CID #%d (pending = %d)\n",
375 plen, chan->lc_lcid, chan->lc_pending);
376
377 /* Encapsulate with B-Frame */
378 M_PREPEND(m, sizeof(l2cap_hdr_t), M_DONTWAIT);
379 if (m == NULL)
380 return ENOMEM;
381
382 hdr = mtod(m, l2cap_hdr_t *);
383 hdr->length = htole16(plen);
384 hdr->dcid = htole16(chan->lc_rcid);
385
386 /* Queue it on our list */
387 MBUFQ_ENQUEUE(&chan->lc_txq, m);
388
389 /* If we are not sending, then start doing so */
390 if (chan->lc_pending == 0)
391 return l2cap_start(chan);
392
393 return 0;
394 }
395
396 /*
397 * l2cap_setopt(channel, opt, addr)
398 *
399 * Apply configuration options to channel. This corresponds to
400 * "Configure Channel Request" in the L2CAP specification.
401 */
402 int
403 l2cap_setopt(struct l2cap_channel *chan, int opt, void *addr)
404 {
405 int err = 0;
406 uint16_t tmp;
407
408 /*
409 * currently we dont allow changing any options when channel
410 * is other than closed. We could allow this (not sure why?)
411 * but would have to instigate a configure request.
412 */
413 if (chan->lc_state != L2CAP_CLOSED)
414 return EBUSY;
415
416 switch (opt) {
417 case SO_L2CAP_IMTU: /* set Incoming MTU */
418 tmp = *(uint16_t *)addr;
419 if (tmp < L2CAP_MTU_MINIMUM) {
420 err = EINVAL;
421 break;
422 }
423
424 chan->lc_imtu = tmp;
425 break;
426
427 case SO_L2CAP_OQOS: /* set Outgoing QoS flow spec */
428 // XXX
429 // memcpy(&chan->lc_oqos, addr, sizeof(l2cap_qos_t));
430 //break;
431
432 case SO_L2CAP_FLUSH: /* set Outgoing Flush Timeout */
433 // XXX
434 // chan->lc_flush = *(uint16_t *)addr;
435 //break;
436
437 default:
438 err = ENOPROTOOPT;
439 break;
440 }
441
442 return err;
443 }
444
445 int
446 l2cap_getopt(struct l2cap_channel *chan, int opt, void *addr)
447 {
448
449 switch (opt) {
450 case SO_L2CAP_IMTU: /* get Incoming MTU */
451 *(uint16_t *)addr = chan->lc_imtu;
452 return sizeof(uint16_t);
453
454 case SO_L2CAP_OMTU: /* get Outgoing MTU */
455 *(uint16_t *)addr = chan->lc_omtu;
456 return sizeof(uint16_t);
457
458 case SO_L2CAP_IQOS: /* get Incoming QoS flow spec */
459 memcpy(addr, &chan->lc_iqos, sizeof(l2cap_qos_t));
460 return sizeof(l2cap_qos_t);
461
462 case SO_L2CAP_OQOS: /* get Outgoing QoS flow spec */
463 memcpy(addr, &chan->lc_oqos, sizeof(l2cap_qos_t));
464 return sizeof(l2cap_qos_t);
465
466 case SO_L2CAP_FLUSH: /* get Flush Timeout */
467 *(uint16_t *)addr = chan->lc_flush;
468 return sizeof(uint16_t);
469
470 default:
471 break;
472 }
473
474 return 0;
475 }
476