testexecmgmt/ucc/Source/hacontroller/CNetworkPartitionManager.cpp
changeset 0 3da2a79470a7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testexecmgmt/ucc/Source/hacontroller/CNetworkPartitionManager.cpp	Mon Mar 08 15:04:18 2010 +0800
@@ -0,0 +1,254 @@
+/*
+* Copyright (c) 2005-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:   
+* CNetworkPartitionManager
+* System Includes
+*
+*/
+
+
+
+
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+#include <assert.h>
+#include <math.h>
+
+
+/*******************************************************************************
+ *
+ * Local Includes
+ *
+ ******************************************************************************/
+#include "CNetworkPartitionManager.h"
+
+
+/*******************************************************************************
+ *
+ * PUBLIC METHOD: CNetworkPartitionManager
+ *
+ ******************************************************************************/
+CNetworkPartitionManager::CNetworkPartitionManager()
+{
+}
+
+
+/*******************************************************************************
+ *
+ * PUBLIC METHOD: ~CNetworkPartitionManager
+ *
+ ******************************************************************************/
+CNetworkPartitionManager::~CNetworkPartitionManager()
+{
+}
+
+
+/*******************************************************************************
+ *
+ * PUBLIC METHOD: SetConfiguration
+ *
+ ******************************************************************************/
+int CNetworkPartitionManager::SetConfiguration( int aBaseNetworkAddress, int aBaseNetworkBitCount, int aSegmentSize )
+{
+	int err;
+	int i;
+
+	// check the params
+	assert( aBaseNetworkBitCount > 0 );
+	assert( aBaseNetworkBitCount <= 31 );
+	assert( aSegmentSize > 0 );
+
+	// check that the chunk size is a power of two
+	err = IsPowerOfTwo( aSegmentSize );
+	if( err == 0 ) {
+		return -1;
+	}
+
+	// calculate the number of bits for each part
+	iBaseNetworkPartBitcount = aBaseNetworkBitCount;
+	iHostPartBitcount = log2( aSegmentSize );
+	iSegmentPartBitcount = 32 - iBaseNetworkPartBitcount - iHostPartBitcount;
+	if( iSegmentPartBitcount < 1 ) {
+		return -1;
+	}
+	iSegmentCount = 1<<iSegmentPartBitcount;
+
+	// create the useful netmasks
+	iBaseNetworkNetmask = NetmaskFromBitcount( iBaseNetworkPartBitcount );
+	iCompleteSegmentNetmask = NetmaskFromBitcount( 32 - iHostPartBitcount );
+
+	// save the other info
+	iBaseNetworkAddress = htonl((ntohl(aBaseNetworkAddress) & iBaseNetworkNetmask));
+	iSegmentSize = aSegmentSize;
+
+	// now create the list of all available segments
+	err = iAddressAllocator.AddToIntegerPool( 0, iSegmentCount-1 );
+	if( err == -1 ) {
+		return -1;
+	}
+
+	// create a mask for the segment bits in position
+	for( iSegmentMask = 0, i = 0; i < iSegmentPartBitcount; i++ ) {
+	  iSegmentMask |= 1<<(iHostPartBitcount + i);
+	}
+
+
+	// done
+	return 0;
+}
+
+
+/*******************************************************************************
+ *
+ * PUBLIC METHOD: AllocateNetworkChunk
+ *
+ ******************************************************************************/
+int CNetworkPartitionManager::AllocateNetworkSegment( int *aNetmaskBitcount, int *aSegmentSize )
+{
+	int segment_number, complete_address, shifted_segment_number;
+
+	// check
+	assert( aSegmentSize != NULL );
+
+	// allocate a segment number
+	segment_number = iAddressAllocator.AllocateInteger();
+	if( segment_number == -1 ) {
+	  return -1;
+	}
+	
+
+	// make a complete address for the segment number
+	complete_address = ntohl( iBaseNetworkAddress );
+	shifted_segment_number = (segment_number << iHostPartBitcount) & (iSegmentMask);
+	complete_address |= shifted_segment_number;
+
+
+	// set the return values
+	complete_address = htonl( complete_address );
+	*aNetmaskBitcount = iBaseNetworkPartBitcount + iSegmentPartBitcount;
+	*aSegmentSize = iSegmentSize;
+	assert( (*aNetmaskBitcount + log2(*aSegmentSize)) == 32 );
+
+	// done
+	return complete_address;
+}
+
+
+/*******************************************************************************
+ *
+ * PUBLIC METHOD: FreeNetworkChunk
+ *
+ ******************************************************************************/
+int CNetworkPartitionManager::FreeNetworkSegment( int aSegmentBaseAddress )
+{
+	int i, err;
+	int segment_number;
+	int lower_bits_segment_mask;
+
+	// create a mask for the segment bits in the lower part of the work
+	for( lower_bits_segment_mask = 0, i = 0; i < iSegmentPartBitcount; i++ ) {
+		lower_bits_segment_mask |= 1<<i;
+	}
+
+	// extract the segment number
+	segment_number = ntohl( aSegmentBaseAddress );
+	segment_number = segment_number >> iHostPartBitcount;
+	segment_number &= lower_bits_segment_mask;
+
+	// make sure this number is in the expected range
+	assert( (segment_number >= 0) && (segment_number < iSegmentCount) );
+
+	// free the segment - this will assert that there are no duplicates
+	err = iAddressAllocator.FreeInteger( segment_number );
+	assert( err == 0 );
+
+	// done
+	return 0;
+}
+
+
+/****************************************************************************************
+ * 
+ * PRIVATE: log2
+ * 
+ ***************************************************************************************/
+int CNetworkPartitionManager::log2( int aValue )
+{
+	double base;
+	double value;
+	double simple_result, integer_result;
+	int rv;
+
+	// if the value is less than zero then we have an error which I want to catch NOW
+	assert( aValue >= 0 );
+	
+	// if the value is zero then - this is also an error?
+	assert( aValue > 0 );
+
+	// calculate the logarithm using doubles (we have to) and convert back to integer
+	base = 2;
+	value = (double)aValue;
+	simple_result = log(value) / log(base);
+	integer_result = ceil(simple_result);
+	rv = (int)integer_result;
+
+	// since this is not very nice (the need for ceil) I verify the result
+	if( (1<<rv) != aValue ) {
+	  fprintf( stderr, "CRITICAL ERROR: log2() made an incorrect calculation - log2(%d) => %d (%g,%g,%g,%g).\n", aValue, rv, base, value, 
+		   simple_result, integer_result );
+	}
+	assert( (1<<rv) == aValue );
+
+	// done - success
+	return rv;
+}
+
+
+/****************************************************************************************
+ * 
+ * PRIVATE: IsPowerOfTwo
+ * 
+ ***************************************************************************************/
+int CNetworkPartitionManager::IsPowerOfTwo( int aValue )
+{
+	int bit_count = 0, i;
+	
+	// check how many bits are set
+	for( i = 0; i < 32; i++ ) {
+		if( (aValue & 0x1) != 0 ) {
+			bit_count++;
+		}
+	}
+
+	// if more than one bit is set then this number is not a power of two
+	return ((bit_count > 1) ? 0 : 1);
+}
+
+
+/****************************************************************************************
+ * 
+ * PRIVATE: NetmaskFromBitcount
+ * 
+ ***************************************************************************************/
+int CNetworkPartitionManager::NetmaskFromBitcount( int aBitCount )
+{
+	int i, netmask = 0;
+	for( netmask = 0, i = 0; i < aBitCount; i++ ) {
+	    netmask |= 1<<(31-i);
+	}
+	return netmask;
+}