[USB] Added UsbEndpoint and related classes 48/133848/3
authorDinesh Dwivedi <dinesh.d@samsung.com>
Wed, 14 Jun 2017 14:49:46 +0000 (20:19 +0530)
committerDinesh Dwivedi <dinesh.d@samsung.com>
Wed, 21 Jun 2017 10:39:16 +0000 (16:09 +0530)
Change-Id: Ia29ff49bf74e2053b28438322cddf44e9326d369
Signed-off-by: Dinesh Dwivedi <dinesh.d@samsung.com>
Tizen.System.Usb/Interop/Interop.Constants.cs [new file with mode: 0644]
Tizen.System.Usb/Interop/Interop.Endpoint.cs [new file with mode: 0644]
Tizen.System.Usb/Interop/Interop.ErrorCode.cs [new file with mode: 0644]
Tizen.System.Usb/Interop/Interop.SafeUsbHandle.cs [new file with mode: 0644]
Tizen.System.Usb/Usb/EndpointDirection.cs [new file with mode: 0644]
Tizen.System.Usb/Usb/UsbEndpoint.cs [new file with mode: 0644]

diff --git a/Tizen.System.Usb/Interop/Interop.Constants.cs b/Tizen.System.Usb/Interop/Interop.Constants.cs
new file mode 100644 (file)
index 0000000..0e79720
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+internal static partial class Interop
+{
+    internal const int MaxStringDescriptorSize = 255;
+    internal const int MaxPortNumberCount = 8; // As per the USB 3.0 specs, the current maximum limit for the depth is 7
+    internal static partial class Libraries
+    {
+        public const string Usb = "libcapi-system-usbhost.so.0";
+    }
+}
\ No newline at end of file
diff --git a/Tizen.System.Usb/Interop/Interop.Endpoint.cs b/Tizen.System.Usb/Interop/Interop.Endpoint.cs
new file mode 100644 (file)
index 0000000..65536e7
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal enum EndpointDirection
+    {
+        In, // USB_HOST_DIRECTION_IN
+        Out, // USB_HOST_DIRECTION_OUT
+        InOut,
+    }
+
+    internal enum TransferType
+    {
+        Control, // USB_HOST_TRANSFER_TYPE_CONTROL
+        Isochronous, // USB_HOST_TRANSFER_TYPE_ISOCHRONOUS
+        Bulk, // USB_HOST_TRANSFER_TYPE_BULK
+        Interrupt, // USB_HOST_TRANSFER_TYPE_INTERRUPT
+    }
+
+    internal enum SynchronizationType
+    {
+        None, // USB_HOST_ISO_SYNC_TYPE_NONE
+        Async, // USB_HOST_ISO_SYNC_TYPE_ASYNC
+        Adaptive, // USB_HOST_ISO_SYNC_TYPE_ADAPTIVE
+        Sync, // USB_HOST_ISO_SYNC_TYPE_SYNC
+    }
+
+    internal enum UsageType
+    {
+        Data, // USB_HOST_USAGE_TYPE_DATA
+        Feedback, // USB_HOST_USAGE_TYPE_FEEDBACK
+        Implicit, // USB_HOST_USAGE_TYPE_IMPLICIT
+    }
+
+    [DllImport(Libraries.Usb, EntryPoint = "usb_host_endpoint_get_number")]
+    internal static extern ErrorCode GetNumber(this UsbEndpointHandle /* usb_host_endpoint_h */ ep, out int number);
+
+    [DllImport(Libraries.Usb, EntryPoint = "usb_host_endpoint_get_direction")]
+    internal static extern ErrorCode GetDirection(this UsbEndpointHandle /* usb_host_endpoint_h */ ep, out EndpointDirection /* usb_host_endpoint_direction_e */ direction);
+
+    [DllImport(Libraries.Usb, EntryPoint = "usb_host_endpoint_get_transfer_type")]
+    internal static extern ErrorCode GetTransferType(this UsbEndpointHandle /* usb_host_endpoint_h */ ep, out TransferType /* usb_host_transfer_type_e */ transferType);
+
+    [DllImport(Libraries.Usb, EntryPoint = "usb_host_endpoint_get_synch_type")]
+    internal static extern ErrorCode GetSynchType(this UsbEndpointHandle /* usb_host_endpoint_h */ ep, out SynchronizationType /* usb_host_iso_sync_type_e */ synchType);
+
+    [DllImport(Libraries.Usb, EntryPoint = "usb_host_endpoint_get_usage_type")]
+    internal static extern ErrorCode GetUsageType(this UsbEndpointHandle /* usb_host_endpoint_h */ ep, out UsageType /* usb_host_usage_type_e */ usageType);
+
+    [DllImport(Libraries.Usb, EntryPoint = "usb_host_endpoint_get_max_packet_size")]
+    internal static extern ErrorCode GetMaxPacketSize(this UsbEndpointHandle /* usb_host_endpoint_h */ ep, out int maxPacketSize);
+
+    [DllImport(Libraries.Usb, EntryPoint = "usb_host_endpoint_get_interval")]
+    internal static extern ErrorCode GetInterval(this UsbEndpointHandle /* usb_host_endpoint_h */ ep, out int interval);
+
+    [DllImport(Libraries.Usb, EntryPoint = "usb_host_transfer")]
+    internal static extern ErrorCode Transfer(this UsbEndpointHandle /* usb_host_endpoint_h */ ep, byte[] data, int length, out int transferred, uint timeout);
+
+    internal class UsbEndpointHandle
+    {
+        private IntPtr _handle;
+        public UsbEndpointHandle(IntPtr handle){ _handle = handle; }
+    }
+}
\ No newline at end of file
diff --git a/Tizen.System.Usb/Interop/Interop.ErrorCode.cs b/Tizen.System.Usb/Interop/Interop.ErrorCode.cs
new file mode 100644 (file)
index 0000000..973dc9d
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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.Runtime.CompilerServices;
+using Tizen;
+
+internal static partial class Interop
+{
+    internal enum ErrorCode
+    {
+        None = Tizen.Internals.Errors.ErrorCode.None,
+        IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+        InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+        PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+        NoSuchDevice = Tizen.Internals.Errors.ErrorCode.NoSuchDevice,
+        ResourceBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy,
+        TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut,
+        BrokenPipe = Tizen.Internals.Errors.ErrorCode.BrokenPipe,
+        InterruptedSysCall = Tizen.Internals.Errors.ErrorCode.InterruptedSysCall,
+        OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+        NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+        Unknown = Tizen.Internals.Errors.ErrorCode.Unknown,
+
+        NotFound = -0x024B0000 | 0x01, // USB_HOST_ERROR_NOT_FOUND,
+        Overflow = -0x024B0000 | 0x02, // USB_HOST_ERROR_OVERFLOW
+        DeviceNotOpened = -0x024B0000 | 0x03, // USB_HOST_ERROR_DEVICE_NOT_OPENED
+    }
+}
+
+internal static class ErrorCodeExtensions
+{
+    private const string LogTag = "Tizen.System.Usb";
+
+    internal static bool IsSuccess(this Interop.ErrorCode err)
+    {
+        return err == Interop.ErrorCode.None;
+    }
+
+    internal static bool IsFailed(this Interop.ErrorCode err)
+    {
+        return !err.IsSuccess();
+    }
+
+    /// <summary>
+    /// Utility method to check for error, returns false if failed and print warning messages
+    /// </summary>
+    /// <returns>true in case of no error, false otherwise</returns>
+    internal static bool WarnIfFailed(this Interop.ErrorCode err, string msg, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+    {
+        if (err.IsFailed())
+        {
+            Log.Debug(LogTag, $"{msg}, err: {err.ToString()}", file, func, line);
+            return false;
+        }
+        return true;
+    }
+
+    /// <summary>
+    /// Utility method to check for error, returns false if failed and throw exception
+    /// </summary>
+    /// <returns>true in case of no error</returns>
+    internal static bool ThrowIfFailed(this Interop.ErrorCode err, string msg, [CallerFilePath] string file = "", [CallerMemberName] string func = "", [CallerLineNumber] int line = 0)
+    {
+        if (err.IsFailed())
+        {
+            Log.Error(LogTag, $"{msg}, err: {err.ToString()}", file, func, line);
+            throw err.GetException(msg);
+        }
+        return true;
+    }
+
+    internal static Exception GetException(this Interop.ErrorCode err, string message)
+    {
+        string errMessage = $"{message}, err: {err.ToString()}";
+        switch (err)
+        {
+            //case Interop.ErrorCode.None:
+            case Interop.ErrorCode.PermissionDenied:
+                return new UnauthorizedAccessException(errMessage);
+            case Interop.ErrorCode.InvalidParameter:
+                return new ArgumentException(errMessage);
+            case Interop.ErrorCode.TimedOut:
+                return new TimeoutException(errMessage);
+            case Interop.ErrorCode.OutOfMemory:
+                return new OutOfMemoryException(errMessage);
+            case Interop.ErrorCode.NotSupported:
+                return new NotSupportedException(errMessage);
+
+            case Interop.ErrorCode.IoError:
+            case Interop.ErrorCode.NoSuchDevice:
+            case Interop.ErrorCode.ResourceBusy:
+            case Interop.ErrorCode.BrokenPipe:
+            case Interop.ErrorCode.InterruptedSysCall:
+            case Interop.ErrorCode.Unknown:
+
+            case Interop.ErrorCode.NotFound:
+            case Interop.ErrorCode.Overflow:
+            case Interop.ErrorCode.DeviceNotOpened:
+
+            default: return new InvalidOperationException(errMessage);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Tizen.System.Usb/Interop/Interop.SafeUsbHandle.cs b/Tizen.System.Usb/Interop/Interop.SafeUsbHandle.cs
new file mode 100644 (file)
index 0000000..5c5b5e7
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+
+internal static partial class Interop
+{
+    public delegate ErrorCode GetterMethod<T>(out T value);
+    public delegate ErrorCode GetterPtrMethod(out IntPtr value);
+    public delegate ErrorCode GetDescriptorString(ref int length, byte[] data);
+    public delegate ErrorCode SetterMethod<T>(T value);
+
+    internal static T NativeGet<T>(GetterMethod<T> getter, [CallerMemberName] string propertyName = "")
+    {
+        T value;
+        var err = getter(out value);
+        if (err.IsSuccess())
+        {
+            return value;
+        }
+
+        err.ThrowIfFailed($"Native getter for {propertyName} failed");
+        return default(T);
+    }
+
+    internal static string DescriptorString(GetDescriptorString getter, string language = "us-ascii", [CallerMemberName] string propertyName = "")
+    {
+        int len = MaxStringDescriptorSize;
+        byte[] data = new byte[len];
+        getter(ref len, data).ThrowIfFailed($"Native setter for {propertyName} failed");
+        return Encoding.GetEncoding(language).GetString(data, 0, len);
+    }
+
+    internal static void NativeSet<T>(SetterMethod<T> setter, T value, [CallerMemberName] string propertyName = "")
+    {
+        setter(value).ThrowIfFailed($"Native setter for {propertyName} failed");
+    }
+
+    internal abstract class SafeUsbHandle : SafeHandle
+    {
+        public abstract void Destroy();
+        public SafeUsbHandle() : base(IntPtr.Zero, true) { }
+        public SafeUsbHandle(IntPtr handle) : base(handle, true) { }
+        public override bool IsInvalid { get { return handle == IntPtr.Zero; } }
+        protected override bool ReleaseHandle()
+        {
+            Destroy();
+            SetHandle(IntPtr.Zero);
+            return true;
+        }
+    }
+}
diff --git a/Tizen.System.Usb/Usb/EndpointDirection.cs b/Tizen.System.Usb/Usb/EndpointDirection.cs
new file mode 100644 (file)
index 0000000..234054c
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+namespace Tizen.System.Usb
+{
+    /// <summary>
+    /// Enumeration of transfer direction for Endpoints
+    /// </summary>
+    public enum EndpointDirection
+    {
+        /// <summary>
+        /// IN direction
+        /// </summary>
+        In = Interop.EndpointDirection.In,
+        /// <summary>
+        /// OUT direction
+        /// </summary>
+        Out = Interop.EndpointDirection.Out,
+        /// <summary>
+        /// Bi-directional
+        /// </summary>
+        InOut = Interop.EndpointDirection.InOut,
+    }
+}
\ No newline at end of file
diff --git a/Tizen.System.Usb/Usb/UsbEndpoint.cs b/Tizen.System.Usb/Usb/UsbEndpoint.cs
new file mode 100644 (file)
index 0000000..ab366a6
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+namespace Tizen.System.Usb
+{
+    /// <summary>
+    /// USB Endpoint class
+    /// </summary>
+    public class UsbEndpoint
+    {
+        internal readonly Interop.UsbEndpointHandle _handle;
+
+        internal UsbEndpoint(Interop.UsbEndpointHandle handle)
+        {
+            _handle = handle;
+        }
+
+        /// <summary>
+        /// Gets number of this endpoint
+        /// </summary>
+        public int Id
+        {
+            get
+            {
+                return Interop.NativeGet<int>(_handle.GetNumber);
+            }
+        }
+
+        /// <summary>
+        /// Gets direction of this endpoint
+        /// </summary>
+        public EndpointDirection Direction
+        {
+            get
+            {
+                return (EndpointDirection)Interop.NativeGet<Interop.EndpointDirection>(_handle.GetDirection);
+            }
+        }
+
+        /// <summary>
+        /// Gets max packet size of given endpoint
+        /// </summary>
+        public int MaxPacketSize
+        {
+            get
+            {
+                return Interop.NativeGet<int>(_handle.GetMaxPacketSize);
+            }
+        }
+
+        protected int TransferImpl(byte[] buffer, int length, uint timeout)
+        {
+            int transferred;
+            _handle.Transfer(buffer, length, out transferred, timeout).ThrowIfFailed("Transfer failed");
+            return transferred;
+        }
+    }
+}
\ No newline at end of file