Diff between 2d7a7404a44e3bbbd2edb7387719146c308a187b and bd08d166082b4e624770eb3b42fad3e736880e31

Changed Files

File Additions Deletions Status
tools/parser/obex.c +239 -1 modified

Full Patch

diff --git a/tools/parser/obex.c b/tools/parser/obex.c
index 9e4aae3..e5af352 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);
 }