This section looks at example code in the Function Driver Controller (FDC) template and in a mass storage FDC implementation of the template.
In this code example (provided in the template), NewL() calls ContructL().
CRefFdc* CRefFdc::NewL(MFdcPluginObserver& aObserver) { CRefFdc* self = new(ELeave) CRefFdc(aObserver); CleanupStack::PushL(self); self->ConstructL(); CleanupStack::Pop(self); return self; }
ConstructL() needs to set up a private channel between the Function Driver Controller and the Function Driver Implementation. The following example is provided in a mass storage FDC implementation. In it the mass storage FDC sets up a connection with the mount manager.
void CRefFdc::ConstructL() { //Set up the connection with mount manager TInt error = iMsmmSession.Connect(); //Handle errors }
When the FDF discovers a device is attached, it calls Mfi1newFunction(), which does the following:
Claims a token for the interface offered (from the FDF) and gets various strings from the device
Creates a data structure containing all the information that the Function Driver Implementation needs
Passes the token and data to the Function Driver Implementation.
The following example code shows a token being claimed for a mass storage device FDC:
// Mass Storage FDC only claims one interface. TUint32 token = Observer().TokenForInterface(aInterfaces[0]); if (token == 0) { return KErrGeneral; }
This example code shows descriptors being collected and stored in a data structure a mass storage device FDC:
//Get the languages that is supported by this device. ... //Get Serial number from string descriptor ... //Get Product string descriptor ... //Get Manufacturer string descriptor ... //Send information data->iConfigurationNumber = aDeviceDescriptor.NumConfigurations(); data->iBcdDevice = aDeviceDescriptor.DeviceBcd(); data->iDeviceId = aDeviceId; data->iProductId = aDeviceDescriptor.ProductId(); data->iVendorId = aDeviceDescriptor.VendorId(); data->iHNPSupported = aOtgDescriptor.HNPSupported(); data->iSRPSupported = aOtgDescriptor.SRPSupported();
It uses the session created in ContsructL() and tells it to pass a Function with the data structure and, most importantly, the token it claimed. The token is passed to the FDI. This example code for a mass storage FDC uses the session connected to earlier and passes the information:
TRAP(error, addret = iMsmmSession.AddFunctionL(*data, aInterfaces[0], token)); delete data;
From here the FDI sets up a session with the host driver and takes over the interface, allowing it to make data transfers. For information on implementing FDIs, see Writing a Function Driver Implementation.
To close down, a device identifier gets passed to the session created earlier and the session removes the device from its records.