--- /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" ) ) );
+ }
+ }