connectivitylayer/isce/p2prouter_dll/src/p2puserchannel.cpp
changeset 0 63b37f68c1ce
child 5 8ccc39f9d787
equal deleted inserted replaced
-1:000000000000 0:63b37f68c1ce
       
     1 /*
       
     2 * Copyright (c) 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 the License "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 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <kern_priv.h>              // For DMutex
       
    21 #include "p2puserchannel.h"         // For DP2PUserChannel
       
    22 #include "msgqueue.h"               // For DMsgQueue 
       
    23 #include "p2proutertrace.h"         // For C_TRACE, ASSERT_RESET.. and fault codes.
       
    24 #include "memapi.h"                 // MemApi
       
    25 #include "p2pdefs.h"                // For EP2PAmountOfProtocols
       
    26 
       
    27 enum TP2PUserChannelFaults
       
    28     {
       
    29     EP2PUserChannelMemAllocFail = 0x00,
       
    30     EP2PUserChannelMemAllocFail1,
       
    31     EP2PUserChannelMemAllocFail2,
       
    32     EP2PUserChannelWrongRequest,
       
    33     EP2PUserChannelWrongRequest1,
       
    34     EP2PUserChannelWrongRequest2,
       
    35     EP2PUserChannelWrongRequest3,
       
    36     EP2PUserChannelWrongRequest4,
       
    37     EP2PUserChannelWrongRequest5,
       
    38     EP2PUserChannelWrongRequest6,
       
    39     EP2PUserChannelWrongRequest7,
       
    40     EP2PUserChannelWrongParam,
       
    41     EP2PUserChannelWrongParam2,
       
    42     EP2PUserChannelProtocolIdNotSpecified,
       
    43     EP2PUserChannelOverTheArrayLimits,
       
    44     EP2PUserChannelDesWriteFailed,
       
    45     EP2PUserChannelSameRequest,
       
    46     EP2PUserChannelSameRequest2,
       
    47     EP2PUserChannelNullParam,
       
    48     EP2PUserChannelNullParam2,
       
    49     EP2PUserChannelDesReadFailed,
       
    50     EP2PIUserChannelfNotThreadContext,
       
    51     EP2PIUserChannelfNotThreadContext2,
       
    52     EP2PIUserChannelfNotThreadContext3,
       
    53     EP2PIUserChannelfNotThreadContext4,
       
    54     EP2PIUserChannelfNotThreadContext5,
       
    55     EP2PUserChannelMutexCreateFailed,
       
    56     EP2PUserChannelMutexWaitFailed,
       
    57     EP2PUserChannelMutexWaitFailed2,
       
    58     EP2PUserChannelMutexWaitFailed3,
       
    59     EP2PUserChannelMutexWaitFailed4,
       
    60     EP2PUserChannelReqQueueOutOfSync,
       
    61     EP2PUserChannelReqQueueOutOfSync1,
       
    62     EP2PUserChannelReqQueueOutOfSync2,
       
    63     EP2PUserChannelReqQueueOutOfSync3,
       
    64     EP2PUserChannelReqQueueOutOfSync4,
       
    65     EP2PUserChannelReqQueueOutOfSync5,
       
    66     EP2PUserChannelReqQueueOutOfSync6,
       
    67     EP2PUserChannelReqQueueOutOfSync7,
       
    68     EP2PUserChannelReqQueueOverTheLimits,
       
    69     EP2PUserChannelReqQueueOverTheLimits2,
       
    70     EP2PUserChannelReqQueueWrongRequest,
       
    71     EP2PUserChannelReqQueueWrongRequest2,
       
    72     EP2PUserChannelReqQueueMemoryAllocFailure,
       
    73     EP2PUserChannelReqQueueCommon,
       
    74     };
       
    75 
       
    76 
       
    77 // Extracting and adding the pipeheader.
       
    78 const TInt KFirstParam( 0 );
       
    79 const TInt KSecondParam( 1 );
       
    80 const TInt KNoParams( KErrNone );
       
    81 const TInt KOneParam( 1 );
       
    82 const TInt KTwoParams( 2 );
       
    83 const TInt KThreeParams( 3 );
       
    84 
       
    85 const TInt KDestStartOffset( 0 );
       
    86 const TInt KP2PLddEmptyRxPriori( 1 );
       
    87 const TInt KP2PLddCompletePriori( 1 );
       
    88 
       
    89 const TInt KP2PMaximumSendSize( 0xffff );
       
    90 
       
    91 //DMutex* DP2PUserChannel::iShP2PProtocolIdMutex = NULL;
       
    92 _LIT8( KP2PUserChannelP2PProtocolIdMutex, "P2PUserChannelP2PProtocolIdMutex" );
       
    93 
       
    94 //
       
    95 // user<> kernel interaction() done in LDD DFC thread
       
    96 // 
       
    97 // kernel<>kernel interaction() done in Extension DFC thread
       
    98 //
       
    99 // DEMAND_PAGING
       
   100 // Receive (write k>u) is done only in LDD thread context to allow Extension thread to continue when dp swaps.
       
   101 // Send ((write u>k) is not done at the moment in LDD thread context only. Check is it possible to happend (not to be in usable memory after send (unlikely?)).
       
   102 DP2PUserChannel::DP2PUserChannel(
       
   103         // None
       
   104         )
       
   105     :
       
   106     iShP2PProtocolId( EP2PAmountOfProtocols ),
       
   107     iReceiveBufPtr( NULL ),
       
   108     iRx( NULL ),
       
   109     iP2PReqQueue( NULL ),
       
   110     iThread( &Kern::CurrentThread() )
       
   111     {
       
   112 
       
   113     C_TRACE( ( _T( "DP2PUserChannel::DP2PUserChannel>" ) ) );
       
   114     iRouterIf = MP2PChRouterIf::GetIf();
       
   115     ASSERT_RESET_ALWAYS( iRouterIf, ( EP2PUserChannelMemAllocFail | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   116     iEmptyRxQueueDfc = new TDfc( EmptyRxQueueDfc, this, iRouterIf->GetDfcThread( MP2PChRouterIf::EP2PLddDfcThread ), KP2PLddEmptyRxPriori );
       
   117     iCompleteChannelRequestDfc = new TDfc( CompleteChReqDfc, this, iRouterIf->GetDfcThread( MP2PChRouterIf::EP2PLddDfcThread ), KP2PLddCompletePriori );
       
   118     iP2PReqQueue = new DP2PReqQueue();
       
   119     ASSERT_RESET_ALWAYS( iEmptyRxQueueDfc && iCompleteChannelRequestDfc && iP2PReqQueue, ( EP2PUserChannelMemAllocFail1 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   120     TInt err( Kern::MutexCreate( iShP2PProtocolIdMutex, KP2PUserChannelP2PProtocolIdMutex, KMutexOrdGeneral0 ) );
       
   121     ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EP2PUserChannelMutexCreateFailed | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   122     C_TRACE( ( _T( "DP2PUserChannel::DP2PUserChannel<" ) ) );
       
   123 
       
   124     }
       
   125 
       
   126 DP2PUserChannel::~DP2PUserChannel(
       
   127         // None
       
   128         )
       
   129     {
       
   130 
       
   131     C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x>" ), this, iShP2PProtocolId ) );
       
   132     // owned starts
       
   133     if( iEmptyRxQueueDfc )
       
   134         {
       
   135         C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iEmptyRxQueueDfc 0x%x" ), this, iShP2PProtocolId, iEmptyRxQueueDfc ) );
       
   136         iEmptyRxQueueDfc->Cancel();
       
   137         delete iEmptyRxQueueDfc;
       
   138         iEmptyRxQueueDfc = NULL;
       
   139         }
       
   140     if( iCompleteChannelRequestDfc )
       
   141         {
       
   142         C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iCompleteChannelRequestDfc 0x%x" ), this, iShP2PProtocolId, iCompleteChannelRequestDfc ) );
       
   143         iCompleteChannelRequestDfc->Cancel();
       
   144         delete iCompleteChannelRequestDfc;
       
   145         iCompleteChannelRequestDfc = NULL;
       
   146         }
       
   147     if( iRx )
       
   148         {
       
   149         C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iRx 0x%x" ), this, iShP2PProtocolId, iRx ) );
       
   150         delete iRx;
       
   151         iRx = NULL;
       
   152         }
       
   153     if( iReceiveBufPtr )
       
   154         {
       
   155         C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iReceiveBufPtr 0x%x" ), this, iShP2PProtocolId, iReceiveBufPtr ) );
       
   156         iReceiveBufPtr = NULL;
       
   157         }
       
   158     if( iP2PReqQueue )
       
   159        {
       
   160        C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iP2PReqQueue 0x%x" ), this, iShP2PProtocolId, iP2PReqQueue ) );
       
   161        delete iP2PReqQueue;
       
   162        iP2PReqQueue = NULL;
       
   163        }
       
   164     // No need to check, if failed reseted already
       
   165     C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x iShP2PProtocolIdMutex 0x%x" ), this, iShP2PProtocolId, iShP2PProtocolIdMutex ) );
       
   166     iShP2PProtocolIdMutex->Close( NULL );
       
   167     // owned ends
       
   168     iRouterIf = NULL;
       
   169     Kern::SafeClose( reinterpret_cast<DObject*&>(iThread), NULL );
       
   170     C_TRACE( ( _T( "DP2PUserChannel::~DP2PUserChannel 0x%x 0x%x<" ), this, iShP2PProtocolId ) );
       
   171 
       
   172     }
       
   173 
       
   174 /*
       
   175 * Executed in user thread context thread inside CS, cannot be pre-empted.
       
   176 * Channel can not be used before creation, so no need to synch if congesting only btw the creating user thread and one thread.
       
   177 */    
       
   178 TInt DP2PUserChannel::DoCreate(
       
   179         TInt, //aUnit,              // No need to use this, we can avoid the limit of 32 channels
       
   180         const TDesC8* anInfo,       // Contains the protocolId
       
   181         const TVersion& // aVer     // Not used at the moment.
       
   182         )
       
   183     {
       
   184 
       
   185     C_TRACE( ( _T( "DP2PUserChannel::DoCreate 0x%x 0x%x 0x%x>" ), this, iShP2PProtocolId, anInfo ) );
       
   186     if( !Kern::CurrentThreadHasCapability( ECapabilityCommDD, __PLATSEC_DIAGNOSTIC_STRING( "Check by: P2PRouter" ) ) ) return KErrPermissionDenied;  
       
   187     TRACE_ASSERT_INFO( anInfo, EP2PUserChannelProtocolIdNotSpecified );
       
   188     // Check for channel number inside anInfo.
       
   189     TRACE_ASSERT_INFO( anInfo->Length() > 0, ( EP2PUserChannelOverTheArrayLimits | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   190     if( !anInfo || anInfo->Length() == 0 ) return KErrNotSupported;
       
   191     TUint8 protocolId = static_cast<TUint8>( ( *anInfo )[ 0 ] );
       
   192     TRACE_ASSERT_INFO( ( protocolId < EP2PAmountOfProtocols ), ( EP2PUserChannelWrongParam | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   193     if( protocolId >= EP2PAmountOfProtocols ) return KErrNotSupported;
       
   194     TInt err( Kern::MutexWait( *iShP2PProtocolIdMutex ) );
       
   195     ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EP2PUserChannelMutexWaitFailed | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   196     // If channel is already used for some protocol.
       
   197     if( iShP2PProtocolId != EP2PAmountOfProtocols )
       
   198         {
       
   199         Kern::MutexSignal( *iShP2PProtocolIdMutex );
       
   200         return KErrAlreadyExists;
       
   201         }
       
   202     iShP2PProtocolId = ~protocolId;
       
   203     Kern::MutexSignal( *iShP2PProtocolIdMutex );
       
   204     C_TRACE( ( _T( "DP2PUserChannel::DoCreate protocolId 0x%x 0x%x" ), this, iShP2PProtocolId ) );
       
   205     iRx = new DMsgQueue( KP2PLddRxQueuSize );
       
   206     ASSERT_RESET_ALWAYS( iRx, ( EP2PUserChannelMemAllocFail2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   207     // Other DFC functions handling user<>kernel copying done in ldd DFC. Ldd DFC function priority is 1.
       
   208     SetDfcQ( iRouterIf->GetDfcThread( MP2PChRouterIf::EP2PDfcThread ) );
       
   209     iMsgQ.Receive();
       
   210     DObject* thread = reinterpret_cast<DObject*>( iThread );
       
   211     // Open is needed to increase ref count to calling thread that is decreased in Kern::SafeClose
       
   212     // Possible returns KErrNone ? KErrGeneral
       
   213     TInt threadOpen( thread->Open() );
       
   214     TRACE_ASSERT_INFO( threadOpen == KErrNone, (TUint8)iShP2PProtocolId );
       
   215     C_TRACE( ( _T( "DP2PUserChannel::DoCreate 0x%x 0x%x %d<" ), this, iShP2PProtocolId, threadOpen ) );
       
   216     return threadOpen;
       
   217     
       
   218     }
       
   219 
       
   220 void DP2PUserChannel::HandleMsg(
       
   221         TMessageBase* aMsg
       
   222         )
       
   223     {
       
   224 
       
   225     C_TRACE( ( _T( "DP2PUserChannel::HandleMsg 0x%x 0x%x 0x%x>" ), this, iShP2PProtocolId, aMsg ) );
       
   226     TThreadMessage& m= *( static_cast< TThreadMessage* >( aMsg ) );
       
   227     TInt id( m.iValue );
       
   228     if( static_cast<TInt>( ECloseMsg ) == id )
       
   229         {
       
   230         C_TRACE( ( _T( "DP2PUserChannel::HandleMsg ECloseMsg 0x%x 0x%x 0x%x" ), this, iShP2PProtocolId, aMsg ) );
       
   231         m.Complete( HandleSyncRequest( EP2PClose, NULL ), EFalse );
       
   232         }
       
   233     else if( KMaxTInt == id )
       
   234         {
       
   235         C_TRACE( ( _T( "DP2PUserChannel::HandleMsg cancel 0x%x 0x%x 0x%x" ), this, iShP2PProtocolId, aMsg ) );
       
   236         DoCancel( id, m.Int0() );
       
   237         m.Complete( KErrNone, ETrue );
       
   238         }
       
   239     else
       
   240         {
       
   241         ASSERT_RESET_ALWAYS( ( KErrNotFound < id ), ( EP2PUserChannelWrongRequest | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   242         C_TRACE( ( _T( "DP2PUserChannel::HandleMsg request 0x%x 0x%x %d 0x%x" ), this, iShP2PProtocolId, id, aMsg ) );
       
   243         TInt completeValue( KErrNone );
       
   244         TInt ulen( KErrNotFound );
       
   245         switch ( id )
       
   246             {
       
   247             case EP2PClose:
       
   248                 {
       
   249                 ulen = KNoParams;
       
   250                 break;
       
   251                 }
       
   252             case EP2PSend:
       
   253             case EP2PAsyncConnectionLost:
       
   254                 {
       
   255                 ulen = KOneParam;
       
   256                 break;
       
   257                 }
       
   258             case EP2PAsyncOpen:
       
   259             case EP2PAsyncReceive:
       
   260                 {
       
   261                 ulen = KTwoParams;
       
   262                 break;
       
   263                 }
       
   264             default:
       
   265                 {
       
   266                 ASSERT_RESET_ALWAYS( 0, ( EP2PUserChannelWrongRequest1 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   267                 break;
       
   268                 }
       
   269             }
       
   270         TUint32* table[ KThreeParams ];
       
   271         completeValue = Kern::ThreadRawRead( iThread, m.Ptr0(), table, ulen * sizeof( TAny* ) );
       
   272         if( completeValue == KErrNone )
       
   273             {
       
   274             switch( id )
       
   275                 {
       
   276                 // All asynchronous requests.
       
   277                 case EP2PAsyncOpen:
       
   278                 case EP2PAsyncReceive:
       
   279                 case EP2PAsyncConnectionLost:
       
   280                     {
       
   281                     // No need to check return value in async functions, completed to user
       
   282                     HandleAsyncRequest( id, table );
       
   283                     break;
       
   284                     }
       
   285                 case EP2PClose:
       
   286                 case EP2PSend:
       
   287                     {
       
   288                     completeValue = HandleSyncRequest( id, table );
       
   289                     break;
       
   290                     }
       
   291                 default:
       
   292                     {
       
   293                     ASSERT_RESET_ALWAYS( 0, ( EP2PUserChannelWrongRequest2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   294                     break;
       
   295                     }
       
   296                 }
       
   297             }
       
   298         m.Complete( completeValue, ETrue );
       
   299         }
       
   300     C_TRACE( ( _T( "DP2PUserChannel::HandleMsg 0x%x 0x%x 0x%x<" ), this, iShP2PProtocolId, aMsg ) );
       
   301 
       
   302     }
       
   303 
       
   304 TInt DP2PUserChannel::Request(
       
   305         TInt aReqNo,
       
   306         TAny* a1,
       
   307         TAny* //a2
       
   308         )
       
   309     {
       
   310 
       
   311     C_TRACE( ( _T( "DP2PUserChannel::Request 0x%x 0x%x %d 0x%x>" ), this, iShP2PProtocolId, aReqNo, a1 ) );
       
   312     // Programmer errors.
       
   313     ASSERT_RESET_ALWAYS( aReqNo >= ( TInt ) EMinRequestId, ( EP2PUserChannelWrongRequest3 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   314     ASSERT_RESET_ALWAYS( ( aReqNo <= EP2PLastAsyncRequest || aReqNo == KMaxTInt ), ( EP2PUserChannelWrongRequest4 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   315     // Wrong API usage e.g. called function when interface is not open so panic the client thread.
       
   316     ASSERT_PANIC_USER_THREAD_ALWAYS( ( iShP2PProtocolId < EP2PAmountOfProtocols || EP2PAsyncOpen == aReqNo ), iThread, ( EP2PUserChannelWrongParam2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   317     TInt result( KErrNotFound );
       
   318     // All request go in kernel context and with ::DoControl call.
       
   319     TThreadMessage& m=Kern::Message();
       
   320     m.iValue = aReqNo;
       
   321     m.iArg[ KFirstParam ] = a1;
       
   322     m.iArg[ KSecondParam ] = NULL;
       
   323     result = m.SendReceive( &iMsgQ );
       
   324     C_TRACE( ( _T( "DP2PUserChannel::Request 0x%x 0x%x %d 0x%x %d<" ), this, iShP2PProtocolId, aReqNo, a1, result ) );
       
   325     return result;
       
   326 
       
   327     }
       
   328 
       
   329 ///// Functions from MChannelCallback start (from extension binary)
       
   330 // called in router ext context
       
   331 void DP2PUserChannel::ConnectionLost()
       
   332     {
       
   333 
       
   334     C_TRACE( ( _T( "DP2PKernelChannel::ConnectionLost 0x%x 0x%x %d %d 0x%x>" ), this, iShP2PProtocolId ) );
       
   335     EnqueChannelRequestCompleteDfc( EP2PAsyncConnectionLost, KErrNotReady );
       
   336     ResetQueues();
       
   337     //Closing();
       
   338     C_TRACE( ( _T( "DP2PKernelChannel::ConnectionLost 0x%x 0x%x %d %d 0x%x<" ), this, iShP2PProtocolId ) );
       
   339 
       
   340     }
       
   341 
       
   342 // called in router ext context
       
   343 void DP2PUserChannel::EnqueChannelRequestCompleteDfc(
       
   344         TInt aRequest,
       
   345         TInt aStatusToComplete
       
   346         )
       
   347     {
       
   348 
       
   349     C_TRACE( ( _T( "DP2PUserChannel::EnqueChannelRequestCompleteDfc 0x%x 0x%x %d %d>" ), this, iShP2PProtocolId, aRequest, aStatusToComplete ) );
       
   350     ASSERT_THREAD_CONTEXT_ALWAYS( ( EP2PIUserChannelfNotThreadContext | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   351     TP2PReq req( static_cast<TP2PAsyncRequest>( aRequest ), aStatusToComplete );
       
   352     if( iP2PReqQueue->Add( req ) )
       
   353         {
       
   354         TRACE_ASSERT_INFO( !iCompleteChannelRequestDfc->Queued(), (TUint8)iShP2PProtocolId << KProtocolIdShift | (TUint16)aRequest );
       
   355         iCompleteChannelRequestDfc->Enque();
       
   356         }
       
   357     C_TRACE( ( _T( "DP2PUserChannel::EnqueChannelRequestCompleteDfc 0x%x 0x%x %d %d<" ), this, iShP2PProtocolId, aRequest, aStatusToComplete ) );
       
   358 
       
   359     }
       
   360 
       
   361 // This is called in 1...N thread contextes
       
   362 void DP2PUserChannel::ReceiveMsg(
       
   363         const TDesC8& aMessage
       
   364         )
       
   365     {
       
   366 
       
   367     C_TRACE( ( _T( "DP2PUserChannel::ReceiveMsg 0x%x 0x%x 0x%x>" ), this, iShP2PProtocolId, &aMessage ) );
       
   368     // Can only be called from thread context.
       
   369     ASSERT_THREAD_CONTEXT_ALWAYS( ( EP2PIUserChannelfNotThreadContext3 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   370     iRx->Add( aMessage );
       
   371     iEmptyRxQueueDfc->Enque();
       
   372     C_TRACE( ( _T( "DP2PUserChannel::ReceiveMsg 0x%x 0x%x 0x%x<" ), this, iShP2PProtocolId, &aMessage ) );
       
   373 
       
   374     }
       
   375 
       
   376 
       
   377 ///// Functions from MChannelCallback end (from extension binary)
       
   378 
       
   379 // Run in P2P extension kernel thread context.
       
   380 void DP2PUserChannel::Close(
       
   381         const TUint8 aP2PProtocolId
       
   382         )
       
   383     {
       
   384 
       
   385     C_TRACE( ( _T( "DP2PUserChannel::Close 0x%x 0x%x 0x%x>" ), this, iShP2PProtocolId, aP2PProtocolId ) );
       
   386     if( EP2PAmountOfProtocols != iShP2PProtocolId )
       
   387         {
       
   388         C_TRACE( ( _T( "DP2PKernelChannel::Close closing 0x%x 0x%x>" ), iShP2PProtocolId, aP2PProtocolId ) );
       
   389         iRouterIf->Close( aP2PProtocolId );
       
   390         }
       
   391     iShP2PProtocolId = EP2PAmountOfProtocols;
       
   392     C_TRACE( ( _T( "DP2PUserChannel::Close 0x%x 0x%x 0x%x<" ), this, iShP2PProtocolId, aP2PProtocolId ) );
       
   393 
       
   394     }
       
   395 
       
   396 void DP2PUserChannel::Closing(
       
   397         // None
       
   398         )
       
   399     {
       
   400 
       
   401     C_TRACE( ( _T( "DP2PUserChannel::Closing 0x%x 0x%x 0x%x>" ), this, iShP2PProtocolId ) );
       
   402     ResetQueues();
       
   403     TInt err( Kern::MutexWait( *iShP2PProtocolIdMutex ) );
       
   404     ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EP2PUserChannelMutexWaitFailed2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   405     if( EP2PAmountOfProtocols != iShP2PProtocolId )
       
   406         {
       
   407         // Cancel any outstanding request. // remember in asynch close not to close it asynhronously
       
   408         for( TInt i( 0 ); i < EP2PLastAsyncRequest; ++i )
       
   409             {
       
   410             if( iP2PReqQueue->GetReq( static_cast< TP2PAsyncRequest >( i ) ) )
       
   411                 {
       
   412                 C_TRACE( ( _T( "DP2PUserChannel::Closing 0x%x 0x%x EP2PClose req to cancel" ), this, iShP2PProtocolId, i ) );
       
   413                 DoCancel( KMaxTInt, i );
       
   414                 }
       
   415             }
       
   416         Close( iShP2PProtocolId );
       
   417         }
       
   418     Kern::MutexSignal( *iShP2PProtocolIdMutex );
       
   419     C_TRACE( ( _T( "DP2PUserChannel::Closing 0x%x 0x%x 0x%x<" ), this, iShP2PProtocolId ) );
       
   420 
       
   421     }
       
   422 
       
   423 // Run in P2P user channel kernel thread context.
       
   424 void DP2PUserChannel::CompleteChReqDfc(
       
   425         TAny* aPtr
       
   426         )
       
   427     {
       
   428 
       
   429     C_TRACE( ( _T( "DP2PUserChannel::CompleteChReqDfc>" ) ) );
       
   430     // Make sure that user side is accessed only by ldd DFCThread.
       
   431     ASSERT_THREAD_CONTEXT_ALWAYS( ( EP2PIUserChannelfNotThreadContext2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   432     //TODO    ASSERT_DFCTHREAD_INLDD();
       
   433     DP2PUserChannel* chPtr = reinterpret_cast<DP2PUserChannel*>( aPtr );
       
   434     C_TRACE( ( _T( "DP2PUserChannel::CompleteChReqDfc 0x%x 0x%x" ), chPtr, chPtr->iShP2PProtocolId ) );
       
   435     TP2PReq requ = chPtr->iP2PReqQueue->Get();
       
   436     if( EP2PAsyncOpen == requ.iRequest )
       
   437         {
       
   438         C_TRACE( ( _T( "DP2PUserChannel::CompleteChReqDfc 0x%x 0x%x status %d" ), chPtr, chPtr->iShP2PProtocolId, requ.iCompleteStatus ) );
       
   439         // Check of KErrNone and KErrInUse (same object same id open) and in only those cases ~iCh = ~~iCh kernel already has.
       
   440         TInt err( Kern::MutexWait( *chPtr->iShP2PProtocolIdMutex ) );
       
   441         ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EP2PUserChannelMutexWaitFailed3 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   442         TUint8 chNumber( ( KErrNone == requ.iCompleteStatus || KErrInUse == requ.iCompleteStatus ? ~chPtr->iShP2PProtocolId : EP2PAmountOfProtocols ) );
       
   443         chPtr->iShP2PProtocolId = chNumber;
       
   444         Kern::MutexSignal( *chPtr->iShP2PProtocolIdMutex );
       
   445         }
       
   446     TRequestStatus* status( chPtr->iP2PReqQueue->GetReq( requ.iRequest ) );
       
   447     Kern::RequestComplete( chPtr->iThread, status, requ.iCompleteStatus );
       
   448     C_TRACE( ( _T( "DP2PUserChannel::CompleteChReqDfc 0x%x 0x%x req %d status %d" ), chPtr, chPtr->iShP2PProtocolId, requ.iRequest, requ.iCompleteStatus ) );
       
   449     chPtr->iP2PReqQueue->SetReq( requ.iRequest, NULL );
       
   450     if( !chPtr->iP2PReqQueue->Empty() )
       
   451         {
       
   452         CompleteChReqDfc( chPtr );
       
   453         }
       
   454     C_TRACE( ( _T( "DP2PUserChannel::CompleteChReqDfc 0x%x 0x%x<" ), chPtr, chPtr->iShP2PProtocolId ) );
       
   455 
       
   456     }
       
   457 
       
   458 void DP2PUserChannel::EmptyRxQueueDfc(
       
   459         TAny* aPtr // Pointer to self
       
   460         )
       
   461     {
       
   462 
       
   463 // TODO    ASSERT_DFCTHREAD_INLDD();
       
   464     DP2PUserChannel& chTmp = *reinterpret_cast<DP2PUserChannel*>( aPtr );
       
   465     C_TRACE( ( _T( "DP2PUserChannel::EmptyRxQueueDfc 0x%x 0x%x>" ), &chTmp, chTmp.iShP2PProtocolId ) );
       
   466     if( ( chTmp.iP2PReqQueue->GetReq( EP2PAsyncReceive ) ) && ( chTmp.iRx->Count() > 0 ) )
       
   467         {
       
   468         TDes8& tmpDes = chTmp.iRx->Get();
       
   469         // Write to user address space (iReceiveBufPtr) the content of tmpDes starting from zero offset as 8bit descriptor data.
       
   470         TInt writeError( Kern::ThreadDesWrite( chTmp.iThread, chTmp.iReceiveBufPtr, tmpDes, KDestStartOffset, KChunkShiftBy0, chTmp.iThread ) );
       
   471         TRACE_ASSERT_INFO( writeError == KErrNone, ( chTmp.iShP2PProtocolId | writeError << KClassIdentifierShift ) );
       
   472         C_TRACE( ( _T( "DP2PUserChannel::EmptyRxQueueDfc writing 0x%x k>u 0x%x 0x%x writeError %d length %d" ), &tmpDes, chTmp.iReceiveBufPtr, chTmp.iShP2PProtocolId, writeError, tmpDes.Length() ) );
       
   473         TP2PReq req( static_cast<TP2PAsyncRequest>( EP2PAsyncReceive ), writeError );
       
   474         if( chTmp.iP2PReqQueue->Add( req ) )
       
   475             {
       
   476             TRACE_ASSERT( !chTmp.iCompleteChannelRequestDfc->Queued() );
       
   477             CompleteChReqDfc( &chTmp );
       
   478             }
       
   479         MemApi::DeallocBlock( tmpDes );
       
   480         }
       
   481     else
       
   482         {
       
   483         C_TRACE( ( _T( "DP2PUserChannel::EmptyRxQueueDfc 0x%x 0x%x rx inactive or no message" ), &chTmp, chTmp.iShP2PProtocolId ) );
       
   484         }
       
   485     C_TRACE( ( _T( "DP2PUserChannel::EmptyRxQueueDfc 0x%x 0x%x<" ), &chTmp, chTmp.iShP2PProtocolId ) );
       
   486 
       
   487     }
       
   488 
       
   489 
       
   490 void DP2PUserChannel::ResetQueues(
       
   491         // None
       
   492         )
       
   493     {
       
   494 
       
   495     C_TRACE( ( _T( "DP2PUserChannel::ResetQueues 0x%x 0x%x>" ), this, iShP2PProtocolId ) );
       
   496     if( iRx )
       
   497         {
       
   498         C_TRACE( ( _T( "DP2PUserChannel::ResetQueues 0x%x 0x%x iRx 0x%x" ), this, iShP2PProtocolId, iRx ) );
       
   499         while( iRx->Count() )
       
   500             {
       
   501             MemApi::DeallocBlock( iRx->Get() );
       
   502             }
       
   503         }
       
   504     C_TRACE( ( _T( "DP2PUserChannel::ResetQueues 0x%x 0x%x<" ), this, iShP2PProtocolId ) );
       
   505 
       
   506     }
       
   507 
       
   508 void DP2PUserChannel::HandleAsyncRequest(
       
   509         TInt aRequest,
       
   510         TAny* a1
       
   511         )
       
   512     {
       
   513 
       
   514     C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest 0x%x 0x%x %d>" ), this, iShP2PProtocolId, aRequest ) );
       
   515     ASSERT_THREAD_CONTEXT_ALWAYS( ( EP2PIUserChannelfNotThreadContext4 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   516     TUint32* tablePtr = reinterpret_cast<TUint32*>( a1 );
       
   517     TRACE_ASSERT_INFO( tablePtr[ KFirstParam ], (TUint16)aRequest );
       
   518     TRequestStatus* requestStatus = reinterpret_cast<TRequestStatus*>( tablePtr[ KFirstParam ] );
       
   519     // If request already active.
       
   520     if( ( iP2PReqQueue->GetReq( static_cast<TP2PAsyncRequest>( aRequest ) ) ) )
       
   521         {
       
   522         // Fault if request is already pending and the request status pointer is different.
       
   523         // Fault prints 0-7bits: request, 8-15bits: ch number, 16-31bits: fault identifier
       
   524         // Assert cause request already active.
       
   525         TRACE_ASSERT_INFO( 0, ( EP2PUserChannelSameRequest | static_cast<TUint8>( iShP2PProtocolId ) << KProtocolIdShift | static_cast<TUint8>( aRequest ) << KExtraInfoShift ) );
       
   526         // Active object should not give same request object twice before completing the first one.
       
   527         ASSERT_PANIC_USER_THREAD_ALWAYS( iP2PReqQueue->GetReq( static_cast< TP2PAsyncRequest >( aRequest ) ) == requestStatus, iThread,
       
   528                                        ( EP2PUserChannelSameRequest2 | static_cast<TUint8>( iShP2PProtocolId ) << KProtocolIdShift | static_cast<TUint8>( aRequest ) << KExtraInfoShift  ) );
       
   529         }
       
   530     else
       
   531         {
       
   532         iP2PReqQueue->SetReq( static_cast<TP2PAsyncRequest>( aRequest ), requestStatus );
       
   533         switch ( aRequest )
       
   534             {
       
   535             case EP2PAsyncOpen:
       
   536                 {
       
   537                 C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest 0x%x 0x%x EP2PAsyncOpen" ), this, iShP2PProtocolId ) );
       
   538                 // Set open to pending to router, router completes it when the interconnection to other point is ready.
       
   539                 iRouterIf->Open( ~iShP2PProtocolId, this );
       
   540                 break;
       
   541                 }
       
   542             case EP2PAsyncReceive:
       
   543                 {
       
   544                 iReceiveBufPtr = reinterpret_cast<TAny*>( tablePtr[ KSecondParam ] );
       
   545                 C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest 0x%x 0x%x EP2PAsyncReceive 0x%x" ), this, iShP2PProtocolId, iReceiveBufPtr ) );
       
   546                 iEmptyRxQueueDfc->Enque();
       
   547                 break;
       
   548                 }
       
   549             case EP2PAsyncConnectionLost:
       
   550                 {
       
   551                 C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest 0x%x 0x%x EP2PAsyncConnectionLost" ), this, iShP2PProtocolId ) );
       
   552                 // If the connection is already lost when function is called return immediately.
       
   553                 // This might happend in between calls to ::Open and ::NotifyClose
       
   554                 if( !iRouterIf->ConnectionExist( iShP2PProtocolId ) )
       
   555                     {
       
   556                     EnqueChannelRequestCompleteDfc( EP2PAsyncConnectionLost, KErrNotReady );
       
   557                     ResetQueues();
       
   558                     //Closing( iP2PProtocolId );
       
   559                     }
       
   560                 break;
       
   561                 }
       
   562             default:
       
   563                 {
       
   564                 ASSERT_RESET_ALWAYS( 0, ( EP2PUserChannelWrongRequest5 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   565                 break;
       
   566                 }
       
   567             }
       
   568         }
       
   569     C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest 0x%x 0x%x %d<" ), this, iShP2PProtocolId, aRequest ) );
       
   570 
       
   571     }
       
   572 
       
   573 TInt DP2PUserChannel::HandleSyncRequest(
       
   574         TInt aRequest,
       
   575         TAny* a1
       
   576         )
       
   577     {
       
   578 
       
   579     C_TRACE( ( _T( "DP2PUserChannel::HandleSyncRequest 0x%x 0x%x %d>" ), this, iShP2PProtocolId, aRequest ) );
       
   580     ASSERT_THREAD_CONTEXT_ALWAYS( ( EP2PIUserChannelfNotThreadContext5 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   581     TInt error( KErrNotSupported );
       
   582     switch( aRequest )
       
   583         {
       
   584         case EP2PClose:
       
   585             {
       
   586             C_TRACE( ( _T( "DP2PUserChannel::HandleSyncRequest 0x%x 0x%x EP2PClose" ), this, iShP2PProtocolId ) );
       
   587             Closing();
       
   588             error = KErrNone;
       
   589             break;
       
   590             }
       
   591         case EP2PSend:
       
   592                 {
       
   593                 C_TRACE( ( _T( "DP2PUserChannel::HandleSyncRequest 0x%x 0x%x EP2PSend" ), this, iShP2PProtocolId ) );
       
   594                 TUint32* tablePtr = reinterpret_cast<TUint32*>( a1 );
       
   595                 TAny* firstParam = reinterpret_cast<TAny*>( tablePtr[ KFirstParam ] );
       
   596                 TRACE_ASSERT_INFO( firstParam, ( (TUint8)iShP2PProtocolId << KProtocolIdShift | ( EP2PUserChannelNullParam2 | EDP2PUserChannelTraceId << KClassIdentifierShift ) ) );
       
   597                 TInt msgLength( Kern::ThreadGetDesLength( iThread, firstParam ) );
       
   598                 C_TRACE( ( _T( "DP2PUserChannel::HandleSyncRequest 0x%x 0x%x EP2PSend 0x%x %d" ), this, iShP2PProtocolId, firstParam, msgLength ) );
       
   599                 if( msgLength > 0 && msgLength < KP2PMaximumSendSize )
       
   600                     {
       
   601                     TDes8& sendBlock = MemApi::AllocBlock( msgLength );
       
   602                     ASSERT_RESET_ALWAYS( KErrNone == Kern::ThreadDesRead( iThread, firstParam, sendBlock, 0, KChunkShiftBy0 ), ( EP2PUserChannelDesReadFailed | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   603                     TRACE_ASSERT_INFO( sendBlock.Length() == msgLength, (TUint8)iShP2PProtocolId << KProtocolIdShift );
       
   604                     C_TRACE( ( _T( "DP2PUserChannel::HandleAsyncRequest EP2PAsyncSend 0x%x 0x%x 0x%x" ), this, iShP2PProtocolId, &sendBlock ) );
       
   605                     error = iRouterIf->Send( sendBlock, iShP2PProtocolId );
       
   606                     }
       
   607                 else
       
   608                     {
       
   609                     error = ( msgLength > KP2PMaximumSendSize ) ? KErrNoMemory : KErrBadDescriptor;
       
   610                     TRACE_ASSERT_INFO( 0, (TUint8)iShP2PProtocolId << KProtocolIdShift | (TUint16)msgLength );
       
   611                     }
       
   612                 break;
       
   613                 }
       
   614         default:
       
   615             {
       
   616             ASSERT_RESET_ALWAYS( 0, ( EP2PUserChannelWrongRequest6 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   617             break;
       
   618             }
       
   619         }
       
   620     C_TRACE( ( _T( "DP2PUserChannel::HandleSyncRequest 0x%x 0x%x %d ret %d<" ), this, iShP2PProtocolId, aRequest, error ) );
       
   621     return error;
       
   622 
       
   623     }
       
   624 
       
   625 void DP2PUserChannel::DoCancel(
       
   626         TInt aRequest,
       
   627         TInt aMask )
       
   628     {
       
   629 
       
   630     C_TRACE( ( _T( "DP2PUserChannel::DoCancel 0x%x 0x%x>" ), this, iShP2PProtocolId ) );
       
   631     switch( aMask&aRequest )
       
   632         {
       
   633         case EP2PAsyncReceive:
       
   634             {
       
   635             C_TRACE( ( _T( "DP2PUserChannel::DoCancel 0x%x 0x%x EP2PAsyncReceive 0x%x " ), this, iShP2PProtocolId, iReceiveBufPtr ) );
       
   636             iReceiveBufPtr = NULL;
       
   637             break;
       
   638             }
       
   639         case EP2PAsyncOpen:
       
   640             {
       
   641             // Just complete with cancel
       
   642             C_TRACE( ( _T( "DP2PUserChannel::DoCancel 0x%x 0x%x EP2PAsyncOpen" ), this, iShP2PProtocolId ) );
       
   643             TInt err( Kern::MutexWait( *iShP2PProtocolIdMutex ) );
       
   644             ASSERT_RESET_ALWAYS( ( KErrNone == err ), ( EP2PUserChannelMutexWaitFailed4 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   645             Close( ~iShP2PProtocolId );
       
   646             Kern::MutexSignal( *iShP2PProtocolIdMutex );
       
   647             break;
       
   648             }
       
   649         default:
       
   650             {
       
   651             ASSERT_RESET_ALWAYS( 0, ( EP2PUserChannelWrongRequest7 | EDP2PUserChannelTraceId << KClassIdentifierShift ) );
       
   652             break;
       
   653             }
       
   654         }
       
   655     EnqueChannelRequestCompleteDfc( aMask&aRequest, KErrCancel );
       
   656     C_TRACE( ( _T( "DP2PUserChannel::DoCancel 0x%x 0x%x<" ), this, iShP2PProtocolId ) );
       
   657 
       
   658     }
       
   659 
       
   660 // Internal class start
       
   661 DP2PUserChannel::TP2PReq::TP2PReq()
       
   662 :iRequest( EP2PLastAsyncRequest ), iCompleteStatus( KRequestPending )
       
   663     {
       
   664     }
       
   665 
       
   666 DP2PUserChannel::TP2PReq::TP2PReq( TP2PAsyncRequest aReq, TInt aStat  )
       
   667 :iRequest( aReq), iCompleteStatus( aStat )
       
   668 {
       
   669     ASSERT_RESET_ALWAYS( iRequest != EP2PLastAsyncRequest, ( EP2PUserChannelReqQueueOutOfSync | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   670     ASSERT_RESET_ALWAYS( iCompleteStatus != KRequestPending, ( EP2PUserChannelReqQueueOutOfSync1 | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   671 }
       
   672 
       
   673 DP2PUserChannel::DP2PReqQueue::DP2PReqQueue()
       
   674     {
       
   675     C_TRACE( ( _T( "DP2PReqQueue::DP2PReqQueue 0x%x %d>" ), this ) );
       
   676     iQueueMutex = new NFastMutex();
       
   677     ASSERT_RESET_ALWAYS( iQueueMutex, ( EP2PUserChannelReqQueueMemoryAllocFailure | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   678     iSize = EP2PLastAsyncRequest;
       
   679     ASSERT_RESET_ALWAYS( ( iSize > 0 ), ( EP2PUserChannelReqQueueOutOfSync2 | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   680     iShInputIndex = 0;
       
   681     iShOutputIndex = 0;
       
   682     iShCount = 0;
       
   683     for( TInt i( 0 ); i < iSize; ++i )
       
   684         {
       
   685         iShReqRingBuffer[ i ].iRequest = EP2PLastAsyncRequest;
       
   686         iShReqRingBuffer[ i ].iCompleteStatus = KRequestPending;
       
   687         iShReqList[ i ] = NULL;
       
   688         }    
       
   689     C_TRACE( ( _T( "DP2PReqQueue::DP2PReqQueue 0x%x<" ), this ) );
       
   690     }
       
   691 
       
   692 DP2PUserChannel::DP2PReqQueue::~DP2PReqQueue()
       
   693     {
       
   694     C_TRACE( ( _T( "DP2PReqQueue::~DP2PReqQueue 0x%x %d>" ), this, iShCount ) );
       
   695     // NOTE! This don't deallocate the blocks from the allocated memory just the pointers!
       
   696     ASSERT_RESET_ALWAYS( iShCount == 0, ( EP2PUserChannelReqQueueOutOfSync3 | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   697     for( TInt i( 0 ); i < iSize; ++i )
       
   698         {
       
   699         iShReqRingBuffer[ i ].iRequest = EP2PLastAsyncRequest;
       
   700         iShReqRingBuffer[ i ].iCompleteStatus = KRequestPending;
       
   701         iShReqList[ i ] = NULL;
       
   702         }
       
   703     iSize = 0;
       
   704     iShInputIndex = 0;
       
   705     iShOutputIndex = 0;
       
   706     iShCount = 0;
       
   707     if( iQueueMutex )
       
   708         {
       
   709         C_TRACE( ( _T( "DP2PReqQueue::~DP2PReqQueue iQueueMutex" ) ) );
       
   710         delete iQueueMutex;
       
   711         iQueueMutex = NULL;
       
   712         }
       
   713     C_TRACE( ( _T( "DP2PReqQueue::~DP2PReqQueue 0x%x<" ), this ) );
       
   714     }
       
   715 
       
   716 /* 
       
   717 * In case of queue overflow throw kern::fault
       
   718 */
       
   719 TBool DP2PUserChannel::DP2PReqQueue::Add( TP2PReq aReq )
       
   720     {
       
   721     C_TRACE( ( _T( "DP2PReqQueue::Add 0x%x %d %d %d %d>" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex ) );
       
   722     TBool ok( EFalse );
       
   723     NKern::FMWait( iQueueMutex );
       
   724     // If queue get's overfilled throw kernel fault.
       
   725     ASSERT_RESET_ALWAYS( ( iShCount < iSize ), ( EP2PUserChannelReqQueueOutOfSync4 | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   726     ASSERT_RESET_ALWAYS( EP2PLastAsyncRequest > aReq.iRequest, ( EP2PUserChannelReqQueueOverTheLimits | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   727     if( iShReqList[ aReq.iRequest ] )
       
   728         {
       
   729         // Place the buffer into the queue.
       
   730         iShReqRingBuffer[ iShInputIndex ] = aReq;
       
   731         // Adjust input pointer.
       
   732         iShInputIndex = ( ( iShInputIndex + 1 ) % iSize );
       
   733         // Remember the amount of the requests in the queue.
       
   734         iShCount++;
       
   735         ok = ETrue;
       
   736         }
       
   737     NKern::FMSignal( iQueueMutex );
       
   738     C_TRACE( ( _T( "DP2PReqQueue::Add 0x%x %d %d %d %d %d<" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex, ok ) );
       
   739     return ok;
       
   740     }
       
   741 
       
   742 /*
       
   743 *Returns the first pointer ( iShOutputIndex ) from the ring buffer.
       
   744 */
       
   745 TBool DP2PUserChannel::DP2PReqQueue::Empty()
       
   746     {
       
   747     C_TRACE( ( _T( "DP2PReqQueue::Empty 0x%x %d<>" ), this, iShCount ) );
       
   748     return iShCount == 0 ?  ETrue : EFalse;
       
   749 
       
   750     }
       
   751 
       
   752 /*
       
   753 *Returns the first pointer ( iShOutputIndex ) from the ring buffer.
       
   754 */
       
   755 DP2PUserChannel::TP2PReq DP2PUserChannel::DP2PReqQueue::Get()
       
   756     {
       
   757     C_TRACE( ( _T( "DP2PReqQueue::Get 0x%x %d %d %d %d>" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex ) );
       
   758     NKern::FMWait( iQueueMutex );
       
   759     // If queue is empty.
       
   760     ASSERT_RESET_ALWAYS( ( iShCount > 0 ), ( EP2PUserChannelReqQueueOutOfSync5 | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   761     // Get the buffer from the queue.
       
   762     ASSERT_RESET_ALWAYS( EP2PLastAsyncRequest > iShOutputIndex, ( EP2PUserChannelReqQueueOverTheLimits2 | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   763     TP2PReq temp = iShReqRingBuffer[ iShOutputIndex ];
       
   764     // Set buffer location to NULL.
       
   765     iShReqRingBuffer[ iShOutputIndex ].iRequest = EP2PLastAsyncRequest;
       
   766     iShReqRingBuffer[ iShOutputIndex ].iCompleteStatus = KRequestPending;
       
   767     // Adjust output pointer.
       
   768     iShOutputIndex = ( ( iShOutputIndex + 1 ) % iSize );
       
   769     // Remember the amount of the requests in the queue.
       
   770     iShCount--;
       
   771     NKern::FMSignal( iQueueMutex );
       
   772     ASSERT_RESET_ALWAYS( temp.iRequest != EP2PLastAsyncRequest, ( EP2PUserChannelReqQueueOutOfSync6 | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   773     ASSERT_RESET_ALWAYS( temp.iCompleteStatus != KRequestPending, ( EP2PUserChannelReqQueueOutOfSync7 | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   774     C_TRACE( ( _T( "DQueue::Get 0x%x %d %d %d %d<" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex ) );
       
   775     return temp;
       
   776     }
       
   777 
       
   778 /*
       
   779 * Set req active / deactive. Default deactive.
       
   780 */
       
   781 void DP2PUserChannel::DP2PReqQueue::SetReq( TP2PAsyncRequest aReqToSet, TRequestStatus* aStatus )
       
   782     {
       
   783     C_TRACE( ( _T( "DP2PReqQueue::SetReq 0x%x %d 0x%x>" ), this, aReqToSet, aStatus ) );
       
   784     ASSERT_RESET_ALWAYS( aReqToSet < EP2PLastAsyncRequest, ( EP2PUserChannelReqQueueWrongRequest | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   785     // If setting same request twice.
       
   786     C_TRACE( ( _T( "DP2PReqQueue::SetReq 0x%x %d 0x%x 0x%x TBR" ), this, aReqToSet, aStatus, iShReqList[ aReqToSet ] ) );
       
   787     ASSERT_RESET_ALWAYS( !( !iShReqList[ aReqToSet ] && aStatus == NULL ), EP2PUserChannelReqQueueCommon );
       
   788     iShReqList[ aReqToSet ] = aStatus;
       
   789     C_TRACE( ( _T( "DP2PReqQueue::SetReq 0x%x %d 0x%x<" ), this, aReqToSet, aStatus ) );
       
   790     }
       
   791 
       
   792 /*
       
   793 * Set req active / deactive. Default deactive.
       
   794 */
       
   795 TRequestStatus* DP2PUserChannel::DP2PReqQueue::GetReq( TP2PAsyncRequest aReqToGet )
       
   796     {
       
   797     ASSERT_RESET_ALWAYS( aReqToGet < EP2PLastAsyncRequest, ( EP2PUserChannelReqQueueWrongRequest2 | EDP2PReqQueueId << KClassIdentifierShift ) );
       
   798     C_TRACE( ( _T( "DP2PReqQueue::GetReq 0x%x 0x%x %d<>" ), this, iShReqList[ aReqToGet ], aReqToGet ) );
       
   799     TRequestStatus* tmpStatus = iShReqList[ aReqToGet ];
       
   800     return tmpStatus;
       
   801     }
       
   802 // Internal class end