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