From 4bd6364f4a0e9c8c52e54f4dc8ba3bac6b607635 Mon Sep 17 00:00:00 2001 From: Dinesh Dwivedi Date: Wed, 14 Jun 2017 20:19:46 +0530 Subject: [PATCH] [USB] Added UsbEndpoint and related classes Change-Id: Ia29ff49bf74e2053b28438322cddf44e9326d369 Signed-off-by: Dinesh Dwivedi --- Tizen.System.Usb/Interop/Interop.Constants.cs | 24 +++++ Tizen.System.Usb/Interop/Interop.Endpoint.cs | 81 +++++++++++++++ Tizen.System.Usb/Interop/Interop.ErrorCode.cs | 117 ++++++++++++++++++++++ Tizen.System.Usb/Interop/Interop.SafeUsbHandle.cs | 68 +++++++++++++ Tizen.System.Usb/Usb/EndpointDirection.cs | 37 +++++++ Tizen.System.Usb/Usb/UsbEndpoint.cs | 73 ++++++++++++++ 6 files changed, 400 insertions(+) create mode 100644 Tizen.System.Usb/Interop/Interop.Constants.cs create mode 100644 Tizen.System.Usb/Interop/Interop.Endpoint.cs create mode 100644 Tizen.System.Usb/Interop/Interop.ErrorCode.cs create mode 100644 Tizen.System.Usb/Interop/Interop.SafeUsbHandle.cs create mode 100644 Tizen.System.Usb/Usb/EndpointDirection.cs create mode 100644 Tizen.System.Usb/Usb/UsbEndpoint.cs diff --git a/Tizen.System.Usb/Interop/Interop.Constants.cs b/Tizen.System.Usb/Interop/Interop.Constants.cs new file mode 100644 index 0000000..0e79720 --- /dev/null +++ b/Tizen.System.Usb/Interop/Interop.Constants.cs @@ -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 index 0000000..65536e7 --- /dev/null +++ b/Tizen.System.Usb/Interop/Interop.Endpoint.cs @@ -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 index 0000000..973dc9d --- /dev/null +++ b/Tizen.System.Usb/Interop/Interop.ErrorCode.cs @@ -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(); + } + + /// + /// Utility method to check for error, returns false if failed and print warning messages + /// + /// true in case of no error, false otherwise + 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; + } + + /// + /// Utility method to check for error, returns false if failed and throw exception + /// + /// true in case of no error + 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 index 0000000..5c5b5e7 --- /dev/null +++ b/Tizen.System.Usb/Interop/Interop.SafeUsbHandle.cs @@ -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(out T value); + public delegate ErrorCode GetterPtrMethod(out IntPtr value); + public delegate ErrorCode GetDescriptorString(ref int length, byte[] data); + public delegate ErrorCode SetterMethod(T value); + + internal static T NativeGet(GetterMethod 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(SetterMethod 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 index 0000000..234054c --- /dev/null +++ b/Tizen.System.Usb/Usb/EndpointDirection.cs @@ -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 +{ + /// + /// Enumeration of transfer direction for Endpoints + /// + public enum EndpointDirection + { + /// + /// IN direction + /// + In = Interop.EndpointDirection.In, + /// + /// OUT direction + /// + Out = Interop.EndpointDirection.Out, + /// + /// Bi-directional + /// + 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 index 0000000..ab366a6 --- /dev/null +++ b/Tizen.System.Usb/Usb/UsbEndpoint.cs @@ -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 +{ + /// + /// USB Endpoint class + /// + public class UsbEndpoint + { + internal readonly Interop.UsbEndpointHandle _handle; + + internal UsbEndpoint(Interop.UsbEndpointHandle handle) + { + _handle = handle; + } + + /// + /// Gets number of this endpoint + /// + public int Id + { + get + { + return Interop.NativeGet(_handle.GetNumber); + } + } + + /// + /// Gets direction of this endpoint + /// + public EndpointDirection Direction + { + get + { + return (EndpointDirection)Interop.NativeGet(_handle.GetDirection); + } + } + + /// + /// Gets max packet size of given endpoint + /// + public int MaxPacketSize + { + get + { + return Interop.NativeGet(_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 -- 2.7.4