From 2c9ff8fd467faf42e9fa7009f971d81ab5ffd4a4 Mon Sep 17 00:00:00 2001 From: Dinesh Dwivedi Date: Fri, 23 Jun 2017 11:12:16 +0530 Subject: [PATCH] [USB] Add UsbDevice class Change-Id: I55d73ea40a683a57dfbd264de60e4ee025cb5bb2 Signed-off-by: Dinesh Dwivedi --- Tizen.System.Usb/Interop/Interop.Device.cs | 111 ++++++++++++++++++ Tizen.System.Usb/Usb/UsbConfiguration.cs | 5 +- Tizen.System.Usb/Usb/UsbDevice.cs | 182 +++++++++++++++++++++++++++++ 3 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 Tizen.System.Usb/Interop/Interop.Device.cs create mode 100644 Tizen.System.Usb/Usb/UsbDevice.cs diff --git a/Tizen.System.Usb/Interop/Interop.Device.cs b/Tizen.System.Usb/Interop/Interop.Device.cs new file mode 100644 index 0000000..e5f8c28 --- /dev/null +++ b/Tizen.System.Usb/Interop/Interop.Device.cs @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + [DllImport(Libraries.Usb, EntryPoint = "usb_host_ref_device")] + internal static extern ErrorCode RefDevice(this HostDeviceHandle /* usb_host_device_h */ dev); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_unref_device")] + internal static extern ErrorCode UnrefDevice(this HostDeviceHandle /* usb_host_device_h */ dev); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_open")] + internal static extern ErrorCode Open(this HostDeviceHandle /* usb_host_device_h */ dev); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_close")] + internal static extern ErrorCode Close(this HostDeviceHandle /* usb_host_device_h */ dev); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_bus_number")] + internal static extern ErrorCode GetBusNumber(this HostDeviceHandle /* usb_host_device_h */ dev, out int busNumber); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_address")] + internal static extern ErrorCode GetAddress(this HostDeviceHandle /* usb_host_device_h */ dev, out int deviceAddress); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_port_numbers")] + internal static extern ErrorCode GetPortNumbers(this HostDeviceHandle /* usb_host_device_h */ dev, [MarshalAs(UnmanagedType.SysInt, SizeParamIndex = 2)] [In, Out] int[] portNumbers, int portNumbersLen, out int portsCount); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_config")] + internal static extern ErrorCode GetConfig(this HostDeviceHandle /* usb_host_device_h */ dev, int configIndex, out UsbConfigHandle /* usb_host_config_h */ config); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_get_active_config")] + internal static extern ErrorCode GetActiveConfig(this HostDeviceHandle /* usb_host_device_h */ dev, out UsbConfigHandle /* usb_host_config_h */ config); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_bcd_usb")] + internal static extern ErrorCode GetBcdUsb(this HostDeviceHandle /* usb_host_device_h */ dev, out int bcdUsb); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_class")] + internal static extern ErrorCode GetClass(this HostDeviceHandle /* usb_host_device_h */ dev, out int deviceClass); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_sub_class")] + internal static extern ErrorCode GetSubClass(this HostDeviceHandle /* usb_host_device_h */ dev, out int subclass); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_protocol")] + internal static extern ErrorCode GetProtocol(this HostDeviceHandle /* usb_host_device_h */ dev, out int protocol); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_max_packet_size_0")] + internal static extern ErrorCode GetMaxPacketSize0(this HostDeviceHandle /* usb_host_device_h */ dev, out int maxPacketSize); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_id_vendor")] + internal static extern ErrorCode GetIdVendor(this HostDeviceHandle /* usb_host_device_h */ dev, out int vendorId); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_id_product")] + internal static extern ErrorCode GetIdProduct(this HostDeviceHandle /* usb_host_device_h */ dev, out int productId); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_bcd_device")] + internal static extern ErrorCode GetBcdDevice(this HostDeviceHandle /* usb_host_device_h */ dev, out int deviceBcd); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_num_configurations")] + internal static extern ErrorCode GetNumConfigurations(this HostDeviceHandle /* usb_host_device_h */ dev, out int numConfigurations); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_is_device_opened")] + internal static extern ErrorCode IsOpened(this HostDeviceHandle /* usb_host_device_h */ dev, out bool isOpened); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_manufacturer_str")] + internal static extern ErrorCode GetManufacturerStr(this HostDeviceHandle /* usb_host_device_h */ dev, ref int length, byte[] data); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_product_str")] + internal static extern ErrorCode GetProductStr(this HostDeviceHandle /* usb_host_device_h */ dev, ref int length, byte[] data); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_device_get_serial_number_str")] + internal static extern ErrorCode GetSerialNumberStr(this HostDeviceHandle /* usb_host_device_h */ dev, ref int length, byte[] data); + + [DllImport(Libraries.Usb, EntryPoint = "usb_host_control_transfer")] + internal static extern ErrorCode ControlTransfer(this HostDeviceHandle /* usb_host_device_h */ dev, byte requestType, byte request, ushort value, ushort index, byte[] data, ushort length, uint timeout, out int transferred); + + internal class HostDeviceHandle : SafeUsbHandle + { + internal HostDeviceHandle(IntPtr handle) : base(handle) { } + + public override void Destroy() + { + //this.UnrefDevice(); + } + + internal IEnumerable Ports() + { + int actualPortsCount; + int[] portList = new int[MaxPortNumberCount]; + var err = this.GetPortNumbers(portList, portList.Length, out actualPortsCount); + err.ThrowIfFailed("Failed to get device port list"); + return portList.Take(actualPortsCount); + } + } +} diff --git a/Tizen.System.Usb/Usb/UsbConfiguration.cs b/Tizen.System.Usb/Usb/UsbConfiguration.cs index 294f905..ba9abfb 100644 --- a/Tizen.System.Usb/Usb/UsbConfiguration.cs +++ b/Tizen.System.Usb/Usb/UsbConfiguration.cs @@ -26,10 +26,12 @@ namespace Tizen.System.Usb public class UsbConfiguration : IDisposable { internal readonly Interop.UsbConfigHandle _handle; + private readonly UsbDevice _parent; private Dictionary _interfaces; - internal UsbConfiguration(Interop.UsbConfigHandle handle) + internal UsbConfiguration(UsbDevice parent, Interop.UsbConfigHandle handle) { + _parent = parent; _handle = handle; } @@ -120,6 +122,7 @@ namespace Tizen.System.Usb internal void ThrowIfDisposed() { if (disposedValue) throw new ObjectDisposedException("Configuration is already disposed"); + _parent.ThrowIfDisposed(); } #region IDisposable Support diff --git a/Tizen.System.Usb/Usb/UsbDevice.cs b/Tizen.System.Usb/Usb/UsbDevice.cs new file mode 100644 index 0000000..a1c6ca3 --- /dev/null +++ b/Tizen.System.Usb/Usb/UsbDevice.cs @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Tizen.System.Usb +{ + /// + /// Class to manage USB host devices. This class contains operations for enumerating, opening and closing devices. + /// + public class UsbDevice : IDisposable + { + internal readonly Interop.HostDeviceHandle _handle; + private Dictionary _configurations; + + internal UsbDevice(Interop.HostDeviceHandle handle) + { + _handle = handle; + } + + /// + /// Number of the bus, this device is connected to. + /// + /// Throws exception if user has insufficient permission on device. + public int BusId { + get + { + ThrowIfDisposed(); + return Interop.NativeGet(_handle.GetBusNumber); + } + } + + /// + /// Address of device on the bus. + /// + public int Address + { + get + { + ThrowIfDisposed(); + return Interop.NativeGet(_handle.GetAddress); + } + } + + /// + /// List of available port numbers from a device. + /// + public IEnumerable Ports + { + get + { + ThrowIfDisposed(); + return _handle.Ports(); + } + } + + /// + /// Checks if device is opened. + /// + public bool IsOpened + { + get + { + ThrowIfDisposed(); + return Interop.NativeGet(_handle.IsOpened); + } + } + + /// + /// Active configuration for the device. + /// + /// Throws exception if device is disconnected. + public UsbConfiguration ActiveConfiguration + { + get + { + ThrowIfDisposed(); + Interop.UsbConfigHandle configHandle = Interop.NativeGet(_handle.GetActiveConfig); + return _configurations.Values.Where(config => config._handle == configHandle).First(); + } + } + + /// + /// Dictionary mapping configuration Ids to configuration instances for this device. + /// + public IReadOnlyDictionary Configurations + { + get + { + ThrowIfDisposed(); + if (_configurations == null) + { + _configurations = new Dictionary(); + int count = Interop.NativeGet(_handle.GetNumConfigurations); + for (int i = 0; i < count; ++i) + { + Interop.UsbConfigHandle configHandle; + _handle.GetConfig(i, out configHandle); + _configurations.Add(i, new UsbConfiguration(this, configHandle)); + } + } + return _configurations; + } + } + + /// + /// Opens device, which allows performing operations on it. + /// + /// Throws exception in case of insufficient memory. + /// Throws exception if device is disconnected. + /// Throws exception if user has insufficient permission on device. + public void Open() + { + ThrowIfDisposed(); + _handle.Open().ThrowIfFailed("Failed to open device for use"); + } + + /// + /// Closes device for operations. + /// + /// Throws exception if device is not opened for operation. + public void Close() + { + ThrowIfDisposed(); + if (IsOpened == false) throw new InvalidOperationException("Device must be opened for operation first"); + + _handle.Close().ThrowIfFailed("Failed to close device for use"); + } + + internal void ThrowIfDisposed() + { + if (disposedValue) throw new ObjectDisposedException("USB Device is already disposed"); + } + + #region IDisposable Support + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (IsOpened) + { + Close(); + } + foreach(var config in _configurations.Values) { + config.Dispose(); + } + _configurations.Clear(); + _handle.Dispose(); + disposedValue = true; + } + } + + ~UsbDevice() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + #endregion + } +} -- 2.7.4