avdtp.c revision 1f2ab27c77f01e4aa213844bc3409634eea24d4a
1d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann/* 2d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * 3d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * Bluetooth packet analyzer - AVDTP parser 4d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * 5d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * Copyright (C) 2004 Marcel Holtmann <marcel@holtmann.org> 6d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * 7d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * 8d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * This program is free software; you can redistribute it and/or modify 9d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * it under the terms of the GNU General Public License as published by 10d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * the Free Software Foundation; either version 2 of the License, or 11d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * (at your option) any later version. 12d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * 13d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * This program is distributed in the hope that it will be useful, 14d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 15d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * GNU General Public License for more details. 17d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * 18d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * You should have received a copy of the GNU General Public License 19d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * along with this program; if not, write to the Free Software 20d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * 22d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * 23d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann * $Id$ 24d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann */ 25d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 26d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann#include <stdio.h> 27d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann#include <stdlib.h> 28d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann#include <unistd.h> 29d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann#include <errno.h> 30d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann#include <string.h> 31d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 32d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann#include <sys/types.h> 33d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann#include <netinet/in.h> 34d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 35d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann#include "parser.h" 36d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 37d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmannstatic char *si2str(uint8_t si) 38d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann{ 39d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann switch (si & 0x7f) { 40d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x01: 41d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Discover"; 42d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x02: 43d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Capabilities"; 44d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x03: 45d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Set config"; 46d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x04: 47d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Get config"; 48d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x05: 49d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Reconfigure"; 50d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x06: 51d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Open"; 52d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x07: 53d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Start"; 54d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x08: 55d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Close"; 56d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x09: 57d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Suspend"; 58d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x0a: 59d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Abort"; 60d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x0b: 61d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Security"; 62d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann default: 63d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Unknown"; 64d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann } 65d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann} 66d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 67d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmannstatic char *pt2str(uint8_t hdr) 68d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann{ 69d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann switch (hdr & 0x0c) { 70d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x00: 71d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Single"; 72d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x04: 73d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Start"; 74d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x08: 75d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Cont"; 76d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x0c: 77d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "End"; 78d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann default: 79d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "Unk"; 80d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann } 81d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann} 82d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 83d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmannstatic char *mt2str(uint8_t hdr) 84d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann{ 85d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann switch (hdr & 0x03) { 86d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann case 0x00: 87d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "cmd"; 88312106553ff029c8970f23011085a0fe8bf25c66Marcel Holtmann case 0x02: 89d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "rsp"; 90312106553ff029c8970f23011085a0fe8bf25c66Marcel Holtmann case 0x03: 91d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann return "rej"; 92d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann default: 9316dddb442a1e249eea3cce08fbac926d1fd19e1eMarcel Holtmann return "rfd"; 94d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann } 95d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann} 96d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 97563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic char *media2str(uint8_t type) 98563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 99563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (type) { 100563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0: 101563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Audio"; 102563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 1: 103563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Video"; 104563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 2: 105563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Multimedia"; 106563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann default: 107563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Reserved"; 108563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 109563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 110563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 111563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic char *codec2str(uint8_t type, uint8_t codec) 112563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 113563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (type) { 114563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0: 115563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (codec) { 116563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0: 117563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "SBC"; 118563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 1: 119563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "MPEG-1,2 Audio"; 120563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 2: 121563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "MPEG-2,4 AAC"; 122563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 4: 123563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "ATRAC family"; 124563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 255: 125563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "non-A2DP"; 126563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann default: 127563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Reserved"; 128563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 129563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 130563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 1: 131563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (codec) { 132563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 1: 133563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "H.263 baseline"; 134563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 2: 135563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "MPEG-4 Visual Simple Profile"; 136563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 3: 137563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "H.263 profile 3"; 138563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 4: 139563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "H.263 profile 8"; 140563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 255: 141563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Non-VDP"; 142563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann default: 143563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Reserved"; 144563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 145563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 146563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann default: 147563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Unknown"; 148563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 149563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 150563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 151563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic char *cat2str(uint8_t cat) 152563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 153563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (cat) { 154563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 1: 155563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Media Transport"; 156563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 2: 157563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Reporting"; 158563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 3: 159563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Recovery"; 160563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 4: 161563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Content Protection"; 162563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 5: 163563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Header Compression"; 164563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 6: 165563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Multiplexing"; 166563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 7: 167563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Media Codec"; 168563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann default: 169563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann return "Reserved"; 170563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 171563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 172563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 173563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic void errorcode(int level, struct frame *frm) 174563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 175563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann uint8_t code; 176563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 177563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level, frm); 178563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann code = get_u8(frm); 179563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("Error code %d\n", code); 180563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 181563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 182563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic void acp_seid(int level, struct frame *frm) 183563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 184563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann uint8_t seid; 185563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 186563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level, frm); 187563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann seid = get_u8(frm); 188563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("ACP SEID %d\n", seid >> 2); 189563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 190563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 191563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic void acp_int_seid(int level, struct frame *frm) 192563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 193563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann uint8_t acp_seid, int_seid; 194563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 195563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level, frm); 196563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann acp_seid = get_u8(frm); 197563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann int_seid = get_u8(frm); 198563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("ACP SEID %d - INT SEID %d\n", acp_seid >> 2, int_seid >> 2); 199563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 200563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 201563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic void capabilities(int level, struct frame *frm) 202563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 203563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann uint8_t cat, len; 204563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 205563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann while (frm->len > 1) { 206563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level, frm); 207563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann cat = get_u8(frm); 208563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann len = get_u8(frm); 209563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 210563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (cat == 7) { 211563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann uint8_t type, codec, tmp; 212563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 213563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann type = get_u8(frm); 214563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann codec = get_u8(frm); 215563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 216563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("%s - %s\n", cat2str(cat), codec2str(type, codec)); 217563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 218563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (codec) { 219563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0: 220563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann tmp = get_u8(frm); 221563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level + 1, frm); 222563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x80) 223563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("16kHz "); 224563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x40) 225563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("32kHz "); 226563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x20) 227563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("44.1kHz "); 228563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x10) 229563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("48kHz "); 230563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("\n"); 231563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level + 1, frm); 232563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x08) 233563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("Mono "); 234563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x04) 235563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("DualChannel "); 236563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x02) 237563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("Stereo "); 238563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x01) 239563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("JointStereo "); 240563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("\n"); 241563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann tmp = get_u8(frm); 242563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level + 1, frm); 243563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x80) 244563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("4 "); 245563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x40) 246563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("8 "); 247563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x20) 248563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("12 "); 249563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x10) 250563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("16 "); 251563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("Blocks\n"); 252563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level + 1, frm); 253563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x08) 254563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("4 "); 255563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x04) 256563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("8 "); 257563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("Subbands\n"); 258563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level + 1, frm); 259563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x02) 260563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("SNR "); 261563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann if (tmp & 0x01) 262563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("Loudness "); 263563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("\n"); 264563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann tmp = get_u8(frm); 265563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level + 1, frm); 266563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("Bitpool Range %d-%d\n", tmp, get_u8(frm)); 267563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 268563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann default: 269563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann hex_dump(level + 1, frm, len - 2); 270563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann frm->ptr += (len - 2); 271563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann frm->len -= (len - 2); 272563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 273563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 274563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } else { 275563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("%s\n", cat2str(cat)); 276563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann hex_dump(level + 1, frm, len); 277563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 278563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann frm->ptr += len; 279563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann frm->len -= len; 280563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 281563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 282563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 283563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 284563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic inline void discover(int level, uint8_t hdr, struct frame *frm) 285563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 286563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann uint8_t seid, type; 287563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 288563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (hdr & 0x03) { 289563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x02: 290563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann while (frm->len > 1) { 291563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level, frm); 292563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann seid = get_u8(frm); 293563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann type = get_u8(frm); 294563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("ACP SEID %d - %s %s%s\n", 295563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann seid >> 2, media2str(type >> 4), 296563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann type & 0x08 ? "Sink" : "Source", 297563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann seid & 0x02 ? " (InUse)" : ""); 298563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 299563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 300563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x03: 301563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann errorcode(level, frm); 302563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 303563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 304563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 305563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 306563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic inline void get_capabilities(int level, uint8_t hdr, struct frame *frm) 307563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 308563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (hdr & 0x03) { 309563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x00: 310563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann acp_seid(level, frm); 311563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 312563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x02: 313563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann capabilities(level, frm); 314563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 315563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x03: 316563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann errorcode(level, frm); 317563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 318563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 319563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 320563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 321563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic inline void set_configuration(int level, uint8_t hdr, struct frame *frm) 322563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 323563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann uint8_t cat; 324563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 325563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (hdr & 0x03) { 326563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x00: 327563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann acp_int_seid(level, frm); 328563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann capabilities(level, frm); 329563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 330563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x03: 331563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level, frm); 332563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann cat = get_u8(frm); 333563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("%s\n", cat2str(cat)); 334563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann errorcode(level, frm); 335563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 336563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 337563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 338563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 339563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic inline void get_configuration(int level, uint8_t hdr, struct frame *frm) 340563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 341563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (hdr & 0x03) { 342563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x00: 343563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann acp_seid(level, frm); 344563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x02: 345563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann capabilities(level, frm); 346563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 347563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x03: 348563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann errorcode(level, frm); 349563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 350563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 351563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 352563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 353563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic inline void reconfigure(int level, uint8_t hdr, struct frame *frm) 354563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 355563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann uint8_t cat; 356563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 357563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (hdr & 0x03) { 358563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x00: 359563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann acp_seid(level, frm); 360563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann capabilities(level, frm); 361563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 362563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x03: 363563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann p_indent(level, frm); 364563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann cat = get_u8(frm); 365563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann printf("%s\n", cat2str(cat)); 366563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann errorcode(level, frm); 367563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 368563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 369563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 370563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 371563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic inline void open_close_stream(int level, uint8_t hdr, struct frame *frm) 372563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 373563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (hdr & 0x03) { 374563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x00: 375563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann acp_seid(level, frm); 376563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 377563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x03: 378563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann errorcode(level, frm); 379563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 380563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 381563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 382563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 383563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic inline void start_suspend_stream(int level, uint8_t hdr, struct frame *frm) 384563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 385563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (hdr & 0x03) { 386563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x00: 387563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann while (frm->len > 0) 388563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann acp_seid(level, frm); 389563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 390563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x03: 391563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann acp_seid(level, frm); 392563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann errorcode(level, frm); 393563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 394563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 395563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 396563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 397563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic inline void abort_streaming(int level, uint8_t hdr, struct frame *frm) 398563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 399563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (hdr & 0x03) { 400563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x00: 401563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann acp_seid(level, frm); 402563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 403563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 404563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 405563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 406563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmannstatic inline void security(int level, uint8_t hdr, struct frame *frm) 407563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann{ 408563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (hdr & 0x03) { 409563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x00: 410563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann acp_seid(level, frm); 411563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x02: 412563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann hex_dump(level + 1, frm, frm->len); 413563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann frm->ptr += frm->len; 414563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann frm->len = 0; 415563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 416563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x03: 417563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann errorcode(level, frm); 418563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 419563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 420563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann} 421563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 422d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmannvoid avdtp_dump(int level, struct frame *frm) 423d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann{ 424563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann uint8_t hdr, sid, nsp; 425d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 4261f2ab27c77f01e4aa213844bc3409634eea24d4aMarcel Holtmann switch (frm->num) { 4271f2ab27c77f01e4aa213844bc3409634eea24d4aMarcel Holtmann case 1: 4281f2ab27c77f01e4aa213844bc3409634eea24d4aMarcel Holtmann p_indent(level, frm); 429c8958756bc90521ac900ebfeb650bc4d7a8c0a45Marcel Holtmann hdr = get_u8(frm); 430d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 431c8958756bc90521ac900ebfeb650bc4d7a8c0a45Marcel Holtmann nsp = (hdr & 0x0c) == 0x04 ? get_u8(frm) : 0; 432c8958756bc90521ac900ebfeb650bc4d7a8c0a45Marcel Holtmann sid = hdr & 0x08 ? 0x00 : get_u8(frm); 433d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 434c8958756bc90521ac900ebfeb650bc4d7a8c0a45Marcel Holtmann printf("AVDTP(s): %s %s: transaction %d\n", 435c8958756bc90521ac900ebfeb650bc4d7a8c0a45Marcel Holtmann sid & 0x08 ? pt2str(hdr) : si2str(sid), mt2str(hdr), hdr >> 4); 436563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann 437563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann switch (sid & 0x7f) { 438563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x01: 439563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann discover(level + 1, hdr, frm); 440563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 441563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x02: 442563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann get_capabilities(level + 1, hdr, frm); 443563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 444563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x03: 445563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann set_configuration(level + 1, hdr, frm); 446563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 447563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x04: 448563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann get_configuration(level + 1, hdr, frm); 449563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 450563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x05: 451563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann reconfigure(level + 1, hdr, frm); 452563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 453563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x06: 454563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann open_close_stream(level + 1, hdr, frm); 455563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 456563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x07: 457563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann start_suspend_stream(level + 1, hdr, frm); 458563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 459563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x08: 460563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann open_close_stream(level + 1, hdr, frm); 461563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 462563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x09: 463563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann start_suspend_stream(level + 1, hdr, frm); 464563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 465563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x0a: 466563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann abort_streaming(level + 1, hdr, frm); 467563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 468563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann case 0x0b: 469563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann security(level + 1, hdr, frm); 470563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann break; 471563423c8e0de4403baed6b642fca585634de3c0aMarcel Holtmann } 4721f2ab27c77f01e4aa213844bc3409634eea24d4aMarcel Holtmann 4731f2ab27c77f01e4aa213844bc3409634eea24d4aMarcel Holtmann break; 4741f2ab27c77f01e4aa213844bc3409634eea24d4aMarcel Holtmann 4751f2ab27c77f01e4aa213844bc3409634eea24d4aMarcel Holtmann case 2: 4761f2ab27c77f01e4aa213844bc3409634eea24d4aMarcel Holtmann p_indent(level, frm); 477c8958756bc90521ac900ebfeb650bc4d7a8c0a45Marcel Holtmann printf("AVDTP(m): \n"); 4781f2ab27c77f01e4aa213844bc3409634eea24d4aMarcel Holtmann break; 479c8958756bc90521ac900ebfeb650bc4d7a8c0a45Marcel Holtmann } 480d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann 481d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann raw_dump(level, frm); 482d12491e536bff28ee5c3895c6de55eefd052c93dMarcel Holtmann} 483