diff -r 7fdc9a71d314 -r 8ad140f3dd41 hti/HtiFramework/src/HtiMessage.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hti/HtiFramework/src/HtiMessage.cpp Wed Oct 13 16:17:58 2010 +0300 @@ -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 ); + }