--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usbmgmt/usbmgr/host/fdf/production/server/src/deviceproxy.cpp Tue Feb 02 02:02:59 2010 +0200
@@ -0,0 +1,444 @@
+/*
+* Copyright (c) 2007-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 "deviceproxy.h"
+#include <usb/usblogger.h>
+#include <usbhostdefs.h>
+#include "utils.h"
+#include "event.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "fdf ");
+#endif
+
+#ifdef _DEBUG
+PANICCATEGORY("devproxy");
+#endif
+
+#ifdef __FLOG_ACTIVE
+#define LOG Log()
+#else
+#define LOG
+#endif
+
+CDeviceProxy* CDeviceProxy::NewL(RUsbHubDriver& aHubDriver, TUint aDeviceId)
+ {
+ LOG_STATIC_FUNC_ENTRY
+
+ CDeviceProxy* self = new(ELeave) CDeviceProxy(aDeviceId);
+ CleanupStack::PushL(self);
+ self->ConstructL(aHubDriver);
+ CLEANUPSTACK_POP1(self);
+ return self;
+ }
+
+CDeviceProxy::CDeviceProxy(TUint aDeviceId)
+: iId(aDeviceId)
+ {
+ LOG_FUNC
+ }
+
+void CDeviceProxy::ConstructL(RUsbHubDriver& aHubDriver)
+ {
+ LOG_FUNC
+
+ LEAVEIFERRORL(iHandle.Open(aHubDriver, iId));
+
+ // Pre-allocate objects relating to this device for the event queue.
+ iAttachmentEvent = new(ELeave) TDeviceEvent;
+ iAttachmentEvent->iInfo.iEventType = EDeviceAttachment;
+ iAttachmentEvent->iInfo.iDeviceId = iId;
+
+ iDriverLoadingEvent = new(ELeave) TDeviceEvent;
+ iDriverLoadingEvent->iInfo.iEventType = EDriverLoad;
+ iDriverLoadingEvent->iInfo.iDeviceId = iId;
+
+ iDetachmentEvent = new(ELeave) TDeviceEvent;
+ iDetachmentEvent->iInfo.iEventType = EDeviceDetachment;
+ iDetachmentEvent->iInfo.iDeviceId = iId;
+
+ ReadStringDescriptorsL();
+
+ LOG;
+ }
+
+void CDeviceProxy::ReadStringDescriptorsL()
+ {
+ LOG_FUNC
+
+ // wait 10 ms before reading any string descriptors
+ // to avoid IOP issues with some USB devices (e.g. PNY Attache)
+ User::After(10000);
+
+ // First read string descriptor 0 (supported languages).
+ // For each supported language, read the manufacturer, product and serial
+ // number string descriptors (as supported). (These are not cached in
+ // USBD.)
+ // To look up these string descriptors we need to get the device
+ // descriptor. The device descriptor *is* cached in USBD, so we don't
+ // remember our own copy, even though it is queried later by the CFdf.
+
+ // '0' is the index of the string descriptor which holds the supported
+ // language IDs.
+ TBuf8<256> stringBuf;
+ TUsbStringDescriptor* stringDesc = NULL;
+ ASSERT_DEBUG(iHandle.Handle());
+ LEAVEIFERRORL(iHandle.GetStringDescriptor(stringDesc, stringBuf, 0));
+ CleanupStack::PushL(*stringDesc);
+
+ // Copy the language IDs into our array.
+ TUint index = 0;
+ TInt16 langId = stringDesc->GetLangId(index);
+ while ( langId != KErrNotFound )
+ {
+ LOGTEXT2(_L8("\tsupported language: 0x%04x"), langId);
+ iLangIds.AppendL(langId); // stored as TUint
+ ++index;
+ langId = stringDesc->GetLangId(index);
+ }
+
+ CleanupStack::PopAndDestroy(stringDesc);
+
+ // Get the actual strings for each supported language.
+ TUsbDeviceDescriptor deviceDescriptor;
+ ASSERT_DEBUG(iHandle.Handle());
+ LEAVEIFERRORL(iHandle.GetDeviceDescriptor(deviceDescriptor));
+ TUint8 manufacturerStringDescriptorIndex = deviceDescriptor.ManufacturerIndex();
+ TUint8 productStringDescriptorIndex = deviceDescriptor.ProductIndex();
+ TUint8 serialNumberStringDescriptorIndex = deviceDescriptor.SerialNumberIndex();
+ PopulateStringDescriptorsL(manufacturerStringDescriptorIndex, iManufacturerStrings);
+ PopulateStringDescriptorsL(productStringDescriptorIndex, iProductStrings);
+ PopulateStringDescriptorsL(serialNumberStringDescriptorIndex, iSerialNumberStrings);
+ ASSERT_DEBUG(iManufacturerStrings.Count() == iLangIds.Count());
+ ASSERT_DEBUG(iProductStrings.Count() == iLangIds.Count());
+ ASSERT_DEBUG(iSerialNumberStrings.Count() == iLangIds.Count());
+ }
+
+// Populates the given array with the supported language variants of the given
+// string. Can only leave with KErrNoMemory, which fails instantiation of the
+// CDeviceProxy. (It is legal for instance for manufacturer strings to be
+// supported but serial number strings to *not* be.)
+void CDeviceProxy::PopulateStringDescriptorsL(TUint8 aStringDescriptorIndex, RArray<TName>& aStringArray)
+ {
+ LOG_FUNC
+
+ const TUint langCount = iLangIds.Count();
+ for ( TUint ii = 0 ; ii < langCount ; ++ii )
+ {
+ TName string;
+ TRAPD(err, GetStringDescriptorFromUsbdL(iLangIds[ii], string, aStringDescriptorIndex));
+ if ( err == KErrNotFound)
+ {
+ // Make sure the string is blanked before storing it.
+ string = KNullDesC();
+ }
+ else
+ {
+ LEAVEIFERRORL(err);
+ }
+
+ LEAVEIFERRORL(aStringArray.Append(string));
+ }
+ }
+
+CDeviceProxy::~CDeviceProxy()
+ {
+ LOG_FUNC
+ LOG;
+
+ // In the design, the event objects should all have had ownership taken
+ // onto the event queue by now. The owner of the device proxy is required
+ // to take ownership of these objects before destroying the proxy.
+ // However, we might hit the destructor due to an out-of-memory failure
+ // during construction, so we can't assert this, and we still have to
+ // destroy the objects.
+ delete iAttachmentEvent;
+ delete iDriverLoadingEvent;
+ delete iDetachmentEvent;
+ delete iOtgDescriptor;
+
+ iLangIds.Reset();
+ iManufacturerStrings.Reset();
+ iProductStrings.Reset();
+ iSerialNumberStrings.Reset();
+
+ iHandle.Close();
+ }
+
+TInt CDeviceProxy::GetDeviceDescriptor(TUsbDeviceDescriptor& aDescriptor)
+ {
+ LOG_FUNC
+
+ ASSERT_DEBUG(iHandle.Handle());
+ TInt err = iHandle.GetDeviceDescriptor(aDescriptor);
+
+ LOGTEXT2(_L8("\terr = %d"), err);
+ return err;
+ }
+
+TInt CDeviceProxy::GetConfigurationDescriptor(TUsbConfigurationDescriptor& aDescriptor) const
+ {
+ LOG_FUNC
+
+ ASSERT_DEBUG(iHandle.Handle());
+ TInt err = const_cast<RUsbDevice&>(iHandle).GetConfigurationDescriptor(aDescriptor);
+
+ LOGTEXT2(_L8("\terr = %d"), err);
+ return err;
+ }
+
+TInt CDeviceProxy::GetTokenForInterface(TUint aIndex, TUint32& aToken) const
+ {
+ LOG_FUNC
+
+ ASSERT_DEBUG(iHandle.Handle());
+ // We shouldn't need to worry about whether the device is suspended or
+ // resumed before doing this. This function is only called if we find FDs
+ // for the device, in which case we wouldn't have suspended it in the
+ // first place.
+ TInt err = const_cast<RUsbDevice&>(iHandle).GetTokenForInterface(aIndex, aToken);
+
+ LOGTEXT2(_L8("\terr = %d"), err);
+ return err;
+ }
+
+const RArray<TUint>& CDeviceProxy::GetSupportedLanguages() const
+ {
+ LOG_FUNC
+
+ return iLangIds;
+ }
+
+void CDeviceProxy::GetManufacturerStringDescriptorL(TUint32 aLangId, TName& aString) const
+ {
+ LOG_FUNC
+
+ GetStringDescriptorFromCacheL(aLangId, aString, iManufacturerStrings);
+ }
+
+void CDeviceProxy::GetProductStringDescriptorL(TUint32 aLangId, TName& aString) const
+ {
+ LOG_FUNC
+
+ GetStringDescriptorFromCacheL(aLangId, aString, iProductStrings);
+ }
+
+void CDeviceProxy::GetSerialNumberStringDescriptorL(TUint32 aLangId, TName& aString) const
+ {
+ LOG_FUNC
+
+ GetStringDescriptorFromCacheL(aLangId, aString, iSerialNumberStrings);
+ }
+
+void CDeviceProxy::GetOtgDescriptorL(TOtgDescriptor& aDescriptor) const
+ {
+ LOG_FUNC
+
+ if (iOtgDescriptor)
+ {
+ aDescriptor = *iOtgDescriptor;
+ }
+ else
+ {
+ LEAVEL(KErrNotSupported);
+ }
+ }
+
+void CDeviceProxy::SetOtgDescriptorL(const TUsbOTGDescriptor& aDescriptor)
+ {
+ if (iOtgDescriptor)
+ {
+ delete iOtgDescriptor;
+ iOtgDescriptor = NULL;
+ }
+ iOtgDescriptor = new (ELeave) TOtgDescriptor();
+
+ iOtgDescriptor->iDeviceId = iId;
+ iOtgDescriptor->iAttributes = aDescriptor.Attributes();
+ }
+
+// Used during instantiation to read supported strings.
+void CDeviceProxy::GetStringDescriptorFromUsbdL(TUint32 aLangId, TName& aString, TUint8 aStringDescriptorIndex) const
+ {
+ LOG_FUNC
+ LOGTEXT3(_L8("\taLangId = 0x%04x, aStringDescriptorIndex = %d"), aLangId, aStringDescriptorIndex);
+
+ // If the string is not defined by the device, leave.
+ if ( aStringDescriptorIndex == 0 )
+ {
+ LEAVEL(KErrNotFound);
+ }
+
+ TBuf8<255> stringBuf;
+ TUsbStringDescriptor* stringDesc = NULL;
+ ASSERT_DEBUG(iHandle.Handle());
+ LEAVEIFERRORL(const_cast<RUsbDevice&>(iHandle).GetStringDescriptor(stringDesc, stringBuf, aStringDescriptorIndex, aLangId));
+ stringDesc->StringData(aString);
+ stringDesc->DestroyTree();
+ delete stringDesc;
+ LOGTEXT2(_L("\taString = \"%S\""), &aString);
+ }
+
+// Called indirectly by users of this class to query a string descriptor.
+void CDeviceProxy::GetStringDescriptorFromCacheL(TUint32 aLangId, TName& aString, const RArray<TName>& aStringArray) const
+ {
+ LOG_FUNC
+ LOGTEXT2(_L8("\taLangId = 0x%04x"), aLangId);
+
+ // If the lang ID is not supported by the device, leave. At the same time
+ // find the index of the required string in the given string array.
+ const TUint langCount = iLangIds.Count();
+ TUint index = 0;
+ for ( index = 0 ; index < langCount ; ++index )
+ {
+ if ( iLangIds[index] == aLangId )
+ {
+ break;
+ }
+ }
+ if ( index == langCount )
+ {
+ LEAVEL(KErrNotFound);
+ }
+
+ aString = aStringArray[index];
+ LOGTEXT2(_L("\taString = \"%S\""), &aString);
+ }
+
+TInt CDeviceProxy::Suspend()
+ {
+ LOG_FUNC
+
+ ASSERT_DEBUG(iHandle.Handle());
+ TInt ret = iHandle.Suspend();
+
+ LOGTEXT2(_L8("\tret = %d"), ret);
+ return ret;
+ }
+
+TUint CDeviceProxy::DeviceId() const
+ {
+ return iId;
+ }
+
+void CDeviceProxy::SetDriverLoadingEventData(TDriverLoadStatus aStatus, TInt aError)
+ {
+ LOG_FUNC
+ LOGTEXT3(_L8("\taStatus = %d, aError = %d"), aStatus, aError);
+
+ ASSERT_DEBUG(iDriverLoadingEvent);
+ iDriverLoadingEvent->iInfo.iDriverLoadStatus = aStatus;
+ iDriverLoadingEvent->iInfo.iError = aError;
+
+ LOG;
+ }
+
+TDeviceEvent* CDeviceProxy::GetAttachmentEventObject()
+ {
+ LOG_FUNC
+ LOG;
+
+ ASSERT_DEBUG(iAttachmentEvent);
+ TDeviceEvent* const obj = iAttachmentEvent;
+ iAttachmentEvent = NULL;
+ LOGTEXT2(_L8("\tobj = 0x%08x"), obj);
+ return obj;
+ }
+
+TDeviceEvent* CDeviceProxy::GetDriverLoadingEventObject()
+ {
+ LOG_FUNC
+ LOG;
+
+ ASSERT_DEBUG(iDriverLoadingEvent);
+ TDeviceEvent* const obj = iDriverLoadingEvent;
+ iDriverLoadingEvent = NULL;
+ LOGTEXT2(_L8("\tobj = 0x%08x"), obj);
+ return obj;
+ }
+
+TDeviceEvent* CDeviceProxy::GetDetachmentEventObject()
+ {
+ LOG_FUNC
+ LOG;
+
+ ASSERT_DEBUG(iDetachmentEvent);
+ TDeviceEvent* const obj = iDetachmentEvent;
+ iDetachmentEvent = NULL;
+ LOGTEXT2(_L8("\tobj = 0x%08x"), obj);
+ return obj;
+ }
+
+#ifdef __FLOG_ACTIVE
+
+void CDeviceProxy::Log()
+ {
+ LOG_FUNC
+
+ LOGTEXT2(_L8("\tiId = %d"), iId);
+ LOGTEXT2(_L8("\tiHandle.Handle() = %d"), iHandle.Handle());
+ if ( iAttachmentEvent )
+ {
+ LOGTEXT(_L8("\tlogging iAttachmentEvent"));
+ iAttachmentEvent->Log();
+ }
+ if ( iDriverLoadingEvent )
+ {
+ LOGTEXT(_L8("\tlogging iDriverLoadingEvent"));
+ iDriverLoadingEvent->Log();
+ }
+ if ( iDetachmentEvent )
+ {
+ LOGTEXT(_L8("\tlogging iDetachmentEvent"));
+ iDetachmentEvent->Log();
+ }
+ const TUint langCount = iLangIds.Count();
+ const TUint manufacturerCount = iManufacturerStrings.Count();
+ const TUint productCount = iProductStrings.Count();
+ const TUint serialNumberCount = iSerialNumberStrings.Count();
+
+ // from the code below we can see that some protection have been added
+ // if(ii<manufacturerCount) etc...
+ // This has been done to protect in case there have been an incomplete construction etc..
+ // when logging the data
+
+ LOGTEXT2(_L8("\tlangCount = %d"), langCount);
+ for ( TUint ii = 0 ; ii < langCount ; ++ii )
+ {
+ LOGTEXT2(_L("\tlang ID 0x%04x:"), iLangIds[ii]);
+ if(ii<manufacturerCount)
+ {
+ LOGTEXT2(_L("\t\tmanufacturer string: \"%S\""), &iManufacturerStrings[ii]);
+ }
+ if(ii<productCount)
+ {
+ LOGTEXT2(_L("\t\tproduct string: \"%S\""), &iProductStrings[ii]);
+ }
+ if(ii<serialNumberCount)
+ {
+ LOGTEXT2(_L("\t\tserial number string: \"%S\""), &iSerialNumberStrings[ii]);
+ }
+
+ }
+ }
+
+#endif