hti/HtiFramework/src/HtiMessage.cpp
branchRCL_3
changeset 59 8ad140f3dd41
parent 0 a03f92240627
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  CHtiMessage implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "HtiMessage.h"
       
    20 #include "HtiLogging.h"
       
    21 
       
    22 //format constants
       
    23 
       
    24 const TInt KMsgServiceNameOffset = 0;
       
    25 const TInt KMsgBodySizeLen = 4;
       
    26 const TInt KMsgBodySizeOffset = KMsgServiceNameOffset + KHtiMsgServiceUidLen;
       
    27 const TInt KMsgVersionOffset = KMsgBodySizeOffset+KMsgBodySizeLen;
       
    28 const TInt KMsgPriorityOffset = KMsgVersionOffset+1;
       
    29 const TInt KMsgWrapFlagOffset = KMsgPriorityOffset+1;
       
    30 const TInt KMsgExtSizeOffset = KMsgWrapFlagOffset+1;
       
    31 const TInt KMsgCrcOffset = KMsgExtSizeOffset+1; //two bytes field
       
    32 const TInt KMsgExtOffset = KMsgCrcOffset+2;
       
    33 
       
    34 const TInt KMsgHeaderMinSize = KMsgExtOffset;
       
    35 
       
    36 const TInt KMsgMaxBodySize = 0xFFFFFF; //max in KMsgBodySizeLen bytes
       
    37 const TInt KMsgMaxExtSize = 0xFF;
       
    38 
       
    39 const TUint16 KCrcInitValue = 0xFFFF;
       
    40 
       
    41 const TUint8 KDefaultVersion = 1;
       
    42 
       
    43 const TInt CHtiMessage::iLinkOffset = _FOFF( CHtiMessage, iLink );
       
    44 
       
    45 CHtiMessage::CHtiMessage():
       
    46     iBody( NULL ),
       
    47     iBodyDes( NULL ),
       
    48     iBodySize( 0 ),
       
    49     iServiceUid(),
       
    50     iExtRemainderSize( 0 )
       
    51     {
       
    52 
       
    53     }
       
    54 
       
    55 CHtiMessage::~CHtiMessage()
       
    56     {
       
    57     HTI_LOG_FUNC_IN("~CHtiMessage");
       
    58     delete iHeader;
       
    59     delete iBodyDes;
       
    60     delete iBody; //delete if incomplete message is destructed
       
    61     HTI_LOG_FUNC_OUT("~CHtiMessage");
       
    62     }
       
    63 
       
    64 CHtiMessage* CHtiMessage::NewL(const TDesC8& aMessage)
       
    65     {
       
    66     CHtiMessage* obj = new(ELeave) CHtiMessage();
       
    67     CleanupStack::PushL(obj);
       
    68     obj->ConstructL( aMessage );
       
    69     CleanupStack::Pop();
       
    70     return obj;
       
    71     }
       
    72 
       
    73 CHtiMessage* CHtiMessage::NewL( TDesC8* aMessageBody,
       
    74                                const TUid aServiceUid,
       
    75                                TBool aWraped,
       
    76                                TInt aPriority)
       
    77     {
       
    78     CHtiMessage* obj = new(ELeave) CHtiMessage();
       
    79     CleanupStack::PushL(obj);
       
    80     obj->ConstructL( aServiceUid, aMessageBody,
       
    81                     KNullDesC8, aWraped, aPriority );
       
    82     CleanupStack::Pop();
       
    83     return obj;
       
    84     }
       
    85 
       
    86 CHtiMessage* CHtiMessage::NewL( TDesC8* aMessageBody,
       
    87                                const TUid aServiceUid,
       
    88                                const TDesC8& aExtBody,
       
    89                                TBool aWraped,
       
    90                                TInt aPriority)
       
    91     {
       
    92     CHtiMessage* obj = new(ELeave) CHtiMessage();
       
    93     CleanupStack::PushL(obj);
       
    94     obj->ConstructL( aServiceUid, aMessageBody,
       
    95             aExtBody, aWraped, aPriority );
       
    96     CleanupStack::Pop();
       
    97     return obj;
       
    98     }
       
    99 
       
   100 void CHtiMessage::ConstructL(const TUid aServiceUid,
       
   101         TDesC8* aMessageBody,
       
   102         const TDesC8& aExtBody,
       
   103         TBool aWraped,
       
   104         TInt aPriority)
       
   105     {
       
   106     if ( aMessageBody->Length()>KMsgMaxBodySize ||
       
   107          aExtBody.Length()>KMsgMaxExtSize)
       
   108         {
       
   109         User::Leave(KErrArgument);
       
   110         }
       
   111 
       
   112     iBodyDes = aMessageBody;
       
   113     iBodySize = iBodyDes->Length();
       
   114 
       
   115     //allocate header space
       
   116     iHeader = new(ELeave) TUint8[MinHeaderSize() + aExtBody.Length()];
       
   117 
       
   118     //set UID
       
   119     *((TInt32*)(iHeader+KMsgServiceNameOffset)) = aServiceUid.iUid;
       
   120     iServiceUid = aServiceUid;
       
   121 
       
   122     //set msg body size in little-endian
       
   123     *((TUint32*)(iHeader+KMsgBodySizeOffset)) = iBodySize;
       
   124 
       
   125     //set version
       
   126     iHeader[KMsgVersionOffset] = KDefaultVersion;
       
   127 
       
   128     //priority
       
   129     iHeader[KMsgPriorityOffset] = aPriority;
       
   130 
       
   131     //wrapped flag
       
   132     iHeader[KMsgWrapFlagOffset] = aWraped?1:0;
       
   133 
       
   134     //ext size
       
   135     iHeader[KMsgExtSizeOffset] = aExtBody.Length();
       
   136 
       
   137     //set CRC16
       
   138     TUint16 crc16 = KCrcInitValue;
       
   139     Mem::Crc( crc16, iHeader, KMsgCrcOffset );
       
   140     //put crc16 in little-endian format
       
   141     *((TUint16*)(iHeader + KMsgCrcOffset)) = crc16;
       
   142 
       
   143     if ( aExtBody.Length()>0 )
       
   144         {
       
   145         Mem::Copy( iHeader + KMsgExtOffset,
       
   146                    aExtBody.Ptr(),
       
   147                    aExtBody.Length() );
       
   148         }
       
   149     }
       
   150 
       
   151 void CHtiMessage::ConstructL(const TDesC8& aMessage)
       
   152     {
       
   153     if ( !CheckValidHtiHeader( aMessage ) )
       
   154         {
       
   155         User::Leave( KErrArgument );
       
   156         }
       
   157 
       
   158     const TUint8* src = aMessage.Ptr();
       
   159     iBodySize = * ( ( TUint32* ) ( src + KMsgBodySizeOffset ) );
       
   160     TInt extSize = src[KMsgExtSizeOffset];
       
   161     TInt headerSize = MinHeaderSize() + extSize;
       
   162 
       
   163     //allocate header space
       
   164     iHeader = new ( ELeave ) TUint8[headerSize];
       
   165     iBody = HBufC8::NewL( iBodySize );
       
   166 
       
   167     //copy header wo ext
       
   168     Mem::Copy( iHeader, src, MinHeaderSize() );
       
   169 
       
   170     //set iServiceUid
       
   171     iServiceUid.iUid = *( ( TInt32* ) ( src + KMsgServiceNameOffset ) );
       
   172 
       
   173     //copy ext
       
   174     if ( extSize>0 )
       
   175         {
       
   176         if ( aMessage.Length() >= headerSize )
       
   177             {
       
   178             //copy whole extension section
       
   179             Mem::Copy( iHeader + KMsgExtOffset, src + MinHeaderSize(),
       
   180                        extSize );
       
   181             }
       
   182         else
       
   183             {
       
   184             //copy part
       
   185             TInt copyLen = aMessage.Length() - MinHeaderSize();
       
   186             Mem::Copy( iHeader + KMsgExtOffset, src + MinHeaderSize(),
       
   187                        copyLen );
       
   188             iExtRemainderSize = extSize - copyLen;
       
   189             }
       
   190         }
       
   191 
       
   192     //copy body
       
   193     if ( iExtRemainderSize==0 ) //if it's not 0, then there is nothing in
       
   194         {                       //aMessage left
       
   195         TInt availableData = aMessage.Length() - headerSize;
       
   196         if ( availableData >= iBodySize )
       
   197             {
       
   198             iBody->Des().Copy( aMessage.Mid( headerSize, iBodySize ) );
       
   199             //body ready
       
   200             iBodyDes = iBody;
       
   201             iBody = NULL;
       
   202             }
       
   203         else
       
   204             {
       
   205             iBody->Des().Copy( aMessage.Mid( headerSize, availableData ) );
       
   206             }
       
   207         }
       
   208     }
       
   209 
       
   210 TBool CHtiMessage::CheckValidHtiHeader( const TDesC8& aMessage )
       
   211     {
       
   212     TBool parsingResult = aMessage.Length() >= MinHeaderSize();
       
   213     if ( parsingResult )
       
   214         {
       
   215         //check CRC16
       
   216         const TUint8* data = aMessage.Ptr();
       
   217         TUint16 headerCrc16 = * ( ( TUint16* ) ( data + KMsgCrcOffset ) );
       
   218         TUint16 calcCrc16 = KCrcInitValue;
       
   219         Mem::Crc( calcCrc16, data,  KMsgCrcOffset );
       
   220         parsingResult = ( headerCrc16 == calcCrc16 );
       
   221         }
       
   222     return parsingResult;
       
   223     }
       
   224 
       
   225 TInt CHtiMessage::Size( const TDesC8& aMessage )
       
   226     {
       
   227     const TUint8* data = aMessage.Ptr();
       
   228     return ( *( ( TUint32* ) ( data + KMsgBodySizeOffset ) ) ) + KMsgExtOffset
       
   229              + data[KMsgExtSizeOffset];
       
   230     }
       
   231 
       
   232 TBool CHtiMessage::IsBodyComplete() const
       
   233     {
       
   234     return iBody==NULL;
       
   235     }
       
   236 
       
   237 TInt CHtiMessage::AddToBody( const TDesC8& aBodyPart )
       
   238     {
       
   239     if ( ( aBodyPart.Length() + iBody->Length() ) >= iBodySize )
       
   240         {
       
   241         //body ready
       
   242         TInt copyLen = iBodySize - iBody->Length();
       
   243         iBody->Des().Append( aBodyPart.Left( copyLen ) );
       
   244 
       
   245         iBodyDes = iBody;
       
   246         iBody = NULL;
       
   247 
       
   248         return copyLen;
       
   249         }
       
   250     else
       
   251         {
       
   252         //continue
       
   253         iBody->Des().Append( aBodyPart );
       
   254         }
       
   255     return aBodyPart.Length();
       
   256     }
       
   257 
       
   258 TInt CHtiMessage::MinHeaderSize()
       
   259     {
       
   260     return KMsgHeaderMinSize;
       
   261     }
       
   262 
       
   263 TUid CHtiMessage::DestinationServiceUid() const
       
   264     {
       
   265     return iServiceUid;
       
   266     }
       
   267 
       
   268 TInt CHtiMessage::Size() const
       
   269     {
       
   270     return BodySize() + HeaderSize();
       
   271     }
       
   272 
       
   273 TInt CHtiMessage::BodySize() const
       
   274     {
       
   275     return iBodySize;
       
   276     }
       
   277 
       
   278 TInt CHtiMessage::Priority() const
       
   279     {
       
   280     return iHeader[KMsgPriorityOffset];
       
   281     }
       
   282 
       
   283 TBool CHtiMessage::IsWrapped() const
       
   284     {
       
   285     return iHeader[KMsgWrapFlagOffset]!=0;
       
   286     }
       
   287 
       
   288 TInt CHtiMessage::ExtSize() const
       
   289     {
       
   290     return iHeader[KMsgExtSizeOffset];
       
   291     }
       
   292 
       
   293 TPtrC8 CHtiMessage::Extension() const
       
   294     {
       
   295     return TPtrC8( iHeader + KMsgExtOffset, ExtSize() );
       
   296     }
       
   297 
       
   298 TInt CHtiMessage::HeaderSize() const
       
   299     {
       
   300     return KMsgExtOffset + ExtSize();
       
   301     }
       
   302 
       
   303 TPtrC8 CHtiMessage::Header() const
       
   304     {
       
   305     return TPtrC8( iHeader, HeaderSize() );
       
   306     }
       
   307 
       
   308 TPtrC8 CHtiMessage::Body() const
       
   309     {
       
   310     if ( iBodyDes != NULL )
       
   311         {
       
   312         return TPtrC8( *iBodyDes );
       
   313         }
       
   314     return TPtrC8( KNullDesC8 );
       
   315     }