sensorservices/sensorserver/src/server/sensrvchanneldatareader.cpp
changeset 0 4e1aa6a622a0
--- /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;
+    }