HelenOS sources
This source file includes following definitions.
- get_indent
- dump_buffer
- dump_usb_descriptor
- dump_match_ids
- dump_tree_descriptor
- dump_tree_internal
- dump_tree
- dump_descriptor_tree
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stddef.h>
#include <errno.h>
#include <str_error.h>
#include <usb/usb.h>
#include <usb/descriptor.h>
#include <usb/debug.h>
#include <usb/classes/classes.h>
#include "usbinfo.h"
#include <usb/dev/dp.h>
#define INDENT " "
#define BYTES_PER_LINE 12
const char *get_indent(size_t level)
{
static const char *indents[] = {
INDENT,
INDENT INDENT,
INDENT INDENT INDENT,
INDENT INDENT INDENT INDENT,
INDENT INDENT INDENT INDENT INDENT,
INDENT INDENT INDENT INDENT INDENT INDENT,
};
static size_t indents_count = sizeof(indents) / sizeof(indents[0]);
if (level >= indents_count) {
return indents[indents_count - 1];
}
return indents[level];
}
void dump_buffer(const char *msg, size_t indent,
const uint8_t *buffer, size_t length)
{
if (msg != NULL) {
printf("%s\n", msg);
}
size_t i;
if (length > 0) {
printf("%s", get_indent(indent));
}
for (i = 0; i < length; i++) {
printf("0x%02X", buffer[i]);
if (((i > 0) && (((i + 1) % BYTES_PER_LINE) == 0)) ||
(i + 1 == length)) {
printf("\n");
if (i + 1 < length) {
printf("%s", get_indent(indent));
}
} else {
printf(" ");
}
}
}
void dump_usb_descriptor(uint8_t *descriptor, size_t size)
{
printf("Device descriptor:\n");
usb_dump_standard_descriptor(stdout, get_indent(0), "\n",
descriptor, size);
}
void dump_match_ids(match_id_list_t *matches, const char *line_prefix)
{
list_foreach(matches->ids, link, match_id_t, match) {
printf("%s%3d %s\n", line_prefix, match->score, match->id);
}
}
static void dump_tree_descriptor(const uint8_t *descriptor, size_t depth)
{
if (descriptor == NULL) {
return;
}
int type = descriptor[1];
const char *name = "unknown";
switch (type) {
#define _TYPE(descriptor_type) \
case USB_DESCTYPE_##descriptor_type: name = #descriptor_type; break
_TYPE(DEVICE);
_TYPE(CONFIGURATION);
_TYPE(STRING);
_TYPE(INTERFACE);
_TYPE(ENDPOINT);
_TYPE(HID);
_TYPE(HID_REPORT);
_TYPE(HID_PHYSICAL);
_TYPE(HUB);
#undef _TYPE
}
printf("%s%s (0x%02X):\n", get_indent(depth), name, type);
usb_dump_standard_descriptor(stdout, get_indent(depth), "\n",
descriptor, descriptor[0]);
}
static void dump_tree_internal(
usb_dp_parser_t *parser, usb_dp_parser_data_t *data,
const uint8_t *root, size_t depth)
{
if (root == NULL) {
return;
}
dump_tree_descriptor(root, depth);
const uint8_t *child = usb_dp_get_nested_descriptor(parser, data, root);
do {
dump_tree_internal(parser, data, child, depth + 1);
child = usb_dp_get_sibling_descriptor(parser, data, root, child);
} while (child != NULL);
}
static void dump_tree(usb_dp_parser_t *parser, usb_dp_parser_data_t *data)
{
const uint8_t *ptr = data->data;
printf("Descriptor tree:\n");
dump_tree_internal(parser, data, ptr, 0);
}
#define NESTING(parentname, childname) \
{ \
.child = USB_DESCTYPE_##childname, \
.parent = USB_DESCTYPE_##parentname, \
}
#define LAST_NESTING { -1, -1 }
static usb_dp_descriptor_nesting_t descriptor_nesting[] = {
NESTING(CONFIGURATION, INTERFACE),
NESTING(INTERFACE, ENDPOINT),
NESTING(INTERFACE, HUB),
NESTING(INTERFACE, HID),
NESTING(HID, HID_REPORT),
LAST_NESTING
};
static usb_dp_parser_t parser = {
.nesting = descriptor_nesting
};
void dump_descriptor_tree(uint8_t *descriptors, size_t length)
{
usb_dp_parser_data_t data = {
.data = descriptors,
.size = length,
.arg = NULL
};
dump_tree(&parser, &data);
}
HelenOS homepage, sources at GitHub