diff -r 000000000000 -r 4e1aa6a622a0 sensorservices/sensorserver/src/server/sensrvchanneldatareader.cpp --- /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 +#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( + ( ( 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; + }