--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hti/HtiFramework/src/HtiMessage.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,315 @@
+/*
+* Copyright (c) 2009 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: CHtiMessage implementation
+*
+*/
+
+
+#include "HtiMessage.h"
+#include "HtiLogging.h"
+
+//format constants
+
+const TInt KMsgServiceNameOffset = 0;
+const TInt KMsgBodySizeLen = 4;
+const TInt KMsgBodySizeOffset = KMsgServiceNameOffset + KHtiMsgServiceUidLen;
+const TInt KMsgVersionOffset = KMsgBodySizeOffset+KMsgBodySizeLen;
+const TInt KMsgPriorityOffset = KMsgVersionOffset+1;
+const TInt KMsgWrapFlagOffset = KMsgPriorityOffset+1;
+const TInt KMsgExtSizeOffset = KMsgWrapFlagOffset+1;
+const TInt KMsgCrcOffset = KMsgExtSizeOffset+1; //two bytes field
+const TInt KMsgExtOffset = KMsgCrcOffset+2;
+
+const TInt KMsgHeaderMinSize = KMsgExtOffset;
+
+const TInt KMsgMaxBodySize = 0xFFFFFF; //max in KMsgBodySizeLen bytes
+const TInt KMsgMaxExtSize = 0xFF;
+
+const TUint16 KCrcInitValue = 0xFFFF;
+
+const TUint8 KDefaultVersion = 1;
+
+const TInt CHtiMessage::iLinkOffset = _FOFF( CHtiMessage, iLink );
+
+CHtiMessage::CHtiMessage():
+ iBody( NULL ),
+ iBodyDes( NULL ),
+ iBodySize( 0 ),
+ iServiceUid(),
+ iExtRemainderSize( 0 )
+ {
+
+ }
+
+CHtiMessage::~CHtiMessage()
+ {
+ HTI_LOG_FUNC_IN("~CHtiMessage");
+ delete iHeader;
+ delete iBodyDes;
+ delete iBody; //delete if incomplete message is destructed
+ HTI_LOG_FUNC_OUT("~CHtiMessage");
+ }
+
+CHtiMessage* CHtiMessage::NewL(const TDesC8& aMessage)
+ {
+ CHtiMessage* obj = new(ELeave) CHtiMessage();
+ CleanupStack::PushL(obj);
+ obj->ConstructL( aMessage );
+ CleanupStack::Pop();
+ return obj;
+ }
+
+CHtiMessage* CHtiMessage::NewL( TDesC8* aMessageBody,
+ const TUid aServiceUid,
+ TBool aWraped,
+ TInt aPriority)
+ {
+ CHtiMessage* obj = new(ELeave) CHtiMessage();
+ CleanupStack::PushL(obj);
+ obj->ConstructL( aServiceUid, aMessageBody,
+ KNullDesC8, aWraped, aPriority );
+ CleanupStack::Pop();
+ return obj;
+ }
+
+CHtiMessage* CHtiMessage::NewL( TDesC8* aMessageBody,
+ const TUid aServiceUid,
+ const TDesC8& aExtBody,
+ TBool aWraped,
+ TInt aPriority)
+ {
+ CHtiMessage* obj = new(ELeave) CHtiMessage();
+ CleanupStack::PushL(obj);
+ obj->ConstructL( aServiceUid, aMessageBody,
+ aExtBody, aWraped, aPriority );
+ CleanupStack::Pop();
+ return obj;
+ }
+
+void CHtiMessage::ConstructL(const TUid aServiceUid,
+ TDesC8* aMessageBody,
+ const TDesC8& aExtBody,
+ TBool aWraped,
+ TInt aPriority)
+ {
+ if ( aMessageBody->Length()>KMsgMaxBodySize ||
+ aExtBody.Length()>KMsgMaxExtSize)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ iBodyDes = aMessageBody;
+ iBodySize = iBodyDes->Length();
+
+ //allocate header space
+ iHeader = new(ELeave) TUint8[MinHeaderSize() + aExtBody.Length()];
+
+ //set UID
+ *((TInt32*)(iHeader+KMsgServiceNameOffset)) = aServiceUid.iUid;
+ iServiceUid = aServiceUid;
+
+ //set msg body size in little-endian
+ *((TUint32*)(iHeader+KMsgBodySizeOffset)) = iBodySize;
+
+ //set version
+ iHeader[KMsgVersionOffset] = KDefaultVersion;
+
+ //priority
+ iHeader[KMsgPriorityOffset] = aPriority;
+
+ //wrapped flag
+ iHeader[KMsgWrapFlagOffset] = aWraped?1:0;
+
+ //ext size
+ iHeader[KMsgExtSizeOffset] = aExtBody.Length();
+
+ //set CRC16
+ TUint16 crc16 = KCrcInitValue;
+ Mem::Crc( crc16, iHeader, KMsgCrcOffset );
+ //put crc16 in little-endian format
+ *((TUint16*)(iHeader + KMsgCrcOffset)) = crc16;
+
+ if ( aExtBody.Length()>0 )
+ {
+ Mem::Copy( iHeader + KMsgExtOffset,
+ aExtBody.Ptr(),
+ aExtBody.Length() );
+ }
+ }
+
+void CHtiMessage::ConstructL(const TDesC8& aMessage)
+ {
+ if ( !CheckValidHtiHeader( aMessage ) )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ const TUint8* src = aMessage.Ptr();
+ iBodySize = * ( ( TUint32* ) ( src + KMsgBodySizeOffset ) );
+ TInt extSize = src[KMsgExtSizeOffset];
+ TInt headerSize = MinHeaderSize() + extSize;
+
+ //allocate header space
+ iHeader = new ( ELeave ) TUint8[headerSize];
+ iBody = HBufC8::NewL( iBodySize );
+
+ //copy header wo ext
+ Mem::Copy( iHeader, src, MinHeaderSize() );
+
+ //set iServiceUid
+ iServiceUid.iUid = *( ( TInt32* ) ( src + KMsgServiceNameOffset ) );
+
+ //copy ext
+ if ( extSize>0 )
+ {
+ if ( aMessage.Length() >= headerSize )
+ {
+ //copy whole extension section
+ Mem::Copy( iHeader + KMsgExtOffset, src + MinHeaderSize(),
+ extSize );
+ }
+ else
+ {
+ //copy part
+ TInt copyLen = aMessage.Length() - MinHeaderSize();
+ Mem::Copy( iHeader + KMsgExtOffset, src + MinHeaderSize(),
+ copyLen );
+ iExtRemainderSize = extSize - copyLen;
+ }
+ }
+
+ //copy body
+ if ( iExtRemainderSize==0 ) //if it's not 0, then there is nothing in
+ { //aMessage left
+ TInt availableData = aMessage.Length() - headerSize;
+ if ( availableData >= iBodySize )
+ {
+ iBody->Des().Copy( aMessage.Mid( headerSize, iBodySize ) );
+ //body ready
+ iBodyDes = iBody;
+ iBody = NULL;
+ }
+ else
+ {
+ iBody->Des().Copy( aMessage.Mid( headerSize, availableData ) );
+ }
+ }
+ }
+
+TBool CHtiMessage::CheckValidHtiHeader( const TDesC8& aMessage )
+ {
+ TBool parsingResult = aMessage.Length() >= MinHeaderSize();
+ if ( parsingResult )
+ {
+ //check CRC16
+ const TUint8* data = aMessage.Ptr();
+ TUint16 headerCrc16 = * ( ( TUint16* ) ( data + KMsgCrcOffset ) );
+ TUint16 calcCrc16 = KCrcInitValue;
+ Mem::Crc( calcCrc16, data, KMsgCrcOffset );
+ parsingResult = ( headerCrc16 == calcCrc16 );
+ }
+ return parsingResult;
+ }
+
+TInt CHtiMessage::Size( const TDesC8& aMessage )
+ {
+ const TUint8* data = aMessage.Ptr();
+ return ( *( ( TUint32* ) ( data + KMsgBodySizeOffset ) ) ) + KMsgExtOffset
+ + data[KMsgExtSizeOffset];
+ }
+
+TBool CHtiMessage::IsBodyComplete() const
+ {
+ return iBody==NULL;
+ }
+
+TInt CHtiMessage::AddToBody( const TDesC8& aBodyPart )
+ {
+ if ( ( aBodyPart.Length() + iBody->Length() ) >= iBodySize )
+ {
+ //body ready
+ TInt copyLen = iBodySize - iBody->Length();
+ iBody->Des().Append( aBodyPart.Left( copyLen ) );
+
+ iBodyDes = iBody;
+ iBody = NULL;
+
+ return copyLen;
+ }
+ else
+ {
+ //continue
+ iBody->Des().Append( aBodyPart );
+ }
+ return aBodyPart.Length();
+ }
+
+TInt CHtiMessage::MinHeaderSize()
+ {
+ return KMsgHeaderMinSize;
+ }
+
+TUid CHtiMessage::DestinationServiceUid() const
+ {
+ return iServiceUid;
+ }
+
+TInt CHtiMessage::Size() const
+ {
+ return BodySize() + HeaderSize();
+ }
+
+TInt CHtiMessage::BodySize() const
+ {
+ return iBodySize;
+ }
+
+TInt CHtiMessage::Priority() const
+ {
+ return iHeader[KMsgPriorityOffset];
+ }
+
+TBool CHtiMessage::IsWrapped() const
+ {
+ return iHeader[KMsgWrapFlagOffset]!=0;
+ }
+
+TInt CHtiMessage::ExtSize() const
+ {
+ return iHeader[KMsgExtSizeOffset];
+ }
+
+TPtrC8 CHtiMessage::Extension() const
+ {
+ return TPtrC8( iHeader + KMsgExtOffset, ExtSize() );
+ }
+
+TInt CHtiMessage::HeaderSize() const
+ {
+ return KMsgExtOffset + ExtSize();
+ }
+
+TPtrC8 CHtiMessage::Header() const
+ {
+ return TPtrC8( iHeader, HeaderSize() );
+ }
+
+TPtrC8 CHtiMessage::Body() const
+ {
+ if ( iBodyDes != NULL )
+ {
+ return TPtrC8( *iBodyDes );
+ }
+ return TPtrC8( KNullDesC8 );
+ }