--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sensorservices/sensorserver/src/server/sensrvchanneldatareader.cpp Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,350 @@
+/*
+* Copyright (c) 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: TSensrvChannelDataReader implementation
+*
+*/
+
+
+#include <ecom/implementationinformation.h>
+#include "sensrvchanneldatareader.h"
+#include "sensrvtrace.h"
+
+/**
+* version 1 byte
+* length 1 byte
+* flags 1 byte
+* channeltype 4 bytes
+* contexttype 4 bytes
+* quantity 4 bytes
+* location 1 bytes (byte array, at least length (zero) must be present if empty)
+* vendorid 1 bytes (byte array, at least length (zero) must be present if empty)
+* data type id 4 bytes
+* security policy 8 bytes
+*/
+const TInt KChannelInfoVersion = 1;
+const TInt KChannelGroupBitShift = 4;
+const TInt KByteShift = 8;
+
+/**
+ * An internal helper class for SSY info read stream.
+ *
+ * @lib None.
+ * @since S60 5.0
+ */
+class TSsyInfoReadStream
+ {
+ public:
+ TSsyInfoReadStream( const CImplementationInformation& aSsyInfo );
+ TUint8 ReadTUint8L();
+ TUint32 ReadTUint32L();
+ void ReadTDes8L( TDes8& aValue, TInt aLength );
+ inline TInt DataLeft() const { return iMaxLen - iPos; }
+ inline TInt DataPos() const { return iPos; }
+
+ private:
+ TSsyInfoReadStream();
+ void DoReadL( TAny* aPtr, TInt aLength );
+
+ private:
+ TPtrC8 iDefaultData;
+ TPtrC8 iOpaqueData;
+ TInt iPos;
+ TInt iMaxLen;
+ };
+
+// ---------------------------------------------------------------------------
+// TSsyInfoReadStream::TSsyInfoReadStream
+// ---------------------------------------------------------------------------
+//
+TSsyInfoReadStream::TSsyInfoReadStream( const CImplementationInformation& aSsyInfo ) :
+ iDefaultData( aSsyInfo.DataType() ),
+ iOpaqueData( aSsyInfo.OpaqueData() ),
+ iPos( 0 ),
+ iMaxLen( iDefaultData.Length() + iOpaqueData.Length() )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// TSsyInfoReadStream::ReadTUint8L
+// ---------------------------------------------------------------------------
+//
+TUint8 TSsyInfoReadStream::ReadTUint8L()
+ {
+ TUint8 ret( 0 );
+ DoReadL( &ret, sizeof( TUint8 ) );
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// TSsyInfoReadStream::ReadTUint32L
+// ---------------------------------------------------------------------------
+//
+TUint32 TSsyInfoReadStream::ReadTUint32L()
+ {
+ TUint8 intBytes[ sizeof( TUint32) ];
+ DoReadL( intBytes, sizeof( TUint32 ) );
+
+ // Convert array of bytes read from resource file to TUint32. DoReadL() cannot
+ // directly copy to TUint32 because of potential panics on ARM targets when byte
+ // boundaries are crossed by the raw data read from the resource file.
+ TUint32 ret( 0 );
+ TInt i( sizeof( TUint32 ) );
+ while (i--)
+ {
+ ret <<= KByteShift;
+ ret |= intBytes[ i ];
+ }
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// TSsyInfoReadStream::ReadTDes8L
+// ---------------------------------------------------------------------------
+//
+void TSsyInfoReadStream::ReadTDes8L( TDes8& aValue, TInt aLength )
+ {
+ if ( aLength < 0 || aLength > aValue.MaxLength() )
+ {
+ ERROR_TRACE( ( _L("Sensor server - TSsyInfoReadStream::ReadTDes8L: invalid length %d" ), aLength ) );
+ User::Leave( KErrCorrupt );
+ }
+ else if ( aLength > 0 )
+ {
+ DoReadL( const_cast< TUint8* >( aValue.Ptr() ), aLength );
+ aValue.SetLength( aLength );
+ }
+ else // !aLength
+ {
+ aValue.Zero();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// TSsyInfoReadStream::DoReadL
+// ---------------------------------------------------------------------------
+//
+void TSsyInfoReadStream::DoReadL( TAny* aPtr, TInt aLength )
+ {
+ if ( iPos + aLength > iMaxLen )
+ {
+ ERROR_TRACE( ( _L("Sensor server - TSsyInfoReadStream::DoReadL: read overflow (max %d read %d)" ), iMaxLen, iPos + aLength ) );
+ User::Leave( KErrCorrupt );
+ }
+
+ TUint8* ptr = static_cast< TUint8* >( aPtr );
+ if( (aPtr == NULL) || (ptr == NULL) )
+ return;
+
+ TInt defaultLen( iDefaultData.Length() );
+ if ( iPos < defaultLen )
+ {
+ // Copy from default data and handle possible concatenation
+ TInt len( Min( defaultLen - iPos, aLength ) );
+ Mem::Copy( ptr, iDefaultData.Ptr() + iPos, len );
+ ptr += len;
+ aLength -= len;
+ iPos += len;
+ }
+ if ( aLength > 0 && iPos < iMaxLen )
+ {
+ // Copy from opaque data
+ Mem::Copy( ptr, iOpaqueData.Ptr() + iPos - defaultLen, aLength );
+ iPos += aLength;
+ }
+ }
+
+// ======== LOCAL FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// ReadChannelDataL
+// ---------------------------------------------------------------------------
+//
+static void ReadChannelDataL( TSsyInfoReadStream& aReadStream, TSensrvResourceChannelInfo& aChannel )
+ {
+ COMPONENT_TRACE( _L("Sensor server - ReadChannelDataL") );
+
+ TUint8 flags( aReadStream.ReadTUint8L() ); // Flags field
+ aChannel.iChannelType = aReadStream.ReadTUint32L(); // Channel type field
+ aChannel.iContextType = aReadStream.ReadTUint32L(); // Context type field
+ aChannel.iQuantity = aReadStream.ReadTUint32L(); // Quantity field
+
+ TSensrvResourceChannelInfo::TSensrvChannelGroup group =
+ static_cast<TSensrvResourceChannelInfo::TSensrvChannelGroup>(
+ ( ( flags & TSensrvChannelDataReader::EChannelFlagChannelGroupReserved ) >> KChannelGroupBitShift ) );
+
+ if ( group != TSensrvResourceChannelInfo::ESensrvChannelGroupNotDefined
+ && group != TSensrvResourceChannelInfo::ESensrvChannelGroupData
+ && group != TSensrvResourceChannelInfo::ESensrvChannelGroupEvent
+ && group != TSensrvResourceChannelInfo::ESensrvChannelGroupState )
+ {
+ ERROR_TRACE( _L("Sensor server - ReadChannelDataL: invalid channel group set") );
+ User::Leave( KErrCorrupt );
+ }
+
+ aChannel.iChannelGroup = group;
+
+ // check location present for static channels
+ if ( !( flags & TSensrvChannelDataReader::EChannelFlagDynamic ) &&
+ !( flags & TSensrvChannelDataReader::EChannelFlagLocationPresent ) )
+ {
+ ERROR_TRACE( _L("Sensor server - ReadChannelDataL: location missing for a static channel") );
+ User::Leave( KErrCorrupt );
+ }
+
+ // check required for dynamic channels, will always succeed for static channels
+ if ( flags & TSensrvChannelDataReader::EChannelFlagLocationPresent )
+ {
+ TUint8 locationLen( aReadStream.ReadTUint8L() ); // Location byte array field
+
+ if ( !locationLen )
+ {
+ ERROR_TRACE( _L("Sensor server - ReadChannelDataL: location length is 0 ") );
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( locationLen > KSensrvLocationLength )
+ {
+ ERROR_TRACE( _L("Sensor server - ReadChannelDataL: location length above maximum") );
+ User::Leave( KErrCorrupt );
+ }
+
+ aReadStream.ReadTDes8L( aChannel.iLocation, locationLen );
+ }
+
+ // check vendorId present for static channels
+ if ( !( flags & TSensrvChannelDataReader::EChannelFlagDynamic ) &&
+ !( flags & TSensrvChannelDataReader::EChannelFlagVendorIdPresent ) )
+ {
+ ERROR_TRACE( _L("Sensor server - ReadChannelDataL: vendor id missing for a static channel") );
+ User::Leave( KErrCorrupt );
+ }
+
+ // check required for dynamic channels, will always succeed for static channels
+ if ( flags & TSensrvChannelDataReader::EChannelFlagVendorIdPresent )
+ {
+ TUint8 vendorIdLen( aReadStream.ReadTUint8L() ); // Vendor byte array field
+
+ if ( !vendorIdLen )
+ {
+ ERROR_TRACE( _L("Sensor server - ReadChannelDataL: vendor id length is 0") );
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( vendorIdLen > KSensrvVendorIdLength )
+ {
+ ERROR_TRACE( _L("Sensor server - ReadChannelDataL: vendor id length above maximum") );
+ User::Leave( KErrCorrupt );
+ }
+
+ aReadStream.ReadTDes8L( aChannel.iVendorId, vendorIdLen );
+ }
+
+ aChannel.iChannelDataTypeId = aReadStream.ReadTUint32L(); // Data type Id field
+
+ // Security policy byte array field, if not present encoded as ETypePass i.e. use default
+ if ( flags & TSensrvChannelDataReader::EChannelFlagSecPolicyPresent )
+ {
+ TBuf8< sizeof( TSecurityPolicy ) > policyData;
+ aReadStream.ReadTDes8L( policyData, sizeof( TSecurityPolicy ) );
+ aChannel.iPolicy.Set( policyData );
+ }
+
+ if ( flags & TSensrvChannelDataReader::EChannelFlagDynamic )
+ {
+ aChannel.iDynamic = ETrue;
+ }
+
+ COMPONENT_TRACE( _L("Sensor server - ReadChannelDataL return") );
+ }
+
+// ---------------------------------------------------------------------------
+// ReadChannelsL
+// ---------------------------------------------------------------------------
+//
+void ReadChannelsL( const CImplementationInformation& aSsyInfo,
+ RSensrvResourceChannelInfoList& aChannelList,
+ RSensrvResourceChannelInfoList& aDynamicChannelList )
+ {
+ COMPONENT_TRACE( _L("Sensor server - ReadChannelsL") );
+
+ aChannelList.Reset(); // Clean channel lists
+ aDynamicChannelList.Reset();
+
+ // See the channel data field format from beginning of this file. Parsing logic in nutshell:
+ // 1. Read 'version' and 'length' fields first
+ // 2. Read the actual channel data fields ('flags', ..., 'security policy') using ReadChannelDataL()
+
+ TSsyInfoReadStream readStream( aSsyInfo );
+ while ( readStream.DataLeft() > 0 )
+ {
+ TInt dataStartPos( readStream.DataPos() );
+ TUint8 version( readStream.ReadTUint8L() ); // Version field
+ if ( version != KChannelInfoVersion )
+ {
+ ERROR_TRACE( ( _L("Sensor server - ReadChannelsL: invalid version %d" ), version ) );
+ User::Leave( KErrCorrupt );
+ }
+
+ TInt dataLen( readStream.ReadTUint8L() ); // Length field
+ TSensrvResourceChannelInfo channel;
+ channel.iSsyImplementationUid = aSsyInfo.ImplementationUid();
+ ReadChannelDataL( readStream, channel );
+
+ if ( readStream.DataPos() - dataStartPos != dataLen ) // Verify read data size
+ {
+ ERROR_TRACE( ( _L("Sensor server - ReadChannelsL: invalid data length %d (expected %d)" ),
+ readStream.DataPos() - dataStartPos, dataLen ) );
+ User::Leave( KErrCorrupt );
+ }
+
+ if ( channel.iDynamic )
+ {
+ aDynamicChannelList.AppendL( channel );
+ }
+ else
+ {
+ aChannelList.AppendL( channel );
+ }
+ }
+
+ COMPONENT_TRACE( _L("Sensor server - ReadChannelsL return") );
+ }
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// TSensrvChannelDataReader::ReadChannels
+// ---------------------------------------------------------------------------
+//
+TInt TSensrvChannelDataReader::ReadChannels( const CImplementationInformation& aSsyInfo,
+ RSensrvResourceChannelInfoList& aChannelList,
+ RSensrvResourceChannelInfoList& aDynamicChannelList )
+ {
+ COMPONENT_TRACE( _L("Sensor server - TSensrvChannelDataReader::ReadChannels") );
+
+ TRAPD( ret, ReadChannelsL( aSsyInfo, aChannelList, aDynamicChannelList ) );
+ if ( ret != KErrNone )
+ {
+ ERROR_TRACE( (_L("Sensor server - ReadChannels: error %d SsyUid 0x%x" ), ret, aSsyInfo.ImplementationUid().iUid ) );
+ }
+ else if ( !aChannelList.Count() && !aDynamicChannelList.Count() )
+ {
+ ERROR_TRACE( (_L("Sensor server - ReadChannels: No channels found SsyUid 0x%x" ), aSsyInfo.ImplementationUid().iUid ) );
+ }
+
+ COMPONENT_TRACE( _L("Sensor server - TSensrvChannelDataReader::ReadChannels return" ) );
+
+ return ret;
+ }