connectivitylayer/isce/p2prouter_dll/inc/p2puserchannel.h
author mikaruus
Tue, 19 Oct 2010 13:16:20 +0300
changeset 9 8486d82aef45
parent 0 63b37f68c1ce
permissions -rw-r--r--
modemadaptation release 2010wk40

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
* 
* Description: 
*
*/



#ifndef __DP2PUSERCHANNEL_H__
#define __DP2PUSERCHANNEL_H__

// Includes
#include <kernel.h>                 // For DLogicalChannel
#include "p2prouterchannelifs.h"    // For MP2PRouterChIf
#include "p2pinternaldefs.h"        // For TP2PAsyncRequest

// Class declaration
class DMsgQueue;
class DP2PReqQueue;

/**
* Provides channel for user side P2P API
*/
NONSHARABLE_CLASS( DP2PUserChannel ) : public DLogicalChannel, public MP2PRouterChIf
    {

    public: 

        /**
        * C++ default constructor.
        */
        DP2PUserChannel();

        /**
        * Destructor.
        */
        ~DP2PUserChannel();

        ///// Functions from base class DLogicalChannel start

        /**
        * Second phase constructor. Run in user thread context.
        * Thread in CS and can not be pre-empted.
        * See other comments from DLogicalChannel.
        * @param aUnit, Not used at the moment possible to have over 32 channel.
        * @param anInfo, contains the protocol id
        * @param aVer, Not used at the moment.
        */
        virtual TInt DoCreate( TInt aUnit, const TDesC8* anInfo, const TVersion& aVer );

        /**
        * Kernel message que function. Run in kernel thread context.
        * See other comments from DLogicalChannel.
        * @param aMsg, message from Request function.
        */
        virtual void HandleMsg( TMessageBase* aMsg );

        /**
        * Overwritten so that accepts only calls with DoControl.
        * See other comments from DLogicalChannel.
        */
        TInt Request( TInt aReqNo, TAny* a1, TAny* a2 );

        ///// Functions from base class DLogicalChannel end

        ///// Functions from MP2PRouterChIf start
        /*
        * See comments from MP2PRouterChIf.
        */
        void ConnectionLost();

        /**
        * See other comments from MP2PRouterChIf.
        */
        void EnqueChannelRequestCompleteDfc( TInt aRequest, TInt aStatusToComplete );

        /*
        * Called when message to this channel is to be received.
        * @param aDataMessage, data message.
        * @return void
        */
        void ReceiveMsg( const TDesC8& aMessage );

        ///// Functions from MP2PRouterChIf end

    private:

        /*
        * Closes the channel toward router.
        * Modifies member variable iShP2PProtocolId.
        * Called in P2P extension kernel thead context.
        * @param aP2PProtocolId, protocol id of the channel to be closed.
        */
        void Close( const TUint8 aP2PProtocolId );

        /*
        * Handles actions related to closing the channel.
        */
        void Closing();

        /**
        * DFC function that completes channel requests to user thread.
        * Run always in P2P user channel kernel thread context.
        * @param aPtr, pointer to self
        * @return None
        */
        static void CompleteChReqDfc( TAny* aPtr );

        /*
        * Handling of asynchronous requests.
        * @param aFunction, request id
        * @param a1, pointer to parameters.
        * @return void
        */
        void HandleAsyncRequest( TInt aFunction, TAny* a1 );

        /*
        * Handling of cancellation of asynchronous requests.
        * @param aFunction, request id
        * @param a1, pointer to parameters.
        * @return void
        */
        TInt HandleCancelRequest( TInt aFunction, TAny* a1 );

        /*
        * Handling of all requests.
        * @param aFunction, request id
        * @param a1, pointer to parameters.
        * @param a2, not used
        * @return void
        */
        TInt HandleRequest( TInt aFunction, TAny* a1, TAny* a2 );

        /*
        * Handling of synchronous requests.
        * @param aFunction, request id
        * @param a1, pointer to parameters.
        * @return void
        */
        TInt HandleSyncRequest( TInt aFunction, TAny* a1 );

        /**
        * DFC function that empties message receive queue to user thread.
        * @param aPtr, pointer to self
        * @return None
        */
        static void EmptyRxQueueDfc( TAny* aPtr );

        /**
        * Resets channel data message and message queues.
        * @return None
        */
        void ResetQueues();

        /**
        * Do the cancellation of request.
        * @param aRequest,
        * @param aMask
        * @return None
        */
        void DoCancel( TInt aRequest, TInt aMask );

    // Internal Classes

    /*
    * 
    */
    NONSHARABLE_CLASS( TP2PReq )
        {

        public:

           TP2PReq();

           TP2PReq( TP2PAsyncRequest aReq, TInt aStat );

           // Data
           TP2PAsyncRequest    iRequest;
           TInt                iCompleteStatus;

        };

    /*
    * Handles requests in a ring buffer manner.
    * Syncronization protection by NFastMutex.
    */
    NONSHARABLE_CLASS( DP2PReqQueue ) : public DBase
        {

        public:

            /*
            * Default constructor
            */
            DP2PReqQueue();

            /*
            * Destructor
            */
            ~DP2PReqQueue();

            /* 
            * In case of queue overflow throw kern::fault
            * Adds the message in the end of the ringbuffer queue.
            * @param aReq
            */
            TBool Add( TP2PReq aReq );

            /*
            *Returns ETrue if empty.
            */
            TBool Empty();

            /*
            *Returns first request.
            */
            TP2PReq Get();

            /*
            * Set req active / deactive. Default deactive.
            */
            void SetReq( TP2PAsyncRequest aReqToSet, TRequestStatus* aStatus = NULL );

            /*
            * Get req. If NULL, request not pending.
            */
            TRequestStatus* GetReq( TP2PAsyncRequest aReqToGet );

      private:

            // Index where to add next message pointer.
            TUint8          iShInputIndex;
            // Index where to get next message pointer.
            TUint8          iShOutputIndex;
            // Count of items in the array.
            TUint8          iShCount;
            // Size of the ring buffer. Write only in constructor.
            TUint8          iSize;
            // Guards internal states of this class.
            NFastMutex*     iQueueMutex;
            // Ring buffer must be as big as we have request.  is there a danger to get more request..?
            TP2PReq         iShReqRingBuffer[ EP2PLastAsyncRequest ];
            // Active / Deactive requests are kept in list to make finding easier.
            TRequestStatus* iShReqList[ EP2PLastAsyncRequest ];

        };

    private:

        // Added convention:
        // Prefix "iSh" means shared member variable
        // Prefix "gSh" means shared global variable

        // Data members
        // Channel number of this channel.
        TUint8              iShP2PProtocolId;
        // Mutex guarding iShP2PProtocolId, not owned
        DMutex*             iShP2PProtocolIdMutex;
        // Pointers to client message buffer, not owned
        TAny*               iReceiveBufPtr;
        // Owned, synchronized internally with fastmutexes no need to guard
        DMsgQueue*          iRx;
        // Owned, no need to sync don internally
        TDfc*               iEmptyRxQueueDfc;
        // Owned, no need to sync don internally
        TDfc*               iCompleteChannelRequestDfc;
        // Owned, synchronized internally with fastmutexes.
        DP2PReqQueue*       iP2PReqQueue;
        // Not owned, no need to guard open/close in one thread in construction and desctruction.
        DThread*            iThread;
        // Not owned, no need to guard only written in one thread in construction and desctruction.
        MP2PChRouterIf*     iRouterIf;

    };

#endif      // __DP2PUSERCHANNEL_H__
            
// End of File