/*
* 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 <e32base.h>
#include <s32mem.h>
#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<CMediatorQueItem> 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<CMediatorServer*>(const_cast<CServer2*>(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<TInt> 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<TInt> 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<TInt> 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<TInt> 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<TInt> 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