diff -r 000000000000 -r 4e1aa6a622a0 sensorservices/sensorserver/src/server/sensrvsession.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sensorservices/sensorserver/src/server/sensrvsession.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,493 @@ +/* +* Copyright (c) 2006-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: Sensor server session +* +*/ + + +#include "sensrvdefines.h" +#include "sensrvsession.h" +#include "sensrvserver.h" +#include "sensrvproxymanager.h" +#include "sensrvclientserver.h" +#include "sensrvtrace.h" +#include "sensrvmessage.h" +#include "sensrvchannelchangequeue.h" + + +// ----------------------------------------------------------------------------- +// C++ constructor +// ----------------------------------------------------------------------------- +// +CSensrvSession::CSensrvSession( CSensrvServer& aServer, + CSensrvProxyManager& aProxyManager, + TSecureId aSecureId ) + : iServer(aServer), + iProxyManager(aProxyManager), + iSecureId(aSecureId) + { + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::CSensrvSession()" ) ) ); + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::CSensrvSession - return" )) ); + } + +// ----------------------------------------------------------------------------- +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CSensrvSession* CSensrvSession::NewL( CSensrvServer& aServer, + CSensrvProxyManager& aProxyManager, + TSecureId aSecureId ) + { + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::NewL()" ) ) ); + + CSensrvSession* self = new( ELeave ) CSensrvSession(aServer, aProxyManager, aSecureId); + + self->ConstructL(); + + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::NewL - return 0x%x" ), self ) ); + + return self; + } + +// ----------------------------------------------------------------------------- +// SensrvSession::ConstructL() +// ----------------------------------------------------------------------------- +// +void CSensrvSession::ConstructL() + { + iProxyManager.AddSession(); + } + +// --------------------------------------------------------- +// Destructor +// --------------------------------------------------------- +// +CSensrvSession::~CSensrvSession() + { + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::~CSensrvSession()" ) ) ); + + if (iAsyncChannelChangeMessage) + { + iProxyManager.RemoveChannelChangeListenerFromDynamicChannelSsys( + iChannelChangeSearchParams, iAsyncChannelChangeMessage->GetMessage()); + } + + // Kill all ongoing transactions and channel listeners initiated by this session + // Note: This is not actually necessary for sessions that are used by channel finder, + // but doing special case for that is not cost effective. + iProxyManager.SessionTerminated(this); + + // iServer and iProxyManager are not owned and therefore not cleaned + + delete iSyncMessage; + delete iAsyncDataMessage; + delete iAsyncPropertyMessage; + delete iAsyncConditionMessage; + delete iAsyncChannelChangeMessage; + + delete iChannelChangeQueue; + +#ifdef MEMORY_TRACE_DEBUG + // TRACE heap usage + TInt heapSize = User::Heap().Size(); + TInt biggestBlock(0); + TInt heapAvail = User::Heap().Available(biggestBlock); + TInt used(heapSize-heapAvail); + MEMORY_TRACE( ( _L( "#### Sensor Server, ~CSensrvSession - HEAP: Size: %d, Available: %d, Used: %d" ), heapSize, heapAvail, used ) ); +#endif + + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::~CSensrvSession - return" ) ) ); + } + +// ----------------------------------------------------------------------------- +// Calls request handling functions. Also traps any leaves and signals client if +// error occurs. +// ----------------------------------------------------------------------------- +// +void CSensrvSession::ServiceL( const RMessage2& aMessage ) + { + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::ServiceL(0x%x)" ), aMessage.Handle() ) ); + +#ifdef MEMORY_TRACE_DEBUG + // TRACE heap usage + TInt heapSize = User::Heap().Size(); + TInt biggestBlock(0); + TInt heapAvail = User::Heap().Available(biggestBlock); + TInt used(heapSize-heapAvail); + MEMORY_TRACE( ( _L( "#### Sensor Server, ServiceL - HEAP: Size: %d, Available: %d, Used: %d" ), heapSize, heapAvail, used ) ); +#endif + +#ifdef API_TRACE_DEBUG + switch ( aMessage.Function() ) + { + case ESensrvSrvReqQueryChannels: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqQueryChannels ####" )) ); + break; + case ESensrvSrvReqOpenChannel: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqOpenChannel ####" )) ); + break; + case ESensrvSrvReqCloseChannel: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqCloseChannel ####" )) ); + break; + case ESensrvSrvReqStartListening: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqStartListening ####" )) ); + break; + case ESensrvSrvReqStopListening: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqStopListening ####" )) ); + break; + case ESensrvSrvReqAsyncChannelData: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqAsyncChannelData ####" )) ); + break; + case ESensrvSrvReqShutdownServer: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqShutdownServer ####" )) ); + break; + case ESensrvSrvReqGetProperty: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqGetProperty ####" )) ); + break; + case ESensrvSrvReqAsyncPropertyData: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqAsyncPropertyData ####" )) ); + break; + case ESensrvSrvReqStopPropertyListening: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqStopPropertyListening ####" )) ); + break; + case ESensrvSrvReqSetProperty: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqSetProperty ####" )) ); + break; + case ESensrvSrvReqGetAllProperties: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqGetAllProperties ####" )) ); + break; + case ESensrvSrvReqAddConditionSet: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqAddConditionSet ####" )) ); + break; + case ESensrvSrvReqRemoveConditionSet: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqRemoveConditionSet ####" )) ); + break; + case ESensrvSrvReqStartConditionListening: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqStartConditionListening ####" )) ); + break; + case ESensrvSrvReqStopConditionListening: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqStopConditionListening ####" )) ); + break; + case ESensrvSrvReqAsyncConditionMet: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqAsyncConditionMet ####" )) ); + break; + case ESensrvSrvReqAsyncChannelChangeNotification: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqAsyncChannelChangeNotification ####" )) ); + break; + case ESensrvSrvReqStopChannelChangeListening: + API_TRACE( ( _L( "#### Sensor Server - Message from client #### ESensrvSrvReqStopChannelChangeListening ####" )) ); + break; + default: + break; + } +#endif + + TInt err(KErrNone); + CSensrvMessage* wrappedMsg = NULL; + + switch ( aMessage.Function() ) + { + case ESensrvSrvReqQueryChannels: + case ESensrvSrvReqOpenChannel: + case ESensrvSrvReqCloseChannel: + case ESensrvSrvReqStartListening: + case ESensrvSrvReqStopListening: + case ESensrvSrvReqGetProperty: + case ESensrvSrvReqStopPropertyListening: + case ESensrvSrvReqSetProperty: + case ESensrvSrvReqGetAllProperties: + case ESensrvSrvReqAddConditionSet: + case ESensrvSrvReqRemoveConditionSet: + case ESensrvSrvReqStartConditionListening: + case ESensrvSrvReqStopConditionListening: + { + if (!iSyncMessage) + { + TRAP( err, iSyncMessage = CSensrvMessage::NewL() ); + } + + wrappedMsg = iSyncMessage; + } + break; + + case ESensrvSrvReqAsyncChannelData: + { + if (!iAsyncDataMessage) + { + TRAP( err, iAsyncDataMessage = CSensrvMessage::NewL() ); + } + + wrappedMsg = iAsyncDataMessage; + } + break; + + case ESensrvSrvReqAsyncPropertyData: + { + if (!iAsyncPropertyMessage) + { + TRAP( err, iAsyncPropertyMessage = CSensrvMessage::NewL() ); + } + + wrappedMsg = iAsyncPropertyMessage; + } + break; + + case ESensrvSrvReqAsyncConditionMet: + { + if (!iAsyncConditionMessage) + { + TRAP( err, iAsyncConditionMessage = CSensrvMessage::NewL() ); + } + + wrappedMsg = iAsyncConditionMessage; + } + break; + + case ESensrvSrvReqAsyncChannelChangeNotification: + { + // Create queue if it doesn't yet exist + if (!iChannelChangeQueue) + { + TRAP(err, iChannelChangeQueue = CSensrvChannelChangeQueue::NewL()); + } + + if (err == KErrNone) + { + // Create async change notification message if it doesn't exist yet + if (!iAsyncChannelChangeMessage) + { + TRAP( err, iAsyncChannelChangeMessage = CSensrvMessage::NewL() ); + if (err != KErrNone) + { + ERROR_TRACE( ( _L( "Sensor Server - CSensrvSession::ServiceL - ERROR: Unable to create channel change notification message wrapper: %d" ), err ) ); + } + } + + // Initialize wrapper and check if there are notifications waiting + if (err == KErrNone) + { + iAsyncChannelChangeMessage->Initialize(aMessage); + + TSensrvChannelInfoPckgBuf searchParamsPckgBuf; + err = iAsyncChannelChangeMessage->Read( KSensrvAsyncChannelSearchParamsSlot, searchParamsPckgBuf ); + if ( err == KErrNone ) + { + iChannelChangeSearchParams = searchParamsPckgBuf(); + + iProxyManager.LoadDynamicChannelSsysIfNeeded( + iChannelChangeSearchParams, iAsyncChannelChangeMessage->GetMessage(), ETrue); // Ignore return value + + CSensrvChannelChangeQueue::TChannelChangeNotification* + changeNotification = iChannelChangeQueue->First(); + + if (changeNotification) + { + CompleteChangeNotificationMessage(changeNotification->iChannelInfo, + changeNotification->iChangeType); + iChannelChangeQueue->RemoveFirst(); + } + } + else + { + ERROR_TRACE( ( _L( "Sensor Server - CSensrvSession::ServiceL - ERROR: Unable to read channel change search params: %d" ), err ) ); + } + } + } + else + { + ERROR_TRACE( ( _L( "Sensor Server - CSensrvSession::ServiceL - ERROR: Unable to create channel change notification queue: %d" ), err ) ); + } + + if ( err != KErrNone ) + { + aMessage.Complete( KErrGeneral ); + } + } + break; + + case ESensrvSrvReqStopChannelChangeListening: + { + if (iAsyncChannelChangeMessage) + { + iProxyManager.RemoveChannelChangeListenerFromDynamicChannelSsys( + iChannelChangeSearchParams, iAsyncChannelChangeMessage->GetMessage()); + } + + // Complete async message before deletion. + if (iAsyncChannelChangeMessage && iAsyncChannelChangeMessage->Handle()) + { + iAsyncChannelChangeMessage->Complete(KErrCancel); + } + + // Delete channel notification queue and asynchronous notification message + delete iChannelChangeQueue; + iChannelChangeQueue = NULL; + delete iAsyncChannelChangeMessage; + iAsyncChannelChangeMessage = NULL; + + // Complete stop message, since it won't be dispatched further. + aMessage.Complete(KErrNone); + } + break; + + case ESensrvSrvReqShutdownServer: + { + // Test framework needs to be able to shutdown the server (checked in sensor server policy) + API_TRACE( ( _L( "Sensor Server - CSensrvSession::ServiceL - Attempting shutdown from 0x%x" ), aMessage.SecureId().iId ) ); + iProxyManager.ShutdownServer(aMessage); + } + break; + + default: + { + ERROR_TRACE( ( _L( "Sensor Server - CSensrvSession::ServiceL - ERROR: Invalid function, panicing client" ) ) ); + aMessage.Panic(KSensrvPanicCategory, ESensrvPanicInvalidFunction); + } + break; + } + + if ( aMessage.Function() == ESensrvSrvReqShutdownServer + || aMessage.Function() == ESensrvSrvReqStopChannelChangeListening + || aMessage.Function() == ESensrvSrvReqAsyncChannelChangeNotification) + { + // Do nothing + } + else if ( wrappedMsg ) + { + wrappedMsg->Initialize(aMessage); + iProxyManager.DispatchMessage(*wrappedMsg); + } + else + { + aMessage.Complete(KErrNoMemory); + } + +#ifdef MEMORY_TRACE_DEBUG + // TRACE heap usage + heapSize = User::Heap().Size(); + heapAvail = User::Heap().Available(biggestBlock); + TInt newUsed(heapSize-heapAvail); + MEMORY_TRACE( ( _L( "#### Sensor Server, ServiceL - HEAP: Size: %d, Available: %d, Used: %d, Change in used: %d" ), heapSize, heapAvail, newUsed, newUsed - used ) ); +#endif + + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::ServiceL - return" )) ); + } + +// ----------------------------------------------------------------------------- +// CSensrvSession::SecureId +// ----------------------------------------------------------------------------- +// +TSecureId CSensrvSession::SecureId() + { + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::SecureId()" ) ) ); + + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::SecureId - return 0x%x" ), iSecureId.iId ) ); + + return iSecureId; + } + +// --------------------------------------------------------------------------- +// Adds channel change to queue if client is interested in such changes, +// unless async message is currently present, in which case will directly +// complete it without queueuing. +// --------------------------------------------------------------------------- +// +void CSensrvSession::NotifyChannelChange(const TSensrvResourceChannelInfo& aChangedChannel, + TSensrvChannelChangeType aChangeType ) + { + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::NotifyChannelChange(aChangedChannel.iChannelId: %d, aChangeType: %d)"), aChangedChannel.iChannelId, aChangeType ) ); + + // Client is interested if notification queue exists + if (iChannelChangeQueue) + { + // If async message is present, handle notification + if (iAsyncChannelChangeMessage && iAsyncChannelChangeMessage->Handle()) + { + CompleteChangeNotificationMessage(aChangedChannel, aChangeType); + } + else + { + // No async message currently, so queue notification + iChannelChangeQueue->Append(aChangedChannel, aChangeType); + } + } + + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::NotifyChannelChange - return" )) ); + } + +// --------------------------------------------------------- +// Completes asynchronous change notification message +// --------------------------------------------------------- +// +void CSensrvSession::CompleteChangeNotificationMessage(const TSensrvResourceChannelInfo& aChangedChannel, + TSensrvChannelChangeType aChangeType ) + { + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::CompleteChangeNotificationMessage(aChangedChannel.iChannelId: %d, aChangeType: %d)" ), aChangedChannel.iChannelId, aChangeType ) ); + + __ASSERT_DEBUG(iAsyncChannelChangeMessage, User::Panic(KSensrvPanicCategory, ESensrvPanicNullMessage)); + __ASSERT_DEBUG(iAsyncChannelChangeMessage->Handle(), User::Panic(KSensrvPanicCategory, ESensrvPanicNullMessage)); + + // Check first if this channel change is interesting and allowed + if ( aChangedChannel.IsMatch( iChannelChangeSearchParams, iAsyncChannelChangeMessage->GetMessage() ) ) + { + // Change is interesting and allowed + TInt err( KErrNone ); + TSensrvChannelInfoPckgBuf infoPckg( aChangedChannel ); + TInt space = iAsyncChannelChangeMessage->GetDesMaxLength( KSensrvAsyncChannelChangeInfoSlot ); + if ( space >= infoPckg.Length() ) + { + err = iAsyncChannelChangeMessage->Write( KSensrvAsyncChannelChangeInfoSlot, infoPckg ); + if (err == KErrNone) + { + TSensrvTSensrvChannelChangeTypePckgBuf changeTypePckg( aChangeType ); + + space = iAsyncChannelChangeMessage->GetDesMaxLength( KSensrvAsyncChannelChangeTypeSlot ); + + if ( space >= changeTypePckg.Length() ) + { + err = iAsyncChannelChangeMessage->Write( KSensrvAsyncChannelChangeTypeSlot, changeTypePckg ); + + if (err != KErrNone) + { + ERROR_TRACE( ( _L( "Sensor Server - CSensrvSession::CompleteChangeNotificationMessage - ERROR: Write to KSensrvAsyncChannelChangeTypeSlot failed: %d" ), err ) ); + } + } + else + { + ERROR_TRACE( ( _L( "Sensor Server - CSensrvSession::CompleteChangeNotificationMessage - ERROR: Not enough space to write to KSensrvAsyncChannelChangeTypeSlot" ) ) ); + err = KErrOverflow; + } + } + else + { + ERROR_TRACE( ( _L( "Sensor Server - CSensrvSession::CompleteChangeNotificationMessage - ERROR: Write to KSensrvAsyncChannelChangeInfoSlot failed: %d" ), err ) ); + } + } + else + { + ERROR_TRACE( ( _L( "Sensor Server - CSensrvSession::CompleteChangeNotificationMessage - ERROR: Not enough space to write to KSensrvAsyncChannelChangeInfoSlot" ) ) ); + err = KErrOverflow; + } + + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::CompleteChangeNotificationMessage - Completing: %d" ), err ) ); + + // Complete message even if there is error. + iAsyncChannelChangeMessage->Complete(err); + } + else + { + // Change was not interesting or allowed + COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvSession::CompleteChangeNotificationMessage - Skipped" ) ) ); + } + }