/*
* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
/**
@file
@internalComponent
*/
#include "subcommands.h"
#include "msmmserver.h"
#include "msmmengine.h"
#include "msmmnodebase.h"
#include "handlerinterface.h"
#include "msmm_internal_def.h"
#include <usb/hostms/msmmpolicypluginbase.h>
#include <usb/hostms/srverr.h>
#include <usb/usblogger.h>
#ifdef __FLOG_ACTIVE
_LIT8(KLogComponent, "UsbHostMsmmServer");
#endif
/**
* TRegisterInterface member functions
*/
TRegisterInterface::TRegisterInterface(THostMsSubCommandParam aParam):
TSubCommandBase(aParam),
iDeviceNode(NULL),
iInterfaceNode(NULL)
{
LOG_FUNC
}
void TRegisterInterface::DoExecuteL()
{
LOG_FUNC
// Add new interface node into data engine
iInterfaceNode = iServer.Engine().AddUsbMsInterfaceL(iEvent.iDeviceId,
iEvent.iInterfaceNumber, iEvent.iInterfaceToken);
iDeviceNode = iServer.Engine().SearchDevice(iEvent.iDeviceId);
if (!iDeviceNode)
{
User::Leave(KErrArgument);
}
TUSBMSDeviceDescription& device = iDeviceNode->iDevice;
iMsConfig.iInterfaceToken = iEvent.iInterfaceToken;
iMsConfig.iInterfaceNumber = iEvent.iInterfaceNumber;
iMsConfig.iVendorId = device.iVendorId;
iMsConfig.iProductId = device.iProductId;
iMsConfig.iBcdDevice = device.iBcdDevice;
iMsConfig.iConfigurationNumber = device.iConfigurationNumber;
iMsConfig.iSerialNumber.Copy(device.iSerialNumber);
iMsConfig.iProtocolId = device.iProtocolId;
iMsConfig.iTransportId = device.iTransportId;
iMsConfig.iRemoteWakeup = device.iRemoteWakeup;
iMsConfig.iIsOtgClient = device.iIsOtgClient;
LOGTEXT2(_L8("\t iMsConfig.iProtocolId %d"), iMsConfig.iProtocolId);
LOGTEXT2(_L8("\t iMsConfig.iTransportId %d"), iMsConfig.iTransportId);
LOGTEXT2(_L8("\t iMsConfig.iRemoteWakeup %d"), iMsConfig.iRemoteWakeup);
LOGTEXT2(_L8("\t iMsConfig.iIsOtgClient %d"), iMsConfig.iIsOtgClient);
TSuspensionPolicy suspensionPolicy;
iServer.PolicyPlugin()->GetSuspensionPolicy(suspensionPolicy);
iMsConfig.iOtgSuspendTime = suspensionPolicy.iOtgSuspendTime;
iMsConfig.iStatusPollingInterval = suspensionPolicy.iStatusPollingInterval;
LOGTEXT2(_L8("\t iMsConfig.iStatusPollingInterval %d"), iMsConfig.iStatusPollingInterval);
LOGTEXT2(_L8("\t iMsConfig.iOtgSuspendTime %d"), iMsConfig.iOtgSuspendTime);
iHandler.Start();
iInterfaceNode->iUsbMsDevice.Add(iMsConfig, iHandler.Status());
}
void TRegisterInterface::HandleError(THostMsErrData& aData, TInt aError)
{
LOG_FUNC
switch (aError)
{
case KErrNoMemory:
aData.iError = EHostMsErrOutOfMemory;
break;
case KErrAlreadyExists:
case KErrArgument:
aData.iError = EHostMsErrInvalidParameter;
break;
default:
aData.iError = EHostMsErrGeneral;
}
aData.iE32Error = aError;
if (iDeviceNode)
{
TUSBMSDeviceDescription& device = iDeviceNode->iDevice;
aData.iManufacturerString.Copy(device.iManufacturerString);
aData.iProductString.Copy(device.iProductString);
aData.iDriveName = 0x0;
}
if (iInterfaceNode)
{
iServer.Engine().RemoveUsbMsNode(iInterfaceNode);
iInterfaceNode = NULL;
}
}
void TRegisterInterface::DoAsyncCmdCompleteL()
{
LOG_FUNC
User::LeaveIfError(iHandler.Status().Int());
if(iInterfaceNode)
{
User::LeaveIfError(
iInterfaceNode->iUsbMsDevice.GetNumLun(iMaxLogicalUnit));
}
LOGTEXT2(_L8("\tGetNumLun %d"), iMaxLogicalUnit);
iCreator.CreateSubCmdForRetrieveDriveLetterL(iMaxLogicalUnit);
}
void TRegisterInterface::DoCancelAsyncCmd()
{
LOG_FUNC
if(iInterfaceNode)
{
iInterfaceNode->iUsbMsDevice.Remove();
iServer.Engine().RemoveUsbMsNode(iInterfaceNode);
iInterfaceNode = NULL;
}
}
/**
* TRetrieveDriveLetter member functions
*/
TRetrieveDriveLetter::TRetrieveDriveLetter(
THostMsSubCommandParam& aParameter, TInt aLuNumber):
TSubCommandBase(aParameter),
iLuNumber(aLuNumber),
iDrive(0)
{
LOG_FUNC
}
void TRetrieveDriveLetter::DoExecuteL()
{
LOG_FUNC
TUsbMsDevice* deviceEntry(NULL);
deviceEntry = iServer.Engine().SearchDevice(iEvent.iDeviceId);
if (!deviceEntry)
{
User::Leave(KErrArgument);
}
else
{
TUSBMSDeviceDescription& device = deviceEntry->iDevice;
iRequestData.iBcdDevice = device.iBcdDevice;
iRequestData.iConfigurationNumber = device.iConfigurationNumber;
iRequestData.iInterfaceNumber = iEvent.iInterfaceNumber;
iRequestData.iDeviceId = iEvent.iDeviceId;
iRequestData.iProductId = device.iProductId;
iRequestData.iVendorId = device.iVendorId;
iRequestData.iLogicUnitNumber = iLuNumber;
iRequestData.iOtgInformation = device.iOtgInformation;
iRequestData.iManufacturerString = device.iManufacturerString;
iRequestData.iProductString = device.iProductString;
iRequestData.iSerialNumber = device.iSerialNumber;
iHandler.Start();
TRequestStatus& status = iHandler.Status();
iServer.PolicyPlugin()->RetrieveDriveLetterL(
iDrive, iRequestData, status);
}
}
void TRetrieveDriveLetter::HandleError(THostMsErrData& aData, TInt aError)
{
LOG_FUNC
switch (aError)
{
case KErrArgument:
aData.iError = EHostMsErrInvalidParameter;
break;
case KErrNotFound:
aData.iError = EHostMsErrNoDriveLetter;
break;
case KErrNoMemory:
aData.iError = EHostMsErrOutOfMemory;
break;
default:
aData.iError = EHostMsErrGeneral;
}
aData.iE32Error = aError;
aData.iManufacturerString = iRequestData.iManufacturerString;
aData.iProductString = iRequestData.iProductString;
aData.iDriveName = iDrive;
}
void TRetrieveDriveLetter::DoAsyncCmdCompleteL()
{
LOG_FUNC
User::LeaveIfError(iHandler.Status().Int());
iCreator.CreateSubCmdForMountingLogicalUnitL(iDrive, iLuNumber);
}
void TRetrieveDriveLetter::DoCancelAsyncCmd()
{
LOG_FUNC
iServer.PolicyPlugin()->CancelRetrieveDriveLetter();
}
/**
* TMountLogicalUnit member functions
*/
TMountLogicalUnit::TMountLogicalUnit(THostMsSubCommandParam& aParameter,
TText aDrive, TInt aLuNumber):
TSubCommandBase(aParameter),
iDrive(aDrive),
iLuNumber(aLuNumber)
{
LOG_FUNC
iIsKeyCommand = EFalse;
}
void TMountLogicalUnit::DoExecuteL()
{
LOG_FUNC
TInt ret(KErrNone);
RFs& fs = iServer.FileServerSession();
TInt driveNum;
User::LeaveIfError(fs.CharToDrive(iDrive, driveNum));
TUsbMsDevice* device = NULL;
TUsbMsInterface* interface = NULL;
device = iServer.Engine().SearchDevice(iEvent.iDeviceId);
if (!device)
{
User::Leave(KErrArgument);
}
interface = iServer.Engine().SearchInterface(device, iEvent.iInterfaceNumber);
if (!interface)
{
User::Leave(KErrArgument);
}
ret = interface->iUsbMsDevice.MountLun(iLuNumber, driveNum);
if ((KErrNone != ret) && (KErrAlreadyExists != ret)
&& (KErrNotReady != ret))
{
User::Leave (ret);
}
iHandler.Start();
iHandler.Complete();
}
void TMountLogicalUnit::HandleError(THostMsErrData& aData, TInt aError)
{
LOG_FUNC
switch (aError)
{
case KErrNoMemory:
aData.iError = EHostMsErrOutOfMemory;
break;
case KErrArgument:
aData.iError = EHostMsErrInvalidParameter;
break;
case KErrCorrupt:
{
aData.iError = EHostMsErrUnknownFileSystem;
// Current implementation of USB Mass Storage extension will mount
// a logical unit successfully even the logical unit is in an
// unsupported format like NTFS or CDFS. So we have to recode this
// Logical unit down in the our data engine in order to dismount it
// in future when the interface which presents this logical unit is
// dettached. Reuse DoAsyncCmdCompleteL to do this.
// Check if the new drive mounted successfully.
RFs& fs = iServer.FileServerSession();
TInt driveNum;
User::LeaveIfError(fs.CharToDrive(iDrive, driveNum));
TDriveList drives;
User::LeaveIfError(fs.DriveList(drives));
if (drives[driveNum])
{
// Drive name mounted
DoAsyncCmdCompleteL();
// Restart the handler
iHandler.Start();
}
}
break;
default:
aData.iError = EHostMsErrGeneral;
}
aData.iE32Error = aError;
TUsbMsDevice* deviceNode = iServer.Engine().SearchDevice(iEvent.iDeviceId);
if (deviceNode)
{
aData.iManufacturerString.Copy(deviceNode->iDevice.iManufacturerString);
aData.iProductString.Copy(deviceNode->iDevice.iProductString);
}
aData.iDriveName = iDrive;
}
void TMountLogicalUnit::DoAsyncCmdCompleteL()
{
LOG_FUNC
iServer.Engine().AddUsbMsLogicalUnitL(
iEvent.iDeviceId, iEvent.iInterfaceNumber,
iLuNumber, iDrive);
iCreator.CreateSubCmdForSaveLatestMountInfoL(iDrive, iLuNumber);
}
/**
* TSaveLatestMountInfo member functions
*/
TSaveLatestMountInfo::TSaveLatestMountInfo(
THostMsSubCommandParam& aParameter,
TText aDrive, TInt aLuNumber):
TSubCommandBase(aParameter),
iDrive(aDrive),
iLuNumber(aLuNumber)
{
LOG_FUNC
iIsKeyCommand = EFalse;
}
void TSaveLatestMountInfo::DoExecuteL()
{
LOG_FUNC
TUsbMsDevice* deviceEntry(NULL);
deviceEntry = iServer.Engine().SearchDevice(iEvent.iDeviceId);
if (!deviceEntry)
{
User::Leave(KErrArgument);
}
else
{
TPolicyRequestData& request = iRecord.iLogicUnit;
TUSBMSDeviceDescription& device = deviceEntry->iDevice;
request.iBcdDevice = device.iBcdDevice;
request.iConfigurationNumber = device.iConfigurationNumber;
request.iInterfaceNumber = iEvent.iInterfaceNumber;
request.iDeviceId = iEvent.iDeviceId;
request.iProductId = device.iProductId;
request.iVendorId = device.iVendorId;
request.iLogicUnitNumber = iLuNumber;
request.iOtgInformation = device.iOtgInformation;
request.iManufacturerString = device.iManufacturerString;
request.iProductString = device.iProductString;
request.iSerialNumber = device.iSerialNumber;
iRecord.iDriveName = iDrive;
iHandler.Start();
TRequestStatus& status = iHandler.Status();
iServer.PolicyPlugin()->SaveLatestMountInfoL(iRecord, status);
}
}
void TSaveLatestMountInfo::DoAsyncCmdCompleteL()
{
LOG_FUNC
User::LeaveIfError(iHandler.Status().Int());
}
void TSaveLatestMountInfo::HandleError(THostMsErrData& aData, TInt aError)
{
LOG_FUNC
switch (aError)
{
case KErrNoMemory:
aData.iError = EHostMsErrOutOfMemory;
break;
case KErrArgument:
aData.iError = EHostMsErrInvalidParameter;
break;
default:
aData.iError = EHostMsErrGeneral;
}
aData.iE32Error = aError;
aData.iManufacturerString = iRecord.iLogicUnit.iManufacturerString;
aData.iProductString = iRecord.iLogicUnit.iProductString;
aData.iDriveName = iDrive;
}
void TSaveLatestMountInfo::DoCancelAsyncCmd()
{
LOG_FUNC
iServer.PolicyPlugin()->CancelSaveLatestMountInfo();
}
/**
* TDeregisterInterface member functions
*/
TDeregisterInterface::TDeregisterInterface(
THostMsSubCommandParam& aParameter,
TUint8 aInterfaceNumber, TUint32 aInterfaceToken):
TSubCommandBase(aParameter),
iInterfaceNumber(aInterfaceNumber),
iInterfaceToken(aInterfaceToken),
iDeviceNode(NULL),
iInterfaceNode(NULL)
{
LOG_FUNC
}
void TDeregisterInterface::DoExecuteL()
{
LOG_FUNC
iDeviceNode = iServer.Engine().SearchDevice(iEvent.iDeviceId);
if (!iDeviceNode)
{
User::Leave(KErrArgument);
}
iInterfaceNode = iServer.Engine().SearchInterface(iDeviceNode,
iInterfaceNumber);
if (!iInterfaceNode)
{
User::Leave(KErrArgument);
}
TUSBMSDeviceDescription& device = iDeviceNode->iDevice;
iMsConfig.iInterfaceToken = iInterfaceToken;
iMsConfig.iVendorId = device.iVendorId;
iMsConfig.iProductId = device.iVendorId;
iMsConfig.iBcdDevice = device.iBcdDevice;
iMsConfig.iConfigurationNumber = device.iConfigurationNumber;
iMsConfig.iInterfaceNumber = iInterfaceNumber;
iMsConfig.iSerialNumber.Copy(device.iSerialNumber);
iInterfaceNode->iUsbMsDevice.Remove();
// Activate the handler.
iHandler.Start();
// Simulate a async request be completed.
iHandler.Complete();
}
void TDeregisterInterface::HandleError(THostMsErrData& aData, TInt aError)
{
LOG_FUNC
switch (aError)
{
case KErrNoMemory:
aData.iError = EHostMsErrOutOfMemory;
break;
case KErrArgument:
aData.iError = EHostMsErrInvalidParameter;
break;
default:
aData.iError = EHostMsErrGeneral;
}
aData.iE32Error = aError;
if (iDeviceNode)
{
aData.iManufacturerString.Copy(iDeviceNode->iDevice.iManufacturerString);
aData.iProductString.Copy(iDeviceNode->iDevice.iProductString);
}
aData.iDriveName = 0;
}
/**
* TDismountLogicalUnit member functions
*/
TDismountLogicalUnit::TDismountLogicalUnit(
THostMsSubCommandParam& aParameter,
const TUsbMsLogicalUnit& aLogicalUnit):
TSubCommandBase(aParameter),
iLogicalUnit(aLogicalUnit)
{
LOG_FUNC
}
void TDismountLogicalUnit::DoExecuteL()
{
LOG_FUNC
RFs& fs = iServer.FileServerSession();
TInt driveNum;
fs.CharToDrive(iLogicalUnit.iDrive, driveNum);
TUsbMsInterface* interface(NULL);
interface = iLogicalUnit.Parent();
if (!interface)
{
User::Leave(KErrArgument);
}
User::LeaveIfError(interface->iUsbMsDevice.DismountLun(driveNum));
// Activate the handler.
iHandler.Start();
// Simulate a async request be completed.
iHandler.Complete();
}
void TDismountLogicalUnit::HandleError(THostMsErrData& aData, TInt aError)
{
LOG_FUNC
switch (aError)
{
case KErrNoMemory:
aData.iError = EHostMsErrOutOfMemory;
break;
case KErrArgument:
aData.iError = EHostMsErrInvalidParameter;
break;
default:
aData.iError = EHostMsErrGeneral;
}
aData.iE32Error = aError;
TUsbMsDevice* deviceNode = iServer.Engine().SearchDevice(iEvent.iDeviceId);
if (deviceNode)
{
aData.iManufacturerString.Copy(deviceNode->iDevice.iManufacturerString);
aData.iProductString.Copy(deviceNode->iDevice.iProductString);
}
aData.iDriveName = iLogicalUnit.iDrive;
}
/**
* TRemoveUsbMsDeviceNode member functions
*/
TRemoveUsbMsDeviceNode::TRemoveUsbMsDeviceNode(
THostMsSubCommandParam& aParameter,
TMsmmNodeBase* aNodeToBeRemoved):
TSubCommandBase(aParameter),
iNodeToBeRemoved(aNodeToBeRemoved)
{
LOG_FUNC
}
void TRemoveUsbMsDeviceNode::DoExecuteL()
{
LOG_FUNC
if(iNodeToBeRemoved)
{
iServer.Engine().RemoveUsbMsNode(iNodeToBeRemoved);
iNodeToBeRemoved = NULL;
}
else
{
User::Leave(KErrArgument);
}
// Activate the handler.
iHandler.Start();
// Simulate a async request be completed.
iHandler.Complete();
}
void TRemoveUsbMsDeviceNode::HandleError(THostMsErrData& aData, TInt aError)
{
LOG_FUNC
switch (aError)
{
case KErrArgument:
aData.iError = EHostMsErrInvalidParameter;
break;
default:
aData.iError = EHostMsErrGeneral;
}
aData.iE32Error = aError;
TUsbMsDevice* deviceNode = iServer.Engine().SearchDevice(iEvent.iDeviceId);
if (deviceNode)
{
aData.iManufacturerString.Copy(deviceNode->iDevice.iManufacturerString);
aData.iProductString.Copy(deviceNode->iDevice.iProductString);
}
aData.iDriveName = 0;
}
// End of file