HostUSBDeviceImpl.h revision 2782c227354d0c29f08a7933a07f8aa9b30e010d
/* $Id$ */
/** @file
* VirtualBox IHostUSBDevice COM interface implementation.
*/
/*
* Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#ifndef ____H_HOSTUSBDEVICEIMPL
#define ____H_HOSTUSBDEVICEIMPL
#include "VirtualBoxBase.h"
#include "USBDeviceFilterImpl.h"
/* #include "USBProxyService.h" circular on Host/HostUSBDevice, the includer
* must include this. */
#include "Logging.h"
#include "HostUSBDeviceWrap.h"
/**
* The unified state machine of HostUSBDevice.
*
* This is a super set of USBDEVICESTATE / USBDeviceState_T that
* includes additional states for tracking state transitions.
*
* @remarks
* The CapturingForVM and CapturingForProxy states have been merged
* into Capturing with a destination state (AttachingToVM or HeldByProxy).
*
* The DetachingFromVM state is a merge of DetachingFromVMToProxy and
* DetachingFromVMToHost and uses the destination state (HeldByProxy
* or ReleasingToHost) like Capturing.
*
* The *AwaitingDetach and *AwaitingReattach substates (optionally used
* in Capturing, AttachingToVM, DetachingFromVM and ReleasingToHost) are
* implemented via a substate kHostUSBDeviceSubState.
*/
typedef enum
{
/** The device is unsupported (HUB).
* Next Host: PhysDetached.
* Next VBox: No change permitted.
*/
/** The device is used exclusivly by the host or is inaccessible for some other reason.
* Next Host: Capturable, Unused, PhysDetached.
* Run filters.
* Next VBox: No change permitted.
*/
/** The device is used by the host but can be captured.
* Next Host: Unsupported, UsedByHost, Unused, PhysDetached.
* Run filters if Unused (for wildcard filters).
* Next VBox: CapturingForVM, CapturingForProxy.
*/
/** The device is not used by the host and can be captured.
* Next Host: UsedByHost, Capturable, PhysDetached
* Don't run any filters (done on state entry).
* Next VBox: CapturingForVM, CapturingForProxy.
*/
/** The device is held captive by the proxy.
* Next Host: PhysDetached
* Next VBox: ReleasingHeld, AttachingToVM
*/
/** The device is in use by a VM.
* Next Host: PhysDetachingFromVM
* Next VBox: DetachingFromVM
*/
/** The device has been detach from both the host and VMs.
* This is the final state. */
/** The start of the transitional states. */
/** The device is being seized from the host, either for HeldByProxy or for AttachToVM.
*
* On some hosts we will need to re-enumerate the in which case the sub-state
* is employed to track this progress. On others, this is synchronous or faked, and
* will will then leave the device in this state and poke the service thread to do
* the completion state change.
*
* Next Host: PhysDetached.
* Next VBox: HeldByProxy or AttachingToVM on success,
* previous state (Unused or Capturable) or UsedByHost on failure.
*/
/** The device is being released back to the host, following VM or Proxy usage.
* Most hosts needs to re-enumerate the device and will therefore employ the
* sub-state as during capturing. On the others we'll just leave it to the usb
* service thread to advance the device state.
*
* Next Host: Unused, UsedByHost, Capturable.
* No filters.
* Next VBox: PhysDetached (timeout), HeldByProxy (failure).
*/
/** The device is being attached to a VM.
*
* This requires IPC to the VM and we will not advance the state until
* that completes.
*
* Next Host: PhysDetachingFromVM.
* Next VBox: UsedByGuest, HeldByProxy (failure).
*/
/** The device is being detached from a VM and will be returned to the proxy or host.
*
* This involves IPC and may or may not also require re-enumeration of the
* device. Which means that it might transition directly into the ReleasingToHost state
* because the client (VM) will do the actual re-enumeration.
*
* Next Host: PhysDetachingFromVM (?) or just PhysDetached.
* Next VBox: ReleasingToHost, HeldByProxy.
*/
/** The device has been physically removed while a VM used it.
*
* This is the device state while VBoxSVC is doing IPC to the client (VM) telling it
* to detach it.
*
* Next Host: None.
* Next VBox: PhysDetached
*/
/** Just an invalid state value for use as default for some methods. */
kHostUSBDeviceState_Invalid = 0x7fff
/**
* Sub-state for dealing with device re-enumeration.
*/
typedef enum
{
/** Not in any sub-state. */
/** Awaiting a logical device detach following a device re-enumeration. */
/** Awaiting a logical device re-attach following a device re-enumeration. */
/**
* Object class used to hold Host USB Device properties.
*/
{
void FinalRelease();
// public initializer/uninitializer for internal purposes only
void uninit();
// public methods only for internal purposes
/** @note Must be called from under the object read lock. */
/** @note Must be called from under the object read lock. */
/** @note Must be called from under the object read lock. */
/** @note Must be called from under the object read lock. */
bool i_isCapturableOrHeld()
{
return mUniState == kHostUSBDeviceState_Unused
}
/** @note Must be called from under the object read lock. */
/** @note Must be called from under the object read lock. */
HRESULT i_onDetachFromVM(SessionMachine *aMachine, bool aDone, bool *aRunFilters, bool aAbnormal = false);
bool i_wasActuallyDetached();
void i_onPhysicalDetached();
HRESULT i_attachToVM(SessionMachine *aMachine, const com::Utf8Str &aCaptureFilename, ULONG aMaskedIfs = 0);
void i_onPhysicalDetachedInternal();
bool i_hasAsyncOperationTimedOut() const;
bool i_setState (HostUSBDeviceState aNewState, HostUSBDeviceState aNewPendingState = kHostUSBDeviceState_Invalid,
bool i_advanceTransition(bool aSkipReAttach = false);
bool i_failTransition();
USBDeviceState_T i_canonicalState() const;
// wrapped IUSBDevice properties
/** @name The state machine variables
* Only setState(), init() and uninit() will modify these members!
* @{ */
/** The RTTimeNanoTS() corresponding to the last state change.
*
* Old state machine: RTTimeNanoTS() of when mIsStatePending was set or mDetaching changed
* from kNotDetaching. For operations that cannot be canceled it's 0. */
/** Current state. */
/** Sub-state for tracking re-enumeration. */
/** The final state of an pending transition.
* This is mainly a measure to reduce the number of HostUSBDeviceState values. */
/** Previous state.
* This is used for bailing out when a transition like capture fails. */
/** Indicator set by onDetachedPhys and check when advancing a transitional state. */
bool mIsPhysicallyDetached;
/** @} */
/** The machine the usb device is (being) attached to. */
/** Pointer to the USB Proxy Service instance. */
/** Pointer to the USB Device structure owned by this device.
* Only used for host devices. */
/** The interface mask to be used in the pending capture.
* This is a filter property. */
/** The name of this device. */
/** The name of this device (for logging purposes).
* This points to the string in mNameObj. */
const char *mName;
/** The filename to capture the USB traffic to. */
#ifdef RT_OS_SOLARIS
/** One-shot filter id only for new code */
void *mOneShotId;
#endif
#ifdef RT_OS_LINUX
#endif
#ifdef RT_OS_DARWIN
/** One-shot filter id. */
void *mOneShotId;
#endif
#ifdef RT_OS_FreeBSD
#endif
};
#endif // ____H_HOSTUSBDEVICEIMPL
/* vi: set tabstop=4 shiftwidth=4 expandtab: */