natfw/natfwstunturnclient/src/ctransactionidgenerator.cpp
changeset 0 1bce908db942
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/natfw/natfwstunturnclient/src/ctransactionidgenerator.cpp	Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,195 @@
+/*
+* Copyright (c) 2006 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:    
+*
+*/
+
+
+
+
+#include <hash.h>
+#include <e32math.h>
+#include "stunassert.h"
+#include "ctransactionidgenerator.h"
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CTransactionIDGenerator::NewL
+// ---------------------------------------------------------------------------
+//
+CTransactionIDGenerator* CTransactionIDGenerator::NewL()
+    {    
+    return new ( ELeave ) CTransactionIDGenerator();
+    }
+
+// ---------------------------------------------------------------------------
+// CTransactionIDGenerator::CTransactionIDGenerator
+// ---------------------------------------------------------------------------
+//
+CTransactionIDGenerator::CTransactionIDGenerator()
+    {
+    TUint ticks = User::TickCount();
+    TTime now;
+    now.UniversalTime();
+    TInt64 us = now.Int64();
+
+    iSeed = static_cast<TInt64>( ticks ) + us;
+    iCounter = I64LOW( us ) - ticks;
+    }
+
+// ---------------------------------------------------------------------------
+// CTransactionIDGenerator::CTransactionIDGenerator
+// Dummy implementation, as copy constructor is declared private and not used.
+// ---------------------------------------------------------------------------
+//
+CTransactionIDGenerator::CTransactionIDGenerator(
+    const CTransactionIDGenerator& /*aTransactionIDGenerator*/ ) :
+    CBase()
+    {    
+    }
+
+// ---------------------------------------------------------------------------
+// CTransactionIDGenerator::~CTransactionIDGenerator
+// ---------------------------------------------------------------------------
+//
+CTransactionIDGenerator::~CTransactionIDGenerator()
+    {
+    }
+    
+// ---------------------------------------------------------------------------
+// CTransactionIDGenerator::GetIDL
+// CMD5 exists only during hash computing, to save memory.
+// ---------------------------------------------------------------------------
+//
+void CTransactionIDGenerator::GetIDL( TAny* aObject,
+                                      TInt aObjectSize,
+                                      TNATFWUNSAFTransactionID& aTransactionID )
+    {
+    ++iCounter;
+    HBufC8* data = BuildInputDataLC( aObject, aObjectSize );
+
+    CMD5* md5 = CMD5::NewL();
+    CleanupStack::PushL( md5 );
+    TPtrC8 hash = md5->Hash( *data );
+
+    __STUN_ASSERT_L( md5->HashSize() >= KMaxNATFWUNSAFTransactionIdLength,
+                     KErrUnderflow );
+    TPtrC8 ptrToHash = hash.Left(KMaxNATFWUNSAFTransactionIdLength);
+    aTransactionID = ptrToHash;
+
+    CleanupStack::PopAndDestroy( md5 );
+    CleanupStack::PopAndDestroy( data );
+    }
+
+// ---------------------------------------------------------------------------
+// CTransactionIDGenerator::BuildInputDataL
+// ---------------------------------------------------------------------------
+//
+HBufC8* CTransactionIDGenerator::BuildInputDataLC( TAny* aObject,
+                                                   TInt aObjectSize )
+    {
+    const TInt KAmountOfRandomNbrsToFill = 10;
+
+    //Size of the input data buffer. It contains the following items:
+    //
+    //item                        item's size
+    //----                        -----------
+    //iCounter                       sizeof( iCounter )
+    //aObject's state              aObjectSize    
+    //checksum of this               sizeof( TUint16 )
+    //clock info                  sizeof( TInt64 ) + sizeof( TUint )
+    //system info                  sizeof( TUint16 ) + sizeof( TUint8 )
+    //KAmountOfRandomNbrsToFill
+    //random integer values     KAmountOfRandomNbrsToFill * sizeof( TInt )
+    TInt dataSize = sizeof( iCounter ) + aObjectSize +
+                    sizeof( TUint16 ) + sizeof( TInt64 ) + sizeof( TUint ) +
+                    sizeof( TUint16 ) + sizeof( TUint8 ) +
+                    KAmountOfRandomNbrsToFill * sizeof( TInt );
+    HBufC8* buf = HBufC8::NewLC( dataSize );
+
+    TPtr8 ptr = buf->Des();
+
+    ptr.Append( reinterpret_cast<const TUint8*>( &iCounter ),
+                sizeof( iCounter ) );
+    ptr.Append( reinterpret_cast<const TUint8*>( aObject ), aObjectSize );
+    
+    ComputeChecksum( ptr, this, sizeof( this ) );
+
+    AddClockInfo( ptr );
+    AddSystemInfo( ptr );    
+
+    TInt random = 0;
+    TInt randomNumberSize = sizeof( random );
+    while ( ptr.Size() <= ( ptr.MaxSize() - randomNumberSize ) )
+        {
+        random = Math::Rand( iSeed );
+        ptr.Append( reinterpret_cast<const TUint8*>( &random ),
+                    sizeof( random ) );
+        }
+
+    return buf;
+    }
+
+// -----------------------------------------------------------------------------
+// CTransactionIDGenerator::AddClockInfo
+// -----------------------------------------------------------------------------
+//
+void CTransactionIDGenerator::AddClockInfo( TDes8& aBuf ) const
+    {
+    TTime now;
+    now.UniversalTime();
+    TInt64 timeAsInt = now.Int64();
+
+    aBuf.Append( reinterpret_cast<const TUint8*>( &timeAsInt ),
+                 sizeof( timeAsInt ) );
+
+    TUint ticks = User::TickCount();
+    aBuf.Append( reinterpret_cast<const TUint8*>( &ticks ), sizeof( ticks ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CTransactionIDGenerator::AddSystemInfo
+// -----------------------------------------------------------------------------
+//
+void CTransactionIDGenerator::AddSystemInfo( TDes8& aBuf ) const
+    {
+    TInt biggestBlock = 0;
+    TInt totalAvailable = User::Available( biggestBlock );
+    TInt value = biggestBlock + totalAvailable - User::CountAllocCells();
+    ComputeChecksum( aBuf, &value, sizeof( value ) );
+
+    TTimeIntervalSeconds inactivity = User::InactivityTime();
+    if ( inactivity.Int() > 0 )
+        {
+        TUint8 byteVal = static_cast<TUint8>( inactivity.Int() & 0xff );
+        aBuf.Append( &byteVal, sizeof( byteVal ) );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CTransactionIDGenerator::ComputeChecksum
+// ---------------------------------------------------------------------------
+//
+void CTransactionIDGenerator::ComputeChecksum( TDes8& aBuf,
+                                               const TAny* aPtr,
+                                               TInt aLength ) const
+    {
+    __STUN_ASSERT_RETURN( aPtr != NULL, KErrArgument );
+
+    TUint16 cs = 0;
+    Mem::Crc( cs, aPtr, aLength );
+    aBuf.Append( reinterpret_cast<const TUint8*>( &cs ), sizeof( cs ) );
+    }