From bd08d166082b4e624770eb3b42fad3e736880e31 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 17 Sep 2004 16:45:59 +0000 Subject: [PATCH] hcidump: Update OBEX parser --- tools/parser/obex.c | 240 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 239 insertions(+), 1 deletion(-) diff --git a/tools/parser/obex.c b/tools/parser/obex.c index 9e4aae3eb..e5af3525c 100644 --- a/tools/parser/obex.c +++ b/tools/parser/obex.c @@ -34,11 +34,249 @@ #include "parser.h" +static char *opcode2str(uint8_t opcode) +{ + switch (opcode & 0x7f) { + case 0x00: + return "Connect"; + case 0x01: + return "Disconnect"; + case 0x02: + return "Put"; + case 0x03: + return "Get"; + case 0x04: + return "Reserved"; + case 0x05: + return "SetPath"; + case 0x06: + return "Reserved"; + case 0x07: + return "Session"; + case 0x7f: + return "Abort"; + case 0x10: + return "Continue"; + case 0x20: + return "Success"; + case 0x21: + return "Created"; + case 0x22: + return "Accepted"; + case 0x23: + return "Non-authoritative information"; + case 0x24: + return "No content"; + case 0x25: + return "Reset content"; + case 0x26: + return "Partial content"; + case 0x30: + return "Multiple choices"; + case 0x31: + return "Moved permanently"; + case 0x32: + return "Moved temporarily"; + case 0x33: + return "See other"; + case 0x34: + return "Not modified"; + case 0x35: + return "Use Proxy"; + case 0x40: + return "Bad request"; + case 0x41: + return "Unauthorized"; + case 0x42: + return "Payment required"; + case 0x43: + return "Forbidden"; + case 0x44: + return "Not found"; + case 0x45: + return "Method not allowed"; + case 0x46: + return "Not acceptable"; + case 0x47: + return "Proxy authentication required"; + case 0x48: + return "Request timeout"; + case 0x49: + return "Conflict"; + case 0x4a: + return "Gone"; + case 0x4b: + return "Length required"; + case 0x4c: + return "Precondition failed"; + case 0x4d: + return "Requested entity too large"; + case 0x4e: + return "Requested URL too large"; + case 0x4f: + return "Unsupported media type"; + case 0x50: + return "Internal server error"; + case 0x51: + return "Not implemented"; + case 0x52: + return "Bad gateway"; + case 0x53: + return "Service unavailable"; + case 0x54: + return "Gateway timeout"; + case 0x55: + return "HTTP version not supported"; + case 0x60: + return "Database full"; + case 0x61: + return "Database locked"; + default: + return "Unknown"; + } +} + +static char *hi2str(uint8_t hi) +{ + switch (hi & 0x3f) { + case 0x00: + return "Count"; + case 0x01: + return "Name"; + case 0x02: + return "Type"; + case 0x03: + return "Length"; + case 0x04: + return "Time"; + case 0x05: + return "Description"; + case 0x06: + return "Target"; + case 0x07: + return "HTTP"; + case 0x08: + return "Body"; + case 0x09: + return "End of Body"; + case 0x0a: + return "Who"; + case 0x0b: + return "Connection ID"; + case 0x0c: + return "App. Parameters"; + case 0x0d: + return "Auth. Challenge"; + case 0x0e: + return "Auth. Response"; + case 0x0f: + return "Creator ID"; + case 0x10: + return "WAN UUID"; + case 0x11: + return "Object Class"; + case 0x12: + return "Session Parameters"; + case 0x13: + return "Session Sequence Number"; + default: + return "Unknown"; + } +} + +static void parse_headers(int level, struct frame *frm) +{ + uint8_t hi, hv8; + uint16_t len; + uint32_t hv32; + + while (frm->len > 0) { + hi = get_u8(frm); + + p_indent(level, frm); + + printf("%s (0x%02x)", hi2str(hi), hi); + switch (hi & 0xc0) { + case 0x00: /* Unicode */ + len = get_u16(frm) - 3; + printf(" = Unicode length %d\n", len); + raw_ndump(level, frm, len * 2); + frm->ptr += (len + 1) * 2; + frm->len -= (len + 1) * 2; + break; + + case 0x40: /* Byte sequence */ + len = get_u16(frm) - 3; + printf(" = Sequence length %d\n", len); + raw_ndump(level, frm, len); + frm->ptr += len; + frm->len -= len; + break; + + case 0x80: /* One byte */ + hv8 = get_u8(frm); + printf(" = %d\n", hv8); + break; + + case 0xc0: /* Four bytes */ + hv32 = get_u32(frm); + printf(" = %u\n", hv32); + break; + } + } +} + +static uint8_t last_opcode = 0x00; +static uint8_t last_status = 0x00; + void obex_dump(int level, struct frame *frm) { + uint8_t opcode, status, version, flags, constants; + uint16_t length, pktlen; + + opcode = get_u8(frm); + length = get_u16(frm); + status = opcode & 0x7f; + p_indent(level, frm); - printf("OBEX: \n"); + if ((opcode & 0x70) == 0x00) { + printf("OBEX: %s cmd(%c): len %d", + opcode2str(opcode), opcode & 0x80 ? 'f' : 'c', length); + if (last_status == 0x10) + printf(" (continue)"); + last_opcode = opcode; + } else { + printf("OBEX: %s rsp(%c): status %x%02d len %d", + opcode2str(last_opcode), opcode & 0x80 ? 'f' : 'c', + status >> 4, status & 0xf, length); + if (status == 0x10) + printf(" (continue)"); + opcode = last_opcode; + } + + last_status = status; + + switch (opcode & 0x7f) { + case 0x00: /* Connect */ + version = get_u8(frm); + flags = get_u8(frm); + pktlen = get_u16(frm); + printf(" version %d.%d flags %d mtu %d\n", + version >> 4, version & 0xf, flags, pktlen); + break; + + case 0x05: /* SetPath */ + flags = get_u8(frm); + constants = get_u8(frm); + printf(" flags %d constants %d\n", flags, constants); + break; + + default: + printf("\n"); + } + + parse_headers(level, frm); raw_dump(level, frm); } -- 2.47.3