This source file includes following definitions.
- rfcomm_init
- rfcomm_session_alloc
- rfcomm_session_free
- rfcomm_session_lookup
- rfcomm_session_timeout
- rfcomm_session_connecting
- rfcomm_session_connected
- rfcomm_session_disconnected
- rfcomm_session_newconn
- rfcomm_session_complete
- rfcomm_session_linkmode
- rfcomm_session_input
- rfcomm_session_recv_sabm
- rfcomm_session_recv_disc
- rfcomm_session_recv_ua
- rfcomm_session_recv_dm
- rfcomm_session_recv_uih
- rfcomm_session_recv_mcc
- rfcomm_session_recv_mcc_test
- rfcomm_session_recv_mcc_fcon
- rfcomm_session_recv_mcc_fcoff
- rfcomm_session_recv_mcc_msc
- rfcomm_session_recv_mcc_rpn
- rfcomm_session_recv_mcc_rls
- rfcomm_session_recv_mcc_pn
- rfcomm_session_recv_mcc_nsc
- rfcomm_session_send_frame
- rfcomm_session_send_uih
- rfcomm_session_send_mcc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <sys/cdefs.h>
36
37 #include <sys/param.h>
38 #include <sys/kernel.h>
39 #include <sys/mbuf.h>
40 #include <sys/proc.h>
41 #include <sys/systm.h>
42 #include <sys/types.h>
43
44 #include <netbt/bluetooth.h>
45 #include <netbt/hci.h>
46 #include <netbt/l2cap.h>
47 #include <netbt/rfcomm.h>
48
49
50
51
52
53
54
55
56 static void rfcomm_session_timeout(void *);
57 static void rfcomm_session_recv_sabm(struct rfcomm_session *, int);
58 static void rfcomm_session_recv_disc(struct rfcomm_session *, int);
59 static void rfcomm_session_recv_ua(struct rfcomm_session *, int);
60 static void rfcomm_session_recv_dm(struct rfcomm_session *, int);
61 static void rfcomm_session_recv_uih(struct rfcomm_session *, int, int, struct mbuf *, int);
62 static void rfcomm_session_recv_mcc(struct rfcomm_session *, struct mbuf *);
63 static void rfcomm_session_recv_mcc_test(struct rfcomm_session *, int, struct mbuf *);
64 static void rfcomm_session_recv_mcc_fcon(struct rfcomm_session *, int);
65 static void rfcomm_session_recv_mcc_fcoff(struct rfcomm_session *, int);
66 static void rfcomm_session_recv_mcc_msc(struct rfcomm_session *, int, struct mbuf *);
67 static void rfcomm_session_recv_mcc_rpn(struct rfcomm_session *, int, struct mbuf *);
68 static void rfcomm_session_recv_mcc_rls(struct rfcomm_session *, int, struct mbuf *);
69 static void rfcomm_session_recv_mcc_pn(struct rfcomm_session *, int, struct mbuf *);
70 static void rfcomm_session_recv_mcc_nsc(struct rfcomm_session *, int, struct mbuf *);
71
72
73 static void rfcomm_session_connecting(void *);
74 static void rfcomm_session_connected(void *);
75 static void rfcomm_session_disconnected(void *, int);
76 static void *rfcomm_session_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
77 static void rfcomm_session_complete(void *, int);
78 static void rfcomm_session_linkmode(void *, int);
79 static void rfcomm_session_input(void *, struct mbuf *);
80
81 static const struct btproto rfcomm_session_proto = {
82 rfcomm_session_connecting,
83 rfcomm_session_connected,
84 rfcomm_session_disconnected,
85 rfcomm_session_newconn,
86 rfcomm_session_complete,
87 rfcomm_session_linkmode,
88 rfcomm_session_input,
89 };
90
91 struct rfcomm_session_list
92 rfcomm_session_active = LIST_HEAD_INITIALIZER(rfcomm_session_active);
93
94 struct rfcomm_session_list
95 rfcomm_session_listen = LIST_HEAD_INITIALIZER(rfcomm_session_listen);
96
97 struct pool rfcomm_credit_pool;
98
99
100
101
102 int rfcomm_mtu_default = 127;
103 int rfcomm_ack_timeout = 20;
104 int rfcomm_mcc_timeout = 20;
105
106
107
108
109 static const uint8_t crctable[256] = {
110 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
111 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
112 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
113 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
114
115 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
116 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
117 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
118 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
119
120 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
121 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
122 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
123 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
124
125 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
126 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
127 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
128 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
129
130 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
131 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
132 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
133 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
134
135 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
136 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
137 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
138 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
139
140 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
141 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
142 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
143 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
144
145 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
146 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
147 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
148 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
149 };
150
151 #define FCS(f, d) crctable[(f) ^ (d)]
152
153
154
155
156
157
158 void
159 rfcomm_init(void)
160 {
161 pool_init(&rfcomm_credit_pool, 0, 0, 0, 0, "rfcomm_credit", NULL);
162 }
163
164
165
166
167
168
169
170 struct rfcomm_session *
171 rfcomm_session_alloc(struct rfcomm_session_list *list,
172 struct sockaddr_bt *laddr)
173 {
174 struct rfcomm_session *rs;
175 int err;
176
177 rs = malloc(sizeof(*rs), M_BLUETOOTH, M_NOWAIT);
178 if (rs == NULL)
179 return NULL;
180 bzero(rs, sizeof *rs);
181
182 rs->rs_state = RFCOMM_SESSION_CLOSED;
183
184 timeout_set(&rs->rs_timeout, rfcomm_session_timeout, rs);
185
186 SIMPLEQ_INIT(&rs->rs_credits);
187 LIST_INIT(&rs->rs_dlcs);
188
189 err = l2cap_attach(&rs->rs_l2cap, &rfcomm_session_proto, rs);
190 if (err) {
191 free(rs, M_BLUETOOTH);
192 return NULL;
193 }
194
195 (void)l2cap_getopt(rs->rs_l2cap, SO_L2CAP_OMTU, &rs->rs_mtu);
196
197 if (laddr->bt_psm == L2CAP_PSM_ANY)
198 laddr->bt_psm = L2CAP_PSM_RFCOMM;
199
200 (void)l2cap_bind(rs->rs_l2cap, laddr);
201
202 LIST_INSERT_HEAD(list, rs, rs_next);
203
204 return rs;
205 }
206
207
208
209
210
211
212 void
213 rfcomm_session_free(struct rfcomm_session *rs)
214 {
215 struct rfcomm_credit *credit;
216
217 KASSERT(rs != NULL);
218 KASSERT(LIST_EMPTY(&rs->rs_dlcs));
219
220 rs->rs_state = RFCOMM_SESSION_CLOSED;
221
222
223
224
225
226
227 timeout_del(&rs->rs_timeout);
228 if (timeout_triggered(&rs->rs_timeout))
229 return;
230
231
232
233
234
235
236 if (rs->rs_flags & RFCOMM_SESSION_FREE)
237 return;
238
239 rs->rs_flags |= RFCOMM_SESSION_FREE;
240
241
242 while ((credit = SIMPLEQ_FIRST(&rs->rs_credits)) != NULL) {
243 SIMPLEQ_REMOVE_HEAD(&rs->rs_credits, rc_next);
244 pool_put(&rfcomm_credit_pool, credit);
245 }
246
247 KASSERT(SIMPLEQ_EMPTY(&rs->rs_credits));
248
249
250 LIST_REMOVE(rs, rs_next);
251 l2cap_detach(&rs->rs_l2cap);
252 free(rs, M_BLUETOOTH);
253 }
254
255
256
257
258
259
260
261 struct rfcomm_session *
262 rfcomm_session_lookup(struct sockaddr_bt *src, struct sockaddr_bt *dest)
263 {
264 struct rfcomm_session *rs;
265 struct sockaddr_bt addr;
266
267 LIST_FOREACH(rs, &rfcomm_session_active, rs_next) {
268 if (rs->rs_state == RFCOMM_SESSION_CLOSED)
269 continue;
270
271 l2cap_sockaddr(rs->rs_l2cap, &addr);
272
273 if (bdaddr_same(&src->bt_bdaddr, &addr.bt_bdaddr) == 0)
274 if (bdaddr_any(&src->bt_bdaddr) == 0)
275 continue;
276
277 l2cap_peeraddr(rs->rs_l2cap, &addr);
278
279 if (addr.bt_psm != dest->bt_psm)
280 continue;
281
282 if (bdaddr_same(&dest->bt_bdaddr, &addr.bt_bdaddr))
283 break;
284 }
285
286 return rs;
287 }
288
289
290
291
292
293
294
295
296
297
298
299 static void
300 rfcomm_session_timeout(void *arg)
301 {
302 struct rfcomm_session *rs = arg;
303 struct rfcomm_dlc *dlc;
304 int s;
305
306 KASSERT(rs != NULL);
307
308 s = splsoftnet();
309
310 if (rs->rs_state != RFCOMM_SESSION_OPEN) {
311 DPRINTF("timeout\n");
312 rs->rs_state = RFCOMM_SESSION_CLOSED;
313
314 while (!LIST_EMPTY(&rs->rs_dlcs)) {
315 dlc = LIST_FIRST(&rs->rs_dlcs);
316
317 rfcomm_dlc_close(dlc, ETIMEDOUT);
318 }
319 }
320
321 if (LIST_EMPTY(&rs->rs_dlcs)) {
322 DPRINTF("expiring\n");
323 rfcomm_session_free(rs);
324 }
325 splx(s);
326 }
327
328
329
330
331
332
333
334 static void
335 rfcomm_session_connecting(void *arg)
336 {
337
338
339 DPRINTF("Connecting\n");
340 }
341
342 static void
343 rfcomm_session_connected(void *arg)
344 {
345 struct rfcomm_session *rs = arg;
346
347 DPRINTF("Connected\n");
348
349
350
351
352
353
354
355
356
357
358 l2cap_getopt(rs->rs_l2cap, SO_L2CAP_OMTU, &rs->rs_mtu);
359
360 rs->rs_mtu -= 6;
361 if (rs->rs_mtu < RFCOMM_MTU_MIN) {
362 rfcomm_session_disconnected(rs, EINVAL);
363 return;
364 }
365
366 if (IS_INITIATOR(rs)) {
367 int err;
368
369 err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_SABM, 0);
370 if (err)
371 rfcomm_session_disconnected(rs, err);
372
373 timeout_add(&rs->rs_timeout, rfcomm_ack_timeout * hz);
374 }
375 }
376
377 static void
378 rfcomm_session_disconnected(void *arg, int err)
379 {
380 struct rfcomm_session *rs = arg;
381 struct rfcomm_dlc *dlc;
382
383 DPRINTF("Disconnected\n");
384
385 rs->rs_state = RFCOMM_SESSION_CLOSED;
386
387 while (!LIST_EMPTY(&rs->rs_dlcs)) {
388 dlc = LIST_FIRST(&rs->rs_dlcs);
389
390 rfcomm_dlc_close(dlc, err);
391 }
392
393 rfcomm_session_free(rs);
394 }
395
396 static void *
397 rfcomm_session_newconn(void *arg, struct sockaddr_bt *laddr,
398 struct sockaddr_bt *raddr)
399 {
400 struct rfcomm_session *new, *rs = arg;
401
402 DPRINTF("New Connection\n");
403
404
405
406
407
408
409
410 new = rfcomm_session_lookup(laddr, raddr);
411 if (new != NULL)
412 return NULL;
413
414 new = rfcomm_session_alloc(&rfcomm_session_active, laddr);
415 if (new == NULL)
416 return NULL;
417
418 new->rs_mtu = rs->rs_mtu;
419 new->rs_state = RFCOMM_SESSION_WAIT_CONNECT;
420
421
422
423
424
425 timeout_add(&new->rs_timeout, rfcomm_mcc_timeout * hz);
426
427 return new->rs_l2cap;
428 }
429
430 static void
431 rfcomm_session_complete(void *arg, int count)
432 {
433 struct rfcomm_session *rs = arg;
434 struct rfcomm_credit *credit;
435 struct rfcomm_dlc *dlc;
436
437
438
439
440
441
442
443 while (count-- > 0) {
444 credit = SIMPLEQ_FIRST(&rs->rs_credits);
445 #ifdef DIAGNOSTIC
446 if (credit == NULL) {
447 printf("%s: too many packets completed!\n", __func__);
448 break;
449 }
450 #endif
451 dlc = credit->rc_dlc;
452 if (dlc != NULL) {
453 dlc->rd_pending--;
454 (*dlc->rd_proto->complete)
455 (dlc->rd_upper, credit->rc_len);
456
457
458
459
460
461 if ((rs->rs_flags & RFCOMM_SESSION_CFC) == 0
462 && dlc->rd_state == RFCOMM_DLC_OPEN) {
463 rfcomm_dlc_start(dlc);
464 }
465
466
467
468
469
470 if ((dlc->rd_flags & RFCOMM_DLC_SHUTDOWN)
471 && dlc->rd_txbuf == NULL && dlc->rd_pending == 0) {
472 dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
473 rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC,
474 dlc->rd_dlci);
475 timeout_add(&dlc->rd_timeout,
476 rfcomm_ack_timeout * hz);
477 }
478 }
479
480 SIMPLEQ_REMOVE_HEAD(&rs->rs_credits, rc_next);
481 pool_put(&rfcomm_credit_pool, credit);
482 }
483
484
485
486
487 if (rs->rs_state == RFCOMM_SESSION_CLOSED) {
488 if (SIMPLEQ_EMPTY(&rs->rs_credits))
489 l2cap_disconnect(rs->rs_l2cap, 0);
490 }
491 }
492
493
494
495
496
497
498
499 static void
500 rfcomm_session_linkmode(void *arg, int new)
501 {
502 struct rfcomm_session *rs = arg;
503 struct rfcomm_dlc *dlc, *next;
504 int err, mode = 0;
505
506 DPRINTF("auth %s, encrypt %s, secure %s\n",
507 (new & L2CAP_LM_AUTH ? "on" : "off"),
508 (new & L2CAP_LM_ENCRYPT ? "on" : "off"),
509 (new & L2CAP_LM_SECURE ? "on" : "off"));
510
511 if (new & L2CAP_LM_AUTH)
512 mode |= RFCOMM_LM_AUTH;
513
514 if (new & L2CAP_LM_ENCRYPT)
515 mode |= RFCOMM_LM_ENCRYPT;
516
517 if (new & L2CAP_LM_SECURE)
518 mode |= RFCOMM_LM_SECURE;
519
520 next = LIST_FIRST(&rs->rs_dlcs);
521 while ((dlc = next) != NULL) {
522 next = LIST_NEXT(dlc, rd_next);
523
524 switch (dlc->rd_state) {
525 case RFCOMM_DLC_WAIT_SEND_SABM:
526 if ((mode & dlc->rd_mode) != dlc->rd_mode) {
527 rfcomm_dlc_close(dlc, ECONNABORTED);
528 } else {
529 err = rfcomm_session_send_frame(rs,
530 RFCOMM_FRAME_SABM, dlc->rd_dlci);
531 if (err) {
532 rfcomm_dlc_close(dlc, err);
533 } else {
534 dlc->rd_state = RFCOMM_DLC_WAIT_RECV_UA;
535 timeout_add(&dlc->rd_timeout,
536 rfcomm_ack_timeout * hz);
537 break;
538 }
539 }
540
541
542
543
544
545 if (!LIST_EMPTY(&rs->rs_dlcs))
546 break;
547
548 rs->rs_state = RFCOMM_SESSION_WAIT_DISCONNECT;
549 rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC, 0);
550 timeout_add(&rs->rs_timeout, rfcomm_ack_timeout * hz);
551 break;
552
553 case RFCOMM_DLC_WAIT_SEND_UA:
554 if ((mode & dlc->rd_mode) != dlc->rd_mode) {
555 rfcomm_session_send_frame(rs,
556 RFCOMM_FRAME_DM, dlc->rd_dlci);
557 rfcomm_dlc_close(dlc, ECONNABORTED);
558 break;
559 }
560
561 err = rfcomm_session_send_frame(rs,
562 RFCOMM_FRAME_UA, dlc->rd_dlci);
563 if (err) {
564 rfcomm_session_send_frame(rs,
565 RFCOMM_FRAME_DM, dlc->rd_dlci);
566 rfcomm_dlc_close(dlc, err);
567 break;
568 }
569
570 err = rfcomm_dlc_open(dlc);
571 if (err) {
572 rfcomm_session_send_frame(rs,
573 RFCOMM_FRAME_DM, dlc->rd_dlci);
574 rfcomm_dlc_close(dlc, err);
575 break;
576 }
577
578 break;
579
580 case RFCOMM_DLC_WAIT_RECV_UA:
581 case RFCOMM_DLC_OPEN:
582 (*dlc->rd_proto->linkmode)(dlc->rd_upper, mode);
583 break;
584
585 default:
586 break;
587 }
588 }
589 }
590
591
592
593
594
595 static void
596 rfcomm_session_input(void *arg, struct mbuf *m)
597 {
598 struct rfcomm_session *rs = arg;
599 int dlci, len, type, pf;
600 uint8_t fcs, b;
601
602 KASSERT(m != NULL);
603 KASSERT(rs != NULL);
604
605
606
607
608
609
610 fcs = 0xff;
611
612 if (m->m_pkthdr.len < 4) {
613 DPRINTF("short frame (%d), discarded\n", m->m_pkthdr.len);
614 goto done;
615 }
616
617
618 m_copydata(m, 0, 1, &b);
619 m_adj(m, 1);
620 fcs = FCS(fcs, b);
621 dlci = RFCOMM_DLCI(b);
622
623
624 m_copydata(m, 0, 1, &b);
625 m_adj(m, 1);
626 fcs = FCS(fcs, b);
627 type = RFCOMM_TYPE(b);
628 pf = RFCOMM_PF(b);
629
630
631 m_copydata(m, 0, 1, &b);
632 m_adj(m, 1);
633 if (type != RFCOMM_FRAME_UIH)
634 fcs = FCS(fcs, b);
635 len = (b >> 1) & 0x7f;
636
637 if (RFCOMM_EA(b) == 0) {
638 if (m->m_pkthdr.len < 2) {
639 DPRINTF("short frame (%d, EA = 0), discarded\n",
640 m->m_pkthdr.len);
641 goto done;
642 }
643
644 m_copydata(m, 0, 1, &b);
645 m_adj(m, 1);
646 if (type != RFCOMM_FRAME_UIH)
647 fcs = FCS(fcs, b);
648
649 len |= (b << 7);
650 }
651
652
653 m_copydata(m, m->m_pkthdr.len - 1, 1, &b);
654 m_adj(m, -1);
655 fcs = FCS(fcs, b);
656
657 if (fcs != 0xcf) {
658 DPRINTF("Bad FCS value (%#2.2x), frame discarded\n", fcs);
659 goto done;
660 }
661
662 DPRINTFN(10, "dlci %d, type %2.2x, len = %d\n", dlci, type, len);
663
664 switch (type) {
665 case RFCOMM_FRAME_SABM:
666 if (pf)
667 rfcomm_session_recv_sabm(rs, dlci);
668 break;
669
670 case RFCOMM_FRAME_DISC:
671 if (pf)
672 rfcomm_session_recv_disc(rs, dlci);
673 break;
674
675 case RFCOMM_FRAME_UA:
676 if (pf)
677 rfcomm_session_recv_ua(rs, dlci);
678 break;
679
680 case RFCOMM_FRAME_DM:
681 rfcomm_session_recv_dm(rs, dlci);
682 break;
683
684 case RFCOMM_FRAME_UIH:
685 rfcomm_session_recv_uih(rs, dlci, pf, m, len);
686 return;
687
688 default:
689 UNKNOWN(type);
690 break;
691 }
692
693 done:
694 m_freem(m);
695 }
696
697
698
699
700
701
702
703
704
705
706
707 static void
708 rfcomm_session_recv_sabm(struct rfcomm_session *rs, int dlci)
709 {
710 struct rfcomm_dlc *dlc;
711 int err;
712
713 DPRINTFN(5, "SABM(%d)\n", dlci);
714
715 if (dlci == 0) {
716 rs->rs_state = RFCOMM_SESSION_OPEN;
717 rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, 0);
718 LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
719 if (dlc->rd_state == RFCOMM_DLC_WAIT_SESSION)
720 rfcomm_dlc_connect(dlc);
721 }
722 return;
723 }
724
725 if (rs->rs_state != RFCOMM_SESSION_OPEN) {
726 DPRINTF("session was not even open!\n");
727 return;
728 }
729
730
731 if ((IS_INITIATOR(rs) && !RFCOMM_DIRECTION(dlci))
732 || (!IS_INITIATOR(rs) && RFCOMM_DIRECTION(dlci))) {
733 DPRINTF("Invalid direction bit on DLCI\n");
734 return;
735 }
736
737
738
739
740
741 dlc = rfcomm_dlc_lookup(rs, dlci);
742 if (dlc == NULL) {
743 dlc = rfcomm_dlc_newconn(rs, dlci);
744 if (dlc == NULL)
745 return;
746 }
747
748
749
750
751
752 if (dlc->rd_state != RFCOMM_DLC_WAIT_CONNECT)
753 return;
754
755
756 err = rfcomm_dlc_setmode(dlc);
757 if (err == EINPROGRESS) {
758 dlc->rd_state = RFCOMM_DLC_WAIT_SEND_UA;
759 (*dlc->rd_proto->connecting)(dlc->rd_upper);
760 return;
761 }
762 if (err)
763 goto close;
764
765 err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, dlci);
766 if (err)
767 goto close;
768
769
770 err = rfcomm_dlc_open(dlc);
771 if (err)
772 goto close;
773
774 return;
775
776 close:
777 rfcomm_dlc_close(dlc, err);
778 }
779
780
781
782
783 static void
784 rfcomm_session_recv_disc(struct rfcomm_session *rs, int dlci)
785 {
786 struct rfcomm_dlc *dlc;
787
788 DPRINTFN(5, "DISC(%d)\n", dlci);
789
790 if (dlci == 0) {
791
792
793
794
795
796
797
798
799
800
801 rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, 0);
802 rs->rs_state = RFCOMM_SESSION_CLOSED;
803 return;
804 }
805
806 dlc = rfcomm_dlc_lookup(rs, dlci);
807 if (dlc == NULL) {
808 rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM, dlci);
809 return;
810 }
811
812 rfcomm_dlc_close(dlc, ECONNRESET);
813 rfcomm_session_send_frame(rs, RFCOMM_FRAME_UA, dlci);
814 }
815
816
817
818
819
820
821
822 static void
823 rfcomm_session_recv_ua(struct rfcomm_session *rs, int dlci)
824 {
825 struct rfcomm_dlc *dlc;
826
827 DPRINTFN(5, "UA(%d)\n", dlci);
828
829 if (dlci == 0) {
830 switch (rs->rs_state) {
831 case RFCOMM_SESSION_WAIT_CONNECT:
832 timeout_del(&rs->rs_timeout);
833 rs->rs_state = RFCOMM_SESSION_OPEN;
834 LIST_FOREACH(dlc, &rs->rs_dlcs, rd_next) {
835 if (dlc->rd_state == RFCOMM_DLC_WAIT_SESSION)
836 rfcomm_dlc_connect(dlc);
837 }
838 break;
839
840 case RFCOMM_SESSION_WAIT_DISCONNECT:
841 timeout_del(&rs->rs_timeout);
842 rs->rs_state = RFCOMM_SESSION_CLOSED;
843 l2cap_disconnect(rs->rs_l2cap, 0);
844 break;
845
846 default:
847 DPRINTF("Received spurious UA(0)!\n");
848 break;
849 }
850
851 return;
852 }
853
854
855
856
857
858
859 dlc = rfcomm_dlc_lookup(rs, dlci);
860 if (dlc == NULL)
861 goto check;
862
863 switch (dlc->rd_state) {
864 case RFCOMM_DLC_WAIT_RECV_UA:
865 rfcomm_dlc_open(dlc);
866 return;
867
868 case RFCOMM_DLC_WAIT_DISCONNECT:
869 rfcomm_dlc_close(dlc, 0);
870 break;
871
872 default:
873 DPRINTF("Received spurious UA(%d)!\n", dlci);
874 return;
875 }
876
877 check:
878 if (LIST_EMPTY(&rs->rs_dlcs)) {
879 rs->rs_state = RFCOMM_SESSION_WAIT_DISCONNECT;
880 rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC, 0);
881 timeout_add(&rs->rs_timeout, rfcomm_ack_timeout * hz);
882 }
883 }
884
885
886
887
888
889
890 static void
891 rfcomm_session_recv_dm(struct rfcomm_session *rs, int dlci)
892 {
893 struct rfcomm_dlc *dlc;
894
895 DPRINTFN(5, "DM(%d)\n", dlci);
896
897 dlc = rfcomm_dlc_lookup(rs, dlci);
898 if (dlc == NULL)
899 return;
900
901 if (dlc->rd_state == RFCOMM_DLC_WAIT_CONNECT)
902 rfcomm_dlc_close(dlc, ECONNREFUSED);
903 else
904 rfcomm_dlc_close(dlc, ECONNRESET);
905 }
906
907
908
909
910 static void
911 rfcomm_session_recv_uih(struct rfcomm_session *rs, int dlci,
912 int pf, struct mbuf *m, int len)
913 {
914 struct rfcomm_dlc *dlc;
915 uint8_t credits = 0;
916
917 DPRINTFN(10, "UIH(%d)\n", dlci);
918
919 if (dlci == 0) {
920 rfcomm_session_recv_mcc(rs, m);
921 return;
922 }
923
924 if (m->m_pkthdr.len != len + pf) {
925 DPRINTF("Bad Frame Length (%d), frame discarded\n",
926 m->m_pkthdr.len);
927
928 goto discard;
929 }
930
931 dlc = rfcomm_dlc_lookup(rs, dlci);
932 if (dlc == NULL) {
933 DPRINTF("UIH received for non existent DLC, discarded\n");
934 rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM, dlci);
935 goto discard;
936 }
937
938 if (dlc->rd_state != RFCOMM_DLC_OPEN) {
939 DPRINTF("non-open DLC (state = %d), discarded\n",
940 dlc->rd_state);
941 goto discard;
942 }
943
944
945 if (rs->rs_flags & RFCOMM_SESSION_CFC) {
946 if (pf != 0) {
947 if (m->m_pkthdr.len < sizeof(credits)) {
948 DPRINTF("Bad PF value, UIH discarded\n");
949 goto discard;
950 }
951
952 m_copydata(m, 0, sizeof(credits), &credits);
953 m_adj(m, sizeof(credits));
954
955 dlc->rd_txcred += credits;
956
957 if (credits > 0 && dlc->rd_txbuf != NULL)
958 rfcomm_dlc_start(dlc);
959 }
960
961 if (len == 0)
962 goto discard;
963
964 if (dlc->rd_rxcred == 0) {
965 DPRINTF("Credit limit reached, UIH discarded\n");
966 goto discard;
967 }
968
969 if (len > dlc->rd_rxsize) {
970 DPRINTF("UIH frame exceeds rxsize, discarded\n");
971 goto discard;
972 }
973
974 dlc->rd_rxcred--;
975 dlc->rd_rxsize -= len;
976 }
977
978 (*dlc->rd_proto->input)(dlc->rd_upper, m);
979 return;
980
981 discard:
982 m_freem(m);
983 }
984
985
986
987
988 static void
989 rfcomm_session_recv_mcc(struct rfcomm_session *rs, struct mbuf *m)
990 {
991 int type, cr, len;
992 uint8_t b;
993
994
995
996
997
998
999
1000
1001
1002
1003
1004 if (m->m_pkthdr.len < sizeof(b)) {
1005 DPRINTF("Short MCC header, discarded\n");
1006 goto release;
1007 }
1008
1009 m_copydata(m, 0, sizeof(b), &b);
1010 m_adj(m, sizeof(b));
1011
1012 if (RFCOMM_EA(b) == 0) {
1013 DPRINTF("MCC type EA = 0, discarded\n");
1014 goto release;
1015 }
1016
1017 type = RFCOMM_MCC_TYPE(b);
1018 cr = RFCOMM_CR(b);
1019
1020 len = 0;
1021 do {
1022 if (m->m_pkthdr.len < sizeof(b)) {
1023 DPRINTF("Short MCC header, discarded\n");
1024 goto release;
1025 }
1026
1027 m_copydata(m, 0, sizeof(b), &b);
1028 m_adj(m, sizeof(b));
1029
1030 len = (len << 7) | (b >> 1);
1031 len = min(len, RFCOMM_MTU_MAX);
1032 } while (RFCOMM_EA(b) == 0);
1033
1034 if (len != m->m_pkthdr.len) {
1035 DPRINTF("Incorrect MCC length, discarded\n");
1036 goto release;
1037 }
1038
1039 DPRINTFN(2, "MCC %s type %2.2x (%d bytes)\n",
1040 (cr ? "command" : "response"), type, len);
1041
1042
1043
1044
1045 switch(type) {
1046 case RFCOMM_MCC_TEST:
1047 rfcomm_session_recv_mcc_test(rs, cr, m);
1048 break;
1049
1050 case RFCOMM_MCC_FCON:
1051 rfcomm_session_recv_mcc_fcon(rs, cr);
1052 break;
1053
1054 case RFCOMM_MCC_FCOFF:
1055 rfcomm_session_recv_mcc_fcoff(rs, cr);
1056 break;
1057
1058 case RFCOMM_MCC_MSC:
1059 rfcomm_session_recv_mcc_msc(rs, cr, m);
1060 break;
1061
1062 case RFCOMM_MCC_RPN:
1063 rfcomm_session_recv_mcc_rpn(rs, cr, m);
1064 break;
1065
1066 case RFCOMM_MCC_RLS:
1067 rfcomm_session_recv_mcc_rls(rs, cr, m);
1068 break;
1069
1070 case RFCOMM_MCC_PN:
1071 rfcomm_session_recv_mcc_pn(rs, cr, m);
1072 break;
1073
1074 case RFCOMM_MCC_NSC:
1075 rfcomm_session_recv_mcc_nsc(rs, cr, m);
1076 break;
1077
1078 default:
1079 b = RFCOMM_MKMCC_TYPE(cr, type);
1080 rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_NSC, &b, sizeof(b));
1081 }
1082
1083 release:
1084 m_freem(m);
1085 }
1086
1087
1088
1089
1090 static void
1091 rfcomm_session_recv_mcc_test(struct rfcomm_session *rs, int cr, struct mbuf *m)
1092 {
1093 void *data;
1094 int len;
1095
1096 if (cr == 0)
1097 return;
1098
1099
1100
1101
1102
1103 len = m->m_pkthdr.len;
1104 if (len > RFCOMM_MTU_MAX)
1105 return;
1106
1107 data = malloc(len, M_BLUETOOTH, M_NOWAIT);
1108 if (data == NULL)
1109 return;
1110
1111 m_copydata(m, 0, len, data);
1112 rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_TEST, data, len);
1113 free(data, M_BLUETOOTH);
1114 }
1115
1116
1117
1118
1119 static void
1120 rfcomm_session_recv_mcc_fcon(struct rfcomm_session *rs, int cr)
1121 {
1122
1123 if (cr == 0)
1124 return;
1125
1126 rs->rs_flags |= RFCOMM_SESSION_RFC;
1127 rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_FCON, NULL, 0);
1128 }
1129
1130
1131
1132
1133 static void
1134 rfcomm_session_recv_mcc_fcoff(struct rfcomm_session *rs, int cr)
1135 {
1136
1137 if (cr == 0)
1138 return;
1139
1140 rs->rs_flags &= ~RFCOMM_SESSION_RFC;
1141 rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_FCOFF, NULL, 0);
1142 }
1143
1144
1145
1146
1147 static void
1148 rfcomm_session_recv_mcc_msc(struct rfcomm_session *rs, int cr, struct mbuf *m)
1149 {
1150 struct rfcomm_mcc_msc msc;
1151 struct rfcomm_dlc *dlc;
1152 int len = 0;
1153
1154
1155 if (m->m_pkthdr.len < sizeof(msc.address))
1156 return;
1157
1158 m_copydata(m, 0, sizeof(msc.address), &msc.address);
1159 m_adj(m, sizeof(msc.address));
1160 len += sizeof(msc.address);
1161
1162 dlc = rfcomm_dlc_lookup(rs, RFCOMM_DLCI(msc.address));
1163
1164 if (cr == 0) {
1165 if (dlc != NULL)
1166 timeout_del(&dlc->rd_timeout);
1167
1168 return;
1169 }
1170
1171 if (dlc == NULL) {
1172 rfcomm_session_send_frame(rs, RFCOMM_FRAME_DM,
1173 RFCOMM_DLCI(msc.address));
1174 return;
1175 }
1176
1177
1178 if (m->m_pkthdr.len < sizeof(msc.modem))
1179 return;
1180
1181 m_copydata(m, 0, sizeof(msc.modem), &msc.modem);
1182 m_adj(m, sizeof(msc.modem));
1183 len += sizeof(msc.modem);
1184
1185 dlc->rd_rmodem = msc.modem;
1186
1187
1188 if (RFCOMM_EA(msc.modem) == 0) {
1189 if (m->m_pkthdr.len < sizeof(msc.brk))
1190 return;
1191
1192 m_copydata(m, 0, sizeof(msc.brk), &msc.brk);
1193 m_adj(m, sizeof(msc.brk));
1194 len += sizeof(msc.brk);
1195
1196
1197 }
1198
1199 rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_MSC, &msc, len);
1200 }
1201
1202
1203
1204
1205 static void
1206 rfcomm_session_recv_mcc_rpn(struct rfcomm_session *rs, int cr, struct mbuf *m)
1207 {
1208 struct rfcomm_mcc_rpn rpn;
1209 uint16_t mask;
1210
1211 if (cr == 0)
1212 return;
1213
1214
1215 rpn.bit_rate = RFCOMM_RPN_BR_9600;
1216 rpn.line_settings = RFCOMM_RPN_8_N_1;
1217 rpn.flow_control = RFCOMM_RPN_FLOW_NONE;
1218 rpn.xon_char = RFCOMM_RPN_XON_CHAR;
1219 rpn.xoff_char = RFCOMM_RPN_XOFF_CHAR;
1220
1221 if (m->m_pkthdr.len == sizeof(rpn)) {
1222 m_copydata(m, 0, sizeof(rpn), (caddr_t)&rpn);
1223 rpn.param_mask = RFCOMM_RPN_PM_ALL;
1224 } else if (m->m_pkthdr.len == 1) {
1225 m_copydata(m, 0, 1, (caddr_t)&rpn);
1226 rpn.param_mask = letoh16(rpn.param_mask);
1227 } else {
1228 DPRINTF("Bad RPN length (%d)\n", m->m_pkthdr.len);
1229 return;
1230 }
1231
1232 mask = 0;
1233
1234 if (rpn.param_mask & RFCOMM_RPN_PM_RATE)
1235 mask |= RFCOMM_RPN_PM_RATE;
1236
1237 if (rpn.param_mask & RFCOMM_RPN_PM_DATA
1238 && RFCOMM_RPN_DATA_BITS(rpn.line_settings) == RFCOMM_RPN_DATA_8)
1239 mask |= RFCOMM_RPN_PM_DATA;
1240
1241 if (rpn.param_mask & RFCOMM_RPN_PM_STOP
1242 && RFCOMM_RPN_STOP_BITS(rpn.line_settings) == RFCOMM_RPN_STOP_1)
1243 mask |= RFCOMM_RPN_PM_STOP;
1244
1245 if (rpn.param_mask & RFCOMM_RPN_PM_PARITY
1246 && RFCOMM_RPN_PARITY(rpn.line_settings) == RFCOMM_RPN_PARITY_NONE)
1247 mask |= RFCOMM_RPN_PM_PARITY;
1248
1249 if (rpn.param_mask & RFCOMM_RPN_PM_XON
1250 && rpn.xon_char == RFCOMM_RPN_XON_CHAR)
1251 mask |= RFCOMM_RPN_PM_XON;
1252
1253 if (rpn.param_mask & RFCOMM_RPN_PM_XOFF
1254 && rpn.xoff_char == RFCOMM_RPN_XOFF_CHAR)
1255 mask |= RFCOMM_RPN_PM_XOFF;
1256
1257 if (rpn.param_mask & RFCOMM_RPN_PM_FLOW
1258 && rpn.flow_control == RFCOMM_RPN_FLOW_NONE)
1259 mask |= RFCOMM_RPN_PM_FLOW;
1260
1261 rpn.param_mask = htole16(mask);
1262
1263 rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_RPN, &rpn, sizeof(rpn));
1264 }
1265
1266
1267
1268
1269 static void
1270 rfcomm_session_recv_mcc_rls(struct rfcomm_session *rs, int cr, struct mbuf *m)
1271 {
1272 struct rfcomm_mcc_rls rls;
1273
1274 if (cr == 0)
1275 return;
1276
1277 if (m->m_pkthdr.len != sizeof(rls)) {
1278 DPRINTF("Bad RLS length %d\n", m->m_pkthdr.len);
1279 return;
1280 }
1281
1282 m_copydata(m, 0, sizeof(rls), (caddr_t)&rls);
1283
1284
1285
1286
1287
1288
1289 rls.address |= 0x03;
1290 rls.status &= 0x0f;
1291
1292 rfcomm_session_send_mcc(rs, 0, RFCOMM_MCC_RLS, &rls, sizeof(rls));
1293 }
1294
1295
1296
1297
1298 static void
1299 rfcomm_session_recv_mcc_pn(struct rfcomm_session *rs, int cr, struct mbuf *m)
1300 {
1301 struct rfcomm_dlc *dlc;
1302 struct rfcomm_mcc_pn pn;
1303 int err;
1304
1305 if (m->m_pkthdr.len != sizeof(pn)) {
1306 DPRINTF("Bad PN length %d\n", m->m_pkthdr.len);
1307 return;
1308 }
1309
1310 m_copydata(m, 0, sizeof(pn), (caddr_t)&pn);
1311
1312 pn.dlci &= 0x3f;
1313 pn.mtu = letoh16(pn.mtu);
1314
1315 dlc = rfcomm_dlc_lookup(rs, pn.dlci);
1316 if (cr) {
1317
1318
1319
1320
1321 if (dlc == NULL) {
1322 dlc = rfcomm_dlc_newconn(rs, pn.dlci);
1323 if (dlc == NULL)
1324 return;
1325 }
1326
1327
1328 pn.mtu = min(pn.mtu, RFCOMM_MTU_MAX);
1329 pn.mtu = min(pn.mtu, rs->rs_mtu);
1330 pn.mtu = max(pn.mtu, RFCOMM_MTU_MIN);
1331 dlc->rd_mtu = pn.mtu;
1332 pn.mtu = htole16(pn.mtu);
1333
1334
1335 if (dlc->rd_state == RFCOMM_DLC_WAIT_CONNECT
1336 && (pn.flow_control & 0xf0) == 0xf0) {
1337 rs->rs_flags |= RFCOMM_SESSION_CFC;
1338 dlc->rd_txcred = pn.credits & 0x07;
1339
1340 dlc->rd_rxcred = (dlc->rd_rxsize / dlc->rd_mtu);
1341 dlc->rd_rxcred = min(dlc->rd_rxcred,
1342 RFCOMM_CREDITS_DEFAULT);
1343
1344 pn.flow_control = 0xe0;
1345 pn.credits = dlc->rd_rxcred;
1346 } else {
1347 pn.flow_control = 0x00;
1348 pn.credits = 0x00;
1349 }
1350
1351
1352 pn.ack_timer = 0;
1353 pn.max_retrans = 0;
1354
1355
1356 err = rfcomm_session_send_mcc(rs, 0,
1357 RFCOMM_MCC_PN, &pn, sizeof(pn));
1358 if (err)
1359 goto close;
1360
1361 } else {
1362
1363 if (dlc == NULL)
1364 return;
1365
1366 timeout_del(&dlc->rd_timeout);
1367
1368 if (pn.mtu > RFCOMM_MTU_MAX || pn.mtu > dlc->rd_mtu) {
1369 dlc->rd_state = RFCOMM_DLC_WAIT_DISCONNECT;
1370 err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_DISC,
1371 pn.dlci);
1372 if (err)
1373 goto close;
1374
1375 timeout_add(&dlc->rd_timeout,
1376 rfcomm_ack_timeout * hz);
1377 return;
1378 }
1379 dlc->rd_mtu = pn.mtu;
1380
1381
1382 if (dlc->rd_state != RFCOMM_DLC_WAIT_CONNECT)
1383 return;
1384
1385
1386 if ((pn.flow_control & 0xf0) == 0xe0) {
1387 rs->rs_flags |= RFCOMM_SESSION_CFC;
1388 dlc->rd_txcred = (pn.credits & 0x07);
1389 }
1390
1391 timeout_add(&dlc->rd_timeout, rfcomm_ack_timeout * hz);
1392
1393
1394 err = rfcomm_dlc_setmode(dlc);
1395 if (err == EINPROGRESS) {
1396 dlc->rd_state = RFCOMM_DLC_WAIT_SEND_SABM;
1397 (*dlc->rd_proto->connecting)(dlc->rd_upper);
1398 return;
1399 }
1400 if (err)
1401 goto close;
1402
1403
1404 err = rfcomm_session_send_frame(rs, RFCOMM_FRAME_SABM, pn.dlci);
1405 if (err)
1406 goto close;
1407
1408 dlc->rd_state = RFCOMM_DLC_WAIT_RECV_UA;
1409 }
1410 return;
1411
1412 close:
1413 rfcomm_dlc_close(dlc, err);
1414 }
1415
1416
1417
1418
1419 static void
1420 rfcomm_session_recv_mcc_nsc(struct rfcomm_session *rs,
1421 int cr, struct mbuf *m)
1422 {
1423 struct rfcomm_dlc *dlc, *next;
1424
1425
1426
1427
1428
1429
1430 next = LIST_FIRST(&rs->rs_dlcs);
1431 while ((dlc = next) != NULL) {
1432 next = LIST_NEXT(dlc, rd_next);
1433 rfcomm_dlc_close(dlc, ECONNABORTED);
1434 }
1435
1436 rfcomm_session_free(rs);
1437 }
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447 int
1448 rfcomm_session_send_frame(struct rfcomm_session *rs, int type, int dlci)
1449 {
1450 struct rfcomm_cmd_hdr *hdr;
1451 struct rfcomm_credit *credit;
1452 struct mbuf *m;
1453 uint8_t fcs, cr;
1454
1455 credit = pool_get(&rfcomm_credit_pool, PR_NOWAIT);
1456 if (credit == NULL)
1457 return ENOMEM;
1458
1459 m = m_gethdr(M_DONTWAIT, MT_DATA);
1460 if (m == NULL) {
1461 pool_put(&rfcomm_credit_pool, credit);
1462 return ENOMEM;
1463 }
1464
1465
1466
1467
1468
1469
1470
1471
1472 if (type == RFCOMM_FRAME_UA || type == RFCOMM_FRAME_DM)
1473 cr = IS_INITIATOR(rs) ? 0 : 1;
1474 else
1475 cr = IS_INITIATOR(rs) ? 1 : 0;
1476
1477 hdr = mtod(m, struct rfcomm_cmd_hdr *);
1478 hdr->address = RFCOMM_MKADDRESS(cr, dlci);
1479 hdr->control = RFCOMM_MKCONTROL(type, 1);
1480 hdr->length = (0x00 << 1) | 0x01;
1481
1482 fcs = 0xff;
1483 fcs = FCS(fcs, hdr->address);
1484 fcs = FCS(fcs, hdr->control);
1485 fcs = FCS(fcs, hdr->length);
1486 fcs = 0xff - fcs;
1487 hdr->fcs = fcs;
1488
1489 m->m_pkthdr.len = m->m_len = sizeof(struct rfcomm_cmd_hdr);
1490
1491
1492 credit->rc_dlc = NULL;
1493 credit->rc_len = m->m_pkthdr.len;
1494 SIMPLEQ_INSERT_TAIL(&rs->rs_credits, credit, rc_next);
1495
1496 DPRINTFN(5, "dlci %d type %2.2x (%d bytes, fcs=%#2.2x)\n",
1497 dlci, type, m->m_pkthdr.len, fcs);
1498
1499 return l2cap_send(rs->rs_l2cap, m);
1500 }
1501
1502
1503
1504
1505
1506
1507
1508
1509 int
1510 rfcomm_session_send_uih(struct rfcomm_session *rs, struct rfcomm_dlc *dlc,
1511 int credits, struct mbuf *m)
1512 {
1513 struct rfcomm_credit *credit;
1514 struct mbuf *m0 = NULL;
1515 int err, len;
1516 uint8_t fcs, *hdr;
1517
1518 KASSERT(rs != NULL);
1519
1520 len = (m == NULL) ? 0 : m->m_pkthdr.len;
1521 KASSERT(!(credits == 0 && len == 0));
1522
1523
1524
1525
1526 credit = pool_get(&rfcomm_credit_pool, PR_NOWAIT);
1527 if (credit == NULL)
1528 goto nomem;
1529
1530 credit->rc_len = len;
1531 credit->rc_dlc = dlc;
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549 m0 = m_gethdr(M_DONTWAIT, MT_DATA);
1550 if (m0 == NULL)
1551 goto nomem;
1552
1553 MH_ALIGN(m0, 5);
1554 hdr = mtod(m0, uint8_t *);
1555
1556
1557 *hdr = RFCOMM_MKADDRESS((IS_INITIATOR(rs) ? 1 : 0),
1558 (dlc ? dlc->rd_dlci : 0));
1559 fcs = FCS(0xff, *hdr);
1560 hdr++;
1561
1562
1563 *hdr = RFCOMM_MKCONTROL(RFCOMM_FRAME_UIH, (credits > 0 ? 1 : 0));
1564 fcs = FCS(fcs, *hdr);
1565 hdr++;
1566
1567 if (len < (1 << 7)) {
1568 *hdr++ = ((len << 1) & 0xfe) | 0x01;
1569 } else {
1570 *hdr++ = ((len << 1) & 0xfe);
1571 *hdr++ = ((len >> 7) & 0xff);
1572 }
1573
1574 if (credits > 0)
1575 *hdr++ = (uint8_t)credits;
1576
1577 m0->m_len = hdr - mtod(m0, uint8_t *);
1578
1579
1580 m0->m_next = m;
1581 m = NULL;
1582
1583 m0->m_pkthdr.len = m0->m_len + len;
1584
1585
1586 fcs = 0xff - fcs;
1587 len = m0->m_pkthdr.len;
1588 m_copyback(m0, len, sizeof(fcs), &fcs);
1589 if (m0->m_pkthdr.len != len + sizeof(fcs))
1590 goto nomem;
1591
1592 DPRINTFN(10, "dlci %d, pktlen %d (%d data, %d credits), fcs=%#2.2x\n",
1593 dlc ? dlc->rd_dlci : 0, m0->m_pkthdr.len, credit->rc_len,
1594 credits, fcs);
1595
1596
1597
1598
1599 err = l2cap_send(rs->rs_l2cap, m0);
1600 if (err)
1601 goto fail;
1602
1603 SIMPLEQ_INSERT_TAIL(&rs->rs_credits, credit, rc_next);
1604 return 0;
1605
1606 nomem:
1607 err = ENOMEM;
1608
1609 if (m0 != NULL)
1610 m_freem(m0);
1611
1612 if (m != NULL)
1613 m_freem(m);
1614
1615 fail:
1616 if (credit != NULL)
1617 pool_put(&rfcomm_credit_pool, credit);
1618
1619 return err;
1620 }
1621
1622
1623
1624
1625 int
1626 rfcomm_session_send_mcc(struct rfcomm_session *rs, int cr,
1627 uint8_t type, void *data, int len)
1628 {
1629 struct mbuf *m;
1630 uint8_t *hdr;
1631 int hlen;
1632
1633 m = m_gethdr(M_DONTWAIT, MT_DATA);
1634 if (m == NULL)
1635 return ENOMEM;
1636
1637 hdr = mtod(m, uint8_t *);
1638
1639
1640
1641
1642
1643 *hdr++ = RFCOMM_MKMCC_TYPE(cr, type);
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654 if (len < (1 << 7)) {
1655 *hdr++ = ((len << 1) & 0xfe) | 0x01;
1656 } else if (len < (1 << 14)) {
1657 *hdr++ = ((len << 1) & 0xfe);
1658 *hdr++ = ((len >> 6) & 0xfe) | 0x01;
1659 } else if (len < (1 << 15)) {
1660 *hdr++ = ((len << 1) & 0xfe);
1661 *hdr++ = ((len >> 6) & 0xfe);
1662 *hdr++ = ((len >> 13) & 0x02) | 0x01;
1663 } else {
1664 DPRINTF("incredible length! (%d)\n", len);
1665 m_freem(m);
1666 return EMSGSIZE;
1667 }
1668
1669
1670
1671
1672 hlen = hdr - mtod(m, uint8_t *);
1673
1674 if (len > 0) {
1675 m->m_pkthdr.len = m->m_len = MHLEN;
1676 m_copyback(m, hlen, len, data);
1677 if (m->m_pkthdr.len != max(MHLEN, hlen + len)) {
1678 m_freem(m);
1679 return ENOMEM;
1680 }
1681 }
1682
1683 m->m_pkthdr.len = hlen + len;
1684 m->m_len = min(MHLEN, m->m_pkthdr.len);
1685
1686 DPRINTFN(5, "%s type %2.2x len %d\n",
1687 (cr ? "command" : "response"), type, m->m_pkthdr.len);
1688
1689 return rfcomm_session_send_uih(rs, NULL, 0, m);
1690 }