usbmgmt/usbmgr/device/classdrivers/ms/classcontroller/src/CUsbMsClassController.cpp
changeset 0 c9bc50fca66e
child 15 f92a4f87e424
equal deleted inserted replaced
-1:000000000000 0:c9bc50fca66e
       
     1 /*
       
     2 * Copyright (c) 2004-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 * Adheres to the UsbMan USB Class Controller API and talks to mass storage 
       
    16 * file server
       
    17 *
       
    18 */
       
    19 
       
    20 /**
       
    21  @file
       
    22  @internalTechnology
       
    23 */
       
    24 
       
    25 #include <barsc.h> 
       
    26 #include <barsread.h>
       
    27 #include <usb_std.h>
       
    28 #include <cusbclasscontrollerplugin.h>
       
    29 #include <usbms.rsg>
       
    30 #include "CUsbMsClassController.h"
       
    31 #include <usb/usblogger.h>
       
    32  
       
    33 #ifdef __FLOG_ACTIVE
       
    34 _LIT8(KLogComponent, "MSCC");
       
    35 #endif
       
    36 
       
    37 // Panic category 
       
    38 #ifdef _DEBUG
       
    39 _LIT( KMsCcPanicCategory, "UsbMsCc" );
       
    40 #endif
       
    41 
       
    42 /**
       
    43  Panic codes for the USB mass storage Class Controller.
       
    44  */
       
    45 enum TMsCcPanic
       
    46 	{
       
    47 	//Class called while in an illegal state
       
    48 	EBadApiCall = 0,
       
    49     EUnusedFunction = 1,
       
    50 	};
       
    51 
       
    52 /**
       
    53  Constructs a CUsbMsClassController object
       
    54  
       
    55  @param	aOwner	USB Device that owns and manages the class
       
    56  @return	A new CUsbMsClassController object
       
    57  */
       
    58 CUsbMsClassController* CUsbMsClassController::NewL(
       
    59 	MUsbClassControllerNotify& aOwner)
       
    60 	{
       
    61 	LOG_STATIC_FUNC_ENTRY
       
    62 
       
    63 	CUsbMsClassController* r = new (ELeave) CUsbMsClassController(aOwner);
       
    64 	CleanupStack::PushL(r);
       
    65 	r->ConstructL();
       
    66 	CleanupStack::Pop();
       
    67 	return r;
       
    68 	}
       
    69 
       
    70 /**
       
    71  Destructor
       
    72  */
       
    73 CUsbMsClassController::~CUsbMsClassController()
       
    74 	{
       
    75 	Cancel();
       
    76 	}
       
    77 
       
    78 /**
       
    79  Constructor.
       
    80  
       
    81  @param	aOwner	USB Device that owns and manages the class
       
    82  */
       
    83 CUsbMsClassController::CUsbMsClassController(
       
    84 	MUsbClassControllerNotify& aOwner)
       
    85 	: CUsbClassControllerPlugIn(aOwner, KMsStartupPriority)	
       
    86 	{
       
    87 	// Intentionally left blank
       
    88 	}
       
    89 
       
    90 /**
       
    91  2nd Phase Construction.
       
    92  */
       
    93 void CUsbMsClassController::ConstructL()
       
    94 	{
       
    95 	LOG_FUNC
       
    96 
       
    97 	ReadMassStorageConfigL();
       
    98 	}
       
    99 
       
   100 /**
       
   101  Called by UsbMan when it wants to start the mass storage class. 
       
   102  
       
   103  @param aStatus The caller's request status, filled in with an error code
       
   104  */
       
   105 void CUsbMsClassController::Start(TRequestStatus& aStatus)
       
   106 	{
       
   107 	LOG_FUNC
       
   108 	
       
   109 	// The service state should always be idle when this function is called 
       
   110 	// (guaranteed by CUsbSession).
       
   111 	__ASSERT_DEBUG( iState == EUsbServiceIdle, _USB_PANIC(KMsCcPanicCategory, EBadApiCall) );
       
   112 
       
   113 	TRequestStatus* reportStatus = &aStatus;
       
   114 
       
   115 	iState = EUsbServiceStarting;
       
   116 
       
   117 	// Connect to USB Mass Storage server
       
   118 	TInt err = iUsbMs.Connect();
       
   119 
       
   120 	if (err != KErrNone)
       
   121 		{
       
   122 		iState = EUsbServiceIdle;
       
   123 		User::RequestComplete(reportStatus, err);
       
   124 		LOGTEXT(_L8("Failed to connect to mass storage file server"));
       
   125 		return;
       
   126 		}
       
   127 
       
   128 	// Start mass storage device
       
   129 	err = iUsbMs.Start(iMsConfig);
       
   130 
       
   131 	if (err != KErrNone)
       
   132 		{
       
   133 		iState = EUsbServiceIdle;
       
   134 		
       
   135 		// Connection was created successfully in last step
       
   136 		// Get it closed since failed to start device.
       
   137 		iUsbMs.Close();
       
   138 		
       
   139 		User::RequestComplete(reportStatus, err);
       
   140 		LOGTEXT(_L8("Failed to start mass storage device"));
       
   141 		return;
       
   142 		}
       
   143 
       
   144 	iState = EUsbServiceStarted;
       
   145 
       
   146 	User::RequestComplete(reportStatus, KErrNone);
       
   147 	}
       
   148 
       
   149 /**
       
   150  Called by UsbMan when it wants to stop the USB ACM class.
       
   151  
       
   152  @param aStatus KErrNone on success or a system wide error code
       
   153  */
       
   154 void CUsbMsClassController::Stop(TRequestStatus& aStatus)
       
   155 	{
       
   156 	LOG_FUNC
       
   157 	
       
   158 	// The service state should always be started when this function is called
       
   159 	// (guaranteed by CUsbSession)
       
   160 	__ASSERT_DEBUG( iState == EUsbServiceStarted, _USB_PANIC(KMsCcPanicCategory, EBadApiCall) );
       
   161 
       
   162 	TRequestStatus* reportStatus = &aStatus;
       
   163 	
       
   164 	TInt err = iUsbMs.Stop();
       
   165 	
       
   166 	if (err != KErrNone)
       
   167 		{
       
   168 		iState = EUsbServiceStarted;
       
   169 		User::RequestComplete(reportStatus, err);
       
   170 		LOGTEXT(_L8("Failed to stop mass storage device"));
       
   171 		return;
       
   172 		}	
       
   173 
       
   174 	iUsbMs.Close();
       
   175 
       
   176 	User::RequestComplete(reportStatus, KErrNone);
       
   177 	}
       
   178 
       
   179 /**
       
   180  Gets information about the descriptor which this class provides. Never called
       
   181  by usbMan.
       
   182  
       
   183  @param aDescriptorInfo Descriptor info structure filled in by this function
       
   184  */
       
   185 void CUsbMsClassController::GetDescriptorInfo(TUsbDescriptor& /*aDescriptorInfo*/) const
       
   186 	{
       
   187 	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction));
       
   188 	}
       
   189 
       
   190 /**
       
   191  Standard active object RunL. Never called because this class has no
       
   192  asynchronous requests.
       
   193  */
       
   194 void CUsbMsClassController::RunL()
       
   195 	{
       
   196 	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction) );
       
   197 	}
       
   198 
       
   199 /**
       
   200  Standard active object cancellation function. Never called because this
       
   201  class has no asynchronous requests.
       
   202  */
       
   203 void CUsbMsClassController::DoCancel()
       
   204 	{
       
   205 	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction) );
       
   206 	}
       
   207 
       
   208 /**
       
   209  Standard active object error function. Never called because this class has
       
   210  no asynchronous requests, and hence its RunL is never called.
       
   211  
       
   212  @param aError The error code (unused)
       
   213  @return Always KErrNone to avoid an active scheduler panic
       
   214  */
       
   215 TInt CUsbMsClassController::RunError(TInt /*aError*/)
       
   216 	{
       
   217 	__ASSERT_DEBUG( EFalse, _USB_PANIC(KMsCcPanicCategory, EUnusedFunction) );
       
   218 	return KErrNone;
       
   219 	}
       
   220 
       
   221 /**
       
   222  Read mass storage configuration info from the resource file
       
   223  */
       
   224 void CUsbMsClassController::ReadMassStorageConfigL()
       
   225 	{
       
   226 	LOG_FUNC
       
   227 
       
   228 	// Try to connect to file server
       
   229 	RFs fs;
       
   230 	LEAVEIFERRORL(fs.Connect());
       
   231 	CleanupClosePushL(fs);
       
   232 
       
   233 	RResourceFile resource;
       
   234 	TRAPD(err, resource.OpenL(fs, KUsbMsResource));
       
   235 	LOGTEXT2(_L8("Opened resource file with error %d"), err);
       
   236 
       
   237 	if (err != KErrNone)
       
   238 		{
       
   239 		LOGTEXT(_L8("Unable to open resource file"));
       
   240 		CleanupStack::PopAndDestroy(&fs);
       
   241 		return;
       
   242 		}
       
   243 
       
   244 	CleanupClosePushL(resource);
       
   245 
       
   246 	resource.ConfirmSignatureL(KUsbMsResourceVersion);
       
   247 
       
   248 	HBufC8* msConfigBuf = 0;
       
   249 	TRAPD(ret, msConfigBuf = resource.AllocReadL(USBMS_CONFIG));
       
   250 	if (ret != KErrNone)
       
   251 		{
       
   252 		LOGTEXT(_L8("Failed to open mass storage configuration file"));
       
   253 		CleanupStack::PopAndDestroy(2, &fs); 
       
   254 		return;
       
   255 		}
       
   256 	CleanupStack::PushL(msConfigBuf);
       
   257 	
       
   258 
       
   259 	// The format of the USB resource structure is:
       
   260 	
       
   261 	/* 	
       
   262 	 * 	STRUCT USBMASSSTORAGE_CONFIG
       
   263 	 *	{
       
   264 	 *	LTEXT	vendorId;           // no more than 8 characters
       
   265 	 *	LTEXT	productId;          // no more than 16 characters
       
   266 	 *	LTEXT	productRev;        	// no more than 4 characters
       
   267 	 *	};
       
   268 	 */
       
   269 	 
       
   270 	// Note that the resource must be read in this order!
       
   271 	
       
   272 	TResourceReader reader;
       
   273 	reader.SetBuffer(msConfigBuf);
       
   274 
       
   275 	TPtrC	vendorId		= reader.ReadTPtrC();
       
   276 	TPtrC	productId		= reader.ReadTPtrC();
       
   277 	TPtrC	productRev		= reader.ReadTPtrC();
       
   278 	
       
   279 	// populate iMsConfig, truncate if exceeding limit
       
   280 	ConfigItem(vendorId, iMsConfig.iVendorId, 8);
       
   281 	ConfigItem(productId, iMsConfig.iProductId, 16);
       
   282 	ConfigItem(productRev, iMsConfig.iProductRev, 4);
       
   283 	
       
   284 	// Debugging
       
   285 	LOGTEXT2(_L8("vendorId = %S\n"), 	&vendorId);
       
   286 	LOGTEXT2(_L8("productId = %S\n"), 	&productId);
       
   287 	LOGTEXT2(_L8("productRev = %S\n"), 	&productRev);
       
   288 		
       
   289 	CleanupStack::PopAndDestroy(3, &fs); // msConfigBuf, resource, fs		
       
   290 	}
       
   291 	
       
   292 /**
       
   293  Utility. Copies the data from TPtr to TBuf and checks data length 
       
   294  to make sure the source does not exceed the capacity of the target
       
   295  */
       
   296  void CUsbMsClassController::ConfigItem(const TPtrC& source, TDes& target, TInt maxLength)
       
   297  	{
       
   298  	if (source.Length() < maxLength)
       
   299  		{
       
   300  		maxLength = source.Length();
       
   301  		}
       
   302  		
       
   303  	target.Copy(source.Ptr(), maxLength);	 	
       
   304  	}
       
   305