add f_usb_get_desc_tree() to provide hierarchical tree of descriptors

parsing a hierarchical structure makes it easier for users to iterate
over configurations, interfaces in one config, endpoints within one
interface, etc.
This commit is contained in:
Harald Welte 2019-11-27 20:34:37 +01:00
parent e80a330430
commit 51681d18b7
1 changed files with 42 additions and 0 deletions

View File

@ -145,6 +145,48 @@ runs on USB_CT
f_usb_dev_req_exp_fail(ts_DevReq_GET_DESCRIPTOR(dtype, idx, len), exp_status);
}
type record USB_Descriptor_Node {
USB_StandardDescriptor desc,
USB_Descriptor_Nodes children
};
type record of USB_Descriptor_Node USB_Descriptor_Nodes;
/* Generata hierarchical tree of USB Descriptors; easier to parse for most use cases */
function f_usb_get_desc_tree() runs on USB_CT return USB_Descriptor_Node
{
var USB_Descriptor_Node device_node;
var USB_StandardDescriptors dev_descs;
var integer i, j, cur_config, cur_interface;
dev_descs := f_usb_get_desc_std(USB_DescriptorType_DEVICE, 0, 255);
device_node.desc := dev_descs[0];
for (i := 0; i < device_node.desc.device.bNumConfigurations; i := i+1) {
var USB_StandardDescriptors cfg_descs;
cfg_descs := f_usb_get_desc_std(USB_DescriptorType_CONFIGURATION, i, 255);
for (j := 0; j < lengthof(cfg_descs); j:= j+1) {
var USB_StandardDescriptor desc := cfg_descs[j];
log("Descriptor ", j, ": ", desc);
if (ischosen(desc.configuration)) {
cur_config := desc.configuration.bConfigurationValue;
cur_interface := 0;
device_node.children[cur_config] := { desc := desc, children := {} };
} else if (ischosen(desc.interface)) {
cur_interface := desc.interface.bInterfaceNumber;
device_node.children[cur_config].children[cur_interface] :=
{ desc := desc, children := {} };
} else {
var integer next := lengthof(device_node.children[cur_config].children[cur_interface].children);
device_node.children[cur_config].children[cur_interface].children[next] :=
{ desc := desc, children := {} };
}
}
}
return device_node;
}
function f_usb_get_config()
runs on USB_CT return integer {
var USB_transfer_compl tc;