hti/HtiFramework/src/HtiMessage.cpp
branchRCL_3
changeset 59 8ad140f3dd41
parent 0 a03f92240627
--- /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 );
+    }