connectivitylayer/isce/p2prouter_dll/src/p2prouter.cpp
changeset 0 63b37f68c1ce
child 8 6295dc2169f3
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 <kernel.h>             // For Kern
       
    21 
       
    22 #include "p2prouter.h"          // For DP2PRouter
       
    23 #include "memapi.h"             // For MemApi
       
    24 #include "p2proutertrace.h"     // For C_TRACE..
       
    25 #include "p2pdevice.h"          // For DP2PDevice
       
    26 #include "mlinkmuxif.h"         // For MLinkMuxIf
       
    27 #include "trxdefs.h"            // For ETrx...
       
    28 #include "p2pinternaldefs.h"    // For EP2PAsyncOpen
       
    29 
       
    30 // Faults
       
    31 enum TP2PRouterFaults
       
    32     {
       
    33     EP2PRouterMemAllocFailure = 0x00,
       
    34     EP2PRouterMemAllocFailure1,
       
    35     EP2PRouterMemAllocFailure2,
       
    36     EP2PRouterMemAllocFailure3,
       
    37     EP2PRouterMemAllocFailure4,
       
    38     EP2PRouterMemAllocFailure5,
       
    39     EP2PRouterMemAllocFailure6,
       
    40     EP2PRouterMemAllocFailure7,
       
    41     EP2PRouterMemAllocFailure8,
       
    42     EP2PRouterOverTheLimits,
       
    43     EP2PRouterWrongRequest,
       
    44     EP2PRouterWrongRequest2,
       
    45     EP2PRouterNullParam,
       
    46     EP2PRouterWrongParam,
       
    47     EP2PRouterWrongParam2,
       
    48     EP2PRouterWrongParam3,
       
    49     EP2PRouterWrongParam4,
       
    50     EP2PRouterWrongParam5,
       
    51     EP2PRouterWrongParam6,
       
    52     EP2PRouterWrongParam7,
       
    53     EP2PRouterWrongParam8,
       
    54     };
       
    55 
       
    56 const TInt KDfcPriority( 5 );
       
    57 const TInt KDefaultDfcThreadPriority( 27 );
       
    58 
       
    59 _LIT( KP2PDfcQThreadName, "P2PRouter" );
       
    60 _LIT( KP2PLddDfcQThreadName, "P2PUserChannel" );
       
    61 TDfcQue* DP2PRouter::iP2PDfcQueList[ EAmountOfP2PDfcThreads ] = { NULL, NULL };
       
    62 DP2PRouter* DP2PRouter::iSelfPtr = NULL;
       
    63 
       
    64 DP2PRouter::DP2PRouter(
       
    65         // None
       
    66         )
       
    67     {
       
    68 
       
    69     C_TRACE( ( _T( "DP2PRouter::DP2PRouter>" ) ) );
       
    70     TInt err = Kern::DfcQCreate( iP2PDfcQueList[ MP2PChRouterIf::EP2PDfcThread ], KDefaultDfcThreadPriority, &KP2PDfcQThreadName );
       
    71     ASSERT_RESET_ALWAYS( iP2PDfcQueList[ MP2PChRouterIf::EP2PDfcThread ], EP2PRouterMemAllocFailure );
       
    72     err = Kern::DfcQCreate( iP2PDfcQueList[ MP2PChRouterIf::EP2PLddDfcThread ], KDefaultDfcThreadPriority, &KP2PLddDfcQThreadName );
       
    73     ASSERT_RESET_ALWAYS( iP2PDfcQueList[ MP2PChRouterIf::EP2PLddDfcThread ], EP2PRouterMemAllocFailure1 );
       
    74     iInitDfc = new TDfc( InitDfc, this, iP2PDfcQueList[ MP2PChRouterIf::EP2PDfcThread ], KDfcPriority );
       
    75     ASSERT_RESET_ALWAYS( iInitDfc, EP2PRouterMemAllocFailure2 );
       
    76     iInitDfc->Enque();
       
    77     C_TRACE( ( _T( "DP2PRouter::DP2PRouter<" ) ) );
       
    78 
       
    79     }
       
    80 
       
    81 DP2PRouter::~DP2PRouter(
       
    82         // None
       
    83         )
       
    84     {
       
    85 
       
    86     C_TRACE( ( _T( "DP2PRouter::~DP2PRouter>" ) ) );
       
    87     iSelfPtr = NULL;
       
    88     delete iShChannelTableFastMutex;
       
    89     iShChannelTableFastMutex = NULL;
       
    90     // owning so deleting
       
    91     for( TInt i( 0 ); i < EP2PAmountOfProtocols; i++ )
       
    92         {
       
    93         MP2PRouterLinkIf* temp = iLinksArray[ i ];
       
    94         temp->Release();
       
    95         temp = NULL;
       
    96         iLinksArray[ i ] = NULL;
       
    97         }
       
    98     delete []iLinksArray;
       
    99     delete []iP2PDfcQueList;
       
   100     iInitDfc->Cancel();
       
   101     delete iInitDfc;
       
   102     iInitDfc = NULL;
       
   103     iTrxPrecentDfc->Cancel();
       
   104     delete iTrxPrecentDfc;
       
   105     iTrxPrecentDfc = NULL;
       
   106     iTrxNotPrecentDfc->Cancel();
       
   107     delete iTrxNotPrecentDfc;
       
   108     iTrxNotPrecentDfc = NULL;
       
   109     C_TRACE( ( _T( "DP2PRouter::~DP2PRouter<" ) ) );
       
   110 
       
   111     }
       
   112 
       
   113 // From MP2PLinkRouterIf start
       
   114 
       
   115 // Called with FM held, no blocking no nesting, allocation etc.. just enque dfc.
       
   116 void DP2PRouter::NotifyTrxPresenceEnqueDfc(
       
   117         TBool aPresent
       
   118         )
       
   119     {
       
   120 
       
   121     // No traces allowed due to no blocking.
       
   122     if( aPresent )
       
   123         {
       
   124         iTrxPrecentDfc->Enque();
       
   125         }
       
   126     else
       
   127         {
       
   128         iTrxNotPrecentDfc->Enque();
       
   129         }
       
   130 
       
   131     }
       
   132 
       
   133 // Called in some thread contextes
       
   134 void DP2PRouter::Receive(
       
   135         TDes8& aMsg,
       
   136         const TUint8 aProtocolId
       
   137         )
       
   138     {
       
   139 
       
   140     C_TRACE( ( _T( "DP2PRouter::Receive 0x%x %d>" ), &aMsg, aProtocolId ) );
       
   141     ASSERT_RESET_ALWAYS( aProtocolId < EP2PAmountOfProtocols, ( EP2PRouterWrongParam | EDP2PRouterTraceId << KClassIdentifierShift ) );
       
   142     NKern::FMWait( iShChannelTableFastMutex );
       
   143     MP2PRouterChIf* channel = iShChannelTable[ aProtocolId ].iChannel;
       
   144     if( channel )
       
   145         {
       
   146         NKern::FMSignal( iShChannelTableFastMutex );
       
   147         // This functions calling thread shall content with channels thread.
       
   148         channel->ReceiveMsg( aMsg );
       
   149         }
       
   150     else
       
   151         {
       
   152         NKern::FMSignal( iShChannelTableFastMutex );
       
   153         // Discard incoming messages without a receiving point channel open.
       
   154         TRACE_ASSERT_ALWAYS;
       
   155         MemApi::DeallocBlock( aMsg );
       
   156         }
       
   157     C_TRACE( ( _T( "DP2PRouter::Receive 0x%x %d<" ), &aMsg, aProtocolId ) );
       
   158 
       
   159     }
       
   160 
       
   161 // From MP2PLinkRouterIf end
       
   162 
       
   163 // From MP2PChRouterIf start
       
   164 void DP2PRouter::Open(
       
   165         const TUint8 aProtocolId,
       
   166         MP2PRouterChIf* aCallback
       
   167         )
       
   168     {
       
   169 
       
   170     C_TRACE( ( _T( "DP2PRouter::Open %d>" ), aProtocolId ) );
       
   171     // TODO :  assert to check always called in p2p extension thread context
       
   172     ASSERT_RESET_ALWAYS( aCallback, EP2PRouterNullParam );
       
   173     ASSERT_RESET_ALWAYS( aProtocolId < EP2PAmountOfProtocols, ( EP2PRouterWrongParam2 | EDP2PRouterTraceId << KClassIdentifierShift ) );
       
   174     ASSERT_RESET_ALWAYS( iLinksArray[ aProtocolId ], ( EP2PRouterWrongParam3 | EDP2PRouterTraceId << KClassIdentifierShift ) );
       
   175     if( iLinksArray[ aProtocolId ]->TrxPresent() )
       
   176         {
       
   177         C_TRACE( ( _T( "DP2PRouter::Open ok %d" ), aProtocolId ) );
       
   178         NKern::FMWait( iShChannelTableFastMutex );
       
   179         // Channel with the same protocol id is already opened or waiting to complete the opening.
       
   180         if( iShChannelTable[ aProtocolId ].iChannel || iShChannelTable[ aProtocolId ].iWaitingChannel )
       
   181             {
       
   182             NKern::FMSignal( iShChannelTableFastMutex );
       
   183             // If another channel tries to open already open channel.
       
   184             TRACE_WARNING( iShChannelTable[ aProtocolId ].iChannel == aCallback, (TUint8)aProtocolId );
       
   185             aCallback->EnqueChannelRequestCompleteDfc( EP2PAsyncOpen, KErrInUse );//TODO: synch user and kernel APIs return values
       
   186             }
       
   187         else
       
   188             {
       
   189             iShChannelTable[ aProtocolId ].iChannel = aCallback;
       
   190             NKern::FMSignal( iShChannelTableFastMutex );
       
   191             aCallback->EnqueChannelRequestCompleteDfc( EP2PAsyncOpen, KErrNone );
       
   192             }
       
   193         }
       
   194     else
       
   195         {
       
   196         C_TRACE( ( _T( "DP2PRouter::Open pending %d" ), aProtocolId ) );
       
   197         ASSERT_RESET_ALWAYS( !iShChannelTable[ aProtocolId ].iWaitingChannel, EP2PRouterWrongRequest );
       
   198         NKern::FMWait( iShChannelTableFastMutex );
       
   199         iShChannelTable[ aProtocolId ].iWaitingChannel = aCallback;
       
   200         NKern::FMSignal( iShChannelTableFastMutex );
       
   201         }
       
   202     C_TRACE( ( _T( "DP2PRouter::Open %d<" ), aProtocolId ) );
       
   203 
       
   204     }
       
   205 
       
   206 void DP2PRouter::Close(
       
   207         const TUint8 aProtocolId
       
   208         )
       
   209     {
       
   210 
       
   211     C_TRACE( ( _T( "DP2PRouter::Close %d>" ), aProtocolId ) );
       
   212     // TODO :  assert to check always called in p2p extension thread context
       
   213     ASSERT_RESET_ALWAYS( aProtocolId < EP2PAmountOfProtocols, ( EP2PRouterWrongParam4 | EDP2PRouterTraceId << KClassIdentifierShift ) );
       
   214     NKern::FMWait( iShChannelTableFastMutex );
       
   215     if( iShChannelTable[ aProtocolId ].iChannel || iShChannelTable[ aProtocolId ].iWaitingChannel )
       
   216         {
       
   217         iShChannelTable[ aProtocolId ].iChannel = NULL;
       
   218         iShChannelTable[ aProtocolId ].iWaitingChannel = NULL;
       
   219         }
       
   220     NKern::FMSignal( iShChannelTableFastMutex );
       
   221     C_TRACE( ( _T( "DP2PRouter::Close<" ) ) );
       
   222 
       
   223     }
       
   224 
       
   225 // Shall be called from P2P ext router thread context only.
       
   226 TBool DP2PRouter::ConnectionExist(
       
   227         const TUint8 aProtocolId
       
   228         )
       
   229     {
       
   230 
       
   231     C_TRACE( ( _T( "DP2PRouter::ConnectionExists %d<>" ), aProtocolId ) );
       
   232     ASSERT_RESET_ALWAYS( aProtocolId < EP2PAmountOfProtocols, ( EP2PRouterWrongParam5 | EDP2PRouterTraceId << KClassIdentifierShift ) );
       
   233     ASSERT_RESET_ALWAYS( iLinksArray[ aProtocolId ], ( EP2PRouterWrongParam6 | EDP2PRouterTraceId << KClassIdentifierShift ) );
       
   234     return iLinksArray[ aProtocolId ]->TrxPresent();
       
   235 
       
   236     }
       
   237 
       
   238 TDfcQue* DP2PRouter::GetDfcThread(
       
   239         const TP2PDfcThread anIndex
       
   240         )
       
   241     {
       
   242 
       
   243     C_TRACE( ( _T( "DP2PRouter::GetDfcThread<>" ) ) );
       
   244     ASSERT_RESET_ALWAYS( anIndex < EAmountOfP2PDfcThreads, EP2PRouterWrongRequest2 );
       
   245     ASSERT_RESET_ALWAYS( iP2PDfcQueList[ anIndex ], EP2PRouterMemAllocFailure6 );
       
   246     return iP2PDfcQueList[ anIndex ];
       
   247 
       
   248     }
       
   249 
       
   250 
       
   251 MP2PChRouterIf* MP2PChRouterIf::GetIf()
       
   252     {
       
   253 
       
   254     C_TRACE( ( _T( "MP2PChRouterIf::GetIf<>" ) ) );
       
   255     return DP2PRouter::GetRouter();
       
   256 
       
   257     }
       
   258 
       
   259 TInt DP2PRouter::Send(
       
   260         TDes8& aMessage,
       
   261         const TUint8 aProtocolId
       
   262         )
       
   263     {
       
   264 
       
   265     C_TRACE( ( _T( "DP2PRouter::Send 0x%x>" ), &aMessage ) );
       
   266     // TODO :  assert to check always called in p2p extension thread context
       
   267     // Inside link array limits, if not programmer error.
       
   268     ASSERT_RESET_ALWAYS( aProtocolId < EP2PAmountOfProtocols, ( EP2PRouterWrongParam7 | EDP2PRouterTraceId << KClassIdentifierShift ) );
       
   269     MP2PRouterLinkIf* link = iLinksArray[ aProtocolId ];
       
   270     ASSERT_RESET_ALWAYS( link, ( EP2PRouterWrongParam8 | EDP2PRouterTraceId << KClassIdentifierShift ) );
       
   271     TInt sendResult( KErrNone );
       
   272     if( link->TrxPresent() )
       
   273         {
       
   274         link->Send( aMessage );
       
   275         }
       
   276     else
       
   277         {
       
   278         TRACE_ASSERT_ALWAYS;
       
   279         // Discard send block if connection lost
       
   280         MemApi::DeallocBlock( aMessage );
       
   281         sendResult = KErrNotReady;
       
   282         }
       
   283     C_TRACE( ( _T( "DP2PRouter::Send 0x%x %d<" ), &aMessage, sendResult ) );
       
   284     return sendResult;
       
   285 
       
   286     }
       
   287 // From MP2PChRouterIf end
       
   288 
       
   289 // privates start
       
   290 void DP2PRouter::Init(
       
   291         // None
       
   292         )
       
   293     {
       
   294 
       
   295     C_TRACE( ( _T( "DP2PRouter::Init>" ) ) );
       
   296     iLinksArray = new MP2PRouterLinkIf*[ EP2PAmountOfProtocols ];
       
   297     ASSERT_RESET_ALWAYS( iLinksArray, ( EP2PRouterOverTheLimits | EDP2PRouterTraceId << KClassIdentifierShift ) );
       
   298     // Initialize links
       
   299     for( TInt i( 0 ); i < EP2PAmountOfProtocols; i++ )
       
   300         {
       
   301         iLinksArray[ i ] = NULL;
       
   302         C_TRACE( ( _T( "DP2PRouter::DP2PRouter %d" ), i ) );
       
   303         }
       
   304     // Initialize channels
       
   305     for( TInt i( 0 ); i < EP2PAmountOfProtocols; ++i )
       
   306         {
       
   307         iShChannelTable[ i ].iChannel = NULL;
       
   308         iShChannelTable[ i ].iWaitingChannel = NULL;
       
   309         }
       
   310     // TODO:do more clever way to create links.
       
   311     // Configuration of links.
       
   312     iLinksArray[ EP2PRpc ] = MP2PRouterLinkIf::CreateLinkF( this, EP2PRpc, ETrxTest );
       
   313     iLinksArray[ EP2PTest ] = MP2PRouterLinkIf::CreateLinkF( this, EP2PTest, ETrxTest );
       
   314     iLinksArray[ EP2PTest2 ] = MP2PRouterLinkIf::CreateLinkF( this, EP2PTest2, ETrxTest );
       
   315     iTrxPrecentDfc = new TDfc( TrxPrecentDfc, this, iP2PDfcQueList[ MP2PChRouterIf::EP2PDfcThread ], KDfcPriority );
       
   316     iTrxNotPrecentDfc = new TDfc( TrxNotPrecentDfc, this, iP2PDfcQueList[ MP2PChRouterIf::EP2PDfcThread ], KDfcPriority );
       
   317     iShChannelTableFastMutex = new NFastMutex();
       
   318     ASSERT_RESET_ALWAYS( ( iTrxNotPrecentDfc && iTrxPrecentDfc && iShChannelTableFastMutex ), EP2PRouterMemAllocFailure4 );
       
   319     iSelfPtr = this;
       
   320     C_TRACE( ( _T( "DP2PRouter::Init<" ) ) );
       
   321 
       
   322     }
       
   323 
       
   324 void DP2PRouter::InitDfc(
       
   325         TAny* aPtr
       
   326         )
       
   327     {
       
   328 
       
   329     C_TRACE( ( _T( "DP2PRouter::InitDfc>" ) ) );
       
   330     DP2PRouter* self = reinterpret_cast<DP2PRouter*>( aPtr );
       
   331     self->Init();
       
   332     C_TRACE( ( _T( "DP2PRouter::InitDfc<" ) ) );
       
   333 
       
   334     }
       
   335 
       
   336 void DP2PRouter::TrxPrecentDfc(
       
   337         TAny* aPtr
       
   338         )
       
   339     {
       
   340 
       
   341     C_TRACE( ( _T( "DP2PRouter::TrxPrecentDfc>" ) ) );
       
   342     DP2PRouter& self = *reinterpret_cast<DP2PRouter*>( aPtr );
       
   343     // Notify all the protocols channel objects of the change of the presence.
       
   344     for( TUint8 i( 0 ); i < EP2PAmountOfProtocols; i++ )
       
   345         {
       
   346         TUint8 protocolId( i );
       
   347         C_TRACE( ( _T( "DP2PRouter::TrxPrecentDfc Trx present id=0x%x" ), protocolId ) );
       
   348         NKern::FMWait( self.iShChannelTableFastMutex );
       
   349         MP2PRouterChIf* waitingChannel = self.iShChannelTable[ protocolId ].iWaitingChannel;
       
   350         if( waitingChannel )
       
   351             {
       
   352             self.iShChannelTable[ protocolId ].iChannel = waitingChannel;
       
   353             NKern::FMSignal( self.iShChannelTableFastMutex );
       
   354             C_TRACE( ( _T( "DP2PRouter::TrxPrecentDfc channel open waiting %d>" ), protocolId ) );
       
   355             waitingChannel->EnqueChannelRequestCompleteDfc( EP2PAsyncOpen, KErrNone );
       
   356             }
       
   357         else
       
   358             {
       
   359             // No need to inform presence, when connection is lost it is closed too and must be opened again.
       
   360             NKern::FMSignal( self.iShChannelTableFastMutex );
       
   361             C_TRACE( ( _T( "DP2PRouter::TrxPrecentDfc nothing waiting %d>" ), protocolId ) );
       
   362             }
       
   363         }
       
   364     C_TRACE( ( _T( "DP2PRouter::TrxPrecentDfc<" )) );
       
   365 
       
   366     }
       
   367 
       
   368 void DP2PRouter::TrxNotPrecentDfc(
       
   369         TAny* aPtr
       
   370         )
       
   371     {
       
   372 
       
   373     C_TRACE( ( _T( "DP2PRouter::TrxNotPrecentDfc>" ) ) );
       
   374     DP2PRouter& self = *reinterpret_cast<DP2PRouter*>( aPtr );
       
   375     // Notify all the protocols channel objects of the change of the presence.
       
   376     for( TUint8 i( 0 ); i < EP2PAmountOfProtocols; i++ )
       
   377         {
       
   378         TUint8 protocolId( i );
       
   379         C_TRACE( ( _T( "DP2PRouter::TrxNotPrecentDfc Trx lost id=0x%x" ), protocolId ) );
       
   380         // Notifying channel that connection is lost and discard any received messages.
       
   381         NKern::FMWait( self.iShChannelTableFastMutex );
       
   382         MP2PRouterChIf* channel = self.iShChannelTable[ protocolId ].iChannel;
       
   383         if( channel )
       
   384             {
       
   385             NKern::FMSignal( self.iShChannelTableFastMutex );
       
   386             C_TRACE( ( _T( "DP2PRouter::TrxNotPrecentDfc Trx lost channel found for id=0x%x" ), protocolId ) );
       
   387             channel->ConnectionLost();
       
   388             }
       
   389         else
       
   390             {
       
   391             NKern::FMSignal( self.iShChannelTableFastMutex );
       
   392             C_TRACE( ( _T( "DP2PRouter::TrxNotPrecentDfc Trx lost no channel found for id=0x%x" ), protocolId ) );
       
   393             }
       
   394         }
       
   395     C_TRACE( ( _T( "DP2PRouter::TrxNotPrecentDfc<" )) );
       
   396 
       
   397     }
       
   398 // privates end
       
   399 
       
   400 DECLARE_STANDARD_EXTENSION()
       
   401     {
       
   402 
       
   403     Kern::Printf( "P2Prouter extension>" );
       
   404     // Create a container extension
       
   405     DP2PRouter* extension = new DP2PRouter();
       
   406     TRACE_ASSERT( extension );
       
   407     Kern::Printf( "P2Prouter extension<" );
       
   408     return extension ? KErrNone : KErrNoMemory;
       
   409 
       
   410     }
       
   411 
       
   412 DECLARE_EXTENSION_LDD()
       
   413     {
       
   414 
       
   415     Kern::Printf( "P2Prouter ldd>" );
       
   416     DLogicalDevice* device = new DP2PDevice;
       
   417     TRACE_ASSERT( device );
       
   418     Kern::Printf( "P2Prouter ldd 0x%x<", device );
       
   419     return( device );
       
   420 
       
   421     }
       
   422