usbmgmt/usbmgr/device/classdrivers/acm/classcontroller/SRC/CUsbACMClassController.cpp
branchRCL_3
changeset 6 96e575696901
parent 0 c9bc50fca66e
child 15 f92a4f87e424
equal deleted inserted replaced
5:c2db6e29750c 6:96e575696901
    24 
    24 
    25 #include "CUsbACMClassController.h"
    25 #include "CUsbACMClassController.h"
    26 #include <usb_std.h>
    26 #include <usb_std.h>
    27 #include <acminterface.h>
    27 #include <acminterface.h>
    28 #include <usb/acmserver.h>		
    28 #include <usb/acmserver.h>		
    29 #include "inifile.h"
       
    30 #include "UsbmanInternalConstants.h"
    29 #include "UsbmanInternalConstants.h"
    31 #include <usb/usblogger.h>
    30 #include <usb/usblogger.h>
    32 #include "acmserverconsts.h"
    31 #include "acmserverconsts.h"
    33 
    32 
    34 #ifdef __FLOG_ACTIVE
    33 #ifdef __FLOG_ACTIVE
    35 _LIT8(KLogComponent, "ACMCC");
    34 _LIT8(KLogComponent, "ACMCC");
    36 #endif
       
    37 
       
    38 
    35 
    39 // Panic category 
    36 // Panic category 
    40 _LIT( KAcmCcPanicCategory, "UsbAcmCc" );
    37 _LIT( KAcmCcPanicCategory, "UsbAcmCc" );
       
    38 
       
    39 #endif
       
    40 
    41 
    41 
    42 
    42 
    43 /**
    43 /**
    44  * Panic codes for the USB ACM Class Controller.
    44  * Panic codes for the USB ACM Class Controller.
    45  */
    45  */
    47 	{
    47 	{
    48 	/** Start called while in an illegal state */
    48 	/** Start called while in an illegal state */
    49 	EBadApiCallStart = 0,
    49 	EBadApiCallStart = 0,
    50 	/** Asynchronous function called (not needed, as all requests complete synchronously) */
    50 	/** Asynchronous function called (not needed, as all requests complete synchronously) */
    51 	EUnusedFunction = 1,
    51 	EUnusedFunction = 1,
    52 	/** Error reading ini file. */
    52 	/** Value reserved */
    53 	EPanicBadIniFile = 2,		
    53 	EPanicReserved2 = 2,		
    54 	/** Bad value for the iNumberOfAcmFunctions member.*/
    54 	/** Value reserved */
    55 	EPanicBadNumberOfAcmFunctions = 3,
    55 	EPanicReserved3 = 3,
    56 	/** Stop called while in an illegal state */
    56 	/** Stop called while in an illegal state */
    57 	EBadApiCallStop = 4,
    57 	EBadApiCallStop = 4,
    58 	};
    58 	};
    59 
    59 
    60 
    60 
    85 
    85 
    86 #ifdef USE_ACM_REGISTRATION_PORT
    86 #ifdef USE_ACM_REGISTRATION_PORT
    87 	iComm.Close();
    87 	iComm.Close();
    88 	iCommServer.Close();
    88 	iCommServer.Close();
    89 #else
    89 #else
    90 	// Clean up any interface name strings
    90     iAcmServer.Close();
    91 	for ( TUint i = 0 ; i < KMaximumAcmFunctions ; i++ )
       
    92 		{
       
    93 		iAcmControlIfcName[i].Close();
       
    94 		iAcmDataIfcName[i].Close();
       
    95 		}
       
    96 	iAcmServer.Close();
       
    97 #endif // USE_ACM_REGISTRATION_PORT
    91 #endif // USE_ACM_REGISTRATION_PORT
    98 	}
    92 	}
    99 
    93 
   100 /**
    94 /**
   101  * Constructor.
    95  * Constructor.
   102  *
    96  *
   103  * @param	aOwner	USB Device that owns and manages the class
    97  * @param	aOwner	USB Device that owns and manages the class
   104  */
    98  */
   105 CUsbACMClassController::CUsbACMClassController(
    99 CUsbACMClassController::CUsbACMClassController(
   106 	MUsbClassControllerNotify& aOwner)
   100     MUsbClassControllerNotify& aOwner) 
   107 	: CUsbClassControllerPlugIn(aOwner, KAcmStartupPriority),	
   101     : CUsbClassControllerPlugIn(aOwner, KAcmStartupPriority),
   108 	iNumberOfAcmFunctions(KDefaultNumberOfAcmFunctions)
   102     iNumberOfAcmFunctions(KDefaultNumberOfAcmFunctions)
   109 	{
   103     {
   110 	// Initialise all elements to KDefaultAcmProtocolNum.
   104     }
   111 	for ( TUint ii = 0 ; ii < KMaximumAcmFunctions ; ii++ )
       
   112 		{
       
   113 		iAcmProtocolNum[ii] = KDefaultAcmProtocolNum;
       
   114 		// iAcmControlIfcName[ii] and iAcmDataIfcName[ii] are already set to empty strings (RBuf);
       
   115 		}
       
   116 	}
       
   117 
   105 
   118 /**
   106 /**
   119  * 2nd Phase Construction.
   107  * 2nd Phase Construction.
   120  */
   108  */
   121 void CUsbACMClassController::ConstructL()
   109 void CUsbACMClassController::ConstructL()
   122 	{
   110     {
   123 	//open ini file to find out how many acm functions are needed and read in their configuration data
   111     iNumberOfAcmFunctions = KUsbAcmNumberOfAcmFunctions;
   124 	ReadAcmConfigurationL();
   112 
       
   113     iAcmProtocolNum[0] = KUsbAcmProtocolNumAcm1;
       
   114     iAcmProtocolNum[1] = KUsbAcmProtocolNumAcm2;
       
   115     iAcmProtocolNum[2] = KUsbAcmProtocolNumAcm3;
       
   116     iAcmProtocolNum[3] = KUsbAcmProtocolNumAcm4;
       
   117     iAcmProtocolNum[4] = KUsbAcmProtocolNumAcm5;
   125 
   118 
   126 	// Prepare to use whichever mechanism is enabled to control bringing ACM 
   119 	// Prepare to use whichever mechanism is enabled to control bringing ACM 
   127 	// functions up and down.
   120 	// functions up and down.
   128 #ifdef USE_ACM_REGISTRATION_PORT
   121 #ifdef USE_ACM_REGISTRATION_PORT
   129 
   122 
   135 	// open it.
   128 	// open it.
   136 	LEAVEIFERRORL(iComm.Open(iCommServer, portName, ECommShared)); 
   129 	LEAVEIFERRORL(iComm.Open(iCommServer, portName, ECommShared)); 
   137 
   130 
   138 #else
   131 #else
   139 
   132 
   140 	LEAVEIFERRORL(iAcmServer.Connect());
   133     LEAVEIFERRORL(iAcmServer.Connect());
   141 
   134 
   142 #endif // USE_ACM_REGISTRATION_PORT
   135 #endif // USE_ACM_REGISTRATION_PORT
   143 	}
   136     }
   144 
   137 
   145 /**
       
   146 * Searches numberofacmfunctions.ini file for protocol number and for control and data
       
   147 * interface names, leaving if any is not found.
       
   148 */
       
   149 void CUsbACMClassController::ReadAcmIniDataL(CIniFile* aIniFile, TUint aCount, RBuf& aAcmControlIfcName, RBuf& aAcmDataIfcName)
       
   150 	{
       
   151 	LOG_FUNC
       
   152 	
       
   153 	TName sectionName;
       
   154 	TInt  protocolNum;
       
   155 
       
   156 #ifdef __FLOG_ACTIVE
       
   157 	TName acmProtocolNum(KAcmProtocolNum);
       
   158 	TBuf8<KMaxName> narrowAcmProtocolNum;
       
   159 	narrowAcmProtocolNum.Copy(acmProtocolNum);
       
   160 #endif
       
   161 	LOGTEXT3(_L8("\tLooking for ACM Section %d, keyword \"%S\""), aCount+1, &narrowAcmProtocolNum);
       
   162 
       
   163 	sectionName.Format(KAcmSettingsSection,(aCount+1));
       
   164 	
       
   165 #ifdef __FLOG_ACTIVE
       
   166 	// Set up useful narrow logging strings.
       
   167 	TBuf8<KMaxName> narrowSectionName;
       
   168 	narrowSectionName.Copy(sectionName);
       
   169 #endif
       
   170 	LOGTEXT2(_L8("\t  Section Name %S"), &narrowSectionName);
       
   171 
       
   172 	if (aIniFile->FindVar(sectionName, KAcmProtocolNum(), protocolNum))
       
   173 		{
       
   174 		LOGTEXT3(_L8("\tACM Section %d: Protocol No %d"),aCount+1, protocolNum);
       
   175 		iAcmProtocolNum[aCount] = static_cast<TUint8>(protocolNum);
       
   176 		}
       
   177 
       
   178 	// Search ini file for interface names. If either of the interface names does not exist then the
       
   179 	// descriptors remain at zero length. This is caught in DoStartL and the descriptors defaulted.
       
   180 	// Using this method saves memory on storing copies of the default interface names.
       
   181 	TPtrC ptrControlIfcName;
       
   182 	if (aIniFile->FindVar(sectionName, KAcmControlIfcName(), ptrControlIfcName))
       
   183 		{
       
   184 		TPtrC ptrDataIfcName;
       
   185 		if (aIniFile->FindVar(sectionName, KAcmDataIfcName(), ptrDataIfcName))
       
   186 			{
       
   187 			// Only copy the data if both interface names are valid
       
   188 			aAcmControlIfcName.CreateL(ptrControlIfcName);
       
   189 			aAcmControlIfcName.CleanupClosePushL();
       
   190 			aAcmDataIfcName.CreateL(ptrDataIfcName);
       
   191 			CleanupStack::Pop(&aAcmControlIfcName);
       
   192 			}
       
   193 		}
       
   194 	
       
   195 #ifdef __FLOG_ACTIVE
       
   196 	// Set up useful narrow logging strings.
       
   197 	TName dbgControlIfcName(aAcmControlIfcName);
       
   198 	TBuf8<KMaxName> narrowControlIfcName;
       
   199 	narrowControlIfcName.Copy(dbgControlIfcName);
       
   200 
       
   201 	TName dbgDataIfcName(aAcmDataIfcName);
       
   202 	TBuf8<KMaxName> narrowDataIfcName;
       
   203 	narrowDataIfcName.Copy(dbgDataIfcName);
       
   204 #endif
       
   205 	LOGTEXT2(_L8("\t  Control Interface Name %S"), &narrowControlIfcName);
       
   206 	LOGTEXT2(_L8("\t  Data Interface Name %S"), &narrowDataIfcName);
       
   207 	}
       
   208 	
       
   209 /**
       
   210 Called when class Controller constructed 
       
   211 It opens a numberofacmfunctions.ini file and gets the info from there
       
   212 Error behaviour: 
       
   213 If the ini file is not found the number of ACM functions, their protocol 
       
   214 settings and interface names will be the default values.
       
   215 If a memory error occurs then leaves with KErrNoMemory.
       
   216 If the ini file is created but the file contains invalid configuration then panic.
       
   217 */
       
   218 void CUsbACMClassController::ReadAcmConfigurationL()
       
   219 	{
       
   220 	LOG_FUNC
       
   221 	
       
   222 	// The number of ACM functions should at this point be as set in the 
       
   223 	// constructor.
       
   224 	__ASSERT_DEBUG(static_cast<TUint>(iNumberOfAcmFunctions) == KDefaultNumberOfAcmFunctions, 
       
   225 		_USB_PANIC(KAcmCcPanicCategory, EPanicBadNumberOfAcmFunctions));
       
   226 	
       
   227 	LOGTEXT3(_L("\ttrying to open file \"%S\" in directory \"%S\""), 
       
   228 		&KAcmFunctionsIniFileName, &KUsbManPrivatePath);
       
   229 	
       
   230 	// First find the file
       
   231 	CIniFile* iniFile = NULL;
       
   232 	TRAPD (error, iniFile = CIniFile::NewL(KAcmFunctionsIniFileName, KUsbManPrivatePath));
       
   233 	
       
   234 	if (error == KErrNotFound)
       
   235 		{	
       
   236 		LOGTEXT(_L8("\tfile not found"));
       
   237 		}
       
   238 	else if (error != KErrNone)
       
   239 		{
       
   240 		LOGTEXT(_L8("\tini file was found, but couldn't be opened"));
       
   241 		LEAVEL(error);	
       
   242 		}
       
   243 	else 
       
   244 		{
       
   245 		LOGTEXT(_L8("\tOpened ini file"));
       
   246 		LOGTEXT3(_L("\tLooking for Section \"%S\", keyword \"%S\""), 
       
   247 			&KAcmConfigSection, &KNumberOfAcmFunctionsKeyWord);
       
   248 
       
   249 		CleanupStack::PushL(iniFile);
       
   250 		if ( !iniFile->FindVar(KAcmConfigSection(), KNumberOfAcmFunctionsKeyWord(), iNumberOfAcmFunctions) )
       
   251 			{
       
   252 			// PANIC since this should only happen in development environment. 
       
   253 			// The file is incorrectly written.
       
   254 			LOGTEXT(_L8("\tCan't find item"));
       
   255 			_USB_PANIC(KAcmCcPanicCategory, EPanicBadNumberOfAcmFunctions);
       
   256 			}
       
   257 					
       
   258 		LOGTEXT2(_L8("\tini file specifies %d ACM function(s)"), iNumberOfAcmFunctions);
       
   259 		
       
   260 		for ( TUint i = 0 ; i < iNumberOfAcmFunctions ; i++ )
       
   261 			{
       
   262 	 		 // Search ini file for the protocol number and interface names for 
       
   263 	 		 // the function, using defaults if any are not found.
       
   264 	 		 // May leave with KErrNoMemory.
       
   265 	 		 ReadAcmIniDataL(iniFile, i, iAcmControlIfcName[i], iAcmDataIfcName[i]);
       
   266 	 		 }
       
   267 		CleanupStack::PopAndDestroy(iniFile);
       
   268 		}
       
   269 	}
       
   270 	
       
   271 /**
   138 /**
   272  * Called by UsbMan when it wants to start the USB ACM class. This always
   139  * Called by UsbMan when it wants to start the USB ACM class. This always
   273  * completes immediately.
   140  * completes immediately.
   274  *
   141  *
   275  * @param aStatus The caller's request status, filled in with an error code
   142  * @param aStatus The caller's request status, filled in with an error code
   291 void CUsbACMClassController::DoStartL()
   158 void CUsbACMClassController::DoStartL()
   292 	{
   159 	{
   293 	LOG_FUNC
   160 	LOG_FUNC
   294 
   161 
   295 	iState = EUsbServiceStarting;
   162 	iState = EUsbServiceStarting;
       
   163 	LOGTEXT2(_L8("    iNumberOfAcmFunctions = %d"), iNumberOfAcmFunctions);
   296 
   164 
   297 #ifdef USE_ACM_REGISTRATION_PORT
   165 #ifdef USE_ACM_REGISTRATION_PORT
   298 
   166 
   299 	// Create ACM functions.
   167     // Create ACM functions.
   300 	TUint acmSetting;
   168     TUint acmSetting;
   301 	for ( TUint i = 0 ; i < iNumberOfAcmFunctions ; i++ )
   169     for (TUint i = 0; i < iNumberOfAcmFunctions; i++)
   302 		{
   170         {
   303 		// indicate the number of ACMs to create, and its protocol number (in the 3rd-lowest byte)
   171         LOGTEXT2(_L8("    iAcmProtocolNum[i] = %d"), iAcmProtocolNum[i]);
   304 		acmSetting = 1 | (static_cast<TUint>(iAcmProtocolNum[i])<< 16); 
   172 
   305 		TInt err = iComm.SetSignalsToMark(acmSetting);
   173         // indicate the number of ACMs to create, and its protocol number (in the 3rd-lowest byte)
   306 		if ( err != KErrNone )
   174         acmSetting = 1 | (static_cast<TUint> (iAcmProtocolNum[i]) << 16);
   307 			{
   175         TInt err = iComm.SetSignalsToMark(acmSetting);
   308 			LOGTEXT2(_L8("    SetSignalsToMark error = %d"), err);
   176         if (err != KErrNone)
   309 			if (i != 0)
   177             {
   310 				{
   178             LOGTEXT2(_L8("    SetSignalsToMark error = %d"), err);
   311 				// Must clear any ACMs that have completed.
   179             if (i != 0)
   312 				// only other than KErrNone if C32 Server fails
   180                 {
   313 				(void)iComm.SetSignalsToSpace(i);
   181                 // Must clear any ACMs that have completed.
   314 				}
   182                 // only other than KErrNone if C32 Server fails
   315 			LEAVEL(err);
   183                 (void) iComm.SetSignalsToSpace(i);
   316 			}
   184                 }
   317 		}
   185             LEAVEL(err);
       
   186             }
       
   187         }
   318 
   188 
   319 #else // use ACM server
   189 #else // use ACM server
   320 
   190     // Create ACM functions
   321 	// Create ACM functions
   191     for ( TInt i = 0; i < iNumberOfAcmFunctions; i++ )
   322 	for ( TInt i = 0 ; i < iNumberOfAcmFunctions ; i++ )
   192         {
   323 		{
   193         TInt err;
   324 		TInt err;
   194         //Use default control interface name and data interface name
   325 		// Check for zero length descriptor and default it if so
   195         //For improving performance, control interface name and data interface name configurable 
   326 		if (iAcmControlIfcName[i].Length())
   196         //is not supported now.
   327 			{
   197         err = iAcmServer.CreateFunctions(1, iAcmProtocolNum[i], KControlIfcName, KDataIfcName);
   328 			err = iAcmServer.CreateFunctions(1, iAcmProtocolNum[i], iAcmControlIfcName[i], iAcmDataIfcName[i]);
   198 
   329 			}
   199         if ( err != KErrNone )
   330 		else
   200             {
   331 			{
   201             LOGTEXT2(_L8("\tFailed to create ACM function. Error: %d"), err);
   332 			err = iAcmServer.CreateFunctions(1, iAcmProtocolNum[i], KControlIfcName, KDataIfcName);
   202             if (i != 0)
   333 			}
   203                 {
   334 
   204                 //Must clear any ACMs that have been completed
   335 		if ( err != KErrNone )
   205                 iAcmServer.DestroyFunctions(i);
   336 			{
   206                 LOGTEXT2(_L8("\tDestroyed %d Interfaces"), i);
   337 			LOGTEXT2(_L8("\tFailed to create ACM function. Error: %d"), err);
   207                 }
   338 			if (i != 0)
   208             LEAVEL(err);
   339 				{
   209             }
   340 				//Must clear any ACMs that have been completed
   210         }
   341 				iAcmServer.DestroyFunctions(i);
       
   342 				LOGTEXT2(_L8("\tDestroyed %d Interfaces"), i);
       
   343 				}
       
   344 			LEAVEL(err);
       
   345 			}
       
   346 		}
       
   347 
   211 
   348 #endif // USE_ACM_REGISTRATION_PORT
   212 #endif // USE_ACM_REGISTRATION_PORT
   349 	
   213 	
   350 	LOGTEXT2(_L8("\tCreated %d ACM Interfaces"), iNumberOfAcmFunctions);
   214 	LOGTEXT2(_L8("\tCreated %d ACM Interfaces"), iNumberOfAcmFunctions);
   351 	}
   215 	}