|
|
67abd2 |
From e497fcd9d69f2ba6b8672e430ee273db4afbea17 Mon Sep 17 00:00:00 2001
|
|
|
67abd2 |
From: Michael Drake <michael.drake@codethink.co.uk>
|
|
|
67abd2 |
Date: Thu, 7 Jun 2018 11:01:37 +0100
|
|
|
67abd2 |
Subject: [PATCH 5/9] lsusb: Split out routine that fetches value for given
|
|
|
67abd2 |
field.
|
|
|
67abd2 |
|
|
|
67abd2 |
Field value lookup was done in multiple places, so it's useful
|
|
|
67abd2 |
as a helper function.
|
|
|
67abd2 |
|
|
|
67abd2 |
Signed-off-by: Michael Drake <michael.drake@codethink.co.uk>
|
|
|
67abd2 |
---
|
|
|
67abd2 |
desc-dump.c | 106 +++++++++++++++++++++++++++++++++---------------------------
|
|
|
67abd2 |
1 file changed, 58 insertions(+), 48 deletions(-)
|
|
|
67abd2 |
|
|
|
67abd2 |
diff --git a/desc-dump.c b/desc-dump.c
|
|
|
67abd2 |
index 9210df7..393ff70 100644
|
|
|
67abd2 |
--- a/desc-dump.c
|
|
|
67abd2 |
+++ b/desc-dump.c
|
|
|
67abd2 |
@@ -2,7 +2,7 @@
|
|
|
67abd2 |
/*
|
|
|
67abd2 |
* USB descriptor dumping
|
|
|
67abd2 |
*
|
|
|
67abd2 |
- * Copyright (C) 2017 Michael Drake <michael.drake@codethink.co.uk>
|
|
|
67abd2 |
+ * Copyright (C) 2017-2018 Michael Drake <michael.drake@codethink.co.uk>
|
|
|
67abd2 |
*/
|
|
|
67abd2 |
|
|
|
67abd2 |
#include "config.h"
|
|
|
67abd2 |
@@ -109,6 +109,57 @@ static unsigned long long get_n_bytes_as_ull(
|
|
|
67abd2 |
return ret;
|
|
|
67abd2 |
}
|
|
|
67abd2 |
|
|
|
67abd2 |
+/**
|
|
|
67abd2 |
+ * Get the size of a descriptor field in bytes.
|
|
|
67abd2 |
+ *
|
|
|
67abd2 |
+ * Normally the size is provided in the entry's size parameter, but some
|
|
|
67abd2 |
+ * fields have a variable size, with the actual size being stored in as
|
|
|
67abd2 |
+ * the value of another field.
|
|
|
67abd2 |
+ *
|
|
|
67abd2 |
+ * \param[in] buf Descriptor data.
|
|
|
67abd2 |
+ * \param[in] desc First field in the descriptor definition array.
|
|
|
67abd2 |
+ * \param[in] entry The descriptor definition field to get size for.
|
|
|
67abd2 |
+ * \return Size of the field in bytes.
|
|
|
67abd2 |
+ */
|
|
|
67abd2 |
+static unsigned int get_entry_size(
|
|
|
67abd2 |
+ const unsigned char *buf,
|
|
|
67abd2 |
+ const struct desc *desc,
|
|
|
67abd2 |
+ const struct desc *entry);
|
|
|
67abd2 |
+
|
|
|
67abd2 |
+/**
|
|
|
67abd2 |
+ * Read a value from a field of given name.
|
|
|
67abd2 |
+ *
|
|
|
67abd2 |
+ * \param[in] buf Descriptor data.
|
|
|
67abd2 |
+ * \param[in] desc First field in the descriptor definition array.
|
|
|
67abd2 |
+ * \param[in] field The name of the field to get the value for.
|
|
|
67abd2 |
+ * \return The value from the given field.
|
|
|
67abd2 |
+ */
|
|
|
67abd2 |
+static unsigned long long get_value_from_field(
|
|
|
67abd2 |
+ const unsigned char *buf,
|
|
|
67abd2 |
+ const struct desc *desc,
|
|
|
67abd2 |
+ const char *field)
|
|
|
67abd2 |
+{
|
|
|
67abd2 |
+ size_t offset = 0;
|
|
|
67abd2 |
+ const struct desc *current;
|
|
|
67abd2 |
+ unsigned long long value = 0;
|
|
|
67abd2 |
+
|
|
|
67abd2 |
+ /* Search descriptor definition array for the field who's value
|
|
|
67abd2 |
+ * gives the value of the entry we're interested in. */
|
|
|
67abd2 |
+ for (current = desc; current->field != NULL; current++) {
|
|
|
67abd2 |
+ if (strcmp(current->field, field) == 0) {
|
|
|
67abd2 |
+ value = get_n_bytes_as_ull(buf, offset,
|
|
|
67abd2 |
+ current->size);
|
|
|
67abd2 |
+ break;
|
|
|
67abd2 |
+ }
|
|
|
67abd2 |
+
|
|
|
67abd2 |
+ /* Keep track of our offset in the descriptor data
|
|
|
67abd2 |
+ * as we look for the field we want. */
|
|
|
67abd2 |
+ offset += get_entry_size(buf, desc, current);
|
|
|
67abd2 |
+ }
|
|
|
67abd2 |
+
|
|
|
67abd2 |
+ return value;
|
|
|
67abd2 |
+}
|
|
|
67abd2 |
+
|
|
|
67abd2 |
/**
|
|
|
67abd2 |
* Dump a number as hex to stdout.
|
|
|
67abd2 |
*
|
|
|
67abd2 |
@@ -270,18 +321,7 @@ static void value_renderer(
|
|
|
67abd2 |
}
|
|
|
67abd2 |
}
|
|
|
67abd2 |
|
|
|
67abd2 |
-/**
|
|
|
67abd2 |
- * Get the size of a descriptor field in bytes.
|
|
|
67abd2 |
- *
|
|
|
67abd2 |
- * Normally the size is provided in the entry's size parameter, but some
|
|
|
67abd2 |
- * fields have a variable size, with the actual size being stored in as
|
|
|
67abd2 |
- * the value of another field.
|
|
|
67abd2 |
- *
|
|
|
67abd2 |
- * \param[in] buf Descriptor data.
|
|
|
67abd2 |
- * \param[in] desc First field in the descriptor definition array.
|
|
|
67abd2 |
- * \param[in] entry The descriptor definition field to get size for.
|
|
|
67abd2 |
- * \return Size of the field in bytes.
|
|
|
67abd2 |
- */
|
|
|
67abd2 |
+/* Documented at forward declaration above. */
|
|
|
67abd2 |
static unsigned int get_entry_size(
|
|
|
67abd2 |
const unsigned char *buf,
|
|
|
67abd2 |
const struct desc *desc,
|
|
|
67abd2 |
@@ -292,24 +332,7 @@ static unsigned int get_entry_size(
|
|
|
67abd2 |
|
|
|
67abd2 |
if (entry->size_field != NULL) {
|
|
|
67abd2 |
/* Variable field length, given by `size_field`'s value. */
|
|
|
67abd2 |
- size_t offset = 0;
|
|
|
67abd2 |
-
|
|
|
67abd2 |
- /* Search descriptor definition array for the field who's value
|
|
|
67abd2 |
- * gives the size of the entry we're interested in. */
|
|
|
67abd2 |
- for (current = desc; current->field != NULL; current++) {
|
|
|
67abd2 |
- if (strcmp(current->field, entry->size_field) == 0) {
|
|
|
67abd2 |
- /* Found the field who's value gives us the
|
|
|
67abd2 |
- * size of, so read that field's value out of
|
|
|
67abd2 |
- * the descriptor data buffer. */
|
|
|
67abd2 |
- size = get_n_bytes_as_ull(buf, offset,
|
|
|
67abd2 |
- current->size);
|
|
|
67abd2 |
- break;
|
|
|
67abd2 |
- }
|
|
|
67abd2 |
-
|
|
|
67abd2 |
- /* Keep track of our offset in the descriptor data
|
|
|
67abd2 |
- * as we look for the field we want. */
|
|
|
67abd2 |
- offset += get_entry_size(buf, desc, current);
|
|
|
67abd2 |
- }
|
|
|
67abd2 |
+ size = get_value_from_field(buf, desc, entry->size_field);
|
|
|
67abd2 |
}
|
|
|
67abd2 |
|
|
|
67abd2 |
if (size == 0) {
|
|
|
67abd2 |
@@ -347,27 +370,14 @@ static unsigned int get_array_entry_count(
|
|
|
67abd2 |
|
|
|
67abd2 |
if (array_entry->array.length_field1) {
|
|
|
67abd2 |
/* We can get the array size from the length_field1. */
|
|
|
67abd2 |
- size_t offset = 0;
|
|
|
67abd2 |
- for (current = desc; current->field != NULL; current++) {
|
|
|
67abd2 |
- if (strcmp(current->field, array_entry->array.length_field1) == 0) {
|
|
|
67abd2 |
- entries = get_n_bytes_as_ull(buf, offset, current->size);
|
|
|
67abd2 |
- break;
|
|
|
67abd2 |
- }
|
|
|
67abd2 |
+ entries = get_value_from_field(buf, desc,
|
|
|
67abd2 |
+ array_entry->array.length_field1);
|
|
|
67abd2 |
|
|
|
67abd2 |
- offset += get_entry_size(buf, desc, current);
|
|
|
67abd2 |
- }
|
|
|
67abd2 |
- offset = 0; /* skip first three common 1-byte fields */
|
|
|
67abd2 |
if (array_entry->array.length_field2 != NULL) {
|
|
|
67abd2 |
/* There's a second field specifying length. The two
|
|
|
67abd2 |
* lengths are multiplied. */
|
|
|
67abd2 |
- for (current = desc; current->field != NULL; current++) {
|
|
|
67abd2 |
- if (strcmp(current->field, array_entry->array.length_field2) == 0) {
|
|
|
67abd2 |
- entries *= get_n_bytes_as_ull(buf, offset, current->size);
|
|
|
67abd2 |
- break;
|
|
|
67abd2 |
- }
|
|
|
67abd2 |
-
|
|
|
67abd2 |
- offset += get_entry_size(buf, desc, current);
|
|
|
67abd2 |
- }
|
|
|
67abd2 |
+ entries *= get_value_from_field(buf, desc,
|
|
|
67abd2 |
+ array_entry->array.length_field2);
|
|
|
67abd2 |
}
|
|
|
67abd2 |
|
|
|
67abd2 |
/* If the bits flag is set, then the entry count so far
|
|
|
67abd2 |
--
|
|
|
67abd2 |
2.14.4
|
|
|
67abd2 |
|