testexecmgmt/ucc/Source/hacontroller/CNetworkPartitionManager.cpp
changeset 0 3da2a79470a7
equal deleted inserted replaced
-1:000000000000 0:3da2a79470a7
       
     1 /*
       
     2 * Copyright (c) 2005-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:   
       
    15 * CNetworkPartitionManager
       
    16 * System Includes
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 #ifdef WIN32
       
    24 #include <winsock2.h>
       
    25 #else
       
    26 #include <netinet/in.h>
       
    27 #endif
       
    28 #include <assert.h>
       
    29 #include <math.h>
       
    30 
       
    31 
       
    32 /*******************************************************************************
       
    33  *
       
    34  * Local Includes
       
    35  *
       
    36  ******************************************************************************/
       
    37 #include "CNetworkPartitionManager.h"
       
    38 
       
    39 
       
    40 /*******************************************************************************
       
    41  *
       
    42  * PUBLIC METHOD: CNetworkPartitionManager
       
    43  *
       
    44  ******************************************************************************/
       
    45 CNetworkPartitionManager::CNetworkPartitionManager()
       
    46 {
       
    47 }
       
    48 
       
    49 
       
    50 /*******************************************************************************
       
    51  *
       
    52  * PUBLIC METHOD: ~CNetworkPartitionManager
       
    53  *
       
    54  ******************************************************************************/
       
    55 CNetworkPartitionManager::~CNetworkPartitionManager()
       
    56 {
       
    57 }
       
    58 
       
    59 
       
    60 /*******************************************************************************
       
    61  *
       
    62  * PUBLIC METHOD: SetConfiguration
       
    63  *
       
    64  ******************************************************************************/
       
    65 int CNetworkPartitionManager::SetConfiguration( int aBaseNetworkAddress, int aBaseNetworkBitCount, int aSegmentSize )
       
    66 {
       
    67 	int err;
       
    68 	int i;
       
    69 
       
    70 	// check the params
       
    71 	assert( aBaseNetworkBitCount > 0 );
       
    72 	assert( aBaseNetworkBitCount <= 31 );
       
    73 	assert( aSegmentSize > 0 );
       
    74 
       
    75 	// check that the chunk size is a power of two
       
    76 	err = IsPowerOfTwo( aSegmentSize );
       
    77 	if( err == 0 ) {
       
    78 		return -1;
       
    79 	}
       
    80 
       
    81 	// calculate the number of bits for each part
       
    82 	iBaseNetworkPartBitcount = aBaseNetworkBitCount;
       
    83 	iHostPartBitcount = log2( aSegmentSize );
       
    84 	iSegmentPartBitcount = 32 - iBaseNetworkPartBitcount - iHostPartBitcount;
       
    85 	if( iSegmentPartBitcount < 1 ) {
       
    86 		return -1;
       
    87 	}
       
    88 	iSegmentCount = 1<<iSegmentPartBitcount;
       
    89 
       
    90 	// create the useful netmasks
       
    91 	iBaseNetworkNetmask = NetmaskFromBitcount( iBaseNetworkPartBitcount );
       
    92 	iCompleteSegmentNetmask = NetmaskFromBitcount( 32 - iHostPartBitcount );
       
    93 
       
    94 	// save the other info
       
    95 	iBaseNetworkAddress = htonl((ntohl(aBaseNetworkAddress) & iBaseNetworkNetmask));
       
    96 	iSegmentSize = aSegmentSize;
       
    97 
       
    98 	// now create the list of all available segments
       
    99 	err = iAddressAllocator.AddToIntegerPool( 0, iSegmentCount-1 );
       
   100 	if( err == -1 ) {
       
   101 		return -1;
       
   102 	}
       
   103 
       
   104 	// create a mask for the segment bits in position
       
   105 	for( iSegmentMask = 0, i = 0; i < iSegmentPartBitcount; i++ ) {
       
   106 	  iSegmentMask |= 1<<(iHostPartBitcount + i);
       
   107 	}
       
   108 
       
   109 
       
   110 	// done
       
   111 	return 0;
       
   112 }
       
   113 
       
   114 
       
   115 /*******************************************************************************
       
   116  *
       
   117  * PUBLIC METHOD: AllocateNetworkChunk
       
   118  *
       
   119  ******************************************************************************/
       
   120 int CNetworkPartitionManager::AllocateNetworkSegment( int *aNetmaskBitcount, int *aSegmentSize )
       
   121 {
       
   122 	int segment_number, complete_address, shifted_segment_number;
       
   123 
       
   124 	// check
       
   125 	assert( aSegmentSize != NULL );
       
   126 
       
   127 	// allocate a segment number
       
   128 	segment_number = iAddressAllocator.AllocateInteger();
       
   129 	if( segment_number == -1 ) {
       
   130 	  return -1;
       
   131 	}
       
   132 	
       
   133 
       
   134 	// make a complete address for the segment number
       
   135 	complete_address = ntohl( iBaseNetworkAddress );
       
   136 	shifted_segment_number = (segment_number << iHostPartBitcount) & (iSegmentMask);
       
   137 	complete_address |= shifted_segment_number;
       
   138 
       
   139 
       
   140 	// set the return values
       
   141 	complete_address = htonl( complete_address );
       
   142 	*aNetmaskBitcount = iBaseNetworkPartBitcount + iSegmentPartBitcount;
       
   143 	*aSegmentSize = iSegmentSize;
       
   144 	assert( (*aNetmaskBitcount + log2(*aSegmentSize)) == 32 );
       
   145 
       
   146 	// done
       
   147 	return complete_address;
       
   148 }
       
   149 
       
   150 
       
   151 /*******************************************************************************
       
   152  *
       
   153  * PUBLIC METHOD: FreeNetworkChunk
       
   154  *
       
   155  ******************************************************************************/
       
   156 int CNetworkPartitionManager::FreeNetworkSegment( int aSegmentBaseAddress )
       
   157 {
       
   158 	int i, err;
       
   159 	int segment_number;
       
   160 	int lower_bits_segment_mask;
       
   161 
       
   162 	// create a mask for the segment bits in the lower part of the work
       
   163 	for( lower_bits_segment_mask = 0, i = 0; i < iSegmentPartBitcount; i++ ) {
       
   164 		lower_bits_segment_mask |= 1<<i;
       
   165 	}
       
   166 
       
   167 	// extract the segment number
       
   168 	segment_number = ntohl( aSegmentBaseAddress );
       
   169 	segment_number = segment_number >> iHostPartBitcount;
       
   170 	segment_number &= lower_bits_segment_mask;
       
   171 
       
   172 	// make sure this number is in the expected range
       
   173 	assert( (segment_number >= 0) && (segment_number < iSegmentCount) );
       
   174 
       
   175 	// free the segment - this will assert that there are no duplicates
       
   176 	err = iAddressAllocator.FreeInteger( segment_number );
       
   177 	assert( err == 0 );
       
   178 
       
   179 	// done
       
   180 	return 0;
       
   181 }
       
   182 
       
   183 
       
   184 /****************************************************************************************
       
   185  * 
       
   186  * PRIVATE: log2
       
   187  * 
       
   188  ***************************************************************************************/
       
   189 int CNetworkPartitionManager::log2( int aValue )
       
   190 {
       
   191 	double base;
       
   192 	double value;
       
   193 	double simple_result, integer_result;
       
   194 	int rv;
       
   195 
       
   196 	// if the value is less than zero then we have an error which I want to catch NOW
       
   197 	assert( aValue >= 0 );
       
   198 	
       
   199 	// if the value is zero then - this is also an error?
       
   200 	assert( aValue > 0 );
       
   201 
       
   202 	// calculate the logarithm using doubles (we have to) and convert back to integer
       
   203 	base = 2;
       
   204 	value = (double)aValue;
       
   205 	simple_result = log(value) / log(base);
       
   206 	integer_result = ceil(simple_result);
       
   207 	rv = (int)integer_result;
       
   208 
       
   209 	// since this is not very nice (the need for ceil) I verify the result
       
   210 	if( (1<<rv) != aValue ) {
       
   211 	  fprintf( stderr, "CRITICAL ERROR: log2() made an incorrect calculation - log2(%d) => %d (%g,%g,%g,%g).\n", aValue, rv, base, value, 
       
   212 		   simple_result, integer_result );
       
   213 	}
       
   214 	assert( (1<<rv) == aValue );
       
   215 
       
   216 	// done - success
       
   217 	return rv;
       
   218 }
       
   219 
       
   220 
       
   221 /****************************************************************************************
       
   222  * 
       
   223  * PRIVATE: IsPowerOfTwo
       
   224  * 
       
   225  ***************************************************************************************/
       
   226 int CNetworkPartitionManager::IsPowerOfTwo( int aValue )
       
   227 {
       
   228 	int bit_count = 0, i;
       
   229 	
       
   230 	// check how many bits are set
       
   231 	for( i = 0; i < 32; i++ ) {
       
   232 		if( (aValue & 0x1) != 0 ) {
       
   233 			bit_count++;
       
   234 		}
       
   235 	}
       
   236 
       
   237 	// if more than one bit is set then this number is not a power of two
       
   238 	return ((bit_count > 1) ? 0 : 1);
       
   239 }
       
   240 
       
   241 
       
   242 /****************************************************************************************
       
   243  * 
       
   244  * PRIVATE: NetmaskFromBitcount
       
   245  * 
       
   246  ***************************************************************************************/
       
   247 int CNetworkPartitionManager::NetmaskFromBitcount( int aBitCount )
       
   248 {
       
   249 	int i, netmask = 0;
       
   250 	for( netmask = 0, i = 0; i < aBitCount; i++ ) {
       
   251 	    netmask |= 1<<(31-i);
       
   252 	}
       
   253 	return netmask;
       
   254 }