sensorservices/sensorserver/src/server/sensrvsession.cpp
changeset 0 4e1aa6a622a0
child 76 cb32bcc88bad
--- /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" ) ) );
+        }
+    }