--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/accessoryservices/accessoryserver/src/Policy/AccPolAccessoryPolicy.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,1237 @@
+/*
+* Copyright (c) 2002-2006 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: Private, Accessory Policy
+*
+*/
+
+
+// INCLUDE FILES
+#include <AccPolCommonNameValuePairs.h>
+#include <AccPolSubblockNameArray.h>
+#include <AccessoryTypes.h>
+#include <featmgr.h>
+#include "AccPolGenericIDAccessor.h"
+#include "AccPolNameValueArraySerial.h"
+#include "AccPolAccessoryPolicy.h"
+#include "AccPolSubblockNameArrayAccessor.h"
+#include "acc_debug.h"
+#include "AccPolicyDB.h"
+#include "AccPolGenericIDArrayAccessor.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+const TInt KAccMaxRules = 6;
+
+const TInt KAccConfigMaxCapabilityGroups = 64;
+const TInt KAccGidIntBuf = 100;
+const TInt KCapabilityGroupMaxLength = 12;//32 bit number presented in decimal format is 10 character lenght
+
+// bit mask
+const TUint8 KDT = 0x1; // 00000001
+const TUint8 KPC = 0x2; // 00000010
+const TUint8 KAP = 0x4; // 00000100
+const TUint8 KCG = 0x8; // 00001000
+const TUint8 KDI = 0x10; // 00010000
+
+
+// LOCAL CONSTANTS AND MACROS
+
+// MODULE DATA STRUCTURES
+struct TAccPolMultibleConnectionRules
+ {
+ TUint32 iPhysicalConnection;
+ TUint32 iCapabiltyName;
+ };
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::CAccPolAccessoryPolicy
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CAccPolAccessoryPolicy::CAccPolAccessoryPolicy( CCapabilityStorage * aCapabilityStorage )
+ : iCapabilityStorage( aCapabilityStorage ),
+ iCriticalCaps( EFalse )
+ {
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::CAccPolAccessoryPolicy()" );
+
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::CAccPolAccessoryPolicy() - return void" );
+ }
+
+// Destructor
+CAccPolAccessoryPolicy::~CAccPolAccessoryPolicy()
+ {
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::~CAccPolAccessoryPolicy()" );
+
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::~CAccPolAccessoryPolicy() - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// TAccPolGenericID::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CAccPolAccessoryPolicy::ConstructL()
+ {
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ConstructL()" );
+
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ConstructL() - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// TAccPolGenericID::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CAccPolAccessoryPolicy* CAccPolAccessoryPolicy::NewL(
+ CCapabilityStorage * aCapabilityStorage )
+ {
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::NewL()" );
+
+ CAccPolAccessoryPolicy* self = new( ELeave ) CAccPolAccessoryPolicy( aCapabilityStorage );
+
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::CAccPolAccessoryPolicy::NewL() - return" );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::ResolveCriticalCapabilitiesL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAccPolAccessoryPolicy::ResolveCriticalCapabilitiesL(
+ const TAccPolGenericID& aGenericID,
+ CAccPolSubblockNameArray& aCriticalCapabilities )
+ {
+ API_TRACE_1( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ResolveCriticalCapabilitiesL() UniqueId: %d", aGenericID.UniqueID() );
+
+ if( !iCriticalCaps )
+ {
+ //At first time, read all critical capabilities from AccessoryPolicyDB and store them to capability storage.
+ GetAllCriticalCapabilitiesL();
+ iCriticalCaps = ETrue;
+ }
+
+ iCapabilityStorage->ResolveCriticalCapabilitiesL( aGenericID, aCriticalCapabilities );
+
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ResolveCriticalCapabilitiesL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::GetAllCriticalCapabilities
+//
+// Critical capabilities are read from Policy DB
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAccPolAccessoryPolicy::GetAllCriticalCapabilitiesL() const
+ {
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::GetAllCriticalCapabilitiesL()" );
+ TUint32 name( 0 );
+ TInt32 value( 0 );
+ TInt capabilityCount( 0 );
+
+ CAccPolicyDB* db = CAccPolicyDB::NewL();
+ CleanupStack::PushL( db );
+ TRAPD( err, db->OpenDBL() );
+ if ( KErrNone == err )
+ {
+ // Check do we use type as extra search criteria
+ capabilityCount = db->ReadAllCriticalCapabilitiesL();
+ //Go throught all critical capabilities and store them
+ for( TInt i = 0; i < capabilityCount; i++ )
+ {
+ db->GetNextCriticalCapabilityL( name, value );//Get next capability from filtered view...
+ iCapabilityStorage->SetCriticalCapabilityL( name, EAPVNotDefined, EAPVInt, value ); //...and store it
+ }
+ }
+ else
+ {
+ // No need to leave. Result of this is that GenericID contains
+ // unique ID with value KErrNotFound.
+ capabilityCount = 0;
+ }
+
+
+ db->CloseDB();
+ CleanupStack::PopAndDestroy( db );
+
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::GetAllCriticalCapabilitiesL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::IsValidConnectionL
+//
+// Check if connection of the accessory is allowed.
+// Connection is allowed if all critical capabilities have non-critical value.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TAccSrvConnection CAccPolAccessoryPolicy::IsValidConnectionL(
+ const TAccPolGenericID& aGenericID,
+ TInt& aError )
+ {
+ API_TRACE_1( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::IsValidConnectionL() 0x%x", aGenericID.UniqueID() );
+
+ TAccSrvConnection ret( EAccSrvConnect );
+
+ //Chek if all critical capabilities have correct value
+ if( !iCapabilityStorage->CompareCriticalValuesL( aGenericID ) )
+ {
+ ret = EAccSrvDetect;
+ }
+
+ //*************************************************************************
+ // BT-specific connection checkings
+ //
+ // 1. It is not possible to connect more than one
+ // Bluetooth Handsfree Profile accessory at any time.
+ // 2. It is not possible to connect a Bluetooth Handsfree Profile accessory
+ // while in Bluetooth Headset Profile mode.
+ // 3 It is not possible to connect a Bluetooth Headset Profile accessory
+ // while in Bluetooth Handsfree Profile accessory mode.
+ // 4. It is not possible to connect more than one
+ // Bluetooth Headset Profile accessory at any time.
+ //*******************************************************************
+ if( aGenericID.PhysicalConnectionCaps( KPCBluetooth ) )
+ {
+ API_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::IsValidConnectionL() - BT checks" );
+ CAccPolSubblockNameArray* nameArray = CAccPolSubblockNameArray::NewL();
+ CleanupStack::PushL( nameArray );
+
+ if( iCapabilityStorage->GetCapability( aGenericID, KAccBTHSP))
+ {
+ // Accessory supports Headset Profile (HSP).
+ if( iCapabilityStorage->CapabilityInUse( aGenericID, KAccBTHSP ))
+ {
+ // Accessory with Headset Profile (HSP) is allready connected
+ // #4
+ aError = KErrInUse;
+ }
+ if( iCapabilityStorage->CapabilityInUse( aGenericID, KAccBTHFP ) )
+ {
+ // Accessory with Handsfree Profile (HFP) is allready connected
+ // #3
+ aError = KErrInUse;
+ }
+ }
+
+ if( iCapabilityStorage->GetCapability( aGenericID, KAccBTHFP) )
+ {
+ //Accessory supports Handsfree Profile (HFP).
+ if( iCapabilityStorage->CapabilityInUse( aGenericID, KAccBTHSP ) )
+ {
+ // Accessory with Headset Profile (HSP) is allready connected
+ // #2
+ aError = KErrInUse;
+ }
+ if( iCapabilityStorage->CapabilityInUse( aGenericID, KAccBTHFP ) )
+ {
+ // Accessory with Handsfree Profile (HFP) is allready connected
+ // #1
+ aError = KErrInUse;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( nameArray );
+ }
+
+ API_TRACE_1( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::IsValidConnectionL() - return %d", ret );
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::ResolveAccessoryModeL
+// Resolve the accessory mode based on the given set of accessories.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TAccPolAccessoryMode CAccPolAccessoryPolicy::ResolveAccessoryModeL(
+ const TAccPolGenericIDArray& aGenericIDArray,
+ const TInt aPresentUniqueID,
+ const TBool aCurrentAudioOutputStatus,
+ const TAccPolAccessoryMode aCurrentAccessoryMode,
+ const TInt aCurrentAudioOutputStatusUniqueID )
+ {
+
+ COM_TRACE_3( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ResolveAccessoryModeL(mode=%d dbID=%d audio=%d)", aCurrentAccessoryMode.iAccessoryMode, aPresentUniqueID, aCurrentAudioOutputStatus );
+
+ TAccPolAccessoryMode accMode( aCurrentAccessoryMode );
+
+ switch ( aPresentUniqueID )
+ {
+ // KErrUnknown means that HandleAccessoryModeChanged() is
+ // NOT called via AudioRoutingStatusNotify() method.
+ case KErrUnknown:
+ {
+ // Check current mode, if audio is already routed.
+ if( aCurrentAccessoryMode.iAudioOutputStatus && aGenericIDArray.Count() > 0 )
+ {
+ TInt index( TAccPolGenericIDArrayAccessor::FindWithUniqueIDL(
+ aGenericIDArray, aCurrentAudioOutputStatusUniqueID ) );
+ if ( KErrNotFound != index )
+ {
+ // Audio is routed to current GID, so resolve mode because this can be accessory settings case.
+ SetAccessoryModeL( aGenericIDArray.GetGenericIDL( index ), accMode );
+ COM_TRACE_2( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ResolveAccessoryModeL - set mode according to current audio output status UniqueID, (UniqueID=%d, mode=%d) ", aCurrentAudioOutputStatusUniqueID, accMode.iAccessoryMode );
+ }
+ else
+ {
+ // Case when accessory is removed and GID count > 0.
+ GetAccessoryModeFromRulesTableL( aGenericIDArray, accMode );
+ accMode.iAudioOutputStatus = EFalse;
+ COM_TRACE_2( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ResolveAccessoryModeL - No need to resolve accessory mode, (UniqueID=%d, mode=%d) ", aCurrentAudioOutputStatusUniqueID, accMode.iAccessoryMode );
+ }
+ }
+ else
+ {
+ // Set accessory mode using rules table, audio is not routed.
+ GetAccessoryModeFromRulesTableL( aGenericIDArray, accMode );
+ COM_TRACE_1( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ResolveAccessoryModeL - mode is changed: %d", accMode.iAccessoryMode );
+ }
+ }
+ break;
+
+ // AudioRoutingStatusNotify() method is called with a Gereric ID
+ default:
+ {
+ if ( aCurrentAudioOutputStatus )
+ {
+ TInt index( TAccPolGenericIDArrayAccessor::FindWithUniqueIDL(
+ aGenericIDArray, aPresentUniqueID ) );
+ if ( KErrNotFound != index )
+ {
+ // Audio is routed to current GID
+ SetAccessoryModeL( aGenericIDArray.GetGenericIDL( index ), accMode );
+ accMode.iAudioOutputStatus = aCurrentAudioOutputStatus;
+ COM_TRACE_1( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ResolveAccessoryModeL - set mode according to audio routing notification : %d", accMode.iAccessoryMode );
+ }
+ else if ( KErrNotFound == aPresentUniqueID )
+ {
+ // AudioRoutingStatusNotify() method is called with empty Generic ID
+ // which means that audio is routed to phone.
+ accMode.iAccessoryMode = EAccModeHandPortable;
+ accMode.iAudioOutputStatus = aCurrentAudioOutputStatus;
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ResolveAccessoryModeL - mode is handportable" );
+ }
+ else
+ {
+ // AudioRoutingStatusNotify() is called with Generic ID that doesn't exist anymore
+ GetAccessoryModeFromRulesTableL( aGenericIDArray, accMode );
+ accMode.iAudioOutputStatus = EFalse;
+ }
+ }
+ else
+ {
+ // Set accessory mode using rules table.
+ GetAccessoryModeFromRulesTableL( aGenericIDArray, accMode );
+ accMode.iAudioOutputStatus = aCurrentAudioOutputStatus;
+ COM_TRACE_1( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ResolveAccessoryModeL - mode is changed to %d", accMode.iAccessoryMode );
+ }
+ }
+ break;
+ }
+
+ COM_TRACE_2( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::ResolveAccessoryModeL - return %d (audio=%d)", accMode.iAccessoryMode, accMode.iAudioOutputStatus );
+
+ return accMode;
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::GetAccessoryModeFromRulesTableL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CAccPolAccessoryPolicy::GetAccessoryModeFromRulesTableL(
+ const TAccPolGenericIDArray& aGenericIDArray,
+ TAccPolAccessoryMode& aAccMode)
+ {
+
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::GetAccessoryModeFromRulesTableL()" );
+
+ TInt rulesCount(0);
+ TInt GIDIndex;
+ TInt count( aGenericIDArray.Count() );
+
+ // This should allocated from heap in future
+ TAccPolMultibleConnectionRules aAccPolConnRules[KAccMaxRules] =
+ {
+ {KPCWired, KAccStereoAudio},
+ {KPCWired, KAccMonoAudio},
+ {KPCBluetooth, KAccStereoAudio},
+ {KPCBluetooth, KAccMonoAudio},
+ {KPCWired, 0},
+ {KPCBluetooth, 0}
+ };
+
+
+ rulesCount = sizeof ( aAccPolConnRules ) / sizeof ( TAccPolMultibleConnectionRules );
+
+ for( TInt i = 0; i < rulesCount; i++ )
+ {
+ for( GIDIndex = 0; GIDIndex < count; GIDIndex++ )
+ {
+ TAccPolGenericID gID( aGenericIDArray.GetGenericIDL( GIDIndex ) );
+
+ if( aAccPolConnRules[i].iCapabiltyName != 0 )
+ {
+ if( gID.PhysicalConnectionCaps(aAccPolConnRules[i].iPhysicalConnection )
+ && iCapabilityStorage->GetCapability( gID , aAccPolConnRules[i].iCapabiltyName ))
+ {
+ i = rulesCount; //break from rules count loop
+ COM_TRACE_1( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::GetAccessoryModeFromRulesTableL() - mode found (index=%d)",
+ GIDIndex );
+ break;
+ }
+ }
+ else
+ {
+ if( gID.PhysicalConnectionCaps( aAccPolConnRules[i].iPhysicalConnection ) )
+ {
+ i = rulesCount; //break from rules count loop
+ COM_TRACE_1( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::GetAccessoryModeFromRulesTableL() - mode found (index=%d)",
+ GIDIndex );
+ break;
+ }
+ }
+ }
+ }
+
+
+ if(count == GIDIndex)
+ {
+ GIDIndex = 0; // Just get first one in GID array to set mode handportable.
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::GetAccessoryModeFromRulesTableL() - mode not found, set default" );
+ }
+
+ SetAccessoryModeL( aGenericIDArray.GetGenericIDL( GIDIndex ), aAccMode);
+
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::GetAccessoryModeFromRulesTableL() - Return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::SetAccessoryModeL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CAccPolAccessoryPolicy::SetAccessoryModeL(
+ const TAccPolGenericID& gID,
+ TAccPolAccessoryMode& aAccMode) const
+ {
+
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::SetAccessoryModeL() )" );
+
+ TUint32 physicalCon( gID.PhysicalConnectionCaps() );
+
+ if ( physicalCon == 0 )
+ {
+ aAccMode.iAccessoryMode = EAccModeHandPortable;
+ }
+ else if ( gID.PhysicalConnectionCaps( KPCBluetooth ) )
+ {
+ if( gID.DeviceTypeCaps( KDTHeadset ) )
+ {
+ aAccMode.iAccessoryMode = EAccModeWirelessHeadset;
+ }
+ else if( gID.DeviceTypeCaps( KDTCarKit ) )
+ {
+ aAccMode.iAccessoryMode = EAccModeWirelessCarKit;
+ }
+ }
+ else if ( gID.PhysicalConnectionCaps( KPCWired ) ||
+ gID.PhysicalConnectionCaps( KPCHDMI ) )
+ {
+ if( gID.DeviceTypeCaps( KDTHeadset ) )
+ {
+
+ if( iCapabilityStorage->GetCapability( gID , KAccIntegratedAudioInput ) )
+ {
+ aAccMode.iAccessoryMode = EAccModeWiredHeadset;
+ }
+ else
+ {
+ aAccMode.iAccessoryMode = EAccModeHeadphones;
+ }
+ }
+ else if( gID.DeviceTypeCaps( KDTCarKit ) )
+ {
+ aAccMode.iAccessoryMode = EAccModeWiredCarKit;
+ }
+ else if( gID.DeviceTypeCaps( KDTLoopset ) )
+ {
+ aAccMode.iAccessoryMode = EAccModeLoopset;
+ }
+ else if( gID.DeviceTypeCaps( KDTTTY ) )
+ {
+ aAccMode.iAccessoryMode = EAccModeTextDevice;
+ }
+ else if( gID.DeviceTypeCaps( KDTOffice ) )
+ {
+ //Office device is interpreted as MusicStand if it has
+ //mono or stereo audio capability
+ if ( iCapabilityStorage->GetCapability( gID, KAccStereoAudio ) ||
+ iCapabilityStorage->GetCapability( gID, KAccMonoAudio ) )
+ {
+ aAccMode.iAccessoryMode = EAccModeMusicStand;
+ }
+ else
+ {
+ aAccMode.iAccessoryMode = EAccModeHandPortable;
+ }
+ }
+ else if( gID.DeviceTypeCaps( KDTAVDevice ) )
+ {
+ if( gID.SubblockCaps( KSBVideoSubblock ) )
+ {
+ if( gID.PhysicalConnectionCaps( KPCHDMI ) )
+ {
+ aAccMode.iAccessoryMode = EAccModeHDMI;
+ }
+ else
+ {
+ aAccMode.iAccessoryMode = EAccModeTVOut;
+ }
+ }
+ else
+ {
+ aAccMode.iAccessoryMode = EAccModeHandPortable;
+ }
+ }
+ }
+ else
+ {
+ aAccMode.iAccessoryMode = EAccModeHandPortable;
+ }
+
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::SetAccessoryModeL() - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::EvaluateConnectionRulesL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAccPolAccessoryPolicy::EvaluateConnectionRulesL(
+ const TAccPolGenericID& aGenericID,
+ TUint32& aSelectionListBitMask )
+ {
+ TAccPolGenericID staticRule;
+ TBuf8<KGIDIntMaxLength> ruleBuf;
+ TUint64 ruleIndex(0);
+ TBool bMatch = EFalse;
+
+ //Create DB instance
+ CAccPolicyDB* db = CAccPolicyDB::NewL();
+ CleanupStack::PushL( db );
+
+ //Open DB
+ db->OpenDBL();
+
+ //Filter GID by type
+ TInt ruleCount = db->FilterGIDByTypeL( EAccRule );
+
+ //Go throught the connection rules.
+ for(TInt ii = 0; ii < ruleCount; ii++ )
+ {
+
+ //Get next GID from filtered view
+ db->GetNextGIDL( ruleIndex, ruleBuf );
+
+
+ if( ruleBuf.Length() > 0 )
+ {
+
+ //Generic ID instance,
+ CAccConGenericID* decodedRule = CAccConGenericID::NewL();
+ CleanupStack::PushL( decodedRule );
+
+ // Parse GID
+ ParseGenericIDContentL( decodedRule,
+ ruleIndex,
+ KNullDesC,
+ ruleBuf,
+ EAccRule );
+
+ // Return static part of rules
+ staticRule = TAccPolGenericIDAccessor::GenericIDRef( decodedRule );
+
+
+ if( EvaluateGidHeader( aGenericID, staticRule ) )
+ {
+ bMatch = ETrue;
+ db->GetSelectionsL( ruleIndex, aSelectionListBitMask );
+ }
+ else
+ {
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::EvaluateConnectionRulesL() - rule not match" );
+ }
+
+ // Match found, stop loop.
+ if( bMatch )
+ {
+ ii = ruleCount;
+ }
+
+ CleanupStack::PopAndDestroy( decodedRule );
+
+ }
+
+ }
+
+ //Close DB
+ db->CloseDB();
+ CleanupStack::Pop( db );
+ delete db;
+}
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::UpdateGenericIDL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAccPolAccessoryPolicy::UpdateGenericIDL( TAccPolGenericID& aGenericID,
+ const TInt& aSelectionIndex )
+{
+ // Create new GID
+ CAccConGenericID* genericId = CAccConGenericID::NewL();
+ CleanupStack::PushL( genericId );
+
+ //Parse GID
+ TBuf8<KGIDIntMaxLength> gidInt;
+ ParseGenericIDContentL( genericId,
+ aSelectionIndex,
+ KNullDesC,
+ gidInt,
+ EAccSelection );
+
+ //Remove old one
+ iCapabilityStorage->RemoveCapabilitiesL( aGenericID );
+
+ //and create new gid header
+ TAccPolGenericID staticGenericId( TAccPolGenericIDAccessor::GenericIDRef( genericId ));
+ TAccPolGIDHeader header( *((TAccPolGIDHeader*)&staticGenericId));
+ header.iDBID = aGenericID.UniqueID();
+
+ // Update static header part
+ TAccPolGenericIDAccessor::SetGenericIDStaticAttributes( aGenericID, header);
+ iCapabilityStorage->SetGenericIDHeaderL( header);
+
+ //Update caps
+ RBufReadStream rStrm;
+ (void) rStrm.Open( *TAccPolGenericIDAccessor::NameValueBuf( genericId ) );
+ rStrm.PushL();
+ iCapabilityStorage->SetCapabilitiesL( aGenericID, rStrm );
+ rStrm.Close();
+ rStrm.Pop();
+
+ //destroy genericId
+ CleanupStack::PopAndDestroy( genericId );
+}
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::ParseGenericIDContentL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CAccPolAccessoryPolicy::ParseGenericIDContentL(
+ CAccConGenericID* const aGenericID,
+ TUint64 aHWDeviceID,
+ const TDesC& aHWModelID,
+ const TDes8& aGidInt,
+ TAccGIDtype aType )
+ {
+ const TChar KDelimiter = ' '; //space
+ const TChar KLineEnd1 = '\n'; //line feed, new line
+ const TChar KLineEnd2 = '\r' ; //carriage return
+ const TChar KCapabilitiesEndDelimiter = ',' ; //after KCapabilitiesEndDelimiter are values
+
+ API_TRACE_2( "[AccFW:SrvUtil] CAccPolAccessoryPolicy::ParseGenericIDContentL(Device HI:0x%x LO:0x%x)", I64HIGH( aHWDeviceID ), I64LOW( aHWDeviceID ) );
+
+ const TChar KAccSpaceSeparator(' ');
+ RArray<TAccPolNameValueRecord> nameValueArray;
+ CleanupClosePushL( nameValueArray );
+ RBufWriteStream wStrm;
+ TAccPolGenericID genericID;
+ TBuf8<KGIDIntMaxLength> gidInt;
+
+ if ( aType != EAccRule )
+ {
+ //Read Gid integer from database
+ CAccPolicyDB* db = CAccPolicyDB::NewL();
+ CleanupStack::PushL( db );
+ TRAPD( err, db->OpenDBL() );
+ if ( KErrNone == err )
+ {
+ // Check do we use type as extra search criteria
+ if ( EAccUnknown == aType )
+ {
+ // type is unknown, do not use it
+ db->FindGIDIntL( aHWDeviceID, gidInt );
+ TAccPolGenericIDAccessor::SetHWDeviceID( genericID, aHWDeviceID );
+ }
+ else
+ {
+ // Type is known, use it to optimize search
+ db->FindGIDIntL( aHWDeviceID, gidInt, aType );
+ }
+ }
+ else
+ {
+ // No need to leave. Result of this is that GenericID contains
+ // unique ID with value KErrNotFound.
+ TAccPolGenericIDAccessor::SetHWDeviceID( genericID, aHWDeviceID );
+ }
+ db->CloseDB();
+ CleanupStack::Pop( db );
+ delete db;
+ }
+ else
+ {
+ gidInt.Copy( aGidInt );
+ }
+
+ if ( gidInt.Length() > 0 )
+ {
+ TAccPolGenericIDAccessor::SetDBID( genericID, KAccSrvGenerateGID );
+
+ // Parse static GID Data from GIDInteger
+ RArray<TUint64> foundCapabilityGroups;
+ CleanupClosePushL( foundCapabilityGroups );
+ RArray<TUint32> foundCapability;
+ CleanupClosePushL( foundCapability );
+
+ TBuf<KAccGidIntBuf> result;
+ TLex8 buf( gidInt );
+ TUint32 val(0);
+ TInt64 deviceid(0);
+
+ /*** Parse Accessory name, i.e. HW Model ID **************************/
+ TBuf<KHWModelIDMaxLength> modelID;
+ while ( buf.Peek() != KDelimiter )
+ {
+ modelID.Append( buf.Get () );
+ }
+ buf.Inc();// Skip over delimiter between Accessory name and device ID
+
+ if( KErrNone == aHWModelID.Compare( KNullDesC ) )
+ {
+ TAccPolGenericIDAccessor::SetHWModelID( genericID, modelID );
+ }
+ else
+ {
+ TAccPolGenericIDAccessor::SetHWModelID( genericID, aHWModelID );
+ }
+ /*** Skip device ID **************************************************/
+ result.Copy( KNullDesC );
+ while ( buf.Peek() != KDelimiter )
+ {
+ result.Append( buf.Get () );
+ }
+
+ // If type is unknown, DB Query result is different and HWDeviceId is already set
+ if ( EAccUnknown != aType )
+ {
+ // Device ID
+ TLex resDV( result );
+ resDV.Val( deviceid, EDecimal );
+
+ TAccPolGenericIDAccessor::SetHWDeviceID( genericID, deviceid );
+ }
+
+ buf.Inc(); // Skip over delimiter between device ID and GID Int
+ /*** Parse Device Type ***********************************************/
+ result.Copy( KNullDesC );
+ while ( buf.Peek() != KAccSpaceSeparator && !buf.Eos() )
+ {
+ result.Append( buf.Get() );
+ }
+
+ // DT-def block from GID-integer
+ TLex resDT( result );
+ resDT.Val( val, EDecimal );
+ TAccPolGenericIDAccessor::SetFeatureAttributeL( genericID, KAccPolDTDeviceType, val );
+
+ // Parse Physical Connection
+ val = 0;
+ result.Copy( KNullDesC );
+ buf.Inc();
+ while ( buf.Peek() != KAccSpaceSeparator && !buf.Eos() )
+ {
+ result.Append( buf.Get() );
+ }
+ TLex resPC( result );
+ resPC.Val( val, EDecimal );
+ TAccPolGenericIDAccessor::SetFeatureAttributeL(
+ genericID, KAccPolPCPhysicalConnection, val );
+
+ // Parse Application Protocol
+ val = 0;
+ result.Copy( KNullDesC );
+ buf.Inc();
+ while ( buf.Peek() != KAccSpaceSeparator && !buf.Eos() )
+ {
+ result.Append( buf.Get() );
+ }
+ TLex resAP( result );
+ resAP.Val( val, EDecimal );
+ TAccPolGenericIDAccessor::SetFeatureAttributeL(
+ genericID, KAccPolAPApplicationProtocol, val );
+
+ // Parse Capability Groups
+ foundCapabilityGroups.Reset();
+ result.Copy( KNullDesC );
+ buf.Inc();
+ while ( buf.Peek() != KAccSpaceSeparator && !buf.Eos() )
+ {
+ result.Append( buf.Get() );
+ }
+ TLex resSB( result );
+ TInt64 val64( 0 ); // Capability Groups from GID-integer
+ resSB.Val( val64, EDecimal );
+ TUint64 valU64( ( TUint64 ) val64 );
+ TAccPolGenericIDAccessor::SetFeatureAttributeL(
+ genericID, KAccPolSBCapabilities, valU64 );
+
+ ParseSubblocks( valU64, foundCapabilityGroups );
+
+ //set "values" to point to firts value
+ TLex8 values;
+ values.Assign( buf );
+ while ( ( values.Peek() != KLineEnd1 ) &&
+ ( values.Peek() != KLineEnd2 ) &&
+ ( !values.Eos() ) &&
+ ( values.Peek() != KCapabilitiesEndDelimiter ) )
+ {
+ values.Inc();
+ }
+
+ if ( values.Peek() == KCapabilitiesEndDelimiter )
+ {
+ values.Inc();//Skip the delimiter i.e. ","
+ }
+
+ TInt capabilityGroupCount( foundCapabilityGroups.Count() );
+ for ( TInt c(0); c < capabilityGroupCount; ++c )
+ {
+ TInt iterations( 0 ); // Capability Group has 4 namespaces (i.e. 4 times 32 bits)
+ do {
+ TBool firstDigit( ETrue ); // If first digit is 0 then do not insert name (empty)
+ foundCapability.Reset(); // Clear last iterations results
+ buf.Inc();
+
+ TBuf<KCapabilityGroupMaxLength> capabilityGroupVal;
+ while ( buf.Peek() != KAccSpaceSeparator && !buf.Eos() )
+ {
+ if ( firstDigit )
+ {
+ firstDigit = EFalse;
+ TChar c = buf.Get();
+ if ( c == '0' )
+ {
+ break; // from while loop, capability is 0 (not used)
+ }
+ else
+ {
+ capabilityGroupVal.Append( c );
+ }
+ }
+ else
+ {
+ capabilityGroupVal.Append( buf.Get() );
+ }
+ }
+ TLex lVal( capabilityGroupVal );
+ TUint32 capabilityGroupValue(0);
+ lVal.Val( capabilityGroupValue, EDecimal );
+
+ ParseNames( capabilityGroupValue, foundCapability );
+
+ TInt capabilityIter(0);
+ TInt foundCapabilityCount( foundCapability.Count() );
+ while ( capabilityIter < foundCapabilityCount )
+ {
+ //Read Location
+ TBuf<2> locationBuf;
+ while ( values.Peek() != KDelimiter &&
+ ( values.Peek() != KLineEnd1 ) &&
+ ( values.Peek() != KLineEnd2 ) &&
+ ( !values.Eos() ) )
+ {
+ locationBuf.Append( values.Get() );
+ }
+
+ if ( values.Peek() == KDelimiter )
+ {
+ values.Inc();//Skip the delimiter i.e. " "
+ }
+
+ //Read Value
+ TBuf<KSBMaxValueLength> valueBuff;
+ while ( values.Peek() != KDelimiter &&
+ ( values.Peek() != KLineEnd1 ) &&
+ ( values.Peek() != KLineEnd2 ) &&
+ ( !values.Eos() ) )
+ {
+ valueBuff.Append( values.Get() );
+ }
+
+ if ( values.Peek() == KDelimiter )
+ {
+ values.Inc();//Skip the delimiter i.e. " "
+ }
+
+ //Read Type
+ TBuf<2> typeBuf;
+ while ( values.Peek() != KDelimiter &&
+ ( values.Peek() != KLineEnd1 ) &&
+ ( values.Peek() != KLineEnd2 ) &&
+ ( !values.Eos() ) )
+ {
+ typeBuf.Append( values.Get() );
+ }
+
+ if ( values.Peek() == KDelimiter )
+ {
+ values.Inc();//Skip the delimiter i.e. " "
+ }
+
+ TUint capability( 0 );
+
+ capability = BitNumber( foundCapabilityGroups[c] ) << 5;
+ capability = capability + iterations << 5;
+ capability = capability + BitNumber( foundCapability[capabilityIter] );
+
+ TInt location( 0 );
+ TLex loc( locationBuf );
+ loc.Val( location );
+
+ TInt type( 0 );
+ TLex typ( typeBuf );
+ typ.Val( type );
+
+ COM_TRACE_4( "[AccFW:SrvUtil] CAccPolAccessoryPolicy::ParseGenericIDContentL - capability group=(HI:0x%x LO:0x%x) namespace=%d capability=%d", I64HIGH( foundCapabilityGroups[c] ),
+ I64LOW( foundCapabilityGroups[c] ),
+ iterations,
+ foundCapability[capabilityIter] );
+ COM_TRACE_3( "[AccFW:SrvUtil] CAccPolAccessoryPolicy::ParseGenericIDContentL - location=%d type=%d value=%S", location, type, &valueBuff );
+
+ // Format of capability:
+ // =====================
+ //
+ // 0b 000001 00000 00010
+ // ------ ----- -----
+ // | | |
+ // | | |_5 bits for capability. Tells which bit is one (*).
+ // | |_5 bits for namespace,
+ // |_6 bits for capability group. Tells which bit is one (*).
+ //
+ // (*):
+ // 0b00 -> bit number 1 is one -> value is 0b0001=1
+ // 0b01 -> bit number 2 is one -> value is 0b0010=2
+ // 0b10 -> bit number 3 is one -> value is 0b0100=4
+ // 0b11 -> bit number 4 is one -> value is 0b1000=8
+ //
+ COM_TRACE_2( "[AccFW:SrvUtil] CAccPolAccessoryPolicy::ParseGenericIDContentL - capability=0x%x 0b%b", capability, capability );
+
+ //Store value to nameValueArray
+ if( EAPVDes8 != type )
+ {
+ TLex val( valueBuff );
+ TInt value( 0 );
+ val.Val( value );
+ TAccPolNameValueRecord nameValueRecord( capability,
+ value,
+ ( TAccPolValueType )type,
+ ( TAccPolValueLocation )location );
+ nameValueArray.Append( nameValueRecord );
+ }
+ ++capabilityIter;
+ }
+ ++iterations;
+ }
+ while ( iterations <= 3 );
+ }
+
+ //Assign constructed static Generic ID header to
+ //Generic ID given as a parameter
+ TAccPolGenericIDAccessor::SetGenericIDStaticAttributes( aGenericID, genericID );
+ //Externalize vaslues to Generic ID given as a parameter
+ (void) wStrm.Open( *TAccPolGenericIDAccessor::NameValueBuf( aGenericID ) );
+ wStrm.PushL();
+ TAccPolNameValueArraySerial::ExternalizeL( nameValueArray, wStrm );
+ wStrm.CommitL();
+ wStrm.Close();
+ wStrm.Pop();
+
+ CleanupStack::PopAndDestroy( &foundCapability );//foundCapability.Close() is called;
+ CleanupStack::PopAndDestroy( &foundCapabilityGroups );//foundCapabilityGroups.Close() is called;
+ }
+ else
+ {
+ COM_TRACE_( "[AccFW:SrvUtil] Unsupported accessory detected" );
+ }
+
+ CleanupStack::PopAndDestroy( &nameValueArray );//nameValueArray.Close() is called;
+
+ API_TRACE_( "[AccFW:SrvUtil] CAccPolAccessoryPolicy::ParseGenericIDContentL - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::ParseSubblocks
+// Detecting subblocks and store them to destination array
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CAccPolAccessoryPolicy::ParseSubblocks( const TUint64& aVal, RArray<TUint64>& aCaps )
+ {
+ COM_TRACE_( "[AccFW:SrvUtil] CAccConfigFileParser::ParseSubblocks()" );
+
+ TUint64 sum( 0 );
+ TUint64 curVal( 1 );
+ TInt curBit( 0 );
+
+ do {
+ COM_TRACE_4( "[AccFW:SrvUtil] CAccConfigFileParser::(Cap) Binary for this roundtrip is HI:0x%x LO:0x%x, total sum is HI:0x%x LO:0x%x", I64HIGH( curVal ), I64LOW( curVal ), I64HIGH( sum ), I64LOW( sum ) );
+ COM_TRACE_2( "[AccFW:SrvUtil] CAccConfigFileParser::(Cap) & HI:0x%x LO:0x%x", I64HIGH( curVal & aVal ), I64LOW( curVal & aVal ) );
+
+ // Check if this subblock is defined in SB-def block
+ if ( ( curVal & aVal ) == curVal )
+ {
+ COM_TRACE_2( "[AccFW:SrvUtil] CAccConfigFileParser::(Cap) MATCH! HI:0x%x LO:0x%x", I64HIGH( curVal ), I64LOW( curVal ) );
+ aCaps.Append( curVal ); // Append to found caps array
+ sum += curVal;
+ }
+ curBit++;
+ curVal = 2 * curVal;
+ }
+ while ( sum < aVal && curBit < KAccConfigMaxCapabilityGroups );
+
+ COM_TRACE_( "[AccFW:SrvUtil] CAccConfigFileParser::ParseSubblocks - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::ParseNames
+// Detect all subblock names and append them to the gicen array.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CAccPolAccessoryPolicy::ParseNames( const TUint32& aVal, RArray<TUint32>& aNames )
+ {
+ COM_TRACE_( "[AccFW:SrvUtil] CAccConfigFileParser::ParseNames()" );
+ TUint32 sum( 0 );
+ TUint32 curVal( 1 );
+ TInt curBit( 0 );
+
+ do {
+ COM_TRACE_2( "[AccFW:SrvUtil] CAccConfigFileParser::ParseNames Binary for this roundtrip is 0x%x, total sum is 0x%x", curVal, sum );
+ COM_TRACE_1( "[AccFW:SrvUtil] CAccConfigFileParser::ParseNames & 0x%x", curVal & aVal );
+ // Check if this subblock is defined in SB-def block
+
+ if ( ( curVal & aVal ) == curVal )
+ {
+ COM_TRACE_1( "[AccFW:SrvUtil] (Name) MATCH! 0x%x",curVal );
+ aNames.Append( curVal ); // Append to found caps array
+ sum += curVal;
+ }
+ curBit++;
+ curVal = 2 * curVal;
+ }
+ while ( sum < aVal && curBit < KAccConfigMaxCapabilityGroups );
+
+ COM_TRACE_( "[AccFW:SrvUtil] CAccConfigFileParser::ParseNames - return void" );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::BitNumber
+// Find a bit from aBitmask.
+// -----------------------------------------------------------------------------
+//
+TInt CAccPolAccessoryPolicy::BitNumber( TUint64 aBitmask )
+ {
+ API_TRACE_2( "[AccFW:SrvUtil] CAccConfigFileParser::BitNumber(HI:0x%x LO:0x%x)", I64HIGH( aBitmask ), I64LOW( aBitmask ) );
+ TUint64 bitIterator( 1 );
+ TInt currentBit( 0 );
+
+ do {
+ if ( aBitmask & bitIterator )
+ {
+ break;//Found a hit
+ }
+ bitIterator = bitIterator << 1;
+ currentBit++;
+ }
+ while ( currentBit < KAccConfigMaxCapabilityGroups );
+
+ API_TRACE_1( "[AccFW:SrvUtil] CAccConfigFileParser::BitNumber - return %d", currentBit );
+ return currentBit;
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::EvaluateGidHeader
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CAccPolAccessoryPolicy::EvaluateGidHeader(
+ const TAccPolGenericID& aGenericID,
+ const TAccPolGenericID& aGIDRule )
+ {
+
+ TUint32 KDoNotEvaluate(0);
+ TUint8 ruleMatch(0);
+ TUint8 ruleEvaluated(0);
+
+ //Device types
+ if ( aGIDRule.DeviceTypeCaps() != KDoNotEvaluate )
+ {
+ ruleEvaluated = ( ruleEvaluated | KDT ); // Rule evaluated
+ if ( aGIDRule.DeviceTypeCaps() == aGenericID.DeviceTypeCaps() )
+ {
+ ruleMatch = ( ruleMatch | KDT ); //Rule match
+ }
+ else
+ {
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::EvaluateGidHeader - DeviceType rule not evaluated" );
+ }
+ }
+ else
+ {
+ ruleEvaluated = ( 0xFF & ruleEvaluated );
+ }
+
+ //Physical Connection
+ if ( aGIDRule.PhysicalConnectionCaps() != KDoNotEvaluate )
+ {
+ ruleEvaluated = ( ruleEvaluated | KPC );
+ if ( !aGIDRule.PhysicalConnectionCaps() == aGenericID.PhysicalConnectionCaps() )
+ {
+ ruleMatch = ( ruleMatch | KPC );
+ }
+ else
+ {
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::EvaluateGidHeader - PhysicalConnection rule not evaluated" );
+ }
+ }
+ else
+ {
+ ruleEvaluated = ( 0xFF & ruleEvaluated );
+ }
+
+ //Application protocol
+ if ( aGIDRule.ApplicationProtocolCaps() != KDoNotEvaluate )
+ {
+ ruleEvaluated = ( ruleEvaluated | KAP );
+ if ( aGIDRule.ApplicationProtocolCaps() == aGenericID.ApplicationProtocolCaps() )
+ {
+ ruleMatch = ( ruleMatch | KAP );
+ }
+ else
+ {
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::EvaluateGidHeader - ApplicationProtocol rule not evaluated" );
+ }
+ }
+ else
+ {
+ ruleEvaluated = ( 0xFF & ruleEvaluated );
+ }
+
+ //Capability groups
+ if ( aGIDRule.SubblockCaps() != KDoNotEvaluate )
+ {
+ ruleEvaluated = ( ruleEvaluated | KCG );
+ if ( aGIDRule.SubblockCaps() == aGenericID.SubblockCaps() )
+ {
+ ruleMatch = ( ruleMatch | KCG );
+ }
+ else
+ {
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::EvaluateGidHeader - SubblockCaps rule not evaluated" );
+ }
+ }
+ else
+ {
+ ruleEvaluated = ( 0xFF & ruleEvaluated );
+ }
+
+ //DeviceID
+ if( aGIDRule.HWDeviceID() != KDoNotEvaluate )
+ {
+ ruleEvaluated = ( ruleEvaluated | KDI );
+ if ( aGIDRule.HWDeviceID() == aGenericID.HWDeviceID() )
+ {
+ ruleMatch = ( ruleMatch | KDI );
+ }
+ else
+ {
+ COM_TRACE_( "[AccFW: ACCPOLICY] CAccPolAccessoryPolicy::EvaluateGidHeader - HWDeviceID rule not evaluated" );
+ }
+ }
+ else
+ {
+ ruleEvaluated = ( 0xFF & ruleEvaluated );
+ }
+
+ return ( ( ruleEvaluated != 0x0 ) && ( ruleMatch !=0x0 ) && ( ruleEvaluated == ruleMatch ) );
+ }
+
+// -----------------------------------------------------------------------------
+// CAccPolAccessoryPolicy::SupportedHWDevicesL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TUint32 CAccPolAccessoryPolicy::SupportedHWDevicesL()
+ {
+ COM_TRACE_( "[AccFW:ACCPOLICY] CAccPolAccessoryPolicy::SupportedHWDevicesL()" );
+
+ TUint32 dummyRuleIndex( 0 );
+ TUint32 supportedDevices( 0 );
+
+ //Read All supported Device Types from Accessory Policy DB.
+ CAccPolicyDB* db = CAccPolicyDB::NewL();
+ CleanupStack::PushL( db );
+ db->OpenDBL();
+ db->GetSelectionsL( dummyRuleIndex, supportedDevices, ETrue );
+ db->CloseDB();
+ CleanupStack::Pop( db );
+ delete db;
+
+ //AccFW doesnt support Loopsets which can not be identified properly.
+ supportedDevices = supportedDevices & ( ~KASLoopset );
+
+ //Support for following features are queried from FeatureManager.
+ FeatureManager::InitializeLibL();// Initialize FeatureManager for this thread
+ if ( !FeatureManager::FeatureSupported( KFeatureIdPhoneTty ) )
+ {
+ supportedDevices = supportedDevices & ( ~KASTTY );//Device doesn't support TTY
+ }
+ if ( !FeatureManager::FeatureSupported( KFeatureIdTvOut ) )
+ {
+ supportedDevices = supportedDevices & ( ~KASTVOut );//Device doesn't support TV-Out
+ }
+ FeatureManager::UnInitializeLib();// Uninitialize FeatureManager for this thread
+
+ COM_TRACE_1( "[AccFW:ACCPOLICY] CAccPolAccessoryPolicy::SupportedHWDevicesL - return 0b%b", supportedDevices );
+ return supportedDevices;
+ }
+
+// End of File