Index: media/midi/usb_midi_descriptor_parser.cc |
diff --git a/media/midi/usb_midi_descriptor_parser.cc b/media/midi/usb_midi_descriptor_parser.cc |
index d454ff9469152c7fd9f39df314eaa2775b16a673..baf503bfae50e05cb561a4211d8eb416311bdf96 100644 |
--- a/media/midi/usb_midi_descriptor_parser.cc |
+++ b/media/midi/usb_midi_descriptor_parser.cc |
@@ -7,6 +7,7 @@ |
#include <algorithm> |
#include "base/logging.h" |
+#include "base/strings/stringprintf.h" |
namespace media { |
@@ -58,8 +59,20 @@ class JackMatcher { |
uint8 id_; |
}; |
+int DecodeBcd(uint8 byte) { |
+ DCHECK_LT((byte & 0xf0) >> 4, 0xa); |
+ DCHECK_LT(byte & 0x0f, 0xa); |
+ return ((byte & 0xf0) >> 4) * 10 + (byte & 0x0f); |
+} |
+ |
} // namespace |
+std::string UsbMidiDescriptorParser::DeviceInfo::BcdVersionToString( |
+ uint16 version) { |
+ return base::StringPrintf("%d.%02d", DecodeBcd(version >> 8), |
+ DecodeBcd(version & 0xff)); |
+} |
+ |
UsbMidiDescriptorParser::UsbMidiDescriptorParser() |
: is_parsing_usb_midi_interface_(false), |
current_endpoint_address_(0), |
@@ -79,6 +92,31 @@ bool UsbMidiDescriptorParser::Parse(UsbMidiDevice* device, |
return result; |
} |
+bool UsbMidiDescriptorParser::ParseDeviceInfo( |
+ const uint8* data, size_t size, DeviceInfo* info) { |
+ *info = DeviceInfo(); |
+ for (const uint8* current = data; |
+ current < data + size; |
+ current += current[0]) { |
+ uint8 length = current[0]; |
+ if (length < 2) { |
+ DVLOG(1) << "Descriptor Type is not accessible."; |
+ return false; |
+ } |
+ if (current + length > data + size) { |
+ DVLOG(1) << "The header size is incorrect."; |
+ return false; |
+ } |
+ DescriptorType descriptor_type = static_cast<DescriptorType>(current[1]); |
+ if (descriptor_type != TYPE_DEVICE) |
+ continue; |
+ // We assume that ParseDevice doesn't modify |*info| if it returns false. |
+ return ParseDevice(current, length, info); |
+ } |
+ // No DEVICE descriptor is found. |
+ return false; |
+} |
+ |
bool UsbMidiDescriptorParser::ParseInternal(UsbMidiDevice* device, |
const uint8* data, |
size_t size, |
@@ -129,6 +167,21 @@ bool UsbMidiDescriptorParser::ParseInternal(UsbMidiDevice* device, |
return true; |
} |
+bool UsbMidiDescriptorParser::ParseDevice( |
+ const uint8* data, size_t size, DeviceInfo* info) { |
+ if (size < 0x12) { |
+ DVLOG(1) << "DEVICE header size is incorrect."; |
+ return false; |
+ } |
+ |
+ info->vendor_id = data[8] | (data[9] << 8); |
+ info->product_id = data[0xa] | (data[0xb] << 8); |
+ info->bcd_device_version = data[0xc] | (data[0xd] << 8); |
+ info->manufacturer_index = data[0xe]; |
+ info->product_index = data[0xf]; |
+ return true; |
+} |
+ |
bool UsbMidiDescriptorParser::ParseInterface(const uint8* data, size_t size) { |
if (size != 9) { |
DVLOG(1) << "INTERFACE header size is incorrect."; |