eapol/eapol_framework/eapol_common/am/common/eap_am_tools.cpp
changeset 0 c8830336c852
child 2 1c7bc153c08e
equal deleted inserted replaced
-1:000000000000 0:c8830336c852
       
     1 /*
       
     2 * Copyright (c) 2001-2006 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 the License "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:  EAP and WLAN authentication protocols.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // This is enumeration of EAPOL source code.
       
    20 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    21 	#undef EAP_FILE_NUMBER_ENUM
       
    22 	#define EAP_FILE_NUMBER_ENUM 13 
       
    23 	#undef EAP_FILE_NUMBER_DATE 
       
    24 	#define EAP_FILE_NUMBER_DATE 1127594498 
       
    25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
       
    26 
       
    27 
       
    28 
       
    29 #include "eap_am_memory.h"
       
    30 #include "eap_am_tools.h"
       
    31 #include "abs_eap_am_mutex.h"
       
    32 #include "eap_crypto_api.h"
       
    33 #include "eap_buffer.h"
       
    34 #include "eap_configuration_field.h"
       
    35 
       
    36 //#if !defined(NO_EAP_AM_MEMORY_STORE)
       
    37 	#include "eap_am_memory_store.h"
       
    38 //#endif //#if !defined(NO_EAP_AM_MEMORY_STORE)
       
    39 
       
    40 /**
       
    41  * This is the at character used in NAI.
       
    42  */
       
    43 const u8_t EAP_AT_CHARACTER = '@';
       
    44 
       
    45 /**
       
    46  * This is the length of UUIDs.
       
    47  */
       
    48 static const u32_t EAP_UUID_LENGTH = 16;
       
    49 
       
    50 /**
       
    51  * This is the name space UUID for MAC addresses.
       
    52  */
       
    53 static const u8_t EAP_MAC_ADDRESS_NAMESPACE_UUID_V5[] = 
       
    54 	{ 0x35, 0x0b, 0x16, 0xfd, 
       
    55 	  0x5c, 0xd8, 0x45, 0x50, 
       
    56 	  0x9b, 0xb8, 0x49, 0x8f, 
       
    57 	  0x95, 0x8a, 0xc9, 0x66 };
       
    58 
       
    59 
       
    60 //--------------------------------------------------
       
    61 
       
    62 //
       
    63 EAP_FUNC_EXPORT eap_am_tools_c::~eap_am_tools_c()
       
    64 {
       
    65 	EAP_ASSERT_ALWAYS_NO_TRACE(m_shutdown_was_called == true);
       
    66 }
       
    67 
       
    68 //--------------------------------------------------
       
    69 
       
    70 //
       
    71 EAP_FUNC_EXPORT eap_am_tools_c::eap_am_tools_c()
       
    72 : 
       
    73 #if !defined(NO_EAP_AM_MEMORY_STORE)
       
    74   m_memory_store(0)
       
    75 , 
       
    76 #endif //#if !defined(NO_EAP_AM_MEMORY_STORE)
       
    77  m_trace_mask(eap_am_tools_c::eap_trace_mask_none)
       
    78 #if defined(USE_EAP_ERROR_TESTS)
       
    79 , m_packet_index(0u)
       
    80 #endif //#if defined(USE_EAP_ERROR_TESTS)
       
    81 , m_use_seconds_timestamp_in_traces(true)
       
    82 , m_thread_stopped(false)
       
    83 , m_use_timer_queue(false)
       
    84 , m_shutdown_was_called(false)
       
    85 , m_activate_trace_on_error(false)
       
    86 {
       
    87 	abs_eap_am_tools_c *m_am_tools = this;
       
    88 	u32_t bytes_8 = 8u;
       
    89 	u32_t bytes_4 = 4u;
       
    90 	u32_t bytes_2 = 2u;
       
    91 	u32_t bytes_1 = 1u;
       
    92 
       
    93 	EAP_UNREFERENCED_PARAMETER(m_am_tools);
       
    94 	EAP_UNREFERENCED_PARAMETER(bytes_8);
       
    95 	EAP_UNREFERENCED_PARAMETER(bytes_4);
       
    96 	EAP_UNREFERENCED_PARAMETER(bytes_2);
       
    97 	EAP_UNREFERENCED_PARAMETER(bytes_1);
       
    98 
       
    99 	EAP_ASSERT_ALWAYS(sizeof(u64_t) == bytes_8);
       
   100 	EAP_ASSERT_ALWAYS(sizeof(u32_t) == bytes_4);
       
   101 	EAP_ASSERT_ALWAYS(sizeof(u16_t) == bytes_2);
       
   102 	EAP_ASSERT_ALWAYS(sizeof(u8_t) == bytes_1);
       
   103 
       
   104 	EAP_ASSERT_ALWAYS(sizeof(i64_t) == bytes_8);
       
   105 	EAP_ASSERT_ALWAYS(sizeof(i32_t) == bytes_4);
       
   106 	EAP_ASSERT_ALWAYS(sizeof(i16_t) == bytes_2);
       
   107 	EAP_ASSERT_ALWAYS(sizeof(i8_t) == bytes_1);
       
   108 
       
   109 	m_tmp_buffer[0] = 0;
       
   110 	m_tmp_ascii_buffer[0] = 0;
       
   111 
       
   112 #if !defined(NO_EAP_AM_MEMORY_STORE)
       
   113 	m_memory_store = new eap_am_memory_store_c(m_am_tools);
       
   114 #endif //#if !defined(NO_EAP_AM_MEMORY_STORE)
       
   115 }
       
   116 
       
   117 //--------------------------------------------------
       
   118 
       
   119 //
       
   120 EAP_FUNC_EXPORT bool eap_am_tools_c::get_use_seconds_timestamp_in_traces()
       
   121 {
       
   122 	return m_use_seconds_timestamp_in_traces;
       
   123 }
       
   124 
       
   125 //--------------------------------------------------
       
   126 
       
   127 //
       
   128 EAP_FUNC_EXPORT bool eap_am_tools_c::get_thread_stopped()
       
   129 {
       
   130 	return m_thread_stopped;
       
   131 }
       
   132 
       
   133 //--------------------------------------------------
       
   134 
       
   135 //
       
   136 EAP_FUNC_EXPORT void eap_am_tools_c::set_use_timer_queue()
       
   137 {
       
   138 	m_use_timer_queue = true;
       
   139 }
       
   140 
       
   141 //--------------------------------------------------
       
   142 
       
   143 //
       
   144 EAP_FUNC_EXPORT bool eap_am_tools_c::get_use_timer_queue()
       
   145 {
       
   146 	return m_use_timer_queue;
       
   147 }
       
   148 
       
   149 //--------------------------------------------------
       
   150 
       
   151 //
       
   152 EAP_FUNC_EXPORT u32_t eap_am_tools_c::get_trace_mask() const
       
   153 {
       
   154 	return m_trace_mask;
       
   155 }
       
   156 
       
   157 //--------------------------------------------------
       
   158 
       
   159 //
       
   160 EAP_FUNC_EXPORT void eap_am_tools_c::set_trace_mask(const u32_t mask)
       
   161 {
       
   162 	m_trace_mask = mask;
       
   163 }
       
   164 
       
   165 //--------------------------------------------------
       
   166 
       
   167 //
       
   168 EAP_FUNC_EXPORT void eap_am_tools_c::set_activate_trace_on_error()
       
   169 {
       
   170 	m_activate_trace_on_error = true;
       
   171 
       
   172 	// NOTE the always active traces are only left active.
       
   173 	set_trace_mask(eap_trace_mask_always);
       
   174 }
       
   175 
       
   176 //--------------------------------------------------
       
   177 
       
   178 //
       
   179 EAP_FUNC_EXPORT void eap_am_tools_c::check_activate_trace_on_error()
       
   180 {
       
   181 	if (m_activate_trace_on_error == true)
       
   182 	{
       
   183 		set_trace_mask(
       
   184 			eap_trace_mask_debug
       
   185 			| eap_trace_mask_always
       
   186 			| eap_trace_mask_error
       
   187 			| eap_am_tools_c::eap_trace_mask_message_data);
       
   188 	}
       
   189 }
       
   190 
       
   191 //--------------------------------------------------
       
   192 
       
   193 //
       
   194 EAP_FUNC_EXPORT u8_t eap_am_tools_c::octet_to_ascii(i32_t octet)
       
   195 {
       
   196 	if (0 <= octet && octet <= 9)
       
   197 	{
       
   198 		return static_cast<u8_t>('0' + octet);
       
   199 	}
       
   200 	else if (10 <= octet && octet <= 16)
       
   201 	{
       
   202 		return static_cast<u8_t>('a' + (octet-10u));
       
   203 	}
       
   204 	else
       
   205 	{
       
   206 		return 0;
       
   207 	}
       
   208 }
       
   209 
       
   210 
       
   211 //--------------------------------------------------
       
   212 
       
   213 //
       
   214 EAP_FUNC_EXPORT u8_t eap_am_tools_c::ascii_to_octet(i32_t character)
       
   215 {
       
   216 	if ('0' <= character && character <= '9')
       
   217 	{
       
   218 		return static_cast<u8_t>(character - '0');
       
   219 	}
       
   220 	else if ('a' <= character && character <= 'f')
       
   221 	{
       
   222 		return static_cast<u8_t>((character - 'a') + 10u);
       
   223 	}
       
   224 	else if ('A' <= character && character <= 'F')
       
   225 	{
       
   226 		return static_cast<u8_t>((character - 'A') + 10u);
       
   227 	}
       
   228 	else
       
   229 	{
       
   230 		return 0;
       
   231 	}
       
   232 }
       
   233 
       
   234 
       
   235 //--------------------------------------------------
       
   236 
       
   237 //
       
   238 EAP_FUNC_EXPORT void eap_am_tools_c::trace_data(
       
   239 	eap_const_string prefix,
       
   240 	const void * const p_data,
       
   241 	const u32_t data_length)
       
   242 {
       
   243 	u8_t *cursor = m_tmp_buffer;
       
   244 	u8_t *cursor_ascii = m_tmp_ascii_buffer;
       
   245 	const u8_t *data = reinterpret_cast<const u8_t *>(p_data);
       
   246 	u32_t ind;
       
   247 	bool must_print = false;
       
   248 	u32_t data_start = 0u;
       
   249 
       
   250 	const u32_t EAP_DATA_TRACE_BYTE_GROUP_SIZE = 1;
       
   251 	u32_t byte_group_size = EAP_DATA_TRACE_BYTE_GROUP_SIZE;
       
   252 
       
   253 #if !defined(USE_EAP_DEBUG_TRACE)
       
   254 	// This does not trace the pointer of the data.
       
   255 	formatted_print(
       
   256 		EAPL("%s: data begins: %d (0x%x) bytes\n"),
       
   257 		prefix,
       
   258 		data_length,
       
   259 		data_length);
       
   260 #else
       
   261 	formatted_print(
       
   262 		EAPL("%s: data begins 0x%08x: %d (0x%x) bytes\n"),
       
   263 		prefix,
       
   264 		p_data,
       
   265 		data_length,
       
   266 		data_length);
       
   267 #endif
       
   268 
       
   269 	if (p_data != 0)
       
   270 	{
       
   271 		for (ind = 0u; ind < data_length; ind++)
       
   272 		{
       
   273 			if ((cursor-m_tmp_buffer)+5u >= sizeof(m_tmp_buffer))
       
   274 			{
       
   275 				must_print = true;
       
   276 				formatted_print(
       
   277 					EAPL("ERROR: eap_am_tools_c::trace_data local buffer (%d bytes) too small.\n"),
       
   278 					sizeof(m_tmp_buffer));
       
   279 				break;
       
   280 			}
       
   281 
       
   282 			if (ind > 0u
       
   283 				&& (ind % 16) == 0)
       
   284 			{
       
   285 				*cursor++ = 0;
       
   286 				*cursor_ascii++ = 0;
       
   287 
       
   288 				formatted_print(
       
   289 					EAPL("%s: 0x%04x: %-48s |%-16s|\n"),
       
   290 					prefix,
       
   291 					data_start,
       
   292 					m_tmp_buffer,
       
   293 					m_tmp_ascii_buffer);
       
   294 
       
   295 				cursor = m_tmp_buffer;
       
   296 				cursor_ascii = m_tmp_ascii_buffer;
       
   297 				must_print = false;
       
   298 				data_start = ind;
       
   299 			}
       
   300 
       
   301 			*cursor_ascii++ = (*data >= 0x20 && *data < 0x7f) ? *data : '.';
       
   302 
       
   303 			*cursor++ = octet_to_ascii(((*data) & 0xf0) >> 4);
       
   304 			*cursor++ = octet_to_ascii(((*data) & 0x0f));
       
   305 			data++;
       
   306 
       
   307 			if (ind > 0u
       
   308 				&& ((ind+1) % byte_group_size) == 0
       
   309 				|| byte_group_size == 1ul)
       
   310 			{
       
   311 				*cursor++ = ' ';
       
   312 			}
       
   313 
       
   314 			must_print = true;
       
   315 		}
       
   316 
       
   317 		if (must_print == true)
       
   318 		{
       
   319 			*cursor++ = 0;
       
   320 			*cursor_ascii = 0;
       
   321 			formatted_print(
       
   322 				EAPL("%s: 0x%04x: %-48s |%-16s|\n"),
       
   323 				prefix,
       
   324 				data_start,
       
   325 				m_tmp_buffer,
       
   326 				m_tmp_ascii_buffer);
       
   327 		}
       
   328 	}
       
   329 
       
   330 #if !defined(USE_EAP_DEBUG_TRACE)
       
   331 	// This does not trace the pointer of the data.
       
   332 	formatted_print(
       
   333 		EAPL("%s: data ends: %d (0x%x) bytes\n"),
       
   334 		prefix,
       
   335 		data_length,
       
   336 		data_length);
       
   337 #else
       
   338 	formatted_print(
       
   339 		EAPL("%s: data ends 0x%08x: %d (0x%x) bytes\n"),
       
   340 		prefix,
       
   341 		p_data,
       
   342 		data_length,
       
   343 		data_length);
       
   344 #endif
       
   345 
       
   346 }
       
   347 
       
   348 //--------------------------------------------------
       
   349 
       
   350 #if defined(__SYMBIAN32__) && defined(USE_MULTITHREADING)// Symbian does not have 64 bit divide operator :-(.
       
   351 
       
   352 #include "eap_am_tools_symbian.h"
       
   353 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::timer_thread_function()
       
   354 {
       
   355 	EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: Timer thread starts.\n")));
       
   356 
       
   357 	u64_t start_time = get_clock_ticks();
       
   358 	u64_t current_time = start_time;
       
   359 	u64_t real_time = 0u;
       
   360 	u64_t virtual_time = 0u;
       
   361 	u64_t begin_time = 0u;
       
   362 	u64_t end_time = 0u;
       
   363 #if defined(_DEBUG)
       
   364 	TInt64 *_begin_time = (TInt64 *)&begin_time;	
       
   365 	TInt64 *_real_time = (TInt64 *)&real_time;	
       
   366 	TInt64 *_end_time = (TInt64 *)&end_time;	
       
   367 #endif
       
   368 	u64_t hw_ticks_of_millisecond = get_clock_ticks_of_second();
       
   369 	TInt64 *hw_ticks_of_millisecond_tmp = (TInt64 *)&hw_ticks_of_millisecond;
       
   370 	TReal _hw_ticks_of_millisecond = hw_ticks_of_millisecond_tmp->GetTReal();	
       
   371 	_hw_ticks_of_millisecond /= 1000.0;
       
   372 
       
   373 	// Note 64-bit casted to 32-bit.
       
   374 	EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: get_clock_ticks_of_second() = %lu\n"),
       
   375 		static_cast<u32_t>(get_clock_ticks_of_second()));
       
   376 
       
   377 
       
   378 	u32_t sleep_time = get_timer_resolution_ms();
       
   379 	// The mutex handle must be dublicated in Symbian operating system for each thread.
       
   380 	abs_eap_am_mutex_c *mutex = get_global_mutex()->dublicate_mutex();
       
   381 
       
   382 	if (mutex == 0
       
   383 		|| mutex->get_is_valid() == false)
       
   384 	{
       
   385 		EAP_TRACE_ERROR(this, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Mutex dublication failed.\n")));
       
   386 		m_thread_stopped =true;
       
   387 		return EAP_STATUS_RETURN(this, eap_status_allocation_error);
       
   388 	}
       
   389 
       
   390 	u32_t next_sleep_time = sleep_time;
       
   391 
       
   392 	mutex->mutex_enter();
       
   393 	while(get_is_timer_thread_active())
       
   394 	{
       
   395 		mutex->mutex_leave(this);
       
   396 
       
   397 		virtual_time += sleep_time;
       
   398 
       
   399 		// Symbian sleep is more like random generator.
       
   400 		// It never sleep right time.
       
   401 		begin_time = get_clock_ticks();
       
   402 		timer_sleep(sleep_time);
       
   403 		end_time = get_clock_ticks();
       
   404 
       
   405 		current_time = get_clock_ticks();		
       
   406 		real_time = current_time - start_time;
       
   407 	
       
   408 		EAP_TRACE_DEBUG(
       
   409 			this,
       
   410 			TRACE_FLAGS_DEFAULT,
       
   411 			(EAPL("TIMER: Timer thread pulse_timer, sleep time = %d ms, ")
       
   412 			 EAPL("actually %.3f ms, virtual_time %d ms, real_time %.3f ms.\n"),
       
   413 			 sleep_time,
       
   414 			 ((_end_time->GetTReal() - _begin_time->GetTReal()))/_hw_ticks_of_millisecond,
       
   415 			 (static_cast<u32_t>(virtual_time),
       
   416 			 (_real_time->GetTReal())/_hw_ticks_of_millisecond));
       
   417 		
       
   418 		mutex->mutex_enter();
       
   419 		if (get_is_timer_thread_active())
       
   420 		{
       
   421 			next_sleep_time = pulse_timer(next_sleep_time);
       
   422 		}
       
   423 	}
       
   424 
       
   425 	mutex->mutex_leave(this);
       
   426 
       
   427 	delete mutex;
       
   428 	EAP_TRACE_DEBUG(this, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: Timer thread stops.\n")));
       
   429 
       
   430 	m_thread_stopped =true;
       
   431 
       
   432 	return eap_status_ok; 
       
   433 }
       
   434 
       
   435 #elif !defined(__SYMBIAN32__)
       
   436 
       
   437 #if defined(USE_EAP_TIMER_QUEUE_TRACE)
       
   438 	#define EAP_TRACE_TIMER EAP_TRACE_DEBUG
       
   439 #else
       
   440 	#define EAP_TRACE_TIMER(object, flags, parameters)
       
   441 #endif //#if defined(USE_EAP_TIMER_QUEUE_TRACE)
       
   442 
       
   443 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::timer_thread_function()
       
   444 {
       
   445 	EAP_TRACE_TIMER(this, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: Timer thread starts.\n")));
       
   446 
       
   447 	u32_t static_sleep_time = get_timer_resolution_ms();
       
   448 	u64_t start_time = get_clock_ticks();
       
   449 	u64_t current_time = start_time;
       
   450 	u64_t virtual_time = 0u;
       
   451 	u64_t real_sleep_time = 0ul;
       
   452 	u32_t current_sleep_time = 0u;
       
   453 	u64_t real_time = 0u;
       
   454 	u64_t hw_ticks_of_millisecond = 0u;
       
   455 
       
   456 	u64_t begin_time = 0u;
       
   457 	u64_t end_time = 0u;
       
   458 
       
   459 	// Note 64-bit casted to 32-bit.
       
   460 	EAP_TRACE_TIMER(
       
   461 		this,
       
   462 		TRACE_FLAGS_DEFAULT, (EAPL("TIMER: get_clock_ticks_of_second() = %lu\n"),
       
   463 		static_cast<u32_t>(get_clock_ticks_of_second())));
       
   464 
       
   465 	hw_ticks_of_millisecond = get_clock_ticks_of_second();
       
   466 	hw_ticks_of_millisecond /= 1000u;
       
   467 
       
   468 	// The mutex handle must be dublicated in Symbian operating system for each thread.
       
   469 	abs_eap_am_mutex_c *mutex = get_global_mutex()->dublicate_mutex();
       
   470 
       
   471 	if (mutex == 0
       
   472 		|| mutex->get_is_valid() == false)
       
   473 	{
       
   474 		EAP_TRACE_ERROR(
       
   475 			this,
       
   476 			TRACE_FLAGS_DEFAULT,
       
   477 			(EAPL("ERROR: Mutex dublication failed.\n")));
       
   478 		m_thread_stopped =true;
       
   479 		return EAP_STATUS_RETURN(this, eap_status_allocation_error);
       
   480 	}
       
   481 
       
   482 	u32_t next_sleep_time = static_sleep_time;
       
   483 	u64_t delay_time = 0ul;
       
   484 
       
   485 
       
   486 	EAP_TRACE_TIMER(
       
   487 		this,
       
   488 		TRACE_FLAGS_DEFAULT,
       
   489 		(EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_enter(): begin\n")));
       
   490 
       
   491 	mutex->mutex_enter();
       
   492 
       
   493 	EAP_TRACE_TIMER(
       
   494 		this,
       
   495 		TRACE_FLAGS_DEFAULT,
       
   496 		(EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_enter(): end\n")));
       
   497 
       
   498 	while(get_is_timer_thread_active())
       
   499 	{
       
   500 		bool timer_queue_is_empty = get_timer_queue_is_empty();
       
   501 
       
   502 		current_sleep_time = next_sleep_time;
       
   503 
       
   504 		EAP_TRACE_TIMER(
       
   505 			this,
       
   506 			TRACE_FLAGS_DEFAULT,
       
   507 			(EAPL("TIMER: timer_sleep(): current_sleep_time=%d\n"),
       
   508 			 static_cast<u32_t>(current_sleep_time)));
       
   509 
       
   510 		// - - - - - - - - - - - - - - - - - - - - - - - -
       
   511 		begin_time = get_clock_ticks();
       
   512 
       
   513 		EAP_TRACE_TIMER(
       
   514 			this,
       
   515 			TRACE_FLAGS_DEFAULT,
       
   516 			(EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_leave(): begin\n")));
       
   517 
       
   518 		mutex->mutex_leave(this);
       
   519 
       
   520 		EAP_TRACE_TIMER(
       
   521 			this,
       
   522 			TRACE_FLAGS_DEFAULT,
       
   523 			(EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_leave(): end\n")));
       
   524 
       
   525 		// Sleep happens outside of the mutex.
       
   526 		timer_sleep(current_sleep_time);
       
   527 
       
   528 		EAP_TRACE_TIMER(
       
   529 			this,
       
   530 			TRACE_FLAGS_DEFAULT,
       
   531 			(EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_enter(): begin\n")));
       
   532 
       
   533 		mutex->mutex_enter();
       
   534 
       
   535 		EAP_TRACE_TIMER(
       
   536 			this,
       
   537 			TRACE_FLAGS_DEFAULT,
       
   538 			(EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_enter(): end\n")));
       
   539 
       
   540 		end_time = get_clock_ticks();
       
   541 		// - - - - - - - - - - - - - - - - - - - - - - - -
       
   542 
       
   543 		if (timer_queue_is_empty == true)
       
   544 		{
       
   545 			real_sleep_time = 0ul;
       
   546 			delay_time = 0ul;
       
   547 			EAP_TRACE_TIMER(
       
   548 				this,
       
   549 				TRACE_FLAGS_DEFAULT,
       
   550 				(EAPL("TIMER: empty timer queue\n")));
       
   551 		}
       
   552 		else
       
   553 		{
       
   554 			if (end_time < begin_time)
       
   555 			{
       
   556 				end_time = begin_time;
       
   557 			}
       
   558 			real_sleep_time = (end_time - begin_time)/hw_ticks_of_millisecond;
       
   559 		}
       
   560 
       
   561 		// - - - - - - - - - - - - - - - - - - - - - - - -
       
   562 		begin_time = get_clock_ticks();
       
   563 		if (get_is_timer_thread_active() == true
       
   564 			&& get_use_eap_milli_second_timer() == true)
       
   565 		{
       
   566 			EAP_TRACE_TIMER(
       
   567 				this,
       
   568 				TRACE_FLAGS_DEFAULT,
       
   569 				(EAPL("TIMER: real_sleep_time=%d, delay_time=%d\n"),
       
   570 				 static_cast<u32_t>(real_sleep_time),
       
   571 				 static_cast<u32_t>(delay_time)));
       
   572 
       
   573 			next_sleep_time = pulse_timer(static_cast<u32_t>(real_sleep_time+delay_time));
       
   574 		}
       
   575 		else
       
   576 		{
       
   577 			(void) pulse_timer(static_sleep_time);
       
   578 			next_sleep_time = static_sleep_time;
       
   579 		}
       
   580 		end_time = get_clock_ticks();
       
   581 		// - - - - - - - - - - - - - - - - - - - - - - - -
       
   582 
       
   583 
       
   584 		if (end_time < begin_time)
       
   585 		{
       
   586 			end_time = begin_time;
       
   587 		}
       
   588 
       
   589 		delay_time = (end_time - begin_time)/hw_ticks_of_millisecond;
       
   590 		if (delay_time < next_sleep_time)
       
   591 		{
       
   592 			next_sleep_time -= static_cast<u32_t>(delay_time);
       
   593 		}
       
   594 		else
       
   595 		{
       
   596 			next_sleep_time = 0ul;
       
   597 		}
       
   598 		
       
   599 		current_time = get_clock_ticks();
       
   600 		real_time = current_time - start_time;
       
   601 		real_time /= hw_ticks_of_millisecond;
       
   602 		
       
   603 		real_sleep_time += delay_time;
       
   604 		virtual_time += real_sleep_time;
       
   605 
       
   606 
       
   607 		EAP_TRACE_TIMER(
       
   608 			this,
       
   609 			TRACE_FLAGS_DEFAULT,
       
   610 			(EAPL("TIMER: Timer thread pulse_timer, sleep time = %4d ms, real_sleep_time %4d ms, ")
       
   611 			 EAPL("virtual_time %6d, real_time %6d, next_sleep_time %4d, delay_time %4d.\n"),
       
   612 			 current_sleep_time,
       
   613 			 static_cast<u32_t>(real_sleep_time),
       
   614 			 static_cast<u32_t>(virtual_time),
       
   615 			 static_cast<u32_t>(real_time),
       
   616 			 next_sleep_time,
       
   617 			 delay_time));
       
   618 
       
   619 	} // while()
       
   620 
       
   621 	EAP_TRACE_TIMER(
       
   622 		this,
       
   623 		TRACE_FLAGS_DEFAULT,
       
   624 		(EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_leave(): begin\n")));
       
   625 
       
   626 	mutex->mutex_leave(this);
       
   627 
       
   628 	EAP_TRACE_TIMER(
       
   629 		this,
       
   630 		TRACE_FLAGS_DEFAULT,
       
   631 		(EAPL("MUTEX: eap_am_tools_c::timer_thread_function(): mutex_leave(): end\n")));
       
   632 
       
   633 	delete mutex;
       
   634 
       
   635 	EAP_TRACE_TIMER(this, TRACE_FLAGS_DEFAULT, (EAPL("TIMER: Timer thread stops.\n")));
       
   636 
       
   637 	m_thread_stopped =true;
       
   638 
       
   639 	return eap_status_ok; 
       
   640 }
       
   641 
       
   642 #else
       
   643 
       
   644 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::timer_thread_function()
       
   645 {
       
   646 	return EAP_STATUS_RETURN(this, eap_status_not_supported); 
       
   647 }
       
   648 
       
   649 #endif
       
   650 
       
   651 //--------------------------------------------------
       
   652 
       
   653 //
       
   654 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_ascii_to_uppercase(
       
   655 	u8_t * const source_bytes,
       
   656 	const u32_t source_bytes_length)
       
   657 {
       
   658 	u32_t ind;
       
   659 	for (ind = 0u; ind < source_bytes_length; ind++)
       
   660 	{
       
   661 		if (source_bytes[ind] >= 'a' && source_bytes[ind] <= 'z')
       
   662 		{
       
   663 			source_bytes[ind] -= 32;
       
   664 		}
       
   665 	}
       
   666 
       
   667 	return eap_status_ok;
       
   668 }
       
   669 
       
   670 //--------------------------------------------------
       
   671 
       
   672 //
       
   673 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_bytes_to_hex_ascii(
       
   674 	const u8_t * const source_bytes,
       
   675 	const u32_t source_bytes_length,
       
   676 	u8_t * const target,
       
   677 	u32_t *target_length)
       
   678 {
       
   679 	u32_t ind;
       
   680 	u32_t length = (source_bytes_length*2u < (*target_length)) ? source_bytes_length : (*target_length)/2u;
       
   681 	for (ind = 0u; ind < length; ind++)
       
   682 	{
       
   683 		target[ind*2u] = octet_to_ascii((source_bytes[ind] >> 4) & 0x0f);
       
   684 		target[(ind*2u)+1] = octet_to_ascii(source_bytes[ind] & 0x0f);
       
   685 	}
       
   686 	*target_length = (ind*2u);
       
   687 
       
   688 	return eap_status_ok;
       
   689 }
       
   690 
       
   691 //--------------------------------------------------
       
   692 
       
   693 //
       
   694 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_bytes_to_hex_ascii(
       
   695 	const void * const source_bytes,
       
   696 	const u32_t source_bytes_length,
       
   697 	eap_variable_data_c * const target)
       
   698 {
       
   699 	if (target == 0
       
   700 		|| target->get_is_valid() == false)
       
   701 	{
       
   702 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   703 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
   704 	}
       
   705 
       
   706 	eap_status_e status = target->set_buffer_length(source_bytes_length/2ul);
       
   707 	if (status != eap_status_ok)
       
   708 	{
       
   709 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   710 		return EAP_STATUS_RETURN(this, status);
       
   711 	}
       
   712 
       
   713 	status = target->set_data_length(target->get_buffer_length());
       
   714 	if (status != eap_status_ok)
       
   715 	{
       
   716 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   717 		return EAP_STATUS_RETURN(this, status);
       
   718 	}
       
   719 
       
   720 	u32_t byte_length(target->get_data_length());
       
   721 
       
   722 	status = convert_bytes_to_hex_ascii(
       
   723 		reinterpret_cast<const u8_t *>(source_bytes),
       
   724 		source_bytes_length,
       
   725 		target->get_data(),
       
   726 		&byte_length);
       
   727 	if (status != eap_status_ok)
       
   728 	{
       
   729 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   730 		return EAP_STATUS_RETURN(this, status);
       
   731 	}
       
   732 	else if (byte_length != target->get_data_length())
       
   733 	{
       
   734 		target->reset();
       
   735 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   736 		return EAP_STATUS_RETURN(this, eap_status_illegal_data_payload);
       
   737 	}
       
   738 
       
   739 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   740 	return EAP_STATUS_RETURN(this, status);
       
   741 }
       
   742 
       
   743 //--------------------------------------------------
       
   744 
       
   745 //
       
   746 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_hex_ascii_to_bytes(
       
   747 	const u8_t * const source_bytes,
       
   748 	const u32_t source_bytes_length,
       
   749 	u8_t * const target,
       
   750 	u32_t *target_length)
       
   751 {
       
   752 	if ((source_bytes_length % 2u) != 0)
       
   753 	{
       
   754 		return EAP_STATUS_RETURN(this, eap_status_data_length_not_aligned_to_block_size);
       
   755 	}
       
   756 
       
   757 	u32_t ind;
       
   758 	u32_t length = (source_bytes_length/2u < (*target_length)) ? source_bytes_length/2u : (*target_length);
       
   759 	for (ind = 0u; ind < length; ind++)
       
   760 	{
       
   761 		target[ind] = static_cast<u8_t>(ascii_to_octet(source_bytes[ind*2u]) << 4u | ascii_to_octet(source_bytes[ind*2u+1u]));
       
   762 	}
       
   763 	*target_length = (ind);
       
   764 
       
   765 	return eap_status_ok;
       
   766 }
       
   767 
       
   768 //--------------------------------------------------
       
   769 
       
   770 //
       
   771 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_hex_ascii_to_bytes(
       
   772 	const void * const source_bytes,
       
   773 	const u32_t source_bytes_length,
       
   774 	eap_variable_data_c * const target)
       
   775 {
       
   776 	if (target == 0
       
   777 		|| target->get_is_valid() == false)
       
   778 	{
       
   779 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   780 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
   781 	}
       
   782 
       
   783 	eap_status_e status = target->set_buffer_length(source_bytes_length/2ul);
       
   784 	if (status != eap_status_ok)
       
   785 	{
       
   786 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   787 		return EAP_STATUS_RETURN(this, status);
       
   788 	}
       
   789 
       
   790 	status = target->set_data_length(source_bytes_length/2ul);
       
   791 	if (status != eap_status_ok)
       
   792 	{
       
   793 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   794 		return EAP_STATUS_RETURN(this, status);
       
   795 	}
       
   796 
       
   797 	u32_t byte_length(target->get_data_length());
       
   798 
       
   799 	status = convert_hex_ascii_to_bytes(
       
   800 		reinterpret_cast<const u8_t *>(source_bytes),
       
   801 		source_bytes_length,
       
   802 		target->get_data(),
       
   803 		&byte_length);
       
   804 	if (status != eap_status_ok)
       
   805 	{
       
   806 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   807 		return EAP_STATUS_RETURN(this, status);
       
   808 	}
       
   809 	else if (byte_length != target->get_data_length())
       
   810 	{
       
   811 		target->reset();
       
   812 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   813 		return EAP_STATUS_RETURN(this, eap_status_illegal_data_payload);
       
   814 	}
       
   815 
       
   816 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
   817 	return EAP_STATUS_RETURN(this, status);
       
   818 }
       
   819 
       
   820 //--------------------------------------------------
       
   821 
       
   822 //
       
   823 EAP_FUNC_EXPORT u8_t eap_am_tools_c::octet_to_ascii_armor(
       
   824 	const u8_t source_byte)
       
   825 {
       
   826 	if (source_byte < 26u)
       
   827 	{
       
   828 		// 'A' ... 'Z'
       
   829 		return static_cast<u8_t>((source_byte) + 'A');
       
   830 	}
       
   831 	else if (26u <= source_byte && source_byte < 52u)
       
   832 	{
       
   833 		// 'a' ... 'z'
       
   834 		return static_cast<u8_t>((source_byte - 26u) + 'a');
       
   835 	}
       
   836 	else if (52u <= source_byte && source_byte < 62u)
       
   837 	{
       
   838 		// '0' ... '9'
       
   839 		return static_cast<u8_t>(source_byte - 52u + '0');
       
   840 	}
       
   841 	else if (source_byte == 62u)
       
   842 	{
       
   843 		return static_cast<u8_t>('+');
       
   844 	}
       
   845 	else if (source_byte == 63u)
       
   846 	{
       
   847 		return static_cast<u8_t>('/');
       
   848 	}
       
   849 	else
       
   850 	{
       
   851 		return 0u;
       
   852 	}
       
   853 }
       
   854 
       
   855 //--------------------------------------------------
       
   856 
       
   857 //
       
   858 EAP_FUNC_EXPORT u8_t eap_am_tools_c::octet_from_ascii_armor(
       
   859 	const u8_t source_byte)
       
   860 {
       
   861 	if ('A' <= source_byte && source_byte <= 'Z')
       
   862 	{
       
   863 		// 'A' ... 'Z'
       
   864 		return static_cast<u8_t>((source_byte) - 'A');
       
   865 	}
       
   866 	else if ('a' <= source_byte && source_byte <= 'z')
       
   867 	{
       
   868 		// 'a' ... 'z'
       
   869 		return static_cast<u8_t>((source_byte + 26u) - 'a');
       
   870 	}
       
   871 	else if ('0' <= source_byte && source_byte <= '9')
       
   872 	{
       
   873 		// '0' ... '9'
       
   874 		return static_cast<u8_t>((source_byte + 52) - '0');
       
   875 	}
       
   876 	else if (source_byte == '+')
       
   877 	{
       
   878 		return 62;
       
   879 	}
       
   880 	else if (source_byte == '/')
       
   881 	{
       
   882 		return 63;
       
   883 	}
       
   884 	else
       
   885 	{
       
   886 		return 0u;
       
   887 	}
       
   888 }
       
   889 
       
   890 //--------------------------------------------------
       
   891 
       
   892 //
       
   893 EAP_FUNC_EXPORT void eap_am_tools_c::convert_selected_bytes_to_ascii_armor(
       
   894 	const u8_t source_byte,
       
   895 	u32_t * const saved_bit_count,
       
   896 	u8_t * const saved_bits,
       
   897 	u8_t * const target,
       
   898 	u32_t * const output_ind,
       
   899 	const bool last_input_byte)
       
   900 {
       
   901 	u8_t value;
       
   902 
       
   903 	if (*saved_bit_count == 0u)
       
   904 	{
       
   905 		/* |0 1 2 3 4 5 6 7|
       
   906 		// +-+-+-+-+-+-+-+-+
       
   907 		// | : : : : : : : |
       
   908 		// +-+-+-+-+-+-+-+-+
       
   909 		// |0 1 2 3 4 5|0 1 
       
   910 		// |           +    
       
   911 		// |            \   
       
   912 		// |              \ 
       
   913 		// |               +
       
   914 		// |               |
       
   915 		// |0 1 2 3 4 5 6 7|
       
   916 		// +-+-+-+-+-+-+-+-+
       
   917 		// | : : : : : : : |
       
   918 		// +-+-+-+-+-+-+-+-+
       
   919 		*/
       
   920 		value = octet_to_ascii_armor(static_cast<u8_t>(source_byte >> 2u));
       
   921 		*saved_bits = static_cast<u8_t>(source_byte & 0x03);
       
   922 		*saved_bit_count = 2u;
       
   923 		target[*output_ind] = value;
       
   924 		++(*output_ind);
       
   925 	}
       
   926 	else if (*saved_bit_count == 2u)
       
   927 	{
       
   928 		/*  6 7|0 1 2 3 4 5 6 7|
       
   929 		// +-+-+-+-+-+-+-+-+-+-+
       
   930 		// : : | : : : : : : : |
       
   931 		// +-+-+-+-+-+-+-+-+-+-+
       
   932 		// |0 1 2 3 4 5|0 1 2 3 
       
   933 		// |           +        
       
   934 		// |            \       
       
   935 		// +              \     
       
   936 		//  \               \   
       
   937 		//    \               \ 
       
   938 		//     +               +
       
   939 		//     |               |
       
   940 		//  6 7|0 1 2 3 4 5 6 7|
       
   941 		// +-+-+-+-+-+-+-+-+-+-+
       
   942 		// : : | : : : : : : : |
       
   943 		// +-+-+-+-+-+-+-+-+-+-+
       
   944 		*/
       
   945 		const u8_t src = static_cast<u8_t>(((*saved_bits) << 4u) | ((source_byte & 0xf0) >> 4u));
       
   946 		value = octet_to_ascii_armor(src);
       
   947 		*saved_bits = static_cast<u8_t>(source_byte & 0x0f);
       
   948 		*saved_bit_count = 4u;
       
   949 		target[*output_ind] = value;
       
   950 		++(*output_ind);
       
   951 	}
       
   952 	else if (*saved_bit_count == 4u)
       
   953 	{
       
   954 		/*  4 5 6 7|0 1 2 3 4 5 6 7|
       
   955 		// +-+-+-+-+-+-+-+-+-+-+-+-+
       
   956 		// : : : : | : : : : : : : |
       
   957 		// +-+-+-+-+-+-+-+-+-+-+-+-+
       
   958 		// |0 1 2 3 4 5|0 1 2 3 4 5|
       
   959 		// |           |           +
       
   960 		// |           |            \               
       
   961 		// |           +              \             
       
   962 		// |            \               \           
       
   963 		// +              \               \         
       
   964 		//  \               \               \       
       
   965 		//    \               \               \     
       
   966 		//      \               \               \   
       
   967 		//        \               \               \ 
       
   968 		//         +               +               +
       
   969 		//         |               |               |
       
   970 		//  4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
       
   971 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   972 		// : : : : | : : : : : : : | : : : : : : : |
       
   973 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
   974 		*/
       
   975 		const u8_t src = static_cast<u8_t>(((*saved_bits) << 2u) | ((source_byte & 0xc0) >> 6u));
       
   976 		value = octet_to_ascii_armor(src);
       
   977 		target[*output_ind] = value;
       
   978 		++(*output_ind);
       
   979 		value = octet_to_ascii_armor(static_cast<u8_t>(source_byte & 0x3f));
       
   980 		target[*output_ind] = value;
       
   981 		++(*output_ind);
       
   982 		*saved_bits = 0u;
       
   983 		*saved_bit_count = 0u;
       
   984 	}
       
   985 	else
       
   986 	{
       
   987 		eap_am_tools_c *m_am_tools = this;
       
   988 		EAP_UNREFERENCED_PARAMETER(m_am_tools);
       
   989 		EAP_ASSERT(*saved_bit_count == 0u || *saved_bit_count == 2u || *saved_bit_count == 4u);
       
   990 	}
       
   991 
       
   992 	if (last_input_byte == true
       
   993 		&& *saved_bit_count > 0u)
       
   994 	{
       
   995 		value = octet_to_ascii_armor(static_cast<u8_t>((*saved_bits) << (6u - *saved_bit_count)));
       
   996 		target[*output_ind] = value;
       
   997 		++(*output_ind);
       
   998 		*saved_bits = 0u;
       
   999 		*saved_bit_count = 0u;
       
  1000 	}
       
  1001 
       
  1002 }
       
  1003 
       
  1004 //--------------------------------------------------
       
  1005 
       
  1006 //
       
  1007 EAP_FUNC_EXPORT void eap_am_tools_c::restore_selected_bytes_from_ascii_armor(
       
  1008 	const u8_t source_byte,
       
  1009 	u32_t * const missing_bit_count,
       
  1010 	u8_t * const target,
       
  1011 	u32_t * const output_ind,
       
  1012 	const bool last_input_byte)
       
  1013 {
       
  1014 	u8_t value;
       
  1015 
       
  1016 	EAP_UNREFERENCED_PARAMETER(last_input_byte);
       
  1017 
       
  1018 	if (source_byte == '=')
       
  1019 	{
       
  1020 		return;
       
  1021 	}
       
  1022 
       
  1023 	if (*missing_bit_count == 0u)
       
  1024 	{
       
  1025 		/* |0 1 2 3 4 5 6 7|
       
  1026 		// +-+-+-+-+-+-+-+-+
       
  1027 		// | : : : : : : : |
       
  1028 		// +-+-+-+-+-+-+-+-+
       
  1029 		// |0 1 2 3 4 5|0 1 
       
  1030 		// |           +    
       
  1031 		// |            \   
       
  1032 		// |              \ 
       
  1033 		// |               +
       
  1034 		// |               |
       
  1035 		// |0 1 2 3 4 5 6 7|
       
  1036 		// +-+-+-+-+-+-+-+-+
       
  1037 		// | : : : : : : : |
       
  1038 		// +-+-+-+-+-+-+-+-+
       
  1039 		*/
       
  1040 		value = static_cast<u8_t>(octet_from_ascii_armor(source_byte) << 2u);
       
  1041 		target[*output_ind] = value;
       
  1042 		*missing_bit_count = 2u;
       
  1043 	}
       
  1044 	else if (*missing_bit_count == 2u)
       
  1045 	{
       
  1046 		/*  6 7|0 1 2 3 4 5 6 7|
       
  1047 		// +-+-+-+-+-+-+-+-+-+-+
       
  1048 		// : : | : : : : : : : |
       
  1049 		// +-+-+-+-+-+-+-+-+-+-+
       
  1050 		// |0 1 2 3 4 5|0 1 2 3 
       
  1051 		// |           +        
       
  1052 		// |            \       
       
  1053 		// +              \     
       
  1054 		//  \               \   
       
  1055 		//    \               \ 
       
  1056 		//     +               +
       
  1057 		//     |               |
       
  1058 		//  6 7|0 1 2 3 4 5 6 7|
       
  1059 		// +-+-+-+-+-+-+-+-+-+-+
       
  1060 		// : : | : : : : : : : |
       
  1061 		// +-+-+-+-+-+-+-+-+-+-+
       
  1062 		*/
       
  1063 		value = octet_from_ascii_armor(source_byte);
       
  1064 		target[*output_ind] |= (value & 0x30) >> 4u;
       
  1065 		++(*output_ind);
       
  1066 		if (last_input_byte == false)
       
  1067 		{
       
  1068 			target[*output_ind] = static_cast<u8_t>((value & 0x0f) << 4u);
       
  1069 			*missing_bit_count = 4u;
       
  1070 		}
       
  1071 		else
       
  1072 		{
       
  1073 			*missing_bit_count = 0u;
       
  1074 		}
       
  1075 	}
       
  1076 	else if (*missing_bit_count == 4u)
       
  1077 	{
       
  1078 		/*  4 5 6 7|0 1 
       
  1079 		// +-+-+-+-+-+-+
       
  1080 		// : : : : | : :
       
  1081 		// +-+-+-+-+-+-+
       
  1082 		// |0 1 2 3 4 5|
       
  1083 		// |           +            
       
  1084 		// |            \           
       
  1085 		// +              \         
       
  1086 		//  \               \       
       
  1087 		//    \               \     
       
  1088 		//      \               \   
       
  1089 		//        \               \ 
       
  1090 		//         +               +
       
  1091 		//         |               |
       
  1092 		//  4 5 6 7|0 1 2 3 4 5 6 7|
       
  1093 		// +-+-+-+-+-+-+-+-+-+-+-+-+
       
  1094 		// : : : : | : : : : : : : |
       
  1095 		// +-+-+-+-+-+-+-+-+-+-+-+-+
       
  1096 		*/
       
  1097 		value = octet_from_ascii_armor(source_byte);
       
  1098 		target[*output_ind] |= (value >> 2u) & 0x0f;
       
  1099 		++(*output_ind);
       
  1100 		if (last_input_byte == false)
       
  1101 		{
       
  1102 			target[*output_ind] = static_cast<u8_t>((value & 0x03) << 6u);
       
  1103 			*missing_bit_count = 6u;
       
  1104 		}
       
  1105 		else
       
  1106 		{
       
  1107 			*missing_bit_count = 0u;
       
  1108 		}
       
  1109 	}
       
  1110 	else if (*missing_bit_count == 6u)
       
  1111 	{
       
  1112 		/*  2 3 4 5 6 7|
       
  1113 		// +-+-+-+-+-+-+
       
  1114 		// : : : : : : |
       
  1115 		// +-+-+-+-+-+-+
       
  1116 		// |0 1 2 3 4 5|
       
  1117 		// |           +                
       
  1118 		// |            \               
       
  1119 		// +              \             
       
  1120 		//  \               \           
       
  1121 		//    \               \         
       
  1122 		//      \               \       
       
  1123 		//        \               \     
       
  1124 		//          \               \   
       
  1125 		//            \               \ 
       
  1126 		//             +               +
       
  1127 		//             |               |
       
  1128 		//  2 3 4 5 6 7|0 1 2 3 4 5 6 7|
       
  1129 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1130 		// : : : : : : | : : : : : : : |
       
  1131 		// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1132 		*/
       
  1133 		value = octet_from_ascii_armor(source_byte);
       
  1134 		target[*output_ind] |= value;
       
  1135 		++(*output_ind);
       
  1136 		*missing_bit_count = 0u;
       
  1137 	}
       
  1138 	else
       
  1139 	{
       
  1140 		eap_am_tools_c *m_am_tools = this;
       
  1141 		EAP_UNREFERENCED_PARAMETER(m_am_tools);
       
  1142 		EAP_ASSERT(*missing_bit_count == 0u || *missing_bit_count == 2u || *missing_bit_count == 4u || *missing_bit_count == 6u);
       
  1143 	}
       
  1144 
       
  1145 }
       
  1146 
       
  1147 //--------------------------------------------------
       
  1148 
       
  1149 //
       
  1150 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::convert_bytes_to_ascii_armor(
       
  1151 	const u8_t * const source_bytes,
       
  1152 	const u32_t source_bytes_length,
       
  1153 	u8_t * const target,
       
  1154 	u32_t *target_length)
       
  1155 {
       
  1156 	if (source_bytes == 0)
       
  1157 	{
       
  1158 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1159 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
  1160 	}
       
  1161 
       
  1162 	if (target == 0)
       
  1163 	{
       
  1164 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1165 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
  1166 	}
       
  1167 
       
  1168 	if (target_length == 0)
       
  1169 	{
       
  1170 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1171 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
  1172 	}
       
  1173 
       
  1174 	/* 8-bit ascii values are converted to binary 6-bit blocks. Ascii values can easily represent 2^6=64 values.
       
  1175 	// If length of source array is not module 3, missing bits are padded with zero bits.
       
  1176 
       
  1177 	// |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|                                
       
  1178 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        
       
  1179 	// | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : |0:0:0:0|                        
       
  1180 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                        
       
  1181 	// |0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|                        
       
  1182 	// |           |           |           |           |           |           +                        
       
  1183 	// |           |           |           |           |           |            \                       
       
  1184 	// |           |           |           |           |           +              \                     
       
  1185 	// |           |           |           |           |            \               \                   
       
  1186 	// |           |           |           |           +              \               \                 
       
  1187 	// |           |           |           |            \               \               \                
       
  1188 	// |           |           |           +              \               \               \             
       
  1189 	// |           |           |            \               \               \               \           
       
  1190 	// |           |           +              \               \               \               \         
       
  1191 	// |           |            \               \               \               \               \       
       
  1192 	// |           +              \               \               \               \               \     
       
  1193 	// |            \               \               \               \               \               \   
       
  1194 	// |              \               \               \               \               \               \ 
       
  1195 	// |               +               +               +               +               +               +
       
  1196 	// |               |               |               |               |               |               |
       
  1197 	// |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
       
  1198 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1199 	// | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : |
       
  1200 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1201 	*/
       
  1202 	u32_t output_ind = 0u;
       
  1203 	u32_t input_ind = 0u;
       
  1204 	u32_t input_count = (source_bytes_length*4u < (*target_length)*3u) ? source_bytes_length : (*target_length)*3u/4u;
       
  1205 	u8_t saved_bits = 0u;
       
  1206 	u32_t saved_bit_count = 0ul;
       
  1207 
       
  1208 	for (input_ind = 0u; input_ind < input_count; input_ind++)
       
  1209 	{
       
  1210 		convert_selected_bytes_to_ascii_armor(source_bytes[input_ind], &saved_bit_count, &saved_bits, target, &output_ind, (input_ind+1 == input_count));
       
  1211 	} // for()
       
  1212 
       
  1213 	u32_t remainder = output_ind % 4ul;
       
  1214 	if (remainder != 0ul)
       
  1215 	{
       
  1216 		u32_t padding_count(4ul - remainder);
       
  1217 
       
  1218 		if (padding_count == 2ul)
       
  1219 		{
       
  1220 			// Add padding '='-characters.
       
  1221 			target[output_ind++] = '=';
       
  1222 			--padding_count;
       
  1223 		}
       
  1224 		if (padding_count == 1ul)
       
  1225 		{
       
  1226 			// Add padding '='-characters.
       
  1227 			target[output_ind++] = '=';
       
  1228 		}
       
  1229 	}
       
  1230 
       
  1231 	*target_length = output_ind;
       
  1232 
       
  1233 	return eap_status_ok;
       
  1234 }
       
  1235 
       
  1236 //--------------------------------------------------
       
  1237 
       
  1238 //
       
  1239 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::restore_bytes_from_ascii_armor(
       
  1240 	const u8_t * const source_bytes,
       
  1241 	const u32_t source_bytes_length,
       
  1242 	u8_t * const target,
       
  1243 	u32_t *target_length)
       
  1244 {
       
  1245 	if (source_bytes == 0)
       
  1246 	{
       
  1247 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1248 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
  1249 	}
       
  1250 
       
  1251 	if (target == 0)
       
  1252 	{
       
  1253 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1254 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
  1255 	}
       
  1256 
       
  1257 	if (target_length == 0)
       
  1258 	{
       
  1259 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1260 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
  1261 	}
       
  1262 
       
  1263 	/* Binary 6-bit blocks are converted to 8-bit ascii values. Ascii values can easily represent 2^6=64 values.
       
  1264 	// If length of target array is not module 3, padding zero bits are ignored.
       
  1265 
       
  1266 	// |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|                                
       
  1267 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                
       
  1268 	// | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : |                                
       
  1269 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                                
       
  1270 	// |0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|0 1 2 3 4 5|                        
       
  1271 	// |           |           |           |           |           |           +                        
       
  1272 	// |           |           |           |           |           |            \                       
       
  1273 	// |           |           |           |           |           +              \                     
       
  1274 	// |           |           |           |           |            \               \                   
       
  1275 	// |           |           |           |           +              \               \                 
       
  1276 	// |           |           |           |            \               \               \                
       
  1277 	// |           |           |           +              \               \               \             
       
  1278 	// |           |           |            \               \               \               \           
       
  1279 	// |           |           +              \               \               \               \         
       
  1280 	// |           |            \               \               \               \               \       
       
  1281 	// |           +              \               \               \               \               \     
       
  1282 	// |            \               \               \               \               \               \   
       
  1283 	// |              \               \               \               \               \               \ 
       
  1284 	// |               +               +               +               +               +               +
       
  1285 	// |               |               |               |               |               |               |
       
  1286 	// |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
       
  1287 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1288 	// | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : | : : : : : : : |
       
  1289 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  1290 	*/
       
  1291 	u32_t output_ind = 0u;
       
  1292 	u32_t input_ind = 0u;
       
  1293 	u32_t input_count = source_bytes_length;
       
  1294 	u32_t missing_bit_count = 0ul;
       
  1295 
       
  1296 	for (input_ind = 0u; input_ind < input_count; input_ind++)
       
  1297 	{
       
  1298 		restore_selected_bytes_from_ascii_armor(source_bytes[input_ind], &missing_bit_count, target, &output_ind, (input_ind+1 == input_count));
       
  1299 	} // for()
       
  1300 
       
  1301 	*target_length = output_ind;
       
  1302 
       
  1303 	return eap_status_ok;
       
  1304 }
       
  1305 
       
  1306 //-----------------------------------------------------------------------------------------------
       
  1307 
       
  1308 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::eap_status_return(
       
  1309 	const bool print_error_when_true,
       
  1310 	const eap_status_e status,
       
  1311 	const eap_char * const file_name,
       
  1312 	const i32_t line_number)
       
  1313 {
       
  1314 	if (status == eap_status_not_supported)
       
  1315 	{
       
  1316 		eap_status_string_c status_string;
       
  1317 
       
  1318 		EAP_UNREFERENCED_PARAMETER(file_name);
       
  1319 		EAP_UNREFERENCED_PARAMETER(line_number);
       
  1320 
       
  1321 		EAP_TRACE_DEBUG(
       
  1322 			this,
       
  1323 			TRACE_FLAGS_DEFAULT,
       
  1324 			(EAPL("TODO: %s=%d returned from %s:%d\n"),
       
  1325 			status_string.get_status_string(status),
       
  1326 			status,
       
  1327 			file_name,
       
  1328 			line_number));
       
  1329 	}
       
  1330 	else if (status == eap_status_success)
       
  1331 	{
       
  1332 		eap_status_string_c status_string;
       
  1333 
       
  1334 		EAP_TRACE_DEBUG(
       
  1335 			this,
       
  1336 			TRACE_FLAGS_DEFAULT,
       
  1337 			(EAPL("SUCCESS: %s=%d returned from %s:%d\n"),
       
  1338 			status_string.get_status_string(status),
       
  1339 			status,
       
  1340 			file_name,
       
  1341 			line_number));
       
  1342 	}
       
  1343 	else if (status == eap_status_not_found
       
  1344 		|| status == eap_status_illegal_configure_field
       
  1345 		|| status == eap_status_illegal_configure_type
       
  1346 		|| status == eap_status_syncronization_failure)
       
  1347 	{
       
  1348 		eap_status_string_c status_string;
       
  1349 
       
  1350 		EAP_TRACE_DEBUG(
       
  1351 			this,
       
  1352 			TRACE_FLAGS_DEFAULT,
       
  1353 			(EAPL("WARNING: %s=%d returned from %s:%d\n"),
       
  1354 			status_string.get_status_string(status),
       
  1355 			status,
       
  1356 			file_name,
       
  1357 			line_number));
       
  1358 	}
       
  1359 	else if (status == eap_status_pending_request
       
  1360 		|| status == eap_status_completed_request
       
  1361 		|| status == eap_status_drop_packet_quietly
       
  1362 		|| status == eap_status_end_of_file
       
  1363 		|| status == eap_status_section_ends
       
  1364 		|| status == eap_status_end_recursion)
       
  1365 	{
       
  1366 		eap_status_string_c status_string;
       
  1367 
       
  1368 		EAP_TRACE_DEBUG(
       
  1369 			this,
       
  1370 			TRACE_FLAGS_DEFAULT,
       
  1371 			(EAPL("INFO: %s=%d returned from %s:%d\n"),
       
  1372 			status_string.get_status_string(status),
       
  1373 			status,
       
  1374 			file_name,
       
  1375 			line_number));
       
  1376 	}
       
  1377 #if defined(_DEBUG)
       
  1378 	else if ((get_trace_mask() & TRACE_FLAGS_OK_RETURNS)
       
  1379 		&& (status == eap_status_ok
       
  1380 			|| status == eap_status_success
       
  1381 			|| status == eap_status_not_supported
       
  1382 			|| status == eap_status_pending_request
       
  1383 			|| status == eap_status_completed_request
       
  1384 			|| status == eap_status_drop_packet_quietly)
       
  1385 		)
       
  1386 	{
       
  1387 		eap_status_string_c status_string;
       
  1388 
       
  1389 		EAP_TRACE_DEBUG(
       
  1390 			this,
       
  1391 			TRACE_FLAGS_DEFAULT,
       
  1392 			(EAPL("EXTRA: %s=%d returned from %s:%d\n"),
       
  1393 			status_string.get_status_string(status),
       
  1394 			status,
       
  1395 			file_name,
       
  1396 			line_number));
       
  1397 	}
       
  1398 #endif
       
  1399 	else if (status != eap_status_ok
       
  1400 		&& status != eap_status_success
       
  1401 		&& status != eap_status_not_supported
       
  1402 		&& status != eap_status_pending_request
       
  1403 		&& status != eap_status_completed_request
       
  1404 		&& status != eap_status_drop_packet_quietly
       
  1405 		)
       
  1406 	{
       
  1407 		check_activate_trace_on_error();
       
  1408 
       
  1409 		eap_status_string_c status_string;
       
  1410 
       
  1411 		if (print_error_when_true == true)
       
  1412 		{
       
  1413 			EAP_TRACE_ALWAYS(
       
  1414 				this,
       
  1415 				TRACE_FLAGS_DEFAULT,
       
  1416 				(EAPL("ERROR: %s=%d returned from %s:%d\n"),
       
  1417 				status_string.get_status_string(status),
       
  1418 				status,
       
  1419 				file_name,
       
  1420 				line_number));
       
  1421 		}
       
  1422 		else
       
  1423 		{
       
  1424 			EAP_TRACE_ALWAYS(
       
  1425 				this,
       
  1426 				TRACE_FLAGS_DEFAULT,
       
  1427 				(EAPL("WARNING: %s=%d returned from %s:%d\n"),
       
  1428 				status_string.get_status_string(status),
       
  1429 				status,
       
  1430 				file_name,
       
  1431 				line_number));
       
  1432 		}
       
  1433 	}
       
  1434 
       
  1435 	return status;
       
  1436 }
       
  1437 
       
  1438 //-----------------------------------------------------------------------------------------------
       
  1439 
       
  1440 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::eap_status_return_file_number(
       
  1441 	const bool print_error_when_true,
       
  1442 	const eap_status_e status,
       
  1443 	const u32_t file_date,
       
  1444 	const u32_t file_number,
       
  1445 	const i32_t line_number)
       
  1446 {
       
  1447 	if (status == eap_status_not_supported)
       
  1448 	{
       
  1449 		eap_status_string_c status_string;
       
  1450 
       
  1451 		EAP_UNREFERENCED_PARAMETER(file_date);
       
  1452 		EAP_UNREFERENCED_PARAMETER(file_number);
       
  1453 		EAP_UNREFERENCED_PARAMETER(line_number);
       
  1454 
       
  1455 		EAP_TRACE_DEBUG(
       
  1456 			this,
       
  1457 			TRACE_FLAGS_DEFAULT,
       
  1458 			(EAPL("TODO: %d:%d:%d:%d\n"),
       
  1459 			status,
       
  1460 			file_date,
       
  1461 			file_number,
       
  1462 			line_number));
       
  1463 	}
       
  1464 	else if (status == eap_status_success)
       
  1465 	{
       
  1466 		EAP_TRACE_DEBUG(
       
  1467 			this,
       
  1468 			TRACE_FLAGS_DEFAULT,
       
  1469 			(EAPL("SUCCESS: %d:%d:%d:%d\n"),
       
  1470 			status,
       
  1471 			file_date,
       
  1472 			file_number,
       
  1473 			line_number));
       
  1474 	}
       
  1475 	else if (status == eap_status_not_found
       
  1476 		|| status == eap_status_illegal_configure_field
       
  1477 		|| status == eap_status_illegal_configure_type
       
  1478 		|| status == eap_status_syncronization_failure)
       
  1479 	{
       
  1480 		EAP_TRACE_DEBUG(
       
  1481 			this,
       
  1482 			TRACE_FLAGS_DEFAULT,
       
  1483 			(EAPL("WARNING: %d:%d:%d:%d\n"),
       
  1484 			status,
       
  1485 			file_date,
       
  1486 			file_number,
       
  1487 			line_number));
       
  1488 	}
       
  1489 	else if (status == eap_status_pending_request
       
  1490 		|| status == eap_status_completed_request
       
  1491 		|| status == eap_status_drop_packet_quietly
       
  1492 		|| status == eap_status_end_of_file
       
  1493 		|| status == eap_status_section_ends)
       
  1494 	{
       
  1495 		EAP_TRACE_DEBUG(
       
  1496 			this,
       
  1497 			TRACE_FLAGS_DEFAULT,
       
  1498 			(EAPL("INFO: %d:%d:%d:%d\n"),
       
  1499 			status,
       
  1500 			file_date,
       
  1501 			file_number,
       
  1502 			line_number));
       
  1503 	}
       
  1504 	else if (status != eap_status_ok
       
  1505 		&& status != eap_status_success
       
  1506 		&& status != eap_status_not_supported
       
  1507 		&& status != eap_status_pending_request
       
  1508 		&& status != eap_status_completed_request
       
  1509 		&& status != eap_status_drop_packet_quietly
       
  1510 
       
  1511 		)
       
  1512 	{
       
  1513 		check_activate_trace_on_error();
       
  1514 
       
  1515 		if (print_error_when_true == true)
       
  1516 		{
       
  1517 			EAP_TRACE_ALWAYS(
       
  1518 				this,
       
  1519 				TRACE_FLAGS_DEFAULT,
       
  1520 				(EAPL("ERROR: %d:%d:%d:%d\n"),
       
  1521 				status,
       
  1522 				file_date,
       
  1523 				file_number,
       
  1524 				line_number));
       
  1525 		}
       
  1526 		else
       
  1527 		{
       
  1528 			EAP_TRACE_ALWAYS(
       
  1529 				this,
       
  1530 				TRACE_FLAGS_DEFAULT,
       
  1531 				(EAPL("WARNING: %d:%d:%d:%d\n"),
       
  1532 				status,
       
  1533 				file_date,
       
  1534 				file_number,
       
  1535 				line_number));
       
  1536 		}
       
  1537 	}
       
  1538 
       
  1539 	return status;
       
  1540 }
       
  1541 
       
  1542 //-----------------------------------------------------------------------------------------------
       
  1543 
       
  1544 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::memory_store_add_data(
       
  1545 	const eap_variable_data_c * const key,
       
  1546 	eap_tlv_message_data_c * const data,
       
  1547 	const u32_t timeout)
       
  1548 {
       
  1549 	EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT);
       
  1550 
       
  1551 #if !defined(NO_EAP_AM_MEMORY_STORE)
       
  1552 
       
  1553 	if (m_memory_store == 0
       
  1554 		|| 	m_memory_store->get_is_valid() == false)
       
  1555 	{
       
  1556 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1557 		return EAP_STATUS_RETURN(this, eap_status_allocation_error);
       
  1558 	}
       
  1559 
       
  1560 	eap_status_e status = m_memory_store->add_data(
       
  1561 		key,
       
  1562 		data,
       
  1563 		timeout);
       
  1564 
       
  1565 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1566 	return EAP_STATUS_RETURN(this, status);
       
  1567 
       
  1568 #else
       
  1569 
       
  1570 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1571 	return EAP_STATUS_RETURN(this, eap_status_not_supported);
       
  1572 
       
  1573 #endif //#if !defined(NO_EAP_AM_MEMORY_STORE)
       
  1574 }
       
  1575 
       
  1576 //-----------------------------------------------------------------------------------------------
       
  1577 
       
  1578 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::memory_store_get_data(
       
  1579 	const eap_variable_data_c * const key,
       
  1580 	eap_tlv_message_data_c * const data)
       
  1581 {
       
  1582 	EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT);
       
  1583 
       
  1584 #if !defined(NO_EAP_AM_MEMORY_STORE)
       
  1585 
       
  1586 	if (m_memory_store == 0
       
  1587 		|| 	m_memory_store->get_is_valid() == false)
       
  1588 	{
       
  1589 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1590 		return EAP_STATUS_RETURN(this, eap_status_allocation_error);
       
  1591 	}
       
  1592 
       
  1593 	eap_status_e status = eap_status_process_general_error;
       
  1594 
       
  1595 	status = m_memory_store->get_data(
       
  1596 		key,
       
  1597 		data);
       
  1598 
       
  1599 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1600 	return EAP_STATUS_RETURN(this, status);
       
  1601 
       
  1602 #else
       
  1603 
       
  1604 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1605 	return EAP_STATUS_RETURN(this, eap_status_not_found);
       
  1606 
       
  1607 #endif //#if !defined(NO_EAP_AM_MEMORY_STORE)
       
  1608 
       
  1609 }
       
  1610 
       
  1611 //-----------------------------------------------------------------------------------------------
       
  1612 
       
  1613 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::memory_store_remove_data(
       
  1614 	const eap_variable_data_c * const key)
       
  1615 {
       
  1616 	EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT);
       
  1617 
       
  1618 #if !defined(NO_EAP_AM_MEMORY_STORE)
       
  1619 
       
  1620 	if (m_memory_store == 0
       
  1621 		|| 	m_memory_store->get_is_valid() == false)
       
  1622 	{
       
  1623 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1624 		return EAP_STATUS_RETURN(this, eap_status_allocation_error);
       
  1625 	}
       
  1626 
       
  1627 	eap_status_e status = m_memory_store->remove_data(
       
  1628 		key);
       
  1629 
       
  1630 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1631 	return EAP_STATUS_RETURN(this, status);
       
  1632 
       
  1633 #else
       
  1634 
       
  1635 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1636 	return EAP_STATUS_RETURN(this, eap_status_not_found);
       
  1637 
       
  1638 #endif //#if !defined(NO_EAP_AM_MEMORY_STORE)
       
  1639 }
       
  1640 
       
  1641 //--------------------------------------------------
       
  1642 
       
  1643 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::shutdown_am_tools()
       
  1644 {
       
  1645 	eap_status_e status = eap_status_ok;
       
  1646 
       
  1647 	EAP_TRACE_DEBUG(
       
  1648 		this,
       
  1649 		TRACE_FLAGS_DEFAULT,
       
  1650 		(EAPL("eap_am_tools_c::shutdown_am_tools(); this = 0x%08x\n"),
       
  1651 		 this));
       
  1652 
       
  1653 	if (m_shutdown_was_called == false)
       
  1654 	{
       
  1655 		m_shutdown_was_called = true;
       
  1656 
       
  1657 		#if !defined(NO_EAP_AM_MEMORY_STORE)
       
  1658 		if (m_memory_store != 0)
       
  1659 		{
       
  1660 			status = m_memory_store->shutdown();
       
  1661 		}
       
  1662 		delete m_memory_store;
       
  1663 		m_memory_store = 0;
       
  1664 		#endif //#if !defined(NO_EAP_AM_MEMORY_STORE)
       
  1665 	}
       
  1666 
       
  1667 	return EAP_STATUS_RETURN(this, status);
       
  1668 }
       
  1669 
       
  1670 //--------------------------------------------------
       
  1671 
       
  1672 /// Coverts unicode string to UTF8 string.
       
  1673 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::generic_convert_unicode_to_utf8(
       
  1674 	eap_variable_data_c & dest,
       
  1675 	const eap_variable_data_c & src)
       
  1676 {
       
  1677 	if (src.get_is_valid_data() == true)
       
  1678 	{
       
  1679 		u32_t len = src.get_data_length();
       
  1680 		u8_t * ascii = new u8_t[len / 2];
       
  1681 		if (!ascii)
       
  1682 		{
       
  1683 			return EAP_STATUS_RETURN(this, eap_status_allocation_error);
       
  1684 		}
       
  1685 		u8_t * src_ptr = src.get_data(len);
       
  1686 		u32_t dest_len = len / 2;
       
  1687 		u32_t i;
       
  1688 		for (i = 0; i < dest_len; i++)
       
  1689 		{
       
  1690 			ascii[i] = src_ptr[i * 2];
       
  1691 		}
       
  1692 
       
  1693 		return EAP_STATUS_RETURN(this, dest.set_buffer(ascii, dest_len, true, true));
       
  1694 	}
       
  1695 
       
  1696 	return EAP_STATUS_RETURN(this, eap_status_process_general_error);
       
  1697 }
       
  1698 
       
  1699 //--------------------------------------------------
       
  1700 
       
  1701 /// Coverts UTF8 string to unicode string. Not yet implemented.
       
  1702 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::generic_convert_utf8_to_unicode(
       
  1703 	eap_variable_data_c & dest,
       
  1704 	const eap_variable_data_c & src)
       
  1705 {
       
  1706 	if (src.get_is_valid_data() == true)
       
  1707 	{
       
  1708 		u32_t len = src.get_data_length();
       
  1709 		u8_t * src_ptr = src.get_data(len);
       
  1710 
       
  1711 		eap_status_e status = dest.set_buffer_length(2ul*len);
       
  1712 		if (status != eap_status_ok)
       
  1713 		{
       
  1714 			return EAP_STATUS_RETURN(this, status);
       
  1715 		}
       
  1716 
       
  1717 		u8_t null_byte(0x00);
       
  1718 		u32_t i;
       
  1719 		for (i = 0; i < len; i++)
       
  1720 		{
       
  1721 			status = dest.add_data(&(src_ptr[i]), sizeof(u8_t));
       
  1722 			if (status != eap_status_ok)
       
  1723 			{
       
  1724 				return EAP_STATUS_RETURN(this, status);
       
  1725 			}
       
  1726 
       
  1727 			status = dest.add_data(&null_byte, sizeof(u8_t));
       
  1728 			if (status != eap_status_ok)
       
  1729 			{
       
  1730 				return EAP_STATUS_RETURN(this, status);
       
  1731 			}
       
  1732 		}
       
  1733 
       
  1734 		return EAP_STATUS_RETURN(this, eap_status_ok);
       
  1735 	}
       
  1736 
       
  1737 	return EAP_STATUS_RETURN(this, eap_status_process_general_error);
       
  1738 }
       
  1739 
       
  1740 //-----------------------------------------------------------------------------------------------
       
  1741 
       
  1742 //
       
  1743 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::parse_nai(
       
  1744 	const eap_variable_data_c * const nai,
       
  1745 	eap_variable_data_c * const username,
       
  1746 	eap_variable_data_c * const realm)
       
  1747 {
       
  1748 	if (nai == 0
       
  1749 		|| username == 0
       
  1750 		|| realm == 0)
       
  1751 	{
       
  1752 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
  1753 	}
       
  1754 
       
  1755 	username->reset();
       
  1756 	realm->reset();
       
  1757 
       
  1758 	if (nai->get_is_valid() == false)
       
  1759 	{
       
  1760 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
  1761 	}
       
  1762 
       
  1763 	EAP_TRACE_DATA_DEBUG(
       
  1764 		this,
       
  1765 		TRACE_FLAGS_DEFAULT,
       
  1766 		(EAPL("eap_am_tools_c::parse_nai(): NAI"),
       
  1767 		nai->get_data(),
       
  1768 		nai->get_data_length()));
       
  1769 
       
  1770 
       
  1771 	eap_status_e status(eap_status_ok);
       
  1772 	u32_t username_length = nai->get_data_length();
       
  1773 
       
  1774 	// We read the realm from NAI.
       
  1775 	const u8_t *at_character = reinterpret_cast<const u8_t *>(
       
  1776 		memchr(
       
  1777 			nai->get_data(nai->get_data_length()),
       
  1778 			EAP_AT_CHARACTER,
       
  1779 			nai->get_data_length()));
       
  1780 	if (at_character != 0
       
  1781 		&& nai->get_data_length()
       
  1782 		> ((1UL + reinterpret_cast<u32_t>(at_character))
       
  1783 		   - reinterpret_cast<u32_t>(nai->get_data(
       
  1784 										 nai->get_data_length()))))
       
  1785 	{
       
  1786 		u32_t realm_length = nai->get_data_length()
       
  1787 			- ((1UL + reinterpret_cast<u32_t>(at_character))
       
  1788 			   - reinterpret_cast<u32_t>(nai->get_data(
       
  1789 											 nai->get_data_length())));
       
  1790 		
       
  1791 		if (realm_length > 0UL)
       
  1792 		{
       
  1793 			status = realm->set_copy_of_buffer(
       
  1794 				at_character+1,
       
  1795 				realm_length);
       
  1796 			if (status != eap_status_ok)
       
  1797 			{
       
  1798 				EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1799 				return EAP_STATUS_RETURN(this, status);
       
  1800 			}
       
  1801 
       
  1802 			username_length -= (realm_length + 1ul);
       
  1803 		}
       
  1804 	}
       
  1805 	else
       
  1806 	{
       
  1807 		// No realm.
       
  1808 	}
       
  1809 
       
  1810 	// The begin of the NAI to '@' or the end is username.
       
  1811 	status = username->set_copy_of_buffer(
       
  1812 		nai->get_data(username_length),
       
  1813 		username_length);
       
  1814 	if (status != eap_status_ok)
       
  1815 	{
       
  1816 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1817 		return EAP_STATUS_RETURN(this, status);
       
  1818 	}
       
  1819 
       
  1820 	EAP_TRACE_DATA_DEBUG(
       
  1821 		this,
       
  1822 		TRACE_FLAGS_DEFAULT,
       
  1823 		(EAPL("eap_am_tools_c::parse_nai(): username"),
       
  1824 		username->get_data(),
       
  1825 		username->get_data_length()));
       
  1826 
       
  1827 	EAP_TRACE_DATA_DEBUG(
       
  1828 		this,
       
  1829 		TRACE_FLAGS_DEFAULT,
       
  1830 		(EAPL("eap_am_tools_c::parse_nai(): realm"),
       
  1831 		realm->get_data(),
       
  1832 		realm->get_data_length()));
       
  1833 
       
  1834 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  1835 	return EAP_STATUS_RETURN(this, status);
       
  1836 }
       
  1837 
       
  1838 //-----------------------------------------------------------------------------------------------
       
  1839 
       
  1840 #if defined(USE_EAP_ERROR_TESTS)
       
  1841 
       
  1842 //
       
  1843 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::generate_random_error(
       
  1844 	eap_buf_chain_wr_c * const sent_packet,
       
  1845 	const bool forse_error,
       
  1846 	const u32_t packet_index,
       
  1847 	const u32_t minimum_index,
       
  1848 	const u32_t error_probability,
       
  1849 	const u32_t minimum_packet_length)
       
  1850 {
       
  1851 	eap_status_e status(eap_status_ok);
       
  1852 	EAP_UNREFERENCED_PARAMETER(packet_index);
       
  1853 
       
  1854 	u8_t *data = sent_packet->get_data(sent_packet->get_data_length());
       
  1855 	if (data == 0)
       
  1856 	{
       
  1857 		return EAP_STATUS_RETURN(this, eap_status_allocation_error);
       
  1858 	}
       
  1859 
       
  1860 	crypto_random_c rand(this);
       
  1861 	u32_t random_guard = 0;
       
  1862 	bool error_generated = false;
       
  1863 
       
  1864 	for (u32_t ind = minimum_index; ind < sent_packet->get_data_length(); ind++)
       
  1865 	{
       
  1866 		status = rand.get_rand_bytes(
       
  1867 			reinterpret_cast<u8_t *>(&random_guard),
       
  1868 			sizeof(random_guard));
       
  1869 		if (status != eap_status_ok)
       
  1870 		{
       
  1871 			return EAP_STATUS_RETURN(this, status);
       
  1872 		}
       
  1873 
       
  1874 		// This is simple limiter to the probability of an error.
       
  1875 		// probability = m_error_probability / (2^32)
       
  1876 		if (random_guard < error_probability)
       
  1877 		{
       
  1878 			u8_t rnd;
       
  1879 			u8_t previous_data;
       
  1880 			// Create an error.
       
  1881 			status = rand.get_rand_bytes(
       
  1882 				&rnd,
       
  1883 				sizeof(rnd));
       
  1884 			if (status != eap_status_ok)
       
  1885 			{
       
  1886 				return EAP_STATUS_RETURN(this, status);
       
  1887 			}
       
  1888 
       
  1889 			previous_data = data[ind];
       
  1890 			data[ind] ^= rnd;
       
  1891 
       
  1892 			if (previous_data != data[ind])
       
  1893 			{
       
  1894 				error_generated = true;
       
  1895 				sent_packet->set_random_error_type(eap_random_error_type_manipulate_byte);
       
  1896 
       
  1897 				EAP_TRACE_DEBUG(
       
  1898 					this, 
       
  1899 					TRACE_FLAGS_DEFAULT, 
       
  1900 					(EAPL("TEST: random_error(): error: manipulate, packet_index 0x%08x:%lu, data[0x%04x] ")
       
  1901 					 EAPL("changed from 0x%02x to 0x%02x.\n"),
       
  1902 					this, packet_index, ind, previous_data, data[ind]));
       
  1903 			}
       
  1904 		}
       
  1905 	} // for()
       
  1906 
       
  1907 
       
  1908 	if (error_generated == false
       
  1909 		&& forse_error == true
       
  1910 		&& sent_packet->get_data_length() > 0ul)
       
  1911 	{
       
  1912 		// Generate one error.
       
  1913 
       
  1914 		// Random error type.
       
  1915 		eap_random_error_type error_type = eap_random_error_type_none_keep_this_last_case;
       
  1916 		status = rand.get_rand_bytes(
       
  1917 			reinterpret_cast<u8_t *>(&error_type),
       
  1918 			sizeof(error_type));
       
  1919 		if (status != eap_status_ok)
       
  1920 		{
       
  1921 			return EAP_STATUS_RETURN(this, status);
       
  1922 		}
       
  1923 
       
  1924 		error_type = static_cast<eap_random_error_type>(
       
  1925 			static_cast<u32_t>(error_type)
       
  1926 			% static_cast<u32_t>(eap_random_error_type_none_keep_this_last_case));
       
  1927 
       
  1928 		sent_packet->set_random_error_type(error_type);
       
  1929 
       
  1930 		switch(error_type)
       
  1931 		{
       
  1932 		case eap_random_error_type_manipulate_byte:
       
  1933 			{
       
  1934 				u32_t rnd_index;
       
  1935 				u8_t previous_data;
       
  1936 				u32_t index;
       
  1937 
       
  1938 				do
       
  1939 				{
       
  1940 					do
       
  1941 					{
       
  1942 						// Create an error index.
       
  1943 						status = rand.get_rand_bytes(
       
  1944 							reinterpret_cast<u8_t *>(&rnd_index),
       
  1945 							sizeof(rnd_index));
       
  1946 						if (status != eap_status_ok)
       
  1947 						{
       
  1948 							return EAP_STATUS_RETURN(this, status);
       
  1949 						}
       
  1950 
       
  1951 						index = (rnd_index % (sent_packet->get_data_length() - minimum_index))
       
  1952 							+ minimum_index;
       
  1953 					}
       
  1954 					while(index < minimum_index
       
  1955 						|| index > sent_packet->get_buffer_length());
       
  1956 
       
  1957 					u8_t rnd;
       
  1958 					// Create an error.
       
  1959 					status = rand.get_rand_bytes(
       
  1960 						&rnd,
       
  1961 						sizeof(rnd));
       
  1962 					if (status != eap_status_ok)
       
  1963 					{
       
  1964 						return EAP_STATUS_RETURN(this, status);
       
  1965 					}
       
  1966 
       
  1967 					previous_data = data[index];
       
  1968 					data[index] ^= rnd;
       
  1969 				}
       
  1970 				while(previous_data == data[index]);
       
  1971 
       
  1972 				EAP_TRACE_DEBUG(
       
  1973 					this, 
       
  1974 					TRACE_FLAGS_DEFAULT, 
       
  1975 					(EAPL("TEST: random_error(): error: manipulate, packet_index 0x%08x:%lu, ")
       
  1976 					 EAPL("data[0x%04x] changed from 0x%02x to 0x%02x.\n"),
       
  1977 					this, packet_index, index, previous_data, data[index]));
       
  1978 
       
  1979 				error_generated = true;
       
  1980 			}
       
  1981 			break;
       
  1982 		case eap_random_error_type_change_packet_length_longer:
       
  1983 			{
       
  1984 				u8_t delta_length = 0;
       
  1985 				i32_t new_length = 0;
       
  1986 
       
  1987 				do
       
  1988 				{
       
  1989 					status = rand.get_rand_bytes(
       
  1990 						reinterpret_cast<u8_t *>(&delta_length),
       
  1991 						sizeof(delta_length));
       
  1992 					if (status != eap_status_ok)
       
  1993 					{
       
  1994 						return EAP_STATUS_RETURN(this, status);
       
  1995 					}
       
  1996 
       
  1997 					new_length = static_cast<i32_t>(sent_packet->get_data_length()) + static_cast<i32_t>(delta_length);
       
  1998 				}
       
  1999 				while (new_length < static_cast<i32_t>(minimum_packet_length) /*eapol_ethernet_header_wr_c::get_header_length()*/
       
  2000 					|| new_length > static_cast<i32_t>(sent_packet->get_buffer_length()));
       
  2001 
       
  2002 				EAP_TRACE_DEBUG(
       
  2003 					this, 
       
  2004 					TRACE_FLAGS_DEFAULT, 
       
  2005 					(EAPL("TEST: random_error(): error: manipulate, packet_index 0x%08x:%lu, ")
       
  2006 					 EAPL("packet length changed from %lu to %lu.\n"),
       
  2007 					this,
       
  2008 					packet_index,
       
  2009 					sent_packet->get_data_length(),
       
  2010 					new_length));
       
  2011 
       
  2012 				sent_packet->set_data_length(new_length);
       
  2013 
       
  2014 				error_generated = true;
       
  2015 			}
       
  2016 			break;
       
  2017 		case eap_random_error_type_change_packet_length_shorter:
       
  2018 			{
       
  2019 				u8_t delta_length = 0;
       
  2020 				i32_t new_length = 0;
       
  2021 
       
  2022 				do
       
  2023 				{
       
  2024 					status = rand.get_rand_bytes(
       
  2025 						reinterpret_cast<u8_t *>(&delta_length),
       
  2026 						sizeof(delta_length));
       
  2027 					if (status != eap_status_ok)
       
  2028 					{
       
  2029 						return EAP_STATUS_RETURN(this, status);
       
  2030 					}
       
  2031 
       
  2032 					delta_length %= (static_cast<i32_t>(sent_packet->get_data_length())
       
  2033 									 - static_cast<i32_t>(minimum_packet_length) /*eapol_ethernet_header_wr_c::get_header_length()*/ );
       
  2034 
       
  2035 					if (delta_length == 0)
       
  2036 					{
       
  2037 						continue;
       
  2038 					}
       
  2039 
       
  2040 					new_length = static_cast<i32_t>(sent_packet->get_data_length()) - static_cast<i32_t>(delta_length);
       
  2041 				}
       
  2042 				while (new_length < static_cast<i32_t>(minimum_packet_length) /*eapol_ethernet_header_wr_c::get_header_length()*/
       
  2043 					|| new_length > static_cast<i32_t>(sent_packet->get_buffer_length()));
       
  2044 
       
  2045 				EAP_TRACE_DEBUG(
       
  2046 					this, 
       
  2047 					TRACE_FLAGS_DEFAULT, 
       
  2048 					(EAPL("TEST: random_error(): error: manipulate, packet_index 0x%08x:%lu, ")
       
  2049 					 EAPL("packet length changed from %lu to %lu.\n"),
       
  2050 					this,
       
  2051 					packet_index,
       
  2052 					sent_packet->get_data_length(),
       
  2053 					new_length));
       
  2054 
       
  2055 				sent_packet->set_data_length(new_length);
       
  2056 
       
  2057 				error_generated = true;
       
  2058 			}
       
  2059 			break;
       
  2060 		default:
       
  2061 			EAP_ASSERT_ANYWAY_TOOLS(this);
       
  2062 			break;
       
  2063 		}
       
  2064 	} // if ()
       
  2065 
       
  2066 
       
  2067 	if (error_generated == true)
       
  2068 	{
       
  2069 		sent_packet->set_is_manipulated();
       
  2070 	}
       
  2071 
       
  2072 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  2073 	return EAP_STATUS_RETURN(this, status);
       
  2074 }
       
  2075 
       
  2076 #endif //#if defined(USE_EAP_ERROR_TESTS)
       
  2077 
       
  2078 //-----------------------------------------------------------------------------------------------
       
  2079 
       
  2080 #if defined(USE_EAP_ERROR_TESTS)
       
  2081 
       
  2082 EAP_FUNC_EXPORT u32_t eap_am_tools_c::get_packet_index()
       
  2083 {
       
  2084 	return m_packet_index;
       
  2085 }
       
  2086 
       
  2087 #endif //#if defined(USE_EAP_ERROR_TESTS)
       
  2088 
       
  2089 //-----------------------------------------------------------------------------------------------
       
  2090 
       
  2091 #if defined(USE_EAP_ERROR_TESTS)
       
  2092 
       
  2093 EAP_FUNC_EXPORT void eap_am_tools_c::increase_packet_index()
       
  2094 {
       
  2095 	++m_packet_index;
       
  2096 }
       
  2097 
       
  2098 #endif //#if defined(USE_EAP_ERROR_TESTS)
       
  2099 
       
  2100 //-----------------------------------------------------------------------------------------------
       
  2101 
       
  2102 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::number_string_to_u32(
       
  2103 	const u8_t * const number_string,
       
  2104 	const u32_t number_string_length,
       
  2105 	u32_t * const integer)
       
  2106 {
       
  2107 	EAP_TRACE_BEGIN(this, TRACE_FLAGS_DEFAULT);
       
  2108 
       
  2109 	if (number_string == 0
       
  2110 		|| number_string_length == 0UL
       
  2111 		|| integer == 0)
       
  2112 	{
       
  2113 		EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  2114 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter);
       
  2115 	}
       
  2116 
       
  2117 	*integer = 0UL;
       
  2118 
       
  2119 	u32_t multiplier = 1UL;
       
  2120 
       
  2121 	for (i32_t ind = number_string_length-1; ind >= 0; ind--)
       
  2122 	{
       
  2123 		u8_t character = number_string[ind];
       
  2124 		if (character < '0' || '9' < character)
       
  2125 		{
       
  2126 			EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  2127 			return EAP_STATUS_RETURN(this, eap_status_illegal_data_payload);
       
  2128 		}
       
  2129 
       
  2130 		u8_t digit = ascii_to_octet(static_cast<i32_t>(number_string[ind]));
       
  2131 
       
  2132 		u32_t addition = static_cast<u32_t>(digit) * multiplier;
       
  2133 		if (((~0UL) - *integer) < addition)
       
  2134 		{
       
  2135 			EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  2136 			return EAP_STATUS_RETURN(this, eap_status_illegal_data_payload);
       
  2137 		}
       
  2138 
       
  2139 		*integer += addition;
       
  2140 
       
  2141 		multiplier *= 10UL;
       
  2142 	}
       
  2143 
       
  2144 	EAP_TRACE_END(this, TRACE_FLAGS_DEFAULT);
       
  2145 	return EAP_STATUS_RETURN(this, eap_status_ok);
       
  2146 }
       
  2147 
       
  2148 //-----------------------------------------------------------------------------------------------
       
  2149 
       
  2150 EAP_FUNC_EXPORT void eap_am_tools_c::trace_configuration(
       
  2151 	const eap_status_e configuration_read_status,
       
  2152 	const eap_configuration_field_c * const field,
       
  2153 	const eap_variable_data_c * const data)
       
  2154 {
       
  2155 	EAP_UNREFERENCED_PARAMETER(data);
       
  2156 
       
  2157 	if (configuration_read_status != eap_status_ok)
       
  2158 	{
       
  2159 		EAP_TRACE_DATA_DEBUG(
       
  2160 			this,
       
  2161 			TRACE_FLAGS_DEFAULT,
       
  2162 			(EAPL("WARNING: unknown configuration parameter"),
       
  2163 			field->get_field(),
       
  2164 			field->get_field_length()));
       
  2165 	}
       
  2166 	else
       
  2167 	{
       
  2168 		EAP_TRACE_DATA_ALWAYS(
       
  2169 			this,
       
  2170 			TRACE_FLAGS_DEFAULT,
       
  2171 			(EAPL("configuration parameter"),
       
  2172 			field->get_field(),
       
  2173 			field->get_field_length()));
       
  2174 
       
  2175 		if (field->get_is_secret() == true)
       
  2176 		{
       
  2177 			EAP_TRACE_DEBUG(
       
  2178 				this, 
       
  2179 				TRACE_FLAGS_DEFAULT, 
       
  2180 				(EAPL("This is secret data. Not shown here.\n")));
       
  2181 		}
       
  2182 		else
       
  2183 		{
       
  2184 			EAP_TRACE_DATA_ALWAYS(
       
  2185 				this,
       
  2186 				TRACE_FLAGS_DEFAULT,
       
  2187 				(EAPL("    configuration value"),
       
  2188 				data->get_data(data->get_data_length()),
       
  2189 				data->get_data_length()));
       
  2190 		}
       
  2191 	}
       
  2192 }
       
  2193 
       
  2194 //-----------------------------------------------------------------------------------------------
       
  2195 
       
  2196 EAP_FUNC_EXPORT u64_t eap_am_tools_c::xor_u64(
       
  2197 	const u64_t p_a,
       
  2198 	const u64_t p_b)
       
  2199 {
       
  2200 
       
  2201 #if defined(USE_EAP_64_BIT_XOR)
       
  2202 
       
  2203 	u64_t ret = p_a ^ p_b;
       
  2204 
       
  2205 #else
       
  2206 
       
  2207 	u64_struct a = u64_t_to_u64_struct(p_a);
       
  2208 	u64_struct b = u64_t_to_u64_struct(p_b);
       
  2209 
       
  2210 
       
  2211 	// Result
       
  2212 	u64_struct result;
       
  2213 	result.high = a.high ^ b.high;
       
  2214 	result.low = a.low ^ b.low;
       
  2215 	
       
  2216 	u64_t ret = u64_struct_to_u64_t(result);
       
  2217 
       
  2218 #endif //#if defined(USE_EAP_64_BIT_XOR)
       
  2219 
       
  2220 	return ret;
       
  2221 }
       
  2222 
       
  2223 //-----------------------------------------------------------------------------------------------
       
  2224 
       
  2225 EAP_FUNC_EXPORT u64_t eap_am_tools_c::multiply_u64(
       
  2226 	const u64_t p_a,
       
  2227 	const u64_t p_b)
       
  2228 {
       
  2229 
       
  2230 #if defined(USE_EAP_64_BIT_MULTIPLICATION)
       
  2231 
       
  2232 	return p_a * p_b;
       
  2233 
       
  2234 #else
       
  2235 
       
  2236 	u32_t a_tmp[4];
       
  2237 	u32_t b_tmp[4];
       
  2238 	u32_t wide_tmp[8];
       
  2239 	u32_t tmp;
       
  2240 	u64_struct a = u64_t_to_u64_struct(p_a);
       
  2241 	u64_struct b = u64_t_to_u64_struct(p_b);
       
  2242 
       
  2243 	//  <--- 32 bits ---> <--- 32 bits ---> <--- 32 bits ---> <--- 32 bits --->
       
  2244 	// +--------+--------+--------+--------+--------+--------+--------+--------+
       
  2245 	// | overf. |  0-15  | overf. |  16-31 | overf. |  32-47 | overf. |  48-63 |
       
  2246 	// +--------+--------+--------+--------+--------+--------+--------+--------+
       
  2247 	a_tmp[0] = a.low & 0xffff;
       
  2248 	a_tmp[1] = (a.low >> 16) & 0xffff;
       
  2249 	a_tmp[2] = a.high & 0xffff;
       
  2250 	a_tmp[3] = (a.high >> 16) & 0xffff;
       
  2251 
       
  2252 	b_tmp[0] = b.low & 0xffff;
       
  2253 	b_tmp[1] = (b.low >> 16) & 0xffff;
       
  2254 	b_tmp[2] = b.high & 0xffff;
       
  2255 	b_tmp[3] = (b.high >> 16) & 0xffff;
       
  2256 
       
  2257 	u32_t j_ind;
       
  2258 
       
  2259 	for(j_ind = 0ul; j_ind < 4ul; j_ind++)
       
  2260 	{
       
  2261 		wide_tmp[j_ind]= 0ul;
       
  2262 	}
       
  2263 
       
  2264 	for(j_ind = 0ul; j_ind < 4ul; j_ind++)
       
  2265 	{
       
  2266 		if(b_tmp[j_ind] == 0ul)
       
  2267 		{
       
  2268 			wide_tmp[j_ind+4ul] = 0ul;
       
  2269 		}
       
  2270 		else
       
  2271 		{
       
  2272 			u32_t l_ind;
       
  2273 			u32_t overflow = 0ul;
       
  2274 
       
  2275 			for(l_ind = 0ul; l_ind < 4ul; l_ind++)
       
  2276 			{
       
  2277 				tmp = a_tmp[l_ind] * b_tmp[j_ind] + wide_tmp[l_ind+j_ind] + overflow;
       
  2278 				wide_tmp[l_ind+j_ind] = tmp & 0xffff;
       
  2279 				overflow = (tmp >> 16) & 0xffff;
       
  2280 			}
       
  2281 
       
  2282 			wide_tmp[j_ind+4] = overflow;
       
  2283 		}
       
  2284 	}
       
  2285 
       
  2286 	// Overflow
       
  2287 	u64_struct overflow;
       
  2288 	overflow.high = ((wide_tmp[7] << 16) & 0xffff0000) + wide_tmp[6];
       
  2289 	overflow.low = ((wide_tmp[5] << 16) & 0xffff0000) + wide_tmp[4];
       
  2290 	EAP_UNREFERENCED_PARAMETER(overflow);
       
  2291 
       
  2292 
       
  2293 	// Result
       
  2294 	u64_struct result;
       
  2295 	result.high = ((wide_tmp[3] << 16) & 0xffff0000) + wide_tmp[2];
       
  2296 	result.low = ((wide_tmp[1] << 16) & 0xffff0000) + wide_tmp[0];
       
  2297 	
       
  2298 	u64_t ret = u64_struct_to_u64_t(result);
       
  2299 
       
  2300 	return ret;
       
  2301 
       
  2302 #endif //#if defined(USE_EAP_64_BIT_MULTIPLICATION)
       
  2303 
       
  2304 }
       
  2305 
       
  2306 //-----------------------------------------------------------------------------------------------
       
  2307 
       
  2308 EAP_FUNC_EXPORT i32_t eap_am_tools_c::compare_u64(const u64_t p_a, const u64_t p_b)
       
  2309 {
       
  2310 	u64_struct a = u64_t_to_u64_struct(p_a);
       
  2311 	u64_struct b = u64_t_to_u64_struct(p_b);
       
  2312 
       
  2313 	if (a.high > b.high)
       
  2314 	{
       
  2315 		return +1;
       
  2316 	}
       
  2317 	else if (a.high < b.high)
       
  2318 	{
       
  2319 		return -1;
       
  2320 	}
       
  2321 	else // if (a.high == b.high)
       
  2322 	{
       
  2323 		if (a.low > b.low)
       
  2324 		{
       
  2325 			return +1;
       
  2326 		}
       
  2327 		else if (a.low < b.low)
       
  2328 		{
       
  2329 			return -1;
       
  2330 		}
       
  2331 		else
       
  2332 		{
       
  2333 			return 0;
       
  2334 		}
       
  2335 	}
       
  2336 }
       
  2337 
       
  2338 //-----------------------------------------------------------------------------------------------
       
  2339 
       
  2340 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::create_uuid_v5( 
       
  2341 	const void* const ns_uuid,
       
  2342 	const u32_t ns_uuid_length,
       
  2343 	const void* const name, 
       
  2344 	const u32_t name_length,
       
  2345 	eap_variable_data_c* const uuid )
       
  2346 {
       
  2347 	// check input
       
  2348 	if( ns_uuid == 0 || 
       
  2349 		ns_uuid_length != EAP_UUID_LENGTH ||
       
  2350 		name == 0 || name_length <= 0 || 
       
  2351 		uuid == 0 || uuid->get_is_valid() == false )
       
  2352 	{
       
  2353 		return EAP_STATUS_RETURN(this, eap_status_illegal_parameter); 
       
  2354 	}
       
  2355 
       
  2356 	// make sure that uuid is empty
       
  2357 	uuid->reset();
       
  2358 
       
  2359 	crypto_sha1_c sha( this );
       
  2360 	if( sha.get_is_valid() == false )
       
  2361 	{
       
  2362 		return EAP_STATUS_RETURN(this, eap_status_allocation_error); 
       
  2363 	}
       
  2364 
       
  2365 	u32_t hash_len = sha.get_digest_length();
       
  2366 	// hash length must be at least the UUID length
       
  2367 	if( hash_len < EAP_UUID_LENGTH )
       
  2368 	{
       
  2369 		return EAP_STATUS_RETURN(this, eap_status_illegal_encryption_parameter_size); 
       
  2370 	}
       
  2371 
       
  2372 	eap_status_e status = sha.hash_init();
       
  2373 	if( status != eap_status_ok )
       
  2374 	{
       
  2375 		return EAP_STATUS_RETURN(this, status); 
       
  2376 	}
       
  2377 
       
  2378 	status = sha.hash_update( ns_uuid, ns_uuid_length );
       
  2379 	if( status != eap_status_ok )
       
  2380 	{
       
  2381 		return EAP_STATUS_RETURN(this, status); 
       
  2382 	}
       
  2383 
       
  2384 	status = sha.hash_update( name, name_length );
       
  2385 	if( status != eap_status_ok )
       
  2386 	{
       
  2387 		return EAP_STATUS_RETURN(this, status); 
       
  2388 	}
       
  2389 
       
  2390 	u8_t* hash = new u8_t[hash_len];
       
  2391 	if( hash == 0 )
       
  2392 	{
       
  2393 		return EAP_STATUS_RETURN(this, eap_status_allocation_error); 
       
  2394 	}
       
  2395 
       
  2396 	status = sha.hash_final( hash, 0 ); // 0 - we have space for full digest in hash
       
  2397 	if( status != eap_status_ok )
       
  2398 	{
       
  2399 		delete[] hash;
       
  2400 		hash = 0;
       
  2401 		return EAP_STATUS_RETURN(this, status); 
       
  2402 	}
       
  2403 
       
  2404 	// save only the needed bytes
       
  2405 	status = uuid->set_copy_of_buffer(hash, EAP_UUID_LENGTH );
       
  2406 	delete[] hash;
       
  2407 	if( status != eap_status_ok )
       
  2408 	{
       
  2409 		return EAP_STATUS_RETURN(this, status); 
       
  2410 	}
       
  2411 
       
  2412 	// use hash as a temporary pointer
       
  2413 	hash = uuid->get_data();
       
  2414 
       
  2415 	// Format according to UUID version 5 (RFC 4122).
       
  2416 	// MSByte                                                     LSByte
       
  2417 	// 0                   1                   2                   3
       
  2418 	//  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
       
  2419 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2420 	// |                          time_low                             |
       
  2421 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2422 	// |       time_mid                |         time_hi_and_version   |
       
  2423 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2424 	// |clk_seq_hi_res |  clk_seq_low  |         node (0-1)            |
       
  2425 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2426 	// |                         node (2-5)                            |
       
  2427 	// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       
  2428 
       
  2429 	// set the four most significant bits (bits 12 through 15) of the
       
  2430 	// time_hi_and_version field to the appropriate 4-bit version number
       
  2431 	hash[6] &= 0x0F;
       
  2432 	hash[6] |= 0x50;
       
  2433 
       
  2434 	// set the two most significant bits (bits 6 and 7) of the
       
  2435     // clock_seq_hi_and_reserved to zero and one, respectively
       
  2436 	hash[8] &= 0x3F;
       
  2437 	hash[8] |= 0x80;
       
  2438 
       
  2439 	return EAP_STATUS_RETURN(this, eap_status_ok);
       
  2440 }
       
  2441 
       
  2442 //-----------------------------------------------------------------------------------------------
       
  2443 
       
  2444 EAP_FUNC_EXPORT eap_status_e eap_am_tools_c::create_uuid_v5_from_mac_address( 
       
  2445 	const u8_t* const mac_address,
       
  2446 	const u32_t mac_address_length,
       
  2447 	eap_variable_data_c* const uuid )
       
  2448 {
       
  2449 
       
  2450 	eap_status_e status = create_uuid_v5( 
       
  2451 		EAP_MAC_ADDRESS_NAMESPACE_UUID_V5,
       
  2452 		sizeof(EAP_MAC_ADDRESS_NAMESPACE_UUID_V5),
       
  2453 		mac_address,
       
  2454 		mac_address_length,
       
  2455 		uuid);
       
  2456 
       
  2457 	return EAP_STATUS_RETURN(this, status);
       
  2458 }
       
  2459 		
       
  2460 //-----------------------------------------------------------------------------------------------
       
  2461 
       
  2462 // End.