contextframework/cfw/src/cfserver/CFMessageHandlerAction.cpp
changeset 0 2e3d3ce01487
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 /*
       
     2 * Copyright (c) 2006-2006 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 "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:  Message handler context class implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <s32mem.h>
       
    20 
       
    21 #include "CFMessageHandlerAction.h"
       
    22 #include "cfcommon.h"
       
    23 #include "CFActionInterface.h"
       
    24 #include "CFActionSubscriptionImpl.h"
       
    25 #include "CFActionIndicationImpl.h"
       
    26 #include "CFServSession.h"
       
    27 #include "cftrace.h"
       
    28 
       
    29 // CONSTANTS
       
    30 
       
    31 #ifdef _DEBUG
       
    32 
       
    33 LOCAL_C void Panic( const RMessage2& aMessage, TInt aCode )
       
    34     {
       
    35     CCFServSession::PanicClient( aMessage, aCode );
       
    36     }
       
    37 
       
    38 #endif
       
    39 
       
    40 CCFMessageHandlerAction* CCFMessageHandlerAction::NewL(
       
    41 	MCFExtendedContextInterface& aCFContext,
       
    42     MCFActionInterface& aCFAction,
       
    43     MCFScriptInterface& aScriptInterface )
       
    44     {
       
    45     FUNC_LOG;
       
    46     
       
    47     CCFMessageHandlerAction* self = CCFMessageHandlerAction::NewLC(
       
    48         aCFContext,
       
    49         aCFAction,
       
    50         aScriptInterface );
       
    51     CleanupStack::Pop( self );
       
    52     
       
    53     return self;
       
    54     }
       
    55 
       
    56 CCFMessageHandlerAction* CCFMessageHandlerAction::NewLC(
       
    57 	MCFExtendedContextInterface& aCFContext,
       
    58     MCFActionInterface& aCFAction,
       
    59     MCFScriptInterface& aScriptInterface )
       
    60     {
       
    61     FUNC_LOG;
       
    62     
       
    63     CCFMessageHandlerAction* self = new( ELeave ) CCFMessageHandlerAction(
       
    64         aCFContext,
       
    65         aCFAction,
       
    66         aScriptInterface );
       
    67     CleanupStack::PushL( self );
       
    68     self->ConstructL();
       
    69     
       
    70     return self;
       
    71     }
       
    72 
       
    73 CCFMessageHandlerAction::~CCFMessageHandlerAction()
       
    74     {
       
    75     FUNC_LOG;
       
    76     
       
    77     if( !iSubscriptionListenMessage.IsNull() )
       
    78         {
       
    79         // Need to complete message
       
    80         iSubscriptionListenMessage.Complete( KErrCancel );
       
    81         }
       
    82     iCFAction.UnsubscribeActions( *this );
       
    83     iCFAction.DeregisterActions( this );
       
    84     iActionQueue.ResetAndDestroy();
       
    85     delete iCurrentAction;
       
    86     }
       
    87 
       
    88 CCFMessageHandlerAction::CCFMessageHandlerAction(
       
    89 	MCFExtendedContextInterface& aCFContext,
       
    90     MCFActionInterface& aCFAction,
       
    91     MCFScriptInterface& aScriptInterface ):
       
    92     CCFMessageHandlerBase( aCFContext, aCFAction, aScriptInterface )
       
    93     {
       
    94     FUNC_LOG;
       
    95     }
       
    96     
       
    97 void CCFMessageHandlerAction::ConstructL()
       
    98     {
       
    99     FUNC_LOG;
       
   100     }
       
   101 
       
   102 // METHODS
       
   103 
       
   104 //-----------------------------------------------------------------------------
       
   105 // CCFMessageHandlerAction::HandleMessageL
       
   106 //-----------------------------------------------------------------------------
       
   107 //
       
   108 TBool CCFMessageHandlerAction::HandleMessageL( const RMessage2& aMessage )
       
   109     {
       
   110     FUNC_LOG;
       
   111 
       
   112     TBool handled = ETrue;
       
   113     switch( aMessage.Function() )
       
   114         {
       
   115         // Slot[0] = TDesC
       
   116         // Slot[1] = TSecurityPolicyBuf
       
   117         case EDefineAction:
       
   118             {
       
   119             INFO( "Handling IPC message [EDefineAction]" );
       
   120             
       
   121             // Read action identifier
       
   122             HBufC* actionId = HBufC::NewLC( aMessage.GetDesLengthL( 0 ) );
       
   123             TPtr actionIdPtr = actionId->Des();
       
   124             aMessage.ReadL( 0, actionIdPtr );
       
   125             
       
   126             // Read security policy
       
   127             TSecurityPolicyBuf secPolicyBuf;
       
   128             aMessage.ReadL( 1, secPolicyBuf );
       
   129             TSecurityPolicy secPolicy;
       
   130             User::LeaveIfError( secPolicy.Set( secPolicyBuf ) );
       
   131             
       
   132             // Get client thread
       
   133             RThread client;
       
   134             aMessage.ClientL( client );
       
   135             CleanupClosePushL( client );
       
   136             
       
   137             // Define action
       
   138             TInt err = iCFAction.DefineAction( actionIdPtr, secPolicy,
       
   139                 client.SecureId(), this );
       
   140             
       
   141             // Cleanup
       
   142             CleanupStack::PopAndDestroy( &client );
       
   143             CleanupStack::PopAndDestroy( actionId );
       
   144             
       
   145             // Complete message and return
       
   146             aMessage.Complete( err );
       
   147             
       
   148             INFO( "Handled IPC message [EDefineAction]" );
       
   149             
       
   150             break;
       
   151             }
       
   152 
       
   153         // Slot[0] = TDesC - CCFActionSubscription
       
   154         case ESubscribeAction:
       
   155             {
       
   156             INFO( "Handling IPC message [ESubscribeAction]" );
       
   157             
       
   158             // Read subscription
       
   159             // Start with buffer
       
   160             HBufC8* buf = HBufC8::NewLC( aMessage.GetDesLengthL( 0 ) );
       
   161             TPtr8 bufPtr = buf->Des();
       
   162             aMessage.ReadL( 0, bufPtr );
       
   163             
       
   164             // Open stream and fetch client thread
       
   165             RDesReadStream stream;
       
   166             stream.Open( bufPtr );
       
   167             stream.PushL();
       
   168             RThread client;
       
   169             aMessage.ClientL( client );
       
   170             CleanupClosePushL( client );
       
   171             
       
   172             // Create subscription from stream
       
   173             CCFActionSubscriptionImpl* subscription = static_cast
       
   174                 <CCFActionSubscriptionImpl*>( CCFActionSubscription::NewLC() );
       
   175             subscription->InternalizeL( stream );
       
   176             CleanupStack::Pop( subscription );
       
   177             
       
   178             // Set subscription
       
   179             TInt err = iCFAction.SubscribeAction( subscription, this, client );
       
   180 
       
   181             // Cleanup
       
   182             CleanupStack::PopAndDestroy( &client );
       
   183             CleanupStack::PopAndDestroy( &stream );
       
   184             CleanupStack::PopAndDestroy( buf );
       
   185 
       
   186             // Complete message and return
       
   187             aMessage.Complete( err );
       
   188 
       
   189             INFO( "Handled IPC message [ESubscribeAction]" );
       
   190             
       
   191             break;
       
   192             }
       
   193 
       
   194         // Slot[0] = TDesC - CCFActionSubscription
       
   195         case EUnsubscribeAction:
       
   196             {
       
   197             INFO( "Handling IPC message [EUnsubscribeAction]" );
       
   198             
       
   199             // Read subscription
       
   200             // Start with buffer
       
   201             HBufC8* buf = HBufC8::NewLC( aMessage.GetDesLengthL( 0 ) );
       
   202             TPtr8 bufPtr = buf->Des();
       
   203             aMessage.ReadL( 0, bufPtr );
       
   204             
       
   205             // Open stream and fetch client thread
       
   206             RDesReadStream stream;
       
   207             stream.Open( bufPtr );
       
   208             stream.PushL();
       
   209             RThread client;
       
   210             aMessage.ClientL( client );
       
   211             CleanupClosePushL( client );
       
   212             
       
   213             // Create subscription from stream
       
   214             CCFActionSubscriptionImpl* subscription = static_cast
       
   215                 <CCFActionSubscriptionImpl*>( CCFActionSubscription::NewLC() );
       
   216             subscription->InternalizeL( stream );
       
   217             
       
   218             // Set subscription
       
   219             iCFAction.UnsubscribeAction( *subscription, *this );
       
   220 
       
   221             // Cleanup
       
   222             CleanupStack::PopAndDestroy( subscription );
       
   223             CleanupStack::PopAndDestroy( &client );
       
   224             CleanupStack::PopAndDestroy( &stream );
       
   225             CleanupStack::PopAndDestroy( buf );
       
   226 
       
   227             // Complete message and return
       
   228             aMessage.Complete( KErrNone );
       
   229 
       
   230             INFO( "Handled IPC message [EUnsubscribeAction]" );
       
   231             
       
   232             break;
       
   233             }
       
   234             
       
   235         // Slot[0] = TDesC - Action indication buffer
       
   236         // Slot[1] = TDesC - Buffer size if current too small
       
   237         case EListenActionSubscription:
       
   238             {
       
   239             INFO( "Handling IPC message [EListenActionSubscription]" );
       
   240             
       
   241             // Store message and check if there is action indication
       
   242             // waiting
       
   243             iSubscriptionListenMessage = aMessage;
       
   244             CheckActionQueueL();
       
   245 
       
   246             INFO( "Handled IPC message [EListenActionSubscription]" );
       
   247             
       
   248             break;
       
   249             }
       
   250             
       
   251         // Slot[0] = TDesC - Action indication buffer
       
   252         case EGetActionIndication:
       
   253             {
       
   254             INFO( "Handling IPC message [EGetActionIndication]" );
       
   255 
       
   256             TInt err = KErrNone;
       
   257             
       
   258             // check that we really have an action indication waiting
       
   259             if( iCurrentAction )
       
   260                 {
       
   261                 // Indicate current action to client
       
   262                 // This should not fail since we are here with this op code
       
   263                 // only if server side has requested client to increase buffer.
       
   264                 HBufC8* buffer = ExternalizeIndicationLC( *iCurrentAction );
       
   265                 TPtr8 bufferPtr = buffer->Des();
       
   266                 
       
   267                 // Write message
       
   268                 aMessage.WriteL( 0, bufferPtr );
       
   269                 
       
   270                 // Cleanup
       
   271                 CleanupStack::PopAndDestroy( buffer );
       
   272                 
       
   273                 // Current action processed, delete and zero
       
   274                 delete iCurrentAction;
       
   275                 iCurrentAction = NULL;
       
   276                 }
       
   277             else
       
   278                 {
       
   279                 // No action indications found
       
   280                 err = KErrNotFound;
       
   281                 }
       
   282             
       
   283             // Complete message and return
       
   284             aMessage.Complete( err );
       
   285 
       
   286             INFO( "Handled IPC message [EGetActionIndication]" );
       
   287             
       
   288             break;
       
   289             }
       
   290             
       
   291         case ECancelListenActionSubscription:
       
   292             {
       
   293             INFO( "Handling IPC message [ECancelListenActionSubscription]" );
       
   294             
       
   295             // Check if subscription message has not been completed yet
       
   296             if( !iSubscriptionListenMessage.IsNull() )
       
   297                 {
       
   298                 iSubscriptionListenMessage.Complete( KErrCancel );
       
   299                 }
       
   300             aMessage.Complete( KErrNone );
       
   301 
       
   302             INFO( "Handled IPC message [ECancelListenActionSubscription]" );
       
   303             
       
   304             break;
       
   305             }
       
   306             
       
   307         default:
       
   308             {
       
   309             // Message not handled
       
   310             handled = EFalse;
       
   311             break;
       
   312             }
       
   313         }
       
   314     
       
   315     return handled;
       
   316     }
       
   317 
       
   318 //-----------------------------------------------------------------------------
       
   319 // CCFMessageHandlerAction::ActionIndicationL
       
   320 //-----------------------------------------------------------------------------
       
   321 //
       
   322 void CCFMessageHandlerAction::ActionIndicationL(
       
   323     CCFActionIndication* aIndication )
       
   324     {
       
   325     FUNC_LOG;
       
   326     
       
   327     INFO_1( "Received action indication: %S", &aIndication->Identifier() );
       
   328 
       
   329     // Append action indication in queue and check queue
       
   330     TInt err = iActionQueue.Append( aIndication );
       
   331     if( err == KErrNone )
       
   332         {
       
   333         CheckActionQueueL();
       
   334         }
       
   335     else
       
   336         {
       
   337         // Something odd happened, try to serve this indication
       
   338         // We still need to have request message pending
       
   339         if( !iSubscriptionListenMessage.IsNull() && !iCurrentAction )
       
   340             {
       
   341             iCurrentAction = aIndication;
       
   342             IndicateCurrentActionL();
       
   343             }
       
   344         else
       
   345             {
       
   346             // Cannot serve this, delete
       
   347             delete aIndication;
       
   348             }
       
   349         }
       
   350     }
       
   351 
       
   352 //------------------------------------------------------------------------------
       
   353 // CCFMessageHandlerAction::ActionOwner
       
   354 //------------------------------------------------------------------------------
       
   355 //
       
   356 MCFActionOwner::TCFActionOwner CCFMessageHandlerAction::ActionOwner() const
       
   357     {
       
   358     FUNC_LOG;
       
   359     
       
   360     return MCFActionOwner::ECFExternalAction;
       
   361     }
       
   362 
       
   363 //-----------------------------------------------------------------------------
       
   364 // CCFMessageHandlerAction::CheckActionQueueL
       
   365 //-----------------------------------------------------------------------------
       
   366 //
       
   367 void CCFMessageHandlerAction::CheckActionQueueL()
       
   368     {
       
   369     FUNC_LOG;
       
   370     
       
   371     // If we have:
       
   372     // - Actions in the queue
       
   373     // - Currently not processing any actions
       
   374     // - Listen message outstanding
       
   375     if( iActionQueue.Count() &&
       
   376         !iCurrentAction &&
       
   377         !iSubscriptionListenMessage.IsNull() )
       
   378         {
       
   379         // Get latest action
       
   380         iCurrentAction = iActionQueue[0];
       
   381         iActionQueue.Remove( 0 );
       
   382         
       
   383         // Indicate current action to client
       
   384         IndicateCurrentActionL();
       
   385         }
       
   386     }
       
   387 
       
   388 //-----------------------------------------------------------------------------
       
   389 // CCFMessageHandlerAction::IndicateCurrentActionL
       
   390 //-----------------------------------------------------------------------------
       
   391 //
       
   392 void CCFMessageHandlerAction::IndicateCurrentActionL()
       
   393     {
       
   394     FUNC_LOG;
       
   395     
       
   396     __ASSERT_DEBUG( iCurrentAction,
       
   397         Panic( iSubscriptionListenMessage, ENoCurrentAction ) );
       
   398     
       
   399     // Check client buffer
       
   400     TInt err = KErrNone;
       
   401     CCFActionIndicationImpl* indication =
       
   402         static_cast<CCFActionIndicationImpl*>( iCurrentAction );
       
   403     TInt indicationSize = indication->Size();
       
   404     TInt clientBufSize = iSubscriptionListenMessage.GetDesMaxLengthL( 0 );
       
   405     if( indicationSize > clientBufSize )
       
   406         {
       
   407         // Client buffer too small
       
   408         // Write new buffer size in Slot[1]
       
   409         TPckgBuf<TInt> indicationSizeBuf( indicationSize );
       
   410         iSubscriptionListenMessage.WriteL( 1, indicationSizeBuf );
       
   411         err = KErrTooBig;
       
   412         }
       
   413     else
       
   414         {
       
   415         // Client buffer sufficient
       
   416         // Stream indication into descriptor
       
   417         HBufC8* buffer = ExternalizeIndicationLC( *indication );
       
   418         TPtr8 bufferPtr = buffer->Des();
       
   419         
       
   420         // Write message
       
   421         iSubscriptionListenMessage.WriteL( 0, bufferPtr );
       
   422         
       
   423         // Cleanup
       
   424         CleanupStack::PopAndDestroy( buffer );
       
   425         delete iCurrentAction;
       
   426         iCurrentAction = NULL;
       
   427         }
       
   428         
       
   429     // Complete message
       
   430     iSubscriptionListenMessage.Complete( err );
       
   431     }
       
   432 
       
   433 //-----------------------------------------------------------------------------
       
   434 // CCFMessageHandlerAction::ExternalizeIndicationL
       
   435 //-----------------------------------------------------------------------------
       
   436 //
       
   437 HBufC8* CCFMessageHandlerAction::ExternalizeIndicationLC(
       
   438     CCFActionIndication& aIndication )
       
   439     {
       
   440     FUNC_LOG;
       
   441     
       
   442     CCFActionIndicationImpl& indication =
       
   443         static_cast<CCFActionIndicationImpl&>( aIndication );
       
   444     
       
   445     HBufC8* buffer = HBufC8::NewLC( indication.Size() );
       
   446     TPtr8 bufferPtr = buffer->Des();
       
   447     RDesWriteStream stream( bufferPtr );
       
   448     stream.PushL();
       
   449     indication.ExternalizeL( stream );
       
   450     
       
   451     // Cleanup
       
   452     CleanupStack::PopAndDestroy( &stream );
       
   453     
       
   454     return buffer;
       
   455     }