Mercurial > hg > ucis.core
diff USBLib/Descriptor/UsbInfo.cs @ 68:e811297f5aa4
Updated USBLib: removed old LibUsbDotNet compatibility code and added new information helper classes
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Wed, 16 Oct 2013 16:58:39 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBLib/Descriptor/UsbInfo.cs Wed Oct 16 16:58:39 2013 +0200 @@ -0,0 +1,187 @@ +using System; +using System.Collections.Generic; +using System.Text; +using UCIS.USBLib.Communication; +using UCIS.Util; + +namespace UCIS.USBLib.Descriptor { + public class UsbDeviceInfo { + private UsbDeviceDescriptor mDeviceDescriptor; + private Boolean mHasDeviceDescriptor = false; + private UsbConfigurationInfo[] mConfigurations = null; + private short language = 0; + public IUsbInterface Device { get; private set; } + public UsbDeviceInfo(IUsbInterface device) { + if (device == null) throw new ArgumentNullException("device"); + this.Device = device; + } + private void GetDescriptor() { + if (mHasDeviceDescriptor) return; + mDeviceDescriptor = UsbDeviceDescriptor.FromDevice(Device); + mHasDeviceDescriptor = (mDeviceDescriptor.Length >= UsbDeviceDescriptor.Size && mDeviceDescriptor.Type == UsbDescriptorType.Device); + } + public String GetString(Byte index, short langId) { + if (index == 0) return null; + return UsbStringDescriptor.GetStringFromDevice(Device, index, langId); + } + public String GetString(Byte index) { + if (language == 0) { + Byte[] buff = new Byte[4]; + int len = Device.GetDescriptor((Byte)UsbDescriptorType.String, 0, 0, buff, 0, buff.Length); + if (len >= 4) language = BitConverter.ToInt16(buff, 2); + } + return GetString(index, language); + } + public UsbDeviceDescriptor Descriptor { get { GetDescriptor(); return mDeviceDescriptor; } } + public String ManufacturerString { get { return GetString(Descriptor.ManufacturerStringID); } } + public String ProductString { get { return GetString(Descriptor.ProductStringID); } } + public String SerialString { get { return GetString(Descriptor.SerialNumberStringID); } } + public IList<UsbConfigurationInfo> Configurations { + get { + if (mConfigurations == null) { + mConfigurations = new UsbConfigurationInfo[Descriptor.NumConfigurations]; + for (Byte i = 0; i < mConfigurations.Length; i++) mConfigurations[i] = new UsbConfigurationInfo(this, i); + } + return mConfigurations; + } + } + public UsbConfigurationInfo FindConfiguration(Byte value) { + foreach (UsbConfigurationInfo configuration in Configurations) if (configuration.Descriptor.ConfigurationValue == value) return configuration; + return null; + } + public static UsbDeviceInfo FromDevice(IUsbInterface device) { + return new UsbDeviceInfo(device); + } + public static UsbDeviceInfo FromDeviceNode(UCIS.HWLib.Windows.Devices.DeviceNode devnode) { + IUsbInterface device = UCIS.HWLib.Windows.USB.UsbDevice.GetUsbDevice(devnode); + if (device == null) return null; + return new UsbDeviceInfo(device); + } + } + public class UsbConfigurationInfo { + private UsbConfigurationDescriptor mConfigurationDescriptor; + private Boolean mHasConfigurationDescriptor = false; + private Byte[] mConfigurationBlob = null; + private UsbDescriptorBlob[] mDescriptors = null; + private UsbInterfaceInfo[] mInterfaces = null; + public UsbDeviceInfo Device { get; private set; } + public Byte Index { get; private set; } + internal UsbConfigurationInfo(UsbDeviceInfo device, Byte index) { + this.Device = device; + this.Index = index; + } + private void GetConfigurationBlob() { + if (mConfigurationBlob != null) return; + int length = Descriptor.TotalLength; + if (!mHasConfigurationDescriptor) throw new Exception("Configuration descriptor is invalid"); + Byte[] blob = new Byte[length]; + length = Device.Device.GetDescriptor((Byte)UsbDescriptorType.Configuration, Index, 0, blob, 0, length); + if (length != blob.Length) throw new Exception("Could not read configuration descriptor"); + List<UsbDescriptorBlob> descriptors = new List<UsbDescriptorBlob>(); + for (int offset = 0; offset < length; ) { + if (length - offset < 2) throw new Exception("Descriptor has been truncated"); + UsbDescriptorBlob descriptor = new UsbDescriptorBlob(blob, offset); + if (length - offset < descriptor.Length) throw new Exception("Descriptor has been truncated"); + descriptors.Add(descriptor); + offset += descriptor.Length; + } + mConfigurationBlob = blob; + mDescriptors = descriptors.ToArray(); + } + public UsbConfigurationDescriptor Descriptor { + get { + if (!mHasConfigurationDescriptor) { + mConfigurationDescriptor = UsbConfigurationDescriptor.FromDevice(Device.Device, Index); + mHasConfigurationDescriptor = (mConfigurationDescriptor.Length >= UsbConfigurationDescriptor.Size && mConfigurationDescriptor.Type == UsbDescriptorType.Configuration); + } + return mConfigurationDescriptor; + } + } + public IList<UsbDescriptorBlob> Descriptors { get { GetConfigurationBlob(); return mDescriptors; } } + private void GetInterfaces() { + if (mInterfaces != null) return; + GetConfigurationBlob(); + UsbInterfaceInfo[] interfaces = new UsbInterfaceInfo[Descriptor.NumInterfaces]; + int index = 0; + int first = -1; + for (int i = 0; i < mDescriptors.Length; i++) { + UsbDescriptorBlob descriptor = mDescriptors[i]; + if (descriptor.Type != UsbDescriptorType.Interface) continue; + if (first != -1) { + if (index >= interfaces.Length) Array.Resize(ref interfaces, index + 1); + interfaces[index] = new UsbInterfaceInfo(this, ArrayUtil.Slice(mDescriptors, first, i - first)); + index++; + } + first = i; + } + if (first != -1) { + if (index >= interfaces.Length) Array.Resize(ref interfaces, index + 1); + interfaces[index] = new UsbInterfaceInfo(this, ArrayUtil.Slice(mDescriptors, first, mDescriptors.Length - first)); + } + mInterfaces = interfaces; + } + public IList<UsbInterfaceInfo> Interfaces { get { GetInterfaces(); return mInterfaces; } } + public UsbInterfaceInfo FindInterface(Predicate<UsbInterfaceInfo> predicate) { + GetInterfaces(); + foreach (UsbInterfaceInfo interf in mInterfaces) if (predicate(interf)) return interf; + return null; + } + public UsbInterfaceInfo FindInterface(Byte number) { + return FindInterface(number, 0); + } + public UsbInterfaceInfo FindInterface(Byte number, Byte alternateSetting) { + return FindInterface(delegate(UsbInterfaceInfo interf) { return interf.Descriptor.InterfaceNumber == number && interf.Descriptor.AlternateSetting == alternateSetting; }); + } + public UsbInterfaceInfo FindInterfaceByClass(UsbClassCode usbclass) { + return FindInterface(delegate(UsbInterfaceInfo interf) { return interf.Descriptor.InterfaceClass == usbclass; }); + } + public UsbInterfaceInfo FindInterfaceByClass(UsbClassCode usbclass, Byte subclass) { + return FindInterface(delegate(UsbInterfaceInfo interf) { return interf.Descriptor.InterfaceClass == usbclass && interf.Descriptor.InterfaceSubClass == subclass; }); + } + public UsbDescriptorBlob FindDescriptor(UsbDescriptorType type) { + GetConfigurationBlob(); + return Array.Find(mDescriptors, delegate(UsbDescriptorBlob descriptor) { return descriptor.Type == type; }); + } + public UsbDescriptorBlob[] FindDescriptors(UsbDescriptorType type) { + GetConfigurationBlob(); + return Array.FindAll(mDescriptors, delegate(UsbDescriptorBlob descriptor) { return descriptor.Type == type; }); + } + } + public class UsbInterfaceInfo { + public UsbConfigurationInfo Configuration { get; private set; } + private UsbDescriptorBlob[] mDescriptors; + public UsbInterfaceInfo(UsbConfigurationInfo configuration, UsbDescriptorBlob[] descriptors) { + this.Configuration = configuration; + this.mDescriptors = descriptors; + } + public UsbInterfaceDescriptor Descriptor { get { return (UsbInterfaceDescriptor)mDescriptors[0]; } } + public IList<UsbEndpointDescriptor> Endpoints { + get { + return Array.ConvertAll(FindDescriptors(UsbDescriptorType.Endpoint), delegate(UsbDescriptorBlob descriptor) { return (UsbEndpointDescriptor)descriptor; }); + } + } + public UsbEndpointDescriptor FindEndpoint(Predicate<UsbEndpointDescriptor> predicate) { + foreach (UsbDescriptorBlob descriptor in mDescriptors) { + if (descriptor.Type != UsbDescriptorType.Endpoint) continue; + UsbEndpointDescriptor ep = (UsbEndpointDescriptor)descriptor; + if (predicate(ep)) return ep; + } + return default(UsbEndpointDescriptor); + } + public UsbEndpointDescriptor FindEndpoint(Byte address) { + return FindEndpoint(delegate(UsbEndpointDescriptor ep) { return ep.EndpointAddress == address; }); + } + public UsbEndpointDescriptor FindEndpoint(Boolean input) { + return FindEndpoint(delegate(UsbEndpointDescriptor ep) { return ep.IsInput == input; }); + } + public UsbEndpointDescriptor FindEndpoint(Boolean input, int transferType) { + return FindEndpoint(delegate(UsbEndpointDescriptor ep) { return ep.TransferType == transferType && ep.IsInput == input; }); + } + public UsbDescriptorBlob FindDescriptor(UsbDescriptorType type) { + return Array.Find(mDescriptors, delegate(UsbDescriptorBlob descriptor) { return descriptor.Type == type; }); + } + public UsbDescriptorBlob[] FindDescriptors(UsbDescriptorType type) { + return Array.FindAll(mDescriptors, delegate(UsbDescriptorBlob descriptor) { return descriptor.Type == type; }); + } + } +}