Data Transfer between LDD and PDD

This document describes how LDDs and PDDs exchange data.

The device driver framework supplies each LDD with a pointer, DLogicalChannelBase::iPdd, through which it can access PDD functions. The pointer is initialised by the Kernel while creating a physical channel.

An example of this pointer in use:

inline DExUartPhysicalChannel * DExDriverLogicalChannel::Pdd()
    { return (DExUartPhysicalChannel *)iPdd; }

// example use
Pdd()->SetDfcQ();

Similarly, a PDD can access a LDD, though this access must be initialised by the LDD. In the following example, the physical channel declares a pointer to a logical channel, which the LDD sets. Callbacks to the LDD are done using this pointer.

// PDD channel class
class DExH4PhysicalChannel: public DBase
    {
    ...
public:
    DExDriverLogicalChannel* iLdd;
    }

// Second stage constructor of Logical channel
TInt DExDriverLogicalChannel::DoCreate(TInt /*aUnit*/, const TDesC8*
        /*anInfo*/, const TVersion& aVer)
    {
    ...
    Pdd()->iLdd=this;
    }

// example use in PDD
iLdd->ReceiveDataComplete(KErrNone);

The logical channel class, DLogicalChannelBase, also has pointers to a logical device (iDevice) and a physical device (iPhysicalDevice). These pointers are initialised during the driver loading and channel open operations, so they can also be used to pass information between the LDD and PDD.

class DLogicalChannelBase: public DObject
    {
    ...
public:
    DLogicalDevice* iDevice;
    DPhysicalDevice* iPhysicalDevice;
    DBase* iPdd;
    }

// example use
TDynamicDfcQue* DExUartPhysicalChannelH4::DfcQ(TInt aUnit)
    {    
    ...
    return ((DExH4PhysicalDevice*)
            (iLdd->iPhysicalDevice))->iDfcQueue;    
    }