--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/contextframework/cfwplugins/sensorsourceplugin/src/sensorchannelbase.cpp Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,633 @@
+/*
+* 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: CSensorChannelBase class implementation.
+*
+*/
+
+
+#include <sensrvchannel.h>
+#include <sensrvchannelfinder.h>
+
+#include "sensorchannelbase.h"
+#include "sensortrace.h"
+#include "sensorsourcecontextdef.h"
+#include "sensorsourceclient.h"
+#include "sensorsourcecommand.h"
+
+// CONSTANTS
+
+#ifdef _DEBUG
+
+// Converts channel id in to descriptor format
+_LIT( KChannelNameDoubleTap, "DoubleTap" );
+_LIT( KChannelNameOrientation, "Orientation" );
+
+LOCAL_C const TDesC& ChannelName( CSensorChannelBase::TSensorChannelId aId )
+ {
+ switch( aId )
+ {
+ case CSensorChannelBase::EChannelDoubleTap:
+ {
+ return KChannelNameDoubleTap;
+ }
+ case CSensorChannelBase::EChannelOrientation:
+ {
+ return KChannelNameOrientation;
+ }
+ default:
+ {
+ return KNullDesC;
+ }
+ }
+ }
+
+// Converts state id in to descriptor format
+_LIT( KChannelStateIdle, "Idle" );
+_LIT( KChannelStateInit, "Initializing" );
+_LIT( KChannelStateActive, "Active" );
+
+LOCAL_C const TDesC& ChannelStateName(
+ CSensorChannelBase::TSensorChannelState aState )
+ {
+ switch( aState )
+ {
+ case CSensorChannelBase::EChannelStateIdle:
+ {
+ return KChannelStateIdle;
+ }
+ case CSensorChannelBase::EChannelStateInitializing:
+ {
+ return KChannelStateInit;
+ }
+ case CSensorChannelBase::EChannelStateActive:
+ {
+ return KChannelStateActive;
+ }
+ default:
+ {
+ return KNullDesC;
+ }
+ }
+ }
+
+#endif
+
+// Default sample rates
+const TInt KMinSampleRate = 1;
+const TInt KMaxSampleRate = 1;
+const TInt KBufferRate = 0;
+
+// Destructor
+CSensorChannelBase::~CSensorChannelBase()
+ {
+ FUNC_LOG;
+
+ iClients.ResetAndDestroy();
+ delete iContext;
+ if( iSensorChannel )
+ {
+ iSensorChannel->CloseChannel();
+ delete iSensorChannel;
+ }
+ }
+
+// Constructor
+CSensorChannelBase::CSensorChannelBase(
+ MCFContextInterface& aCF,
+ TSensorChannelId aSensorChannel ):
+ iChannelId( aSensorChannel ),
+ iCF( aCF )
+ {
+ FUNC_LOG;
+ }
+
+// 2nd phase constructor
+void CSensorChannelBase::BaseConstructL( const TSensrvChannelInfo& aChannelInfo )
+ {
+ FUNC_LOG;
+
+ iSensorChannel = CSensrvChannel::NewL( aChannelInfo );
+ iContext = CCFContextObject::NewL();
+
+ INFO_1( "Created sensor channel: [%S]", &ChannelName( iChannelId ) );
+
+ ChangeState( EChannelStateIdle );
+ }
+
+// METHODS
+
+//-----------------------------------------------------------------------------
+// CSensorChannelBase::StartListeningL
+//-----------------------------------------------------------------------------
+//
+void CSensorChannelBase::StartListeningL()
+ {
+ FUNC_LOG;
+
+ // If we do not have active connections and the channel is currently in
+ // idle mode
+ if( iState == EChannelStateIdle )
+ {
+ DoStartL( EChannelStateActive );
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CSensorChannelBase::StopListening
+//-----------------------------------------------------------------------------
+//
+void CSensorChannelBase::StopListening()
+ {
+ FUNC_LOG;
+
+ // Check if the channel needs to be closed
+ if( iState == EChannelStateActive )
+ {
+ DoStop();
+ }
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::FetchInitialValueL
+//------------------------------------------------------------------------------
+//
+void CSensorChannelBase::FetchInitialValueL()
+ {
+ FUNC_LOG;
+
+ DoStartL( EChannelStateInitializing );
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::HandleSensorCommandL
+//------------------------------------------------------------------------------
+//
+void CSensorChannelBase::HandleSensorCommandL(
+ const CSensorSourceCommand& aCommand )
+ {
+ FUNC_LOG;
+
+ TPtrC commandId( aCommand.CommandId() );
+
+ // activate
+ if( commandId.CompareF( KSensorCommandIdActivateName )
+ == KErrNone )
+ {
+ HandleActivateCommandL( aCommand );
+ INFO_1( "Handled sensor source command: [%S]", &(const TDesC&)aCommand.CommandId() );
+ }
+ // deactivate
+ else if( commandId.CompareF( KSensorCommandIdDeactivateName )
+ == KErrNone )
+ {
+ HandleDeactivateCommandL( aCommand );
+ INFO_1( "Handled sensor source command: [%S]", &(const TDesC&)aCommand.CommandId() );
+ }
+ // unknown command
+ else
+ {
+ ERROR_1( KErrNotSupported, "Unknown sensor source command: [%S]",
+ &commandId );
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CSensorChannelBase::SensorChannelId
+//-----------------------------------------------------------------------------
+//
+CSensorChannelBase::TSensorChannelId CSensorChannelBase::SensorChannelId() const
+ {
+ FUNC_LOG;
+
+ return iChannelId;
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::SensorActive
+//------------------------------------------------------------------------------
+//
+TBool CSensorChannelBase::SensorActive() const
+ {
+ FUNC_LOG;
+
+ INFO_1( "SensorActive(): active clients [%d]", iClients.Count() );
+
+ return ( iClients.Count() > 0 );
+ }
+
+//-----------------------------------------------------------------------------
+// CSensorChannelBase::DataReceived
+//-----------------------------------------------------------------------------
+//
+void CSensorChannelBase::DataReceived( CSensrvChannel& aChannel,
+ TInt aCount,
+ TInt aDataLost )
+ {
+ FUNC_LOG;
+
+ TRAP_IGNORE( HandleDataReceivedL( aChannel, aCount, aDataLost ) );
+
+ // If we are fetching initial value, make sure that the channel is closed
+ // properly if there are no active connections
+ if( !SensorActive() && iState == EChannelStateInitializing )
+ {
+ // Stop data listening and close up channel
+ DoStop();
+ }
+ else
+ {
+ // Active connections received, change state
+ ChangeState( EChannelStateActive );
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CSensorChannelBase::DataError
+//-----------------------------------------------------------------------------
+//
+void CSensorChannelBase::DataError( CSensrvChannel& /*aChannel*/,
+ TSensrvErrorSeverity aError )
+ {
+ FUNC_LOG;
+
+ ChangeState( EChannelStateIdle );
+ if( aError == ESensrvErrorSeverityFatal )
+ {
+ DoReopenChannel();
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CSensorChannelBase::GetDataListenerInterfaceL
+//-----------------------------------------------------------------------------
+//
+void CSensorChannelBase::GetDataListenerInterfaceL( TUid /*aInterfaceUid*/,
+ TAny*& aInterface )
+ {
+ aInterface = NULL;
+ }
+
+//-----------------------------------------------------------------------------
+// CSensorChannelBase::FindChannelL
+//-----------------------------------------------------------------------------
+//
+TBool CSensorChannelBase::FindChannelL(
+ const TSensrvChannelTypeId& aChannelTypeId,
+ const TDesC8& aLocation,
+ const TDesC8& aVendorId,
+ TSensrvChannelInfo& aChannelInfo )
+ {
+ FUNC_LOG;
+
+ TBool found = EFalse;
+
+ // Configure channel
+ CSensrvChannelFinder* channelFinder = CSensrvChannelFinder::NewLC();
+ RSensrvChannelInfoList channelInfoList;
+ CleanupClosePushL( channelInfoList );
+
+ // Find double tap channel
+ aChannelInfo.iChannelId = 0;
+ aChannelInfo.iContextType = ESensrvContextTypeNotDefined;
+ aChannelInfo.iQuantity = ESensrvQuantityNotdefined;
+ aChannelInfo.iChannelType = aChannelTypeId;
+ aChannelInfo.iLocation = aLocation;
+ aChannelInfo.iVendorId = aVendorId;
+ aChannelInfo.iDataItemSize = 0;
+ channelFinder->FindChannelsL( channelInfoList, aChannelInfo );
+ if( channelInfoList.Count() )
+ {
+ // Take first match and assume it to be best one
+ aChannelInfo = channelInfoList[0];
+ found = ETrue;
+ INFO_3( "Found sensor channel with parameters: ChannelTypeId: [%x], Location: [%S], Vendor: [%S]",
+ aChannelTypeId, &aLocation, &aVendorId );
+ }
+ else
+ {
+ ERROR_3( KErrNotFound, "Did not found sensor channel: ChannelTypeId: [%x], Location: [%S], Vendor: [%S]",
+ aChannelTypeId,
+ &aLocation,
+ &aVendorId );
+ }
+
+ // Cleanup
+ CleanupStack::PopAndDestroy( 2, channelFinder );
+
+ return found;
+ }
+
+//-----------------------------------------------------------------------------
+// CSensorChannelBase::DoReopenChannel
+//-----------------------------------------------------------------------------
+//
+void CSensorChannelBase::DoReopenChannel()
+ {
+ FUNC_LOG;
+
+ delete iSensorChannel;
+ iSensorChannel = NULL;
+ TRAP_IGNORE( StartListeningL() );
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::ChangeState
+//------------------------------------------------------------------------------
+//
+void CSensorChannelBase::ChangeState( TSensorChannelState aState )
+ {
+ FUNC_LOG;
+
+ if( aState != iState )
+ {
+ INFO_3( "Sensor channel [%S] changed state: [%S] -> [%S]",
+ &ChannelName( iChannelId ),
+ &ChannelStateName( iState ),
+ &ChannelStateName( aState ) );
+
+ iState = aState;
+ }
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::SearchCommandByFeatureId
+//------------------------------------------------------------------------------
+//
+TInt CSensorChannelBase::SearchCommandByFeatureId( const TPtrC& aFeatureId ) const
+ {
+ FUNC_LOG;
+
+ TInt ret = KErrNotFound;
+ for( TInt i = 0; i < iClients.Count(); i++ )
+ {
+ CSensorSourceClient* client = iClients[i];
+ if( client->iFeatureId.CompareF( aFeatureId ) == KErrNone )
+ {
+ ret = i;
+ break;
+ }
+ }
+ return ret;
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::SearchCommandBySid
+//------------------------------------------------------------------------------
+//
+TInt CSensorChannelBase::SearchCommandBySid( const TSecureId& aSid ) const
+ {
+ FUNC_LOG;
+
+ TInt ret = KErrNotFound;
+ for( TInt i = 0; i < iClients.Count(); i++ )
+ {
+ CSensorSourceClient* client = iClients[i];
+ if( client->iSid == aSid )
+ {
+ ret = i;
+ break;
+ }
+ }
+ return ret;
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::SearchCommandByScriptId
+//------------------------------------------------------------------------------
+//
+TInt CSensorChannelBase::SearchCommandByScriptId( TInt aScriptId ) const
+ {
+ FUNC_LOG;
+
+ TInt ret = KErrNotFound;
+ for( TInt i = 0; i < iClients.Count(); i++ )
+ {
+ CSensorSourceClient* client = iClients[i];
+ if( client->iScriptId == aScriptId )
+ {
+ ret = i;
+ break;
+ }
+ }
+ return ret;
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::DoStartL
+//------------------------------------------------------------------------------
+//
+void CSensorChannelBase::DoStartL( TSensorChannelState aState )
+ {
+ FUNC_LOG;
+
+ // If we have not connected to channel, connect
+ if( !iSensorChannel )
+ {
+ iSensorChannel = CSensrvChannel::NewL( iChannelInfo );
+ }
+
+ iSensorChannel->OpenChannelL();
+ INFO_1( "Opened sensor channel: [%S]", &ChannelName( iChannelId ) );
+
+ iSensorChannel->StartDataListeningL( this,
+ KMinSampleRate, KMaxSampleRate, KBufferRate );
+ INFO_1( "Started sensor data listening: [%S]", &ChannelName( iChannelId ) );
+
+ ChangeState( aState );
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::DoStop
+//------------------------------------------------------------------------------
+//
+void CSensorChannelBase::DoStop()
+ {
+ FUNC_LOG;
+
+ if( iSensorChannel )
+ {
+ iSensorChannel->StopDataListening();
+ INFO_1( "Stopped sensor data listening: [%S]", &ChannelName( iChannelId ) );
+
+ iSensorChannel->CloseChannel();
+ INFO_1( "Closed sensor channel: [%S]", &ChannelName( iChannelId ) );
+
+ ChangeState( EChannelStateIdle );
+ }
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::HandleActivateCommandL
+//------------------------------------------------------------------------------
+//
+void CSensorChannelBase::HandleActivateCommandL(
+ const CSensorSourceCommand& aCommand )
+ {
+ FUNC_LOG;
+
+ // First check the feature id
+ if( aCommand.FeatureId().Length() )
+ {
+ // Check if the feature already has activated the sensors
+ if( SearchCommandByFeatureId( aCommand.FeatureId() ) == KErrNotFound )
+ {
+ // Activate sensor channel for this feature
+ CSensorSourceClient* client = CSensorSourceClient::NewLC(
+ aCommand.SecureId(), aCommand.ScriptId(), aCommand.FeatureId() );
+ AddClientL( client );
+ CleanupStack::Pop( client );
+ INFO_2( "Sensor channel: [%S] activated by feature: [%S]",
+ &ChannelName( iChannelId ), &(const TDesC&)aCommand.FeatureId() );
+ }
+ else
+ {
+ INFO_2( "Sensor channel: [%S] already activated by feature: [%S]",
+ &ChannelName( iChannelId ), &(const TDesC&)aCommand.FeatureId() );
+ }
+ }
+ // Check the script id
+ else if( aCommand.ScriptId() != KErrNotFound )
+ {
+ // Check if the script id already has activated the sensors
+ if( SearchCommandByScriptId( aCommand.ScriptId() ) == KErrNotFound )
+ {
+ // Activate sensor for this script
+ CSensorSourceClient* client = CSensorSourceClient::NewLC(
+ aCommand.SecureId(), aCommand.ScriptId(), aCommand.FeatureId() );
+ AddClientL( client );
+ CleanupStack::Pop( client );
+ INFO_2( "Sensor channel: [%S] activated by script id: [%d]",
+ &ChannelName( iChannelId ), aCommand.ScriptId() );
+ }
+ else
+ {
+ INFO_2( "Sensor channel: [%S] already activated by script id: [%d]",
+ &ChannelName( iChannelId ), aCommand.ScriptId() );
+ }
+ }
+ // Check the SID
+ else
+ {
+ // Check if the script id already has activated the sensors
+ if( SearchCommandBySid( aCommand.SecureId() ) == KErrNotFound )
+ {
+ // Activate sensor for this Sid
+ CSensorSourceClient* client = CSensorSourceClient::NewLC(
+ aCommand.SecureId(), aCommand.ScriptId(), aCommand.FeatureId() );
+ AddClientL( client );
+ CleanupStack::Pop( client );
+ INFO_2( "Sensor channel: [%S] activated by Sid: [0x%x]",
+ &ChannelName( iChannelId ), aCommand.SecureId().iId );
+ }
+ else
+ {
+ INFO_2( "Sensor channel: [%S] already activated by Sid: [0x%x]",
+ &ChannelName( iChannelId ), aCommand.SecureId().iId );
+ }
+ }
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::HandleDeactivateCommandL
+//------------------------------------------------------------------------------
+//
+void CSensorChannelBase::HandleDeactivateCommandL(
+ const CSensorSourceCommand& aCommand )
+ {
+ FUNC_LOG;
+
+ // First check the feature id
+ if( aCommand.FeatureId().Length() )
+ {
+ // Check if the feature already has activated the sensors
+ TInt index = SearchCommandByFeatureId( aCommand.FeatureId() );
+ if( index != KErrNotFound )
+ {
+ RemoveClient( index );
+ INFO_2( "Sensor channel: [%S] deactivated by feature id: [%S]",
+ &ChannelName( iChannelId ), &(const TDesC&)aCommand.FeatureId() );
+ }
+ }
+ // Check the script id
+ else if( aCommand.ScriptId() != KErrNotFound )
+ {
+ // Check if the script id already has activated the sensors
+ TInt index = SearchCommandByScriptId( aCommand.ScriptId() );
+ if( index != KErrNotFound )
+ {
+ RemoveClient( index );
+ INFO_2( "Sensor channel: [%S] deactivated by script id: [%d]",
+ &ChannelName( iChannelId ), aCommand.ScriptId() );
+ }
+ }
+ // Check the SID
+ else
+ {
+ // Check if the script id already has activated the sensors
+ TInt index = SearchCommandBySid( aCommand.SecureId() );
+ if( index != KErrNotFound )
+ {
+ RemoveClient( index );
+ INFO_2( "Sensor channel: [%S] deactivated by Sid: [0x%x]",
+ &ChannelName( iChannelId ), aCommand.SecureId().iId );
+ }
+ }
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::AddClientL
+//------------------------------------------------------------------------------
+//
+void CSensorChannelBase::AddClientL( CSensorSourceClient* aClient )
+ {
+ FUNC_LOG;
+
+ // Get previous client count
+ TInt oldCount = iClients.Count();
+
+ if( iState == EChannelStateIdle && oldCount == 0 )
+ {
+ // Activate sensor channel
+ StartListeningL();
+ }
+ // Add command in to list
+ iClients.AppendL( aClient );
+
+ INFO_2( "AddClientL(): active clients [%d], old client count [%d]", iClients.Count(), oldCount );
+
+ }
+
+//------------------------------------------------------------------------------
+// CSensorChannelBase::RemoveClient
+//------------------------------------------------------------------------------
+//
+void CSensorChannelBase::RemoveClient( TInt aIndex )
+ {
+ FUNC_LOG;
+
+ if( aIndex >= 0 && aIndex < iClients.Count() )
+ {
+ CSensorSourceClient* client = iClients[aIndex];
+ iClients.Remove( aIndex );
+ if( iClients.Count() == 0 )
+ {
+ // There are no clients anymore, stop sensor channel
+ StopListening();
+ }
+ delete client;
+ client = NULL;
+ }
+ }
+
+// End of file