CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/hcitools/monitor/l2cap.c
Views: 3959
1
/*
2
*
3
* BlueZ - Bluetooth protocol stack for Linux
4
*
5
* Copyright (C) 2011-2012 Intel Corporation
6
* Copyright (C) 2004-2010 Marcel Holtmann <[email protected]>
7
*
8
*
9
* This program is free software; you can redistribute it and/or modify
10
* it under the terms of the GNU General Public License as published by
11
* the Free Software Foundation; either version 2 of the License, or
12
* (at your option) any later version.
13
*
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
18
*
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
*
23
*/
24
25
#ifdef HAVE_CONFIG_H
26
#include <config.h>
27
#endif
28
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <inttypes.h>
32
33
#include <bluetooth/bluetooth.h>
34
35
#include "bt.h"
36
#include "packet.h"
37
#include "display.h"
38
#include "l2cap.h"
39
#include "uuid.h"
40
#include "sdp.h"
41
42
#define MAX_CHAN 64
43
44
struct chan_data {
45
uint16_t index;
46
uint16_t handle;
47
uint16_t scid;
48
uint16_t dcid;
49
uint16_t psm;
50
uint8_t ctrlid;
51
uint8_t mode;
52
};
53
54
static struct chan_data chan_list[MAX_CHAN];
55
56
static void assign_scid(const struct l2cap_frame *frame,
57
uint16_t scid, uint16_t psm, uint8_t ctrlid)
58
{
59
int i, n = -1;
60
61
for (i = 0; i < MAX_CHAN; i++) {
62
if (n < 0 && chan_list[i].handle == 0x0000)
63
n = i;
64
65
if (chan_list[i].index != frame->index)
66
continue;
67
68
if (chan_list[i].handle != frame->handle)
69
continue;
70
71
if (frame->in) {
72
if (chan_list[i].dcid == scid) {
73
n = i;
74
break;
75
}
76
} else {
77
if (chan_list[i].scid == scid) {
78
n = i;
79
break;
80
}
81
}
82
}
83
84
if (n < 0)
85
return;
86
87
memset(&chan_list[n], 0, sizeof(chan_list[n]));
88
chan_list[n].index = frame->index;
89
chan_list[n].handle = frame->handle;
90
91
if (frame->in)
92
chan_list[n].dcid = scid;
93
else
94
chan_list[n].scid = scid;
95
96
chan_list[n].psm = psm;
97
chan_list[n].ctrlid = ctrlid;
98
chan_list[n].mode = 0;
99
}
100
101
static void release_scid(const struct l2cap_frame *frame, uint16_t scid)
102
{
103
int i;
104
105
for (i = 0; i < MAX_CHAN; i++) {
106
if (chan_list[i].index != frame->index)
107
continue;
108
109
if (chan_list[i].handle != frame->handle)
110
continue;
111
112
if (frame->in) {
113
if (chan_list[i].scid == scid) {
114
chan_list[i].handle = 0;
115
break;
116
}
117
} else {
118
if (chan_list[i].dcid == scid) {
119
chan_list[i].handle = 0;
120
break;
121
}
122
}
123
}
124
}
125
126
static void assign_dcid(const struct l2cap_frame *frame,
127
uint16_t dcid, uint16_t scid)
128
{
129
int i;
130
131
for (i = 0; i < MAX_CHAN; i++) {
132
if (chan_list[i].index != frame->index)
133
continue;
134
135
if (chan_list[i].handle != frame->handle)
136
continue;
137
138
if (frame->in) {
139
if (chan_list[i].scid == scid) {
140
chan_list[i].dcid = dcid;
141
break;
142
}
143
} else {
144
if (chan_list[i].dcid == scid) {
145
chan_list[i].scid = dcid;
146
break;
147
}
148
}
149
}
150
}
151
152
static void assign_mode(const struct l2cap_frame *frame,
153
uint8_t mode, uint16_t dcid)
154
{
155
int i;
156
157
for (i = 0; i < MAX_CHAN; i++) {
158
if (chan_list[i].index != frame->index)
159
continue;
160
161
if (chan_list[i].handle != frame->handle)
162
continue;
163
164
if (frame->in) {
165
if (chan_list[i].scid == dcid) {
166
chan_list[i].mode = mode;
167
break;
168
}
169
} else {
170
if (chan_list[i].dcid == dcid) {
171
chan_list[i].mode = mode;
172
break;
173
}
174
}
175
}
176
}
177
178
static uint16_t get_psm(const struct l2cap_frame *frame)
179
{
180
int i;
181
182
for (i = 0; i < MAX_CHAN; i++) {
183
if (chan_list[i].index != frame->index &&
184
chan_list[i].ctrlid == 0)
185
continue;
186
187
if (chan_list[i].handle != frame->handle &&
188
chan_list[i].ctrlid != frame->index)
189
continue;
190
191
if (frame->in) {
192
if (chan_list[i].scid == frame->cid)
193
return chan_list[i].psm;
194
} else {
195
if (chan_list[i].dcid == frame->cid)
196
return chan_list[i].psm;
197
}
198
}
199
200
return 0;
201
}
202
203
static uint8_t get_mode(const struct l2cap_frame *frame)
204
{
205
int i;
206
207
for (i = 0; i < MAX_CHAN; i++) {
208
if (chan_list[i].index != frame->index &&
209
chan_list[i].ctrlid == 0)
210
continue;
211
212
if (chan_list[i].handle != frame->handle &&
213
chan_list[i].ctrlid != frame->index)
214
continue;
215
216
if (frame->in) {
217
if (chan_list[i].scid == frame->cid)
218
return chan_list[i].mode;
219
} else {
220
if (chan_list[i].dcid == frame->cid)
221
return chan_list[i].mode;
222
}
223
}
224
225
return 0;
226
}
227
228
static uint16_t get_chan(const struct l2cap_frame *frame)
229
{
230
int i;
231
232
for (i = 0; i < MAX_CHAN; i++) {
233
if (chan_list[i].index != frame->index &&
234
chan_list[i].ctrlid == 0)
235
continue;
236
237
if (chan_list[i].handle != frame->handle &&
238
chan_list[i].ctrlid != frame->index)
239
continue;
240
241
if (frame->in) {
242
if (chan_list[i].scid == frame->cid)
243
return i;
244
} else {
245
if (chan_list[i].dcid == frame->cid)
246
return i;
247
}
248
}
249
250
return 0;
251
}
252
253
#define MAX_INDEX 16
254
255
struct index_data {
256
void *frag_buf;
257
uint16_t frag_pos;
258
uint16_t frag_len;
259
uint16_t frag_cid;
260
};
261
262
static struct index_data index_list[MAX_INDEX];
263
264
static void clear_fragment_buffer(uint16_t index)
265
{
266
free(index_list[index].frag_buf);
267
index_list[index].frag_buf = NULL;
268
index_list[index].frag_pos = 0;
269
index_list[index].frag_len = 0;
270
}
271
272
static void print_psm(uint16_t psm)
273
{
274
print_field("PSM: %d (0x%4.4x)", btohs(psm), btohs(psm));
275
}
276
277
static void print_cid(const char *type, uint16_t cid)
278
{
279
print_field("%s CID: %d", type, btohs(cid));
280
}
281
282
static void print_reject_reason(uint16_t reason)
283
{
284
const char *str;
285
286
switch (btohs(reason)) {
287
case 0x0000:
288
str = "Command not understood";
289
break;
290
case 0x0001:
291
str = "Signaling MTU exceeded";
292
break;
293
case 0x0002:
294
str = "Invalid CID in request";
295
break;
296
default:
297
str = "Reserved";
298
break;
299
}
300
301
print_field("Reason: %s (0x%4.4x)", str, btohs(reason));
302
}
303
304
static void print_conn_result(uint16_t result)
305
{
306
const char *str;
307
308
switch (btohs(result)) {
309
case 0x0000:
310
str = "Connection successful";
311
break;
312
case 0x0001:
313
str = "Connection pending";
314
break;
315
case 0x0002:
316
str = "Connection refused - PSM not supported";
317
break;
318
case 0x0003:
319
str = "Connection refused - security block";
320
break;
321
case 0x0004:
322
str = "Connection refused - no resources available";
323
break;
324
default:
325
str = "Reserved";
326
break;
327
}
328
329
print_field("Result: %s (0x%4.4x)", str, btohs(result));
330
}
331
332
static void print_conn_status(uint16_t status)
333
{
334
const char *str;
335
336
switch (btohs(status)) {
337
case 0x0000:
338
str = "No further information available";
339
break;
340
case 0x0001:
341
str = "Authentication pending";
342
break;
343
case 0x0002:
344
str = "Authorization pending";
345
break;
346
default:
347
str = "Reserved";
348
break;
349
}
350
351
print_field("Status: %s (0x%4.4x)", str, btohs(status));
352
}
353
354
static void print_config_flags(uint16_t flags)
355
{
356
const char *str;
357
358
if (btohs(flags) & 0x0001)
359
str = " (continuation)";
360
else
361
str = "";
362
363
print_field("Flags: 0x%4.4x%s", btohs(flags), str);
364
}
365
366
static void print_config_result(uint16_t result)
367
{
368
const char *str;
369
370
switch (btohs(result)) {
371
case 0x0000:
372
str = "Success";
373
break;
374
case 0x0001:
375
str = "Failure - unacceptable parameters";
376
break;
377
case 0x0002:
378
str = "Failure - rejected";
379
break;
380
case 0x0003:
381
str = "Failure - unknown options";
382
break;
383
case 0x0004:
384
str = "Pending";
385
break;
386
case 0x0005:
387
str = "Failure - flow spec rejected";
388
break;
389
default:
390
str = "Reserved";
391
break;
392
}
393
394
print_field("Result: %s (0x%4.4x)", str, btohs(result));
395
}
396
397
static struct {
398
uint8_t type;
399
uint8_t len;
400
const char *str;
401
} options_table[] = {
402
{ 0x01, 2, "Maximum Transmission Unit" },
403
{ 0x02, 2, "Flush Timeout" },
404
{ 0x03, 22, "Quality of Service" },
405
{ 0x04, 9, "Retransmission and Flow Control" },
406
{ 0x05, 1, "Frame Check Sequence" },
407
{ 0x06, 16, "Extended Flow Specification" },
408
{ 0x07, 2, "Extended Window Size" },
409
{ }
410
};
411
412
static void print_config_options(const struct l2cap_frame *frame,
413
uint8_t offset, uint16_t dcid, bool response)
414
{
415
const uint8_t *data = frame->data + offset;
416
uint16_t size = frame->size - offset;
417
uint16_t consumed = 0;
418
419
while (consumed < size - 2) {
420
const char *str = "Unknown";
421
uint8_t type = data[consumed];
422
uint8_t len = data[consumed + 1];
423
uint8_t expect_len = 0;
424
int i;
425
426
for (i = 0; options_table[i].str; i++) {
427
if (options_table[i].type == type) {
428
str = options_table[i].str;
429
expect_len = options_table[i].len;
430
break;
431
}
432
}
433
434
print_field("Option: %s (0x%2.2x)", str, type);
435
436
if (expect_len == 0) {
437
consumed += 2;
438
break;
439
}
440
441
if (len != expect_len) {
442
print_text(COLOR_ERROR, "wrong option size (%d != %d)",
443
len, expect_len);
444
consumed += 2;
445
break;
446
}
447
448
switch (type) {
449
case 0x01:
450
print_field(" MTU: %d",
451
bt_get_le16(data + consumed + 2));
452
break;
453
case 0x02:
454
print_field(" Flush timeout: %d",
455
bt_get_le16(data + consumed + 2));
456
break;
457
case 0x03:
458
switch (data[consumed + 3]) {
459
case 0x00:
460
str = "No Traffic";
461
break;
462
case 0x01:
463
str = "Best Effort";
464
break;
465
case 0x02:
466
str = "Guaranteed";
467
break;
468
default:
469
str = "Reserved";
470
break;
471
}
472
print_field(" Flags: 0x%2.2x", data[consumed + 2]);
473
print_field(" Service type: %s (0x%2.2x)",
474
str, data[consumed + 3]);
475
print_field(" Token rate: 0x%8.8x",
476
bt_get_le32(data + consumed + 4));
477
print_field(" Token bucket size: 0x%8.8x",
478
bt_get_le32(data + consumed + 8));
479
print_field(" Peak bandwidth: 0x%8.8x",
480
bt_get_le32(data + consumed + 12));
481
print_field(" Latency: 0x%8.8x",
482
bt_get_le32(data + consumed + 16));
483
print_field(" Delay variation: 0x%8.8x",
484
bt_get_le32(data + consumed + 20));
485
break;
486
case 0x04:
487
if (response)
488
assign_mode(frame, data[consumed + 2], dcid);
489
490
switch (data[consumed + 2]) {
491
case 0x00:
492
str = "Basic";
493
break;
494
case 0x01:
495
str = "Retransmission";
496
break;
497
case 0x02:
498
str = "Flow control";
499
break;
500
case 0x03:
501
str = "Enhanced retransmission";
502
break;
503
case 0x04:
504
str = "Streaming";
505
break;
506
default:
507
str = "Reserved";
508
break;
509
}
510
print_field(" Mode: %s (0x%2.2x)",
511
str, data[consumed + 2]);
512
print_field(" TX window size: %d", data[consumed + 3]);
513
print_field(" Max transmit: %d", data[consumed + 4]);
514
print_field(" Retransmission timeout: %d",
515
bt_get_le16(data + consumed + 5));
516
print_field(" Monitor timeout: %d",
517
bt_get_le16(data + consumed + 7));
518
print_field(" Maximum PDU size: %d",
519
bt_get_le16(data + consumed + 9));
520
break;
521
case 0x05:
522
switch (data[consumed + 2]) {
523
case 0x00:
524
str = "No FCS";
525
break;
526
case 0x01:
527
str = "16-bit FCS";
528
break;
529
default:
530
str = "Reserved";
531
break;
532
}
533
print_field(" FCS: %s (0x%2.2d)",
534
str, data[consumed + 2]);
535
break;
536
case 0x06:
537
switch (data[consumed + 3]) {
538
case 0x00:
539
str = "No traffic";
540
break;
541
case 0x01:
542
str = "Best effort";
543
break;
544
case 0x02:
545
str = "Guaranteed";
546
break;
547
default:
548
str = "Reserved";
549
break;
550
}
551
print_field(" Identifier: 0x%2.2x",
552
data[consumed + 2]);
553
print_field(" Service type: %s (0x%2.2x)",
554
str, data[consumed + 3]);
555
print_field(" Maximum SDU size: 0x%4.4x",
556
bt_get_le16(data + consumed + 4));
557
print_field(" SDU inter-arrival time: 0x%8.8x",
558
bt_get_le32(data + consumed + 6));
559
print_field(" Access latency: 0x%8.8x",
560
bt_get_le32(data + consumed + 10));
561
print_field(" Flush timeout: 0x%8.8x",
562
bt_get_le32(data + consumed + 14));
563
break;
564
case 0x07:
565
print_field(" Max window size: %d",
566
bt_get_le16(data + consumed + 2));
567
break;
568
default:
569
packet_hexdump(data + consumed + 2, len);
570
break;
571
}
572
573
consumed += len + 2;
574
}
575
576
if (consumed < size)
577
packet_hexdump(data + consumed, size - consumed);
578
}
579
580
static void print_info_type(uint16_t type)
581
{
582
const char *str;
583
584
switch (btohs(type)) {
585
case 0x0001:
586
str = "Connectionless MTU";
587
break;
588
case 0x0002:
589
str = "Extended features supported";
590
break;
591
case 0x0003:
592
str = "Fixed channels supported";
593
break;
594
default:
595
str = "Reserved";
596
break;
597
}
598
599
print_field("Type: %s (0x%4.4x)", str, btohs(type));
600
}
601
602
static void print_info_result(uint16_t result)
603
{
604
const char *str;
605
606
switch (btohs(result)) {
607
case 0x0000:
608
str = "Success";
609
break;
610
case 0x0001:
611
str = "Not supported";
612
break;
613
default:
614
str = "Reserved";
615
break;
616
}
617
618
print_field("Result: %s (0x%4.4x)", str, btohs(result));
619
}
620
621
static struct {
622
uint8_t bit;
623
const char *str;
624
} features_table[] = {
625
{ 0, "Flow control mode" },
626
{ 1, "Retransmission mode" },
627
{ 2, "Bi-directional QoS" },
628
{ 3, "Enhanced Retransmission Mode" },
629
{ 4, "Streaming Mode" },
630
{ 5, "FCS Option" },
631
{ 6, "Extended Flow Specification for BR/EDR" },
632
{ 7, "Fixed Channels" },
633
{ 8, "Extended Window Size" },
634
{ 9, "Unicast Connectionless Data Reception" },
635
{ 31, "Reserved for feature mask extension" },
636
{ }
637
};
638
639
static void print_features(uint32_t features)
640
{
641
uint32_t mask = features;
642
int i;
643
644
print_field("Features: 0x%8.8x", features);
645
646
for (i = 0; features_table[i].str; i++) {
647
if (features & (1 << features_table[i].bit)) {
648
print_field(" %s", features_table[i].str);
649
mask &= ~(1 << features_table[i].bit);
650
}
651
}
652
653
if (mask)
654
print_field(" Unknown features (0x%8.8x)", mask);
655
}
656
657
static struct {
658
uint16_t cid;
659
const char *str;
660
} channels_table[] = {
661
{ 0x0000, "Null identifier" },
662
{ 0x0001, "L2CAP Signaling (BR/EDR)" },
663
{ 0x0002, "Connectionless reception" },
664
{ 0x0003, "AMP Manager Protocol" },
665
{ 0x0004, "Attribute Protocol" },
666
{ 0x0005, "L2CAP Signaling (LE)" },
667
{ 0x0006, "Security Manager" },
668
{ 0x003f, "AMP Test Manager" },
669
{ }
670
};
671
672
static void print_channels(uint64_t channels)
673
{
674
uint64_t mask = channels;
675
int i;
676
677
print_field("Channels: 0x%16.16" PRIx64, channels);
678
679
for (i = 0; channels_table[i].str; i++) {
680
if (channels & (1 << channels_table[i].cid)) {
681
print_field(" %s", channels_table[i].str);
682
mask &= ~(1 << channels_table[i].cid);
683
}
684
}
685
686
if (mask)
687
print_field(" Unknown channels (0x%8.8" PRIx64 ")", mask);
688
}
689
690
static void print_move_result(uint16_t result)
691
{
692
const char *str;
693
694
switch (btohs(result)) {
695
case 0x0000:
696
str = "Move success";
697
break;
698
case 0x0001:
699
str = "Move pending";
700
break;
701
case 0x0002:
702
str = "Move refused - Controller ID not supported";
703
break;
704
case 0x0003:
705
str = "Move refused - new Controller ID is same";
706
break;
707
case 0x0004:
708
str = "Move refused - Configuration not supported";
709
break;
710
case 0x0005:
711
str = "Move refused - Move Channel collision";
712
break;
713
case 0x0006:
714
str = "Move refused - Channel not allowed to be moved";
715
break;
716
default:
717
str = "Reserved";
718
break;
719
}
720
721
print_field("Result: %s (0x%4.4x)", str, btohs(result));
722
}
723
724
static void print_move_cfm_result(uint16_t result)
725
{
726
const char *str;
727
728
switch (btohs(result)) {
729
case 0x0000:
730
str = "Move success - both sides succeed";
731
break;
732
case 0x0001:
733
str = "Move failure - one or both sides refuse";
734
break;
735
default:
736
str = "Reserved";
737
break;
738
}
739
740
print_field("Result: %s (0x%4.4x)", str, btohs(result));
741
}
742
743
static void print_conn_param_result(uint16_t result)
744
{
745
const char *str;
746
747
switch (btohs(result)) {
748
case 0x0000:
749
str = "Connection Parameters accepted";
750
break;
751
case 0x0001:
752
str = "Connection Parameters rejected";
753
break;
754
default:
755
str = "Reserved";
756
break;
757
}
758
759
print_field("Result: %s (0x%4.4x)", str, btohs(result));
760
}
761
762
static void sig_cmd_reject(const struct l2cap_frame *frame)
763
{
764
const struct bt_l2cap_pdu_cmd_reject *pdu = frame->data;
765
const void *data = frame->data;
766
uint16_t size = frame->size;
767
uint16_t scid, dcid;
768
769
print_reject_reason(pdu->reason);
770
771
data += sizeof(*pdu);
772
size -= sizeof(*pdu);
773
774
switch (btohs(pdu->reason)) {
775
case 0x0000:
776
if (size != 0) {
777
print_text(COLOR_ERROR, "invalid data size");
778
packet_hexdump(data, size);
779
break;
780
}
781
break;
782
case 0x0001:
783
if (size != 2) {
784
print_text(COLOR_ERROR, "invalid data size");
785
packet_hexdump(data, size);
786
break;
787
}
788
print_field("MTU: %d", bt_get_le16(data));
789
break;
790
case 0x0002:
791
if (size != 4) {
792
print_text(COLOR_ERROR, "invalid data size");
793
packet_hexdump(data, size);
794
break;
795
}
796
dcid = bt_get_le16(data);
797
scid = bt_get_le16(data + 2);
798
print_cid("Destination", htobs(dcid));
799
print_cid("Source", htobs(scid));
800
break;
801
default:
802
packet_hexdump(data, size);
803
break;
804
}
805
}
806
807
static void sig_conn_req(const struct l2cap_frame *frame)
808
{
809
const struct bt_l2cap_pdu_conn_req *pdu = frame->data;
810
811
print_psm(pdu->psm);
812
print_cid("Source", pdu->scid);
813
814
assign_scid(frame, btohs(pdu->scid), btohs(pdu->psm), 0);
815
}
816
817
static void sig_conn_rsp(const struct l2cap_frame *frame)
818
{
819
const struct bt_l2cap_pdu_conn_rsp *pdu = frame->data;
820
821
print_cid("Destination", pdu->dcid);
822
print_cid("Source", pdu->scid);
823
print_conn_result(pdu->result);
824
print_conn_status(pdu->status);
825
826
assign_dcid(frame, btohs(pdu->dcid), btohs(pdu->scid));
827
}
828
829
static void sig_config_req(const struct l2cap_frame *frame)
830
{
831
const struct bt_l2cap_pdu_config_req *pdu = frame->data;
832
833
print_cid("Destination", pdu->dcid);
834
print_config_flags(pdu->flags);
835
print_config_options(frame, 4, btohs(pdu->dcid), false);
836
}
837
838
static void sig_config_rsp(const struct l2cap_frame *frame)
839
{
840
const struct bt_l2cap_pdu_config_rsp *pdu = frame->data;
841
842
print_cid("Source", pdu->scid);
843
print_config_flags(pdu->flags);
844
print_config_result(pdu->result);
845
print_config_options(frame, 6, btohs(pdu->scid), true);
846
}
847
848
static void sig_disconn_req(const struct l2cap_frame *frame)
849
{
850
const struct bt_l2cap_pdu_disconn_req *pdu = frame->data;
851
852
print_cid("Destination", pdu->dcid);
853
print_cid("Source", pdu->scid);
854
}
855
856
static void sig_disconn_rsp(const struct l2cap_frame *frame)
857
{
858
const struct bt_l2cap_pdu_disconn_rsp *pdu = frame->data;
859
860
print_cid("Destination", pdu->dcid);
861
print_cid("Source", pdu->scid);
862
863
release_scid(frame, btohs(pdu->scid));
864
}
865
866
static void sig_echo_req(const struct l2cap_frame *frame)
867
{
868
packet_hexdump(frame->data, frame->size);
869
}
870
871
static void sig_echo_rsp(const struct l2cap_frame *frame)
872
{
873
packet_hexdump(frame->data, frame->size);
874
}
875
876
static void sig_info_req(const struct l2cap_frame *frame)
877
{
878
const struct bt_l2cap_pdu_info_req *pdu = frame->data;
879
880
print_info_type(pdu->type);
881
}
882
883
static void sig_info_rsp(const struct l2cap_frame *frame)
884
{
885
const struct bt_l2cap_pdu_info_rsp *pdu = frame->data;
886
const void *data = frame->data;
887
uint16_t size = frame->size;
888
889
print_info_type(pdu->type);
890
print_info_result(pdu->result);
891
892
data += sizeof(*pdu);
893
size -= sizeof(*pdu);
894
895
if (btohs(pdu->result) != 0x0000) {
896
if (size > 0) {
897
print_text(COLOR_ERROR, "invalid data size");
898
packet_hexdump(data, size);
899
}
900
return;
901
}
902
903
switch (btohs(pdu->type)) {
904
case 0x0001:
905
if (size != 2) {
906
print_text(COLOR_ERROR, "invalid data size");
907
packet_hexdump(data, size);
908
break;
909
}
910
print_field("MTU: %d", bt_get_le16(data));
911
break;
912
case 0x0002:
913
if (size != 4) {
914
print_text(COLOR_ERROR, "invalid data size");
915
packet_hexdump(data, size);
916
break;
917
}
918
print_features(bt_get_le32(data));
919
break;
920
case 0x0003:
921
if (size != 8) {
922
print_text(COLOR_ERROR, "invalid data size");
923
packet_hexdump(data, size);
924
break;
925
}
926
print_channels(bt_get_le64(data));
927
break;
928
default:
929
packet_hexdump(data, size);
930
break;
931
}
932
}
933
934
static void sig_create_chan_req(const struct l2cap_frame *frame)
935
{
936
const struct bt_l2cap_pdu_create_chan_req *pdu = frame->data;
937
938
print_psm(pdu->psm);
939
print_cid("Source", pdu->scid);
940
print_field("Controller ID: %d", pdu->ctrlid);
941
942
assign_scid(frame, btohs(pdu->scid), btohs(pdu->psm), pdu->ctrlid);
943
}
944
945
static void sig_create_chan_rsp(const struct l2cap_frame *frame)
946
{
947
const struct bt_l2cap_pdu_create_chan_rsp *pdu = frame->data;
948
949
print_cid("Destination", pdu->dcid);
950
print_cid("Source", pdu->scid);
951
print_conn_result(pdu->result);
952
print_conn_status(pdu->status);
953
954
assign_dcid(frame, btohs(pdu->dcid), btohs(pdu->scid));
955
}
956
957
static void sig_move_chan_req(const struct l2cap_frame *frame)
958
{
959
const struct bt_l2cap_pdu_move_chan_req *pdu = frame->data;
960
961
print_cid("Initiator", pdu->icid);
962
print_field("Controller ID: %d", pdu->ctrlid);
963
}
964
965
static void sig_move_chan_rsp(const struct l2cap_frame *frame)
966
{
967
const struct bt_l2cap_pdu_move_chan_rsp *pdu = frame->data;
968
969
print_cid("Initiator", pdu->icid);
970
print_move_result(pdu->result);
971
}
972
973
static void sig_move_chan_cfm(const struct l2cap_frame *frame)
974
{
975
const struct bt_l2cap_pdu_move_chan_cfm *pdu = frame->data;
976
977
print_cid("Initiator", pdu->icid);
978
print_move_cfm_result(pdu->result);
979
}
980
981
static void sig_move_chan_cfm_rsp(const struct l2cap_frame *frame)
982
{
983
const struct bt_l2cap_pdu_move_chan_cfm_rsp *pdu = frame->data;
984
985
print_cid("Initiator", pdu->icid);
986
}
987
988
static void sig_conn_param_req(const struct l2cap_frame *frame)
989
{
990
const struct bt_l2cap_pdu_conn_param_req *pdu = frame->data;
991
992
print_field("Min interval: %d", btohs(pdu->min_interval));
993
print_field("Max interval: %d", btohs(pdu->max_interval));
994
print_field("Slave latency: %d", btohs(pdu->latency));
995
print_field("Timeout multiplier: %d", btohs(pdu->timeout));
996
}
997
998
static void sig_conn_param_rsp(const struct l2cap_frame *frame)
999
{
1000
const struct bt_l2cap_pdu_conn_param_rsp *pdu = frame->data;
1001
1002
print_conn_param_result(pdu->result);
1003
}
1004
1005
struct sig_opcode_data {
1006
uint8_t opcode;
1007
const char *str;
1008
void (*func) (const struct l2cap_frame *frame);
1009
uint16_t size;
1010
bool fixed;
1011
};
1012
1013
static const struct sig_opcode_data bredr_sig_opcode_table[] = {
1014
{ 0x01, "Command Reject",
1015
sig_cmd_reject, 2, false },
1016
{ 0x02, "Connection Request",
1017
sig_conn_req, 4, true },
1018
{ 0x03, "Connection Response",
1019
sig_conn_rsp, 8, true },
1020
{ 0x04, "Configure Request",
1021
sig_config_req, 4, false },
1022
{ 0x05, "Configure Response",
1023
sig_config_rsp, 6, false },
1024
{ 0x06, "Disconnection Request",
1025
sig_disconn_req, 4, true },
1026
{ 0x07, "Disconnection Response",
1027
sig_disconn_rsp, 4, true },
1028
{ 0x08, "Echo Request",
1029
sig_echo_req, 0, false },
1030
{ 0x09, "Echo Response",
1031
sig_echo_rsp, 0, false },
1032
{ 0x0a, "Information Request",
1033
sig_info_req, 2, true },
1034
{ 0x0b, "Information Response",
1035
sig_info_rsp, 4, false },
1036
{ 0x0c, "Create Channel Request",
1037
sig_create_chan_req, 5, true },
1038
{ 0x0d, "Create Channel Response",
1039
sig_create_chan_rsp, 8, true },
1040
{ 0x0e, "Move Channel Request",
1041
sig_move_chan_req, 3, true },
1042
{ 0x0f, "Move Channel Response",
1043
sig_move_chan_rsp, 4, true },
1044
{ 0x10, "Move Channel Confirmation",
1045
sig_move_chan_cfm, 4, true },
1046
{ 0x11, "Move Channel Confirmation Response",
1047
sig_move_chan_cfm_rsp, 2, true },
1048
{ },
1049
};
1050
1051
static const struct sig_opcode_data le_sig_opcode_table[] = {
1052
{ 0x01, "Command Reject",
1053
sig_cmd_reject, 2, false },
1054
{ 0x12, "Connection Parameter Update Request",
1055
sig_conn_param_req, 8, true },
1056
{ 0x13, "Connection Parameter Update Response",
1057
sig_conn_param_rsp, 2, true },
1058
{ },
1059
};
1060
1061
static void bredr_sig_packet(uint16_t index, bool in, uint16_t handle,
1062
uint16_t cid, const void *data, uint16_t size)
1063
{
1064
struct l2cap_frame frame;
1065
1066
while (size > 0) {
1067
const struct bt_l2cap_hdr_sig *hdr = data;
1068
const struct sig_opcode_data *opcode_data = NULL;
1069
const char *opcode_color, *opcode_str;
1070
uint16_t len;
1071
int i;
1072
1073
if (size < 4) {
1074
print_text(COLOR_ERROR, "malformed signal packet");
1075
packet_hexdump(data, size);
1076
return;
1077
}
1078
1079
len = btohs(hdr->len);
1080
1081
data += 4;
1082
size -= 4;
1083
1084
if (size < len) {
1085
print_text(COLOR_ERROR, "invalid signal packet size");
1086
packet_hexdump(data, size);
1087
return;
1088
}
1089
1090
for (i = 0; bredr_sig_opcode_table[i].str; i++) {
1091
if (bredr_sig_opcode_table[i].opcode == hdr->code) {
1092
opcode_data = &bredr_sig_opcode_table[i];
1093
break;
1094
}
1095
}
1096
1097
if (opcode_data) {
1098
if (opcode_data->func) {
1099
if (in)
1100
opcode_color = COLOR_MAGENTA;
1101
else
1102
opcode_color = COLOR_BLUE;
1103
} else
1104
opcode_color = COLOR_WHITE_BG;
1105
opcode_str = opcode_data->str;
1106
} else {
1107
opcode_color = COLOR_WHITE_BG;
1108
opcode_str = "Unknown";
1109
}
1110
1111
print_indent(6, opcode_color, "L2CAP: ", opcode_str,
1112
COLOR_OFF,
1113
" (0x%2.2x) ident %d len %d",
1114
hdr->code, hdr->ident, len);
1115
1116
if (!opcode_data || !opcode_data->func) {
1117
packet_hexdump(data, len);
1118
data += len;
1119
size -= len;
1120
return;
1121
}
1122
1123
if (opcode_data->fixed) {
1124
if (len != opcode_data->size) {
1125
print_text(COLOR_ERROR, "invalid size");
1126
packet_hexdump(data, len);
1127
data += len;
1128
size -= len;
1129
continue;
1130
}
1131
} else {
1132
if (len < opcode_data->size) {
1133
print_text(COLOR_ERROR, "too short packet");
1134
packet_hexdump(data, size);
1135
data += len;
1136
size -= len;
1137
continue;
1138
}
1139
}
1140
1141
l2cap_frame_init(&frame, index, in, handle, cid, data, len);
1142
opcode_data->func(&frame);
1143
1144
data += len;
1145
size -= len;
1146
}
1147
1148
packet_hexdump(data, size);
1149
}
1150
1151
static void le_sig_packet(uint16_t index, bool in, uint16_t handle,
1152
uint16_t cid, const void *data, uint16_t size)
1153
{
1154
struct l2cap_frame frame;
1155
const struct bt_l2cap_hdr_sig *hdr = data;
1156
const struct sig_opcode_data *opcode_data = NULL;
1157
const char *opcode_color, *opcode_str;
1158
uint16_t len;
1159
int i;
1160
1161
if (size < 4) {
1162
print_text(COLOR_ERROR, "malformed signal packet");
1163
packet_hexdump(data, size);
1164
return;
1165
}
1166
1167
len = btohs(hdr->len);
1168
1169
data += 4;
1170
size -= 4;
1171
1172
if (size != len) {
1173
print_text(COLOR_ERROR, "invalid signal packet size");
1174
packet_hexdump(data, size);
1175
return;
1176
}
1177
1178
for (i = 0; le_sig_opcode_table[i].str; i++) {
1179
if (le_sig_opcode_table[i].opcode == hdr->code) {
1180
opcode_data = &le_sig_opcode_table[i];
1181
break;
1182
}
1183
}
1184
1185
if (opcode_data) {
1186
if (opcode_data->func) {
1187
if (in)
1188
opcode_color = COLOR_MAGENTA;
1189
else
1190
opcode_color = COLOR_BLUE;
1191
} else
1192
opcode_color = COLOR_WHITE_BG;
1193
opcode_str = opcode_data->str;
1194
} else {
1195
opcode_color = COLOR_WHITE_BG;
1196
opcode_str = "Unknown";
1197
}
1198
1199
print_indent(6, opcode_color, "LE L2CAP: ", opcode_str, COLOR_OFF,
1200
" (0x%2.2x) ident %d len %d",
1201
hdr->code, hdr->ident, len);
1202
1203
if (!opcode_data || !opcode_data->func) {
1204
packet_hexdump(data, len);
1205
return;
1206
}
1207
1208
if (opcode_data->fixed) {
1209
if (len != opcode_data->size) {
1210
print_text(COLOR_ERROR, "invalid size");
1211
packet_hexdump(data, len);
1212
return;
1213
}
1214
} else {
1215
if (len < opcode_data->size) {
1216
print_text(COLOR_ERROR, "too short packet");
1217
packet_hexdump(data, size);
1218
return;
1219
}
1220
}
1221
1222
l2cap_frame_init(&frame, index, in, handle, cid, data, len);
1223
opcode_data->func(&frame);
1224
}
1225
1226
static void connless_packet(uint16_t index, bool in, uint16_t handle,
1227
uint16_t cid, const void *data, uint16_t size)
1228
{
1229
struct l2cap_frame frame;
1230
const struct bt_l2cap_hdr_connless *hdr = data;
1231
uint16_t psm;
1232
1233
if (size < 2) {
1234
print_text(COLOR_ERROR, "malformed connectionless packet");
1235
packet_hexdump(data, size);
1236
return;
1237
}
1238
1239
psm = btohs(hdr->psm);
1240
1241
data += 2;
1242
size -= 2;
1243
1244
print_indent(6, COLOR_CYAN, "L2CAP: Connectionless", "", COLOR_OFF,
1245
" len %d [PSM %d]", size, psm);
1246
1247
switch (psm) {
1248
default:
1249
packet_hexdump(data, size);
1250
break;
1251
}
1252
1253
l2cap_frame_init(&frame, index, in, handle, cid, data, size);
1254
}
1255
1256
static void print_controller_list(const uint8_t *data, uint16_t size)
1257
{
1258
while (size > 2) {
1259
const char *str;
1260
1261
print_field("Controller ID: %d", data[0]);
1262
1263
switch (data[1]) {
1264
case 0x00:
1265
str = "Primary BR/EDR Controller";
1266
break;
1267
case 0x01:
1268
str = "802.11 AMP Controller";
1269
break;
1270
default:
1271
str = "Reserved";
1272
break;
1273
}
1274
1275
print_field(" Type: %s (0x%2.2x)", str, data[1]);
1276
1277
switch (data[2]) {
1278
case 0x00:
1279
str = "Present";
1280
break;
1281
case 0x01:
1282
str = "Bluetooth only";
1283
break;
1284
case 0x02:
1285
str = "No capacity";
1286
break;
1287
case 0x03:
1288
str = "Low capacity";
1289
break;
1290
case 0x04:
1291
str = "Medium capacity";
1292
break;
1293
case 0x05:
1294
str = "High capacity";
1295
break;
1296
case 0x06:
1297
str = "Full capacity";
1298
break;
1299
default:
1300
str = "Reserved";
1301
break;
1302
}
1303
1304
print_field(" Status: %s (0x%2.2x)", str, data[2]);
1305
1306
data += 3;
1307
size -= 3;
1308
}
1309
1310
packet_hexdump(data, size);
1311
}
1312
1313
static void amp_cmd_reject(const struct l2cap_frame *frame)
1314
{
1315
const struct bt_l2cap_amp_cmd_reject *pdu = frame->data;
1316
1317
print_field("Reason: 0x%4.4x", btohs(pdu->reason));
1318
}
1319
1320
static void amp_discover_req(const struct l2cap_frame *frame)
1321
{
1322
const struct bt_l2cap_amp_discover_req *pdu = frame->data;
1323
1324
print_field("MTU/MPS size: %d", btohs(pdu->size));
1325
print_field("Extended feature mask: 0x%4.4x", btohs(pdu->features));
1326
}
1327
1328
static void amp_discover_rsp(const struct l2cap_frame *frame)
1329
{
1330
const struct bt_l2cap_amp_discover_rsp *pdu = frame->data;
1331
1332
print_field("MTU/MPS size: %d", btohs(pdu->size));
1333
print_field("Extended feature mask: 0x%4.4x", btohs(pdu->features));
1334
1335
print_controller_list(frame->data + 4, frame->size - 4);
1336
}
1337
1338
static void amp_change_notify(const struct l2cap_frame *frame)
1339
{
1340
print_controller_list(frame->data, frame->size);
1341
}
1342
1343
static void amp_change_response(const struct l2cap_frame *frame)
1344
{
1345
}
1346
1347
static void amp_get_info_req(const struct l2cap_frame *frame)
1348
{
1349
const struct bt_l2cap_amp_get_info_req *pdu = frame->data;
1350
1351
print_field("Controller ID: %d", pdu->ctrlid);
1352
}
1353
1354
static void amp_get_info_rsp(const struct l2cap_frame *frame)
1355
{
1356
const struct bt_l2cap_amp_get_info_rsp *pdu = frame->data;
1357
const char *str;
1358
1359
print_field("Controller ID: %d", pdu->ctrlid);
1360
1361
switch (pdu->status) {
1362
case 0x00:
1363
str = "Success";
1364
break;
1365
case 0x01:
1366
str = "Invalid Controller ID";
1367
break;
1368
default:
1369
str = "Reserved";
1370
break;
1371
}
1372
1373
print_field("Status: %s (0x%2.2x)", str, pdu->status);
1374
1375
print_field("Total bandwidth: %d kbps", btohl(pdu->total_bw));
1376
print_field("Max guaranteed bandwidth: %d kbps", btohl(pdu->max_bw));
1377
print_field("Min latency: %d", btohl(pdu->min_latency));
1378
1379
print_field("PAL capabilities: 0x%4.4x", btohs(pdu->pal_cap));
1380
print_field("Max ASSOC length: %d", btohs(pdu->max_assoc_len));
1381
}
1382
1383
static void amp_get_assoc_req(const struct l2cap_frame *frame)
1384
{
1385
const struct bt_l2cap_amp_get_assoc_req *pdu = frame->data;
1386
1387
print_field("Controller ID: %d", pdu->ctrlid);
1388
}
1389
1390
static void amp_get_assoc_rsp(const struct l2cap_frame *frame)
1391
{
1392
const struct bt_l2cap_amp_get_assoc_rsp *pdu = frame->data;
1393
const char *str;
1394
1395
print_field("Controller ID: %d", pdu->ctrlid);
1396
1397
switch (pdu->status) {
1398
case 0x00:
1399
str = "Success";
1400
break;
1401
case 0x01:
1402
str = "Invalid Controller ID";
1403
break;
1404
default:
1405
str = "Reserved";
1406
break;
1407
}
1408
1409
print_field("Status: %s (0x%2.2x)", str, pdu->status);
1410
1411
packet_hexdump(frame->data + 2, frame->size - 2);
1412
}
1413
1414
static void amp_create_phy_link_req(const struct l2cap_frame *frame)
1415
{
1416
const struct bt_l2cap_amp_create_phy_link_req *pdu = frame->data;
1417
1418
print_field("Local controller ID: %d", pdu->local_ctrlid);
1419
print_field("Remote controller ID: %d", pdu->remote_ctrlid);
1420
1421
packet_hexdump(frame->data + 2, frame->size - 2);
1422
}
1423
1424
static void amp_create_phy_link_rsp(const struct l2cap_frame *frame)
1425
{
1426
const struct bt_l2cap_amp_create_phy_link_rsp *pdu = frame->data;
1427
const char *str;
1428
1429
print_field("Local controller ID: %d", pdu->local_ctrlid);
1430
print_field("Remote controller ID: %d", pdu->remote_ctrlid);
1431
1432
switch (pdu->status) {
1433
case 0x00:
1434
str = "Success";
1435
break;
1436
case 0x01:
1437
str = "Invalid Controller ID";
1438
break;
1439
case 0x02:
1440
str = "Failed - Unable to start link creation";
1441
break;
1442
case 0x03:
1443
str = "Failed - Collision occurred";
1444
break;
1445
case 0x04:
1446
str = "Failed - Disconnected link packet received";
1447
break;
1448
case 0x05:
1449
str = "Failed - Link already exists";
1450
break;
1451
case 0x06:
1452
str = "Failed - Security violation";
1453
break;
1454
default:
1455
str = "Reserved";
1456
break;
1457
}
1458
1459
print_field("Status: %s (0x%2.2x)", str, pdu->status);
1460
}
1461
1462
static void amp_disconn_phy_link_req(const struct l2cap_frame *frame)
1463
{
1464
const struct bt_l2cap_amp_disconn_phy_link_req *pdu = frame->data;
1465
1466
print_field("Local controller ID: %d", pdu->local_ctrlid);
1467
print_field("Remote controller ID: %d", pdu->remote_ctrlid);
1468
}
1469
1470
static void amp_disconn_phy_link_rsp(const struct l2cap_frame *frame)
1471
{
1472
const struct bt_l2cap_amp_disconn_phy_link_rsp *pdu = frame->data;
1473
const char *str;
1474
1475
print_field("Local controller ID: %d", pdu->local_ctrlid);
1476
print_field("Remote controller ID: %d", pdu->remote_ctrlid);
1477
1478
switch (pdu->status) {
1479
case 0x00:
1480
str = "Success";
1481
break;
1482
case 0x01:
1483
str = "Invalid Controller ID";
1484
break;
1485
case 0x02:
1486
str = "Failed - No link exists";
1487
break;
1488
default:
1489
str = "Reserved";
1490
break;
1491
}
1492
1493
print_field("Status: %s (0x%2.2x)", str, pdu->status);
1494
}
1495
1496
struct amp_opcode_data {
1497
uint8_t opcode;
1498
const char *str;
1499
void (*func) (const struct l2cap_frame *frame);
1500
uint16_t size;
1501
bool fixed;
1502
};
1503
1504
static const struct amp_opcode_data amp_opcode_table[] = {
1505
{ 0x01, "Command Reject",
1506
amp_cmd_reject, 2, false },
1507
{ 0x02, "Discover Request",
1508
amp_discover_req, 4, true },
1509
{ 0x03, "Discover Response",
1510
amp_discover_rsp, 7, false },
1511
{ 0x04, "Change Notify",
1512
amp_change_notify, 3, false },
1513
{ 0x05, "Change Response",
1514
amp_change_response, 0, true },
1515
{ 0x06, "Get Info Request",
1516
amp_get_info_req, 1, true },
1517
{ 0x07, "Get Info Response",
1518
amp_get_info_rsp, 18, true },
1519
{ 0x08, "Get Assoc Request",
1520
amp_get_assoc_req, 1, true },
1521
{ 0x09, "Get Assoc Response",
1522
amp_get_assoc_rsp, 2, false },
1523
{ 0x0a, "Create Physical Link Request",
1524
amp_create_phy_link_req, 2, false },
1525
{ 0x0b, "Create Physical Link Response",
1526
amp_create_phy_link_rsp, 3, true },
1527
{ 0x0c, "Disconnect Physical Link Request",
1528
amp_disconn_phy_link_req, 2, true },
1529
{ 0x0d, "Disconnect Physical Link Response",
1530
amp_disconn_phy_link_rsp, 3, true },
1531
{ },
1532
};
1533
1534
static void amp_packet(uint16_t index, bool in, uint16_t handle,
1535
uint16_t cid, const void *data, uint16_t size)
1536
{
1537
struct l2cap_frame frame;
1538
uint16_t control, fcs, len;
1539
uint8_t opcode, ident;
1540
const struct amp_opcode_data *opcode_data = NULL;
1541
const char *opcode_color, *opcode_str;
1542
int i;
1543
1544
if (size < 4) {
1545
print_text(COLOR_ERROR, "malformed info frame packet");
1546
packet_hexdump(data, size);
1547
return;
1548
}
1549
1550
control = bt_get_le16(data);
1551
fcs = bt_get_le16(data + size - 2);
1552
1553
print_indent(6, COLOR_CYAN, "Channel:", "", COLOR_OFF,
1554
" %d dlen %d control 0x%4.4x fcs 0x%4.4x",
1555
3, size, control, fcs);
1556
1557
if (control & 0x01)
1558
return;
1559
1560
if (size < 8) {
1561
print_text(COLOR_ERROR, "malformed manager packet");
1562
packet_hexdump(data, size);
1563
return;
1564
}
1565
1566
opcode = *((const uint8_t *) (data + 2));
1567
ident = *((const uint8_t *) (data + 3));
1568
len = bt_get_le16(data + 4);
1569
1570
if (len != size - 8) {
1571
print_text(COLOR_ERROR, "invalid manager packet size");
1572
packet_hexdump(data + 2, size - 4);
1573
return;
1574
}
1575
1576
for (i = 0; amp_opcode_table[i].str; i++) {
1577
if (amp_opcode_table[i].opcode == opcode) {
1578
opcode_data = &amp_opcode_table[i];
1579
break;
1580
}
1581
}
1582
1583
if (opcode_data) {
1584
if (opcode_data->func) {
1585
if (in)
1586
opcode_color = COLOR_MAGENTA;
1587
else
1588
opcode_color = COLOR_BLUE;
1589
} else
1590
opcode_color = COLOR_WHITE_BG;
1591
opcode_str = opcode_data->str;
1592
} else {
1593
opcode_color = COLOR_WHITE_BG;
1594
opcode_str = "Unknown";
1595
}
1596
1597
print_indent(6, opcode_color, "AMP: ", opcode_str, COLOR_OFF,
1598
" (0x%2.2x) ident %d len %d", opcode, ident, len);
1599
1600
if (!opcode_data || !opcode_data->func) {
1601
packet_hexdump(data + 6, size - 8);
1602
return;
1603
}
1604
1605
if (opcode_data->fixed) {
1606
if (len != opcode_data->size) {
1607
print_text(COLOR_ERROR, "invalid size");
1608
packet_hexdump(data + 6, size - 8);
1609
return;
1610
}
1611
} else {
1612
if (len < opcode_data->size) {
1613
print_text(COLOR_ERROR, "too short packet");
1614
packet_hexdump(data + 6, size - 8);
1615
return;
1616
}
1617
}
1618
1619
l2cap_frame_init(&frame, index, in, handle, cid, data + 6, len);
1620
opcode_data->func(&frame);
1621
}
1622
1623
static void print_hex_field(const char *label, const uint8_t *data,
1624
uint8_t len)
1625
{
1626
char str[len * 2 + 1];
1627
uint8_t i;
1628
1629
str[0] = '\0';
1630
1631
for (i = 0; i < len; i++)
1632
sprintf(str + (i * 2), "%2.2x", data[i]);
1633
1634
print_field("%s: %s", label, str);
1635
}
1636
1637
static void print_uuid(const char *label, const void *data, uint16_t size)
1638
{
1639
const char *str;
1640
1641
switch (size) {
1642
case 2:
1643
str = uuid16_to_str(bt_get_le16(data));
1644
print_field("%s: %s (0x%4.4x)", label, str, bt_get_le16(data));
1645
break;
1646
case 4:
1647
str = uuid32_to_str(bt_get_le32(data));
1648
print_field("%s: %s (0x%8.8x)", label, str, bt_get_le32(data));
1649
break;
1650
case 16:
1651
str = uuid128_to_str(data);
1652
print_field("%s: %s (%8.8x-%4.4x-%4.4x-%4.4x-%8.8x%4.4x)",
1653
label, str,
1654
bt_get_le32(data + 12), bt_get_le16(data + 10),
1655
bt_get_le16(data + 8), bt_get_le16(data + 6),
1656
bt_get_le32(data + 2), bt_get_le16(data + 0));
1657
break;
1658
default:
1659
packet_hexdump(data, size);
1660
break;
1661
}
1662
}
1663
1664
static void print_handle_range(const char *label, const void *data)
1665
{
1666
print_field("%s: 0x%4.4x-0x%4.4x", label,
1667
bt_get_le16(data), bt_get_le16(data + 2));
1668
}
1669
1670
static void print_data_list(const char *label, uint8_t length,
1671
const void *data, uint16_t size)
1672
{
1673
uint8_t count;
1674
1675
if (length == 0)
1676
return;
1677
1678
count = size / length;
1679
1680
print_field("%s: %u entr%s", label, count, count == 1 ? "y" : "ies");
1681
1682
while (size >= length) {
1683
print_field("Handle: 0x%4.4x", bt_get_le16(data));
1684
print_hex_field("Value", data + 2, length - 2);
1685
1686
data += length;
1687
size -= length;
1688
}
1689
1690
packet_hexdump(data, size);
1691
}
1692
1693
static void print_attribute_info(uint16_t type, const void *data, uint16_t len)
1694
{
1695
const char *str = uuid16_to_str(type);
1696
1697
print_field("%s: %s (0x%4.4x)", "Attribute type", str, type);
1698
1699
switch (type) {
1700
case 0x2800: /* Primary Service */
1701
case 0x2801: /* Secondary Service */
1702
print_uuid(" UUID", data, len);
1703
break;
1704
case 0x2802: /* Include */
1705
if (len < 4) {
1706
print_hex_field(" Value", data, len);
1707
break;
1708
}
1709
print_handle_range(" Handle range", data);
1710
print_uuid(" UUID", data + 4, len - 4);
1711
break;
1712
case 0x2803: /* Characteristic */
1713
if (len < 3) {
1714
print_hex_field(" Value", data, len);
1715
break;
1716
}
1717
print_field(" Properties: 0x%2.2x", *((uint8_t *) data));
1718
print_field(" Handle: 0x%2.2x", bt_get_le16(data + 1));
1719
print_uuid(" UUID", data + 3, len - 3);
1720
break;
1721
default:
1722
print_hex_field("Value", data, len);
1723
break;
1724
}
1725
}
1726
1727
static const char *att_opcode_to_str(uint8_t opcode);
1728
1729
static void att_error_response(const struct l2cap_frame *frame)
1730
{
1731
const struct bt_l2cap_att_error_response *pdu = frame->data;
1732
const char *str;
1733
1734
switch (pdu->error) {
1735
case 0x01:
1736
str = "Invalid Handle";
1737
break;
1738
case 0x02:
1739
str = "Read Not Permitted";
1740
break;
1741
case 0x03:
1742
str = "Write Not Permitted";
1743
break;
1744
case 0x04:
1745
str = "Invalid PDU";
1746
break;
1747
case 0x05:
1748
str = "Insufficient Authentication";
1749
break;
1750
case 0x06:
1751
str = "Request Not Supported";
1752
break;
1753
case 0x07:
1754
str = "Invalid Offset";
1755
break;
1756
case 0x08:
1757
str = "Insufficient Authorization";
1758
break;
1759
case 0x09:
1760
str = "Prepare Queue Full";
1761
break;
1762
case 0x0a:
1763
str = "Attribute Not Found";
1764
break;
1765
case 0x0b:
1766
str = "Attribute Not Long";
1767
break;
1768
case 0x0c:
1769
str = "Insufficient Encryption Key Size";
1770
break;
1771
case 0x0d:
1772
str = "Invalid Attribute Value Length";
1773
break;
1774
case 0x0e:
1775
str = "Unlikely Error";
1776
break;
1777
case 0x0f:
1778
str = "Insufficient Encryption";
1779
break;
1780
case 0x10:
1781
str = "Unsupported Group Type";
1782
break;
1783
case 0x11:
1784
str = "Insufficient Resources";
1785
break;
1786
default:
1787
str = "Reserved";
1788
break;
1789
}
1790
1791
print_field("%s (0x%2.2x)", att_opcode_to_str(pdu->request),
1792
pdu->request);
1793
print_field("Handle: 0x%4.4x", btohs(pdu->handle));
1794
print_field("Error: %s (0x%2.2x)", str, pdu->error);
1795
}
1796
1797
static void att_exchange_mtu_req(const struct l2cap_frame *frame)
1798
{
1799
const struct bt_l2cap_att_exchange_mtu_req *pdu = frame->data;
1800
1801
print_field("Client RX MTU: %d", btohs(pdu->mtu));
1802
}
1803
1804
static void att_exchange_mtu_rsp(const struct l2cap_frame *frame)
1805
{
1806
const struct bt_l2cap_att_exchange_mtu_rsp *pdu = frame->data;
1807
1808
print_field("Server RX MTU: %d", btohs(pdu->mtu));
1809
}
1810
1811
static void att_find_info_req(const struct l2cap_frame *frame)
1812
{
1813
print_handle_range("Handle range", frame->data);
1814
}
1815
1816
static const char *att_format_str(uint8_t format)
1817
{
1818
switch (format) {
1819
case 0x01:
1820
return "UUID-16";
1821
case 0x02:
1822
return "UUID-128";
1823
default:
1824
return "unknown";
1825
}
1826
}
1827
1828
static uint16_t print_info_data_16(const uint16_t *data, uint16_t len)
1829
{
1830
while (len >= 4) {
1831
print_field("Handle: 0x%4.4x", bt_get_le16(data));
1832
print_uuid("UUID", data + 2, 2);
1833
data += 4;
1834
len -= 4;
1835
}
1836
1837
return len;
1838
}
1839
1840
static uint16_t print_info_data_128(const uint16_t *data, uint16_t len)
1841
{
1842
while (len >= 18) {
1843
print_field("Handle: 0x%4.4x", bt_get_le16(data));
1844
print_uuid("UUID", data + 2, 16);
1845
data += 18;
1846
len -= 18;
1847
}
1848
1849
return len;
1850
}
1851
1852
static void att_find_info_rsp(const struct l2cap_frame *frame)
1853
{
1854
const uint8_t *format = frame->data;
1855
uint16_t len;
1856
1857
print_field("Format: %s (0x%2.2x)", att_format_str(*format), *format);
1858
1859
if (*format == 0x01)
1860
len = print_info_data_16(frame->data + 1, frame->size - 1);
1861
else if (*format == 0x02)
1862
len = print_info_data_128(frame->data + 1, frame->size - 1);
1863
else
1864
len = frame->size - 1;
1865
1866
packet_hexdump(frame->data + (frame->size - len), len);
1867
}
1868
1869
static void att_find_by_type_val_req(const struct l2cap_frame *frame)
1870
{
1871
uint16_t type;
1872
1873
print_handle_range("Handle range", frame->data);
1874
1875
type = bt_get_le16(frame->data + 4);
1876
print_attribute_info(type, frame->data + 6, frame->size - 6);
1877
}
1878
1879
static void att_find_by_type_val_rsp(const struct l2cap_frame *frame)
1880
{
1881
const uint8_t *ptr = frame->data;
1882
uint16_t len = frame->size;
1883
1884
while (len >= 4) {
1885
print_handle_range("Handle range", ptr);
1886
ptr += 4;
1887
len -= 4;
1888
}
1889
1890
packet_hexdump(ptr, len);
1891
}
1892
1893
static void att_read_type_req(const struct l2cap_frame *frame)
1894
{
1895
print_handle_range("Handle range", frame->data);
1896
print_uuid("Attribute type", frame->data + 4, frame->size - 4);
1897
}
1898
1899
static void att_read_type_rsp(const struct l2cap_frame *frame)
1900
{
1901
const struct bt_l2cap_att_read_group_type_rsp *pdu = frame->data;
1902
1903
print_field("Attribute data length: %d", pdu->length);
1904
print_data_list("Attribute data list", pdu->length,
1905
frame->data + 1, frame->size - 1);
1906
}
1907
1908
static void att_read_req(const struct l2cap_frame *frame)
1909
{
1910
const struct bt_l2cap_att_read_req *pdu = frame->data;
1911
1912
print_field("Handle: 0x%4.4x", btohs(pdu->handle));
1913
}
1914
1915
static void att_read_rsp(const struct l2cap_frame *frame)
1916
{
1917
print_hex_field("Value", frame->data, frame->size);
1918
}
1919
1920
static void att_read_blob_req(const struct l2cap_frame *frame)
1921
{
1922
print_field("Handle: 0x%4.4x", bt_get_le16(frame->data));
1923
print_field("Offset: 0x%4.4x", bt_get_le16(frame->data + 2));
1924
}
1925
1926
static void att_read_blob_rsp(const struct l2cap_frame *frame)
1927
{
1928
packet_hexdump(frame->data, frame->size);
1929
}
1930
1931
static void att_read_multiple_req(const struct l2cap_frame *frame)
1932
{
1933
int i, count;
1934
1935
count = frame->size / 2;
1936
1937
for (i = 0; i < count; i++)
1938
print_field("Handle: 0x%4.4x",
1939
bt_get_le16(frame->data + (i * 2)));
1940
}
1941
1942
static void att_read_group_type_req(const struct l2cap_frame *frame)
1943
{
1944
print_handle_range("Handle range", frame->data);
1945
print_uuid("Attribute group type", frame->data + 4, frame->size - 4);
1946
}
1947
1948
static void att_read_group_type_rsp(const struct l2cap_frame *frame)
1949
{
1950
const struct bt_l2cap_att_read_group_type_rsp *pdu = frame->data;
1951
1952
print_field("Attribute data length: %d", pdu->length);
1953
print_data_list("Attribute data list", pdu->length,
1954
frame->data + 1, frame->size - 1);
1955
}
1956
1957
static void att_write_req(const struct l2cap_frame *frame)
1958
{
1959
print_field("Handle: 0x%4.4x", bt_get_le16(frame->data));
1960
print_hex_field(" Data", frame->data + 2, frame->size - 2);
1961
}
1962
1963
static void att_write_rsp(const struct l2cap_frame *frame)
1964
{
1965
}
1966
1967
static void att_prepare_write_req(const struct l2cap_frame *frame)
1968
{
1969
print_field("Handle: 0x%4.4x", bt_get_le16(frame->data));
1970
print_field("Offset: 0x%4.4x", bt_get_le16(frame->data + 2));
1971
print_hex_field(" Data", frame->data + 4, frame->size - 4);
1972
}
1973
1974
static void att_prepare_write_rsp(const struct l2cap_frame *frame)
1975
{
1976
print_field("Handle: 0x%4.4x", bt_get_le16(frame->data));
1977
print_field("Offset: 0x%4.4x", bt_get_le16(frame->data + 2));
1978
print_hex_field(" Data", frame->data + 4, frame->size - 4);
1979
}
1980
1981
static void att_execute_write_req(const struct l2cap_frame *frame)
1982
{
1983
uint8_t flags = *(uint8_t *) frame->data;
1984
const char *flags_str;
1985
1986
switch (flags) {
1987
case 0x00:
1988
flags_str = "Cancel all prepared writes";
1989
break;
1990
case 0x01:
1991
flags_str = "Immediately write all pending values";
1992
break;
1993
default:
1994
flags_str = "Unknown";
1995
break;
1996
}
1997
1998
print_field("Flags: %s (0x%02x)", flags_str, flags);
1999
}
2000
2001
static void att_handle_value_notify(const struct l2cap_frame *frame)
2002
{
2003
const struct bt_l2cap_att_handle_value_notify *pdu = frame->data;
2004
2005
print_field("Handle: 0x%4.4x", btohs(pdu->handle));
2006
print_hex_field(" Data", frame->data + 2, frame->size - 2);
2007
}
2008
2009
static void att_handle_value_ind(const struct l2cap_frame *frame)
2010
{
2011
const struct bt_l2cap_att_handle_value_ind *pdu = frame->data;
2012
2013
print_field("Handle: 0x%4.4x", btohs(pdu->handle));
2014
print_hex_field(" Data", frame->data + 2, frame->size - 2);
2015
}
2016
2017
static void att_handle_value_conf(const struct l2cap_frame *frame)
2018
{
2019
}
2020
2021
static void att_write_command(const struct l2cap_frame *frame)
2022
{
2023
print_field("Handle: 0x%4.4x", bt_get_le16(frame->data));
2024
print_hex_field(" Data", frame->data + 2, frame->size - 2);
2025
}
2026
2027
struct att_opcode_data {
2028
uint8_t opcode;
2029
const char *str;
2030
void (*func) (const struct l2cap_frame *frame);
2031
uint8_t size;
2032
bool fixed;
2033
};
2034
2035
static const struct att_opcode_data att_opcode_table[] = {
2036
{ 0x01, "Error Response",
2037
att_error_response, 4, true },
2038
{ 0x02, "Exchange MTU Request",
2039
att_exchange_mtu_req, 2, true },
2040
{ 0x03, "Exchange MTU Response",
2041
att_exchange_mtu_rsp, 2, true },
2042
{ 0x04, "Find Information Request",
2043
att_find_info_req, 4, true },
2044
{ 0x05, "Find Information Response",
2045
att_find_info_rsp, 5, false },
2046
{ 0x06, "Find By Type Value Request",
2047
att_find_by_type_val_req, 6, false },
2048
{ 0x07, "Find By Type Value Response",
2049
att_find_by_type_val_rsp, 4, false },
2050
{ 0x08, "Read By Type Request",
2051
att_read_type_req, 6, false },
2052
{ 0x09, "Read By Type Response",
2053
att_read_type_rsp, 3, false },
2054
{ 0x0a, "Read Request",
2055
att_read_req, 2, true },
2056
{ 0x0b, "Read Response",
2057
att_read_rsp, 0, false },
2058
{ 0x0c, "Read Blob Request",
2059
att_read_blob_req, 4, true },
2060
{ 0x0d, "Read Blob Response",
2061
att_read_blob_rsp, 0, false },
2062
{ 0x0e, "Read Multiple Request",
2063
att_read_multiple_req, 4, false },
2064
{ 0x0f, "Read Multiple Response" },
2065
{ 0x10, "Read By Group Type Request",
2066
att_read_group_type_req, 6, false },
2067
{ 0x11, "Read By Group Type Response",
2068
att_read_group_type_rsp, 4, false },
2069
{ 0x12, "Write Request" ,
2070
att_write_req, 2, false },
2071
{ 0x13, "Write Response",
2072
att_write_rsp, 0, true },
2073
{ 0x16, "Prepare Write Request",
2074
att_prepare_write_req, 4, false },
2075
{ 0x17, "Prepare Write Response",
2076
att_prepare_write_rsp, 4, false },
2077
{ 0x18, "Execute Write Request",
2078
att_execute_write_req, 1, true },
2079
{ 0x19, "Execute Write Response" },
2080
{ 0x1b, "Handle Value Notification",
2081
att_handle_value_notify, 2, false },
2082
{ 0x1d, "Handle Value Indication",
2083
att_handle_value_ind, 2, false },
2084
{ 0x1e, "Handle Value Confirmation",
2085
att_handle_value_conf, 0, true },
2086
{ 0x52, "Write Command",
2087
att_write_command, 2, false },
2088
{ 0xd2, "Signed Write Command" },
2089
{ }
2090
};
2091
2092
static const char *att_opcode_to_str(uint8_t opcode)
2093
{
2094
int i;
2095
2096
for (i = 0; att_opcode_table[i].str; i++) {
2097
if (att_opcode_table[i].opcode == opcode)
2098
return att_opcode_table[i].str;
2099
}
2100
2101
return "Unknown";
2102
}
2103
2104
static void att_packet(uint16_t index, bool in, uint16_t handle,
2105
uint16_t cid, const void *data, uint16_t size)
2106
{
2107
struct l2cap_frame frame;
2108
uint8_t opcode = *((const uint8_t *) data);
2109
const struct att_opcode_data *opcode_data = NULL;
2110
const char *opcode_color, *opcode_str;
2111
int i;
2112
2113
if (size < 1) {
2114
print_text(COLOR_ERROR, "malformed attribute packet");
2115
packet_hexdump(data, size);
2116
return;
2117
}
2118
2119
for (i = 0; att_opcode_table[i].str; i++) {
2120
if (att_opcode_table[i].opcode == opcode) {
2121
opcode_data = &att_opcode_table[i];
2122
break;
2123
}
2124
}
2125
2126
if (opcode_data) {
2127
if (opcode_data->func) {
2128
if (in)
2129
opcode_color = COLOR_MAGENTA;
2130
else
2131
opcode_color = COLOR_BLUE;
2132
} else
2133
opcode_color = COLOR_WHITE_BG;
2134
opcode_str = opcode_data->str;
2135
} else {
2136
opcode_color = COLOR_WHITE_BG;
2137
opcode_str = "Unknown";
2138
}
2139
2140
print_indent(6, opcode_color, "ATT: ", opcode_str, COLOR_OFF,
2141
" (0x%2.2x) len %d", opcode, size - 1);
2142
2143
if (!opcode_data || !opcode_data->func) {
2144
packet_hexdump(data + 1, size - 1);
2145
return;
2146
}
2147
2148
if (opcode_data->fixed) {
2149
if (size - 1 != opcode_data->size) {
2150
print_text(COLOR_ERROR, "invalid size");
2151
packet_hexdump(data + 1, size - 1);
2152
return;
2153
}
2154
} else {
2155
if (size - 1 < opcode_data->size) {
2156
print_text(COLOR_ERROR, "too short packet");
2157
packet_hexdump(data + 1, size - 1);
2158
return;
2159
}
2160
}
2161
2162
l2cap_frame_init(&frame, index, in, handle, cid, data + 1, size - 1);
2163
opcode_data->func(&frame);
2164
}
2165
2166
static void print_addr(const uint8_t *addr, uint8_t addr_type)
2167
{
2168
const char *str;
2169
2170
switch (addr_type) {
2171
case 0x00:
2172
print_field("Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
2173
addr[5], addr[4], addr[3],
2174
addr[2], addr[1], addr[0]);
2175
break;
2176
case 0x01:
2177
switch ((addr[5] & 0xc0) >> 6) {
2178
case 0x00:
2179
str = "Non-Resolvable";
2180
break;
2181
case 0x01:
2182
str = "Resolvable";
2183
break;
2184
case 0x03:
2185
str = "Static";
2186
break;
2187
default:
2188
str = "Reserved";
2189
break;
2190
}
2191
2192
print_field("Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X"
2193
" (%s)", addr[5], addr[4], addr[3],
2194
addr[2], addr[1], addr[0], str);
2195
break;
2196
default:
2197
print_field("Address: %2.2X-%2.2X-%2.2X-%2.2X-%2.2X-%2.2X",
2198
addr[5], addr[4], addr[3],
2199
addr[2], addr[1], addr[0]);
2200
break;
2201
}
2202
}
2203
2204
static void print_addr_type(uint8_t addr_type)
2205
{
2206
const char *str;
2207
2208
switch (addr_type) {
2209
case 0x00:
2210
str = "Public";
2211
break;
2212
case 0x01:
2213
str = "Random";
2214
break;
2215
default:
2216
str = "Reserved";
2217
break;
2218
}
2219
2220
print_field("Address type: %s (0x%2.2x)", str, addr_type);
2221
}
2222
2223
static void print_smp_io_capa(uint8_t io_capa)
2224
{
2225
const char *str;
2226
2227
switch (io_capa) {
2228
case 0x00:
2229
str = "DisplayOnly";
2230
break;
2231
case 0x01:
2232
str = "DisplayYesNo";
2233
break;
2234
case 0x02:
2235
str = "KeyboardOnly";
2236
break;
2237
case 0x03:
2238
str = "NoInputNoOutput";
2239
break;
2240
case 0x04:
2241
str = "KeyboardDisplay";
2242
break;
2243
default:
2244
str = "Reserved";
2245
break;
2246
}
2247
2248
print_field("IO capability: %s (0x%2.2x)", str, io_capa);
2249
}
2250
2251
static void print_smp_oob_data(uint8_t oob_data)
2252
{
2253
const char *str;
2254
2255
switch (oob_data) {
2256
case 0x00:
2257
str = "Authentication data not present";
2258
break;
2259
case 0x01:
2260
str = "Authentication data from remote device present";
2261
break;
2262
default:
2263
str = "Reserved";
2264
break;
2265
}
2266
2267
print_field("OOB data: %s (0x%2.2x)", str, oob_data);
2268
}
2269
2270
static void print_smp_auth_req(uint8_t auth_req)
2271
{
2272
const char *str;
2273
2274
switch (auth_req & 0x03) {
2275
case 0x00:
2276
str = "No bonding";
2277
break;
2278
case 0x01:
2279
str = "Bonding";
2280
break;
2281
default:
2282
str = "Reserved";
2283
break;
2284
}
2285
2286
print_field("Authentication requirement: %s - %s (0x%2.2x)",
2287
str, (auth_req & 0x04) ? "MITM" : "No MITM", auth_req);
2288
}
2289
2290
static void smp_pairing_request(const struct l2cap_frame *frame)
2291
{
2292
const struct bt_l2cap_smp_pairing_request *pdu = frame->data;
2293
2294
print_smp_io_capa(pdu->io_capa);
2295
print_smp_oob_data(pdu->oob_data);
2296
print_smp_auth_req(pdu->auth_req);
2297
2298
print_field("Max encryption key size: %d", pdu->max_key_size);
2299
print_field("Initiator key distribution: 0x%2.2x", pdu->init_key_dist);
2300
print_field("Responder key distribution: 0x%2.2x", pdu->resp_key_dist);
2301
}
2302
2303
static void smp_pairing_response(const struct l2cap_frame *frame)
2304
{
2305
const struct bt_l2cap_smp_pairing_response *pdu = frame->data;
2306
2307
print_smp_io_capa(pdu->io_capa);
2308
print_smp_oob_data(pdu->oob_data);
2309
print_smp_auth_req(pdu->auth_req);
2310
2311
print_field("Max encryption key size: %d", pdu->max_key_size);
2312
print_field("Initiator key distribution: 0x%2.2x", pdu->init_key_dist);
2313
print_field("Responder key distribution: 0x%2.2x", pdu->resp_key_dist);
2314
}
2315
2316
static void smp_pairing_confirm(const struct l2cap_frame *frame)
2317
{
2318
const struct bt_l2cap_smp_pairing_confirm *pdu = frame->data;
2319
2320
print_hex_field("Confim value", pdu->value, 16);
2321
}
2322
2323
static void smp_pairing_random(const struct l2cap_frame *frame)
2324
{
2325
const struct bt_l2cap_smp_pairing_random *pdu = frame->data;
2326
2327
print_hex_field("Random value", pdu->value, 16);
2328
}
2329
2330
static void smp_pairing_failed(const struct l2cap_frame *frame)
2331
{
2332
const struct bt_l2cap_smp_pairing_failed *pdu = frame->data;
2333
const char *str;
2334
2335
switch (pdu->reason) {
2336
case 0x01:
2337
str = "Passkey entry failed";
2338
break;
2339
case 0x02:
2340
str = "OOB not available";
2341
break;
2342
case 0x03:
2343
str = "Authentication requirements";
2344
break;
2345
case 0x04:
2346
str = "Confirm value failed";
2347
break;
2348
case 0x05:
2349
str = "Pairing not supported";
2350
break;
2351
case 0x06:
2352
str = "Encryption key size";
2353
break;
2354
case 0x07:
2355
str = "Command not supported";
2356
break;
2357
case 0x08:
2358
str = "Unspecified reason";
2359
break;
2360
case 0x09:
2361
str = "Repeated attempts";
2362
break;
2363
case 0x0a:
2364
str = "Invalid parameters";
2365
break;
2366
default:
2367
str = "Reserved";
2368
break;
2369
}
2370
2371
print_field("Reason: %s (0x%2.2x)", str, pdu->reason);
2372
}
2373
2374
static void smp_encrypt_info(const struct l2cap_frame *frame)
2375
{
2376
const struct bt_l2cap_smp_encrypt_info *pdu = frame->data;
2377
2378
print_hex_field("Long term key", pdu->ltk, 16);
2379
}
2380
2381
static void smp_master_ident(const struct l2cap_frame *frame)
2382
{
2383
const struct bt_l2cap_smp_master_ident *pdu = frame->data;
2384
2385
print_field("EDIV: 0x%4.4x", btohs(pdu->ediv));
2386
print_field("Rand: 0x%16.16" PRIx64, btohll(pdu->rand));
2387
}
2388
2389
static void smp_ident_info(const struct l2cap_frame *frame)
2390
{
2391
const struct bt_l2cap_smp_ident_info *pdu = frame->data;
2392
2393
print_hex_field("Identity resolving key", pdu->irk, 16);
2394
}
2395
2396
static void smp_ident_addr_info(const struct l2cap_frame *frame)
2397
{
2398
const struct bt_l2cap_smp_ident_addr_info *pdu = frame->data;
2399
2400
print_addr_type(pdu->addr_type);
2401
print_addr(pdu->addr, pdu->addr_type);
2402
}
2403
2404
static void smp_signing_info(const struct l2cap_frame *frame)
2405
{
2406
const struct bt_l2cap_smp_signing_info *pdu = frame->data;
2407
2408
print_hex_field("Signature key", pdu->csrk, 16);
2409
}
2410
2411
static void smp_security_request(const struct l2cap_frame *frame)
2412
{
2413
const struct bt_l2cap_smp_security_request *pdu = frame->data;
2414
2415
print_smp_auth_req(pdu->auth_req);
2416
}
2417
2418
struct smp_opcode_data {
2419
uint8_t opcode;
2420
const char *str;
2421
void (*func) (const struct l2cap_frame *frame);
2422
uint8_t size;
2423
bool fixed;
2424
};
2425
2426
static const struct smp_opcode_data smp_opcode_table[] = {
2427
{ 0x01, "Pairing Request",
2428
smp_pairing_request, 6, true },
2429
{ 0x02, "Pairing Response",
2430
smp_pairing_response, 6, true },
2431
{ 0x03, "Pairing Confirm",
2432
smp_pairing_confirm, 16, true },
2433
{ 0x04, "Pairing Random",
2434
smp_pairing_random, 16, true },
2435
{ 0x05, "Pairing Failed",
2436
smp_pairing_failed, 1, true },
2437
{ 0x06, "Encryption Information",
2438
smp_encrypt_info, 16, true },
2439
{ 0x07, "Master Identification",
2440
smp_master_ident, 10, true },
2441
{ 0x08, "Identity Information",
2442
smp_ident_info, 16, true },
2443
{ 0x09, "Identity Address Information",
2444
smp_ident_addr_info, 7, true },
2445
{ 0x0a, "Signing Information",
2446
smp_signing_info, 16, true },
2447
{ 0x0b, "Security Request",
2448
smp_security_request, 1, true },
2449
{ }
2450
};
2451
2452
static void smp_packet(uint16_t index, bool in, uint16_t handle,
2453
uint16_t cid, const void *data, uint16_t size)
2454
{
2455
struct l2cap_frame frame;
2456
uint8_t opcode = *((const uint8_t *) data);
2457
const struct smp_opcode_data *opcode_data = NULL;
2458
const char *opcode_color, *opcode_str;
2459
int i;
2460
2461
if (size < 1) {
2462
print_text(COLOR_ERROR, "malformed attribute packet");
2463
packet_hexdump(data, size);
2464
return;
2465
}
2466
2467
for (i = 0; smp_opcode_table[i].str; i++) {
2468
if (smp_opcode_table[i].opcode == opcode) {
2469
opcode_data = &smp_opcode_table[i];
2470
break;
2471
}
2472
}
2473
2474
if (opcode_data) {
2475
if (opcode_data->func) {
2476
if (in)
2477
opcode_color = COLOR_MAGENTA;
2478
else
2479
opcode_color = COLOR_BLUE;
2480
} else
2481
opcode_color = COLOR_WHITE_BG;
2482
opcode_str = opcode_data->str;
2483
} else {
2484
opcode_color = COLOR_WHITE_BG;
2485
opcode_str = "Unknown";
2486
}
2487
2488
print_indent(6, opcode_color, "SMP: ", opcode_str, COLOR_OFF,
2489
" (0x%2.2x) len %d", opcode, size - 1);
2490
2491
if (!opcode_data || !opcode_data->func) {
2492
packet_hexdump(data + 1, size - 1);
2493
return;
2494
}
2495
2496
if (opcode_data->fixed) {
2497
if (size - 1 != opcode_data->size) {
2498
print_text(COLOR_ERROR, "invalid size");
2499
packet_hexdump(data + 1, size - 1);
2500
return;
2501
}
2502
} else {
2503
if (size - 1 < opcode_data->size) {
2504
print_text(COLOR_ERROR, "too short packet");
2505
packet_hexdump(data + 1, size - 1);
2506
return;
2507
}
2508
}
2509
2510
l2cap_frame_init(&frame, index, in, handle, cid, data + 1, size - 1);
2511
opcode_data->func(&frame);
2512
}
2513
2514
static void l2cap_frame(uint16_t index, bool in, uint16_t handle,
2515
uint16_t cid, const void *data, uint16_t size)
2516
{
2517
struct l2cap_frame frame;
2518
uint16_t psm, chan;
2519
uint8_t mode;
2520
2521
switch (cid) {
2522
case 0x0001:
2523
bredr_sig_packet(index, in, handle, cid, data, size);
2524
break;
2525
case 0x0002:
2526
connless_packet(index, in, handle, cid, data, size);
2527
break;
2528
case 0x0003:
2529
amp_packet(index, in, handle, cid, data, size);
2530
break;
2531
case 0x0004:
2532
att_packet(index, in, handle, cid, data, size);
2533
break;
2534
case 0x0005:
2535
le_sig_packet(index, in, handle, cid, data, size);
2536
break;
2537
case 0x0006:
2538
smp_packet(index, in, handle, cid, data, size);
2539
break;
2540
default:
2541
l2cap_frame_init(&frame, index, in, handle, cid, data, size);
2542
psm = get_psm(&frame);
2543
mode = get_mode(&frame);
2544
chan = get_chan(&frame);
2545
2546
print_indent(6, COLOR_CYAN, "Channel:", "", COLOR_OFF,
2547
" %d len %d [PSM %d mode %d] {chan %d}",
2548
cid, size, psm, mode, chan);
2549
2550
switch (psm) {
2551
case 0x0001:
2552
sdp_packet(&frame, chan);
2553
break;
2554
case 0x001f:
2555
att_packet(index, in, handle, cid, data, size);
2556
break;
2557
default:
2558
packet_hexdump(data, size);
2559
break;
2560
}
2561
break;
2562
}
2563
}
2564
2565
void l2cap_packet(uint16_t index, bool in, uint16_t handle, uint8_t flags,
2566
const void *data, uint16_t size)
2567
{
2568
const struct bt_l2cap_hdr *hdr = data;
2569
uint16_t len, cid;
2570
2571
if (index > MAX_INDEX - 1) {
2572
print_text(COLOR_ERROR, "controller index too large");
2573
packet_hexdump(data, size);
2574
return;
2575
}
2576
2577
switch (flags) {
2578
case 0x00: /* start of a non-automatically-flushable PDU */
2579
case 0x02: /* start of an automatically-flushable PDU */
2580
if (index_list[index].frag_len) {
2581
print_text(COLOR_ERROR, "unexpected start frame");
2582
packet_hexdump(data, size);
2583
clear_fragment_buffer(index);
2584
return;
2585
}
2586
2587
if (size < sizeof(*hdr)) {
2588
print_text(COLOR_ERROR, "frame too short");
2589
packet_hexdump(data, size);
2590
return;
2591
}
2592
2593
len = btohs(hdr->len);
2594
cid = btohs(hdr->cid);
2595
2596
data += sizeof(*hdr);
2597
size -= sizeof(*hdr);
2598
2599
if (len == size) {
2600
/* complete frame */
2601
l2cap_frame(index, in, handle, cid, data, len);
2602
return;
2603
}
2604
2605
if (size > len) {
2606
print_text(COLOR_ERROR, "frame too long");
2607
packet_hexdump(data, size);
2608
return;
2609
}
2610
2611
index_list[index].frag_buf = malloc(len);
2612
if (!index_list[index].frag_buf) {
2613
print_text(COLOR_ERROR, "failed buffer allocation");
2614
packet_hexdump(data, size);
2615
return;
2616
}
2617
2618
memcpy(index_list[index].frag_buf, data, size);
2619
index_list[index].frag_pos = size;
2620
index_list[index].frag_len = len - size;
2621
index_list[index].frag_cid = cid;
2622
break;
2623
2624
case 0x01: /* continuing fragment */
2625
if (!index_list[index].frag_len) {
2626
print_text(COLOR_ERROR, "unexpected continuation");
2627
packet_hexdump(data, size);
2628
return;
2629
}
2630
2631
if (size > index_list[index].frag_len) {
2632
print_text(COLOR_ERROR, "fragment too long");
2633
packet_hexdump(data, size);
2634
clear_fragment_buffer(index);
2635
return;
2636
}
2637
2638
memcpy(index_list[index].frag_buf +
2639
index_list[index].frag_pos, data, size);
2640
index_list[index].frag_pos += size;
2641
index_list[index].frag_len -= size;
2642
2643
if (!index_list[index].frag_len) {
2644
/* complete frame */
2645
l2cap_frame(index, in, handle,
2646
index_list[index].frag_cid,
2647
index_list[index].frag_buf,
2648
index_list[index].frag_pos);
2649
clear_fragment_buffer(index);
2650
return;
2651
}
2652
break;
2653
2654
case 0x03: /* complete automatically-flushable PDU */
2655
if (index_list[index].frag_len) {
2656
print_text(COLOR_ERROR, "unexpected complete frame");
2657
packet_hexdump(data, size);
2658
clear_fragment_buffer(index);
2659
return;
2660
}
2661
2662
if (size < sizeof(*hdr)) {
2663
print_text(COLOR_ERROR, "frame too short");
2664
packet_hexdump(data, size);
2665
return;
2666
}
2667
2668
len = btohs(hdr->len);
2669
cid = btohs(hdr->cid);
2670
2671
data += sizeof(*hdr);
2672
size -= sizeof(*hdr);
2673
2674
if (len != size) {
2675
print_text(COLOR_ERROR, "wrong frame size");
2676
packet_hexdump(data, size);
2677
return;
2678
}
2679
2680
/* complete frame */
2681
l2cap_frame(index, in, handle, cid, data, len);
2682
break;
2683
2684
default:
2685
print_text(COLOR_ERROR, "invalid packet flags (0x%2.2x)",
2686
flags);
2687
packet_hexdump(data, size);
2688
return;
2689
}
2690
}
2691
2692