Kernel part of bluetooth stack ported by Dmitry Komissaroff. Very much work
[dragonfly.git] / sys / netbt / rfcomm_upper.c
1 /* $OpenBSD: rfcomm_upper.c,v 1.3 2007/10/01 16:39:30 krw Exp $ */
2 /* $NetBSD: rfcomm_upper.c,v 1.6 2007/04/21 06:15:23 plunky Exp $ */
3 /* $DragonFly: src/sys/netbt/rfcomm_upper.c,v 1.1 2007/12/30 20:02:56 hasso Exp $ */
4
5 /*-
6  * Copyright (c) 2006 Itronix Inc.
7  * All rights reserved.
8  *
9  * Written by Iain Hibbert for Itronix Inc.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. The name of Itronix Inc. may not be used to endorse
20  *    or promote products derived from this software without specific
21  *    prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
27  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 #include <sys/cdefs.h>
37
38 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/mbuf.h>
41 #include <sys/proc.h>
42 #include <sys/systm.h>
43 #include <sys/socketvar.h>
44
45 #include <netbt/bluetooth.h>
46 #include <netbt/hci.h>
47 #include <netbt/l2cap.h>
48 #include <netbt/rfcomm.h>
49
50 /****************************************************************************
51  *
52  *      RFCOMM DLC - Upper Protocol API
53  *
54  * Currently the only 'Port Emulation Entity' is the RFCOMM socket code
55  * but it is should be possible to provide a pseudo-device for a direct
56  * tty interface.
57  */
58
59 /*
60  * rfcomm_attach(handle, proto, upper)
61  *
62  * attach a new RFCOMM DLC to handle, populate with reasonable defaults
63  */
64 int
65 rfcomm_attach(struct rfcomm_dlc **handle,
66                 const struct btproto *proto, void *upper)
67 {
68         struct rfcomm_dlc *dlc;
69
70         KKASSERT(handle != NULL);
71         KKASSERT(proto != NULL);
72         KKASSERT(upper != NULL);
73
74         dlc = kmalloc(sizeof(*dlc), M_BLUETOOTH, M_NOWAIT | M_ZERO);
75         if (dlc == NULL)
76                 return ENOMEM;
77
78         dlc->rd_state = RFCOMM_DLC_CLOSED;
79         dlc->rd_mtu = rfcomm_mtu_default;
80
81         dlc->rd_proto = proto;
82         dlc->rd_upper = upper;
83
84         dlc->rd_laddr.bt_len = sizeof(struct sockaddr_bt);
85         dlc->rd_laddr.bt_family = AF_BLUETOOTH;
86         dlc->rd_laddr.bt_psm = L2CAP_PSM_RFCOMM;
87
88         dlc->rd_raddr.bt_len = sizeof(struct sockaddr_bt);
89         dlc->rd_raddr.bt_family = AF_BLUETOOTH;
90         dlc->rd_raddr.bt_psm = L2CAP_PSM_RFCOMM;
91
92         dlc->rd_lmodem = RFCOMM_MSC_RTC | RFCOMM_MSC_RTR | RFCOMM_MSC_DV;
93
94         callout_init(&dlc->rd_timeout);
95
96         *handle = dlc;
97         return 0;
98 }
99
100 /*
101  * rfcomm_bind(dlc, sockaddr)
102  *
103  * bind DLC to local address
104  */
105 int
106 rfcomm_bind(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
107 {
108
109         memcpy(&dlc->rd_laddr, addr, sizeof(struct sockaddr_bt));
110         return 0;
111 }
112
113 /*
114  * rfcomm_sockaddr(dlc, sockaddr)
115  *
116  * return local address
117  */
118 int
119 rfcomm_sockaddr(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
120 {
121
122         memcpy(addr, &dlc->rd_laddr, sizeof(struct sockaddr_bt));
123         return 0;
124 }
125
126 /*
127  * rfcomm_connect(dlc, sockaddr)
128  *
129  * Initiate connection of RFCOMM DLC to remote address.
130  */
131 int
132 rfcomm_connect(struct rfcomm_dlc *dlc, struct sockaddr_bt *dest)
133 {
134         struct rfcomm_session *rs;
135         int err = 0;
136
137         if (dlc->rd_state != RFCOMM_DLC_CLOSED)
138                 return EISCONN;
139
140         memcpy(&dlc->rd_raddr, dest, sizeof(struct sockaddr_bt));
141
142         if (dlc->rd_raddr.bt_channel < RFCOMM_CHANNEL_MIN
143             || dlc->rd_raddr.bt_channel > RFCOMM_CHANNEL_MAX
144             || bdaddr_any(&dlc->rd_raddr.bt_bdaddr))
145                 return EDESTADDRREQ;
146
147         if (dlc->rd_raddr.bt_psm == L2CAP_PSM_ANY)
148                 dlc->rd_raddr.bt_psm = L2CAP_PSM_RFCOMM;
149         else if (dlc->rd_raddr.bt_psm != L2CAP_PSM_RFCOMM
150             && (dlc->rd_raddr.bt_psm < 0x1001
151             || L2CAP_PSM_INVALID(dlc->rd_raddr.bt_psm)))
152                 return EINVAL;
153
154         /*
155          * We are allowed only one RFCOMM session between any 2 Bluetooth
156          * devices, so see if there is a session already otherwise create
157          * one and set it connecting.
158          */
159         rs = rfcomm_session_lookup(&dlc->rd_laddr, &dlc->rd_raddr);
160         if (rs == NULL) {
161                 rs = rfcomm_session_alloc(&rfcomm_session_active,
162                                                 &dlc->rd_laddr);
163                 if (rs == NULL)
164                         return ENOMEM;
165
166                 rs->rs_flags |= RFCOMM_SESSION_INITIATOR;
167                 rs->rs_state = RFCOMM_SESSION_WAIT_CONNECT;
168
169                 err = l2cap_connect(rs->rs_l2cap, &dlc->rd_raddr);
170                 if (err) {
171                         rfcomm_session_free(rs);
172                         return err;
173                 }
174
175                 /*
176                  * This session will start up automatically when its
177                  * L2CAP channel is connected.
178                  */
179         }
180
181         /* construct DLC */
182         dlc->rd_dlci = RFCOMM_MKDLCI(IS_INITIATOR(rs) ? 0:1, dest->bt_channel);
183         if (rfcomm_dlc_lookup(rs, dlc->rd_dlci))
184                 return EBUSY;
185
186         l2cap_sockaddr(rs->rs_l2cap, &dlc->rd_laddr);
187
188         /*
189          * attach the DLC to the session and start it off
190          */
191         dlc->rd_session = rs;
192         dlc->rd_state = RFCOMM_DLC_WAIT_SESSION;
193         LIST_INSERT_HEAD(&rs->rs_dlcs, dlc, rd_next);
194
195         if (rs->rs_state == RFCOMM_SESSION_OPEN)
196                 err = rfcomm_dlc_connect(dlc);
197
198         return err;
199 }
200
201 /*
202  * rfcomm_peeraddr(dlc, sockaddr)
203  *
204  * return remote address
205  */
206 int
207 rfcomm_peeraddr(struct rfcomm_dlc *dlc, struct sockaddr_bt *addr)
208 {
209
210         memcpy(addr, &dlc->rd_raddr, sizeof(struct sockaddr_bt));
211         return 0;
212 }
213
214 /*
215  * rfcomm_disconnect(dlc, linger)
216  *
217  * disconnect RFCOMM DLC
218  */
219 int
220 rfcomm_disconnect(struct rfcomm_dlc *dlc, int linger)
221 {
222         struct rfcomm_session *rs = dlc->rd_session;
223         int err = 0;
224
225         KKASSERT(dlc != NULL);
226
227         switch (dlc->rd_state) {
228         case RFCOMM_DLC_CLOSED:
229         case RFCOMM_DLC_LISTEN:
230                 return EINVAL;
231
232         case RFCOMM_DLC_WAIT_SEND_UA:
233                 err = rfcomm_session_send_frame(rs,
234                                 RFCOMM_FRAME_DM, dlc->rd_dlci);
235
236                 /* fall through */
237         case RFCOMM_DLC_WAIT_SESSION:
238         case RFCOMM_DLC_WAIT_CONNECT:
239         case RFCOMM_DLC_WAIT_SEND_SABM:
240                 rfcomm_dlc_close(dlc, 0);
241                 break;
242
243         case RFCOMM_DLC_OPEN:
244                 if (dlc->rd_txbuf != NULL && linger != 0) {
245                         dlc->rd_flags |= RFCOMM_DLC_SHUTDOWN;
246                         break;
247                 }
248
249                 /* else fall through */
250         case RFCOMM_DLC_WAIT_RECV_UA:
251                 dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
252                 err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC,
253                                                         dlc->rd_dlci);
254                 callout_reset(&dlc->rd_timeout, rfcomm_ack_timeout * hz,
255                     rfcomm_dlc_timeout, dlc);
256                 break;
257
258         case RFCOMM_DLC_WAIT_DISCONNECT:
259                 err = EALREADY;
260                 break;
261
262         default:
263                 UNKNOWN(dlc->rd_state);
264                 break;
265         }
266
267         return err;
268 }
269
270 /*
271  * rfcomm_detach(handle)
272  *
273  * detach RFCOMM DLC from handle
274  */
275 int
276 rfcomm_detach(struct rfcomm_dlc **handle)
277 {
278         struct rfcomm_dlc *dlc = *handle;
279
280         if (dlc->rd_state != RFCOMM_DLC_CLOSED)
281                 rfcomm_dlc_close(dlc, 0);
282
283         if (dlc->rd_txbuf != NULL) {
284                 m_freem(dlc->rd_txbuf);
285                 dlc->rd_txbuf = NULL;
286         }
287
288         dlc->rd_upper = NULL;
289         *handle = NULL;
290
291         /*
292          * If callout is invoking we can't free the DLC so
293          * mark it and let the callout release it.
294          */
295         if (callout_active(&dlc->rd_timeout))
296                 dlc->rd_flags |= RFCOMM_DLC_DETACH;
297         else
298                 kfree(dlc, M_BLUETOOTH);
299
300         return 0;
301 }
302
303 /*
304  * rfcomm_listen(dlc)
305  *
306  * This DLC is a listener. We look for an existing listening session
307  * with a matching address to attach to or else create a new one on
308  * the listeners list.
309  */
310 int
311 rfcomm_listen(struct rfcomm_dlc *dlc)
312 {
313         struct rfcomm_session *rs, *any, *best;
314         struct sockaddr_bt addr;
315         int err;
316
317         if (dlc->rd_state != RFCOMM_DLC_CLOSED)
318                 return EISCONN;
319
320         if (dlc->rd_laddr.bt_channel < RFCOMM_CHANNEL_MIN
321             || dlc->rd_laddr.bt_channel > RFCOMM_CHANNEL_MAX)
322                 return EADDRNOTAVAIL;
323
324         if (dlc->rd_laddr.bt_psm == L2CAP_PSM_ANY)
325                 dlc->rd_laddr.bt_psm = L2CAP_PSM_RFCOMM;
326         else if (dlc->rd_laddr.bt_psm != L2CAP_PSM_RFCOMM
327             && (dlc->rd_laddr.bt_psm < 0x1001
328             || L2CAP_PSM_INVALID(dlc->rd_laddr.bt_psm)))
329                 return EADDRNOTAVAIL;
330
331         any = best = NULL;
332         LIST_FOREACH(rs, &rfcomm_session_listen, rs_next) {
333                 l2cap_sockaddr(rs->rs_l2cap, &addr);
334
335                 if (addr.bt_psm != dlc->rd_laddr.bt_psm)
336                         continue;
337
338                 if (bdaddr_same(&dlc->rd_laddr.bt_bdaddr, &addr.bt_bdaddr))
339                         best = rs;
340
341                 if (bdaddr_any(&addr.bt_bdaddr))
342                         any = rs;
343         }
344
345         rs = best ? best : any;
346         if (rs == NULL) {
347                 rs = rfcomm_session_alloc(&rfcomm_session_listen,
348                                                 &dlc->rd_laddr);
349                 if (rs == NULL)
350                         return ENOMEM;
351
352                 rs->rs_state = RFCOMM_SESSION_LISTEN;
353
354                 err = l2cap_listen(rs->rs_l2cap);
355                 if (err) {
356                         rfcomm_session_free(rs);
357                         return err;
358                 }
359         }
360
361         dlc->rd_session = rs;
362         dlc->rd_state = RFCOMM_DLC_LISTEN;
363         LIST_INSERT_HEAD(&rs->rs_dlcs, dlc, rd_next);
364
365         return 0;
366 }
367
368 /*
369  * rfcomm_send(dlc, mbuf)
370  *
371  * Output data on DLC. This is streamed data, so we add it
372  * to our buffer and start the DLC, which will assemble
373  * packets and send them if it can.
374  */
375 int
376 rfcomm_send(struct rfcomm_dlc *dlc, struct mbuf *m)
377 {
378
379         if (dlc->rd_txbuf != NULL) {
380                 dlc->rd_txbuf->m_pkthdr.len += m->m_pkthdr.len;
381                 m_cat(dlc->rd_txbuf, m);
382         } else {
383                 dlc->rd_txbuf = m;
384         }
385
386         if (dlc->rd_state == RFCOMM_DLC_OPEN)
387                 rfcomm_dlc_start(dlc);
388
389         return 0;
390 }
391
392 /*
393  * rfcomm_rcvd(dlc, space)
394  *
395  * Indicate space now available in receive buffer
396  *
397  * This should be used to give an initial value of the receive buffer
398  * size when the DLC is attached and anytime data is cleared from the
399  * buffer after that.
400  */
401 int
402 rfcomm_rcvd(struct rfcomm_dlc *dlc, size_t space)
403 {
404
405         KKASSERT(dlc != NULL);
406
407         dlc->rd_rxsize = space;
408
409         /*
410          * if we are using credit based flow control, we may
411          * want to send some credits..
412          */
413         if (dlc->rd_state == RFCOMM_DLC_OPEN
414             && (dlc->rd_session->rs_flags & RFCOMM_SESSION_CFC))
415                 rfcomm_dlc_start(dlc);
416
417         return 0;
418 }
419
420 /*
421  * rfcomm_setopt(dlc, option, addr)
422  *
423  * set DLC options
424  */
425 int
426 rfcomm_setopt(struct rfcomm_dlc *dlc, int opt, void *addr)
427 {
428         int mode, err = 0;
429         uint16_t mtu;
430
431         switch (opt) {
432         case SO_RFCOMM_MTU:
433                 mtu = *(uint16_t *)addr;
434                 if (mtu < RFCOMM_MTU_MIN || mtu > RFCOMM_MTU_MAX)
435                         err = EINVAL;
436                 else if (dlc->rd_state == RFCOMM_DLC_CLOSED)
437                         dlc->rd_mtu = mtu;
438                 else
439                         err = EBUSY;
440
441                 break;
442
443         case SO_RFCOMM_LM:
444                 mode = *(int *)addr;
445                 mode &= (RFCOMM_LM_SECURE | RFCOMM_LM_ENCRYPT | RFCOMM_LM_AUTH);
446
447                 if (mode & RFCOMM_LM_SECURE)
448                         mode |= RFCOMM_LM_ENCRYPT;
449
450                 if (mode & RFCOMM_LM_ENCRYPT)
451                         mode |= RFCOMM_LM_AUTH;
452
453                 dlc->rd_mode = mode;
454
455                 if (dlc->rd_state == RFCOMM_DLC_OPEN)
456                         err = rfcomm_dlc_setmode(dlc);
457
458                 break;
459
460         default:
461                 err = ENOPROTOOPT;
462                 break;
463         }
464         return err;
465 }
466
467
468 int
469 rfcomm_setopt2(struct rfcomm_dlc *dlc, int opt, struct socket *so,
470     struct sockopt *sopt)
471 {
472         int mode, err = 0;
473         uint16_t mtu;
474
475         switch (opt) {
476         case SO_RFCOMM_MTU:
477                 err = sooptcopyin(sopt, &mtu, sizeof(uint16_t),
478                     sizeof(uint16_t)); 
479                 if (err) break;
480
481                 if (mtu < RFCOMM_MTU_MIN || mtu > RFCOMM_MTU_MAX)
482                         err = EINVAL;
483                 else if (dlc->rd_state == RFCOMM_DLC_CLOSED)
484                         dlc->rd_mtu = mtu;
485                 else
486                         err = EBUSY;
487
488                 break;
489
490         case SO_RFCOMM_LM:
491                 err = sooptcopyin(sopt, &mode, sizeof(int), sizeof(int)); 
492                 if (err) break;
493
494                 mode &= (RFCOMM_LM_SECURE | RFCOMM_LM_ENCRYPT | RFCOMM_LM_AUTH);
495
496                 if (mode & RFCOMM_LM_SECURE)
497                         mode |= RFCOMM_LM_ENCRYPT;
498
499                 if (mode & RFCOMM_LM_ENCRYPT)
500                         mode |= RFCOMM_LM_AUTH;
501
502                 dlc->rd_mode = mode;
503
504                 if (dlc->rd_state == RFCOMM_DLC_OPEN)
505                         err = rfcomm_dlc_setmode(dlc);
506
507                 break;
508
509         default:
510                 err = ENOPROTOOPT;
511                 break;
512         }
513         return err;
514 }
515
516 /*
517  * rfcomm_getopt(dlc, option, addr)
518  *
519  * get DLC options
520  */
521 int
522 rfcomm_getopt(struct rfcomm_dlc *dlc, int opt, void *addr)
523 {
524         struct rfcomm_fc_info *fc;
525
526         switch (opt) {
527         case SO_RFCOMM_MTU:
528                 *(uint16_t *)addr = dlc->rd_mtu;
529                 return sizeof(uint16_t);
530
531         case SO_RFCOMM_FC_INFO:
532                 fc = addr;
533                 memset(fc, 0, sizeof(*fc));
534                 fc->lmodem = dlc->rd_lmodem;
535                 fc->rmodem = dlc->rd_rmodem;
536                 fc->tx_cred = max(dlc->rd_txcred, 0xff);
537                 fc->rx_cred = max(dlc->rd_rxcred, 0xff);
538                 if (dlc->rd_session
539                     && (dlc->rd_session->rs_flags & RFCOMM_SESSION_CFC))
540                         fc->cfc = 1;
541
542                 return sizeof(*fc);
543
544         case SO_RFCOMM_LM:
545                 *(int *)addr = dlc->rd_mode;
546                 return sizeof(int);
547
548         default:
549                 break;
550         }
551
552         return 0;
553 }