--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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