3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2004-2011 Marcel Holtmann <marcel@holtmann.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
36 static char *si2str(uint8_t si)
42 return "Capabilities";
62 return "All Capabilities";
64 return "Delay Report";
70 static char *pt2str(uint8_t hdr)
86 static char *mt2str(uint8_t hdr)
100 static char *media2str(uint8_t type)
114 static char *codec2str(uint8_t type, uint8_t codec)
122 return "MPEG-1,2 Audio";
124 return "MPEG-2,4 AAC";
126 return "ATRAC family";
136 return "H.263 baseline";
138 return "MPEG-4 Visual Simple Profile";
140 return "H.263 profile 3";
142 return "H.263 profile 8";
153 static char *vndcodec2str(uint32_t vendor, uint16_t vndcodec)
155 if (vendor == 0x0000004f && vndcodec == 0x0001)
157 else if (vendor == 0x0000012d && vndcodec == 0x00aa)
162 static char *cat2str(uint8_t cat)
166 return "Media Transport";
172 return "Content Protection";
174 return "Header Compression";
176 return "Multiplexing";
178 return "Media Codec";
180 return "Delay Reporting";
186 static void errorcode(int level, struct frame *frm)
190 p_indent(level, frm);
191 code = p_get_u8(frm);
192 printf("Error code %d\n", code);
195 static void acp_seid(int level, struct frame *frm)
199 p_indent(level, frm);
200 seid = p_get_u8(frm);
201 printf("ACP SEID %d\n", seid >> 2);
204 static void acp_int_seid(int level, struct frame *frm)
206 uint8_t acp_seid, int_seid;
208 p_indent(level, frm);
209 acp_seid = p_get_u8(frm);
210 int_seid = p_get_u8(frm);
211 printf("ACP SEID %d - INT SEID %d\n", acp_seid >> 2, int_seid >> 2);
214 static void capabilities(int level, struct frame *frm)
218 while (frm->len > 1) {
219 p_indent(level, frm);
225 uint16_t tmp, freq, vndcodec = 0;
226 uint32_t bitrate, vendor = 0;
229 type = p_get_u8(frm);
230 codec = p_get_u8(frm);
233 vendor = btohl(htonl(p_get_u32(frm)));
234 vndcodec = btohs(htons(p_get_u16(frm)));
236 printf("%s - %s (%s)\n", cat2str(cat),
237 codec2str(type, codec),
238 vndcodec2str(vendor, vndcodec));
240 printf("%s - %s\n", cat2str(cat),
241 codec2str(type, codec));
247 p_indent(level + 1, frm);
257 p_indent(level + 1, frm);
261 printf("DualChannel ");
265 printf("JointStereo ");
268 p_indent(level + 1, frm);
278 p_indent(level + 1, frm);
283 printf("Subbands\n");
284 p_indent(level + 1, frm);
291 p_indent(level + 1, frm);
292 printf("Bitpool Range %d-%d\n", tmp, p_get_u8(frm));
296 p_indent(level + 1, frm);
305 p_indent(level + 1, frm);
306 printf("CRC Protection: %s\n",
307 tmp & 0x10 ? "Yes" : "No");
308 p_indent(level + 1, frm);
312 printf("DualChannel ");
316 printf("JointStereo ");
319 p_indent(level + 1, frm);
320 printf("Media Payload Format: RFC-2250 %s\n",
321 tmp & 0x40 ? "RFC-3119" : "");
322 p_indent(level + 1, frm);
336 tmp = p_get_u16(frm);
337 p_indent(level + 1, frm);
339 tmp & 0x8000 ? "Yes" : "No");
340 p_indent(level + 1, frm);
341 printf("Bit Rate Indexes: ");
345 for (i = 0; i < 15; i++, tmp >>= 1)
353 p_indent(level + 1, frm);
355 printf("MPEG-2 AAC LC ");
357 printf("MPEG-4 AAC LC ");
359 printf("MPEG-4 AAC LTP ");
361 printf("MPEG-4 AAC scalable ");
363 tmp = p_get_u16(frm);
365 p_indent(level + 1, frm);
369 printf("11.025kHz ");
392 p_indent(level + 1, frm);
397 printf("Channels\n");
399 bitrate = ((tmp & 0x7f) << 16) | p_get_u16(frm);
400 p_indent(level + 1, frm);
401 printf("%ubps ", bitrate);
402 printf("%s\n", tmp & 0x80 ? "VBR" : "");
405 if (vendor == 0x0000004f &&
406 vndcodec == 0x0001) {
408 p_indent(level + 1, frm);
418 p_indent(level + 1, frm);
426 hex_dump(level + 1, frm, len - 8);
427 frm->ptr += (len - 8);
428 frm->len -= (len - 8);
432 hex_dump(level + 1, frm, len - 2);
433 frm->ptr += (len - 2);
434 frm->len -= (len - 2);
438 printf("%s\n", cat2str(cat));
439 hex_dump(level + 1, frm, len);
447 static inline void discover(int level, uint8_t hdr, struct frame *frm)
451 switch (hdr & 0x03) {
453 while (frm->len > 1) {
454 p_indent(level, frm);
455 seid = p_get_u8(frm);
456 type = p_get_u8(frm);
457 printf("ACP SEID %d - %s %s%s\n",
458 seid >> 2, media2str(type >> 4),
459 type & 0x08 ? "Sink" : "Source",
460 seid & 0x02 ? " (InUse)" : "");
464 errorcode(level, frm);
469 static inline void get_capabilities(int level, uint8_t hdr, struct frame *frm)
471 switch (hdr & 0x03) {
473 acp_seid(level, frm);
476 capabilities(level, frm);
479 errorcode(level, frm);
484 static inline void set_configuration(int level, uint8_t hdr, struct frame *frm)
488 switch (hdr & 0x03) {
490 acp_int_seid(level, frm);
491 capabilities(level, frm);
494 p_indent(level, frm);
496 printf("%s\n", cat2str(cat));
497 errorcode(level, frm);
502 static inline void get_configuration(int level, uint8_t hdr, struct frame *frm)
504 switch (hdr & 0x03) {
506 acp_seid(level, frm);
508 capabilities(level, frm);
511 errorcode(level, frm);
516 static inline void reconfigure(int level, uint8_t hdr, struct frame *frm)
520 switch (hdr & 0x03) {
522 acp_seid(level, frm);
523 capabilities(level, frm);
526 p_indent(level, frm);
528 printf("%s\n", cat2str(cat));
529 errorcode(level, frm);
534 static inline void open_close_stream(int level, uint8_t hdr, struct frame *frm)
536 switch (hdr & 0x03) {
538 acp_seid(level, frm);
541 errorcode(level, frm);
546 static inline void start_suspend_stream(int level, uint8_t hdr, struct frame *frm)
548 switch (hdr & 0x03) {
551 acp_seid(level, frm);
554 acp_seid(level, frm);
555 errorcode(level, frm);
560 static inline void abort_streaming(int level, uint8_t hdr, struct frame *frm)
562 switch (hdr & 0x03) {
564 acp_seid(level, frm);
569 static inline void security(int level, uint8_t hdr, struct frame *frm)
571 switch (hdr & 0x03) {
573 acp_seid(level, frm);
575 hex_dump(level + 1, frm, frm->len);
576 frm->ptr += frm->len;
580 errorcode(level, frm);
585 static inline void delay_report(int level, uint8_t hdr, struct frame *frm)
590 switch (hdr & 0x03) {
592 p_indent(level, frm);
593 seid = p_get_u8(frm);
594 delay = p_get_u16(frm);
595 printf("ACP SEID %d delay %u.%ums\n", seid >> 2,
596 delay / 10, delay % 10);
599 errorcode(level, frm);
604 void avdtp_dump(int level, struct frame *frm)
606 uint8_t hdr, sid, nsp, type;
612 p_indent(level, frm);
615 nsp = (hdr & 0x0c) == 0x04 ? p_get_u8(frm) : 0;
616 sid = hdr & 0x08 ? 0x00 : p_get_u8(frm);
618 printf("AVDTP(s): %s %s: transaction %d nsp 0x%02x\n",
619 hdr & 0x08 ? pt2str(hdr) : si2str(sid),
620 mt2str(hdr), hdr >> 4, nsp);
622 switch (sid & 0x7f) {
624 discover(level + 1, hdr, frm);
628 get_capabilities(level + 1, hdr, frm);
631 set_configuration(level + 1, hdr, frm);
634 get_configuration(level + 1, hdr, frm);
637 reconfigure(level + 1, hdr, frm);
640 open_close_stream(level + 1, hdr, frm);
643 start_suspend_stream(level + 1, hdr, frm);
646 open_close_stream(level + 1, hdr, frm);
649 start_suspend_stream(level + 1, hdr, frm);
652 abort_streaming(level + 1, hdr, frm);
655 security(level + 1, hdr, frm);
658 delay_report(level + 1, hdr, frm);
665 p_indent(level, frm);
667 type = p_get_u8(frm);
668 seqn = p_get_u16(frm);
669 time = p_get_u32(frm);
670 ssrc = p_get_u32(frm);
672 printf("AVDTP(m): ver %d %s%scc %d %spt %d seqn %d time %d ssrc %d\n",
673 hdr >> 6, hdr & 0x20 ? "pad " : "", hdr & 0x10 ? "ext " : "",
674 hdr & 0xf, type & 0x80 ? "mark " : "", type & 0x7f, seqn, time, ssrc);
678 raw_dump(level, frm);