1 // SPDX-License-Identifier: LGPL-2.1-or-later
4 * BlueZ - Bluetooth protocol stack for Linux
6 * Copyright (C) 2011-2014 Intel Corporation
7 * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
23 #include <linux/limits.h>
28 #include "lib/bluetooth.h"
31 #include "lib/hci_lib.h"
33 #include "src/shared/util.h"
34 #include "src/shared/queue.h"
35 #include "src/shared/att.h"
36 #include "src/shared/gatt-db.h"
37 #include "src/textfile.h"
38 #include "src/settings.h"
45 static void print_uuid(const char *label, const void *data, uint16_t size)
48 char uuidstr[MAX_LEN_UUID_STR];
52 str = bt_uuid16_to_str(get_le16(data));
53 print_field("%s: %s (0x%4.4x)", label, str, get_le16(data));
56 str = bt_uuid32_to_str(get_le32(data));
57 print_field("%s: %s (0x%8.8x)", label, str, get_le32(data));
60 sprintf(uuidstr, "%8.8x-%4.4x-%4.4x-%4.4x-%8.8x%4.4x",
61 get_le32(data + 12), get_le16(data + 10),
62 get_le16(data + 8), get_le16(data + 6),
63 get_le32(data + 2), get_le16(data + 0));
64 str = bt_uuidstr_to_str(uuidstr);
65 print_field("%s: %s (%s)", label, str, uuidstr);
68 packet_hexdump(data, size);
73 static void print_handle_range(const char *label, const void *data)
75 print_field("%s: 0x%4.4x-0x%4.4x", label,
76 get_le16(data), get_le16(data + 2));
79 static void print_data_list(const char *label, uint8_t length,
80 const void *data, uint16_t size)
87 count = size / length;
89 print_field("%s: %u entr%s", label, count, count == 1 ? "y" : "ies");
91 while (size >= length) {
92 print_field("Handle: 0x%4.4x", get_le16(data));
93 print_hex_field("Value", data + 2, length - 2);
99 packet_hexdump(data, size);
102 static void print_attribute_info(uint16_t type, const void *data, uint16_t len)
104 const char *str = bt_uuid16_to_str(type);
106 print_field("%s: %s (0x%4.4x)", "Attribute type", str, type);
109 case 0x2800: /* Primary Service */
110 case 0x2801: /* Secondary Service */
111 print_uuid(" UUID", data, len);
113 case 0x2802: /* Include */
115 print_hex_field(" Value", data, len);
118 print_handle_range(" Handle range", data);
119 print_uuid(" UUID", data + 4, len - 4);
121 case 0x2803: /* Characteristic */
123 print_hex_field(" Value", data, len);
126 print_field(" Properties: 0x%2.2x", *((uint8_t *) data));
127 print_field(" Handle: 0x%2.2x", get_le16(data + 1));
128 print_uuid(" UUID", data + 3, len - 3);
131 print_hex_field("Value", data, len);
136 static const char *att_opcode_to_str(uint8_t opcode);
138 static void att_error_response(const struct l2cap_frame *frame)
140 const struct bt_l2cap_att_error_response *pdu = frame->data;
143 switch (pdu->error) {
145 str = "Invalid Handle";
148 str = "Read Not Permitted";
151 str = "Write Not Permitted";
157 str = "Insufficient Authentication";
160 str = "Request Not Supported";
163 str = "Invalid Offset";
166 str = "Insufficient Authorization";
169 str = "Prepare Queue Full";
172 str = "Attribute Not Found";
175 str = "Attribute Not Long";
178 str = "Insufficient Encryption Key Size";
181 str = "Invalid Attribute Value Length";
184 str = "Unlikely Error";
187 str = "Insufficient Encryption";
190 str = "Unsupported Group Type";
193 str = "Insufficient Resources";
196 str = "Database Out of Sync";
199 str = "Value Not Allowed";
202 str = "CCC Improperly Configured";
205 str = "Procedure Already in Progress";
208 str = "Out of Range";
215 print_field("%s (0x%2.2x)", att_opcode_to_str(pdu->request),
217 print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle));
218 print_field("Error: %s (0x%2.2x)", str, pdu->error);
221 static const struct bitfield_data ccc_value_table[] = {
222 { 0, "Notification (0x01)" },
223 { 1, "Indication (0x02)" },
227 static void print_ccc_value(const struct l2cap_frame *frame)
232 if (!l2cap_frame_get_u8((void *)frame, &value)) {
233 print_text(COLOR_ERROR, "invalid size");
237 mask = print_bitfield(4, value, ccc_value_table);
239 print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)",
243 static void ccc_read(const struct l2cap_frame *frame)
245 print_ccc_value(frame);
248 static void ccc_write(const struct l2cap_frame *frame)
250 print_ccc_value(frame);
253 static bool print_ase_codec(const struct l2cap_frame *frame)
256 uint16_t codec_cid, codec_vid;
258 if (!l2cap_frame_get_u8((void *)frame, &codec_id)) {
259 print_text(COLOR_ERROR, "Codec: invalid size");
263 packet_print_codec_id(" Codec", codec_id);
265 if (!l2cap_frame_get_le16((void *)frame, &codec_cid)) {
266 print_text(COLOR_ERROR, "Codec Company ID: invalid size");
270 if (!l2cap_frame_get_le16((void *)frame, &codec_vid)) {
271 print_text(COLOR_ERROR, "Codec Vendor ID: invalid size");
275 if (codec_id == 0xff) {
276 print_field(" Codec Company ID: %s (0x%04x)",
277 bt_compidtostr(codec_cid),
279 print_field(" Codec Vendor ID: 0x%04x", codec_vid);
285 static bool print_ase_lv(const struct l2cap_frame *frame, const char *label,
286 struct packet_ltv_decoder *decoder, size_t decoder_len)
288 struct bt_hci_lv_data *lv;
290 lv = l2cap_frame_pull((void *)frame, frame, sizeof(*lv));
292 print_text(COLOR_ERROR, "%s: invalid size", label);
296 if (!l2cap_frame_pull((void *)frame, frame, lv->len)) {
297 print_text(COLOR_ERROR, "%s: invalid size", label);
301 packet_print_ltv(label, lv->data, lv->len, decoder, decoder_len);
306 static bool print_ase_cc(const struct l2cap_frame *frame, const char *label,
307 struct packet_ltv_decoder *decoder, size_t decoder_len)
309 return print_ase_lv(frame, label, decoder, decoder_len);
312 static const struct bitfield_data pac_context_table[] = {
313 { 0, "Unspecified (0x0001)" },
314 { 1, "Conversational (0x0002)" },
315 { 2, "Media (0x0004)" },
316 { 3, "Game (0x0008)" },
317 { 4, "Instructional (0x0010)" },
318 { 5, "Voice Assistants (0x0020)" },
319 { 6, "Live (0x0040)" },
320 { 7, "Sound Effects (0x0080)" },
321 { 8, "Notifications (0x0100)" },
322 { 9, "Ringtone (0x0200)" },
323 { 10, "Alerts (0x0400)" },
324 { 11, "Emergency alarm (0x0800)" },
325 { 12, "RFU (0x1000)" },
326 { 13, "RFU (0x2000)" },
327 { 14, "RFU (0x4000)" },
328 { 15, "RFU (0x8000)" },
332 static void print_context(const struct l2cap_frame *frame, const char *label)
337 if (!l2cap_frame_get_le16((void *)frame, &value)) {
338 print_text(COLOR_ERROR, " value: invalid size");
342 print_field("%s: 0x%4.4x", label, value);
344 mask = print_bitfield(8, value, pac_context_table);
346 print_text(COLOR_WHITE_BG, " Unknown fields (0x%4.4x)",
351 print_hex_field(" Data", frame->data, frame->size);
354 static void ase_decode_preferred_context(const uint8_t *data, uint8_t len)
356 struct l2cap_frame frame;
358 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
360 print_context(&frame, " Preferred Context");
363 static void ase_decode_context(const uint8_t *data, uint8_t len)
365 struct l2cap_frame frame;
367 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
369 print_context(&frame, " Context");
372 static void ase_decode_program_info(const uint8_t *data, uint8_t len)
374 struct l2cap_frame frame;
377 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
379 str = l2cap_frame_pull(&frame, &frame, len);
381 print_text(COLOR_ERROR, " value: invalid size");
385 print_field(" Program Info: %s", str);
389 print_hex_field(" Data", frame.data, frame.size);
392 static void ase_decode_language(const uint8_t *data, uint8_t len)
394 struct l2cap_frame frame;
397 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
399 if (!l2cap_frame_get_le24(&frame, &value)) {
400 print_text(COLOR_ERROR, " value: invalid size");
404 print_field(" Language: 0x%6.6x", value);
408 print_hex_field(" Data", frame.data, frame.size);
411 struct packet_ltv_decoder ase_metadata_table[] = {
412 LTV_DEC(0x01, ase_decode_preferred_context),
413 LTV_DEC(0x02, ase_decode_context),
414 LTV_DEC(0x03, ase_decode_program_info),
415 LTV_DEC(0x04, ase_decode_language)
418 static bool print_ase_metadata(const struct l2cap_frame *frame)
420 return print_ase_lv(frame, " Metadata", NULL, 0);
423 static const struct bitfield_data pac_freq_table[] = {
424 { 0, "8 Khz (0x0001)" },
425 { 1, "11.25 Khz (0x0002)" },
426 { 2, "16 Khz (0x0004)" },
427 { 3, "22.05 Khz (0x0008)" },
428 { 4, "24 Khz (0x0010)" },
429 { 5, "32 Khz (0x0020)" },
430 { 6, "44.1 Khz (0x0040)" },
431 { 7, "48 Khz (0x0080)" },
432 { 8, "88.2 Khz (0x0100)" },
433 { 9, "96 Khz (0x0200)" },
434 { 10, "176.4 Khz (0x0400)" },
435 { 11, "192 Khz (0x0800)" },
436 { 12, "384 Khz (0x1000)" },
437 { 13, "RFU (0x2000)" },
438 { 14, "RFU (0x4000)" },
439 { 15, "RFU (0x8000)" },
443 static void pac_decode_freq(const uint8_t *data, uint8_t len)
445 struct l2cap_frame frame;
449 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
451 if (!l2cap_frame_get_le16(&frame, &value)) {
452 print_text(COLOR_ERROR, " value: invalid size");
456 print_field(" Sampling Frequencies: 0x%4.4x", value);
458 mask = print_bitfield(8, value, pac_freq_table);
460 print_text(COLOR_WHITE_BG, " Unknown fields (0x%4.4x)",
465 print_hex_field(" Data", frame.data, frame.size);
468 static const struct bitfield_data pac_duration_table[] = {
469 { 0, "7.5 ms (0x01)" },
470 { 1, "10 ms (0x02)" },
473 { 4, "7.5 ms preferred (0x10)" },
474 { 5, "10 ms preferred (0x20)" },
480 static void pac_decode_duration(const uint8_t *data, uint8_t len)
482 struct l2cap_frame frame;
486 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
488 if (!l2cap_frame_get_u8(&frame, &value)) {
489 print_text(COLOR_ERROR, " value: invalid size");
493 print_field(" Frame Duration: 0x%4.4x", value);
495 mask = print_bitfield(8, value, pac_duration_table);
497 print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)",
502 print_hex_field(" Data", frame.data, frame.size);
505 static const struct bitfield_data pac_channel_table[] = {
506 { 0, "1 channel (0x01)" },
507 { 1, "2 channels (0x02)" },
508 { 2, "3 channels (0x04)" },
509 { 3, "4 chanenls (0x08)" },
510 { 4, "5 channels (0x10)" },
511 { 5, "6 channels (0x20)" },
512 { 6, "7 channels (0x40)" },
513 { 7, "8 channels (0x80)" },
517 static void pac_decode_channels(const uint8_t *data, uint8_t len)
519 struct l2cap_frame frame;
523 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
525 if (!l2cap_frame_get_u8(&frame, &value)) {
526 print_text(COLOR_ERROR, " value: invalid size");
530 print_field(" Audio Channel Count: 0x%2.2x", value);
532 mask = print_bitfield(8, value, pac_channel_table);
534 print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)",
539 print_hex_field(" Data", frame.data, frame.size);
542 static void pac_decode_frame_length(const uint8_t *data, uint8_t len)
544 struct l2cap_frame frame;
547 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
549 if (!l2cap_frame_get_le16(&frame, &min)) {
550 print_text(COLOR_ERROR, " min: invalid size");
554 if (!l2cap_frame_get_le16(&frame, &max)) {
555 print_text(COLOR_ERROR, " min: invalid size");
559 print_field(" Frame Length: %u (0x%4.4x) - %u (0x%4.4x)",
564 print_hex_field(" Data", frame.data, frame.size);
567 static void pac_decode_sdu(const uint8_t *data, uint8_t len)
569 struct l2cap_frame frame;
572 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
574 if (!l2cap_frame_get_u8(&frame, &value)) {
575 print_text(COLOR_ERROR, " value: invalid size");
579 print_field(" Max SDU: %u (0x%2.2x)", value, value);
583 print_hex_field(" Data", frame.data, frame.size);
586 struct packet_ltv_decoder pac_cap_table[] = {
587 LTV_DEC(0x01, pac_decode_freq),
588 LTV_DEC(0x02, pac_decode_duration),
589 LTV_DEC(0x03, pac_decode_channels),
590 LTV_DEC(0x04, pac_decode_frame_length),
591 LTV_DEC(0x05, pac_decode_sdu)
594 static void print_pac(const struct l2cap_frame *frame)
598 if (!l2cap_frame_get_u8((void *)frame, &num)) {
599 print_text(COLOR_ERROR, "Number of PAC(s): invalid size");
603 print_field(" Number of PAC(s): %u", num);
605 for (i = 0; i < num; i++) {
606 print_field(" PAC #%u:", i);
608 if (!print_ase_codec(frame))
611 if (!print_ase_cc(frame, " Codec Specific Capabilities",
612 pac_cap_table, ARRAY_SIZE(pac_cap_table)))
615 if (!print_ase_metadata(frame))
621 print_hex_field(" Data", frame->data, frame->size);
624 static void pac_read(const struct l2cap_frame *frame)
629 static void pac_notify(const struct l2cap_frame *frame)
634 static bool print_prefer_framing(const struct l2cap_frame *frame)
638 if (!l2cap_frame_get_u8((void *)frame, &framing)) {
639 print_text(COLOR_ERROR, " Framing: invalid size");
645 print_field(" Framing: Unframed PDUs supported (0x00)");
648 print_field(" Framing: Unframed PDUs not supported (0x01)");
651 print_field(" Framing: Reserved (0x%2.2x)", framing);
658 static const struct bitfield_data prefer_phy_table[] = {
659 { 0, "LE 1M PHY preffered (0x01)" },
660 { 1, "LE 2M PHY preffered (0x02)" },
661 { 2, "LE Codec PHY preffered (0x04)" },
665 static bool print_prefer_phy(const struct l2cap_frame *frame)
669 if (!l2cap_frame_get_u8((void *)frame, &phy)) {
670 print_text(COLOR_ERROR, "PHY: invalid size");
674 print_field(" PHY: 0x%2.2x", phy);
676 mask = print_bitfield(4, phy, prefer_phy_table);
678 print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)",
684 static bool print_ase_rtn(const struct l2cap_frame *frame, const char *label)
688 if (!l2cap_frame_get_u8((void *)frame, &rtn)) {
689 print_text(COLOR_ERROR, "%s: invalid size", label);
693 print_field("%s: %u", label, rtn);
698 static bool print_ase_latency(const struct l2cap_frame *frame,
703 if (!l2cap_frame_get_le16((void *)frame, &latency)) {
704 print_text(COLOR_ERROR, "%s: invalid size", label);
708 print_field("%s: %u", label, latency);
713 static bool print_ase_pd(const struct l2cap_frame *frame, const char *label)
717 if (!l2cap_frame_get_le24((void *)frame, &pd)) {
718 print_text(COLOR_ERROR, "%s: invalid size", label);
722 print_field("%s: %u us", label, pd);
727 static void ase_decode_freq(const uint8_t *data, uint8_t len)
729 struct l2cap_frame frame;
732 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
734 if (!l2cap_frame_get_u8(&frame, &value)) {
735 print_text(COLOR_ERROR, " value: invalid size");
741 print_field(" Sampling Frequency: 8 Khz (0x01)");
744 print_field(" Sampling Frequency: 11.25 Khz (0x02)");
747 print_field(" Sampling Frequency: 16 Khz (0x03)");
750 print_field(" Sampling Frequency: 22.05 Khz (0x04)");
753 print_field(" Sampling Frequency: 24 Khz (0x04)");
756 print_field(" Sampling Frequency: 32 Khz (0x04)");
759 print_field(" Sampling Frequency: 44.1 Khz (0x04)");
762 print_field(" Sampling Frequency: 48 Khz (0x04)");
765 print_field(" Sampling Frequency: 88.2 Khz (0x04)");
768 print_field(" Sampling Frequency: 96 Khz (0x04)");
771 print_field(" Sampling Frequency: 176.4 Khz (0x04)");
774 print_field(" Sampling Frequency: 192 Khz (0x04)");
777 print_field(" Sampling Frequency: 384 Khz (0x04)");
780 print_field(" Sampling Frequency: RFU (0x%2.2x)", value);
786 print_hex_field(" Data", frame.data, frame.size);
789 static void ase_decode_duration(const uint8_t *data, uint8_t len)
791 struct l2cap_frame frame;
794 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
796 if (!l2cap_frame_get_u8(&frame, &value)) {
797 print_text(COLOR_ERROR, " value: invalid size");
803 print_field(" Frame Duration: 7.5 ms (0x00)");
806 print_field(" Frame Duration: 10 ms (0x01)");
809 print_field(" Frame Duration: RFU (0x%2.2x)", value);
815 print_hex_field(" Data", frame.data, frame.size);
818 static const struct bitfield_data channel_location_table[] = {
819 { 0, "Front Left (0x00000001)" },
820 { 1, "Front Right (0x00000002)" },
821 { 2, "Front Center (0x00000004)" },
822 { 3, "Low Frequency Effects 1 (0x00000008)" },
823 { 4, "Back Left (0x00000010)" },
824 { 5, "Back Right (0x00000020)" },
825 { 6, "Front Left of Center (0x00000040)" },
826 { 7, "Front Right of Center (0x00000080)" },
827 { 8, "Back Center (0x00000100)" },
828 { 9, "Low Frequency Effects 2 (0x00000200)" },
829 { 10, "Side Left (0x00000400)" },
830 { 11, "Side Right (0x00000800)" },
831 { 12, "Top Front Left (0x00001000)" },
832 { 13, "Top Front Right (0x00002000)" },
833 { 14, "Top Front Center (0x00004000)" },
834 { 15, "Top Center (0x00008000)" },
835 { 16, "Top Back Left (0x00010000)" },
836 { 17, "Top Back Right (0x00020000)" },
837 { 18, "Top Side Left (0x00040000)" },
838 { 19, "Top Side Right (0x00080000)" },
839 { 20, "Top Back Center (0x00100000)" },
840 { 21, "Bottom Front Center (0x00200000)" },
841 { 22, "Bottom Front Left (0x00400000)" },
842 { 23, "Bottom Front Right (0x00800000)" },
843 { 24, "Front Left Wide (0x01000000)" },
844 { 25, "Front Right Wide (0x02000000)" },
845 { 26, "Left Surround (0x04000000)" },
846 { 27, "Right Surround (0x08000000)" },
847 { 28, "RFU (0x10000000)" },
848 { 29, "RFU (0x20000000)" },
849 { 30, "RFU (0x40000000)" },
850 { 31, "RFU (0x80000000)" },
854 static void print_location(const struct l2cap_frame *frame)
859 if (!l2cap_frame_get_le32((void *)frame, &value)) {
860 print_text(COLOR_ERROR, " value: invalid size");
864 print_field(" Location: 0x%8.8x", value);
866 mask = print_bitfield(6, value, channel_location_table);
868 print_text(COLOR_WHITE_BG, " Unknown fields (0x%8.8x)",
873 print_hex_field(" Data", frame->data, frame->size);
876 static void ase_decode_location(const uint8_t *data, uint8_t len)
878 struct l2cap_frame frame;
880 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
882 print_location(&frame);
885 static void ase_decode_frame_length(const uint8_t *data, uint8_t len)
887 struct l2cap_frame frame;
890 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
892 if (!l2cap_frame_get_le16(&frame, &value)) {
893 print_text(COLOR_ERROR, " value: invalid size");
897 print_field(" Frame Length: %u (0x%4.4x)", value, value);
901 print_hex_field(" Data", frame.data, frame.size);
904 static void ase_decode_blocks(const uint8_t *data, uint8_t len)
906 struct l2cap_frame frame;
909 l2cap_frame_init(&frame, 0, 0, 0, 0, 0, 0, data, len);
911 if (!l2cap_frame_get_u8(&frame, &value)) {
912 print_text(COLOR_ERROR, " value: invalid size");
916 print_field(" Frame Blocks per SDU: %u (0x%2.2x)", value, value);
920 print_hex_field(" Data", frame.data, frame.size);
923 struct packet_ltv_decoder ase_cc_table[] = {
924 LTV_DEC(0x01, ase_decode_freq),
925 LTV_DEC(0x02, ase_decode_duration),
926 LTV_DEC(0x03, ase_decode_location),
927 LTV_DEC(0x04, ase_decode_frame_length),
928 LTV_DEC(0x05, ase_decode_blocks)
931 static void print_ase_config(const struct l2cap_frame *frame)
933 if (!print_prefer_framing(frame))
936 if (!print_prefer_phy(frame))
939 if (!print_ase_rtn(frame, " RTN"))
942 if (!print_ase_latency(frame, " Max Transport Latency"))
945 if (!print_ase_pd(frame, " Presentation Delay Min"))
948 if (!print_ase_pd(frame, " Presentation Delay Max"))
951 if (!print_ase_pd(frame, " Preferred Presentation Delay Min"))
954 if (!print_ase_pd(frame, " Preferred Presentation Delay Max"))
957 if (!print_ase_codec(frame))
960 print_ase_cc(frame, " Codec Specific Configuration",
961 ase_cc_table, ARRAY_SIZE(ase_cc_table));
964 static bool print_ase_framing(const struct l2cap_frame *frame,
969 if (!l2cap_frame_get_u8((void *)frame, &framing)) {
970 print_text(COLOR_ERROR, "%s: invalid size", label);
976 print_field("%s: Unframed (0x00)", label);
979 print_field("%s: Framed (0x01)", label);
982 print_field("%s: Reserved (0x%2.2x)", label, framing);
988 static const struct bitfield_data phy_table[] = {
989 { 0, "LE 1M PHY (0x01)" },
990 { 1, "LE 2M PHY (0x02)" },
991 { 2, "LE Codec PHY (0x04)" },
995 static bool print_ase_phy(const struct l2cap_frame *frame, const char *label)
999 if (!l2cap_frame_get_u8((void *)frame, &phy)) {
1000 print_text(COLOR_ERROR, "%s: invalid size", label);
1004 print_field("%s: 0x%2.2x", label, phy);
1006 mask = print_bitfield(4, phy, phy_table);
1008 print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)",
1014 static bool print_ase_interval(const struct l2cap_frame *frame,
1019 if (!l2cap_frame_get_le24((void *)frame, &interval)) {
1020 print_text(COLOR_ERROR, "%s: invalid size", label);
1024 print_field("%s: %u usec", label, interval);
1029 static bool print_ase_sdu(const struct l2cap_frame *frame, const char *label)
1033 if (!l2cap_frame_get_le16((void *)frame, &sdu)) {
1034 print_text(COLOR_ERROR, "%s: invalid size", label);
1038 print_field("%s: %u", label, sdu);
1043 static void print_ase_qos(const struct l2cap_frame *frame)
1045 if (!l2cap_frame_print_u8((void *)frame, " CIG ID"))
1048 if (!l2cap_frame_print_u8((void *)frame, " CIS ID"))
1051 if (!print_ase_interval(frame, " SDU Interval"))
1054 if (!print_ase_framing(frame, " Framing"))
1057 if (!print_ase_phy(frame, " PHY"))
1060 if (!print_ase_sdu(frame, " Max SDU"))
1063 if (!print_ase_rtn(frame, " RTN"))
1066 if (!print_ase_latency(frame, " Max Transport Latency"))
1069 print_ase_pd(frame, " Presentation Delay");
1072 static void print_ase_metadata_status(const struct l2cap_frame *frame)
1074 if (!l2cap_frame_print_u8((void *)frame, " CIG ID"))
1077 if (!l2cap_frame_print_u8((void *)frame, " CIS ID"))
1080 print_ase_metadata(frame);
1083 static void print_ase_status(const struct l2cap_frame *frame)
1087 if (!l2cap_frame_get_u8((void *)frame, &id)) {
1088 print_text(COLOR_ERROR, "ASE ID: invalid size");
1092 print_field(" ASE ID: %u", id);
1094 if (!l2cap_frame_get_u8((void *)frame, &state)) {
1095 print_text(COLOR_ERROR, "ASE State: invalid size");
1100 /* ASE_State = 0x00 (Idle) */
1102 print_field(" State: Idle (0x00)");
1104 /* ASE_State = 0x01 (Codec Configured) */
1106 print_field(" State: Codec Configured (0x01)");
1107 print_ase_config(frame);
1109 /* ASE_State = 0x02 (QoS Configured) */
1111 print_field(" State: QoS Configured (0x02)");
1112 print_ase_qos(frame);
1114 /* ASE_Status = 0x03 (Enabling) */
1116 print_field(" State: Enabling (0x03)");
1117 print_ase_metadata_status(frame);
1119 /* ASE_Status = 0x04 (Streaming) */
1121 print_field(" State: Streaming (0x04)");
1122 print_ase_metadata_status(frame);
1124 /* ASE_Status = 0x05 (Disabling) */
1126 print_field(" State: Disabling (0x05)");
1127 print_ase_metadata_status(frame);
1129 /* ASE_Status = 0x06 (Releasing) */
1131 print_field(" State: Releasing (0x06)");
1134 print_field(" State: Reserved (0x%2.2x)", state);
1140 print_hex_field(" Data", frame->data, frame->size);
1143 static void ase_read(const struct l2cap_frame *frame)
1145 print_ase_status(frame);
1148 static void ase_notify(const struct l2cap_frame *frame)
1150 print_ase_status(frame);
1153 static bool print_ase_target_latency(const struct l2cap_frame *frame)
1157 if (!l2cap_frame_get_u8((void *)frame, &latency)) {
1158 print_text(COLOR_ERROR, " Target Latency: invalid size");
1164 print_field(" Target Latency: Low Latency (0x01)");
1167 print_field(" Target Latency: Balance Latency/Reliability "
1171 print_field(" Target Latency: High Reliability (0x03)");
1174 print_field(" Target Latency: Reserved (0x%2.2x)", latency);
1181 static bool ase_config_cmd(const struct l2cap_frame *frame)
1183 if (!l2cap_frame_print_u8((void *)frame, " ASE ID"))
1186 if (!print_ase_target_latency(frame))
1189 if (!print_ase_phy(frame, " PHY"))
1192 if (!print_ase_codec(frame))
1195 if (!print_ase_cc(frame, " Codec Specific Configuration",
1196 ase_cc_table, ARRAY_SIZE(ase_cc_table)))
1202 static bool ase_qos_cmd(const struct l2cap_frame *frame)
1204 if (!l2cap_frame_print_u8((void *)frame, " ASE ID"))
1207 if (!l2cap_frame_print_u8((void *)frame, " CIG ID"))
1210 if (!l2cap_frame_print_u8((void *)frame, " CIS ID"))
1213 if (!print_ase_interval(frame, " SDU Interval"))
1216 if (!print_ase_framing(frame, " Framing"))
1219 if (!print_ase_phy(frame, " PHY"))
1222 if (!print_ase_sdu(frame, " Max SDU"))
1225 if (!print_ase_rtn(frame, " RTN"))
1228 if (!print_ase_latency(frame, " Max Transport Latency"))
1231 if (!print_ase_pd(frame, " Presentation Delay"))
1237 static bool ase_enable_cmd(const struct l2cap_frame *frame)
1239 if (!l2cap_frame_print_u8((void *)frame, " ASE ID"))
1242 if (!print_ase_metadata(frame))
1248 static bool ase_start_cmd(const struct l2cap_frame *frame)
1250 if (!l2cap_frame_print_u8((void *)frame, " ASE ID"))
1256 static bool ase_disable_cmd(const struct l2cap_frame *frame)
1258 if (!l2cap_frame_print_u8((void *)frame, " ASE ID"))
1264 static bool ase_stop_cmd(const struct l2cap_frame *frame)
1266 if (!l2cap_frame_print_u8((void *)frame, " ASE ID"))
1272 static bool ase_metadata_cmd(const struct l2cap_frame *frame)
1274 if (!l2cap_frame_print_u8((void *)frame, " ASE ID"))
1277 if (!print_ase_metadata(frame))
1283 static bool ase_release_cmd(const struct l2cap_frame *frame)
1285 if (!l2cap_frame_print_u8((void *)frame, " ASE ID"))
1291 #define ASE_CMD(_op, _desc, _func) \
1299 bool (*func)(const struct l2cap_frame *frame);
1300 } ase_cmd_table[] = {
1301 /* Opcode = 0x01 (Codec Configuration) */
1302 ASE_CMD(0x01, "Codec Configuration", ase_config_cmd),
1303 /* Opcode = 0x02 (QoS Configuration) */
1304 ASE_CMD(0x02, "QoS Configuration", ase_qos_cmd),
1305 /* Opcode = 0x03 (Enable) */
1306 ASE_CMD(0x03, "Enable", ase_enable_cmd),
1307 /* Opcode = 0x04 (Receiver Start Ready) */
1308 ASE_CMD(0x04, "Receiver Start Ready", ase_start_cmd),
1309 /* Opcode = 0x05 (Disable) */
1310 ASE_CMD(0x05, "Disable", ase_disable_cmd),
1311 /* Opcode = 0x06 (Receiver Stop Ready) */
1312 ASE_CMD(0x06, "Receiver Stop Ready", ase_stop_cmd),
1313 /* Opcode = 0x07 (Update Metadata) */
1314 ASE_CMD(0x07, "Update Metadata", ase_metadata_cmd),
1315 /* Opcode = 0x08 (Release) */
1316 ASE_CMD(0x08, "Release", ase_release_cmd),
1319 static struct ase_cmd *ase_get_cmd(uint8_t op)
1321 if (op > ARRAY_SIZE(ase_cmd_table))
1324 return &ase_cmd_table[op];
1327 static void print_ase_cmd(const struct l2cap_frame *frame)
1330 struct ase_cmd *cmd;
1332 if (!l2cap_frame_get_u8((void *)frame, &op)) {
1333 print_text(COLOR_ERROR, "opcode: invalid size");
1337 if (!l2cap_frame_get_u8((void *)frame, &num)) {
1338 print_text(COLOR_ERROR, "num: invalid size");
1342 cmd = ase_get_cmd(op);
1344 print_field(" Opcode: Reserved (0x%2.2x)", op);
1348 print_field(" Opcode: %s (0x%2.2x)", cmd->desc, op);
1349 print_field(" Number of ASE(s): %u", num);
1351 for (i = 0; i < num && frame->size; i++) {
1352 print_field(" ASE: #%u", i);
1354 if (!cmd->func(frame))
1360 print_hex_field(" Data", frame->data, frame->size);
1363 static void ase_cp_write(const struct l2cap_frame *frame)
1365 print_ase_cmd(frame);
1368 static bool print_ase_cp_rsp_code(const struct l2cap_frame *frame)
1372 if (!l2cap_frame_get_u8((void *)frame, &code)) {
1373 print_text(COLOR_ERROR, " ASE Response Code: invalid size");
1379 print_field(" ASE Response Code: Success (0x00)");
1382 print_field(" ASE Response Code: Unsupported Opcode (0x01)");
1385 print_field(" ASE Response Code: Invalid Length (0x02)");
1388 print_field(" ASE Response Code: Invalid ASE ID (0x03)");
1391 print_field(" ASE Response Code: Invalid ASE State (0x04)");
1394 print_field(" ASE Response Code: Invalid ASE Direction "
1398 print_field(" ASE Response Code: Unsupported Audio "
1399 "Capabilities (0x06)");
1402 print_field(" ASE Response Code: Unsupported Configuration "
1406 print_field(" ASE Response Code: Rejected Configuration "
1410 print_field(" ASE Response Code: Invalid Configuration "
1414 print_field(" ASE Response Code: Unsupported Metadata "
1418 print_field(" ASE Response Code: Rejected Metadata (0x0b)");
1421 print_field(" ASE Response Code: Invalid Metadata (0x0c)");
1424 print_field(" ASE Response Code: Insufficient Resources "
1428 print_field(" ASE Response Code: Unspecified Error (0x0e)");
1431 print_field(" ASE Response Code: Reserved (0x%2.2x)", code);
1438 static bool print_ase_cp_rsp_reason(const struct l2cap_frame *frame)
1442 if (!l2cap_frame_get_u8((void *)frame, &reason)) {
1443 print_text(COLOR_ERROR,
1444 " ASE Response Reason: invalid size");
1450 print_field(" ASE Response Reason: None (0x00)");
1453 print_field(" ASE Response Reason: ASE ID (0x01)");
1456 print_field(" ASE Response Reason: Codec Specific "
1457 "Configuration (0x02)");
1460 print_field(" ASE Response Reason: SDU Interval (0x03)");
1463 print_field(" ASE Response Reason: Framing (0x04)");
1466 print_field(" ASE Response Reason: PHY (0x05)");
1469 print_field(" ASE Response Reason: Max SDU (0x06)");
1472 print_field(" ASE Response Reason: RTN (0x07)");
1475 print_field(" ASE Response Reason: Max Transport Latency "
1479 print_field(" ASE Response Reason: Presentation Delay "
1483 print_field(" ASE Response Reason: Invalid ASE/CIS Mapping "
1487 print_field(" ASE Response Reason: Reserved (0x%2.2x)",
1495 static void print_ase_cp_rsp(const struct l2cap_frame *frame)
1498 struct ase_cmd *cmd;
1500 if (!l2cap_frame_get_u8((void *)frame, &op)) {
1501 print_text(COLOR_ERROR, " opcode: invalid size");
1505 if (!l2cap_frame_get_u8((void *)frame, &num)) {
1506 print_text(COLOR_ERROR, " Number of ASE(s): invalid size");
1510 cmd = ase_get_cmd(op);
1512 print_field(" Opcode: Reserved (0x%2.2x)", op);
1516 print_field(" Opcode: %s (0x%2.2x)", cmd->desc, op);
1517 print_field(" Number of ASE(s): %u", num);
1519 for (i = 0; i < num && frame->size; i++) {
1520 print_field(" ASE: #%u", i);
1522 if (!l2cap_frame_print_u8((void *)frame, " ASE ID"))
1525 if (!print_ase_cp_rsp_code(frame))
1528 if (!print_ase_cp_rsp_reason(frame))
1534 print_hex_field(" Data", frame->data, frame->size);
1537 static void ase_cp_notify(const struct l2cap_frame *frame)
1539 print_ase_cp_rsp(frame);
1542 static void pac_loc_read(const struct l2cap_frame *frame)
1544 print_location(frame);
1547 static void pac_loc_notify(const struct l2cap_frame *frame)
1549 print_location(frame);
1552 static void print_pac_context(const struct l2cap_frame *frame)
1557 if (!l2cap_frame_get_le16((void *)frame, &snk)) {
1558 print_text(COLOR_ERROR, " sink: invalid size");
1562 print_field(" Sink Context: 0x%4.4x", snk);
1564 mask = print_bitfield(4, snk, pac_context_table);
1566 print_text(COLOR_WHITE_BG, " Unknown fields (0x%4.4x)",
1569 if (!l2cap_frame_get_le16((void *)frame, &src)) {
1570 print_text(COLOR_ERROR, " source: invalid size");
1574 print_field(" Source Context: 0x%4.4x", src);
1576 mask = print_bitfield(4, src, pac_context_table);
1578 print_text(COLOR_WHITE_BG, " Unknown fields (0x%4.4x)",
1583 print_hex_field(" Data", frame->data, frame->size);
1586 static void pac_context_read(const struct l2cap_frame *frame)
1588 print_pac_context(frame);
1591 static void pac_context_notify(const struct l2cap_frame *frame)
1593 print_pac_context(frame);
1596 static void print_vcs_state(const struct l2cap_frame *frame)
1598 uint8_t vol_set, mute, chng_ctr;
1600 if (!l2cap_frame_get_u8((void *)frame, &vol_set)) {
1601 print_text(COLOR_ERROR, "Volume Settings: invalid size");
1604 print_field(" Volume Setting: %u", vol_set);
1606 if (!l2cap_frame_get_u8((void *)frame, &mute)) {
1607 print_text(COLOR_ERROR, "Mute Filed: invalid size");
1613 print_field(" Not Muted: %u", mute);
1616 print_field(" Muted: %u", mute);
1619 print_field(" Unknown Mute Value: %u", mute);
1623 if (!l2cap_frame_get_u8((void *)frame, &chng_ctr)) {
1624 print_text(COLOR_ERROR, "Change Counter: invalid size");
1627 print_field(" Change Counter: %u", chng_ctr);
1631 print_hex_field(" Data", frame->data, frame->size);
1634 static void vol_state_read(const struct l2cap_frame *frame)
1636 print_vcs_state(frame);
1639 static void vol_state_notify(const struct l2cap_frame *frame)
1641 print_vcs_state(frame);
1644 static bool vcs_config_cmd(const struct l2cap_frame *frame)
1646 if (!l2cap_frame_print_u8((void *)frame, " Change Counter"))
1652 static bool vcs_absolute_cmd(const struct l2cap_frame *frame)
1654 if (!l2cap_frame_print_u8((void *)frame, " Change Counter"))
1657 if (!l2cap_frame_print_u8((void *)frame, " Volume Setting"))
1663 #define VCS_CMD(_op, _desc, _func) \
1671 bool (*func)(const struct l2cap_frame *frame);
1672 } vcs_cmd_table[] = {
1673 /* Opcode = 0x00 (Relative Volume Down) */
1674 VCS_CMD(0x00, "Relative Volume Down", vcs_config_cmd),
1675 /* Opcode = 0x01 (Relative Volume Up) */
1676 VCS_CMD(0x01, "Relative Volume Up", vcs_config_cmd),
1677 /* Opcode = 0x02 (Unmute/Relative Volume Down) */
1678 VCS_CMD(0x02, "Unmute/Relative Volume Down", vcs_config_cmd),
1679 /* Opcode = 0x03 (Unmute/Relative Volume Up) */
1680 VCS_CMD(0x03, "Unmute/Relative Volume Up", vcs_config_cmd),
1681 /* Opcode = 0x04 (Set Absolute Volume) */
1682 VCS_CMD(0x04, "Set Absolute Volume", vcs_absolute_cmd),
1683 /* Opcode = 0x05 (Unmute) */
1684 VCS_CMD(0x05, "Unmute", vcs_config_cmd),
1685 /* Opcode = 0x06 (Mute) */
1686 VCS_CMD(0x06, "Mute", vcs_config_cmd),
1689 static struct vcs_cmd *vcs_get_cmd(uint8_t op)
1691 if (op > ARRAY_SIZE(vcs_cmd_table))
1694 return &vcs_cmd_table[op];
1697 static void print_vcs_cmd(const struct l2cap_frame *frame)
1700 struct vcs_cmd *cmd;
1702 if (!l2cap_frame_get_u8((void *)frame, &op)) {
1703 print_text(COLOR_ERROR, "opcode: invalid size");
1707 cmd = vcs_get_cmd(op);
1709 print_field(" Opcode: Reserved (0x%2.2x)", op);
1713 print_field(" Opcode: %s (0x%2.2x)", cmd->desc, op);
1714 if (!cmd->func(frame))
1715 print_field(" Unknown Opcode");
1719 print_hex_field(" Data", frame->data, frame->size);
1722 static void vol_cp_write(const struct l2cap_frame *frame)
1724 print_vcs_cmd(frame);
1727 static void print_vcs_flag(const struct l2cap_frame *frame)
1731 if (!l2cap_frame_get_u8((void *)frame, &vol_flag)) {
1732 print_text(COLOR_ERROR, "Volume Flag: invalid size");
1735 print_field(" Volume Falg: %u", vol_flag);
1739 print_hex_field(" Data", frame->data, frame->size);
1742 static void vol_flag_read(const struct l2cap_frame *frame)
1744 print_vcs_flag(frame);
1747 static void vol_flag_notify(const struct l2cap_frame *frame)
1749 print_vcs_flag(frame);
1752 static char *name2utf8(const uint8_t *name, uint16_t len)
1754 char utf8_name[HCI_MAX_NAME_LENGTH + 2];
1757 if (g_utf8_validate((const char *) name, len, NULL))
1758 return g_strndup((char *) name, len);
1760 len = MIN(len, sizeof(utf8_name) - 1);
1762 memset(utf8_name, 0, sizeof(utf8_name));
1763 strncpy(utf8_name, (char *) name, len);
1765 /* Assume ASCII, and replace all non-ASCII with spaces */
1766 for (i = 0; utf8_name[i] != '\0'; i++) {
1767 if (!isascii(utf8_name[i]))
1771 /* Remove leading and trailing whitespace characters */
1772 g_strstrip(utf8_name);
1774 return g_strdup(utf8_name);
1777 static void print_mp_name(const struct l2cap_frame *frame)
1781 name = name2utf8((uint8_t *)frame->data, frame->size);
1783 print_field(" Media Player Name: %s", name);
1786 static void mp_name_read(const struct l2cap_frame *frame)
1788 print_mp_name(frame);
1791 static void mp_name_notify(const struct l2cap_frame *frame)
1793 print_mp_name(frame);
1796 static void print_track_changed(const struct l2cap_frame *frame)
1798 print_field(" Track Changed");
1801 static void track_changed_notify(const struct l2cap_frame *frame)
1803 print_track_changed(frame);
1806 static void print_track_title(const struct l2cap_frame *frame)
1810 name = name2utf8((uint8_t *)frame->data, frame->size);
1812 print_field(" Track Title: %s", name);
1815 static void track_title_read(const struct l2cap_frame *frame)
1817 print_track_title(frame);
1820 static void track_title_notify(const struct l2cap_frame *frame)
1822 print_track_title(frame);
1825 static void print_track_duration(const struct l2cap_frame *frame)
1829 if (!l2cap_frame_get_le32((void *)frame, (uint32_t *)&duration)) {
1830 print_text(COLOR_ERROR, " Track Duration: invalid size");
1834 print_field(" Track Duration: %u", duration);
1838 print_hex_field(" Data", frame->data, frame->size);
1841 static void track_duration_read(const struct l2cap_frame *frame)
1843 print_track_duration(frame);
1846 static void track_duration_notify(const struct l2cap_frame *frame)
1848 print_track_duration(frame);
1851 static void print_track_position(const struct l2cap_frame *frame)
1855 if (!l2cap_frame_get_le32((void *)frame, (uint32_t *)&position)) {
1856 print_text(COLOR_ERROR, " Track Position: invalid size");
1860 print_field(" Track Position: %u", position);
1864 print_hex_field(" Data", frame->data, frame->size);
1867 static void track_position_read(const struct l2cap_frame *frame)
1869 print_track_position(frame);
1872 static void track_position_write(const struct l2cap_frame *frame)
1874 print_track_position(frame);
1877 static void track_position_notify(const struct l2cap_frame *frame)
1879 print_track_position(frame);
1882 static void print_playback_speed(const struct l2cap_frame *frame)
1884 int8_t playback_speed;
1886 if (!l2cap_frame_get_u8((void *)frame, (uint8_t *)&playback_speed)) {
1887 print_text(COLOR_ERROR, " Playback Speed: invalid size");
1891 print_field(" Playback Speed: %u", playback_speed);
1895 print_hex_field(" Data", frame->data, frame->size);
1898 static void playback_speed_read(const struct l2cap_frame *frame)
1900 print_playback_speed(frame);
1903 static void playback_speed_write(const struct l2cap_frame *frame)
1905 print_playback_speed(frame);
1908 static void playback_speed_notify(const struct l2cap_frame *frame)
1910 print_playback_speed(frame);
1913 static void print_seeking_speed(const struct l2cap_frame *frame)
1915 int8_t seeking_speed;
1917 if (!l2cap_frame_get_u8((void *)frame, (uint8_t *)&seeking_speed)) {
1918 print_text(COLOR_ERROR, " Seeking Speed: invalid size");
1922 print_field(" Seeking Speed: %u", seeking_speed);
1926 print_hex_field(" Data", frame->data, frame->size);
1929 static void seeking_speed_read(const struct l2cap_frame *frame)
1931 print_seeking_speed(frame);
1934 static void seeking_speed_notify(const struct l2cap_frame *frame)
1936 print_seeking_speed(frame);
1939 static const char *play_order_str(uint8_t order)
1943 return "Single once";
1945 return "Single repeat";
1947 return "In order once";
1949 return "In order repeat";
1951 return "Oldest once";
1953 return "Oldest repeat";
1955 return "Newest once";
1957 return "Newest repeat";
1959 return "Shuffle once";
1961 return "Shuffle repeat";
1967 static void print_playing_order(const struct l2cap_frame *frame)
1969 int8_t playing_order;
1971 if (!l2cap_frame_get_u8((void *)frame, (uint8_t *)&playing_order)) {
1972 print_text(COLOR_ERROR, " Playing Order: invalid size");
1976 print_field(" Playing Order: %s", play_order_str(playing_order));
1980 print_hex_field(" Data", frame->data, frame->size);
1983 static void playing_order_read(const struct l2cap_frame *frame)
1985 print_playing_order(frame);
1988 static void playing_order_write(const struct l2cap_frame *frame)
1990 print_playing_order(frame);
1993 static void playing_order_notify(const struct l2cap_frame *frame)
1995 print_playing_order(frame);
1998 static const struct bitfield_data playing_orders_table[] = {
1999 { 0, "Single once (0x0001)" },
2000 { 1, "Single repeat (0x0002)" },
2001 { 2, "In order once (0x0004)" },
2002 { 3, "In Order Repeat (0x0008)" },
2003 { 4, "Oldest once (0x0010)" },
2004 { 5, "Oldest repeat (0x0020)" },
2005 { 6, "Newest once (0x0040)" },
2006 { 7, "Newest repeat (0x0080)" },
2007 { 8, "Shuffle once (0x0100)" },
2008 { 9, "Shuffle repeat (0x0200)" },
2009 { 10, "RFU (0x0400)" },
2010 { 11, "RFU (0x0800)" },
2011 { 12, "RFU (0x1000)" },
2012 { 13, "RFU (0x2000)" },
2013 { 14, "RFU (0x4000)" },
2014 { 15, "RFU (0x8000)" },
2018 static void print_playing_orders_supported(const struct l2cap_frame *frame)
2020 uint16_t supported_orders;
2023 if (!l2cap_frame_get_le16((void *)frame, &supported_orders)) {
2024 print_text(COLOR_ERROR,
2025 " Supported Playing Orders: invalid size");
2029 print_field(" Supported Playing Orders: 0x%4.4x",
2032 mask = print_bitfield(8, supported_orders, playing_orders_table);
2034 print_text(COLOR_WHITE_BG, " Unknown fields (0x%4.4x)",
2039 print_hex_field(" Data", frame->data, frame->size);
2042 static void playing_orders_supported_read(const struct l2cap_frame *frame)
2044 print_playing_orders_supported(frame);
2047 static const char *media_state_str(uint8_t state)
2063 static void print_media_state(const struct l2cap_frame *frame)
2067 if (!l2cap_frame_get_u8((void *)frame, (uint8_t *)&state)) {
2068 print_text(COLOR_ERROR, " Media State: invalid size");
2072 print_field(" Media State: %s", media_state_str(state));
2076 print_hex_field(" Data", frame->data, frame->size);
2079 static void media_state_read(const struct l2cap_frame *frame)
2081 print_media_state(frame);
2084 static void media_state_notify(const struct l2cap_frame *frame)
2086 print_media_state(frame);
2089 struct media_cp_opcode {
2091 const char *opcode_str;
2092 } media_cp_opcode_table[] = {
2095 {0x03, "Fast Rewind"},
2096 {0x04, "Fast Forward"},
2098 {0x10, "Move Relative"},
2099 {0x20, "Previous Segment"},
2100 {0x21, "Next Segment"},
2101 {0x22, "First Segment"},
2102 {0x23, "Last Segment"},
2103 {0x24, "Goto Segment"},
2104 {0x30, "Previous Track"},
2105 {0x31, "Next Track"},
2106 {0x32, "First Track"},
2107 {0x33, "Last Track"},
2108 {0x34, "Goto Track"},
2109 {0x40, "Previous Group"},
2110 {0x41, "Next Group"},
2111 {0x42, "First Group"},
2112 {0x43, "Last Group"},
2113 {0x44, "Goto Group"},
2116 static const char *cp_opcode_str(uint8_t opcode)
2120 for (i = 0; i < ARRAY_SIZE(media_cp_opcode_table); i++) {
2121 const char *str = media_cp_opcode_table[i].opcode_str;
2123 if (opcode == media_cp_opcode_table[i].opcode)
2130 static void print_media_cp(const struct l2cap_frame *frame)
2134 if (!l2cap_frame_get_u8((void *)frame, (uint8_t *)&opcode)) {
2135 print_text(COLOR_ERROR, " Media Control Point: invalid size");
2139 print_field(" Media Control Point: %s", cp_opcode_str(opcode));
2143 print_hex_field(" Data", frame->data, frame->size);
2146 static void media_cp_write(const struct l2cap_frame *frame)
2148 print_media_cp(frame);
2151 static void media_cp_notify(const struct l2cap_frame *frame)
2153 print_media_cp(frame);
2156 static const struct bitfield_data supported_opcodes_table[] = {
2157 {0, "Play (0x00000001)" },
2158 {1, "Pause (0x00000002)" },
2159 {2, "Fast Rewind (0x00000004)" },
2160 {3, "Fast Forward (0x00000008)" },
2161 {4, "Stop (0x00000010)" },
2162 {5, "Move Relative (0x00000020)" },
2163 {6, "Previous Segment (0x00000040)" },
2164 {7, "Next Segment (0x00000080)" },
2165 {8, "First Segment (0x00000100)" },
2166 {9, "Last Segment (0x00000200)" },
2167 {10, "Goto Segment (0x00000400)" },
2168 {11, "Previous Track (0x00000800)" },
2169 {12, "Next Track (0x00001000)" },
2170 {13, "First Track (0x00002000)" },
2171 {14, "Last Track (0x00004000)" },
2172 {15, "Goto Track (0x00008000)" },
2173 {16, "Previous Group (0x00010000)" },
2174 {17, "Next Group (0x00020000)" },
2175 {18, "First Group (0x00040000)" },
2176 {19, "Last Group (0x00080000)" },
2177 {20, "Goto Group (0x00100000)" },
2178 {21, "RFU (0x00200000)" },
2179 {22, "RFU (0x00400000)" },
2180 {23, "RFU (0x00800000)" },
2181 {24, "RFU (0x01000000)" },
2182 {25, "RFU (0x02000000)" },
2183 {26, "RFU (0x04000000)" },
2184 {27, "RFU (0x08000000)" },
2185 {28, "RFU (0x10000000)" },
2186 {29, "RFU (0x20000000)" },
2187 {30, "RFU (0x40000000)" },
2188 {31, "RFU (0x80000000)" },
2192 static void print_media_cp_op_supported(const struct l2cap_frame *frame)
2194 uint32_t supported_opcodes;
2197 if (!l2cap_frame_get_le32((void *)frame, &supported_opcodes)) {
2198 print_text(COLOR_ERROR, " value: invalid size");
2202 print_field(" Supported Opcodes: 0x%8.8x", supported_opcodes);
2204 mask = print_bitfield(8, supported_opcodes, supported_opcodes_table);
2206 print_text(COLOR_WHITE_BG, " Unknown fields (0x%4.4x)",
2211 print_hex_field(" Data", frame->data, frame->size);
2214 static void media_cp_op_supported_read(const struct l2cap_frame *frame)
2216 print_media_cp_op_supported(frame);
2219 static void media_cp_op_supported_notify(const struct l2cap_frame *frame)
2221 print_media_cp_op_supported(frame);
2224 static void print_content_control_id(const struct l2cap_frame *frame)
2228 if (!l2cap_frame_get_u8((void *)frame, (uint8_t *)&ccid)) {
2229 print_text(COLOR_ERROR, " Content Control ID: invalid size");
2233 print_field(" Content Control ID: 0x%2.2x", ccid);
2237 print_hex_field(" Data", frame->data, frame->size);
2240 static void content_control_id_read(const struct l2cap_frame *frame)
2242 print_content_control_id(frame);
2245 #define GATT_HANDLER(_uuid, _read, _write, _notify) \
2248 .type = BT_UUID16, \
2249 .value.u16 = _uuid, \
2256 struct gatt_handler {
2258 void (*read)(const struct l2cap_frame *frame);
2259 void (*write)(const struct l2cap_frame *frame);
2260 void (*notify)(const struct l2cap_frame *frame);
2261 } gatt_handlers[] = {
2262 GATT_HANDLER(0x2902, ccc_read, ccc_write, NULL),
2263 GATT_HANDLER(0x2bc4, ase_read, NULL, ase_notify),
2264 GATT_HANDLER(0x2bc5, ase_read, NULL, ase_notify),
2265 GATT_HANDLER(0x2bc6, NULL, ase_cp_write, ase_cp_notify),
2266 GATT_HANDLER(0x2bc9, pac_read, NULL, pac_notify),
2267 GATT_HANDLER(0x2bca, pac_loc_read, NULL, pac_loc_notify),
2268 GATT_HANDLER(0x2bcb, pac_read, NULL, pac_notify),
2269 GATT_HANDLER(0x2bcc, pac_loc_read, NULL, pac_loc_notify),
2270 GATT_HANDLER(0x2bcd, pac_context_read, NULL, pac_context_notify),
2271 GATT_HANDLER(0x2bce, pac_context_read, NULL, pac_context_notify),
2272 GATT_HANDLER(0x2b7d, vol_state_read, NULL, vol_state_notify),
2273 GATT_HANDLER(0x2b7e, NULL, vol_cp_write, NULL),
2274 GATT_HANDLER(0x2b7f, vol_flag_read, NULL, vol_flag_notify),
2275 GATT_HANDLER(0x2b93, mp_name_read, NULL, mp_name_notify),
2276 GATT_HANDLER(0x2b96, NULL, NULL, track_changed_notify),
2277 GATT_HANDLER(0x2b97, track_title_read, NULL, track_title_notify),
2278 GATT_HANDLER(0x2b98, track_duration_read, NULL, track_duration_notify),
2279 GATT_HANDLER(0x2b99, track_position_read, track_position_write,
2280 track_position_notify),
2281 GATT_HANDLER(0x2b9a, playback_speed_read, playback_speed_write,
2282 playback_speed_notify),
2283 GATT_HANDLER(0x2b9b, seeking_speed_read, NULL, seeking_speed_notify),
2284 GATT_HANDLER(0x2ba1, playing_order_read, playing_order_write,
2285 playing_order_notify),
2286 GATT_HANDLER(0x2ba2, playing_orders_supported_read, NULL, NULL),
2287 GATT_HANDLER(0x2ba3, media_state_read, NULL, media_state_notify),
2288 GATT_HANDLER(0x2ba4, NULL, media_cp_write, media_cp_notify),
2289 GATT_HANDLER(0x2ba5, media_cp_op_supported_read, NULL,
2290 media_cp_op_supported_notify),
2291 GATT_HANDLER(0x2bba, content_control_id_read, NULL, NULL),
2294 static struct gatt_handler *get_handler(struct gatt_db_attribute *attr)
2296 const bt_uuid_t *uuid = gatt_db_attribute_get_type(attr);
2299 for (i = 0; i < ARRAY_SIZE(gatt_handlers); i++) {
2300 struct gatt_handler *handler = &gatt_handlers[i];
2302 if (!bt_uuid_cmp(&handler->uuid, uuid))
2309 static void att_exchange_mtu_req(const struct l2cap_frame *frame)
2311 const struct bt_l2cap_att_exchange_mtu_req *pdu = frame->data;
2313 print_field("Client RX MTU: %d", le16_to_cpu(pdu->mtu));
2316 static void att_exchange_mtu_rsp(const struct l2cap_frame *frame)
2318 const struct bt_l2cap_att_exchange_mtu_rsp *pdu = frame->data;
2320 print_field("Server RX MTU: %d", le16_to_cpu(pdu->mtu));
2323 static void att_find_info_req(const struct l2cap_frame *frame)
2325 print_handle_range("Handle range", frame->data);
2328 static const char *att_format_str(uint8_t format)
2340 static uint16_t print_info_data_16(const void *data, uint16_t len)
2343 print_field("Handle: 0x%4.4x", get_le16(data));
2344 print_uuid("UUID", data + 2, 2);
2352 static uint16_t print_info_data_128(const void *data, uint16_t len)
2355 print_field("Handle: 0x%4.4x", get_le16(data));
2356 print_uuid("UUID", data + 2, 16);
2364 static void att_find_info_rsp(const struct l2cap_frame *frame)
2366 const uint8_t *format = frame->data;
2369 print_field("Format: %s (0x%2.2x)", att_format_str(*format), *format);
2371 if (*format == 0x01)
2372 len = print_info_data_16(frame->data + 1, frame->size - 1);
2373 else if (*format == 0x02)
2374 len = print_info_data_128(frame->data + 1, frame->size - 1);
2376 len = frame->size - 1;
2378 packet_hexdump(frame->data + (frame->size - len), len);
2381 static void att_find_by_type_val_req(const struct l2cap_frame *frame)
2385 print_handle_range("Handle range", frame->data);
2387 type = get_le16(frame->data + 4);
2388 print_attribute_info(type, frame->data + 6, frame->size - 6);
2391 static void att_find_by_type_val_rsp(const struct l2cap_frame *frame)
2393 const uint8_t *ptr = frame->data;
2394 uint16_t len = frame->size;
2397 print_handle_range("Handle range", ptr);
2402 packet_hexdump(ptr, len);
2405 static void att_read_type_req(const struct l2cap_frame *frame)
2407 print_handle_range("Handle range", frame->data);
2408 print_uuid("Attribute type", frame->data + 4, frame->size - 4);
2411 static void att_read_type_rsp(const struct l2cap_frame *frame)
2413 const struct bt_l2cap_att_read_group_type_rsp *pdu = frame->data;
2415 print_field("Attribute data length: %d", pdu->length);
2416 print_data_list("Attribute data list", pdu->length,
2417 frame->data + 1, frame->size - 1);
2421 struct gatt_db_attribute *attr;
2424 void (*func)(const struct l2cap_frame *frame);
2427 struct att_conn_data {
2428 struct gatt_db *ldb;
2429 struct timespec ldb_mtim;
2430 struct gatt_db *rdb;
2431 struct timespec rdb_mtim;
2432 struct queue *reads;
2435 static void att_conn_data_free(void *data)
2437 struct att_conn_data *att_data = data;
2439 gatt_db_unref(att_data->rdb);
2440 gatt_db_unref(att_data->ldb);
2441 queue_destroy(att_data->reads, free);
2445 static void gatt_load_db(struct gatt_db *db, const char *filename,
2446 struct timespec *mtim)
2450 if (lstat(filename, &st))
2453 if (!gatt_db_isempty(db)) {
2454 /* Check if file has been modified since last time */
2455 if (st.st_mtim.tv_sec == mtim->tv_sec &&
2456 st.st_mtim.tv_nsec == mtim->tv_nsec)
2458 /* Clear db before reloading */
2464 btd_settings_gatt_db_load(db, filename);
2467 static void load_gatt_db(struct packet_conn_data *conn)
2469 struct att_conn_data *data = conn->data;
2470 char filename[PATH_MAX];
2475 data = new0(struct att_conn_data, 1);
2476 data->rdb = gatt_db_new();
2477 data->ldb = gatt_db_new();
2479 conn->destroy = att_conn_data_free;
2482 ba2str((bdaddr_t *)conn->src, local);
2483 ba2str((bdaddr_t *)conn->dst, peer);
2485 create_filename(filename, PATH_MAX, "/%s/attributes", local);
2486 gatt_load_db(data->ldb, filename, &data->ldb_mtim);
2488 create_filename(filename, PATH_MAX, "/%s/cache/%s", local, peer);
2489 gatt_load_db(data->rdb, filename, &data->rdb_mtim);
2492 static struct gatt_db_attribute *get_attribute(const struct l2cap_frame *frame,
2493 uint16_t handle, bool rsp)
2495 struct packet_conn_data *conn;
2496 struct att_conn_data *data;
2499 conn = packet_get_conn_data(frame->handle);
2503 /* Try loading local and remote gatt_db if not loaded yet */
2522 return gatt_db_get_attribute(db, handle);
2525 static void print_attribute(struct gatt_db_attribute *attr)
2527 uint16_t handle = gatt_db_attribute_get_handle(attr);
2528 const bt_uuid_t *uuid;
2531 uuid = gatt_db_attribute_get_type(attr);
2535 switch (uuid->type) {
2537 sprintf(label, "Handle: 0x%4.4x Type", handle);
2538 print_field("%s: %s (0x%4.4x)", label,
2539 bt_uuid16_to_str(uuid->value.u16),
2543 sprintf(label, "Handle: 0x%4.4x Type", handle);
2544 print_uuid(label, &uuid->value.u128, 16);
2546 case BT_UUID_UNSPEC:
2552 print_field("Handle: 0x%4.4x", handle);
2555 static void print_handle(const struct l2cap_frame *frame, uint16_t handle,
2558 struct gatt_db_attribute *attr;
2560 attr = get_attribute(frame, handle, rsp);
2562 print_field("Handle: 0x%4.4x", handle);
2566 print_attribute(attr);
2569 static void att_read_req(const struct l2cap_frame *frame)
2571 const struct bt_l2cap_att_read_req *pdu = frame->data;
2573 struct packet_conn_data *conn;
2574 struct att_conn_data *data;
2575 struct att_read *read;
2576 struct gatt_db_attribute *attr;
2577 struct gatt_handler *handler;
2579 l2cap_frame_pull((void *)frame, frame, sizeof(*pdu));
2581 handle = le16_to_cpu(pdu->handle);
2582 print_handle(frame, handle, false);
2584 attr = get_attribute(frame, handle, false);
2588 handler = get_handler(attr);
2589 if (!handler || !handler->read)
2592 conn = packet_get_conn_data(frame->handle);
2596 data->reads = queue_new();
2598 read = new0(struct att_read, 1);
2600 read->in = frame->in;
2601 read->chan = frame->chan;
2602 read->func = handler->read;
2604 queue_push_tail(data->reads, read);
2607 static bool match_read_frame(const void *data, const void *match_data)
2609 const struct att_read *read = data;
2610 const struct l2cap_frame *frame = match_data;
2612 /* Read frame and response frame shall be in the opposite direction to
2615 if (read->in == frame->in)
2618 return read->chan == frame->chan;
2621 static void att_read_rsp(const struct l2cap_frame *frame)
2623 struct packet_conn_data *conn;
2624 struct att_conn_data *data;
2625 struct att_read *read;
2627 print_hex_field("Value", frame->data, frame->size);
2629 conn = packet_get_conn_data(frame->handle);
2635 read = queue_remove_if(data->reads, match_read_frame, (void *)frame);
2639 print_attribute(read->attr);
2646 static void att_read_blob_req(const struct l2cap_frame *frame)
2648 print_handle(frame, get_le16(frame->data), false);
2649 print_field("Offset: 0x%4.4x", get_le16(frame->data + 2));
2652 static void att_read_blob_rsp(const struct l2cap_frame *frame)
2654 packet_hexdump(frame->data, frame->size);
2657 static void att_read_multiple_req(const struct l2cap_frame *frame)
2661 count = frame->size / 2;
2663 for (i = 0; i < count; i++)
2664 print_handle(frame, get_le16(frame->data + (i * 2)), false);
2667 static void att_read_group_type_req(const struct l2cap_frame *frame)
2669 print_handle_range("Handle range", frame->data);
2670 print_uuid("Attribute group type", frame->data + 4, frame->size - 4);
2673 static void print_group_list(const char *label, uint8_t length,
2674 const void *data, uint16_t size)
2681 count = size / length;
2683 print_field("%s: %u entr%s", label, count, count == 1 ? "y" : "ies");
2685 while (size >= length) {
2686 print_handle_range("Handle range", data);
2687 print_uuid("UUID", data + 4, length - 4);
2693 packet_hexdump(data, size);
2696 static void att_read_group_type_rsp(const struct l2cap_frame *frame)
2698 const struct bt_l2cap_att_read_group_type_rsp *pdu = frame->data;
2700 print_field("Attribute data length: %d", pdu->length);
2701 print_group_list("Attribute group list", pdu->length,
2702 frame->data + 1, frame->size - 1);
2705 static void print_write(const struct l2cap_frame *frame, uint16_t handle,
2708 struct gatt_db_attribute *attr;
2709 struct gatt_handler *handler;
2711 print_handle(frame, handle, false);
2712 print_hex_field(" Data", frame->data, frame->size);
2714 if (len > frame->size) {
2715 print_text(COLOR_ERROR, "invalid size");
2719 attr = get_attribute(frame, handle, false);
2723 handler = get_handler(attr);
2727 handler->write(frame);
2730 static void att_write_req(const struct l2cap_frame *frame)
2734 if (!l2cap_frame_get_le16((void *)frame, &handle)) {
2735 print_text(COLOR_ERROR, "invalid size");
2739 print_write(frame, handle, frame->size);
2742 static void att_write_rsp(const struct l2cap_frame *frame)
2746 static void att_prepare_write_req(const struct l2cap_frame *frame)
2748 print_handle(frame, get_le16(frame->data), false);
2749 print_field("Offset: 0x%4.4x", get_le16(frame->data + 2));
2750 print_hex_field(" Data", frame->data + 4, frame->size - 4);
2753 static void att_prepare_write_rsp(const struct l2cap_frame *frame)
2755 print_handle(frame, get_le16(frame->data), true);
2756 print_field("Offset: 0x%4.4x", get_le16(frame->data + 2));
2757 print_hex_field(" Data", frame->data + 4, frame->size - 4);
2760 static void att_execute_write_req(const struct l2cap_frame *frame)
2762 uint8_t flags = *(uint8_t *) frame->data;
2763 const char *flags_str;
2767 flags_str = "Cancel all prepared writes";
2770 flags_str = "Immediately write all pending values";
2773 flags_str = "Unknown";
2777 print_field("Flags: %s (0x%02x)", flags_str, flags);
2780 static void print_notify(const struct l2cap_frame *frame, uint16_t handle,
2783 struct gatt_db_attribute *attr;
2784 struct gatt_handler *handler;
2785 struct l2cap_frame clone;
2787 print_handle(frame, handle, true);
2788 print_hex_field(" Data", frame->data, len);
2790 if (len > frame->size) {
2791 print_text(COLOR_ERROR, "invalid size");
2795 attr = get_attribute(frame, handle, true);
2799 handler = get_handler(attr);
2803 /* Use a clone if the callback is not expected to parse the whole
2806 if (len != frame->size) {
2807 l2cap_frame_clone(&clone, frame);
2812 handler->notify(frame);
2815 static void att_handle_value_notify(const struct l2cap_frame *frame)
2818 const struct bt_l2cap_att_handle_value_notify *pdu = frame->data;
2820 l2cap_frame_pull((void *)frame, frame, sizeof(*pdu));
2822 handle = le16_to_cpu(pdu->handle);
2823 print_notify(frame, handle, frame->size);
2826 static void att_handle_value_ind(const struct l2cap_frame *frame)
2828 const struct bt_l2cap_att_handle_value_ind *pdu = frame->data;
2830 l2cap_frame_pull((void *)frame, frame, sizeof(*pdu));
2832 print_notify(frame, le16_to_cpu(pdu->handle), frame->size);
2835 static void att_handle_value_conf(const struct l2cap_frame *frame)
2839 static void att_multiple_vl_rsp(const struct l2cap_frame *frame)
2841 struct l2cap_frame *f = (void *) frame;
2843 while (frame->size) {
2847 if (!l2cap_frame_get_le16(f, &handle))
2850 if (!l2cap_frame_get_le16(f, &len))
2853 print_field("Length: 0x%4.4x", len);
2855 print_notify(frame, handle, len);
2857 l2cap_frame_pull(f, f, len);
2861 static void att_write_command(const struct l2cap_frame *frame)
2865 if (!l2cap_frame_get_le16((void *)frame, &handle)) {
2866 print_text(COLOR_ERROR, "invalid size");
2870 print_write(frame, handle, frame->size);
2873 static void att_signed_write_command(const struct l2cap_frame *frame)
2877 if (!l2cap_frame_get_le16((void *)frame, &handle)) {
2878 print_text(COLOR_ERROR, "invalid size");
2882 print_write(frame, handle, frame->size - 12);
2883 print_hex_field(" Data", frame->data, frame->size - 12);
2884 print_hex_field(" Signature", frame->data + frame->size - 12, 12);
2887 struct att_opcode_data {
2890 void (*func) (const struct l2cap_frame *frame);
2895 static const struct att_opcode_data att_opcode_table[] = {
2896 { 0x01, "Error Response",
2897 att_error_response, 4, true },
2898 { 0x02, "Exchange MTU Request",
2899 att_exchange_mtu_req, 2, true },
2900 { 0x03, "Exchange MTU Response",
2901 att_exchange_mtu_rsp, 2, true },
2902 { 0x04, "Find Information Request",
2903 att_find_info_req, 4, true },
2904 { 0x05, "Find Information Response",
2905 att_find_info_rsp, 5, false },
2906 { 0x06, "Find By Type Value Request",
2907 att_find_by_type_val_req, 6, false },
2908 { 0x07, "Find By Type Value Response",
2909 att_find_by_type_val_rsp, 4, false },
2910 { 0x08, "Read By Type Request",
2911 att_read_type_req, 6, false },
2912 { 0x09, "Read By Type Response",
2913 att_read_type_rsp, 3, false },
2914 { 0x0a, "Read Request",
2915 att_read_req, 2, true },
2916 { 0x0b, "Read Response",
2917 att_read_rsp, 0, false },
2918 { 0x0c, "Read Blob Request",
2919 att_read_blob_req, 4, true },
2920 { 0x0d, "Read Blob Response",
2921 att_read_blob_rsp, 0, false },
2922 { 0x0e, "Read Multiple Request",
2923 att_read_multiple_req, 4, false },
2924 { 0x0f, "Read Multiple Response" },
2925 { 0x10, "Read By Group Type Request",
2926 att_read_group_type_req, 6, false },
2927 { 0x11, "Read By Group Type Response",
2928 att_read_group_type_rsp, 4, false },
2929 { 0x12, "Write Request" ,
2930 att_write_req, 2, false },
2931 { 0x13, "Write Response",
2932 att_write_rsp, 0, true },
2933 { 0x16, "Prepare Write Request",
2934 att_prepare_write_req, 4, false },
2935 { 0x17, "Prepare Write Response",
2936 att_prepare_write_rsp, 4, false },
2937 { 0x18, "Execute Write Request",
2938 att_execute_write_req, 1, true },
2939 { 0x19, "Execute Write Response" },
2940 { 0x1b, "Handle Value Notification",
2941 att_handle_value_notify, 2, false },
2942 { 0x1d, "Handle Value Indication",
2943 att_handle_value_ind, 2, false },
2944 { 0x1e, "Handle Value Confirmation",
2945 att_handle_value_conf, 0, true },
2946 { 0x20, "Read Multiple Request Variable Length",
2947 att_read_multiple_req, 4, false },
2948 { 0x21, "Read Multiple Response Variable Length",
2949 att_multiple_vl_rsp, 4, false },
2950 { 0x23, "Handle Multiple Value Notification",
2951 att_multiple_vl_rsp, 4, false },
2952 { 0x52, "Write Command",
2953 att_write_command, 2, false },
2954 { 0xd2, "Signed Write Command", att_signed_write_command, 14, false },
2958 static const char *att_opcode_to_str(uint8_t opcode)
2962 for (i = 0; att_opcode_table[i].str; i++) {
2963 if (att_opcode_table[i].opcode == opcode)
2964 return att_opcode_table[i].str;
2970 void att_packet(uint16_t index, bool in, uint16_t handle, uint16_t cid,
2971 const void *data, uint16_t size)
2973 struct l2cap_frame frame;
2974 uint8_t opcode = *((const uint8_t *) data);
2975 const struct att_opcode_data *opcode_data = NULL;
2976 const char *opcode_color, *opcode_str;
2980 print_text(COLOR_ERROR, "malformed attribute packet");
2981 packet_hexdump(data, size);
2985 for (i = 0; att_opcode_table[i].str; i++) {
2986 if (att_opcode_table[i].opcode == opcode) {
2987 opcode_data = &att_opcode_table[i];
2993 if (opcode_data->func) {
2995 opcode_color = COLOR_MAGENTA;
2997 opcode_color = COLOR_BLUE;
2999 opcode_color = COLOR_WHITE_BG;
3000 opcode_str = opcode_data->str;
3002 opcode_color = COLOR_WHITE_BG;
3003 opcode_str = "Unknown";
3006 print_indent(6, opcode_color, "ATT: ", opcode_str, COLOR_OFF,
3007 " (0x%2.2x) len %d", opcode, size - 1);
3009 if (!opcode_data || !opcode_data->func) {
3010 packet_hexdump(data + 1, size - 1);
3014 if (opcode_data->fixed) {
3015 if (size - 1 != opcode_data->size) {
3016 print_text(COLOR_ERROR, "invalid size");
3017 packet_hexdump(data + 1, size - 1);
3021 if (size - 1 < opcode_data->size) {
3022 print_text(COLOR_ERROR, "too short packet");
3023 packet_hexdump(data + 1, size - 1);
3028 l2cap_frame_init(&frame, index, in, handle, 0, cid, 0,
3029 data + 1, size - 1);
3030 opcode_data->func(&frame);