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; } }