eapol/eapol_framework/eapol_common/type/simple_config/eap/src/eap_type_simple_config.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 590 
       
    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 #if defined(USE_EAP_SIMPLE_CONFIG)
       
    29 
       
    30 #include "eap_am_memory.h"
       
    31 #include "eap_type_simple_config_types.h"
       
    32 #include "eap_type_simple_config.h"
       
    33 #include "eap_type_simple_config_header.h"
       
    34 #include "eap_type_simple_config_state_notification.h"
       
    35 #include "eap_am_type_simple_config.h"
       
    36 #include "eap_state_notification.h"
       
    37 #include "simple_config_tlv_header.h"
       
    38 #include "simple_config_base_record.h"
       
    39 #include "eap_config.h"
       
    40 #include "eap_header_string.h"
       
    41 
       
    42 //--------------------------------------------------
       
    43 
       
    44 //
       
    45 EAP_FUNC_EXPORT eap_type_simple_config_c::~eap_type_simple_config_c()
       
    46 {
       
    47 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    48 
       
    49 	EAP_TRACE_DEBUG(
       
    50 		m_am_tools,
       
    51 		TRACE_FLAGS_DEFAULT,
       
    52 		(EAPL("%s: function: eap_type_simple_config_c::~eap_type_simple_config_c(): this = 0x%08x => 0x%08x,")
       
    53 		 EAPL(" m_am_type_simple_config = 0x%08x (validity %d).\n"),
       
    54 		 (m_is_client == true ? "client": "server"),
       
    55 		 this,
       
    56 		 dynamic_cast<abs_eap_base_timer_c *>(this),
       
    57 		 m_am_type_simple_config,
       
    58 		 m_am_type_simple_config->get_is_valid()));
       
    59 
       
    60 	EAP_ASSERT(m_shutdown_was_called == true);
       
    61 
       
    62 	if (m_free_simple_config_record == true)
       
    63 	{
       
    64 		delete m_simple_config_record;
       
    65 		m_simple_config_record = 0;
       
    66 	}
       
    67 
       
    68 	if (m_free_am_type_simple_config == true)
       
    69 	{
       
    70 		delete m_am_type_simple_config;
       
    71 		m_am_type_simple_config = 0;
       
    72 	}
       
    73 
       
    74 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
    75 }
       
    76 
       
    77 //--------------------------------------------------
       
    78 
       
    79 //
       
    80 EAP_FUNC_EXPORT eap_type_simple_config_c::eap_type_simple_config_c(
       
    81 	abs_eap_am_tools_c * const tools, ///< This is pointer to the tools AM of current platform.
       
    82 	abs_eap_base_type_c * const partner, ///< This is back pointer to object which created this object.
       
    83 	eap_am_type_simple_config_c * const am_type_simple_config, ///< This is pointer to adaptation module of EAP-SIMPLE_CONFIG type.
       
    84 	const bool free_am_type_simple_config,
       
    85 	simple_config_base_record_c * const simple_config_record, /// This is pointer to SIMPLE_CONFIG implementation.
       
    86 	const bool free_simple_config_record,
       
    87 	const bool is_client_when_true, ///< Indicates whether this is client (true) or server (false).
       
    88 	const eap_type_value_e current_eap_type, ///< This the current EAP-type (SIMPLE_CONFIG or PEAP).
       
    89 	const eap_am_network_id_c * const receive_network_id)
       
    90 	: eap_base_type_c(tools, partner)
       
    91 	  , m_am_tools(tools)
       
    92 	  , m_am_type_simple_config(am_type_simple_config)
       
    93 	  , m_simple_config_record(simple_config_record)
       
    94 	  , m_nai_realm(tools)
       
    95 	  , m_NAI(tools)
       
    96 	  , m_send_network_id(tools)
       
    97 	  , m_simple_config_header_offset(0u)
       
    98 	  , m_MTU(0u)
       
    99 	  , m_trailer_length(0u)
       
   100 	  , m_state(eap_type_simple_config_state_waiting_for_identity_request)
       
   101 	  , m_saved_previous_state(eap_type_simple_config_state_waiting_for_identity_request)
       
   102 	  , m_reassembly_state(eap_type_simple_config_reassembly_state_wait_first_message)
       
   103 	  , m_saved_previous_reassembly_state(eap_type_simple_config_reassembly_state_wait_first_message)
       
   104 	  , m_simple_config_message_send_offset(0ul)
       
   105 	  , m_simple_config_message_buffer(tools)
       
   106 	  , m_first_fragment_eap_identifier(0ul)
       
   107 	  , m_free_am_type_simple_config(free_am_type_simple_config)
       
   108 	  , m_free_simple_config_record(free_simple_config_record)
       
   109 	  , m_is_valid(false)
       
   110 	  , m_is_client(is_client_when_true)
       
   111 	  , m_check_identifier_of_eap_identity_response(false)
       
   112 	  , m_simple_config_test_version(false)
       
   113 	  , m_check_nai_realm(false)
       
   114 	  , m_failure_message_received(false)
       
   115 	  , m_authentication_finished_successfully(false)
       
   116 	  , m_last_eap_identifier(0ul)
       
   117 	  , m_shutdown_was_called(false)
       
   118 	  , m_simple_config_message_type(simple_config_Message_Type_None)
       
   119 {
       
   120 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   121 
       
   122 	EAP_TRACE_DEBUG(
       
   123 		m_am_tools,
       
   124 		TRACE_FLAGS_DEFAULT,
       
   125 		(EAPL("%s: function: eap_type_simple_config_c::eap_type_simple_config_c(): ")
       
   126 		 EAPL("this = 0x%08x => 0x%08x, compiled %s %s\n"),
       
   127 		 (m_is_client == true ? "client": "server"),
       
   128 		 this,
       
   129 		 dynamic_cast<abs_eap_base_timer_c *>(this),
       
   130 		__DATE__,
       
   131 		__TIME__));
       
   132 
       
   133 	if (receive_network_id == 0
       
   134 		|| receive_network_id->get_is_valid_data() == false)
       
   135 	{
       
   136 		// No need to delete anything here because it is done in destructor.
       
   137 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   138 		return;
       
   139 	}
       
   140 
       
   141 	if (simple_config_record == 0)
       
   142 	{
       
   143 		// No need to delete anything here because it is done in destructor.
       
   144 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   145 		return;
       
   146 	}
       
   147 	m_simple_config_record->set_type_partner(this);
       
   148 
       
   149 	if (m_am_type_simple_config == 0)
       
   150 	{
       
   151 		// Something wrong with AM.
       
   152 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   153 		return;
       
   154 	}
       
   155 	m_am_type_simple_config->set_am_partner(this);
       
   156 
       
   157 
       
   158 	// Here we swap the addresses.
       
   159 	eap_am_network_id_c send_network_id(
       
   160 		m_am_tools,
       
   161 		receive_network_id->get_destination_id(),
       
   162 		receive_network_id->get_source_id(),
       
   163 		receive_network_id->get_type());
       
   164 
       
   165 	eap_status_e status = get_send_network_id()->set_copy_of_network_id(
       
   166 		&send_network_id);
       
   167 	if (status != eap_status_ok)
       
   168 	{
       
   169 		EAP_UNREFERENCED_PARAMETER(current_eap_type);
       
   170 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   171 		return;
       
   172 	}
       
   173 
       
   174 	if (m_is_client == false)
       
   175 	{
       
   176 		// Server waits EAP-Response/Identity.
       
   177 		m_state = eap_type_simple_config_state_waiting_for_identity_response;
       
   178 		m_saved_previous_state
       
   179 			= eap_type_simple_config_state_waiting_for_identity_response;
       
   180 	}
       
   181 
       
   182 	set_is_valid();
       
   183 
       
   184 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   185 }
       
   186 
       
   187 //--------------------------------------------------
       
   188 
       
   189 //
       
   190 EAP_FUNC_EXPORT void eap_type_simple_config_c::save_current_state()
       
   191 {
       
   192 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   193 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   194 	m_saved_previous_state = m_state;
       
   195 }
       
   196 
       
   197 //--------------------------------------------------
       
   198 
       
   199 //
       
   200 EAP_FUNC_EXPORT void eap_type_simple_config_c::restore_saved_previous_state()
       
   201 {
       
   202 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   203 	set_state(m_saved_previous_state);
       
   204 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   205 }
       
   206 
       
   207 //--------------------------------------------------
       
   208 
       
   209 //
       
   210 EAP_FUNC_EXPORT void eap_type_simple_config_c::set_state(
       
   211 	const eap_type_simple_config_state_variable_e state)
       
   212 {
       
   213 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   214 
       
   215 	eap_type_simple_config_state_variable_e previous_state = m_state;
       
   216 	EAP_UNREFERENCED_PARAMETER(previous_state); // This is used only for debugging.
       
   217 
       
   218 	if (m_state != eap_type_simple_config_state_failure)
       
   219 	{
       
   220 		m_state = state;
       
   221 	}
       
   222 
       
   223 	EAP_TRACE_DEBUG(
       
   224 		m_am_tools,
       
   225 		TRACE_FLAGS_DEFAULT,
       
   226 		(EAPL("eap_type_simple_config_c::set_state(): ")
       
   227 		 EAPL("%s: Previous state %d=%s, new state %d=%s.\n"),
       
   228 			(m_is_client == true ? "client": "server"),
       
   229 			previous_state,
       
   230 			get_state_string(previous_state),
       
   231 			m_state,
       
   232 			get_state_string(m_state)));
       
   233 
       
   234 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   235 }
       
   236 
       
   237 //--------------------------------------------------
       
   238 
       
   239 //
       
   240 EAP_FUNC_EXPORT eap_type_simple_config_reassembly_state_e eap_type_simple_config_c::get_reassembly_state() const
       
   241 {
       
   242 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   243 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   244 	return m_reassembly_state;
       
   245 }
       
   246 
       
   247 //--------------------------------------------------
       
   248 
       
   249 //
       
   250 EAP_FUNC_EXPORT void eap_type_simple_config_c::set_reassembly_state(
       
   251 	const eap_type_simple_config_reassembly_state_e state)
       
   252 {
       
   253 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   254 
       
   255 	m_reassembly_state = state;
       
   256 
       
   257 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   258 }
       
   259 
       
   260 //--------------------------------------------------
       
   261 
       
   262 //
       
   263 EAP_FUNC_EXPORT void eap_type_simple_config_c::save_current_reassembly_state()
       
   264 {
       
   265 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   266 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   267 	m_saved_previous_reassembly_state = m_reassembly_state;
       
   268 }
       
   269 
       
   270 //--------------------------------------------------
       
   271 
       
   272 //
       
   273 EAP_FUNC_EXPORT void eap_type_simple_config_c::restore_saved_reassembly_state()
       
   274 {
       
   275 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   276 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   277 	m_reassembly_state = m_saved_previous_reassembly_state;
       
   278 }
       
   279 
       
   280 //--------------------------------------------------
       
   281 
       
   282 //
       
   283 EAP_FUNC_EXPORT eap_am_network_id_c * eap_type_simple_config_c::get_send_network_id()
       
   284 {
       
   285 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   286 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   287 	return &m_send_network_id;
       
   288 }
       
   289 
       
   290 //--------------------------------------------------
       
   291 
       
   292 //
       
   293 EAP_FUNC_EXPORT void eap_type_simple_config_c::set_last_eap_identifier(const u8_t last_eap_identifier)
       
   294 {
       
   295 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   296 
       
   297 	m_last_eap_identifier = last_eap_identifier;
       
   298 
       
   299 	EAP_TRACE_DEBUG(
       
   300 		m_am_tools,
       
   301 		TRACE_FLAGS_DEFAULT,
       
   302 		(EAPL("eap_type_simple_config_c::set_last_eap_identifier():")
       
   303 		 EAPL("%s, saved EAP-identifier %d, state %s\n"),
       
   304 		 (m_is_client == true ? "client": "server"),
       
   305 		 m_last_eap_identifier,
       
   306 		 get_state_string()));
       
   307 
       
   308 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   309 }
       
   310 
       
   311 //--------------------------------------------------
       
   312 
       
   313 //
       
   314 EAP_FUNC_EXPORT u8_t eap_type_simple_config_c::get_last_eap_identifier() const
       
   315 {
       
   316 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   317 
       
   318 	EAP_TRACE_DEBUG(
       
   319 		m_am_tools,
       
   320 		TRACE_FLAGS_DEFAULT,
       
   321 		(EAPL("eap_type_simple_config_c::get_last_eap_identifier():")
       
   322 		 EAPL("%s, saved EAP-identifier %d, state %s\n"),
       
   323 		 (m_is_client == true ? "client": "server"),
       
   324 		 m_last_eap_identifier,
       
   325 		 get_state_string()));
       
   326 
       
   327 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   328 	return m_last_eap_identifier;
       
   329 }
       
   330 
       
   331 //--------------------------------------------------
       
   332 
       
   333 //
       
   334 EAP_FUNC_EXPORT eap_const_string eap_type_simple_config_c::get_state_string(
       
   335 	eap_type_simple_config_state_variable_e state)
       
   336 {
       
   337 
       
   338 #if defined(USE_EAP_TRACE_STRINGS)
       
   339 	EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_waiting_for_identity_request)
       
   340 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_pending_identity_query)
       
   341 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_waiting_for_simple_config_start)
       
   342 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_process_simple_config_start)
       
   343 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_waiting_for_request)
       
   344 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_waiting_for_identity_response)
       
   345 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_waiting_for_response)
       
   346 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_process_simple_config_message)
       
   347 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_success)
       
   348 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_state_failure)
       
   349 	else
       
   350 #else
       
   351 	EAP_UNREFERENCED_PARAMETER(state);	
       
   352 #endif // #if defined(USE_EAP_TRACE_STRINGS)
       
   353 	{
       
   354 		return EAPL("Unknown EAP-SIMPLE_CONFIG state");
       
   355 	}
       
   356 }
       
   357 
       
   358 //--------------------------------------------------
       
   359 
       
   360 //
       
   361 EAP_FUNC_EXPORT eap_const_string eap_type_simple_config_c::get_reassembly_state_string(
       
   362 	eap_type_simple_config_reassembly_state_e state)
       
   363 {
       
   364 
       
   365 #if defined(USE_EAP_TRACE_STRINGS)
       
   366 	EAP_IF_RETURN_STRING(state, eap_type_simple_config_reassembly_state_none)
       
   367 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_reassembly_state_wait_first_message)
       
   368 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_reassembly_state_wait_last_fragment)
       
   369 	else EAP_IF_RETURN_STRING(state, eap_type_simple_config_reassembly_state_message_reassembled)
       
   370 	else
       
   371 #else
       
   372 	EAP_UNREFERENCED_PARAMETER(state);		
       
   373 #endif // #if defined(USE_EAP_TRACE_STRINGS)
       
   374 	{
       
   375 		return EAPL("Unknown SIMPLE_CONFIG reassembly state");
       
   376 	}
       
   377 }
       
   378 
       
   379 //--------------------------------------------------
       
   380 
       
   381 EAP_FUNC_EXPORT eap_const_string eap_type_simple_config_c::get_state_string() const
       
   382 {
       
   383 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   384 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   385 	return get_state_string(m_state);
       
   386 }
       
   387 
       
   388 //--------------------------------------------------
       
   389 
       
   390 EAP_FUNC_EXPORT eap_const_string eap_type_simple_config_c::get_reassembly_state_string() const
       
   391 {
       
   392 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   393 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   394 	return get_reassembly_state_string(m_reassembly_state);
       
   395 }
       
   396 
       
   397 //--------------------------------------------------
       
   398 
       
   399 EAP_FUNC_EXPORT eap_const_string eap_type_simple_config_c::get_saved_previous_state_string() const
       
   400 {
       
   401 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   402 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   403 	return get_state_string(m_saved_previous_state);
       
   404 }
       
   405 
       
   406 //--------------------------------------------------
       
   407 
       
   408 EAP_FUNC_EXPORT void eap_type_simple_config_c::set_failure_message_received()
       
   409 {
       
   410 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   411 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   412 	m_failure_message_received = true;
       
   413 }
       
   414 
       
   415 //--------------------------------------------------
       
   416 
       
   417 EAP_FUNC_EXPORT void eap_type_simple_config_c::unset_failure_message_received()
       
   418 {
       
   419 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   420 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   421 	m_failure_message_received = false;
       
   422 }
       
   423 
       
   424 //--------------------------------------------------
       
   425 
       
   426 EAP_FUNC_EXPORT bool eap_type_simple_config_c::get_failure_message_received() const
       
   427 {
       
   428 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   429 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   430 	return m_failure_message_received;
       
   431 }
       
   432 
       
   433 //--------------------------------------------------
       
   434 
       
   435 EAP_FUNC_EXPORT eap_type_simple_config_state_variable_e eap_type_simple_config_c::get_state() const
       
   436 {
       
   437 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   438 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   439 	return m_state;
       
   440 }
       
   441 
       
   442 //--------------------------------------------------
       
   443 
       
   444 //
       
   445 EAP_FUNC_EXPORT eap_variable_data_c * eap_type_simple_config_c::get_nai_realm()
       
   446 {
       
   447 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   448 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   449 	return &m_nai_realm;
       
   450 }
       
   451 
       
   452 //--------------------------------------------------
       
   453 
       
   454 //
       
   455 EAP_FUNC_EXPORT eap_variable_data_c * eap_type_simple_config_c::get_NAI()
       
   456 {
       
   457 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   458 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   459 	return &m_NAI;
       
   460 }
       
   461 
       
   462 //--------------------------------------------------
       
   463 
       
   464 //
       
   465 EAP_FUNC_EXPORT void eap_type_simple_config_c::update_buffer_indexes(
       
   466 	const u32_t maximum_buffer_size,
       
   467 	const u32_t payload_size,
       
   468 	u32_t * const buffer_offset,
       
   469 	u32_t * const buffer_free)
       
   470 {
       
   471 	EAP_UNREFERENCED_PARAMETER(maximum_buffer_size);
       
   472 
       
   473 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   474 
       
   475 	EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length);
       
   476 	EAP_ASSERT_ALWAYS(*buffer_free >= payload_size);
       
   477 	EAP_ASSERT_ALWAYS(m_simple_config_header_offset+m_MTU == *buffer_offset + *buffer_free);
       
   478 
       
   479 	*buffer_free -= payload_size;
       
   480 	*buffer_offset += payload_size;
       
   481 
       
   482 	EAP_ASSERT_ALWAYS(*buffer_offset + *buffer_free <= maximum_buffer_size-m_trailer_length);
       
   483 	EAP_ASSERT_ALWAYS(*buffer_offset <= m_simple_config_header_offset+m_MTU);
       
   484 
       
   485 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   486 }
       
   487 
       
   488 //--------------------------------------------------
       
   489 
       
   490 //
       
   491 EAP_FUNC_EXPORT void eap_type_simple_config_c::update_payload_indexes(
       
   492 	const u32_t /*maximum_buffer_size*/,
       
   493 	const u32_t /*eap_header_size*/,
       
   494 	const u32_t /*payload_size*/,
       
   495 	u32_t * const /*data_offset*/,
       
   496 	u32_t * const /*data_free*/,
       
   497 	u32_t * const /*buffer_offset*/,
       
   498 	u32_t * const /*buffer_free*/)
       
   499 {
       
   500 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   501 
       
   502 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   503 }
       
   504 
       
   505 //--------------------------------------------------
       
   506 
       
   507 //
       
   508 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::parse_identity(
       
   509 	const u8_t * const identity, ///< This is pointer to received EAP-Identity buffer.
       
   510 	const u32_t identity_length ///< This is length of received EAP-Identity buffer.
       
   511 	)
       
   512 {
       
   513 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   514 
       
   515 	if (identity_length < 1u)
       
   516 	{
       
   517 		// Anonymous identity.
       
   518 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   519 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   520 	}
       
   521 
       
   522 	const u8_t *at_character = reinterpret_cast<const u8_t *>(
       
   523 		m_am_tools->memchr(
       
   524 			identity,
       
   525 			EAP_SIMPLE_CONFIG_AT_CHARACTER,
       
   526 			identity_length));
       
   527 	if (at_character == 0)
       
   528 	{
       
   529 		// No realm.
       
   530 		// This is allowed.
       
   531 	}
       
   532 
       
   533 	eap_status_e status = check_NAI(identity, identity_length, at_character);
       
   534 	if (status != eap_status_ok)
       
   535 	{
       
   536 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   537 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   538 	}
       
   539 
       
   540 	status = eap_status_process_general_error;
       
   541 
       
   542 	status = get_NAI()->set_copy_of_buffer(identity, identity_length);
       
   543 	if (status != eap_status_ok)
       
   544 	{
       
   545 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   546 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   547 	}
       
   548 
       
   549 	EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("SIMPLE_CONFIG received EAP-identity NAI"),
       
   550 		get_NAI()->get_data(get_NAI()->get_data_length()),
       
   551 		get_NAI()->get_data_length()));
       
   552 
       
   553 	if (get_NAI()->get_data_length() != EAP_SIMPLE_CONFIG_ENROLLEE_IDENTITY_LENGTH
       
   554 		|| m_am_tools->memcmp(
       
   555 			get_NAI()->get_data(),
       
   556 			EAP_SIMPLE_CONFIG_ENROLLEE_IDENTITY,
       
   557 			EAP_SIMPLE_CONFIG_ENROLLEE_IDENTITY_LENGTH) != 0)
       
   558 	{
       
   559 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   560 		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
   561 	}
       
   562 
       
   563 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   564 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   565 }
       
   566 
       
   567 //--------------------------------------------------
       
   568 
       
   569 //
       
   570 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::simple_config_packet_send(
       
   571 	eap_buf_chain_wr_c * const sent_packet,
       
   572 	const simple_config_Message_Type_e message_type
       
   573     )
       
   574 {
       
   575 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   576 
       
   577 	EAP_TRACE_DEBUG(
       
   578 		m_am_tools,
       
   579 		TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
   580 	EAP_TRACE_DEBUG(
       
   581 		m_am_tools,
       
   582 		TRACE_FLAGS_DEFAULT,
       
   583 		(EAPL("EAP_type_SIMPLE_CONFIG: %s: function: simple_config_packet_send()\n"),
       
   584 		(m_is_client == true ? "client": "server")));
       
   585 
       
   586 	eap_status_e status = eap_status_not_supported;
       
   587 		
       
   588 	if ((m_is_client == true
       
   589 			&& get_state() == eap_type_simple_config_state_process_simple_config_start)
       
   590 		|| get_state() == eap_type_simple_config_state_process_simple_config_message
       
   591 		|| get_state() == eap_type_simple_config_state_waiting_for_request // This state is needed to send messages from asyncronous completions.
       
   592 		|| get_state() == eap_type_simple_config_state_waiting_for_response // This state is needed to send messages from asyncronous completions.
       
   593 		|| get_state() == eap_type_simple_config_state_success // This state is needed to send the WCS_Done message.
       
   594 		|| get_state() == eap_type_simple_config_state_failure // This state is needed to send failure messages.
       
   595 		|| (m_is_client == false
       
   596 			&& get_state() == eap_type_simple_config_state_success)
       
   597 		)
       
   598 	{
       
   599 		status = m_simple_config_message_buffer.set_copy_of_buffer(
       
   600 			sent_packet->get_data(sent_packet->get_data_length()),
       
   601 			sent_packet->get_data_length());
       
   602 		if (status != eap_status_ok)
       
   603 		{
       
   604 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   605 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   606 		}
       
   607 
       
   608 		// This will start the packet send from begin of the message.
       
   609 		m_simple_config_message_send_offset = 0ul;
       
   610 		
       
   611 		// Save the type of the message for fragmentation
       
   612 		m_simple_config_message_type = message_type;
       
   613 
       
   614 		status = eap_simple_config_fragment_send();
       
   615 		if (status != eap_status_ok)
       
   616 		{
       
   617 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   618 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   619 		}
       
   620 	}
       
   621 	else
       
   622 	{
       
   623 		EAP_TRACE_ERROR(
       
   624 			m_am_tools,
       
   625 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
   626 			(EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_send(): ")
       
   627 			 EAPL("Cannot send EAP-SIMPLE_CONFIG message in ")
       
   628 			 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
   629 			get_state(),
       
   630 			 get_state_string()));
       
   631 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   632 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
   633 	}
       
   634 
       
   635 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   636 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   637 }
       
   638 
       
   639 //--------------------------------------------------
       
   640 
       
   641 //
       
   642 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::packet_send(
       
   643 	const eap_am_network_id_c * const network_id,
       
   644 	eap_buf_chain_wr_c * const sent_packet,
       
   645 	const u32_t header_offset,
       
   646 	const u32_t data_length,
       
   647 	const u32_t buffer_length)
       
   648 {
       
   649 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   650 
       
   651 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
   652 	EAP_TRACE_DEBUG(
       
   653 		m_am_tools,
       
   654 		TRACE_FLAGS_DEFAULT,
       
   655 		(EAPL("EAP_type_SIMPLE_CONFIG: %s: function: packet_send()\n"),
       
   656 		(m_is_client == true ? "client": "server")));
       
   657 
       
   658 	eap_header_wr_c eap(
       
   659 		m_am_tools,
       
   660 		sent_packet->get_data_offset(
       
   661 			header_offset, data_length),
       
   662 		data_length);
       
   663 	if (eap.get_is_valid() == false)
       
   664 	{
       
   665 		EAP_TRACE_ERROR(
       
   666 			m_am_tools,
       
   667 			TRACE_FLAGS_DEFAULT,
       
   668 			(EAPL("packet_send: packet buffer corrupted.\n")));
       
   669 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
   670 	}
       
   671 
       
   672 	packet_trace(
       
   673 		EAPL("<-"),
       
   674 		network_id,
       
   675 		&eap,
       
   676 		data_length);
       
   677 
       
   678 	eap_status_e status = get_type_partner()->packet_send(
       
   679 		network_id, 
       
   680 		sent_packet, 
       
   681 		header_offset, 
       
   682 		data_length,
       
   683 		buffer_length
       
   684 		);
       
   685 
       
   686 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   687 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   688 }
       
   689 
       
   690 //--------------------------------------------------
       
   691 
       
   692 //
       
   693 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::check_NAI(
       
   694 	const u8_t * const identity,
       
   695 	const u32_t identity_length,
       
   696 	const u8_t * const at_character)
       
   697 {
       
   698 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   699 
       
   700 	bool includes_at = false;
       
   701 	bool includes_dot = false;
       
   702 	u32_t username_length = 0u;
       
   703 	u32_t realm_length = 0u;
       
   704 
       
   705 	for (u32_t ind = 0; ind < identity_length; ind++)
       
   706 	{
       
   707 		const u8_t character = identity[ind];
       
   708 
       
   709 		if (includes_at == false)
       
   710 		{
       
   711 			if (character != EAP_SIMPLE_CONFIG_AT_CHARACTER)
       
   712 			{
       
   713 				++username_length;
       
   714 			}
       
   715 		}
       
   716 		else
       
   717 		{
       
   718 			++realm_length;
       
   719 		}
       
   720 
       
   721 
       
   722 		if ('0' <= character && character <= '9')
       
   723 		{
       
   724 			// OK.
       
   725 		}
       
   726 		else if ('a' <= character && character <= 'z')
       
   727 		{
       
   728 			// OK.
       
   729 		}
       
   730 		else if ('A' <= character && character <= 'Z')
       
   731 		{
       
   732 			// OK.
       
   733 		}
       
   734 		else if (character == EAP_SIMPLE_CONFIG_AT_CHARACTER)
       
   735 		{
       
   736 			if (includes_at == false)
       
   737 			{
       
   738 				includes_at = true;
       
   739 			}
       
   740 			else
       
   741 			{
       
   742 				// Second at ('@').
       
   743 				EAP_TRACE_DATA_DEBUG(
       
   744 					m_am_tools,
       
   745 					TRACE_FLAGS_DEFAULT,
       
   746 					(EAPL("ERROR: Illegal NAI, includes second at \'@\' character."),
       
   747 					identity,
       
   748 					identity_length));
       
   749 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   750 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai);
       
   751 			}
       
   752 		}
       
   753 		else if (character == '.')
       
   754 		{
       
   755 			if (includes_at == true)
       
   756 			{
       
   757 				// OK.
       
   758 				includes_dot = true;
       
   759 			}
       
   760 			else
       
   761 			{
       
   762 				// dot ('.') within username
       
   763 				EAP_TRACE_DATA_DEBUG(
       
   764 					m_am_tools,
       
   765 					TRACE_FLAGS_DEFAULT,
       
   766 					(EAPL("ERROR: Illegal NAI, dot \'.\' within username."),
       
   767 					identity,
       
   768 					identity_length));
       
   769 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   770 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai);
       
   771 			}
       
   772 		}
       
   773 		else if (character == '<'
       
   774 			|| character == '>'
       
   775 			|| character == '('
       
   776 			|| character == ')'
       
   777 			|| character == '['
       
   778 			|| character == ']'
       
   779 			|| character == '\\'
       
   780 			|| character == '.'
       
   781 			|| character == ','
       
   782 			|| character == ';'
       
   783 			|| character == ':'
       
   784 			|| character == EAP_SIMPLE_CONFIG_AT_CHARACTER
       
   785 			|| character == ' ' // space
       
   786 			|| character <= 0x1f // Ctrl
       
   787 			|| character >= 0x7f) // extented characters
       
   788 		{
       
   789 			// Illegal character.
       
   790 			EAP_TRACE_ERROR(
       
   791 				m_am_tools,
       
   792 				TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
   793 				(EAPL("ERROR: Illegal NAI, includes illegal character 0x%02x=%c.\n"),
       
   794 				character,
       
   795 				character));
       
   796 			EAP_TRACE_DATA_ERROR(
       
   797 				m_am_tools,
       
   798 				TRACE_FLAGS_DEFAULT,
       
   799 				(EAPL("ERROR: Illegal NAI, includes illegal character."),
       
   800 				identity,
       
   801 				identity_length));
       
   802 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   803 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai);
       
   804 		}
       
   805 		else
       
   806 		{
       
   807 			// All other ascii values are OK.
       
   808 		}
       
   809 	}
       
   810 
       
   811 	// Note the username could be zero length.
       
   812 	if ((realm_length == 1u && includes_at == true) // one at ('@') is illegal.
       
   813 		|| (realm_length == 2u && includes_at == true && includes_dot == true)) //  one at ('@') and one dot is illegal.
       
   814 	{
       
   815 		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: Illegal NAI."),
       
   816 			identity,
       
   817 			identity_length));
       
   818 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   819 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai);
       
   820 	}
       
   821 
       
   822 	if (m_check_nai_realm == true)
       
   823 	{
       
   824 		if (at_character == 0
       
   825 			&& realm_length == 0
       
   826 			&& get_nai_realm()->get_data_length() == 0)
       
   827 		{
       
   828 			// OK, no realm.
       
   829 		}
       
   830 		else if (at_character == 0
       
   831 			|| realm_length != get_nai_realm()->get_data_length()
       
   832 			|| m_am_tools->memcmp(
       
   833 				at_character+1u,
       
   834 				get_nai_realm()->get_data(get_nai_realm()->get_data_length()),
       
   835 				get_nai_realm()->get_data_length()) != 0)
       
   836 		{
       
   837 			EAP_TRACE_DATA_DEBUG(
       
   838 				m_am_tools, 
       
   839 				TRACE_FLAGS_DEFAULT, 
       
   840 				(EAPL("Illegal NAI, realm unknown."),
       
   841 				identity,
       
   842 				identity_length));
       
   843 			EAP_TRACE_DATA_DEBUG(
       
   844 				m_am_tools, 
       
   845 				TRACE_FLAGS_DEFAULT, 
       
   846 				(EAPL("NAI should be"),
       
   847 				get_nai_realm()->get_data(get_nai_realm()->get_data_length()),
       
   848 				get_nai_realm()->get_data_length()));
       
   849 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   850 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai);
       
   851 		}
       
   852 	}
       
   853 
       
   854 
       
   855 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   856 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
   857 }
       
   858 
       
   859 //--------------------------------------------------
       
   860 
       
   861 //
       
   862 EAP_FUNC_EXPORT void eap_type_simple_config_c::packet_trace(
       
   863 	eap_const_string prefix,
       
   864 	const eap_am_network_id_c * const /*receive_network_id*/,
       
   865 	eap_header_wr_c * const eap_packet,
       
   866 	const u32_t eap_packet_length)
       
   867 {
       
   868 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   869 	
       
   870 	EAP_UNREFERENCED_PARAMETER(prefix); // in release
       
   871 	
       
   872 	if (eap_packet_length > eap_header_base_c::get_header_length()
       
   873 		&& eap_packet->get_type() == eap_expanded_type_simple_config.get_type())
       
   874 	{
       
   875 		eap_simple_config_header_c * const received_simple_config
       
   876 			= reinterpret_cast<eap_simple_config_header_c *>(eap_packet);
       
   877 
       
   878 		const u8_t * const p_simple_config_flags = received_simple_config->get_simple_config_flags();
       
   879 		u8_t simple_config_flags = 0u;
       
   880 		EAP_UNREFERENCED_PARAMETER(simple_config_flags); // in release
       
   881 		if (p_simple_config_flags != 0)
       
   882 		{
       
   883 			simple_config_flags = *p_simple_config_flags;
       
   884 		}
       
   885 
       
   886 		u32_t simple_config_message_length = 0ul;
       
   887 		if (received_simple_config->get_simple_config_message_length(&simple_config_message_length) != eap_status_ok)
       
   888 		{
       
   889 			simple_config_message_length = 0ul;
       
   890 		}
       
   891 
       
   892 		EAP_TRACE_DEBUG(
       
   893 			m_am_tools,
       
   894 			TRACE_FLAGS_DEFAULT,
       
   895 			(EAPL("%s EAP-SIMPLE_CONFIG header %s: code=0x%02x=%s, identifier=0x%02x=%d, ")
       
   896 			 EAPL("length=0x%04x=%d, ")
       
   897 			 EAPL("type=0x%08x=%s, OP-Code=0x%02x=%s, SIMPLE_CONFIG-flags=0x%02x %s%s, SIMPLE_CONFIG-length=0x%08x=%d.\n"),
       
   898 			 prefix,
       
   899 			 (m_is_client == true) ? "client": "server",
       
   900 			 received_simple_config->get_code(),
       
   901 			 received_simple_config->get_code_string(),
       
   902 			 received_simple_config->get_identifier(),
       
   903 			 received_simple_config->get_identifier(),
       
   904 			 received_simple_config->get_length(),
       
   905 			 received_simple_config->get_length(),
       
   906 			 convert_eap_type_to_u32_t(received_simple_config->get_type()),
       
   907 			 received_simple_config->get_eap_type_string(),
       
   908 			 received_simple_config->get_sc_op_code(),
       
   909 			 received_simple_config->get_sc_op_code_string(),
       
   910 			 simple_config_flags,
       
   911 			 (simple_config_flags & eap_simple_config_header_c::m_flag_mask_simple_config_length_included) ? "L": " ",
       
   912 			 (simple_config_flags & eap_simple_config_header_c::m_flag_mask_more_fragments) ? "M": " ",
       
   913 			 simple_config_message_length,
       
   914 			 simple_config_message_length));
       
   915 	}
       
   916 	else
       
   917 	{
       
   918 		EAP_TRACE_DEBUG(
       
   919 			m_am_tools,
       
   920 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
   921 			(EAPL("%s EAP header %s: code=0x%02x=%s, identifier=0x%02x, length=0x%04x=%d, ")
       
   922 			 EAPL("type=0x%08x=%s\n"),
       
   923 			prefix,
       
   924 			(m_is_client == true) ? "client": "server",
       
   925 			eap_packet->get_code(),
       
   926 			eap_packet->get_code_string(),
       
   927 			eap_packet->get_identifier(),
       
   928 			eap_packet->get_length(),
       
   929 			eap_packet->get_length(),
       
   930 			convert_eap_type_to_u32_t(eap_packet->get_type()),
       
   931 			eap_packet->get_type_string()));
       
   932 
       
   933 		EAP_TRACE_DEBUG(
       
   934 			m_am_tools,
       
   935 			eap_am_tools_c::eap_trace_mask_eap_messages,
       
   936 			(EAPL("\n\t%s\n\tcode       = 0x%02x   = %s\n\tidentifier = 0x%02x\n\t")
       
   937 			 EAPL("length     = 0x%04x = %lu\n\ttype       = 0x%08x   = %s\n"),
       
   938 			(m_is_client == true) ? "client": "server",
       
   939 			eap_packet->get_code(),
       
   940 			eap_packet->get_code_string(),
       
   941 			eap_packet->get_identifier(),
       
   942 			eap_packet->get_length(),
       
   943 			eap_packet->get_length(),
       
   944 			convert_eap_type_to_u32_t(eap_packet->get_type()),
       
   945 			eap_packet->get_type_string()));
       
   946 	}
       
   947 
       
   948 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   949 }
       
   950 
       
   951 //--------------------------------------------------
       
   952 
       
   953 // 
       
   954 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::finish_successful_authentication()
       
   955 {
       
   956 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   957 
       
   958 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
   959 	EAP_TRACE_DEBUG(
       
   960 		m_am_tools,
       
   961 		TRACE_FLAGS_DEFAULT,
       
   962 		(EAPL("EAP_type_SIMPLE_CONFIG: %s: function: finish_successful_authentication()\n"),
       
   963 		(m_is_client == true ? "client": "server")));
       
   964 
       
   965 	eap_simple_config_trace_string_c simple_config_trace;
       
   966 	EAP_TRACE_ALWAYS(
       
   967 		m_am_tools,
       
   968 		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
   969 		(EAPL("EAP_type_SIMPLE_CONFIG: %s, EAP-type %s EAP-SUCCESS\n"),
       
   970 		 ((m_is_client == true) ? "client": "server"),
       
   971 		 eap_header_string_c::get_eap_type_string(eap_expanded_type_simple_config.get_type())));
       
   972 
       
   973 	set_state(eap_type_simple_config_state_success);
       
   974 
       
   975 	// Note, authentication is always terminated unsuccessfully.
       
   976 	// Server will send EAP-Failure always.
       
   977 	// Client should accept EAP-Failure quietly.
       
   978 	{
       
   979 		eap_state_notification_c notification(
       
   980 			m_am_tools,
       
   981 			get_send_network_id(),
       
   982 			m_is_client,
       
   983 			eap_state_notification_eap,
       
   984 			eap_protocol_layer_eap,
       
   985 			eap_expanded_type_simple_config.get_type(),
       
   986 			eap_state_none,
       
   987 			eap_state_use_eap_failure_in_termination,
       
   988 			get_last_eap_identifier(), // Note the EAP-Failure uses the same EAP-Identifier as the last EAP-Request.
       
   989 			false);
       
   990 		get_type_partner()->state_notification(&notification);
       
   991 	}
       
   992 
       
   993 	eap_state_notification_c notification(
       
   994 		m_am_tools,
       
   995 		get_send_network_id(),
       
   996 		m_is_client,
       
   997 		eap_state_notification_eap,
       
   998 		eap_protocol_layer_eap,
       
   999 		eap_expanded_type_simple_config.get_type(),
       
  1000 		eap_state_none,
       
  1001 		eap_state_authentication_finished_successfully,
       
  1002 		get_last_eap_identifier(), // Note the EAP-Success uses the same EAP-Identifier as the last EAP-Request.
       
  1003 		false);
       
  1004 	get_type_partner()->state_notification(&notification);
       
  1005 
       
  1006 	// Indicate EAP-SIMPLE_CONFIG AM authentication finished successfully.
       
  1007 	m_am_type_simple_config->authentication_finished(true, false);
       
  1008 
       
  1009 	m_authentication_finished_successfully = true;
       
  1010 
       
  1011 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1012 	return EAP_STATUS_RETURN(m_am_tools, eap_status_success);
       
  1013 }
       
  1014 
       
  1015 //--------------------------------------------------
       
  1016 
       
  1017 //
       
  1018 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::send_final_notification()
       
  1019 {
       
  1020 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1021 
       
  1022 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  1023 	EAP_TRACE_DEBUG(
       
  1024 		m_am_tools,
       
  1025 		TRACE_FLAGS_DEFAULT,
       
  1026 		(EAPL("EAP_type_SIMPLE_CONFIG: %s: function: send_final_notification()\n"),
       
  1027 		(m_is_client == true ? "client": "server")));
       
  1028 
       
  1029 	if (m_is_valid == true 
       
  1030 		&& m_authentication_finished_successfully == false)
       
  1031 	{
       
  1032 		eap_simple_config_trace_string_c simple_config_trace;
       
  1033 		EAP_TRACE_ALWAYS(
       
  1034 			m_am_tools,
       
  1035 			TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
       
  1036 			(EAPL("EAP_type_SIMPLE_CONFIG: %s, EAP-type %s FAILED\n"),
       
  1037 			 ((m_is_client == true) ? "client": "server"),
       
  1038 			 eap_header_string_c::get_eap_type_string(eap_expanded_type_simple_config.get_type())));
       
  1039 
       
  1040 		set_state(eap_type_simple_config_state_failure);
       
  1041 
       
  1042 		// Notifies the lower level of unsuccessfull authentication.
       
  1043 		eap_state_notification_c notification(
       
  1044 			m_am_tools,
       
  1045 			get_send_network_id(),
       
  1046 			m_is_client,
       
  1047 			eap_state_notification_eap,
       
  1048 			eap_protocol_layer_eap,
       
  1049 			eap_expanded_type_simple_config.get_type(),
       
  1050 			eap_state_none,
       
  1051 			eap_state_authentication_terminated_unsuccessfully,
       
  1052 			get_last_eap_identifier(),
       
  1053 			false);
       
  1054 
       
  1055 		notification.set_authentication_error(eap_status_authentication_failure);
       
  1056 
       
  1057 		get_type_partner()->state_notification(&notification);
       
  1058 
       
  1059 		// Indicate EAP-SIMPLE_CONFIG AM authentication terminated unsuccessfully.
       
  1060 		m_am_type_simple_config->authentication_finished(false, false);
       
  1061 	}
       
  1062 
       
  1063 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1064 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1065 }
       
  1066 
       
  1067 //--------------------------------------------------
       
  1068 
       
  1069 //
       
  1070 EAP_FUNC_EXPORT bool eap_type_simple_config_c::get_is_client()
       
  1071 {
       
  1072 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1073 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1074 	return m_is_client;
       
  1075 }
       
  1076 
       
  1077 //--------------------------------------------------
       
  1078 
       
  1079 //
       
  1080 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::handle_eap_identity_query(
       
  1081 	const eap_am_network_id_c * const receive_network_id,
       
  1082 	const u8_t eap_identifier,
       
  1083 	const bool use_manual_username,
       
  1084 	const eap_variable_data_c * const manual_username,
       
  1085 	const bool use_manual_realm,
       
  1086 	const eap_variable_data_c * const manual_realm
       
  1087 	)
       
  1088 {
       
  1089 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1090 
       
  1091 	eap_status_e status = eap_status_process_general_error;
       
  1092 	eap_variable_data_c local_identity(m_am_tools);
       
  1093 
       
  1094 	// Here we swap the addresses.
       
  1095 	eap_am_network_id_c send_network_id(
       
  1096 		m_am_tools,
       
  1097 		receive_network_id->get_destination_id(),
       
  1098 		receive_network_id->get_source_id(),
       
  1099 		receive_network_id->get_type());
       
  1100 
       
  1101 	if (use_manual_username == true
       
  1102 		&& manual_username != 0
       
  1103 		&& manual_username->get_is_valid() == true
       
  1104 		&& use_manual_realm == true
       
  1105 		&& manual_realm != 0
       
  1106 		&& manual_realm->get_is_valid() == true)
       
  1107 	{
       
  1108 		EAP_TRACE_DEBUG(
       
  1109 			m_am_tools,
       
  1110 			TRACE_FLAGS_DEFAULT,
       
  1111 			(EAPL("EAP_type_SIMPLE_CONFIG: %s: eap_type_simple_config_c::handle_eap_identity_query(): manual username and manual realm.\n"),
       
  1112 			(m_is_client == true ? "client": "server")));
       
  1113 
       
  1114 		// Here manual username could be zero or more bytes in length.
       
  1115 		status = local_identity.set_copy_of_buffer(manual_username);
       
  1116 		if (status != eap_status_ok)
       
  1117 		{
       
  1118 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1119 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1120 		}
       
  1121 
       
  1122 		if (manual_realm->get_data_length() > 0ul)
       
  1123 		{
       
  1124 			// When manual realm is one or more bytes in length
       
  1125 			// we add @ and manual realm to the identity.
       
  1126 			u8_t at_char = EAP_SIMPLE_CONFIG_AT_CHARACTER;
       
  1127 			status = local_identity.add_data(&at_char, sizeof(at_char));
       
  1128 			if (status != eap_status_ok)
       
  1129 			{
       
  1130 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1131 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1132 			}
       
  1133 			
       
  1134 			status = local_identity.add_data(manual_realm);
       
  1135 			if (status != eap_status_ok)
       
  1136 			{
       
  1137 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1138 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1139 			}
       
  1140 		}
       
  1141 	}
       
  1142 	else if (use_manual_username == true
       
  1143 			&& manual_username != 0
       
  1144 			&& manual_username->get_is_valid() == true
       
  1145 			&& use_manual_realm == false)
       
  1146 	{
       
  1147 		EAP_TRACE_DEBUG(
       
  1148 			m_am_tools,
       
  1149 			TRACE_FLAGS_DEFAULT,
       
  1150 			(EAPL("EAP_type_SIMPLE_CONFIG: %s: eap_type_simple_config_c::handle_eap_identity_query(): manual username.\n"),
       
  1151 			(m_is_client == true ? "client": "server")));
       
  1152 
       
  1153 		status = local_identity.set_copy_of_buffer(manual_username);
       
  1154 		if (status != eap_status_ok)
       
  1155 		{
       
  1156 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1157 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1158 		}
       
  1159 	}
       
  1160 	else
       
  1161 	{
       
  1162 		EAP_TRACE_ERROR(
       
  1163 			m_am_tools,
       
  1164 			TRACE_FLAGS_DEFAULT,
       
  1165 			(EAPL("EAP_type_SIMPLE_CONFIG: %s: eap_type_simple_config_c::handle_eap_identity_query(): no identity.\n"),
       
  1166 			(m_is_client == true ? "client": "server")));
       
  1167 
       
  1168 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1169 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity);
       
  1170 	}
       
  1171 
       
  1172 	status = get_NAI()->set_copy_of_buffer(&local_identity);
       
  1173 	if (status != eap_status_ok)
       
  1174 	{
       
  1175 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1176 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1177 	}
       
  1178 	
       
  1179 	EAP_TRACE_DATA_DEBUG(
       
  1180 		m_am_tools,
       
  1181 		TRACE_FLAGS_DEFAULT,
       
  1182 		(EAPL("eap_type_simple_config_c::handle_eap_identity_query(): identity"),
       
  1183 		local_identity.get_data(),
       
  1184 		local_identity.get_data_length()));
       
  1185 
       
  1186 
       
  1187 	status = get_type_partner()->complete_eap_identity_query(
       
  1188 		&send_network_id,
       
  1189 		&local_identity,
       
  1190 		eap_identifier);	
       
  1191 	if (status == eap_status_ok)
       
  1192 	{
       
  1193 		set_state(eap_type_simple_config_state_waiting_for_simple_config_start);
       
  1194 	}
       
  1195 	else
       
  1196 	{
       
  1197 		get_NAI()->reset();
       
  1198 		restore_saved_previous_state();
       
  1199 	}
       
  1200 	
       
  1201 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1202 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1203 }
       
  1204 
       
  1205 //--------------------------------------------------
       
  1206 
       
  1207 //
       
  1208 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::complete_eap_identity_query(
       
  1209 	const eap_am_network_id_c * const receive_network_id,
       
  1210 	const u8_t eap_identifier,
       
  1211 	const eap_status_e completion_status,
       
  1212 	const bool use_manual_username,
       
  1213 	const eap_variable_data_c * const manual_username,
       
  1214 	const bool use_manual_realm,
       
  1215 	const eap_variable_data_c * const manual_realm
       
  1216 	)
       
  1217 {
       
  1218 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1219 
       
  1220 	if (m_state == eap_type_simple_config_state_pending_identity_query)
       
  1221 	{
       
  1222 		if (completion_status != eap_status_ok)
       
  1223 		{
       
  1224 			set_state(eap_type_simple_config_state_failure);
       
  1225 
       
  1226 			// The completion_status error value is more important
       
  1227 			// than return value of set_session_timeout().
       
  1228 			get_type_partner()->set_session_timeout(0ul);
       
  1229 
       
  1230 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1231 			return EAP_STATUS_RETURN(m_am_tools, completion_status);
       
  1232 		}
       
  1233 
       
  1234 		eap_status_e status = handle_eap_identity_query(
       
  1235 			receive_network_id,
       
  1236 			eap_identifier,
       
  1237 			use_manual_username,
       
  1238 			manual_username,
       
  1239 			use_manual_realm,
       
  1240 			manual_realm);
       
  1241 
       
  1242 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1243 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1244 	}
       
  1245 	else
       
  1246 	{
       
  1247 		EAP_TRACE_ERROR(
       
  1248 			m_am_tools, 
       
  1249 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR, 
       
  1250 			(EAPL("ERROR: eap_type_simple_config_c::complete_eap_identity_query(): ")
       
  1251 			 EAPL("Illegal EAP-Identity query completion in ")
       
  1252 			 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  1253 			get_state(),
       
  1254 			get_state_string()));
       
  1255 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1256 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  1257 	}
       
  1258 }
       
  1259 
       
  1260 //--------------------------------------------------
       
  1261 
       
  1262 //
       
  1263 eap_status_e eap_type_simple_config_c::check_received_eap_identifier(
       
  1264 	const eap_header_wr_c * const eap_header)
       
  1265 {
       
  1266 	if (m_is_client == false
       
  1267 		&& eap_header->get_type() == eap_type_identity
       
  1268 		&& eap_header->get_code() == eap_code_response
       
  1269 		&& m_check_identifier_of_eap_identity_response == true
       
  1270 		&& eap_header->get_identifier() != get_last_eap_identifier())
       
  1271 	{
       
  1272 		eap_status_e status(eap_status_unexpected_message);
       
  1273 
       
  1274 		eap_status_string_c status_string;
       
  1275 		EAP_TRACE_ERROR(
       
  1276 			m_am_tools,
       
  1277 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  1278 			(EAPL("ERROR: eap_type_simple_config_c::packet_process() failed,")
       
  1279 			 EAPL("status %d=%s, received EAP-type 0x%08x, received EAP-code %d, ")
       
  1280 			 EAPL("received EAP-identifier %d, current EAP-identifier %d, state %s\n"),
       
  1281 			 status,
       
  1282 			 status_string.get_status_string(status),
       
  1283 			 convert_eap_type_to_u32_t(eap_header->get_type()),
       
  1284 			 eap_header->get_code(),
       
  1285 			 eap_header->get_identifier(),
       
  1286 			 get_last_eap_identifier(),
       
  1287 			 get_state_string()));
       
  1288 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1289 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1290 	}
       
  1291 	else if (m_is_client == false
       
  1292 			 && eap_header->get_type() == eap_expanded_type_simple_config.get_type()
       
  1293 			 && eap_header->get_identifier() != get_last_eap_identifier())
       
  1294 	{
       
  1295 		eap_status_e status(eap_status_unexpected_message);
       
  1296 
       
  1297 		eap_status_string_c status_string;
       
  1298 		EAP_TRACE_ERROR(
       
  1299 			m_am_tools,
       
  1300 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  1301 			(EAPL("ERROR: eap_type_simple_config_c::packet_process() failed,")
       
  1302 			 EAPL("status %d=%s, received EAP-identifier %d, ")
       
  1303 			 EAPL("current EAP-identifier %d, state %s\n"),
       
  1304 			 status,
       
  1305 			 status_string.get_status_string(status),
       
  1306 			 eap_header->get_identifier(),
       
  1307 			 get_last_eap_identifier(),
       
  1308 			 get_state_string()));
       
  1309 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1310 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1311 	}
       
  1312 	else if (m_is_client == true
       
  1313 		&& eap_header->get_identifier() == get_last_eap_identifier())
       
  1314 	{
       
  1315 		// Client have received this packet already.
       
  1316 		eap_status_e status(eap_status_drop_packet_quietly);
       
  1317 
       
  1318 		eap_status_string_c status_string;
       
  1319 		EAP_TRACE_ERROR(
       
  1320 			m_am_tools,
       
  1321 			TRACE_FLAGS_DEFAULT,
       
  1322 			(EAPL("WARNING: eap_type_simple_config_c::packet_process() failed,")
       
  1323 			 EAPL("status %d=%s, drops already received EAP-identifier %d, ")
       
  1324 			 EAPL("current EAP-identifier %d, state %s\n"),
       
  1325 			 status,
       
  1326 			 status_string.get_status_string(status),
       
  1327 			 eap_header->get_identifier(),
       
  1328 			 get_last_eap_identifier(),
       
  1329 			 get_state_string()));
       
  1330 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1331 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1332 	}
       
  1333 
       
  1334 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1335 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1336 }
       
  1337 
       
  1338 //--------------------------------------------------
       
  1339 
       
  1340 //
       
  1341 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::packet_process(
       
  1342 	const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet.
       
  1343 	eap_header_wr_c * const eap_header, ///< This is pointer to EAP header and data.
       
  1344 	const u32_t eap_packet_length ///< This is length of received EAP packet.
       
  1345 	)
       
  1346 {
       
  1347 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1348 
       
  1349 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  1350 	EAP_TRACE_DEBUG(
       
  1351 		m_am_tools,
       
  1352 		TRACE_FLAGS_DEFAULT,
       
  1353 		(EAPL("EAP_type_SIMPLE_CONFIG: %s: function: packet_process()\n"),
       
  1354 		(m_is_client == true ? "client": "server")));
       
  1355 
       
  1356 	packet_trace(
       
  1357 		EAPL("->"),
       
  1358 		receive_network_id,
       
  1359 		eap_header,
       
  1360 		eap_packet_length);
       
  1361 
       
  1362 	if (eap_packet_length < eap_header->get_length())
       
  1363 	{
       
  1364 		EAP_TRACE_ERROR(
       
  1365 			m_am_tools,
       
  1366 			TRACE_FLAGS_DEFAULT,
       
  1367 			(EAPL("eap_packet_length=0x%04x < eap_header->get_length()=0x%04x.\n"),
       
  1368 			eap_packet_length, eap_header->get_length()));
       
  1369 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1370 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  1371 	}
       
  1372 
       
  1373 	if (eap_header->get_length() < eap_header_base_c::get_header_length())
       
  1374 	{
       
  1375 		EAP_TRACE_ERROR(
       
  1376 			m_am_tools,
       
  1377 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  1378 			(EAPL("ERROR: eap_type_simple_config_c::packet_process(): ")
       
  1379 			 EAPL("eap_header->get_length() < eap_header_base_c::get_header_length().\n")));
       
  1380 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1381 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
       
  1382 	}
       
  1383 
       
  1384 
       
  1385 	// NOTE: by disabling these calls throughput increases about 18%.
       
  1386 	// Disabling also decreases random seeds.
       
  1387 	m_am_tools->get_crypto()->add_rand_seed(
       
  1388 		eap_header->get_header_buffer(eap_packet_length),
       
  1389 		eap_packet_length);
       
  1390 	m_am_tools->get_crypto()->add_rand_seed_hw_ticks();
       
  1391 
       
  1392 	eap_status_e status = eap_status_process_general_error;
       
  1393 
       
  1394 	if ((m_is_client == true
       
  1395 		&& eap_header->get_code() == eap_code_request)
       
  1396 		|| (m_is_client == false
       
  1397 		&& eap_header->get_code() == eap_code_response))
       
  1398 	{
       
  1399 		if (eap_header->get_type() == eap_type_identity
       
  1400 			|| eap_header->get_type() == eap_expanded_type_simple_config.get_type())
       
  1401 		{
       
  1402 			eap_simple_config_header_c simple_config_header(
       
  1403 				m_am_tools,
       
  1404 				eap_header->get_header_buffer(eap_packet_length),
       
  1405 				eap_packet_length);
       
  1406 
       
  1407 			if (eap_header->get_type() == eap_type_identity
       
  1408 				&& eap_header->get_code() == eap_code_request)
       
  1409 			{
       
  1410 				// EAP-Request/Identity is handled in eap_core_c.
       
  1411 				status = eap_status_unexpected_message;
       
  1412 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1413 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1414 			}
       
  1415 			else if (eap_header->get_type() == eap_type_identity
       
  1416 				&& eap_header->get_code() == eap_code_response
       
  1417 				&& eap_header->get_length() <= eap_header_base_c::get_header_length())
       
  1418 			{
       
  1419 				status = eap_status_header_corrupted;
       
  1420 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1421 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1422 			}
       
  1423 			else if (eap_header->get_type() == eap_expanded_type_simple_config.get_type()
       
  1424 				&& eap_header->get_length() < simple_config_header.get_simple_config_min_header_length())
       
  1425 			{
       
  1426 				status = eap_status_header_corrupted;
       
  1427 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1428 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1429 			}
       
  1430 			else if (check_received_eap_identifier(eap_header) != eap_status_ok)
       
  1431 			{
       
  1432 				status = eap_status_unexpected_message;
       
  1433 				eap_status_string_c status_string;
       
  1434 				EAP_TRACE_ERROR(
       
  1435 					m_am_tools,
       
  1436 					TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  1437 					(EAPL("ERROR: eap_type_simple_config_c::packet_process() failed,")
       
  1438 					 EAPL("status %d=%s, received EAP-type 0x%08x, received EAP-code %d, ")
       
  1439 					 EAPL("received EAP-identifier %d, current EAP-identifier %d, state %s\n"),
       
  1440 					 status,
       
  1441 					 status_string.get_status_string(status),
       
  1442 					 convert_eap_type_to_u32_t(eap_header->get_type()),
       
  1443 					 eap_header->get_code(),
       
  1444 					 eap_header->get_identifier(),
       
  1445 					 get_last_eap_identifier(),
       
  1446 					 get_state_string()));
       
  1447 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1448 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1449 			}
       
  1450 			else
       
  1451 			{
       
  1452 				if (m_is_client == true)
       
  1453 				{
       
  1454 					// Client saves the received EAP-Identifier.
       
  1455 					set_last_eap_identifier(eap_header->get_identifier());
       
  1456 				}
       
  1457 
       
  1458 				if (eap_header->get_type() == eap_type_identity)
       
  1459 				{
       
  1460 					status = eap_identity_response_packet_process(
       
  1461 						receive_network_id,
       
  1462 						eap_header,
       
  1463 						eap_packet_length);
       
  1464 
       
  1465 					if (status != eap_status_ok
       
  1466 						&& status != eap_status_success
       
  1467 						&& status != eap_status_drop_packet_quietly)
       
  1468 					{
       
  1469 						eap_status_string_c status_string;
       
  1470 
       
  1471 						EAP_TRACE_ERROR(
       
  1472 							m_am_tools,
       
  1473 							TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  1474 							(EAPL("ERROR: eap_type_simple_config_c::")
       
  1475 							 EAPL("eap_identity_response_packet_process() failed, status %d=%s\n"),
       
  1476 							 status, status_string.get_status_string(status)));
       
  1477 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1478 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  1479 					}
       
  1480 					if (status == eap_status_ok)
       
  1481 					{
       
  1482 						EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false);
       
  1483 
       
  1484 						eap_state_notification_c notification(
       
  1485 							m_am_tools,
       
  1486 							get_send_network_id(),
       
  1487 							m_is_client,
       
  1488 							eap_state_notification_eap,
       
  1489 							eap_protocol_layer_eap,
       
  1490 							eap_expanded_type_simple_config.get_type(),
       
  1491 							eap_state_none,
       
  1492 							eap_state_identity_response_received,
       
  1493 							get_last_eap_identifier(),
       
  1494 							false);
       
  1495 						get_type_partner()->state_notification(&notification);
       
  1496 					}
       
  1497 				}
       
  1498 				else
       
  1499 				{
       
  1500 					status = simple_config_packet_process(
       
  1501 						receive_network_id,
       
  1502 						&simple_config_header,
       
  1503 						eap_packet_length);
       
  1504 
       
  1505 					if (status == eap_status_ok)
       
  1506 					{
       
  1507 						EAP_GENERAL_HEADER_SET_ERROR_DETECTED(eap_header, false);
       
  1508 					}
       
  1509 
       
  1510 					if (status != eap_status_ok
       
  1511 						&& status != eap_status_success
       
  1512 						&& status != eap_status_pending_request
       
  1513 						&& status != eap_status_drop_packet_quietly)
       
  1514 					{
       
  1515 						eap_status_string_c status_string;
       
  1516 
       
  1517 						EAP_TRACE_ERROR(
       
  1518 							m_am_tools,
       
  1519 							TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  1520 							(EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process() ")
       
  1521 							 EAPL("failed, status %d=%s\n"),
       
  1522 							 status, status_string.get_status_string(status)));
       
  1523 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1524 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  1525 					}
       
  1526 				}
       
  1527 			}
       
  1528 
       
  1529 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1530 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1531 		}
       
  1532 		else if (eap_header->get_type() == eap_type_notification)
       
  1533 		{
       
  1534 			EAP_TRACE_ERROR(
       
  1535 				m_am_tools,
       
  1536 				TRACE_FLAGS_DEFAULT,
       
  1537 				(EAPL("dropped EAP type notification: code=0x%02x, identifier=0x%02x, ")
       
  1538 				 EAPL("length=0x%04x, type=0x%08x\n"),
       
  1539 				 eap_header->get_code(),
       
  1540 				 eap_header->get_identifier(),
       
  1541 				 eap_header->get_length(),
       
  1542 				 convert_eap_type_to_u32_t(eap_header->get_type())));
       
  1543 
       
  1544 			status = eap_status_illegal_eap_type;
       
  1545 
       
  1546 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1547 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1548 		}
       
  1549 		else
       
  1550 		{
       
  1551 			EAP_TRACE_ERROR(
       
  1552 				m_am_tools,
       
  1553 				TRACE_FLAGS_DEFAULT,
       
  1554 				(EAPL("dropped EAP type unknown: code=0x%02x, identifier=0x%02x, ")
       
  1555 				 EAPL("length=0x%04x, type=0x%08x\n"),
       
  1556 				 eap_header->get_code(),
       
  1557 				 eap_header->get_identifier(),
       
  1558 				 eap_header->get_length(),
       
  1559 				 convert_eap_type_to_u32_t(eap_header->get_type())));
       
  1560 
       
  1561 			status = eap_status_illegal_eap_type;
       
  1562 
       
  1563 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1564 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1565 		}
       
  1566 	}
       
  1567 	else if (eap_header->get_code() == eap_code_success
       
  1568 		|| eap_header->get_code() == eap_code_failure)
       
  1569 	{
       
  1570 		// Here we swap the addresses.
       
  1571 		eap_am_network_id_c send_network_id(m_am_tools,
       
  1572 			receive_network_id->get_destination_id(),
       
  1573 			receive_network_id->get_source_id(),
       
  1574 			receive_network_id->get_type());
       
  1575 
       
  1576 		if (eap_header->get_code() == eap_code_success)
       
  1577 		{
       
  1578 			if (get_state() == eap_type_simple_config_state_success)
       
  1579 			{
       
  1580 				EAP_TRACE_DEBUG(
       
  1581 					m_am_tools,
       
  1582 					TRACE_FLAGS_DEFAULT,
       
  1583 					(EAPL("quietly dropped EAP-Success: code=0x%02x, identifier=0x%02x, ")
       
  1584 					 EAPL("length=0x%04x, state %d=%s, is client %d\n"),
       
  1585 					 eap_header->get_code(),
       
  1586 					 eap_header->get_identifier(),
       
  1587 					 eap_header->get_length(),
       
  1588 					 get_state(),
       
  1589 					 get_state_string(),
       
  1590 					 (m_is_client == true)));
       
  1591 				status = eap_status_drop_packet_quietly;
       
  1592 			}
       
  1593 			else
       
  1594 			{
       
  1595 				EAP_TRACE_DEBUG(
       
  1596 					m_am_tools,
       
  1597 					TRACE_FLAGS_DEFAULT,
       
  1598 					(EAPL("dropped EAP-Success: code=0x%02x, identifier=0x%02x, ")
       
  1599 					 EAPL("length=0x%04x, state %d=%s, is client %d\n"),
       
  1600 					 eap_header->get_code(),
       
  1601 					 eap_header->get_identifier(),
       
  1602 					 eap_header->get_length(),
       
  1603 					 get_state(),
       
  1604 					 get_state_string(),
       
  1605 					 (m_is_client == true)));
       
  1606 				status = eap_status_illegal_eap_code;
       
  1607 			}
       
  1608 		}
       
  1609 		else if (eap_header->get_code() == eap_code_failure)
       
  1610 		{
       
  1611 			// EAP is quite sloppy protocol.
       
  1612 			// Somebody just send a EAP-failure message and authentication is terminated.
       
  1613 
       
  1614 			// Save received failure. We do not change our state yet.
       
  1615 			// The real correct EAP message could be received later if this failure was
       
  1616 			// send by nasty attacker.
       
  1617 			set_failure_message_received();
       
  1618 			// We handle the EAP-Request/Failure message after a timeout.
       
  1619 
       
  1620 			status = eap_status_ok;
       
  1621 		}
       
  1622 		else
       
  1623 		{
       
  1624 			EAP_TRACE_ERROR(
       
  1625 				m_am_tools,
       
  1626 				TRACE_FLAGS_DEFAULT,
       
  1627 				(EAPL("dropped EAP code unknown: code=0x%02x, identifier=0x%02x, ")
       
  1628 				 EAPL("length=0x%04x, is client %d\n"),
       
  1629 				 eap_header->get_code(),
       
  1630 				 eap_header->get_identifier(),
       
  1631 				 eap_header->get_length(),
       
  1632 				 (m_is_client == true)));
       
  1633 			status = eap_status_illegal_eap_code;
       
  1634 		}
       
  1635 	}
       
  1636 	else
       
  1637 	{
       
  1638 		EAP_TRACE_ERROR(
       
  1639 			m_am_tools,
       
  1640 			TRACE_FLAGS_DEFAULT,
       
  1641 			(EAPL("dropped EAP code unknown: code=0x%02x, identifier=0x%02x, ")
       
  1642 			 EAPL("length=0x%04x, is client %d\n"),
       
  1643 			 eap_header->get_code(),
       
  1644 			 eap_header->get_identifier(),
       
  1645 			 eap_header->get_length(),
       
  1646 			 (m_is_client == true)));
       
  1647 		status = eap_status_illegal_eap_code;
       
  1648 	}
       
  1649 
       
  1650 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1651 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1652 }
       
  1653 
       
  1654 //--------------------------------------------------
       
  1655 
       
  1656 //
       
  1657 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::send_sc_frag_ack()
       
  1658 {
       
  1659 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1660 
       
  1661 	eap_buf_chain_wr_c eap_fragment_acknowledge_packet(
       
  1662 		eap_write_buffer, 
       
  1663 		m_am_tools, 
       
  1664 		SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH);
       
  1665 
       
  1666 	if (eap_fragment_acknowledge_packet.get_is_valid() == false)
       
  1667 	{
       
  1668 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n")));
       
  1669 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1670 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1671 	}
       
  1672 
       
  1673 	EAP_ASSERT_ALWAYS(SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH
       
  1674 					  >= (m_simple_config_header_offset+m_trailer_length));
       
  1675 	u32_t packet_buffer_free = SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length;
       
  1676 	u32_t packet_buffer_offset = 0u;
       
  1677 
       
  1678 	if (m_simple_config_header_offset+m_MTU < packet_buffer_free)
       
  1679 	{
       
  1680 		packet_buffer_free = m_simple_config_header_offset+m_MTU;
       
  1681 	}
       
  1682 
       
  1683 	eap_simple_config_header_c fragment_acknowledge(
       
  1684 		m_am_tools,
       
  1685 		eap_fragment_acknowledge_packet.get_data_offset(
       
  1686 			m_simple_config_header_offset,
       
  1687 			(packet_buffer_free-m_simple_config_header_offset)),
       
  1688 		(packet_buffer_free-m_simple_config_header_offset));
       
  1689 
       
  1690 	if (fragment_acknowledge.get_is_valid() == false)
       
  1691 	{
       
  1692 		EAP_TRACE_ERROR(
       
  1693 			m_am_tools,
       
  1694 			TRACE_FLAGS_DEFAULT,
       
  1695 			(EAPL("packet_send: packet buffer corrupted.\n")));
       
  1696 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  1697 	}
       
  1698 
       
  1699 	fragment_acknowledge.reset_header(
       
  1700 		m_am_tools,
       
  1701 		static_cast<u16_t>(packet_buffer_free-m_simple_config_header_offset),
       
  1702 		true);
       
  1703 
       
  1704 	fragment_acknowledge.set_eap_length(
       
  1705 		static_cast<u16_t>(packet_buffer_free-m_simple_config_header_offset),
       
  1706 		true);
       
  1707 
       
  1708 	if (m_is_client == true)
       
  1709 	{
       
  1710 		fragment_acknowledge.set_eap_code(eap_code_response);
       
  1711 		fragment_acknowledge.set_eap_identifier(static_cast<u8_t>(get_last_eap_identifier()));
       
  1712 	}
       
  1713 	else // if (m_is_client == false)
       
  1714 	{
       
  1715 		fragment_acknowledge.set_eap_code(eap_code_request);
       
  1716 		fragment_acknowledge.set_eap_identifier(static_cast<u8_t>(get_last_eap_identifier()+1u));
       
  1717 	}
       
  1718 
       
  1719 	fragment_acknowledge.set_eap_type(
       
  1720 		eap_expanded_type_simple_config.get_type(),
       
  1721 		true);
       
  1722 
       
  1723 	fragment_acknowledge.set_sc_op_code(eap_simple_config_header_c::op_code_FRAG_ACK);
       
  1724 
       
  1725 	u32_t simple_config_data_offset = 0u;
       
  1726 
       
  1727 	update_buffer_indexes(
       
  1728 		SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH,
       
  1729 		m_simple_config_header_offset+fragment_acknowledge.get_header_length(),
       
  1730 		&packet_buffer_offset,
       
  1731 		&packet_buffer_free);
       
  1732 
       
  1733 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1734 
       
  1735 	// No payloads.
       
  1736 
       
  1737 	fragment_acknowledge.set_data_length(
       
  1738 		simple_config_data_offset,
       
  1739 		true);
       
  1740 	eap_fragment_acknowledge_packet.set_data_length(packet_buffer_offset);
       
  1741 
       
  1742 	EAP_ASSERT_ALWAYS(
       
  1743 		m_simple_config_header_offset
       
  1744 		+fragment_acknowledge.get_header_length()
       
  1745 		+fragment_acknowledge.get_data_length()
       
  1746 		== packet_buffer_offset);
       
  1747 
       
  1748 	eap_status_e status = eap_status_process_general_error;
       
  1749 
       
  1750 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1751 
       
  1752 	if (m_is_client == true)
       
  1753 	{
       
  1754 		EAP_TRACE_DATA_DEBUG(
       
  1755 			m_am_tools,
       
  1756 			TRACE_FLAGS_DEFAULT,
       
  1757 			(EAPL("    send: EAP-Response/SIMPLE_CONFIG/Acknowledge packet"),
       
  1758 			fragment_acknowledge.get_header_buffer(fragment_acknowledge.get_eap_length()),
       
  1759 			fragment_acknowledge.get_eap_length()));
       
  1760 	}
       
  1761 	else // if (m_is_client == false)
       
  1762 	{
       
  1763 		EAP_TRACE_DATA_DEBUG(
       
  1764 			m_am_tools,
       
  1765 			TRACE_FLAGS_DEFAULT,
       
  1766 			(EAPL("    send: EAP-Request/SIMPLE_CONFIG/Acknowledge packet"),
       
  1767 			fragment_acknowledge.get_header_buffer(fragment_acknowledge.get_eap_length()),
       
  1768 			fragment_acknowledge.get_eap_length()));
       
  1769 	}
       
  1770 
       
  1771 	status = packet_send(
       
  1772 		get_send_network_id(),
       
  1773 		&eap_fragment_acknowledge_packet,
       
  1774 		m_simple_config_header_offset,
       
  1775 		fragment_acknowledge.get_eap_length(),
       
  1776 		SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH
       
  1777 		);
       
  1778 
       
  1779 	if (status == eap_status_ok)
       
  1780 	{
       
  1781 		if (m_is_client == false)
       
  1782 		{
       
  1783 			// Server saves the sent EAP-Identifier.
       
  1784 			set_last_eap_identifier(static_cast<u8_t>(get_last_eap_identifier()+1ul));
       
  1785 		}
       
  1786 	}
       
  1787 
       
  1788 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1789 
       
  1790 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1791 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1792 }
       
  1793 
       
  1794 //--------------------------------------------------
       
  1795 
       
  1796 //
       
  1797 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::send_simple_config_start_message(
       
  1798 	const u8_t next_eap_identifier ///< This is EAP-Identifier of next EAP packet.
       
  1799 	)
       
  1800 {
       
  1801 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1802 
       
  1803 	eap_buf_chain_wr_c eap_simple_config_start_packet(
       
  1804 		eap_write_buffer, 
       
  1805 		m_am_tools, 
       
  1806 		SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH);
       
  1807 
       
  1808 	if (eap_simple_config_start_packet.get_is_valid() == false)
       
  1809 	{
       
  1810 		EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n")));
       
  1811 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1812 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1813 	}
       
  1814 
       
  1815 	EAP_ASSERT_ALWAYS(SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH
       
  1816 					  >= (m_simple_config_header_offset+m_trailer_length));
       
  1817 	u32_t packet_buffer_free = SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length;
       
  1818 	u32_t packet_buffer_offset = 0u;
       
  1819 
       
  1820 	if (m_simple_config_header_offset+m_MTU < packet_buffer_free)
       
  1821 	{
       
  1822 		packet_buffer_free = m_simple_config_header_offset+m_MTU;
       
  1823 	}
       
  1824 
       
  1825 	eap_simple_config_header_c simple_config_start_packet(
       
  1826 		m_am_tools,
       
  1827 		eap_simple_config_start_packet.get_data_offset(
       
  1828 			m_simple_config_header_offset,
       
  1829 			(packet_buffer_free-m_simple_config_header_offset)),
       
  1830 		(packet_buffer_free-m_simple_config_header_offset));
       
  1831 
       
  1832 	if (simple_config_start_packet.get_is_valid() == false)
       
  1833 	{
       
  1834 		EAP_TRACE_ERROR(
       
  1835 			m_am_tools,
       
  1836 			TRACE_FLAGS_DEFAULT,
       
  1837 			(EAPL("packet_send: packet buffer corrupted.\n")));
       
  1838 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  1839 	}
       
  1840 
       
  1841 	simple_config_start_packet.reset_header(
       
  1842 		m_am_tools,
       
  1843 		static_cast<u16_t>(packet_buffer_free-m_simple_config_header_offset),
       
  1844 		true);
       
  1845 
       
  1846 	simple_config_start_packet.set_flag_simple_config_length_included(false);
       
  1847 
       
  1848 	simple_config_start_packet.set_eap_length(
       
  1849 		static_cast<u16_t>(
       
  1850 			packet_buffer_free-m_simple_config_header_offset),
       
  1851 		true);
       
  1852 
       
  1853 	simple_config_start_packet.set_eap_code(eap_code_request);
       
  1854 	simple_config_start_packet.set_eap_identifier(next_eap_identifier);
       
  1855 	simple_config_start_packet.set_eap_type(
       
  1856 		eap_expanded_type_simple_config.get_type(),
       
  1857 		true);
       
  1858 	simple_config_start_packet.set_sc_op_code(eap_simple_config_header_c::op_code_WSC_Start);
       
  1859 
       
  1860 	update_buffer_indexes(
       
  1861 		SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH,
       
  1862 		m_simple_config_header_offset+simple_config_start_packet.get_header_length(),
       
  1863 		&packet_buffer_offset,
       
  1864 		&packet_buffer_free);
       
  1865 
       
  1866 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1867 
       
  1868 	simple_config_start_packet.set_data_length(
       
  1869 		0ul,
       
  1870 		true);
       
  1871 	eap_simple_config_start_packet.set_data_length(packet_buffer_offset);
       
  1872 
       
  1873 	EAP_ASSERT_ALWAYS(
       
  1874 		m_simple_config_header_offset+simple_config_start_packet.get_header_length()
       
  1875 		+simple_config_start_packet.get_data_length()
       
  1876 		== packet_buffer_offset);
       
  1877 
       
  1878 	eap_status_e status = eap_status_process_general_error;
       
  1879 
       
  1880 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1881 
       
  1882 	EAP_TRACE_DATA_DEBUG(
       
  1883 		m_am_tools,
       
  1884 		TRACE_FLAGS_DEFAULT,
       
  1885 		(EAPL("    send: EAP-Request/SIMPLE_CONFIG/Start packet"),
       
  1886 		simple_config_start_packet.get_header_buffer(simple_config_start_packet.get_eap_length()),
       
  1887 		simple_config_start_packet.get_eap_length()));
       
  1888 
       
  1889 	status = packet_send(
       
  1890 		get_send_network_id(),
       
  1891 		&eap_simple_config_start_packet,
       
  1892 		m_simple_config_header_offset,
       
  1893 		simple_config_start_packet.get_eap_length(),
       
  1894 		SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH
       
  1895 		);
       
  1896 
       
  1897 	if (status == eap_status_ok)
       
  1898 	{
       
  1899 		if (m_is_client == false)
       
  1900 		{
       
  1901 			// Server saves the sent EAP-Identifier.
       
  1902 			set_last_eap_identifier(next_eap_identifier);
       
  1903 
       
  1904 			set_state(eap_type_simple_config_state_waiting_for_response);
       
  1905 		}
       
  1906 	}
       
  1907 
       
  1908 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  1909 
       
  1910 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1911 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1912 }
       
  1913 
       
  1914 //--------------------------------------------------
       
  1915 
       
  1916 //
       
  1917 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::start_simple_config_authentication(
       
  1918 	const eap_am_network_id_c * const /*receive_network_id*/, ///< This is the network identity of the received EAP packet.
       
  1919 	const eap_variable_data_c * const NAI ///< This is the full NAI of the client.
       
  1920 	)
       
  1921 {
       
  1922 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1923 
       
  1924 	eap_status_e status = m_simple_config_record->start_simple_config_authentication(NAI);
       
  1925 
       
  1926 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1927 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1928 }
       
  1929 
       
  1930 //--------------------------------------------------
       
  1931 
       
  1932 //
       
  1933 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::eap_simple_config_fragment_send()
       
  1934 {
       
  1935 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1936 
       
  1937 	eap_status_e status = eap_status_not_supported;
       
  1938 
       
  1939 	if (m_simple_config_message_send_offset == 0ul
       
  1940 		&& m_simple_config_message_buffer.get_data_length()
       
  1941 		< simple_config_tlv_header_c::get_header_length())
       
  1942 	{
       
  1943 		EAP_TRACE_ERROR(
       
  1944 			m_am_tools,
       
  1945 			TRACE_FLAGS_DEFAULT,
       
  1946 			(EAPL("eap_simple_config_fragment_send(): ")
       
  1947 			 EAPL("packet buffer too short, %d bytes.\n"),
       
  1948 			m_simple_config_message_buffer.get_data_length()));
       
  1949 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1950 	}
       
  1951 	else if (m_simple_config_message_buffer.get_data_length()
       
  1952 			 < m_simple_config_message_send_offset)
       
  1953 	{
       
  1954 		EAP_TRACE_ERROR(
       
  1955 			m_am_tools,
       
  1956 			TRACE_FLAGS_DEFAULT,
       
  1957 			(EAPL("eap_simple_config_fragment_send(): ")
       
  1958 			 EAPL("packet buffer %d shorter than ")
       
  1959 			 EAPL("m_simple_config_message_send_offset %d.\n"),
       
  1960 			 m_simple_config_message_buffer.get_data_length(),
       
  1961 			 m_simple_config_message_send_offset));
       
  1962 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  1963 	}
       
  1964 
       
  1965 
       
  1966 	eap_buf_chain_wr_c eap_simple_config_fragment(
       
  1967 		eap_write_buffer, 
       
  1968 		m_am_tools, 
       
  1969 		EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH);
       
  1970 
       
  1971 	if (eap_simple_config_fragment.get_is_valid() == false)
       
  1972 	{
       
  1973 		EAP_TRACE_ERROR(
       
  1974 			m_am_tools,
       
  1975 			TRACE_FLAGS_DEFAULT,
       
  1976 			(EAPL("packet buffer corrupted.\n")));
       
  1977 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1978 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1979 	}
       
  1980 
       
  1981 	EAP_ASSERT_ALWAYS(EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH
       
  1982 					  >= (m_simple_config_header_offset+m_trailer_length));
       
  1983 	u32_t packet_buffer_free
       
  1984 		= EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length;
       
  1985 	u32_t packet_buffer_offset = 0u;
       
  1986 
       
  1987 	if (m_simple_config_header_offset+m_MTU < packet_buffer_free)
       
  1988 	{
       
  1989 		packet_buffer_free = m_simple_config_header_offset+m_MTU;
       
  1990 	}
       
  1991 
       
  1992 	u32_t packet_eap_data_free
       
  1993 		= packet_buffer_free
       
  1994 		- m_simple_config_header_offset
       
  1995 		- eap_simple_config_header_c::get_simple_config_max_header_length();
       
  1996 
       
  1997 	eap_simple_config_header_c eap_simple_config_packet(
       
  1998 		m_am_tools,
       
  1999 		eap_simple_config_fragment.get_data_offset(
       
  2000 			m_simple_config_header_offset,
       
  2001 			packet_eap_data_free),
       
  2002 		packet_eap_data_free);
       
  2003 
       
  2004 	if (eap_simple_config_packet.get_is_valid() == false)
       
  2005 	{
       
  2006 		EAP_TRACE_ERROR(
       
  2007 			m_am_tools,
       
  2008 			TRACE_FLAGS_DEFAULT,
       
  2009 			(EAPL("packet_send: packet buffer corrupted.\n")));
       
  2010 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  2011 	}
       
  2012 
       
  2013 	eap_simple_config_packet.reset_header(
       
  2014 		m_am_tools,
       
  2015 		static_cast<u16_t>(packet_eap_data_free),
       
  2016 		true);
       
  2017 	if (m_simple_config_message_send_offset == 0)
       
  2018 	{
       
  2019 		// This is the first fragment.
       
  2020 		eap_simple_config_packet.set_flag_simple_config_length_included(true);
       
  2021 		eap_simple_config_packet.set_simple_config_message_length(
       
  2022 			m_simple_config_message_buffer.get_data_length());
       
  2023 	}
       
  2024 
       
  2025 	eap_simple_config_packet.set_eap_length(
       
  2026 		static_cast<u16_t>(packet_eap_data_free),
       
  2027 		true);
       
  2028 
       
  2029 	if (m_is_client == true)
       
  2030 	{
       
  2031 		eap_simple_config_packet.set_eap_code(eap_code_response);
       
  2032 		eap_simple_config_packet.set_eap_identifier(get_last_eap_identifier());
       
  2033 	}
       
  2034 	else
       
  2035 	{
       
  2036 		eap_simple_config_packet.set_eap_code(eap_code_request);
       
  2037 		eap_simple_config_packet.set_eap_identifier(
       
  2038 			static_cast<u8_t>(get_last_eap_identifier()+1ul));
       
  2039 	}
       
  2040 	
       
  2041 	// --------------------------------------------------------------------
       
  2042 	
       
  2043 	eap_simple_config_trace_string_c message_string;
       
  2044 	  
       
  2045     EAP_TRACE_DEBUG(
       
  2046         m_am_tools,
       
  2047         TRACE_FLAGS_DEFAULT,
       
  2048         (EAPL("eap_simple_config_fragment_send: %s: message type: %s\n"),
       
  2049         (m_is_client == true ? "client": "server"),
       
  2050         message_string.get_message_type_string(m_simple_config_message_type)));
       
  2051     
       
  2052     EAP_UNREFERENCED_PARAMETER(message_string); // for release
       
  2053 	
       
  2054 	// Set Op-Code based on the message type
       
  2055 	if( m_simple_config_message_type == simple_config_Message_Type_None 
       
  2056 	        || m_simple_config_message_type == simple_config_Message_Type_Beacon
       
  2057 	        || m_simple_config_message_type == simple_config_Message_Type_Probe_Request
       
  2058 	        || m_simple_config_message_type == simple_config_Message_Type_Probe_Response
       
  2059 	        || m_simple_config_message_type > simple_config_Message_keep_this_last )
       
  2060     {
       
  2061         // Something is wrong
       
  2062         EAP_TRACE_ERROR(
       
  2063             m_am_tools,
       
  2064             TRACE_FLAGS_DEFAULT,
       
  2065             (EAPL("eap_simple_config_fragment_send: invalid message type, cannot set Op-Code correctly.\n")));
       
  2066         return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  2067     }
       
  2068 	else if( m_simple_config_message_type == simple_config_Message_Type_WSC_ACK )
       
  2069 	{
       
  2070 	    eap_simple_config_packet.set_sc_op_code(eap_simple_config_header_c::op_code_WSC_ACK);
       
  2071 	}  
       
  2072 	else if( m_simple_config_message_type == simple_config_Message_Type_WSC_NACK )
       
  2073 	{
       
  2074 	    eap_simple_config_packet.set_sc_op_code(eap_simple_config_header_c::op_code_WSC_NACK);
       
  2075 	}
       
  2076     else if( m_simple_config_message_type == simple_config_Message_Type_WSC_DONE )
       
  2077     {
       
  2078         eap_simple_config_packet.set_sc_op_code(eap_simple_config_header_c::op_code_WSC_Done);  
       
  2079     }
       
  2080 	else 
       
  2081 	{
       
  2082 	    // In other cases this is a WSC message
       
  2083 	    eap_simple_config_packet.set_sc_op_code(eap_simple_config_header_c::op_code_WSC_MSG);
       
  2084 	}
       
  2085 	
       
  2086 	// --------------------------------------------------------------------
       
  2087 	
       
  2088 	eap_simple_config_packet.set_eap_type(
       
  2089 		eap_expanded_type_simple_config.get_type(),
       
  2090 		true);
       
  2091 
       
  2092 
       
  2093 	u32_t fragment_length
       
  2094 		= m_MTU
       
  2095 		- eap_simple_config_header_c::get_simple_config_max_header_length();
       
  2096 	u32_t pending_message_length
       
  2097 		= m_simple_config_message_buffer.get_data_length()
       
  2098 		- m_simple_config_message_send_offset;
       
  2099 
       
  2100 	EAP_TRACE_DEBUG(
       
  2101 		m_am_tools,
       
  2102 		TRACE_FLAGS_DEFAULT,
       
  2103 		(EAPL("EAP-SIMPLE_CONFIG fragment: packet_eap_data_free %d, ")
       
  2104 		 EAPL("fragment_length %d, pending_message_length %d, ")
       
  2105 		 EAPL("EAP-header length %d, buffer length %d\n"),
       
  2106 		 packet_eap_data_free,
       
  2107 		 fragment_length,
       
  2108 		 pending_message_length,
       
  2109 		 eap_simple_config_packet.get_header_length(),
       
  2110 		 eap_simple_config_fragment.get_buffer_length()));
       
  2111 
       
  2112 	if (packet_eap_data_free >= pending_message_length)
       
  2113 	{
       
  2114 		// Message data is less than the buffer length,
       
  2115 		// so the fragment is only length of the message data.
       
  2116 		fragment_length = pending_message_length;
       
  2117 
       
  2118 		// SIMPLE_CONFIG-message length is not included,
       
  2119 		// because no fragmentation is used.
       
  2120 		eap_simple_config_packet.set_flag_simple_config_length_included(false);
       
  2121 
       
  2122 		EAP_TRACE_DEBUG(
       
  2123 			m_am_tools,
       
  2124 			TRACE_FLAGS_DEFAULT,
       
  2125 			(EAPL("EAP-SIMPLE_CONFIG fragment: packet_eap_data_free %d, ")
       
  2126 			 EAPL("fragment_length %d, pending_message_length %d, ")
       
  2127 			 EAPL("EAP-header length %d\n"),
       
  2128 			 packet_eap_data_free,
       
  2129 			 fragment_length,
       
  2130 			 pending_message_length,
       
  2131 			 eap_simple_config_packet.get_header_length()));
       
  2132 	}
       
  2133 
       
  2134 	if (fragment_length < pending_message_length)
       
  2135 	{
       
  2136 		EAP_TRACE_DEBUG(
       
  2137 			m_am_tools,
       
  2138 			TRACE_FLAGS_DEFAULT,
       
  2139 			(EAPL("EAP-SIMPLE_CONFIG fragment: more fragments follow. ")
       
  2140 			 EAPL("fragment_length %d, pending_message_length %d, ")
       
  2141 			 EAPL("EAP-header length %d\n"),
       
  2142 			 fragment_length,
       
  2143 			 pending_message_length,
       
  2144 			 eap_simple_config_packet.get_header_length()));
       
  2145 
       
  2146 		if (m_simple_config_message_send_offset == 0)
       
  2147 		{
       
  2148 			// SIMPLE_CONFIG-message length is included,
       
  2149 			eap_simple_config_packet.set_flag_simple_config_length_included(true);
       
  2150 		}
       
  2151 
       
  2152 		eap_simple_config_packet.set_flag_more_fragments(true);
       
  2153 	}
       
  2154 
       
  2155 
       
  2156 	update_buffer_indexes(
       
  2157 		SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH,
       
  2158 		m_simple_config_header_offset+eap_simple_config_packet.get_header_length(),
       
  2159 		&packet_buffer_offset,
       
  2160 		&packet_buffer_free);
       
  2161 
       
  2162 	status = eap_simple_config_fragment.set_data_length(packet_buffer_offset);
       
  2163 	if (status != eap_status_ok)
       
  2164 	{
       
  2165 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2166 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2167 	}
       
  2168 
       
  2169 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  2170 	// Payload is SIMPLE_CONFIG-message fragment.
       
  2171 
       
  2172 	status = eap_simple_config_fragment.add_data_to_offset(
       
  2173 		packet_buffer_offset,
       
  2174 		m_simple_config_message_buffer.get_data_offset(
       
  2175 			m_simple_config_message_send_offset, fragment_length),
       
  2176 		fragment_length);
       
  2177 	if (status != eap_status_ok)
       
  2178 	{
       
  2179 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2180 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2181 	}
       
  2182 
       
  2183 	update_buffer_indexes(
       
  2184 		SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH,
       
  2185 		fragment_length,
       
  2186 		&packet_buffer_offset,
       
  2187 		&packet_buffer_free);
       
  2188 
       
  2189 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  2190 
       
  2191 	eap_simple_config_packet.set_data_length(
       
  2192 		fragment_length,
       
  2193 		true);
       
  2194 
       
  2195 	status = eap_simple_config_fragment.set_data_length(packet_buffer_offset);
       
  2196 	if (status != eap_status_ok)
       
  2197 	{
       
  2198 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2199 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2200 	}
       
  2201 
       
  2202 	EAP_TRACE_DEBUG(
       
  2203 		m_am_tools,
       
  2204 		TRACE_FLAGS_DEFAULT,
       
  2205 		(EAPL("eap_simple_config_fragment_send(): m_simple_config_header_offset %d ")
       
  2206 		 EAPL("+ eap_simple_config_packet.get_header_length()")
       
  2207 		 EAPL("%d + eap_simple_config_packet.get_data_length() ")
       
  2208 		 EAPL("%d = %d == packet_buffer_offset %d.\n"),
       
  2209 		 m_simple_config_header_offset,
       
  2210 		 eap_simple_config_packet.get_header_length(),
       
  2211 		 eap_simple_config_packet.get_data_length(),
       
  2212 		 (m_simple_config_header_offset
       
  2213 		  + eap_simple_config_packet.get_header_length()
       
  2214 		  + eap_simple_config_packet.get_data_length()),
       
  2215 		 packet_buffer_offset));
       
  2216 
       
  2217 	EAP_ASSERT_ALWAYS(
       
  2218 		m_simple_config_header_offset
       
  2219 		+eap_simple_config_packet.get_header_length()
       
  2220 		+eap_simple_config_packet.get_data_length()
       
  2221 		== packet_buffer_offset);
       
  2222 
       
  2223 	status = eap_status_process_general_error;
       
  2224 
       
  2225 	// - - - - - - - - - - - - - - - - - - - - - - - -
       
  2226 
       
  2227 	status = packet_send(
       
  2228 		get_send_network_id(),
       
  2229 		&eap_simple_config_fragment,
       
  2230 		m_simple_config_header_offset,
       
  2231 		eap_simple_config_packet.get_eap_length(),
       
  2232 		SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH
       
  2233 		);
       
  2234 
       
  2235 	if (status == eap_status_ok)
       
  2236 	{
       
  2237 		m_simple_config_message_send_offset += fragment_length;
       
  2238 
       
  2239 		if (m_is_client == false)
       
  2240 		{
       
  2241 			// Server saves the sent EAP-Identifier.
       
  2242 			set_last_eap_identifier(
       
  2243 				static_cast<u8_t>(get_last_eap_identifier()+1ul));
       
  2244 		}
       
  2245 	}
       
  2246 
       
  2247 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2248 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2249 }
       
  2250 
       
  2251 //--------------------------------------------------
       
  2252 
       
  2253 //
       
  2254 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::simple_config_message_process(
       
  2255 	const eap_am_network_id_c * const /*receive_network_id*/, ///< This is the network identity of the received EAP packet.
       
  2256 	eap_simple_config_header_c * const received_simple_config, ///< This is pointer to EAP header including EAP-SIMPLE_CONFIG fields.
       
  2257 	const u32_t /*simple_config_packet_length*/ ///< This is length of received EAP-SIMPLE_CONFIG packet.
       
  2258 	)
       
  2259 {
       
  2260 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2261 
       
  2262 	if (m_simple_config_message_buffer.get_is_valid_data() == false)
       
  2263 	{
       
  2264 		EAP_TRACE_ERROR(
       
  2265 			m_am_tools,
       
  2266 			TRACE_FLAGS_DEFAULT,
       
  2267 			(EAPL("simple_config_message_process: packet buffer invalid.\n")));
       
  2268 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2269 	}
       
  2270 
       
  2271 	if (m_simple_config_message_buffer.get_data_length()
       
  2272 		< simple_config_tlv_header_c::get_header_length())
       
  2273 	{
       
  2274 		EAP_TRACE_ERROR(
       
  2275 			m_am_tools,
       
  2276 			TRACE_FLAGS_DEFAULT,
       
  2277 			(EAPL("simple_config_message_process: packet buffer too short, %d bytes.\n"),
       
  2278 			m_simple_config_message_buffer.get_data_length()));
       
  2279 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2280 	}
       
  2281 
       
  2282 	save_current_state();
       
  2283 	set_state(eap_type_simple_config_state_process_simple_config_message);
       
  2284 
       
  2285 	eap_status_e status = m_simple_config_record->packet_process(
       
  2286 		&m_simple_config_message_buffer,
       
  2287 		received_simple_config->get_eap_identifier());
       
  2288 
       
  2289 	if (status == eap_status_ok)
       
  2290 	{
       
  2291 		// Do nothing.
       
  2292 	}
       
  2293 	else if (status == eap_status_pending_request)
       
  2294 	{
       
  2295 		// Asyncronous operation is pending.
       
  2296 		// Do nothing.
       
  2297 	}
       
  2298 	else if (status == eap_status_success)
       
  2299 	{
       
  2300 		// Authentication OK.
       
  2301 		// Do nothing.
       
  2302 	}
       
  2303 	else if (status == eap_status_drop_packet_quietly)
       
  2304 	{
       
  2305 		// Dropped packet.
       
  2306 		// Do nothing.
       
  2307 	}
       
  2308 	else
       
  2309 	{
       
  2310 		// All other return values are ERROR. Authentication is failed.
       
  2311 
       
  2312 		EAP_TRACE_ERROR(
       
  2313 			m_am_tools,
       
  2314 			TRACE_FLAGS_DEFAULT,
       
  2315 			(EAPL("%s: simple_config_message_process: Authentication failed.\n"),
       
  2316 			(m_is_client == true) ? "client": "server"));
       
  2317 
       
  2318 		restore_saved_previous_state();
       
  2319 		set_state(eap_type_simple_config_state_failure);
       
  2320 	}
       
  2321 
       
  2322 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2323 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2324 }
       
  2325 
       
  2326 //--------------------------------------------------
       
  2327 
       
  2328 //
       
  2329 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::eap_identity_response_packet_process(
       
  2330 	const eap_am_network_id_c * const /*receive_network_id*/, ///< This is the network identity of the received EAP packet.
       
  2331 	eap_header_wr_c * const eap_header, ///< This is pointer to EAP header and data.
       
  2332 	const u32_t eap_packet_length ///< This is length of received EAP packet.
       
  2333 	)
       
  2334 {
       
  2335 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2336 
       
  2337 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  2338 	EAP_TRACE_DEBUG(
       
  2339 		m_am_tools,
       
  2340 		TRACE_FLAGS_DEFAULT,
       
  2341 		(EAPL("EAP_type_SIMPLE_CONFIG: %s: function: eap_identity_response_packet_process()\n"),
       
  2342 		(m_is_client == true ? "client": "server")));
       
  2343 
       
  2344 	if (eap_header->check_header() != eap_status_ok)
       
  2345 	{
       
  2346 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2347 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2348 	}
       
  2349 	else if (eap_header->get_length() > eap_packet_length)
       
  2350 	{
       
  2351 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2352 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2353 	}
       
  2354 
       
  2355 
       
  2356 	if (m_check_identifier_of_eap_identity_response == true)
       
  2357 	{
       
  2358 		if (m_state == eap_type_simple_config_state_waiting_for_identity_response
       
  2359 			&& eap_header->get_identifier() != get_last_eap_identifier())
       
  2360 		{
       
  2361 			// Wrong EAP-Identifier in this state.
       
  2362 			EAP_TRACE_ERROR(
       
  2363 				m_am_tools,
       
  2364 				TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  2365 				(EAPL("ERROR: eap_type_simple_config_c::handle_identity_response_message(): ")
       
  2366 				 EAPL("EAP-Identifier 0x%02x is wrong (0x%02x is correct) in ")
       
  2367 				 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  2368 				 eap_header->get_identifier(),
       
  2369 				 get_last_eap_identifier(),
       
  2370 				 get_state(),
       
  2371 				 get_state_string()));
       
  2372 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2373 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity);
       
  2374 		}
       
  2375 		else if (m_simple_config_test_version == true
       
  2376 			&& m_state == eap_type_simple_config_state_success) // This one is for testing purposes.
       
  2377 		{
       
  2378 			// NOTE here we can not check the EAP-identifier.
       
  2379 			EAP_TRACE_DEBUG(
       
  2380 				m_am_tools,
       
  2381 				TRACE_FLAGS_DEFAULT,
       
  2382 				(EAPL("WARNING: eap_type_simple_config_c::handle_identity_response_message(): ")
       
  2383 				 EAPL("EAP-Identifier 0x%02x is not checked in ")
       
  2384 				 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  2385 				 eap_header->get_identifier(),
       
  2386 				 get_state(),
       
  2387 				 get_state_string()));
       
  2388 		}
       
  2389 	}
       
  2390 
       
  2391 
       
  2392 	if (m_state == eap_type_simple_config_state_waiting_for_identity_response
       
  2393 		|| (m_simple_config_test_version == true
       
  2394 			// In test version new authentication could start from this state.
       
  2395 			&& m_state == eap_type_simple_config_state_success))
       
  2396 	{
       
  2397 		// EAP-Response/Identity is accepted only as a very first message.
       
  2398 
       
  2399 		eap_status_e status = eap_status_process_general_error;
       
  2400 
       
  2401 		save_current_state();
       
  2402 
       
  2403 		// In test version new authentication could start from this state.
       
  2404 		if (m_simple_config_test_version == true
       
  2405 			&& m_state == eap_type_simple_config_state_success) // This one is for testing purposes.
       
  2406 		{
       
  2407 			// NOTE here we can not check the EAP-identifier.
       
  2408 			set_state(eap_type_simple_config_state_waiting_for_identity_response);
       
  2409 		}
       
  2410 
       
  2411 		u8_t next_eap_identifier = static_cast<u8_t>(eap_header->get_identifier()+1u);
       
  2412 
       
  2413 		status = parse_identity(
       
  2414 			eap_header->get_type_data(
       
  2415 				eap_header->get_type_data_length()),
       
  2416 			eap_header->get_type_data_length());
       
  2417 		if (status != eap_status_ok)
       
  2418 		{
       
  2419 			restore_saved_previous_state();
       
  2420 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2421 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2422 		}
       
  2423 
       
  2424 		status = send_simple_config_start_message(next_eap_identifier);
       
  2425 		if (status != eap_status_ok)
       
  2426 		{
       
  2427 			restore_saved_previous_state();
       
  2428 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2429 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2430 		}
       
  2431 
       
  2432 		set_last_eap_identifier(next_eap_identifier);
       
  2433 		set_state(eap_type_simple_config_state_waiting_for_response);
       
  2434 
       
  2435 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2436 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2437 	}
       
  2438 	else
       
  2439 	{
       
  2440 		EAP_TRACE_ERROR(
       
  2441 			m_am_tools,
       
  2442 			TRACE_FLAGS_DEFAULT,
       
  2443 			(EAPL("ERROR: eap_type_simple_config_c::handle_identity_response_message(): ")
       
  2444 			 EAPL("EAP-Identifier 0x%02x in eap_type_simple_config_state_variable_e %d=%s. ")
       
  2445 			 EAPL("EAP-Response/Identity is accepted only in ")
       
  2446 			 EAPL("eap_type_simple_config_state_waiting_for_identity_response.\n"),
       
  2447 			 eap_header->get_identifier(),
       
  2448 			 get_state(),
       
  2449 			 get_state_string()));
       
  2450 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2451 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  2452 	}
       
  2453 }
       
  2454 
       
  2455 //--------------------------------------------------
       
  2456 
       
  2457 //
       
  2458 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::simple_config_packet_process(
       
  2459 	const eap_am_network_id_c * const receive_network_id, ///< This is the network identity of the received EAP packet.
       
  2460 	eap_simple_config_header_c * const received_simple_config, ///< This is pointer to EAP header including EAP-SIMPLE_CONFIG fields.
       
  2461 	const u32_t simple_config_packet_length ///< This is length of received EAP-SIMPLE_CONFIG packet.
       
  2462 	)
       
  2463 {
       
  2464 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2465 
       
  2466 	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
       
  2467 	EAP_TRACE_DEBUG(
       
  2468 		m_am_tools,
       
  2469 		TRACE_FLAGS_DEFAULT,
       
  2470 		(EAPL("EAP_type_SIMPLE_CONFIG: %s: function: simple_config_packet_process()\n"),
       
  2471 		(m_is_client == true ? "client": "server")));
       
  2472 
       
  2473 	if (m_simple_config_test_version == true
       
  2474 		&& get_state() == eap_type_simple_config_state_failure)
       
  2475 	{
       
  2476 		// This is for testing.
       
  2477 		if (m_is_client == false
       
  2478 			&& received_simple_config->get_eap_code() == eap_code_response
       
  2479 			&& received_simple_config->get_eap_type() == eap_type_identity)
       
  2480 		{
       
  2481 			set_state(eap_type_simple_config_state_waiting_for_identity_response);
       
  2482 		}
       
  2483 		else if (m_is_client == true
       
  2484 			&& received_simple_config->get_sc_op_code() == eap_simple_config_header_c::op_code_WSC_Start)
       
  2485 		{
       
  2486 			set_state(eap_type_simple_config_state_waiting_for_simple_config_start);
       
  2487 		}
       
  2488 	}
       
  2489 
       
  2490 	if (received_simple_config->check_header(
       
  2491 			m_am_tools,
       
  2492 			m_is_client) != eap_status_ok)
       
  2493 	{
       
  2494 		// ERROR: EAP-SIMPLE_CONFIG header is corrupted.
       
  2495 		EAP_TRACE_ERROR(
       
  2496 			m_am_tools,
       
  2497 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  2498 			(EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ")
       
  2499 			 EAPL("EAP-SIMPLE_CONFIG header is corrupted in ")
       
  2500 			 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  2501 			get_state(),
       
  2502 			get_state_string()));
       
  2503 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2504 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2505 	}
       
  2506 	else if (received_simple_config->get_eap_length() > simple_config_packet_length)
       
  2507 	{
       
  2508 		// ERROR: EAP-Lenght field value is larger than actual received packet.
       
  2509 		EAP_TRACE_ERROR(
       
  2510 			m_am_tools,
       
  2511 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  2512 			(EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ")
       
  2513 			 EAPL("EAP-Lenght field %d value is larger than actual received ")
       
  2514 			 EAPL("packet %d in eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  2515 			received_simple_config->get_eap_length(),
       
  2516 			simple_config_packet_length,
       
  2517 			get_state(),
       
  2518 			get_state_string()));
       
  2519 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2520 		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2521 	}
       
  2522 	else if (m_is_client == false
       
  2523 		&& received_simple_config->get_sc_op_code() == eap_simple_config_header_c::op_code_WSC_Start)
       
  2524 	{
       
  2525 		// ERROR: Server cannot receive EAP-SIMPLE_CONFIG Start message.
       
  2526 		EAP_TRACE_ERROR(
       
  2527 			m_am_tools,
       
  2528 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  2529 			(EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ")
       
  2530 			 EAPL("Server cannot receive EAP-SIMPLE_CONFIG Start message. ")
       
  2531 			 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  2532 			get_state(),
       
  2533 			get_state_string()));
       
  2534 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2535 		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
  2536 	}
       
  2537 	else if (m_is_client == true
       
  2538 		&& (get_state() != eap_type_simple_config_state_waiting_for_request
       
  2539 			&& get_state() != eap_type_simple_config_state_waiting_for_identity_request
       
  2540 			// EAP-SIMPLE_CONFIG could start without EAP-Request/Identity message.
       
  2541 			&& get_state() != eap_type_simple_config_state_waiting_for_simple_config_start
       
  2542 			))
       
  2543 	{
       
  2544 		// ERROR: Client cannot receive EAP-SIMPLE_CONFIG message in other states.
       
  2545 		EAP_TRACE_ERROR(
       
  2546 			m_am_tools,
       
  2547 			TRACE_FLAGS_DEFAULT,
       
  2548 			(EAPL("WARNING: eap_type_simple_config_c::simple_config_packet_process(): ")
       
  2549 			 EAPL("Client cannot receive EAP-SIMPLE_CONFIG message in ")
       
  2550 			 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  2551 			get_state(),
       
  2552 			get_state_string()));
       
  2553 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2554 		return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
       
  2555 	}
       
  2556 	else if (m_is_client == false
       
  2557 		&& get_state() != eap_type_simple_config_state_waiting_for_response
       
  2558 		)
       
  2559 	{
       
  2560 		// WARNING: Server cannot receive EAP-SIMPLE_CONFIG message in other states.
       
  2561 		// This packet is dropped quietly.
       
  2562 		EAP_TRACE_ERROR(
       
  2563 			m_am_tools,
       
  2564 			TRACE_FLAGS_DEFAULT,
       
  2565 			(EAPL("WARNING: eap_type_simple_config_c::simple_config_packet_process(): ")
       
  2566 			 EAPL("Server cannot receive EAP-SIMPLE_CONFIG message in ")
       
  2567 			 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  2568 			get_state(),
       
  2569 			get_state_string()));
       
  2570 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2571 		return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
       
  2572 	}
       
  2573 	else if (received_simple_config->get_sc_op_code() == eap_simple_config_header_c::op_code_WSC_Start
       
  2574 		&& get_state() != eap_type_simple_config_state_waiting_for_simple_config_start
       
  2575 		&& get_state() != eap_type_simple_config_state_waiting_for_identity_request)
       
  2576 		// EAP-SIMPLE_CONFIG could start without EAP-Request/Identity message.
       
  2577 	{
       
  2578 		// ERROR: EAP-SIMPLE_CONFIG Start message is accepted only in
       
  2579 		// eap_type_simple_config_state_waiting_for_simple_config_start.
       
  2580 		EAP_TRACE_ERROR(
       
  2581 			m_am_tools,
       
  2582 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  2583 			(EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ")
       
  2584 			 EAPL("EAP-SIMPLE_CONFIG Start message is NOT accepted in ")
       
  2585 			 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  2586 			get_state(),
       
  2587 			get_state_string()));
       
  2588 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2589 		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
       
  2590 	}
       
  2591 
       
  2592 	// EAP-SIMPLE_CONFIG and PEAP fragmentation support:
       
  2593 	// 
       
  2594 	// Flags include the Length included (L), More fragments (M), and EAP-SIMPLE_CONFIG Start (S) bits.
       
  2595 	// 
       
  2596 	// The L flag is set to indicate the presence of the four octet SIMPLE_CONFIG Message
       
  2597 	// Length field, and MUST be set for the first fragment of a fragmented
       
  2598 	// SIMPLE_CONFIG message or set of messages.
       
  2599 	// 
       
  2600 	// The M flag is set on all but the last fragment.
       
  2601 	// 
       
  2602 	// The S flag is set only within the EAP-SIMPLE_CONFIG start message
       
  2603 	// sent from the EAP server to the peer. This differentiates
       
  2604 	// the EAP-SIMPLE_CONFIG Start message from a fragment acknowledgement.
       
  2605 	// 
       
  2606 	// The SIMPLE_CONFIG Message Length field is four octets, and provides
       
  2607 	// the total length of the SIMPLE_CONFIG message or set of messages
       
  2608 	// that is being fragmented. This simplifies buffer allocation.
       
  2609 
       
  2610 	eap_status_e status = eap_status_process_general_error;
       
  2611 
       
  2612 	save_current_reassembly_state();
       
  2613 
       
  2614 	if (get_reassembly_state() == eap_type_simple_config_reassembly_state_wait_first_message)
       
  2615 	{
       
  2616 		if (received_simple_config->get_flag_more_fragments() == true
       
  2617 			&& received_simple_config->get_flag_simple_config_length_included() == false)
       
  2618 		{
       
  2619 			// The first fragmented message must include SIMPLE_CONFIG-length field.
       
  2620 			restore_saved_reassembly_state();
       
  2621 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2622 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2623 		}
       
  2624 
       
  2625 
       
  2626 		bool first_fragment = false;
       
  2627 		u32_t simple_config_message_length = 0ul;
       
  2628 
       
  2629 		if (received_simple_config->get_flag_simple_config_length_included() == true)
       
  2630 		{
       
  2631 			// This is the first fragment and SIMPLE_CONFIG message length is included.
       
  2632 			// We must allocate buffer for the fragments.
       
  2633 
       
  2634 			status = received_simple_config->get_simple_config_message_length(&simple_config_message_length);
       
  2635 			if (status != eap_status_ok)
       
  2636 			{
       
  2637 				restore_saved_reassembly_state();
       
  2638 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2639 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2640 			}
       
  2641 
       
  2642 			first_fragment = true;
       
  2643 		}
       
  2644 		else if (received_simple_config->get_flag_more_fragments() == false
       
  2645 			&& received_simple_config->get_sc_op_code() != eap_simple_config_header_c::op_code_WSC_Start
       
  2646 			&& received_simple_config->get_data_length() > 0ul)
       
  2647 		{
       
  2648 			// This is the individual message and SIMPLE_CONFIG message length is not included.
       
  2649 			// We must allocate buffer for the message.
       
  2650 
       
  2651 			simple_config_message_length = received_simple_config->get_data_length();
       
  2652 
       
  2653 			first_fragment = true;
       
  2654 		}
       
  2655 
       
  2656 
       
  2657 		if (first_fragment == true)
       
  2658 		{
       
  2659 			m_simple_config_message_buffer.reset();
       
  2660 
       
  2661 			if (simple_config_message_length > 0ul)
       
  2662 			{
       
  2663 				if (simple_config_message_length > EAP_SIMPLE_CONFIG_MAX_MESSAGE_LENGTH)
       
  2664 				{
       
  2665 					restore_saved_reassembly_state();
       
  2666 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2667 					return EAP_STATUS_RETURN(m_am_tools, eap_status_too_long_message);
       
  2668 				}
       
  2669 
       
  2670 				// Next allocate buffer for reassembled SIMPLE_CONFIG-message.
       
  2671 				status = m_simple_config_message_buffer.set_buffer_length(simple_config_message_length);
       
  2672 				if (status != eap_status_ok)
       
  2673 				{
       
  2674 					restore_saved_reassembly_state();
       
  2675 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2676 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2677 				}
       
  2678 
       
  2679 				// Copy first fragment to the reassembly buffer.
       
  2680 				status = m_simple_config_message_buffer.add_data(
       
  2681 					received_simple_config->get_data(m_am_tools, received_simple_config->get_data_length()),
       
  2682 					received_simple_config->get_data_length());
       
  2683 				if (status != eap_status_ok)
       
  2684 				{
       
  2685 					restore_saved_reassembly_state();
       
  2686 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2687 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2688 				}
       
  2689 
       
  2690 				m_first_fragment_eap_identifier = received_simple_config->get_eap_identifier();
       
  2691 			}
       
  2692 		}
       
  2693 
       
  2694 
       
  2695 		if (received_simple_config->get_flag_more_fragments() == true)
       
  2696 		{
       
  2697 			// This is NOT the last fragment.
       
  2698 
       
  2699 			// Send fragment acknowledge message.
       
  2700 			status = send_sc_frag_ack();
       
  2701 			if (status != eap_status_ok)
       
  2702 			{
       
  2703 				restore_saved_reassembly_state();
       
  2704 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2705 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2706 			}
       
  2707 
       
  2708 			// Change reassembly state.
       
  2709 			set_reassembly_state(eap_type_simple_config_reassembly_state_wait_last_fragment);
       
  2710 		}
       
  2711 		else
       
  2712 		{
       
  2713 			// This is the last fragment or non fragmented message.
       
  2714 			// Change reassembly state.
       
  2715 			set_reassembly_state(eap_type_simple_config_reassembly_state_message_reassembled);
       
  2716 
       
  2717 			if (received_simple_config->get_sc_op_code() == eap_simple_config_header_c::op_code_FRAG_ACK)
       
  2718 			{
       
  2719 				// This is EAP-SIMPLE_CONFIG fragment acknowledge.
       
  2720 				if (m_simple_config_message_buffer.get_is_valid_data() == true
       
  2721 					&& m_simple_config_message_send_offset < m_simple_config_message_buffer.get_data_length())
       
  2722 				{
       
  2723 					// We can send next fragment.
       
  2724 
       
  2725 					save_current_state();
       
  2726 					set_state(eap_type_simple_config_state_process_simple_config_message);
       
  2727 
       
  2728 					status = eap_simple_config_fragment_send();
       
  2729 					if (status != eap_status_ok)
       
  2730 					{
       
  2731 						restore_saved_previous_state();
       
  2732 						restore_saved_reassembly_state();
       
  2733 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2734 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2735 					}
       
  2736 					
       
  2737 					if (m_is_client == true)
       
  2738 					{
       
  2739 						set_state(eap_type_simple_config_state_waiting_for_request);
       
  2740 					}
       
  2741 					else
       
  2742 					{
       
  2743 						set_state(eap_type_simple_config_state_waiting_for_response);
       
  2744 					}
       
  2745 				}
       
  2746 				else
       
  2747 				{
       
  2748 					// No fragment available. Drop this packet.
       
  2749 					restore_saved_reassembly_state();
       
  2750 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2751 					return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  2752 				}
       
  2753 			}
       
  2754 			else if (received_simple_config->get_sc_op_code() == eap_simple_config_header_c::op_code_WSC_Start)
       
  2755 			{
       
  2756 				if (get_state() == eap_type_simple_config_state_waiting_for_simple_config_start)
       
  2757 				{
       
  2758 					// This is EAP-SIMPLE_CONFIG Start message.
       
  2759 					save_current_state();
       
  2760 					set_state(eap_type_simple_config_state_process_simple_config_start);
       
  2761 
       
  2762 					if (get_NAI()->get_is_valid_data() == false)
       
  2763 					{
       
  2764 						status = get_type_partner()->get_saved_eap_identity(get_NAI());
       
  2765 						if (status != eap_status_ok)
       
  2766 						{
       
  2767 							restore_saved_previous_state();
       
  2768 							restore_saved_reassembly_state();
       
  2769 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2770 							return EAP_STATUS_RETURN(m_am_tools, status);
       
  2771 						}
       
  2772 					}
       
  2773 
       
  2774 					status = start_simple_config_authentication(receive_network_id, get_NAI());
       
  2775 					if (status == eap_status_pending_request)
       
  2776 					{
       
  2777 						// Do nothing.
       
  2778 					}
       
  2779 					else if (status != eap_status_ok)
       
  2780 					{
       
  2781 						restore_saved_previous_state();
       
  2782 						restore_saved_reassembly_state();
       
  2783 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2784 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2785 					}
       
  2786 					else
       
  2787 					{
       
  2788 						// OK.
       
  2789 						set_reassembly_state(eap_type_simple_config_reassembly_state_wait_first_message);
       
  2790 					}
       
  2791 				}
       
  2792 				else
       
  2793 				{
       
  2794 					EAP_TRACE_ERROR(
       
  2795 						m_am_tools,
       
  2796 						TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  2797 						(EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ")
       
  2798 						 EAPL("Cannot receive EAP-SIMPLE_CONFIG message in ")
       
  2799 						 EAPL("eap_type_simple_config_state_variable_e %d=%s, ")
       
  2800 						 EAPL("eap_type_simple_config_reassembly_state_e %d=%s.\n"),
       
  2801 						 get_state(),
       
  2802 						 get_state_string(),
       
  2803 						 get_reassembly_state(),
       
  2804 						 get_reassembly_state_string()));
       
  2805 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2806 					return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  2807 				}
       
  2808 			}
       
  2809 			else
       
  2810 			{
       
  2811 				status = received_simple_config->check_header(
       
  2812 					m_am_tools,
       
  2813 					m_is_client);
       
  2814 				if (status != eap_status_ok)
       
  2815 				{
       
  2816 					restore_saved_reassembly_state();
       
  2817 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2818 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2819 				}
       
  2820 
       
  2821 				// Process the reassembled SIMPLE_CONFIG message.
       
  2822 				status = simple_config_message_process(
       
  2823 					receive_network_id,
       
  2824 					received_simple_config,
       
  2825 					simple_config_packet_length);
       
  2826 
       
  2827 				if (status != eap_status_ok
       
  2828 					&& status != eap_status_pending_request
       
  2829 					&& status != eap_status_success)
       
  2830 				{
       
  2831 					restore_saved_reassembly_state();
       
  2832 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2833 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  2834 				}
       
  2835 			}
       
  2836 
       
  2837 			set_reassembly_state(eap_type_simple_config_reassembly_state_wait_first_message);
       
  2838 		}
       
  2839 	}
       
  2840 	else if (get_reassembly_state() == eap_type_simple_config_reassembly_state_wait_last_fragment)
       
  2841 	{
       
  2842 		// SIMPLE_CONFIG message length field may or may not be included.
       
  2843 
       
  2844 		EAP_ASSERT_ALWAYS(received_simple_config->get_sc_op_code() != eap_simple_config_header_c::op_code_WSC_Start);
       
  2845 
       
  2846 		// Concatenate fragment to the reassembly buffer.
       
  2847 		status = m_simple_config_message_buffer.add_data(
       
  2848 			received_simple_config->get_data(m_am_tools, received_simple_config->get_data_length()),
       
  2849 			received_simple_config->get_data_length());
       
  2850 		if (status != eap_status_ok)
       
  2851 		{
       
  2852 			restore_saved_reassembly_state();
       
  2853 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2854 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2855 		}
       
  2856 
       
  2857 		if (received_simple_config->get_flag_more_fragments() == true)
       
  2858 		{
       
  2859 			// This is NOT the last fragment.
       
  2860 
       
  2861 			// Send fragment acknowledge message.
       
  2862 			status = send_sc_frag_ack();
       
  2863 			if (status != eap_status_ok)
       
  2864 			{
       
  2865 				restore_saved_reassembly_state();
       
  2866 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2867 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2868 			}
       
  2869 		}
       
  2870 		else
       
  2871 		{
       
  2872 			// This is the last fragment.
       
  2873 			// Change reassembly state.
       
  2874 			set_reassembly_state(eap_type_simple_config_reassembly_state_message_reassembled);
       
  2875 
       
  2876 			// Process the reassembled SIMPLE_CONFIG message.
       
  2877 			status = simple_config_message_process(
       
  2878 				receive_network_id,
       
  2879 				received_simple_config,
       
  2880 				simple_config_packet_length);
       
  2881 
       
  2882 			if (status != eap_status_ok
       
  2883 				&& status != eap_status_pending_request
       
  2884 				&& status != eap_status_success)
       
  2885 			{
       
  2886 				restore_saved_reassembly_state();
       
  2887 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2888 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  2889 			}
       
  2890 
       
  2891 			set_reassembly_state(eap_type_simple_config_reassembly_state_wait_first_message);
       
  2892 		}
       
  2893 	}
       
  2894 	else if (get_reassembly_state() == eap_type_simple_config_reassembly_state_message_reassembled)
       
  2895 	{
       
  2896 		EAP_TRACE_ERROR(
       
  2897 			m_am_tools,
       
  2898 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  2899 			(EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ")
       
  2900 			 EAPL("Cannot receive EAP-SIMPLE_CONFIG message in ")
       
  2901 			 EAPL("eap_type_simple_config_state_variable_e %d=%s, ")
       
  2902 			 EAPL("eap_type_simple_config_reassembly_state_e %d=%s.\n"),
       
  2903 			 get_state(),
       
  2904 			 get_state_string(),
       
  2905 			 get_reassembly_state(),
       
  2906 			 get_reassembly_state_string()));
       
  2907 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2908 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  2909 	}
       
  2910 	else
       
  2911 	{
       
  2912 		EAP_TRACE_ERROR(
       
  2913 			m_am_tools,
       
  2914 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  2915 			(EAPL("ERROR: eap_type_simple_config_c::simple_config_packet_process(): ")
       
  2916 			 EAPL("Cannot receive EAP-SIMPLE_CONFIG message in ")
       
  2917 			 EAPL("eap_type_simple_config_state_variable_e %d=%s, ")
       
  2918 			 EAPL("eap_type_simple_config_reassembly_state_e %d=%s.\n"),
       
  2919 			 get_state(),
       
  2920 			 get_state_string(),
       
  2921 			 get_reassembly_state(),
       
  2922 			 get_reassembly_state_string()));
       
  2923 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2924 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  2925 	}
       
  2926 
       
  2927 
       
  2928 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2929 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2930 }
       
  2931 
       
  2932 //--------------------------------------------------
       
  2933 
       
  2934 //
       
  2935 EAP_FUNC_EXPORT u32_t eap_type_simple_config_c::get_header_offset(
       
  2936 	u32_t * const MTU,
       
  2937 	u32_t * const trailer_length
       
  2938 	)
       
  2939 {
       
  2940 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2941 
       
  2942 	// Note, EAP-SIMPLE_CONFIG and PEAP supports fragmentation.
       
  2943 	// Here we could tell the MTU is big enough, the maximum memory buffer size is perfect.
       
  2944 
       
  2945 	if (MTU != 0)
       
  2946 	{
       
  2947 		*MTU = EAP_SIMPLE_CONFIG_MAX_MESSAGE_LENGTH;
       
  2948 	}
       
  2949 
       
  2950 	if (trailer_length != 0)
       
  2951 	{
       
  2952 		*trailer_length = 0ul;
       
  2953 	}
       
  2954 
       
  2955 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2956 	return 0ul; // This is the header offset of the SIMPLE_CONFIG-record header.
       
  2957 }
       
  2958 
       
  2959 //--------------------------------------------------
       
  2960 
       
  2961 //
       
  2962 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::timer_expired(
       
  2963 	const u32_t /*id*/, void * /*data*/
       
  2964 	)
       
  2965 {
       
  2966 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2967 
       
  2968 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2969 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  2970 }
       
  2971 
       
  2972 //--------------------------------------------------
       
  2973 
       
  2974 //
       
  2975 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::timer_delete_data(
       
  2976 	const u32_t /*id*/, void * /*data*/
       
  2977 	)
       
  2978 {
       
  2979 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2980 
       
  2981 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2982 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  2983 }
       
  2984 
       
  2985 //--------------------------------------------------
       
  2986 
       
  2987 //
       
  2988 EAP_FUNC_EXPORT void eap_type_simple_config_c::set_is_valid()
       
  2989 {
       
  2990 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2991 
       
  2992 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2993 	m_is_valid = true;
       
  2994 }
       
  2995 
       
  2996 //--------------------------------------------------
       
  2997 
       
  2998 //
       
  2999 EAP_FUNC_EXPORT bool eap_type_simple_config_c::get_is_valid()
       
  3000 {
       
  3001 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3002 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3003 	return m_is_valid;
       
  3004 }
       
  3005 
       
  3006 //--------------------------------------------------
       
  3007 
       
  3008 //
       
  3009 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::configure()
       
  3010 {
       
  3011 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3012 
       
  3013 	eap_status_e status = eap_status_process_general_error;
       
  3014 
       
  3015 	status = m_am_type_simple_config->configure();
       
  3016 	if (status != eap_status_ok)
       
  3017 	{
       
  3018 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3019 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3020 	}
       
  3021 
       
  3022 	status = m_simple_config_record->configure();
       
  3023 	if (status != eap_status_ok)
       
  3024 	{
       
  3025 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3026 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3027 	}
       
  3028 
       
  3029 	//----------------------------------------------------------
       
  3030 
       
  3031 	{
       
  3032 		eap_variable_data_c check_identifier_of_eap_identity_response(m_am_tools);
       
  3033 
       
  3034 		status = read_configure(
       
  3035 			cf_str_EAP_SIMPLE_CONFIG_check_identifier_of_eap_identity_response.get_field(),
       
  3036 			&check_identifier_of_eap_identity_response);
       
  3037 
       
  3038 		if (status == eap_status_ok
       
  3039 			&& check_identifier_of_eap_identity_response.get_is_valid_data() == true)
       
  3040 		{
       
  3041 			u32_t *flag = reinterpret_cast<u32_t *>(
       
  3042 				check_identifier_of_eap_identity_response.get_data(sizeof(u32_t)));
       
  3043 			if (flag != 0)
       
  3044 			{
       
  3045 				if (*flag == 0)
       
  3046 				{
       
  3047 					m_check_identifier_of_eap_identity_response = false;
       
  3048 				}
       
  3049 				else
       
  3050 				{
       
  3051 					m_check_identifier_of_eap_identity_response = true;
       
  3052 				}
       
  3053 			}
       
  3054 			else
       
  3055 			{
       
  3056 				EAP_TRACE_ERROR(
       
  3057 					m_am_tools,
       
  3058 					TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  3059 					(EAPL("ERROR: illegal configuration value %s\n"),
       
  3060 					 cf_str_EAP_SIMPLE_CONFIG_check_identifier_of_eap_identity_response
       
  3061 					 .get_field()->get_field()));
       
  3062 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3063 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
  3064 			}
       
  3065 		}
       
  3066 	}
       
  3067 
       
  3068 	//----------------------------------------------------------
       
  3069 
       
  3070 	{
       
  3071 		eap_variable_data_c EAP_SIMPLE_CONFIG_check_nai_realm(m_am_tools);
       
  3072 
       
  3073 		status = read_configure(
       
  3074 			cf_str_EAP_SIMPLE_CONFIG_check_nai_realm.get_field(),
       
  3075 			&EAP_SIMPLE_CONFIG_check_nai_realm);
       
  3076 		if (status == eap_status_ok
       
  3077 			&& EAP_SIMPLE_CONFIG_check_nai_realm.get_is_valid_data() == true)
       
  3078 		{
       
  3079 			u32_t *check_nai_realm = reinterpret_cast<u32_t *>(
       
  3080 				EAP_SIMPLE_CONFIG_check_nai_realm.get_data(sizeof(u32_t)));
       
  3081 			if (check_nai_realm != 0
       
  3082 				&& *check_nai_realm != 0)
       
  3083 			{
       
  3084 				m_check_nai_realm = true;
       
  3085 			}
       
  3086 		}
       
  3087 	}
       
  3088 
       
  3089 	//----------------------------------------------------------
       
  3090 
       
  3091 	{
       
  3092 		eap_variable_data_c test_version(m_am_tools);
       
  3093 
       
  3094 		status = read_configure(
       
  3095 			cf_str_EAP_SIMPLE_CONFIG_test_version.get_field(),
       
  3096 			&test_version);
       
  3097 		if (status == eap_status_ok
       
  3098 			&& test_version.get_is_valid_data() == true
       
  3099 			&& test_version.get_data_length() == sizeof(u32_t)
       
  3100 			&& test_version.get_data(sizeof(u32_t)) != 0)
       
  3101 		{
       
  3102 			// This is optional value.
       
  3103 			u32_t *flag = reinterpret_cast<u32_t *>(test_version.get_data(sizeof(u32_t)));
       
  3104 			if (flag != 0)
       
  3105 			{
       
  3106 				if (*flag == 0)
       
  3107 				{
       
  3108 					m_simple_config_test_version = false;
       
  3109 				}
       
  3110 				else
       
  3111 				{
       
  3112 					m_simple_config_test_version = true;
       
  3113 				}
       
  3114 			}
       
  3115 		}
       
  3116 	}
       
  3117 
       
  3118 	//----------------------------------------------------------
       
  3119 
       
  3120 	m_simple_config_header_offset = get_type_partner()->get_header_offset(
       
  3121 		&m_MTU, &m_trailer_length);
       
  3122 
       
  3123 	if (m_simple_config_header_offset+m_MTU+m_trailer_length > SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH)
       
  3124 	{
       
  3125 		EAP_ASSERT_ALWAYS(SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH
       
  3126 						  >= (m_simple_config_header_offset+m_trailer_length));
       
  3127 
       
  3128 		m_MTU = SIMPLE_CONFIG_LOCAL_PACKET_BUFFER_LENGTH
       
  3129 			- (m_simple_config_header_offset+m_trailer_length);
       
  3130 	}
       
  3131 
       
  3132 	//----------------------------------------------------------
       
  3133 
       
  3134 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3135 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3136 }
       
  3137 
       
  3138 //--------------------------------------------------
       
  3139 
       
  3140 //
       
  3141 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::shutdown()
       
  3142 {
       
  3143 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3144 
       
  3145 	EAP_TRACE_DEBUG(
       
  3146 		m_am_tools,
       
  3147 		TRACE_FLAGS_DEFAULT,
       
  3148 		(EAPL("%s: function: eap_type_simple_config_c::shutdown(): this = 0x%08x => 0x%08x\n"),
       
  3149 		 (m_is_client == true ? "client": "server"),
       
  3150 		 this,
       
  3151 		 dynamic_cast<abs_eap_base_timer_c *>(this)));
       
  3152 
       
  3153 	if (m_shutdown_was_called == true)
       
  3154 	{
       
  3155 		// Shutdown was already called (this prevents looping forever)
       
  3156 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3157 	}
       
  3158 
       
  3159 	m_shutdown_was_called = true;
       
  3160 
       
  3161 	send_final_notification();
       
  3162 	
       
  3163 	// Here we ignore return value. Both shutdown() calls must be done.
       
  3164 	eap_status_e status = m_simple_config_record->shutdown();
       
  3165 
       
  3166 	status = m_am_type_simple_config->shutdown();
       
  3167 
       
  3168 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3169 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3170 }
       
  3171 
       
  3172 //--------------------------------------------------
       
  3173 
       
  3174 //
       
  3175 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::read_configure(
       
  3176 	const eap_configuration_field_c * const field,
       
  3177 	eap_variable_data_c * const data
       
  3178 	)
       
  3179 {
       
  3180 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3181 
       
  3182 	// NOTE this will be read from AM of EAP-SIMPLE_CONFIG type.
       
  3183 	eap_status_e status = m_am_type_simple_config->type_configure_read(field, data);
       
  3184 	if (status != eap_status_ok)
       
  3185 	{
       
  3186 		// EAP-SIMPLE_CONFIG AM did not have configuration parameter.
       
  3187 		// Let's try the global configuration.
       
  3188 		status = get_type_partner()->read_configure(field, data);
       
  3189 		if (status != eap_status_ok)
       
  3190 		{
       
  3191 			EAP_TRACE_DATA_DEBUG(
       
  3192 				m_am_tools,
       
  3193 				TRACE_FLAGS_DEFAULT,
       
  3194 				(EAPL("WARNING: eap_type_simple_config_c::read_configure(): ")
       
  3195 				 EAPL("unknown configuration parameter"),
       
  3196 				field->get_field(),
       
  3197 				field->get_field_length()));
       
  3198 
       
  3199 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3200 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3201 		}
       
  3202 	}
       
  3203 
       
  3204 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3205 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3206 }
       
  3207 
       
  3208 //--------------------------------------------------
       
  3209 
       
  3210 //
       
  3211 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::write_configure(
       
  3212 	const eap_configuration_field_c * const field,
       
  3213 	eap_variable_data_c * const data
       
  3214 	)
       
  3215 {
       
  3216 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3217 
       
  3218 	// NOTE this will be read from AM of EAP-SIMPLE_CONFIG type.
       
  3219 	const eap_status_e status = m_am_type_simple_config->type_configure_write(field, data);
       
  3220 
       
  3221 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3222 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3223 }
       
  3224 
       
  3225 //--------------------------------------------------
       
  3226 
       
  3227 //
       
  3228 EAP_FUNC_EXPORT void eap_type_simple_config_c::state_notification(
       
  3229 	const abs_eap_state_notification_c * const state
       
  3230 	)
       
  3231 {
       
  3232 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3233 
       
  3234 	if (state->get_protocol_layer() == eap_protocol_layer_general)
       
  3235 	{
       
  3236 		// Just forward these notifications to lower layers.
       
  3237 
       
  3238 		if (state->get_eap_type() == eap_type_none)
       
  3239 		{
       
  3240 			// NOTE, here we set the EAP-type.
       
  3241 			eap_state_notification_c notification(
       
  3242 				m_am_tools,
       
  3243 				state->get_send_network_id(),
       
  3244 				state->get_is_client(),
       
  3245 				eap_state_notification_eap,
       
  3246 				state->get_protocol_layer(),
       
  3247 				eap_expanded_type_simple_config.get_type(),
       
  3248 				state->get_previous_state(),
       
  3249 				state->get_current_state(),
       
  3250 				state->get_eap_identifier(),
       
  3251 				false);
       
  3252 
       
  3253 			notification.set_authentication_error(state->get_authentication_error());
       
  3254 
       
  3255 			get_type_partner()->state_notification(&notification);
       
  3256 		}
       
  3257 		else
       
  3258 		{
       
  3259 			get_type_partner()->state_notification(state);
       
  3260 		}
       
  3261 
       
  3262 		return;
       
  3263 	}
       
  3264 
       
  3265 
       
  3266 	if (state->get_protocol_layer() == eap_protocol_layer_eap)
       
  3267 	{
       
  3268 		if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully)
       
  3269 		{
       
  3270 			EAP_TRACE_ERROR(
       
  3271 				m_am_tools,
       
  3272 				TRACE_FLAGS_DEFAULT,
       
  3273 				(EAPL("ERROR: %s: eap_type_simple_config_c::state_notification(): ")
       
  3274 				 EAPL("authentication failed: EAP-type 0x%08x\n"),
       
  3275 				 (m_is_client == true ? "client": "server"),
       
  3276 				 convert_eap_type_to_u32_t(eap_expanded_type_simple_config.get_type())));
       
  3277 
       
  3278 			// Here we must change the EAP-type of the notification.
       
  3279 			{
       
  3280 				eap_state_notification_c notification(
       
  3281 					m_am_tools,
       
  3282 					state->get_send_network_id(),
       
  3283 					state->get_is_client(),
       
  3284 					eap_state_notification_eap,
       
  3285 					state->get_protocol_layer(),
       
  3286 					eap_expanded_type_simple_config.get_type(),
       
  3287 					state->get_previous_state(),
       
  3288 					eap_state_authentication_terminated_unsuccessfully,
       
  3289 					state->get_eap_identifier(),
       
  3290 					false);
       
  3291 
       
  3292 				notification.set_authentication_error(eap_status_authentication_failure);
       
  3293 
       
  3294 				get_type_partner()->state_notification(&notification);
       
  3295 			}
       
  3296 		}
       
  3297 		else if (state->get_current_state() == eap_state_authentication_finished_successfully)
       
  3298 		{
       
  3299 			EAP_TRACE_ALWAYS(
       
  3300 				m_am_tools,
       
  3301 				TRACE_FLAGS_DEFAULT,
       
  3302 				(EAPL("%s: eap_type_simple_config_c::state_notification(): ")
       
  3303 				 EAPL("authentication EAP-SUCCESS: EAP-type 0x%08x\n"),
       
  3304 				 (m_is_client == true ? "client": "server"),
       
  3305 				 convert_eap_type_to_u32_t(eap_expanded_type_simple_config.get_type())));
       
  3306 
       
  3307 			(void) finish_successful_authentication();
       
  3308 		}
       
  3309 	}
       
  3310 	else if (state->get_protocol_layer() == eap_protocol_layer_internal_type)
       
  3311 	{
       
  3312 		eap_simple_config_trace_string_c simple_config_trace;
       
  3313 
       
  3314 		if (state->get_current_state() == simple_config_state_failure)
       
  3315 		{
       
  3316 			EAP_TRACE_ERROR(
       
  3317 				m_am_tools,
       
  3318 				TRACE_FLAGS_DEFAULT,
       
  3319 				(EAPL("%s: eap_type_simple_config_c::state_notification(): SIMPLE_CONFIG tunneled ")
       
  3320 				 EAPL("authentication failed: EAP-type 0x%08x\n"),
       
  3321 				 (m_is_client == true ? "client": "server"),
       
  3322 				 convert_eap_type_to_u32_t(eap_expanded_type_simple_config.get_type())));
       
  3323 
       
  3324 			set_state(eap_type_simple_config_state_failure);
       
  3325 		}
       
  3326 		else if (state->get_current_state() == simple_config_state_simple_config_success)
       
  3327 		{
       
  3328 			EAP_TRACE_DEBUG(
       
  3329 				m_am_tools,
       
  3330 				TRACE_FLAGS_DEFAULT,
       
  3331 				(EAPL("%s: eap_type_simple_config_c::state_notification(): ")
       
  3332 				 EAPL("SIMPLE_CONFIG authentication ")
       
  3333 				 EAPL("EAP-SUCCESS: EAP-type 0x%08x\n"),
       
  3334 				 (m_is_client == true ? "client": "server"),
       
  3335 				 convert_eap_type_to_u32_t(eap_expanded_type_simple_config.get_type())));
       
  3336 		}
       
  3337 		else if (state->get_current_state() == simple_config_state_pending_simple_config_messages_processed)
       
  3338 		{
       
  3339 			if (get_state() == eap_type_simple_config_state_process_simple_config_message
       
  3340 				|| get_state() == eap_type_simple_config_state_process_simple_config_start)
       
  3341 			{
       
  3342 				if (m_is_client == true)
       
  3343 				{
       
  3344 					set_state(eap_type_simple_config_state_waiting_for_request);
       
  3345 				}
       
  3346 				else
       
  3347 				{
       
  3348 					set_state(eap_type_simple_config_state_waiting_for_response);
       
  3349 				}
       
  3350 			}
       
  3351 		}
       
  3352 	}
       
  3353 
       
  3354 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3355 }
       
  3356 
       
  3357 //--------------------------------------------------
       
  3358 
       
  3359 //
       
  3360 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::query_eap_identity(
       
  3361 	const bool /* must_be_synchronous */,
       
  3362 	eap_variable_data_c * const identity,
       
  3363 	const eap_am_network_id_c * const receive_network_id,
       
  3364 	const u8_t eap_identifier)
       
  3365 {
       
  3366 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3367 
       
  3368 	EAP_TRACE_DEBUG(
       
  3369 		m_am_tools, 
       
  3370 		TRACE_FLAGS_DEFAULT, 
       
  3371 		(EAPL("eap_type_simple_config_c::query_eap_identity() ")
       
  3372 		 EAPL("in eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  3373 		 get_state(),
       
  3374 		 get_state_string()));
       
  3375 
       
  3376 	if (m_simple_config_test_version == true
       
  3377 		&& get_state() == eap_type_simple_config_state_failure)
       
  3378 	{
       
  3379 		// This is for testing.
       
  3380 		if (m_is_client == false)
       
  3381 		{
       
  3382 			set_state(eap_type_simple_config_state_waiting_for_identity_response);
       
  3383 		}
       
  3384 		else if (m_is_client == true)
       
  3385 		{
       
  3386 			set_state(eap_type_simple_config_state_waiting_for_simple_config_start);
       
  3387 		}
       
  3388 	}
       
  3389 
       
  3390 
       
  3391 	bool use_manual_username(false);
       
  3392 	eap_variable_data_c manual_username(m_am_tools);
       
  3393 	bool use_manual_realm(false);
       
  3394 	eap_variable_data_c manual_realm(m_am_tools);
       
  3395 
       
  3396 
       
  3397 	if (m_state == eap_type_simple_config_state_waiting_for_identity_request
       
  3398 		|| (m_simple_config_test_version == true // This one is for testing purposes.
       
  3399 			&& m_state == eap_type_simple_config_state_success))
       
  3400 	{
       
  3401 		save_current_state();
       
  3402 		set_state(eap_type_simple_config_state_pending_identity_query);
       
  3403 
       
  3404 		eap_status_e status = eap_status_process_general_error;
       
  3405 
       
  3406 		status = m_am_type_simple_config->query_eap_identity(
       
  3407 			receive_network_id,
       
  3408 			eap_identifier,
       
  3409 			&use_manual_username,
       
  3410 			&manual_username,
       
  3411 			&use_manual_realm,
       
  3412 			&manual_realm);
       
  3413 
       
  3414 		if (status == eap_status_pending_request)
       
  3415 		{
       
  3416 			// This is pending query, that will be completed by complete_eap_identity_query() call.
       
  3417 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3418 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3419 		}
       
  3420 		else if (status == eap_status_completed_request)
       
  3421 		{
       
  3422 			// This is already completed by complete_eap_identity_query() call.
       
  3423 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3424 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3425 		}
       
  3426 		else if (status != eap_status_ok
       
  3427 			&& status != eap_status_success)
       
  3428 		{
       
  3429 			// This is an error case.
       
  3430 			restore_saved_previous_state();
       
  3431 
       
  3432 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3433 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3434 		}
       
  3435 		else
       
  3436 		{
       
  3437 			status = handle_eap_identity_query(
       
  3438 				receive_network_id,
       
  3439 				eap_identifier,
       
  3440 				use_manual_username,
       
  3441 				&manual_username,
       
  3442 				use_manual_realm,
       
  3443 				&manual_realm);
       
  3444 		}
       
  3445 
       
  3446 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3447 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  3448 	}
       
  3449 	else if (m_state == eap_type_simple_config_state_waiting_for_simple_config_start)
       
  3450 	{
       
  3451 		// This is re-transmission request. We do not change our state.
       
  3452 		// Just send EAP-Identity again.
       
  3453 		if (get_NAI()->get_is_valid_data() == true)
       
  3454 		{
       
  3455 			eap_status_e status = identity->set_copy_of_buffer(get_NAI());
       
  3456 
       
  3457 			EAP_TRACE_DEBUG(
       
  3458 				m_am_tools, 
       
  3459 				TRACE_FLAGS_DEFAULT, 
       
  3460 				(EAPL("eap_type_simple_config_c::query_eap_identity() ")
       
  3461 				 EAPL("returns already obtained NAI in ")
       
  3462 				 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  3463 				 get_state(),
       
  3464 				 get_state_string()));
       
  3465 
       
  3466 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3467 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  3468 		}
       
  3469 		else
       
  3470 		{
       
  3471 			EAP_TRACE_ERROR(
       
  3472 				m_am_tools, 
       
  3473 				TRACE_FLAGS_SIMPLE_CONFIG_ERROR, 
       
  3474 				(EAPL("ERROR: eap_type_simple_config_c::query_eap_identity(): ")
       
  3475 				 EAPL("EAP-Request/Identity cannot be completed, identity (NAI) ")
       
  3476 				 EAPL("is missing. in eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  3477 				 get_state(),
       
  3478 				 get_state_string()));
       
  3479 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3480 			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
       
  3481 		}
       
  3482 	}
       
  3483 	else if (m_state == eap_type_simple_config_state_pending_identity_query)
       
  3484 	{
       
  3485 		EAP_TRACE_DEBUG(
       
  3486 			m_am_tools,
       
  3487 			TRACE_FLAGS_DEFAULT,
       
  3488 			(EAPL("eap_type_simple_config_c::query_eap_identity(): ")
       
  3489 			 EAPL("Already pending EAP-Identity query in ")
       
  3490 			 EAPL("eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  3491 			get_state(),
       
  3492 			get_state_string()));
       
  3493 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3494 		return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request);
       
  3495 	}
       
  3496 	else
       
  3497 	{	
       
  3498 		EAP_TRACE_ERROR(
       
  3499 			m_am_tools,
       
  3500 			TRACE_FLAGS_SIMPLE_CONFIG_ERROR,
       
  3501 			(EAPL("ERROR: eap_type_simple_config_c::query_eap_identity(): ")
       
  3502 			 EAPL("Illegal EAP-Identity query in eap_type_simple_config_state_variable_e %d=%s.\n"),
       
  3503 			get_state(),
       
  3504 			get_state_string()));
       
  3505 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3506 		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eap_type_state);
       
  3507 	}
       
  3508 }
       
  3509 
       
  3510 //--------------------------------------------------
       
  3511 
       
  3512 //
       
  3513 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::set_initial_eap_identifier(
       
  3514 	const eap_am_network_id_c * const /*receive_network_id*/,
       
  3515 	const u8_t /*initial_identifier*/)
       
  3516 {
       
  3517 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3518 
       
  3519 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3520 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  3521 }
       
  3522 
       
  3523 //--------------------------------------------------
       
  3524 
       
  3525 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::eap_acknowledge(
       
  3526 	const eap_am_network_id_c * const /* receive_network_id */)
       
  3527 {
       
  3528 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3529 
       
  3530 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3531 	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
       
  3532 }
       
  3533 
       
  3534 //--------------------------------------------------
       
  3535 
       
  3536 //
       
  3537 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::reset()
       
  3538 {
       
  3539 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3540 
       
  3541 	EAP_TRACE_DEBUG(
       
  3542 		m_am_tools,
       
  3543 		TRACE_FLAGS_DEFAULT,
       
  3544 		(EAPL("%s: eap_type_simple_config_c::reset(): this = 0x%08x: %d=%s.\n"),
       
  3545 		 (m_is_client == true) ? "client": "server",
       
  3546 		 this,
       
  3547 		 get_state(),
       
  3548 		 get_state_string()));
       
  3549 
       
  3550 	get_NAI()->reset();
       
  3551 
       
  3552 	if (m_is_client == true)
       
  3553 	{
       
  3554 		// Client waits EAP-Request/Identity.
       
  3555 		m_state = eap_type_simple_config_state_waiting_for_identity_request;
       
  3556 		m_saved_previous_state = eap_type_simple_config_state_waiting_for_identity_request;
       
  3557 	}
       
  3558 	else if (m_is_client == false)
       
  3559 	{
       
  3560 		// Server waits EAP-Response/Identity.
       
  3561 		m_state = eap_type_simple_config_state_waiting_for_identity_response;
       
  3562 		m_saved_previous_state = eap_type_simple_config_state_waiting_for_identity_response;
       
  3563 	}
       
  3564 
       
  3565 	m_reassembly_state = eap_type_simple_config_reassembly_state_wait_first_message;
       
  3566 
       
  3567 	m_saved_previous_reassembly_state = eap_type_simple_config_reassembly_state_wait_first_message;
       
  3568 
       
  3569 	m_simple_config_message_send_offset = 0ul;
       
  3570 
       
  3571 	m_simple_config_message_buffer.reset();
       
  3572 
       
  3573 	eap_status_e status = m_simple_config_record->reset();
       
  3574 
       
  3575 	m_failure_message_received = false;
       
  3576 	m_authentication_finished_successfully = false;
       
  3577 	m_last_eap_identifier = 0ul;
       
  3578 
       
  3579 	m_first_fragment_eap_identifier = 0ul;
       
  3580 
       
  3581 	m_am_type_simple_config->reset();
       
  3582 
       
  3583 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3584 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3585 }
       
  3586 
       
  3587 //--------------------------------------------------
       
  3588 
       
  3589 //
       
  3590 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::set_timer(
       
  3591 	abs_eap_base_timer_c * const p_initializer, 
       
  3592 	const u32_t p_id, 
       
  3593 	void * const p_data,
       
  3594 	const u32_t p_time_ms)
       
  3595 {
       
  3596 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3597 
       
  3598 	eap_status_e status = get_type_partner()->set_timer(
       
  3599 		p_initializer, 
       
  3600 		p_id, 
       
  3601 		p_data,
       
  3602 		p_time_ms);
       
  3603 
       
  3604 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3605 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3606 }
       
  3607 
       
  3608 //--------------------------------------------------
       
  3609 
       
  3610 //
       
  3611 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::cancel_timer(
       
  3612 	abs_eap_base_timer_c * const p_initializer, 
       
  3613 	const u32_t p_id)
       
  3614 {
       
  3615 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3616 
       
  3617 	eap_status_e status = get_type_partner()->cancel_timer(
       
  3618 		p_initializer, 
       
  3619 		p_id);
       
  3620 
       
  3621 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3622 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3623 }
       
  3624 
       
  3625 //--------------------------------------------------
       
  3626 
       
  3627 //
       
  3628 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::cancel_all_timers()
       
  3629 {
       
  3630 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3631 
       
  3632 	eap_status_e status = get_type_partner()->cancel_all_timers();
       
  3633 
       
  3634 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3635 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3636 }
       
  3637 
       
  3638 //--------------------------------------------------
       
  3639 
       
  3640 // This is commented in abs_simple_config_base_application_c.
       
  3641 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::load_module(
       
  3642 	const eap_type_value_e type,
       
  3643 	const eap_type_value_e tunneling_type,
       
  3644 	abs_eap_base_type_c * const partner,
       
  3645 	eap_base_type_c ** const eap_type,
       
  3646 	const bool is_client_when_true,
       
  3647 	const eap_am_network_id_c * const receive_network_id)
       
  3648 {
       
  3649 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3650 
       
  3651 	// This call is forwarded to EAPOL AM module because it handles all the 
       
  3652 	// tunneled EAP type handlings for PEAP.
       
  3653 	const eap_status_e status =  get_type_partner()->load_module(
       
  3654 		type,
       
  3655 		tunneling_type,
       
  3656 		partner,
       
  3657 		eap_type,
       
  3658 		is_client_when_true,
       
  3659 		receive_network_id);
       
  3660 	
       
  3661 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3662 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3663 }
       
  3664 
       
  3665 //--------------------------------------------------
       
  3666 
       
  3667 // This is commented in abs_simple_config_base_application_c.
       
  3668 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::unload_module(const eap_type_value_e type)
       
  3669 {
       
  3670 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3671 
       
  3672 	// This call is forwarded to EAPOL AM module because it handles all the 
       
  3673 	// tunneled EAP type handlings for PEAP.
       
  3674 	const eap_status_e status = get_type_partner()->unload_module(type);
       
  3675 
       
  3676 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3677 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3678 }
       
  3679 
       
  3680 //--------------------------------------------------
       
  3681 
       
  3682 // This is commented in abs_simple_config_base_application_c.
       
  3683 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::restart_authentication(
       
  3684 	const eap_am_network_id_c * const receive_network_id,
       
  3685 	const bool is_client_when_true,
       
  3686 	const bool /*force_clean_restart*/,
       
  3687 	const bool /*from_timer*/)
       
  3688 {
       
  3689 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3690 
       
  3691 	// Here we swap the addresses.
       
  3692 	eap_am_network_id_c send_network_id(m_am_tools,
       
  3693 		receive_network_id->get_destination_id(),
       
  3694 		receive_network_id->get_source_id(),
       
  3695 		receive_network_id->get_type());
       
  3696 
       
  3697 	const eap_status_e status = get_type_partner()->restart_authentication(
       
  3698 		&send_network_id,
       
  3699 		is_client_when_true);
       
  3700 
       
  3701 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3702 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3703 }
       
  3704 
       
  3705 //--------------------------------------------------
       
  3706 
       
  3707 // This is commented in abs_simple_config_base_application_c.
       
  3708 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::packet_data_crypto_keys(
       
  3709 	const eap_am_network_id_c * const /*send_network_id*/,
       
  3710 	const eap_master_session_key_c * const /*master_session_key*/)
       
  3711 {
       
  3712 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3713 
       
  3714 	// NOTE we do NOT forward keys to lower layer.
       
  3715 
       
  3716 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3717 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  3718 }
       
  3719 
       
  3720 //--------------------------------------------------
       
  3721 
       
  3722 // This is commented in abs_simple_config_base_application_c.
       
  3723 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::check_is_valid_eap_type(
       
  3724 	const eap_type_value_e eap_type)
       
  3725 {
       
  3726 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3727 
       
  3728 	// This call is forwarded to SIMPLE_CONFIG AM module because it handles all the 
       
  3729 	// tunneled EAP type handlings for PEAP.
       
  3730 	const eap_status_e status = m_am_type_simple_config->check_is_valid_eap_type(eap_type);
       
  3731 
       
  3732 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3733 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3734 }
       
  3735 
       
  3736 //--------------------------------------------------
       
  3737 
       
  3738 // This is commented in abs_simple_config_base_application_c.
       
  3739 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::get_eap_type_list(
       
  3740 	eap_array_c<eap_type_value_e> * const eap_type_list)
       
  3741 {
       
  3742 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3743 
       
  3744 	const eap_status_e status = m_am_type_simple_config->get_eap_type_list(eap_type_list);
       
  3745 
       
  3746 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3747 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3748 }
       
  3749 
       
  3750 //--------------------------------------------------
       
  3751 
       
  3752 //
       
  3753 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::set_session_timeout(
       
  3754 	const u32_t session_timeout_ms)
       
  3755 {
       
  3756 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3757 
       
  3758 	const eap_status_e status = get_type_partner()->set_session_timeout(session_timeout_ms);
       
  3759 
       
  3760 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3761 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3762 }
       
  3763 
       
  3764 //--------------------------------------------------
       
  3765 
       
  3766 EAP_FUNC_EXPORT eap_status_e eap_type_simple_config_c::add_rogue_ap(
       
  3767 	eap_array_c<eap_rogue_ap_entry_c> & rogue_ap_list)
       
  3768 {
       
  3769 	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3770 
       
  3771 	const eap_status_e status = get_type_partner()->add_rogue_ap(rogue_ap_list);
       
  3772 
       
  3773 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  3774 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  3775 }
       
  3776 
       
  3777 //--------------------------------------------------
       
  3778 
       
  3779 
       
  3780 #endif //#if defined(USE_EAP_SIMPLE_CONFIG)
       
  3781 
       
  3782 // End.