usbmgmt/usbmgr/device/classdrivers/whcm/classcontroller/SRC/CUsbWHCMClassController.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
equal deleted inserted replaced
-1:000000000000 0:c9bc50fca66e
       
     1 /*
       
     2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 * Implements part of UsbMan USB Class Framework.
       
    16 *
       
    17 */
       
    18 
       
    19 /**
       
    20  @file
       
    21 */
       
    22 
       
    23 #include "CUsbWHCMClassController.h"
       
    24 #include <usb_std.h>
       
    25 #include <cusbclasscontrolleriterator.h>
       
    26 #include <musbclasscontrollernotify.h>
       
    27 #include <usb/usblogger.h>
       
    28 
       
    29 #ifdef __FLOG_ACTIVE
       
    30 _LIT8(KLogComponent, "WHCMCC");
       
    31 #endif
       
    32 
       
    33 _LIT(KUsbLDDName, "eusbc");
       
    34 
       
    35 _LIT( KWhcmCcPanicCategory, "UsbWhcmCc" );
       
    36 
       
    37 /**
       
    38  * Panic codes for the USB WHCM Class Controller.
       
    39  */
       
    40 enum TWhcmCcPanic
       
    41 	{
       
    42 	/** Start() called while in an illegal state */
       
    43 	EBadApiCallStart = 0,
       
    44 	/** Asynchronous function called (not needed, as all requests complete synchronously) */
       
    45 	EUnusedFunction = 1,
       
    46 	/** Stop() called while in an illegal state */
       
    47 	EBadApiCallStop = 2
       
    48 	};
       
    49 
       
    50 /**
       
    51  * Constructs a CUsbWHCMClassController object.
       
    52  *
       
    53  * @param aOwner USB Device that owns and manages the class
       
    54  * @return A new CUsbWHCMClassController object
       
    55  */
       
    56 CUsbWHCMClassController* CUsbWHCMClassController::NewL(
       
    57 	MUsbClassControllerNotify& aOwner)
       
    58 	{
       
    59 	LOG_STATIC_FUNC_ENTRY
       
    60 
       
    61 	CUsbWHCMClassController* self =
       
    62 		new (ELeave) CUsbWHCMClassController(aOwner);
       
    63 
       
    64 	CleanupStack::PushL(self);
       
    65 	self->ConstructL();
       
    66 	CleanupStack::Pop();
       
    67 	return self;
       
    68 	}
       
    69 
       
    70 /**
       
    71  * Constructor.
       
    72  *
       
    73  * @param aOwner USB Device that owns and manages the class
       
    74  */
       
    75 CUsbWHCMClassController::CUsbWHCMClassController(
       
    76 		MUsbClassControllerNotify& aOwner)
       
    77 	: CUsbClassControllerPlugIn(aOwner, KWHCMPriority)
       
    78 	{
       
    79 	iState = EUsbServiceIdle;
       
    80 	}
       
    81 
       
    82 /**
       
    83  * Method to perform second phase construction.
       
    84  */
       
    85 void CUsbWHCMClassController::ConstructL()
       
    86 	{
       
    87 	// Load the device driver
       
    88 	TInt err = User::LoadLogicalDevice(KUsbLDDName);
       
    89 	if (err != KErrNone && err != KErrAlreadyExists) 
       
    90 		{
       
    91 		LEAVEL(err);      
       
    92 		} 
       
    93 
       
    94 	LEAVEIFERRORL(iLdd.Open(0));
       
    95 	}
       
    96 
       
    97 /**
       
    98  * Destructor.
       
    99  */
       
   100 CUsbWHCMClassController::~CUsbWHCMClassController()
       
   101 	{
       
   102 	Cancel();
       
   103 
       
   104 	if (iState == EUsbServiceStarted)
       
   105 		{
       
   106 		// Must release all interfaces before closing the LDD to avoid a crash.
       
   107 		iLdd.ReleaseInterface(0);
       
   108 		}
       
   109 	iLdd.Close();
       
   110 	}
       
   111 
       
   112 /**
       
   113  * Called by UsbMan to start this class.
       
   114  *
       
   115  * @param aStatus Will be completed with success or failure.
       
   116  */
       
   117 void CUsbWHCMClassController::Start(TRequestStatus& aStatus)
       
   118 	{
       
   119 	LOG_FUNC
       
   120 		
       
   121 	//Start() should never be called if started, starting or stopping (or in state EUsbServiceFatalError)
       
   122 	__ASSERT_DEBUG( iState == EUsbServiceIdle, _USB_PANIC(KWhcmCcPanicCategory, EBadApiCallStart) );
       
   123 	
       
   124 	TRequestStatus* reportStatus = &aStatus;
       
   125 
       
   126 	iState = EUsbServiceStarting;
       
   127 
       
   128 	TRAPD(err, SetUpWHCMDescriptorL());
       
   129 
       
   130 	if (err != KErrNone) 
       
   131 		{
       
   132 		iState = EUsbServiceIdle;
       
   133 		User::RequestComplete(reportStatus, err);
       
   134 		return;
       
   135 		}
       
   136 	iState = EUsbServiceStarted;
       
   137 	User::RequestComplete(reportStatus, KErrNone);
       
   138 	}
       
   139 
       
   140 /**
       
   141  * Called by UsbMan to stop this class.
       
   142  *
       
   143  * @param aStatus Will be completed with success or failure.
       
   144  */
       
   145 void CUsbWHCMClassController::Stop(TRequestStatus& aStatus)
       
   146 	{
       
   147 	LOG_FUNC
       
   148 
       
   149 	//Stop() should never be called if stopping, idle or starting (or in state EUsbServiceFatalError)
       
   150 	__ASSERT_DEBUG( iState == EUsbServiceStarted, _USB_PANIC(KWhcmCcPanicCategory, EBadApiCallStop) );
       
   151 
       
   152 	TRequestStatus* reportStatus = &aStatus;
       
   153 
       
   154 	// Must release all interfaces before closing the LDD to avoid a crash.
       
   155 	iLdd.ReleaseInterface(0);
       
   156 
       
   157 	iState = EUsbServiceIdle;
       
   158 
       
   159 	aStatus = KRequestPending;
       
   160 
       
   161 	User::RequestComplete(reportStatus, KErrNone);
       
   162 	}
       
   163 
       
   164 /**
       
   165  * Returns information about the interfaces supported by this class.
       
   166  *
       
   167  * @param aDescriptorInfo Will be filled in with interface information.
       
   168  */
       
   169 void CUsbWHCMClassController::GetDescriptorInfo(
       
   170 	TUsbDescriptor& /*aDescriptorInfo*/) const
       
   171 	{
       
   172 	}
       
   173 
       
   174 /**
       
   175  * Standard active object RunL.
       
   176  */
       
   177 void CUsbWHCMClassController::RunL()
       
   178 	{
       
   179 	// This function should never be called.
       
   180 	_USB_PANIC(KWhcmCcPanicCategory, EUnusedFunction);
       
   181 	}
       
   182 
       
   183 /**
       
   184  * Standard active object cancellation function. Will only be called when an
       
   185  * asynchronous request is currently active.
       
   186  */
       
   187 void CUsbWHCMClassController::DoCancel()
       
   188 	{
       
   189 	// This function should never be called.
       
   190 	_USB_PANIC(KWhcmCcPanicCategory, EUnusedFunction);
       
   191 	}
       
   192 
       
   193 /**
       
   194  * Standard active object error-handling function. Should return KErrNone to
       
   195  * avoid an active scheduler panic.
       
   196  */
       
   197 TInt CUsbWHCMClassController::RunError(TInt /*aError*/)
       
   198 	{
       
   199 	// This function should never be called.
       
   200 	_USB_PANIC(KWhcmCcPanicCategory, EUnusedFunction);
       
   201 
       
   202 	return KErrNone;
       
   203 	}
       
   204 
       
   205 
       
   206 void CUsbWHCMClassController::SetUpWHCMDescriptorL()
       
   207 /**
       
   208  * Setup the WHCM Class Descriptors.
       
   209  */
       
   210     {
       
   211 	// Set up and register the WHCM interface descriptor
       
   212 
       
   213     TUsbcInterfaceInfoBuf ifc;
       
   214 	ifc().iString = NULL;
       
   215 	ifc().iClass.iClassNum = 0x02;
       
   216 	ifc().iClass.iSubClassNum =  KWHCMSubClass;
       
   217 	ifc().iClass.iProtocolNum = KWHCMProtocol;
       
   218 	ifc().iTotalEndpointsUsed = 0;
       
   219 
       
   220 	// Indicate that this interface does not expect any control transfers 
       
   221 	// from EP0.
       
   222 	ifc().iFeatureWord |= KUsbcInterfaceInfo_NoEp0RequestsPlease;
       
   223 
       
   224 	LEAVEIFERRORL(iLdd.SetInterface(0, ifc));
       
   225 
       
   226 	// Get the interface number from the LDD for later reference
       
   227 	TBuf8<100> interface_descriptor;
       
   228 	LEAVEIFERRORL(iLdd.GetInterfaceDescriptor(0, interface_descriptor));
       
   229 	
       
   230 		
       
   231 	TUint8 WHCM_int_no = interface_descriptor[2];
       
   232 
       
   233 	// Set up the class-specific interface block.
       
   234 	// This consists of:
       
   235 	//		Comms Class Header Functional Desctriptor
       
   236 	//		WHCM Functional Descriptor
       
   237 	//		Union Functional Descriptor
       
   238 	// Most of the data is copied from the static const structure in the header file.
       
   239 
       
   240 	TBuf8<200> desc;
       
   241 	desc.Copy(WHCMheader, sizeof(WHCMheader));
       
   242 
       
   243 	// Append the interface number to the Union Functional Descriptor
       
   244 	desc.Append( WHCM_int_no );
       
   245 
       
   246     // In order to finish off the Union Functional Descriptor we need to fill
       
   247 	// out the Subordinate Class list.
       
   248 	// We can do this by iterating through the remaining class controllers in the
       
   249 	// owner's list to find all the the subordinate classes.
       
   250 
       
   251 	// Two assumptions are made here:
       
   252 	//		1) That all the remaining controller in the list (after this one)
       
   253 	//		   are subordinate classes of this WHCM class.
       
   254 	//		2) That their interface numbers will be assigned contiguously.
       
   255 
       
   256 	TInt if_number = WHCM_int_no + 1;	// for counting interface numbers
       
   257 	TUint8 union_len = 4;				// for holding the length of the union descriptor
       
   258 
       
   259 	// Iterate through the class controllers
       
   260 	CUsbClassControllerIterator *iterator = Owner().UccnGetClassControllerIteratorL();
       
   261 
       
   262 	iterator->Seek(this);
       
   263 
       
   264 	while(    (iterator->Next() != KErrNotFound)
       
   265 			&& (iterator->Current()->StartupPriority() >= StartupPriority()) )
       
   266 		{
       
   267 		// Found another class in the union. Add it to our list.
       
   268 		TUsbDescriptor desc_info;
       
   269 		iterator->Current()->GetDescriptorInfo(desc_info);
       
   270 		for (TInt i=0; i<desc_info.iNumInterfaces; i++)
       
   271 			{
       
   272 			desc.Append(if_number++);
       
   273 			union_len++;
       
   274 			}
       
   275 		}
       
   276     delete iterator;
       
   277 	// We have added to the Union Functional Descriptor.
       
   278 	// So we need to insert the new length into it.
       
   279 	desc[10] = union_len;
       
   280 
       
   281 	// Register the whole class-specific interface block
       
   282     LEAVEIFERRORL(iLdd.SetCSInterfaceDescriptorBlock(0, desc));	
       
   283 	}