diff -r 000000000000 -r 4e1aa6a622a0 mediator/src/Server/MediatorServerSession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mediator/src/Server/MediatorServerSession.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,2030 @@ +/* +* Copyright (c) 2005-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: Session implementation class for Mediator Server +* +*/ + + +// INCLUDE FILES +#include +#include + +#include "MediatorServerSession.h" +#include "MediatorCommon.h" +#include "MediatorServer.h" +#include "MediatorServiceDefs.h" +#include "mediatorqueitem.h" +#include "MediatorDebug.h" +#include "Debug.h" +using namespace MediatorService; + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::CMediatorServerSession +// ----------------------------------------------------------------------------- +// +CMediatorServerSession::CMediatorServerSession() :iNotificationsRegistered( EFalse ), + iNotificationQueue( _FOFF(CMediatorQueItem,iSlink) ) + { + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::NewL +// ----------------------------------------------------------------------------- +// +CMediatorServerSession* CMediatorServerSession::NewL() + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::NewL")); + return new( ELeave ) CMediatorServerSession(); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::~CMediatorServerSession +// ----------------------------------------------------------------------------- +// +CMediatorServerSession::~CMediatorServerSession() + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::~CMediatorServerSession")); + + // cancel all asynchronous waiting procedures + CancelAll( KErrCancel ); + + // cancel pending commands + Server().CommandHandler().CancelCommands( this, this ); + + // Unregister all subscriptions + // Get handler + CMediatorServerObjectHandler& objectHandler = Server().ObjectHandler(); + objectHandler.ClearRegistrations( this, this, this ); + + iEventServiceList.ResetAndDestroy(); + iCommandServiceList.ResetAndDestroy(); + + if ( iDataBuffer ) + { + delete iDataBuffer; + } + + CleanNotificationQueue(); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::CleanNotificationQueue +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::CleanNotificationQueue() + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::CleanNotificationQueue")); + + // release memory allocated to notification queue items + TSglQueIter iter( iNotificationQueue ); + CMediatorQueItem* item; + + while ( ( item = iter++ ) != NULL) + { + iNotificationQueue.Remove( *item ); + delete item; + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::Server +// Returns a reference to server +// ----------------------------------------------------------------------------- +// +CMediatorServer& CMediatorServerSession::Server() + { + return *static_cast(const_cast(CSession2::Server())); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::ServiceL +// Implements CSession2 -derived ServiceL -method. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::ServiceL(const RMessage2& aMessage) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::ServiceL")); + + // If ServiceL leaves, default implementation in server framework + // completes the RMessage2 with the leave code. + DispatchMessageL( aMessage ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::ServiceError +// Implements CSession2 -derived ServiceError -method. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::ServiceError(const RMessage2& aMessage,TInt aError) + { + ERROR_TRACE(Print(_L("[Mediator] CMediatorServerSession::ServiceError: opcode=%d, aError=%d\n"), aMessage.Function(), aError )); + + RMediatorDebug::LogError(aMessage, aError); + + CSession2::ServiceError(aMessage, aError); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::ReadCategoryL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +TMediatorCategory CMediatorServerSession::ReadCategoryL( + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + TMediatorCategoryBuffer categoryBuffer; + aMessage.ReadL( aMessageSlot, categoryBuffer ); + TMediatorCategory category = categoryBuffer(); + return category; + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::WriteCategoryL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::WriteCategoryL( TUid aDomain, + TUid aCategory, + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + TMediatorCategory category; + category.iDomain = aDomain; + category.iCategory = aCategory; + TMediatorCategoryRetBuffer categoryBuffer( category ); + aMessage.WriteL( aMessageSlot, categoryBuffer ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::WriteEventL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::WriteEventL( TInt aEventId, + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + MediatorService::TEvent event; + event.iEventId = aEventId; + TEventRetBuffer buffer( event ); + aMessage.WriteL( aMessageSlot, buffer ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::WriteCommandL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::WriteCommandL( TInt aCommandId, + TVersion aVersion, + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + MediatorService::TCommand command; + command.iCommandId = aCommandId; + command.iVersion = aVersion; + TCommandRetBuffer buffer( command ); + aMessage.WriteL( aMessageSlot, buffer ); + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::ReadEventListL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +REventList CMediatorServerSession::ReadEventListL( const RMessage2& aMessage, + const TInt aMessageSlot ) + { + // Read event list information from Message + REventList eventList; + CleanupClosePushL( eventList ); + + // Create input pointer for data + TInt size = aMessage.GetDesMaxLength( aMessageSlot ); + TInt count = size / ( sizeof(MediatorService::TEvent) ); + + if ( count <= 0 ) + { + User::Leave( KErrArgument ); + } + + for ( TInt index = 0; index < count; index ++ ) + { + TEvent event; + eventList.AppendL( event ); + } + TPtr8 arrayPtr( (TUint8*)&eventList[0], size ); + + // Read data from message + aMessage.ReadL( aMessageSlot, arrayPtr ); + + CleanupStack::Pop( &eventList ); + return eventList; + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::EventListFitsToClientMemory +// ----------------------------------------------------------------------------- +// +TBool CMediatorServerSession::EventListFitsToClientMemory( const REventList& aEvents, + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + TBool retval( ETrue ); + + if ( aEvents.Count() > 0 ) + { + TInt arraySize( ( sizeof(MediatorService::TEvent) ) * aEvents.Count() ); + + // Check that there's enough space before writing the answer + TInt space( aMessage.GetDesMaxLength( aMessageSlot ) ); + + retval = ( arraySize <= space ); + } + + return retval; + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::CommandListFitsToClientMemory +// ----------------------------------------------------------------------------- +// +TBool CMediatorServerSession::CommandListFitsToClientMemory( const RCommandList& aCommands, + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + TBool retval( ETrue ); + + if ( aCommands.Count() > 0 ) + { + TInt arraySize( ( sizeof(MediatorService::TCommand) ) * aCommands.Count() ); + + // Check that there's enough space before writing the answer + TInt space( aMessage.GetDesMaxLength( aMessageSlot ) ); + + retval = ( arraySize <= space ); + } + + return retval; + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::WriteEventListL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::WriteEventListL( const REventList& aEvents, + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + if ( aEvents.Count() > 0 ) + { + TInt arraySize = ( sizeof(MediatorService::TEvent) ) * aEvents.Count(); + TInt space( aMessage.GetDesMaxLength( aMessageSlot ) ); + + // the method assumes that there's enought space in client memory to accommadate the events + __ASSERT_DEBUG( space >= arraySize, User::Invariant() ); + + if ( arraySize > space ) + { + arraySize = space; // ensure that we don't overflow client buffer in any circumstances + } + + TPtr8 arrayPtr( (TUint8*)&aEvents[0], arraySize, arraySize ); + aMessage.WriteL( aMessageSlot, arrayPtr ); + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::ReadCommandListL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +RCommandList CMediatorServerSession::ReadCommandListL( const RMessage2& aMessage, + const TInt aMessageSlot ) + { + // Read command list information from Message + RCommandList commandList; + CleanupClosePushL( commandList ); + + // Create input pointer for data + TInt size = aMessage.GetDesMaxLength( aMessageSlot ); + TInt count = size / ( sizeof(MediatorService::TCommand) ); + for ( TInt index = 0; index < count; index ++ ) + { + TCommand command; + commandList.AppendL( command ); + } + TPtr8 arrayPtr( (TUint8*)&commandList[0], size ); + + // Read data from message + aMessage.ReadL( aMessageSlot, arrayPtr ); + + CleanupStack::Pop( &commandList ); + return commandList; + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::WriteCommandListL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::WriteCommandListL( const RCommandList& aCommands, + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + // Write the command list back to client + if ( ( aCommands.Count() > 0 ) ) + { + TInt arraySize( ( sizeof(MediatorService::TCommand) ) * aCommands.Count() ); + + // Check that there's enough space before writing the answer + TInt space( aMessage.GetDesMaxLength( aMessageSlot ) ); + + // this method assumes that there's enough space in client side + __ASSERT_DEBUG( arraySize <= space, User::Invariant() ); + + if ( arraySize > space ) // overflow prevention + { + arraySize = space; + } + + TPtr8 arrayPtr( (TUint8*)&aCommands[0], arraySize, arraySize ); + aMessage.WriteL( aMessageSlot, arrayPtr ); + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::ReadDataL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +HBufC8* CMediatorServerSession::ReadDataLC( const RMessage2& aMessage, + const TInt aMessageSlot ) + { + // Then read parameter data from slot 2 + TInt dataSize = aMessage.GetDesLength( aMessageSlot ); + + if ( dataSize < 0 ) + { + User::Leave( KErrArgument ); + } + + HBufC8* data = HBufC8::NewLC( dataSize ); + TPtr8 ptr( data->Des() ); + aMessage.ReadL( aMessageSlot, ptr ); + return data; + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::WriteDataL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::WriteDataL( const TDesC8& aData, + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + // Read max data length + TInt space = aMessage.GetDesMaxLength( aMessageSlot ); + if ( space >= aData.Length() ) + { + aMessage.WriteL( aMessageSlot, aData ); + } + else // Not enough space to write + { + // Store the data to temporary buffer --> it is fetched from client side + // synchronously + if ( iDataBuffer ) + { + delete iDataBuffer; + iDataBuffer = NULL; + } + iDataBuffer = aData.AllocL(); + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::ReadEventL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +MediatorService::TEvent CMediatorServerSession::ReadEventL( + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + TEventBuffer eventBuffer; + aMessage.ReadL( aMessageSlot, eventBuffer ); + return eventBuffer(); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::ReadCommandL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +MediatorService::TCommand CMediatorServerSession::ReadCommandL( + const RMessage2& aMessage, + const TInt aMessageSlot ) + { + TCommandBuffer commandBuffer; + aMessage.ReadL( aMessageSlot, commandBuffer ); + return commandBuffer(); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::DispatchMessageL +// Dispatches message according to its opcode +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::DispatchMessageL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::DispatchMessageL")); + + RMediatorDebug::Log(aMessage, *this); + + switch ( aMessage.Function() ) + { + case ERegisterEventList: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: ERegisterEventList")); + RegisterEventListL( aMessage ); + break; + } + case ERegisterCommandList: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: ERegisterCommand")); + RegisterCommandListL( aMessage ); + break; + } + case EUnregisterEventList: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EUnregisterEventList")); + UnregisterEventListL( aMessage ); + break; + } + case EUnregisterCommandList: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EUnregisterCommandList")); + UnregisterCommandListL( aMessage ); + break; + } + case ESubscribeEventList: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: ESubscribeEvent")); + SubscribeEventListL( aMessage ); + break; + } + case EUnsubscribeEventList: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EUnsubscribeEvent")); + UnsubscribeEventListL( aMessage ); + break; + } + case ERaiseEvent: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: ERaiseEvent")); + RaiseEventL( aMessage ); + break; + } + case EIssueCommand: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: IssueCommandL")); + IssueCommandL( aMessage ); + break; + } + case ECancelCommand: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: CancelCommandL")); + CancelCommandL( aMessage ); + break; + } + case EIssueResponse: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EIssueResponse")); + IssueResponseL( aMessage ); + break; + } + case EGetDomains: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EGetDomains")); + GetDomainsL( aMessage ); + break; + } + case EGetCategories: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EGetCategories")); + GetCategoriesL( aMessage ); + break; + } + case EGetCommands: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EGetCommands")); + GetCommandsL( aMessage ); + break; + } + case EGetEvents: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EGetEvents")); + GetEventsL( aMessage ); + break; + } + case EWaitForEvent: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EWaitForEvent")); + WaitForEventsL( aMessage ); + break; + } + case EWaitForCommand: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EWaitForCommand")); + WaitForCommandsL( aMessage ); + break; + } + case EWaitForNotifications: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EWaitForNotifications")); + WaitForNotificationsL( aMessage ); + break; + } + case ECancelNotifications: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: ECancelNotifications")); + CancelNotificationsL( aMessage ); + break; + } + case EWaitForCommandResponse: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EWaitForCommandResponse")); + WaitForCommandResponseL( aMessage ); + break; + } + case EFetchParameterData: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EFetchParameterData")); + FetchParameterDataL( aMessage ); + break; + } + case ECancelAll: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: ECancelAll")); + CancelAll( aMessage ); + break; + } + + case EFetchNotificationEventList: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EFetchNotificationEventList")); + FetchNotificationEventListL( aMessage ); + break; + } + + case EFetchNotificationCommandList: + { + LOG(_L("[Mediator Server]\t DispatchMessageL: EFetchNotificationCommandList")); + FetchNotificationCommandListL( aMessage ); + break; + } + default: + { + // Unknown opcode --> panic client + ERROR_TRACE(Print(_L("[Mediator] CMediatorServerSession::DispatchMessageL: Unknown opcode=%d\n"), aMessage.Function())); + CMediatorServer::PanicClient( aMessage, EMediatorClientBadRequest ); + break; + } + } + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::MediatorCommandL +// Callback from command handler when command is issued +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::MediatorCommandL( TUid aDomain, + TUid aCategory, + TInt aCommandId, + TVersion aVersion, + const TDesC8& aData ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::MediatorCommandL")); + + if ( !iCommandInitMessage.IsNull() ) + { + // Write domain & category information + WriteCategoryL( aDomain, aCategory, iCommandInitMessage, 0 ); + + // Write event to slot 1 + WriteCommandL( aCommandId, aVersion, iCommandInitMessage, 1 ); + + // Write data to slot 2 + WriteDataL( aData, iCommandInitMessage, 2 ); + + // Complete message with data size + iCommandInitMessage.Complete( aData.Length() ); + } + else // Append command to service list + { + // Create a new command object + CCommand* newCommand = CCommand::NewL( aCommandId ); + CleanupStack::PushL( newCommand ); + newCommand->SetParameterDataL( aData ); + newCommand->SetDomain( aDomain ); + newCommand->SetCategory( aCategory ); + newCommand->SetVersion( aVersion ); + iCommandServiceList.AppendL( newCommand ); // Last to queue + CleanupStack::Pop( newCommand ); // ownership is in the array + TRACE(Print(_L("[Mediator Server]\t Session %d - command buffer %d\n"), this, iCommandServiceList.Count() )); + } + + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::CancelMediatorCommandL +// Callback from command handler when command processing is cancelled +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::CancelMediatorCommandL( TUid aDomain, + TUid aCategory, + TInt aCommandId ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::CancelMediatorCommand")); + + // Check the service list and remove the command from there if exists + // At this point it has not been delivered to responder yet + TBool found = EFalse; + for ( TInt index = 0; index < iCommandServiceList.Count() && !found; index++ ) + { + CCommand* commandPtr = iCommandServiceList[index]; + if ( commandPtr ) + { + if ( commandPtr->Domain() == aDomain + && commandPtr->Category() == aCategory + && commandPtr->Id() == aCommandId + && commandPtr->Status() == ECommandPending ) + { + iCommandServiceList.Remove( index ); + delete commandPtr; + commandPtr = NULL; + found = ETrue; + } + } + } + + // Write domain & category information to slot 0 + if ( iCommandInitMessage.Handle() && !found ) + { + WriteCategoryL( aDomain, aCategory, iCommandInitMessage, 0 ); + + // Write command id and version to slot 1 + TVersion version( 0, 0, 0 ); + WriteCommandL( aCommandId, version, iCommandInitMessage, 1 ); + + // Status to slot 2 + TPckg statusBuffer( KErrCancel ); + iCommandInitMessage.WriteL( 2, statusBuffer ); + + // Write data to slot 3 + WriteDataL( KNullDesC8, iCommandInitMessage, 2 ); + + // Complete message + iCommandInitMessage.Complete( KErrCancel ); + } + // The command hs been delivered, but the responder is busy or otherwise is not + // yet ready to handle the command cancellation, add to the list with cancelled status + else if ( !iCommandInitMessage.Handle() && !found ) + { + // Create a new command object + CCommand* newCommand = CCommand::NewL( aCommandId ); + CleanupStack::PushL( newCommand ); + newCommand->SetDomain( aDomain ); + newCommand->SetCategory( aCategory ); + newCommand->SetStatus( ECommandCanceled ); + iCommandServiceList.AppendL( newCommand ); // Last to queue + CleanupStack::Pop( newCommand ); // ownership is in the array + } + + + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::CancelMediatorCommandL +// Callback from command handler when command processing is cancelled +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::MediatorCommandTimeoutL( TUid aDomain, + TUid aCategory, + TInt aCommandId ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::MediatorCommandTimeoutL")); + + // Check the service list and remove the command from there if exists + // At this point it has not been delivered to responder yet + TBool found = EFalse; + for ( TInt index = 0; index < iCommandServiceList.Count() && !found; index++ ) + { + CCommand* commandPtr = iCommandServiceList[index]; + if ( commandPtr ) + { + if ( commandPtr->Domain() == aDomain + && commandPtr->Category() == aCategory + && commandPtr->Id() == aCommandId + && commandPtr->Status() == ECommandPending ) // only pending commands are completed with timeout + { + iCommandServiceList.Remove( index ); + delete commandPtr; + commandPtr = NULL; + found = ETrue; + } + } + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::CommandResponseL +// Callback from command handler when command processing is cancelled +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::CommandResponseL( TUid aDomain, + TUid aCategory, + TInt aCommandId, + TInt aStatus, + const TDesC8& aData ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::CommandResponseL")); + + if ( !iCommandResponseMessage.IsNull() ) + { + // Write domain & category information + WriteCategoryL( aDomain, aCategory, iCommandResponseMessage, 0 ); + + // Write command to slot 1 + TVersion version( 0, 0, 0 ); + WriteCommandL( aCommandId, version, iCommandResponseMessage, 1 ); + + // Write data to slot 2 + WriteDataL( aData, iCommandResponseMessage, 2 ); + + // Status to slot 3 + TPckg statusBuffer( aStatus ); + iCommandResponseMessage.WriteL( 3, statusBuffer ); + + // Complete message with data size + iCommandResponseMessage.Complete( aData.Length() ); + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::MediatorEventL +// Callback from event handler when event occurs +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::MediatorEventL( TUid aDomain, + TUid aCategory, + TInt aEventId, + const TDesC8& aData ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::MediatorEventL")); + if ( !iEventNotificationMessage.IsNull() ) + { + // Write domain & category information + WriteCategoryL( aDomain, aCategory, iEventNotificationMessage, 0 ); + + // Write event to slot 1 + WriteEventL( aEventId, iEventNotificationMessage, 1 ); + + // Write data to slot 2 + WriteDataL( aData, iEventNotificationMessage, 2 ); + + // Complete message with data size + iEventNotificationMessage.Complete( aData.Length() ); + } + else // Append event to service list + { + // Create a new event object + CEvent* newEvent = CEvent::NewL( aEventId ); + CleanupStack::PushL( newEvent ); + newEvent->SetParameterDataL( aData ); + newEvent->SetDomain( aDomain ); + newEvent->SetCategory( aCategory ); + iEventServiceList.AppendL( newEvent ); // Last to queue + CleanupStack::Pop( newEvent ); // ownership is in the array + TRACE(Print(_L("[Mediator Server]\t Session %d - event buffer %d\n"),this ,iEventServiceList.Count() )); + } + + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::MediatorEventsAddedL +// Callback from event handler when an event is added +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::MediatorEventsAddedL( TUid aDomain, + TUid aCategory, + const REventList& aEvents ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::MediatorEventsAddedL")); + + HandleMediatorEventsChangedL( EMediatorEventsRegistered, aDomain, aCategory, aEvents ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::HandleMediatorEventsChangedL +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::HandleMediatorEventsChangedL( TMediatorNotificationType aNotificationType, + const TUid& aDomain, + const TUid& aCategory, + const REventList& aEvents ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::HandleMediatorEventsChangedL")); + + if ( !iNotificationMessage.IsNull() ) + { + TBool eventsPassed( ETrue ); + + DoMediatorEventsChangedL( aNotificationType, aDomain, aCategory, aEvents, eventsPassed ); + + if ( !eventsPassed ) + { + // store events for next EFetchNotificationEventList + CMediatorQueItem* eventsBuffer = CEventListQueItem::NewL( aNotificationType, aDomain, aCategory, aEvents ); + iNotificationQueue.AddFirst( *eventsBuffer ); + } + } + else if ( iNotificationsRegistered ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::HandleMediatorEventsChangedL: received events buffered")); + + // store events for next EWaitForNotifications + CMediatorQueItem* eventsBuffer = CEventListQueItem::NewL( aNotificationType, aDomain, aCategory, aEvents ); + iNotificationQueue.AddLast( *eventsBuffer ); + } + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::DoMediatorEventsChangedL +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::DoMediatorEventsChangedL( TMediatorNotificationType aNotificationType, + const TUid& aDomain, + const TUid& aCategory, + const REventList& aEvents, + TBool& aEventsPassedToClient ) + { + TRACE( Print( _L("[Mediator Server]\t CMediatorServerSession::DoMediatorEventsChangedL: D=0x%x C=0x%x, count=%d"), + aDomain.iUid, aCategory.iUid, aEvents.Count() ) ); + + // Write category information to message slot 0 + WriteCategoryL( aDomain, aCategory, iNotificationMessage, 0 ); + + // Write notification type to slot 1 + TNotificationTypeRetBuffer typeBuffer( aNotificationType ); + iNotificationMessage.WriteL( 1, typeBuffer ); + + // Write event list + if ( EventListFitsToClientMemory( aEvents, iNotificationMessage, 2 ) ) + { + WriteEventListL( aEvents, iNotificationMessage, 2 ); + aEventsPassedToClient = ETrue; + } + else + { + aEventsPassedToClient = EFalse; + } + + // Complete message + iNotificationMessage.Complete( aEvents.Count() ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::PurgeNextBufferedNotificationL +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::PurgeNextBufferedNotificationL() + { + if ( !iNotificationQueue.IsEmpty() ) + { + TBool completed( ETrue ); + CMediatorQueItem* notification = iNotificationQueue.First(); + + TRACE( Print( _L("[Mediator Server]\t CMediatorServerSession::PurgeNextBufferedNotificationL: type=%d"), + notification->NofiticationType() ) ); + // remove now, notification will be pushed back to queue if cannot be delivered with the current client request + iNotificationQueue.Remove( *notification ); + CleanupStack::PushL( notification ); + + switch ( notification->NofiticationType() ) + { + case EMediatorEventsRegistered: + case EMediatorEventsUnregistered: + DoMediatorEventsChangedL( notification->NofiticationType(), + notification->Domain(), + notification->Category(), + *(notification->Events()), + completed ); + break; + + case EMediatorCommandsRegistered: + case EMediatorCommandsUnregistered: + DoMediatorCommandsChangedL( notification->NofiticationType(), + notification->Domain(), + notification->Category(), + *(notification->Commands()), + completed ); + break; + + case EMediatorCategoryUnregistered: + DoMediatorCategoryRemovedL( notification->Domain(), + notification->Category() ); + break; + + default: + __ASSERT_DEBUG( EFalse, User::Invariant() ); + } + + if ( completed ) + { + // no longer needed, cleanup + CleanupStack::PopAndDestroy( notification ); + } + else // could not be completed without further client request + { + iNotificationQueue.AddFirst( *notification ); + CleanupStack::Pop( notification ); + } + + } + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::MediatorCommandsAddedL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::MediatorCommandsAddedL( TUid aDomain, + TUid aCategory, + const RCommandList& aCommands ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::MediatorCommandsAddedL")); + + HandleMediatorCommandsChangedL( EMediatorCommandsRegistered, aDomain, aCategory, aCommands); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::HandleMediatorCommandsChangedL +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::HandleMediatorCommandsChangedL( TMediatorNotificationType aNotificationType, + const TUid& aDomain, + const TUid& aCategory, + const RCommandList& aCommands ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::HandleMediatorCommandsChangedL")); + if ( !iNotificationMessage.IsNull() ) + { + TBool commandListPassed( ETrue ); + + DoMediatorCommandsChangedL( aNotificationType, aDomain, aCategory, aCommands, commandListPassed ); + + if ( !commandListPassed ) + { + // store commands for next EFetchNotificationCommandList + CMediatorQueItem* commandsItem = CCommandListQueItem::NewL( aNotificationType, aDomain, aCategory, aCommands ); + iNotificationQueue.AddFirst( *commandsItem ); + } + } + else if ( iNotificationsRegistered ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::HandleMediatorCommandsChangedL: received commands buffered")); + + // store commands for next EWaitForNotifications + CMediatorQueItem* commandsItem = CCommandListQueItem::NewL( aNotificationType, aDomain, aCategory, aCommands ); + iNotificationQueue.AddLast( *commandsItem ); + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::DoMediatorCommandsChangedL +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::DoMediatorCommandsChangedL( TMediatorNotificationType aNotificationType, + const TUid& aDomain, + const TUid& aCategory, + const RCommandList& aCommands, + TBool& aCommandsPassedToClient ) + { + TRACE( Print( _L("[Mediator Server]\t CMediatorServerSession::DoMediatorCommandsChangedL: D=0x%x, C=0x%x, count=%d" ), + aDomain.iUid, aCategory.iUid, aCommands.Count() ) ); + + // Write category information to message slot 0 + WriteCategoryL( aDomain, aCategory, iNotificationMessage, 0 ); + + // Write notification type to slot 1 + TMediatorNotificationType notificationType = aNotificationType; + TNotificationTypeRetBuffer typeBuffer( notificationType ); + iNotificationMessage.WriteL( 1, typeBuffer ); + + // Write command list to slot 3 + if ( CommandListFitsToClientMemory( aCommands, iNotificationMessage, 3 ) ) + { + WriteCommandListL( aCommands, iNotificationMessage, 3 ); + aCommandsPassedToClient = ETrue; + } + else + { + aCommandsPassedToClient = EFalse; + } + + // Complete message + iNotificationMessage.Complete( aCommands.Count() ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::DoMediatorCategoryRemovedL +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::DoMediatorCategoryRemovedL( const TUid& aDomain, + const TUid& aCategory ) + { + TRACE( Print( _L("[Mediator Server]\t CMediatorServerSession::DoMediatorCategoryRemovedL: D=0x%x, C=0x%x"), + aDomain.iUid, aCategory.iUid ) ); + + // Write category information to message slot 0 + WriteCategoryL( aDomain, aCategory, iNotificationMessage, 0 ); + + // Write notification type to slot 1 + TMediatorNotificationType notificationType = EMediatorCategoryUnregistered; + TNotificationTypeRetBuffer typeBuffer( notificationType ); + iNotificationMessage.WriteL( 1, typeBuffer ); + + // Complete message + iNotificationMessage.Complete( KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::MediatorEventL +// Callback from event handler when event occurs +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::MediatorCategoryRemovedL( TUid aDomain, TUid aCategory ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::MediatorCategoryRemovedL")); + + if ( !iNotificationMessage.IsNull() ) + { + DoMediatorCategoryRemovedL( aDomain, aCategory ); + } + else if ( iNotificationsRegistered ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::MediatorCategoryRemovedL: buffering")); + + // store category removal for next EWaitForNotifications + CMediatorQueItem* notification = CCategoryQueItem::NewL( aDomain, aCategory ); + iNotificationQueue.AddLast( *notification ); + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::MediatorEventL +// Callback from event handler when event occurs +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::MediatorEventsRemovedL( TUid aDomain, + TUid aCategory, + const REventList& aEvents ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::MediatorEventsRemovedL")); + + HandleMediatorEventsChangedL( EMediatorEventsUnregistered, aDomain, aCategory, aEvents ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::MediatorCommandsRemovedL +// Callback from event handler when event occurs +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::MediatorCommandsRemovedL( TUid aDomain, + TUid aCategory, + const RCommandList& aCommands ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::MediatorCommandsRemovedL")); + + HandleMediatorCommandsChangedL( EMediatorCommandsUnregistered, aDomain, aCategory, aCommands ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::RegisterEventListL +// Helper method to register event list. Uses Event handler. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::RegisterEventListL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::RegisterEventListL")); + + // Read domain & category + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Read event list + REventList eventList = ReadEventListL( aMessage, 1 ); + CleanupClosePushL( eventList ); + + RMediatorDebug::LogData(aMessage, *this, eventList); + + // Get handler + CMediatorServerEventHandler& eventHandler = Server().EventHandler(); + + // Register events + eventHandler.RegisterEventListL( category, eventList, aMessage.SecureId() ); + + // Cleanup + CleanupStack::PopAndDestroy( &eventList ); + + // Complete message in case of no errors + aMessage.Complete( KErrNone ); + + RMediatorDebug::LogStatus(); + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::RegisterCommandListL +// Helper function to register command. Uses Command Handler +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::RegisterCommandListL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::RegisterCommandListL")); + + // Read domain & category + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Read command list information from Message + RCommandList commandList = ReadCommandListL( aMessage, 1 ); + CleanupClosePushL( commandList ); + + RMediatorDebug::LogData(aMessage, *this, commandList); + + // Get handler + CMediatorServerCommandHandler& commandHandler = Server().CommandHandler(); + + // Register commands + commandHandler.RegisterCommandListL( category, + commandList, + aMessage.SecureId(), + this ); + + // cleanup + CleanupStack::PopAndDestroy( &commandList ); + + // Complete message in case of no errors + aMessage.Complete( KErrNone ); + + RMediatorDebug::LogStatus(); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::UnregisterEventListL +// Helper method to unregister event(s). Uses Event handler. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::UnregisterEventListL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::UnregisterEventListL")); + + // Read domain & category + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Read event list information from Message + REventList eventList = ReadEventListL( aMessage, 1 ); + CleanupClosePushL( eventList ); + + RMediatorDebug::LogData(aMessage, *this, eventList); + + // Get handler + CMediatorServerEventHandler& eventHandler = Server().EventHandler(); + + // Register events + eventHandler.UnregisterEventListL( category, eventList, aMessage.SecureId() ); + + // cleanup + CleanupStack::PopAndDestroy( &eventList ); + + // Complete message in case of no errors + aMessage.Complete( KErrNone ); + + RMediatorDebug::LogStatus(); + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::UnregisterCommandListL +// Helper method to unregister command(s). Uses Command handler. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::UnregisterCommandListL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::UnregisterCommandListL")); + + // Read domain & category + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Read command list information from Message + RCommandList commandList = ReadCommandListL( aMessage, 1 ); + CleanupClosePushL( commandList ); + + RMediatorDebug::LogData(aMessage, *this, commandList); + + // Get handler + CMediatorServerCommandHandler& commandHandler = Server().CommandHandler(); + + // Unregister commands + commandHandler.UnregisterCommandListL( category, commandList, aMessage.SecureId() ); + + // cleanup + CleanupStack::PopAndDestroy( &commandList ); + + // Complete message in case of no errors + aMessage.Complete( KErrNone ); + + RMediatorDebug::LogStatus(); + } + + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::SubscribeEventL +// Helper method to subscribes to event(s). Uses Event handler. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::SubscribeEventListL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::SubscribeEventListL")); + + // Read domain & category information + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Read event list information from Message + REventList eventList = ReadEventListL( aMessage, 1 ); + CleanupClosePushL( eventList ); + + RMediatorDebug::LogData(aMessage, *this, eventList); + + // Get handler + CMediatorServerEventHandler& eventHandler = Server().EventHandler(); + + // Subscribe to events + TSecurityInfo messageCaps( aMessage ); + eventHandler.SubscribeEventListL( category, eventList, messageCaps.iCaps, this ); + + // Cleanup + CleanupStack::PopAndDestroy( &eventList ); + + // Complete message in case of no errors + aMessage.Complete( KErrNone ); + + RMediatorDebug::LogStatus(); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::UnsubscribeEventL +// Helper method to subscribes to event(s). Uses Event handler. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::UnsubscribeEventListL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::UnsubscribeEventListL")); + + // Read domain & category + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Read event list from slot 1 + REventList eventList = ReadEventListL( aMessage, 1 ); + CleanupClosePushL( eventList ); + + RMediatorDebug::LogData(aMessage, *this, eventList); + + // Get handler + CMediatorServerEventHandler& eventHandler = Server().EventHandler(); + + // Unsubscribe to events + eventHandler.UnsubscribeEventListL( category, eventList, this ); + + // Cleanup + CleanupStack::PopAndDestroy( &eventList ); + // Complete message in case of no errors + aMessage.Complete( KErrNone ); + + RMediatorDebug::LogStatus(); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::GetDomainsL +// Helper method return registered events. Uses Object handler. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::GetDomainsL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::GetDomainsL")); + + // Construct array to hold registered domains + RDomainList domainList; + CleanupClosePushL( domainList ); + + // Get handler + CMediatorServerObjectHandler& objectHandler = Server().ObjectHandler(); + + // Get the list of events + objectHandler.GetDomainsL( domainList ); + + RMediatorDebug::LogData(aMessage, *this, domainList); + + // Write the information back to client + // 2 is for key information + TInt arraySize = ( sizeof(TUid) ) * domainList.Count(); + + // Check that there's enough space before writing the answer + TInt space = aMessage.GetDesMaxLength(0); // Slot 0 + if ( ( domainList.Count() > 0 ) && ( arraySize <= space ) ) + { + TPtr8 arrayPtr( (TUint8*)&domainList[0], arraySize, arraySize ); + aMessage.WriteL( 0, arrayPtr ); + } + + // Complete message in case of no errors with domain count + aMessage.Complete( domainList.Count() ); + + // Clean up + CleanupStack::PopAndDestroy( &domainList ); + + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::GetCategoriesL +// Helper method return registered events. Uses Object handler. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::GetCategoriesL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::GetCategoriesL")); + + // Read domain information + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Construct array to hold registered categories + RCategoryList categoryList; + CleanupClosePushL( categoryList ); + + // Get handler + CMediatorServerObjectHandler& objectHandler = Server().ObjectHandler(); + + // Get the list of events + objectHandler.GetCategoriesL( category, categoryList ); + + RMediatorDebug::LogData(aMessage, *this, categoryList); + + // Write the information back to client + // 2 is for key information + TInt arraySize = ( sizeof(TUid) ) * categoryList.Count(); + + // Check that there's enough space before writing the answer + TInt space = aMessage.GetDesMaxLength(1); // Slot 1 + if ( ( categoryList.Count() > 0 ) && ( arraySize <= space ) ) + { + TPtr8 arrayPtr( (TUint8*)&categoryList[0], arraySize, arraySize ); + aMessage.WriteL( 1, arrayPtr ); + } + + // Complete message in case of no errors with category count + aMessage.Complete( categoryList.Count() ); + + // Clean up + CleanupStack::PopAndDestroy( &categoryList ); + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::GetCommandsL +// Helper method return registered commands. Uses Object handler. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::GetCommandsL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::GetCommandsL")); + + // Read domain & category information + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Construct array to hold registered events + RCommandList commandList; + CleanupClosePushL( commandList ); + + // Get command list using Object handler + CMediatorServerObjectHandler& objectHandler = Server().ObjectHandler(); + objectHandler.GetCommandsL( category, commandList ); + + RMediatorDebug::LogData(aMessage, *this, commandList); + + // Write command list to slot 1 + if ( CommandListFitsToClientMemory( commandList, aMessage, 1 ) ) + { + WriteCommandListL( commandList, aMessage, 1 ); + } + // if the list does not fit to memory, the client library makes a new synchronous request + // with a large enough write buffer + // Complete message in case of no errors with command count + aMessage.Complete( commandList.Count() ); + + // Clean up + CleanupStack::PopAndDestroy( &commandList ); + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::GetEventsL +// Helper method return registered events. Uses Object Handler +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::GetEventsL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::GetEventsL")); + + // Read domain & category information + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Construct array to hold registered events + REventList eventList; + CleanupClosePushL( eventList ); + + // Get events using Event handler + CMediatorServerObjectHandler& objectHandler = Server().ObjectHandler(); + objectHandler.GetEventsL( category, eventList ); + + RMediatorDebug::LogData(aMessage, *this, eventList); + + // Write event list to slot 1 + if ( EventListFitsToClientMemory( eventList, aMessage, 1 ) ) + { + WriteEventListL( eventList, aMessage, 1 ); + } + // if the list does not fit to memory, the client library makes a new synchronous request + // with a large enough write buffer + + // Complete message in case of no errors with command count + aMessage.Complete( eventList.Count() ); + + // Clean up + CleanupStack::PopAndDestroy( &eventList ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::RaiseEventL +// Helper method to raise events. Uses Event Handler +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::RaiseEventL( const RMessage2& aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::RaiseEventL")); + + // Read domain & category information + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Read event information + TEvent raiseEvent = ReadEventL( aMessage, 1 ); + + // Then read parameter data from slot 2 + HBufC8* eventData = ReadDataLC( aMessage, 2 ); + + RMediatorDebug::LogData(aMessage, *this, raiseEvent); + RMediatorDebug::LogData(aMessage, *this, *eventData); + + // Get handler + CMediatorServerEventHandler& eventHandler = Server().EventHandler(); + + // Raise event + eventHandler.RaiseEventL( category, raiseEvent, *eventData ); + + // Cleanup + CleanupStack::PopAndDestroy( eventData ); + + // Complete message in case of no errors + aMessage.Complete( KErrNone ); + + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::IssueCommandL +// Helper function to handle command request. Uses Command Handler +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::IssueCommandL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::IssueCommandL")); + + // Read domain & category information + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Read command information + TCommand issueCommand = ReadCommandL( aMessage, 1 ); + + // Then read parameter data from slot 2 + HBufC8* commandData = ReadDataLC( aMessage, 2 ); + + RMediatorDebug::LogData(aMessage, *this, issueCommand); + RMediatorDebug::LogData(aMessage, *this, *commandData); + + // Get handler & issue command + TSecurityInfo messageCaps( aMessage ); + CMediatorServerCommandHandler& commandHandler = Server().CommandHandler(); + commandHandler.IssueCommandL( category, + issueCommand, + *commandData, + messageCaps.iCaps, + this ); + + + // cleanup + CleanupStack::PopAndDestroy( commandData ); + + // Complete message in case of no errors + aMessage.Complete( KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::CancelCommandL +// Cancels ongoing command processing. Uses Command Handler +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::CancelCommandL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::CancelCommandL")); + + // Read domain & category information + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Read command information + TCommand cancelCommand = ReadCommandL( aMessage, 1 ); + + RMediatorDebug::LogData(aMessage, *this, cancelCommand); + + // Get handler & cancel command + CMediatorServerCommandHandler& commandHandler = Server().CommandHandler(); + commandHandler.CancelCommand( category, cancelCommand ); + + // Complete initiators async request with KErrCancel + if ( iCommandResponseMessage.Handle() ) + { + + // Write domain & category information to slot 0 + WriteCategoryL( category.iDomain, + category.iCategory, + iCommandResponseMessage, + 0 ); + + // Write event to slot 1 + TVersion version( 0, 0, 0 ); + WriteCommandL( cancelCommand.iCommandId, + version, + iCommandResponseMessage, + 1 ); + + // Status to slot 2 + TPckg statusBuffer( KErrCancel ); + iCommandResponseMessage.WriteL( 2, statusBuffer ); + + // Write data to slot 3 + WriteDataL( KNullDesC8, iCommandResponseMessage, 2 ); + + iCommandResponseMessage.Complete( KErrCancel ); + } + + // Complete message in case of no errors + aMessage.Complete( KErrNone ); + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::IssueResponseL +// Helper function to handle command response. Uses Command Handler +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::IssueResponseL( const RMessage2 &aMessage ) + { + LOG(_L("[Mediator Server]\t CMediatorServerSession::IssueResponseL")); + + // Read domain & category information + TMediatorCategory category = ReadCategoryL( aMessage, 0 ); + + // Read command information + TCommand responseCommand = ReadCommandL( aMessage, 1 ); + + // Then read status data from slot 2 + TPckgBuf statusBuffer; + aMessage.ReadL( 2, statusBuffer ); + TInt status = statusBuffer(); + + // And result data from slot 3 + HBufC8* responseData = ReadDataLC( aMessage, 3 ); + + RMediatorDebug::LogData(aMessage, *this, responseCommand); + RMediatorDebug::LogData(aMessage, *this, *responseData); + + // Get handler & respond to command + TSecurityInfo messageCaps( aMessage ); + CMediatorServerCommandHandler& commandHandler = Server().CommandHandler(); + + TInt err = commandHandler.IssueResponse( category, + responseCommand, + *responseData, + status ); + + if ( err != KErrNone ) + { + // If command is not found, it means that the command initiator has cancelled the command + + // Check the command service list and remove the cancelled command if found, because responder + // can interpret the return value as a cancellation and further notifications are thus not needed + TBool found = EFalse; + for ( TInt index = 0; index < iCommandServiceList.Count() && !found; index++ ) + { + CCommand* commandPtr = iCommandServiceList[index]; + if ( commandPtr ) + { + if ( commandPtr->Domain() == category.iDomain + && commandPtr->Category() == category.iCategory + && commandPtr->Id() == responseCommand.iCommandId + && commandPtr->Status() == ECommandCanceled ) + { + iCommandServiceList.Remove( index ); + delete commandPtr; + commandPtr = NULL; + found = ETrue; + } + } + } + + User::Leave( err ); + } + + // cleanup + CleanupStack::PopAndDestroy( responseData ); + + // Complete message in case of no errors + aMessage.Complete( KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::WaitForEventsL +// Helper method to receive events +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::WaitForEventsL( const RMessage2& aMessage ) + { + // Check if we have already events to be notified + if ( iEventServiceList.Count() > 0 ) + { + CEvent* eventPtr = iEventServiceList[0]; // Take the first event + CleanupStack::PushL( eventPtr ); + iEventServiceList.Remove(0); + + // Write domain & category to slot 0 + WriteCategoryL( eventPtr->Domain(), eventPtr->Category(), aMessage, 0 ); + + // Write event to slot 1 + WriteEventL( eventPtr->Id(), aMessage, 1 ); + + // Write data to slot 2 + WriteDataL( eventPtr->ParameterData(), aMessage, 2 ); + + // Complete message with data amount + aMessage.Complete( eventPtr->ParameterData().Length() ); + + //Cleanup + CleanupStack::PopAndDestroy( eventPtr ); + + TRACE(Print(_L("[Mediator Server]\t Session %d - event buffer %d\n"), this, iEventServiceList.Count() )); + } + else // Start async waiting + { + iEventNotificationMessage = aMessage; + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::WaitForCommandsL +// Helper method to receive commands. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::WaitForCommandsL( const RMessage2& aMessage ) + { + // Check if we have already commands to be delivered + if ( iCommandServiceList.Count() > 0 ) + { + CCommand* commandPtr = iCommandServiceList[0]; // Take the first command + CleanupStack::PushL( commandPtr ); + iCommandServiceList.Remove(0); + + // If it's a pending command it can now be delivered + if ( commandPtr->Status() == ECommandPending ) + { + // Write domain & category to slot 0 + WriteCategoryL( commandPtr->Domain(), commandPtr->Category(), aMessage, 0 ); + + // Write event to slot 1 + WriteCommandL( commandPtr->Id(), commandPtr->Version(), aMessage, 1 ); + + // Write data to slot 2 + WriteDataL( commandPtr->ParameterData(), aMessage, 2 ); + + // Complete message with data amount + aMessage.Complete( commandPtr->ParameterData().Length() ); + + } + // If it's a cancelled command then the responder will be notified about cancellation that + // it was not able to handle before + else if ( commandPtr->Status() == ECommandCanceled ) + { + // Write domain & category to slot 0 + WriteCategoryL( commandPtr->Domain(), commandPtr->Category(), aMessage, 0 ); + + // Write command id and version to slot 1 + WriteCommandL( commandPtr->Id(), commandPtr->Version(), aMessage, 1 ); + + // Status to slot 2 + TPckg statusBuffer( KErrCancel ); + aMessage.WriteL( 2, statusBuffer ); + + // Write data to slot 3 + WriteDataL( KNullDesC8, aMessage, 2 ); + + // Complete message + aMessage.Complete( KErrCancel ); + } + + //Cleanup + CleanupStack::PopAndDestroy( commandPtr ); + + TRACE(Print(_L("[Mediator Server]\t Session %d - command buffer %d\n"), this, iCommandServiceList.Count() )); + } + else // Start async waiting + { + iCommandInitMessage = aMessage; + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::WaitForNotificationsL +// Starts async notification waiting. Uses Object Handler +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::WaitForNotificationsL( const RMessage2& aMessage ) + { + if ( !iNotificationMessage.Handle() ) + { + if ( !iNotificationsRegistered ) + { + // Get handler + CMediatorServerObjectHandler& objectHandler = Server().ObjectHandler(); + objectHandler.AddObserverL( this ); + iNotificationsRegistered = ETrue; + } + iNotificationMessage = aMessage; + + if ( !iNotificationQueue.IsEmpty() ) + { + PurgeNextBufferedNotificationL(); + } + } + else + { + ERROR_LOG(_L("[Mediator] CMediatorServerSession::WaitForNotificationsL: KErrAlreadyExists\n")); + User::Leave( KErrAlreadyExists ); + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::CancelNotificationsL +// Stops async notification waiting. +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::CancelNotificationsL( const RMessage2& aMessage ) + { + CleanNotificationQueue(); + + if ( iNotificationMessage.Handle() ) + { + iNotificationMessage.Complete( KErrCancel ); + } + if ( iNotificationsRegistered ) + { + // Get handler + CMediatorServerObjectHandler& objectHandler = Server().ObjectHandler(); + objectHandler.RemoveObserverL( this ); + iNotificationsRegistered = EFalse; + } + else + { + ERROR_LOG(_L("[Mediator] CMediatorServerSession::CancelNotificationsL: KErrNotFound\n")); + User::Leave( KErrNotFound ); + } + aMessage.Complete( KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::WaitForCommandResponseL +// Async waiting for command responses +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::WaitForCommandResponseL( const RMessage2& aMessage ) + { + // Just take message to member variable to future use + if ( !iCommandResponseMessage.Handle() ) + { + iCommandResponseMessage = aMessage; + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::FetchParameterDataL +// Async waiting for command responses +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::FetchParameterDataL( const RMessage2& aMessage ) + { + // Write data buffer to message slot 0 and complete with size of the buffer + if ( iDataBuffer ) + { + WriteDataL( *iDataBuffer, aMessage, 0 ); + aMessage.Complete( iDataBuffer->Length() ); + delete iDataBuffer; + iDataBuffer = NULL; + } + else + { + aMessage.Complete( 0 ); // Just complete with zero sized data + } + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::FetchNotificationEventListL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::FetchNotificationEventListL( const RMessage2& aMessage ) + { + // Write event list to message slot 0 and complete with count of events in the list + CMediatorQueItem* eventList = iNotificationQueue.First(); + iNotificationQueue.Remove( *eventList ); + CleanupStack::PushL( eventList ); + const REventList* events( eventList->Events() ); + + if ( !events ) + { + // should not ever end up leaving here, as this indicates a + // problem with queue management i.e. a programming error + ERROR_LOG( _L("[Mediator] CMediatorServerSession::FetchNotificationEventListL: notif queue corrupted\n") ); + User::Leave( KErrCorrupt ); + } + + WriteEventListL( *events, aMessage, 0 ); + aMessage.Complete( events->Count() ); + CleanupStack::PopAndDestroy( eventList ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::FetchNotificationCommandListL +// +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::FetchNotificationCommandListL( const RMessage2& aMessage ) + { + // Write command list buffer to message slot 0 and complete count of commands in the list + CMediatorQueItem* commandList = iNotificationQueue.First(); + iNotificationQueue.Remove( *commandList ); + CleanupStack::PushL( commandList ); + const RCommandList* commands( commandList->Commands() ); + + if ( !commands ) + { + // should not ever end up leaving here, as this indicates a + // problem with queue management i.e. a programming error + ERROR_LOG( _L("[Mediator] CMediatorServerSession::FetchNotificationCommandListL: notif queue corrupted\n") ); + User::Leave( KErrCorrupt ); + } + + WriteCommandListL( *commands, aMessage, 0 ); + aMessage.Complete( commands->Count() ); + CleanupStack::PopAndDestroy( commandList ); + } + + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::CancelAll +// Async waiting for command responses +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::CancelAll( const RMessage2& aMessage ) + { + // Cancel all possible async wait operations + CancelAll( KErrCancel ); + // Finally complete own message + aMessage.Complete( KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CMediatorServerSession::CancelAll +// Async waiting for command responses +// (other items were commented in a header). +// ----------------------------------------------------------------------------- +// +void CMediatorServerSession::CancelAll( TInt aError ) + { + // Cancel all possible async wait operations + if ( iCommandResponseMessage.Handle() ) + { + iCommandResponseMessage.Complete( aError ); + } + if ( iCommandInitMessage.Handle() ) + { + iCommandInitMessage.Complete( aError ); + } + if ( iNotificationMessage.Handle() ) + { + CleanNotificationQueue(); + iNotificationMessage.Complete( aError ); + } + if ( iEventNotificationMessage.Handle() ) + { + iEventNotificationMessage.Complete( aError ); + } + } + +// End of File