/*
* 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 readonly UsbManager _parent;
private Dictionary _configurations = new Dictionary();
internal UsbDevice(UsbManager parent, Interop.HostDeviceHandle handle)
{
_parent = parent;
_handle = handle;
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));
}
}
///
/// 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);
}
}
///
/// Control endpoint (endpoint 0).
///
public UsbControlEndpoint ControlEndpoint
{
get
{
ThrowIfDisposed();
return new UsbControlEndpoint(this);
}
}
///
/// 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();
return _configurations;
}
}
///
/// Device information such as version, class, subclass etc.
///
public UsbDeviceInformation DeviceInformation
{
get
{
ThrowIfDisposed();
return new UsbDeviceInformation(this);
}
}
///
/// String associated with device.
///
public UsbDeviceStrings Strings
{
get
{
ThrowIfDisposed();
return new UsbDeviceStrings(this, "us-ascii");
}
}
///
/// 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.CloseHandle().ThrowIfFailed("Failed to close device for use");
}
internal void ThrowIfDisposed()
{
if (disposedValue) throw new ObjectDisposedException("USB Device is already disposed");
_parent.ThrowIfDisposed();
}
#region IDisposable Support
private bool disposedValue = false;
///
/// Releases all resources used by the ConnectionProfile.
/// It should be called after finished using of the object.
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;
}
}
///
/// Finalizes an instance of the UsbDevice class.
///
~UsbDevice()
{
Dispose(false);
}
///
/// Releases all resources used by the ConnectionProfile.
/// It should be called after finished using of the object.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
}