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 */
60int
61l2cap_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 */
109int
110l2cap_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 */
125int
126l2cap_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 */
146int
147l2cap_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
204fail:
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 */
216int
217l2cap_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 */
237int
238l2cap_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 */
267void
268l2cap_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 */
310int
311l2cap_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 */
396int
397l2cap_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 */
444int
445l2cap_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 */
500int
501l2cap_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