void packet_hci_command(struct timeval *tv, uint16_t index, const void *data, uint16_t size) { const hci_command_hdr *hdr = data; uint16_t opcode = btohs(hdr->opcode); uint16_t ogf = cmd_opcode_ogf(opcode); uint16_t ocf = cmd_opcode_ocf(opcode); btsnoop_write(tv, index, 0x02, data, size); print_header(tv, index); if (size < HCI_COMMAND_HDR_SIZE) { printf("* Malformed HCI Command packet\n"); return; } printf("< HCI Command: %s (0x%2.2x|0x%4.4x) plen %d\n", opcode2str(opcode), ogf, ocf, hdr->plen); data += HCI_COMMAND_HDR_SIZE; size -= HCI_COMMAND_HDR_SIZE; packet_hexdump(data, size); }
void avrcp_dump(int level, struct frame *frm) { uint8_t ctype, address, subunit, opcode, company[3]; int i; p_indent(level, frm); ctype = get_u8(frm); address = get_u8(frm); opcode = get_u8(frm); printf("AV/C: %s: address 0x%02x opcode 0x%02x\n", ctype2str(ctype), address, opcode); p_indent(level + 1, frm); subunit = address >> 3; printf("Subunit: %s\n", subunit2str(subunit)); p_indent(level + 1, frm); printf("Opcode: %s\n", opcode2str(opcode)); /* Skip non-panel subunit packets */ if (subunit != AVC_SUBUNIT_PANEL) { raw_dump(level, frm); return; } /* Not implemented should not contain any operand */ if (ctype == AVC_CTYPE_NOT_IMPLEMENTED) { raw_dump(level, frm); return; } switch (opcode) { case AVC_OP_PASSTHROUGH: avrcp_passthrough_dump(level + 1, frm); break; case AVC_OP_VENDORDEP: p_indent(level + 1, frm); printf("Company ID: 0x"); for (i = 0; i < 3; i++) { company[i] = get_u8(frm); printf("%02x", company[i]); } printf("\n"); avrcp_pdu_dump(level + 1, frm, ctype); break; default: raw_dump(level, frm); } }
static bool avrcp_control_packet(struct avctp_frame *avctp_frame) { struct l2cap_frame *frame = &avctp_frame->l2cap_frame; uint8_t ctype, address, subunit, opcode, company[3], indent = 2; if (!l2cap_frame_get_u8(frame, &ctype) || !l2cap_frame_get_u8(frame, &address) || !l2cap_frame_get_u8(frame, &opcode)) return false; print_field("AV/C: %s: address 0x%02x opcode 0x%02x", ctype2str(ctype), address, opcode); subunit = address >> 3; print_field("%*cSubunit: %s", indent, ' ', subunit2str(subunit)); print_field("%*cOpcode: %s", indent, ' ', opcode2str(opcode)); /* Skip non-panel subunit packets */ if (subunit != 0x09) { packet_hexdump(frame->data, frame->size); return true; } /* Not implemented should not contain any operand */ if (ctype == 0x8) { packet_hexdump(frame->data, frame->size); return true; } switch (opcode) { case 0x7c: return avrcp_passthrough_packet(avctp_frame); case 0x00: if (!l2cap_frame_get_u8(frame, &company[0]) || !l2cap_frame_get_u8(frame, &company[1]) || !l2cap_frame_get_u8(frame, &company[2])) return false; print_field("%*cCompany ID: 0x%02x%02x%02x", indent, ' ', company[0], company[1], company[2]); return avrcp_pdu_packet(avctp_frame, ctype, 10); default: packet_hexdump(frame->data, frame->size); return true; } }
void obex_dump(int level, struct frame *frm) { uint8_t last_opcode, opcode, status; uint8_t version, flags, constants; uint16_t length, pktlen; frm = add_frame(frm); while (frm->len > 2) { opcode = get_u8(frm); length = get_u16(frm); status = opcode & 0x7f; if ((int) frm->len < length - 3) { frm->ptr -= 3; frm->len += 3; return; } p_indent(level, frm); last_opcode = get_opcode(frm->handle, frm->dlci); if (!(opcode & 0x70)) { printf("OBEX: %s cmd(%c): len %d", opcode2str(opcode), opcode & 0x80 ? 'f' : 'c', length); set_opcode(frm->handle, frm->dlci, opcode); } else { printf("OBEX: %s rsp(%c): status %x%02d len %d", opcode2str(last_opcode), opcode & 0x80 ? 'f' : 'c', status >> 4, status & 0xf, length); opcode = last_opcode; } if (get_status(frm->handle, frm->dlci) == 0x10) printf(" (continue)"); set_status(frm->handle, frm->dlci, status); if (frm->len == 0) { printf("\n"); break; } switch (opcode & 0x7f) { case 0x00: /* Connect */ if (frm->len < 4) { printf("\n"); return; } 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 */ if (frm->len < 2) { printf("\n"); return; } flags = get_u8(frm); constants = get_u8(frm); printf(" flags %d constants %d\n", flags, constants); break; default: printf("\n"); break; } if ((status & 0x70) && (parser.flags & DUMP_VERBOSE)) { p_indent(level, frm); printf("Status %x%02d = %s\n", status >> 4, status & 0xf, opcode2str(status)); } parse_headers(level, frm); }