eapol/eapol_framework/eapol_common/am/common/eap_file_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 14 
       
    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 #include "eap_am_memory.h"
       
    29 #include "eap_file_config.h"
       
    30 #include "eap_automatic_variable.h"
       
    31 
       
    32 #if defined(_WIN32) && !defined(__GNUC__)
       
    33 	#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
       
    34 #endif
       
    35 
       
    36 
       
    37 #if 0
       
    38 	const u32_t TRACE_FLAGS_CONFIGURE_DATA = TRACE_FLAGS_DEFAULT;
       
    39 #else
       
    40 	const u32_t TRACE_FLAGS_CONFIGURE_DATA = eap_am_tools_c::eap_trace_mask_none;
       
    41 #endif
       
    42 
       
    43 //-----------------------------------------------------------------
       
    44 //-----------------------------------------------------------------
       
    45 //-----------------------------------------------------------------
       
    46 
       
    47 eap_config_value_c::~eap_config_value_c()
       
    48 {
       
    49 	delete m_subsection_map;
       
    50 	m_subsection_map = 0;
       
    51 }
       
    52 
       
    53 eap_config_value_c::eap_config_value_c(
       
    54 	abs_eap_am_tools_c* const tools)
       
    55 	: m_am_tools(tools)
       
    56 	, m_subsection_map(0)
       
    57 	, m_data(tools)
       
    58 	, m_type(eap_configure_type_none)
       
    59 	, m_is_valid(false)
       
    60 {
       
    61 	if (m_data.get_is_valid() == false)
       
    62 	{
       
    63 		return;
       
    64 	}
       
    65 
       
    66 	m_is_valid = true;
       
    67 }
       
    68 
       
    69 void eap_config_value_c::set_subsection(
       
    70 	eap_core_map_c<eap_config_value_c, abs_eap_core_map_c, eap_variable_data_c> * const subsection_map)
       
    71 {
       
    72 	m_subsection_map = subsection_map;
       
    73 }
       
    74 
       
    75 eap_core_map_c<eap_config_value_c, abs_eap_core_map_c, eap_variable_data_c> * eap_config_value_c::get_subsection()
       
    76 {
       
    77 	return m_subsection_map;
       
    78 }
       
    79 
       
    80 eap_variable_data_c * eap_config_value_c::get_data()
       
    81 {
       
    82 	return &m_data;
       
    83 }
       
    84 
       
    85 void eap_config_value_c::set_type(const eap_configure_type_e type)
       
    86 {
       
    87 	m_type = type;
       
    88 }
       
    89 
       
    90 eap_configure_type_e eap_config_value_c::get_type()
       
    91 {
       
    92 	return m_type;
       
    93 }
       
    94 
       
    95 void eap_config_value_c::object_increase_reference_count()
       
    96 {
       
    97 }
       
    98 
       
    99 bool eap_config_value_c::get_is_valid()
       
   100 {
       
   101 	return m_is_valid;
       
   102 }
       
   103 
       
   104 //-----------------------------------------------------------------
       
   105 //-----------------------------------------------------------------
       
   106 //-----------------------------------------------------------------
       
   107 
       
   108 
       
   109 EAP_FUNC_EXPORT eap_file_config_c::eap_file_config_c(
       
   110 	abs_eap_am_tools_c* const tools)
       
   111 : m_am_tools(tools)
       
   112 , m_config_map(tools, this)
       
   113 , m_is_valid(false)
       
   114 {
       
   115 	EAP_UNREFERENCED_PARAMETER(TRACE_FLAGS_CONFIGURE_DATA); // in release
       
   116 	
       
   117 	set_is_valid();
       
   118 }
       
   119 
       
   120 //-----------------------------------------------------------------
       
   121 
       
   122 EAP_FUNC_EXPORT eap_file_config_c::~eap_file_config_c()
       
   123 {
       
   124 }
       
   125 
       
   126 //-----------------------------------------------------------------
       
   127 
       
   128 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::configure(
       
   129 	abs_eap_am_file_input_c * const file)
       
   130 {
       
   131 	eap_status_e status = read_subsections(file, &m_config_map);
       
   132 	if (status != eap_status_ok)
       
   133 	{
       
   134 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   135 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   136 	}
       
   137 
       
   138 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   139 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   140 }
       
   141 
       
   142 //-----------------------------------------------------------------
       
   143 
       
   144 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::expand_environment_variables(
       
   145 	eap_core_map_c<eap_config_value_c, abs_eap_core_map_c, eap_variable_data_c> * const config_map,
       
   146 	const eap_variable_data_c * const original_value,
       
   147 	eap_variable_data_c * const expanded_value
       
   148 	)
       
   149 {
       
   150 	eap_status_e status = eap_status_process_general_error;
       
   151 
       
   152 	if (original_value == 0
       
   153 		|| expanded_value == 0
       
   154 		)
       
   155 	{
       
   156 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   157 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
   158 	}
       
   159 
       
   160 	const u8_t env_char = '$';
       
   161 	const u8_t char_left_parenthesis = '(';
       
   162 	const u8_t char_right_parenthesis = ')';
       
   163 
       
   164 	eap_variable_data_c tmp_value_buffer(m_am_tools);
       
   165 	if (tmp_value_buffer.get_is_valid() == false)
       
   166 	{
       
   167 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   168 	}
       
   169 
       
   170 	status = tmp_value_buffer.set_buffer_length(MAX_LINE_LENGTH);
       
   171 	if (status != eap_status_ok)
       
   172 	{
       
   173 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   174 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   175 	}
       
   176 
       
   177 	bool expanded_value_when_true = false;
       
   178 
       
   179 	status = expanded_value->set_copy_of_buffer(original_value);
       
   180 	if (status != eap_status_ok)
       
   181 	{
       
   182 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   183 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   184 	}
       
   185 
       
   186 
       
   187 	for (;;)
       
   188 	{
       
   189 		u8_t * const start_of_value = expanded_value->get_data(expanded_value->get_data_length());
       
   190 
       
   191 		u8_t * const env_start = static_cast<u8_t *>(m_am_tools->memchr(
       
   192 			start_of_value,
       
   193 			env_char,
       
   194 			expanded_value->get_data_length()));
       
   195 
       
   196 		if (env_start == 0)
       
   197 		{
       
   198 			status = eap_status_ok;
       
   199 			break;
       
   200 		}
       
   201 		else
       
   202 		{
       
   203 			if (static_cast<u32_t>((env_start+2)-start_of_value) < expanded_value->get_data_length()
       
   204 				&& env_start[1] == char_left_parenthesis)
       
   205 			{
       
   206 				u8_t *tmp_end = start_of_value + expanded_value->get_data_length();
       
   207 
       
   208 				u8_t *env_end = static_cast<u8_t *>(m_am_tools->memchr(
       
   209 					env_start,
       
   210 					char_right_parenthesis,
       
   211 					tmp_end-env_start));
       
   212 				if (env_end != 0)
       
   213 				{
       
   214 					*env_end = '\0';
       
   215 
       
   216 					u8_t *env_name = env_start+2;
       
   217 
       
   218 					eap_variable_data_c env_name_buffer(m_am_tools);
       
   219 					if (env_name_buffer.get_is_valid() == false)
       
   220 					{
       
   221 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   222 					}
       
   223 
       
   224 					status = env_name_buffer.set_buffer(
       
   225 						env_name,
       
   226 						env_end-env_name,
       
   227 						false,
       
   228 						false);
       
   229 					if (status != eap_status_ok)
       
   230 					{
       
   231 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   232 						return EAP_STATUS_RETURN(m_am_tools, status);
       
   233 					}
       
   234 
       
   235 					eap_variable_data_c env_value_buffer(m_am_tools);
       
   236 					if (env_value_buffer.get_is_valid() == false)
       
   237 					{
       
   238 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   239 					}
       
   240 
       
   241 					eap_status_e env_status = m_am_tools->getenv(
       
   242 						&env_name_buffer,
       
   243 						&env_value_buffer);
       
   244 
       
   245 					eap_variable_data_c parsed_value_buffer(m_am_tools);
       
   246 					if (parsed_value_buffer.get_is_valid() == false)
       
   247 					{
       
   248 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   249 					}
       
   250 
       
   251 					status = parsed_value_buffer.set_buffer_length(MAX_LINE_LENGTH);
       
   252 					if (status != eap_status_ok)
       
   253 					{
       
   254 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   255 						return EAP_STATUS_RETURN(m_am_tools, status);
       
   256 					}
       
   257 					parsed_value_buffer.set_data_length(MAX_LINE_LENGTH);
       
   258 
       
   259 					eap_variable_data_c configure_option(m_am_tools);
       
   260 					if (configure_option.get_is_valid() == false)
       
   261 					{
       
   262 						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   263 					}
       
   264 
       
   265 					if (env_status != eap_status_ok)
       
   266 					{
       
   267 						// Next check whether a one of the defined configuration
       
   268 						// options match to the variable.
       
   269 						eap_configure_type_e configuration_data_type = eap_configure_type_none;
       
   270 						static const u32_t EAP_MAX_CONFIG_BUFFER_LENGTH = 256;
       
   271 						eap_configuration_field_template_c<EAP_MAX_CONFIG_BUFFER_LENGTH> * const tmp_env_name
       
   272 							= new eap_configuration_field_template_c<EAP_MAX_CONFIG_BUFFER_LENGTH>;
       
   273 
       
   274 						eap_automatic_variable_c<eap_configuration_field_template_c<EAP_MAX_CONFIG_BUFFER_LENGTH> >
       
   275 							automatic_tmp_env_name(m_am_tools, tmp_env_name);
       
   276 
       
   277 						if (tmp_env_name == 0)
       
   278 						{
       
   279 							return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   280 						}
       
   281 
       
   282 						eap_status_e status = tmp_env_name->set_fields(
       
   283 							m_am_tools,
       
   284 							env_name,
       
   285 							eap_configure_type_none,
       
   286 							false);
       
   287 						if (status != eap_status_ok)
       
   288 						{
       
   289 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   290 							return EAP_STATUS_RETURN(m_am_tools, status);
       
   291 						}
       
   292 
       
   293 						status = read_configure(
       
   294 							config_map,
       
   295 							tmp_env_name->get_field(),
       
   296 							&configure_option,
       
   297 							&configuration_data_type,
       
   298 							false);
       
   299 
       
   300 						if (status == eap_status_ok)
       
   301 						{
       
   302 							if (configuration_data_type == eap_configure_type_string)
       
   303 							{
       
   304 								status = configure_option.add_end_null();
       
   305 							}
       
   306 							else if (configuration_data_type == eap_configure_type_u32_t)
       
   307 							{
       
   308 								u32_t * const p_value = reinterpret_cast<u32_t *>(
       
   309 									configure_option.get_data(
       
   310 										configure_option.get_data_length()));
       
   311 								if (p_value != 0)
       
   312 								{
       
   313 									u32_t value = *p_value;
       
   314 
       
   315 									status = configure_option.set_buffer_length(EAP_MAX_CONFIG_BUFFER_LENGTH);
       
   316 									if (status != eap_status_ok)
       
   317 									{
       
   318 										EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   319 										return EAP_STATUS_RETURN(m_am_tools, status);
       
   320 									}
       
   321 
       
   322 									status = configure_option.set_data_length(EAP_MAX_CONFIG_BUFFER_LENGTH);
       
   323 									if (status != eap_status_ok)
       
   324 									{
       
   325 										EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   326 										return EAP_STATUS_RETURN(m_am_tools, status);
       
   327 									}
       
   328 
       
   329 									u32_t length = m_am_tools->snprintf(
       
   330 											reinterpret_cast<u8_t *>(
       
   331 												configure_option.get_data(
       
   332 													configure_option.get_data_length())),
       
   333 											EAP_MAX_CONFIG_BUFFER_LENGTH,
       
   334 											EAPL("%u"),
       
   335 											value);
       
   336 									status = configure_option.set_data_length(length);
       
   337 									if (status != eap_status_ok)
       
   338 									{
       
   339 										EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   340 										return EAP_STATUS_RETURN(m_am_tools, status);
       
   341 									}
       
   342 
       
   343 									status = configure_option.add_end_null();
       
   344 									if (status != eap_status_ok)
       
   345 									{
       
   346 										EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   347 										return EAP_STATUS_RETURN(m_am_tools, status);
       
   348 									}
       
   349 								}
       
   350 							}
       
   351 							else if (configuration_data_type == eap_configure_type_boolean)
       
   352 							{
       
   353 								u32_t * const p_value = reinterpret_cast<u32_t *>(
       
   354 									configure_option.get_data(
       
   355 										configure_option.get_data_length()));
       
   356 								if (p_value != 0)
       
   357 								{
       
   358 									bool value = (*p_value == 0) ? false : true;
       
   359 
       
   360 									status = configure_option.set_buffer_length(EAP_MAX_CONFIG_BUFFER_LENGTH);
       
   361 									if (status != eap_status_ok)
       
   362 									{
       
   363 										EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   364 										return EAP_STATUS_RETURN(m_am_tools, status);
       
   365 									}
       
   366 
       
   367 									status = configure_option.set_data_length(EAP_MAX_CONFIG_BUFFER_LENGTH);
       
   368 									if (status != eap_status_ok)
       
   369 									{
       
   370 										EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   371 										return EAP_STATUS_RETURN(m_am_tools, status);
       
   372 									}
       
   373 
       
   374 									if (value == true)
       
   375 									{
       
   376 										u32_t length = m_am_tools->snprintf(
       
   377 												reinterpret_cast<u8_t *>(
       
   378 													configure_option.get_data(
       
   379 														configure_option.get_data_length())),
       
   380 												EAP_MAX_CONFIG_BUFFER_LENGTH,
       
   381 												EAPL("true"));
       
   382 										status = configure_option.set_data_length(length);
       
   383 										if (status != eap_status_ok)
       
   384 										{
       
   385 											EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   386 											return EAP_STATUS_RETURN(m_am_tools, status);
       
   387 										}
       
   388 									}
       
   389 									else
       
   390 									{
       
   391 										u32_t length = m_am_tools->snprintf(
       
   392 												reinterpret_cast<u8_t *>(
       
   393 													configure_option.get_data(
       
   394 														configure_option.get_data_length())),
       
   395 												EAP_MAX_CONFIG_BUFFER_LENGTH,
       
   396 												EAPL("false"));
       
   397 										configure_option.set_data_length(length);
       
   398 									}
       
   399 
       
   400 									status = configure_option.add_end_null();
       
   401 									if (status != eap_status_ok)
       
   402 									{
       
   403 										EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   404 										return EAP_STATUS_RETURN(m_am_tools, status);
       
   405 									}
       
   406 								}
       
   407 							}
       
   408 							else if (configuration_data_type == eap_configure_type_hex_data)
       
   409 							{
       
   410 								u8_t * const p_value = reinterpret_cast<u8_t *>(
       
   411 									configure_option.get_data(
       
   412 										configure_option.get_data_length()));
       
   413 
       
   414 								u8_t buffer[3];
       
   415 								u8_t comma(',');
       
   416 
       
   417 								eap_variable_data_c tmp(m_am_tools);
       
   418 								if (tmp.get_is_valid() == false)
       
   419 								{
       
   420 									return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   421 								}
       
   422 
       
   423 								for (u32_t ind = 0ul; ind < configure_option.get_data_length(); ind++)
       
   424 								{
       
   425 									u32_t length = m_am_tools->snprintf(
       
   426 											buffer,
       
   427 											sizeof(buffer),
       
   428 											EAPL("%02x"),
       
   429 											p_value[ind]);
       
   430 
       
   431 									status = tmp.add_data(buffer, length);
       
   432 									if (status != eap_status_ok)
       
   433 									{
       
   434 										EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   435 										return EAP_STATUS_RETURN(m_am_tools, status);
       
   436 									}
       
   437 
       
   438 									if ((ind+1) < configure_option.get_data_length())
       
   439 									{
       
   440 										status = tmp.add_data(&comma, sizeof(comma));
       
   441 										if (status != eap_status_ok)
       
   442 										{
       
   443 											EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   444 											return EAP_STATUS_RETURN(m_am_tools, status);
       
   445 										}
       
   446 									}
       
   447 								} // for()
       
   448 
       
   449 								status = configure_option.set_copy_of_buffer(&tmp);
       
   450 								if (status != eap_status_ok)
       
   451 								{
       
   452 									EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   453 									return EAP_STATUS_RETURN(m_am_tools, status);
       
   454 								}
       
   455 
       
   456 								status = configure_option.add_end_null();
       
   457 								if (status != eap_status_ok)
       
   458 								{
       
   459 									EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   460 									return EAP_STATUS_RETURN(m_am_tools, status);
       
   461 								}
       
   462 							}
       
   463 						}
       
   464 
       
   465 						if (configure_option.get_is_valid_data() == false
       
   466 							|| configure_option.get_data_length() == 0ul)
       
   467 						{
       
   468 							#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
   469 								printf("WARNING: CONFIG: unknown environment variable %s.\n",
       
   470 									   env_name);
       
   471 							#endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
   472 
       
   473 							EAP_TRACE_DEBUG(
       
   474 								m_am_tools,
       
   475 								TRACE_FLAGS_DEFAULT,
       
   476 								(EAPL("WARNING: CONFIG: unknown environment variable %s.\n"),
       
   477 								 env_name));
       
   478 
       
   479 							// This is empty environment value.
       
   480 						}
       
   481 					}
       
   482 					else
       
   483 					{
       
   484 						// OK environment variable found.
       
   485 						eap_configure_type_e type = eap_configure_type_none;
       
   486 
       
   487 						status = cnf_parse_value(
       
   488 							&env_value_buffer,
       
   489 							&env_name_buffer,
       
   490 							&type,
       
   491 							&configure_option,
       
   492 							true
       
   493 							);
       
   494 						if (status != eap_status_ok)
       
   495 						{
       
   496 							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   497 							return EAP_STATUS_RETURN(m_am_tools, status);
       
   498 						}
       
   499 					}
       
   500 
       
   501 
       
   502 					if (configure_option.get_is_valid_data() == true
       
   503 						&& configure_option.get_data_length() > 0ul)
       
   504 					{
       
   505 						tmp_value_buffer.reset();
       
   506 
       
   507 						u32_t tmp_index = 0ul;
       
   508 
       
   509 						if (env_start > start_of_value)
       
   510 						{
       
   511 							u32_t length_of_begin = env_start-start_of_value;
       
   512 							if (length_of_begin > 0ul)
       
   513 							{
       
   514 								status = tmp_value_buffer.set_copy_of_buffer(
       
   515 									expanded_value->get_data(length_of_begin),
       
   516 									length_of_begin);
       
   517 								if (status != eap_status_ok)
       
   518 								{
       
   519 									EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   520 									return EAP_STATUS_RETURN(m_am_tools, status);
       
   521 								}
       
   522 
       
   523 								tmp_index += length_of_begin;
       
   524 							}
       
   525 						}
       
   526 
       
   527 						if (configure_option.get_data_length() > 0ul)
       
   528 						{
       
   529 							status = tmp_value_buffer.add_data(&configure_option);
       
   530 							if (status != eap_status_ok)
       
   531 							{
       
   532 								EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   533 								return EAP_STATUS_RETURN(m_am_tools, status);
       
   534 							}
       
   535 
       
   536 							tmp_index += configure_option.get_data_length();
       
   537 						}
       
   538 
       
   539 						if (tmp_end > (env_end+1))
       
   540 						{
       
   541 							u32_t length_of_end = tmp_end-(env_end+1);
       
   542 							if (length_of_end > 0ul)
       
   543 							{
       
   544 								status = tmp_value_buffer.add_data(
       
   545 									(env_end+1),
       
   546 									length_of_end);
       
   547 								if (status != eap_status_ok)
       
   548 								{
       
   549 									EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   550 									return EAP_STATUS_RETURN(m_am_tools, status);
       
   551 								}
       
   552 
       
   553 								tmp_index += length_of_end;
       
   554 							}
       
   555 						}
       
   556 
       
   557 						if (tmp_value_buffer.get_is_valid_data() == true
       
   558 							&& tmp_value_buffer.get_data_length() > 0ul)
       
   559 						{
       
   560 							status = expanded_value->set_copy_of_buffer(&tmp_value_buffer);
       
   561 							if (status != eap_status_ok)
       
   562 							{
       
   563 								EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   564 								return EAP_STATUS_RETURN(m_am_tools, status);
       
   565 							}
       
   566 
       
   567 							status = expanded_value->add_end_null();
       
   568 							if (status != eap_status_ok)
       
   569 							{
       
   570 								EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   571 								return EAP_STATUS_RETURN(m_am_tools, status);
       
   572 							}
       
   573 
       
   574 							expanded_value_when_true = true;
       
   575 						}
       
   576 
       
   577 					}
       
   578 				}
       
   579 				else
       
   580 				{
       
   581 					#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
   582 						printf("ERROR: CONFIG: illegal configure value %s.\n",
       
   583 							   expanded_value->get_data(expanded_value->get_data_length()));
       
   584 					#endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
   585 
       
   586 					EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
   587 									(EAPL("ERROR: CONFIG: illegal configure value %s.\n"),
       
   588 									 expanded_value->get_data(expanded_value->get_data_length())));
       
   589 					status = eap_status_illegal_configure_field;
       
   590 					break;
       
   591 				}
       
   592 			}
       
   593 			else
       
   594 			{
       
   595 				#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
   596 					printf("ERROR: CONFIG: illegal configure value %s.\n",
       
   597 						   expanded_value->get_data(expanded_value->get_data_length()));
       
   598 				#endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
   599 
       
   600 				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
   601 								(EAPL("ERROR: CONFIG: illegal configure value %s.\n"),
       
   602 								 expanded_value->get_data(expanded_value->get_data_length())));
       
   603 				status = eap_status_illegal_configure_field;
       
   604 				break;
       
   605 			}
       
   606 		}
       
   607 	} // for()
       
   608 
       
   609 	if (status == eap_status_ok
       
   610 		&& expanded_value_when_true == true)
       
   611 	{
       
   612 		#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
   613 			printf("CONFIG: expanded configuration value [%s] => [%s].\n",
       
   614 				value,
       
   615 				expanded_value);
       
   616 		#endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
   617 
       
   618 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
   619 						(EAPL("CONFIG: expanded configuration value [%s] => [%s].\n"),
       
   620 						 original_value->get_data(original_value->get_data_length()),
       
   621 						 expanded_value->get_data(expanded_value->get_data_length())));
       
   622 	}
       
   623 
       
   624 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   625 	return EAP_STATUS_RETURN(m_am_tools, status);
       
   626 }
       
   627 
       
   628 //-----------------------------------------------------------------
       
   629 
       
   630 EAP_FUNC_EXPORT u8_t * eap_file_config_c::read_hex_byte(
       
   631 	u8_t * cursor,
       
   632 	const u8_t * const end,
       
   633 	u8_t * const hex_byte)
       
   634 {
       
   635 	u8_t * start = cursor;
       
   636 	bool stop = false;
       
   637 
       
   638 	while(stop == false && cursor < end)
       
   639 	{
       
   640 		switch(*cursor)
       
   641 		{
       
   642 		case static_cast<u8_t>(','):
       
   643 		case static_cast<u8_t>(' '):
       
   644 		case static_cast<u8_t>('\t'):
       
   645 			stop = true;
       
   646 			break;
       
   647 		default:
       
   648 			++cursor;
       
   649 			break;
       
   650 		}
       
   651 
       
   652 	}
       
   653 
       
   654 	if (cursor <= end)
       
   655 	{
       
   656 		u32_t target_length = sizeof(*hex_byte);
       
   657 
       
   658 		eap_status_e status = m_am_tools->convert_hex_ascii_to_bytes(
       
   659 			start,
       
   660 			cursor-start,
       
   661 			hex_byte,
       
   662 			&target_length);
       
   663 		if (status != eap_status_ok)
       
   664 		{
       
   665 			return 0;
       
   666 		}
       
   667 
       
   668 		return ++cursor;
       
   669 	}
       
   670 
       
   671 	return 0;
       
   672 }
       
   673 
       
   674 //-----------------------------------------------------------------
       
   675 
       
   676 EAP_FUNC_EXPORT u8_t * eap_file_config_c::read_u32_t(
       
   677 	u8_t * cursor,
       
   678 	const u8_t * const end,
       
   679 	u32_t * const integer)
       
   680 {
       
   681 	u8_t * start = cursor;
       
   682 	bool stop = false;
       
   683 
       
   684 	while(stop == false && cursor < end)
       
   685 	{
       
   686 		switch(*cursor)
       
   687 		{
       
   688 		case static_cast<u8_t>(','):
       
   689 		case static_cast<u8_t>(' '):
       
   690 		case static_cast<u8_t>('\t'):
       
   691 			stop = true;
       
   692 			break;
       
   693 		default:
       
   694 			++cursor;
       
   695 			break;
       
   696 		}
       
   697 
       
   698 	}
       
   699 
       
   700 	if (cursor <= end)
       
   701 	{
       
   702 		eap_variable_data_c buffer(m_am_tools);
       
   703 		if (buffer.get_is_valid() == false)
       
   704 		{
       
   705 			(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   706 			return 0;
       
   707 		}
       
   708 
       
   709 		eap_status_e status = buffer.add_data(start, cursor-start);
       
   710 		if (status != eap_status_ok)
       
   711 		{
       
   712 			(void) EAP_STATUS_RETURN(m_am_tools, status);
       
   713 			return 0;
       
   714 		}
       
   715 
       
   716 		status = m_am_tools->number_string_to_u32(
       
   717 			buffer.get_data(buffer.get_data_length()),
       
   718 			buffer.get_data_length(),
       
   719 			integer);
       
   720 		if (status != eap_status_ok)
       
   721 		{
       
   722 			(void) EAP_STATUS_RETURN(m_am_tools, status);
       
   723 			return 0;
       
   724 		}
       
   725 
       
   726 		return ++cursor;
       
   727 	}
       
   728 
       
   729 	(void) EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
       
   730 	return 0;
       
   731 }
       
   732 
       
   733 //-----------------------------------------------------------------
       
   734 
       
   735 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::convert_value(
       
   736 	eap_core_map_c<eap_config_value_c, abs_eap_core_map_c, eap_variable_data_c> * const config_map,
       
   737 	const eap_variable_data_c * const value_buffer,
       
   738 	const eap_configure_type_e type,
       
   739 	eap_variable_data_c * const value_data)
       
   740 {
       
   741 	eap_status_e status = eap_status_process_general_error;
       
   742 
       
   743 		eap_variable_data_c expanded_value_buffer(m_am_tools);
       
   744 		if (expanded_value_buffer.get_is_valid() == false)
       
   745 		{
       
   746 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   747 		}
       
   748 
       
   749 		status = expanded_value_buffer.set_buffer_length(MAX_LINE_LENGTH);
       
   750 		if (status != eap_status_ok)
       
   751 		{
       
   752 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   753 		}
       
   754 		expanded_value_buffer.set_data_length(MAX_LINE_LENGTH);
       
   755 
       
   756 		status = expand_environment_variables(
       
   757 			config_map,
       
   758 			value_buffer,
       
   759 			&expanded_value_buffer);
       
   760 		if (status != eap_status_ok)
       
   761 		{
       
   762 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   763 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   764 		}
       
   765 		
       
   766 		if (type == eap_configure_type_u32_t)
       
   767 		{
       
   768 			u32_t uint_value = 0UL;
       
   769 			
       
   770 			status = m_am_tools->number_string_to_u32(
       
   771 				expanded_value_buffer.get_data(expanded_value_buffer.get_data_length()),
       
   772 				expanded_value_buffer.get_data_length(),
       
   773 				&uint_value);
       
   774 			if (status != eap_status_ok)
       
   775 			{
       
   776 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   777 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   778 			}
       
   779 			
       
   780 			status = value_data->set_copy_of_buffer(
       
   781 				&uint_value,
       
   782 				sizeof(uint_value));
       
   783 			if (status != eap_status_ok)
       
   784 			{
       
   785 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   786 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   787 			}
       
   788 		}
       
   789 		else if (type == eap_configure_type_boolean)
       
   790 		{
       
   791 			u32_t uint_value = static_cast<u32_t>(~0);
       
   792 			
       
   793 			if (!m_am_tools->memcmp(
       
   794 					expanded_value_buffer.get_data(expanded_value_buffer.get_data_length()),
       
   795 					EAP_FILECONFIG_TRUE,
       
   796 					expanded_value_buffer.get_data_length()))
       
   797 			{
       
   798 				// OK, true
       
   799 				uint_value = 1u;
       
   800 			}
       
   801 			else if (!m_am_tools->memcmp(
       
   802 						 expanded_value_buffer.get_data(expanded_value_buffer.get_data_length()),
       
   803 						 EAP_FILECONFIG_FALSE,
       
   804 						 expanded_value_buffer.get_data_length()))
       
   805 			{
       
   806 				// OK, false
       
   807 				uint_value = 0u;
       
   808 			}
       
   809 			else
       
   810 			{
       
   811 #if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
   812 				printf("ERROR: CONFIG: illegal boolean value %s\n",
       
   813 					   expanded_value_buffer.get_data(expanded_value_buffer.get_data_length()));
       
   814 #endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
   815 				
       
   816 				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
   817 								(EAPL("ERROR: CONFIG: illegal boolean value %s\n"),
       
   818 								 expanded_value_buffer.get_data(expanded_value_buffer.get_data_length())));
       
   819 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
   820 			}
       
   821 			
       
   822 			status = value_data->set_copy_of_buffer(
       
   823 				&uint_value,
       
   824 				sizeof(uint_value));
       
   825 			if (status != eap_status_ok)
       
   826 			{
       
   827 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   828 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   829 			}
       
   830 		}
       
   831 		else if (type == eap_configure_type_string)
       
   832 		{
       
   833 			status = value_data->set_copy_of_buffer(
       
   834 				&expanded_value_buffer);
       
   835 			if (status != eap_status_ok)
       
   836 			{
       
   837 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   838 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   839 			}
       
   840 		}
       
   841 		else if (type == eap_configure_type_hex_data)
       
   842 		{
       
   843 			status = remove_spaces(&expanded_value_buffer);
       
   844 			if (status != eap_status_ok)
       
   845 			{
       
   846 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   847 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   848 			}
       
   849 			
       
   850 			u8_t * cursor = expanded_value_buffer.get_data(expanded_value_buffer.get_data_length());
       
   851 			const u8_t * const cursor_end = cursor + expanded_value_buffer.get_data_length();
       
   852 			
       
   853 			while(cursor < cursor_end)
       
   854 			{
       
   855 				u8_t hex_byte = 0;
       
   856 				cursor = read_hex_byte(
       
   857 					cursor,
       
   858 					cursor_end,
       
   859 					&hex_byte);
       
   860 				if (cursor == 0)
       
   861 				{
       
   862 					break;
       
   863 				}
       
   864 
       
   865 				status = value_data->add_data(&hex_byte, sizeof(hex_byte));
       
   866 				if (status != eap_status_ok)
       
   867 				{
       
   868 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   869 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   870 				}
       
   871 			}
       
   872 		}
       
   873 		else if (type == eap_configure_type_u32array)
       
   874 		{
       
   875 			status = remove_spaces(&expanded_value_buffer);
       
   876 			if (status != eap_status_ok)
       
   877 			{
       
   878 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   879 				return EAP_STATUS_RETURN(m_am_tools, status);
       
   880 			}
       
   881 			
       
   882 			u8_t * cursor = expanded_value_buffer.get_data(expanded_value_buffer.get_data_length());
       
   883 			const u8_t * const cursor_end = cursor + expanded_value_buffer.get_data_length();
       
   884 			
       
   885 			while(cursor < cursor_end)
       
   886 			{
       
   887 				u32_t integer = 0;
       
   888 				cursor = read_u32_t(
       
   889 					cursor,
       
   890 					cursor_end,
       
   891 					&integer);
       
   892 				if (cursor == 0)
       
   893 				{
       
   894 					break;
       
   895 				}
       
   896 
       
   897 				status = value_data->add_data(&integer, sizeof(integer));
       
   898 				if (status != eap_status_ok)
       
   899 				{
       
   900 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
   901 					return EAP_STATUS_RETURN(m_am_tools, status);
       
   902 				}
       
   903 			}
       
   904 		}
       
   905 		else
       
   906 		{
       
   907 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
   908 		}
       
   909 
       
   910 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   911 }
       
   912 
       
   913 
       
   914 //-----------------------------------------------------------------
       
   915 
       
   916 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::store_configure(
       
   917 	abs_eap_am_file_input_c * const file,
       
   918 	const eap_variable_data_c * const line,
       
   919 	eap_core_map_c<eap_config_value_c, abs_eap_core_map_c, eap_variable_data_c> * const config_map)
       
   920 {
       
   921 	eap_status_e status = eap_status_process_general_error;
       
   922 	
       
   923 	eap_variable_data_c name_buffer(m_am_tools);
       
   924 	if (name_buffer.get_is_valid() == false)
       
   925 	{
       
   926 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   927 	}
       
   928 
       
   929 	eap_variable_data_c value_buffer(m_am_tools);
       
   930 	if (value_buffer.get_is_valid() == false)
       
   931 	{
       
   932 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   933 	}
       
   934 
       
   935 	eap_variable_data_c value_data(m_am_tools);
       
   936 	if (value_data.get_is_valid() == false)
       
   937 	{
       
   938 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
   939 	}
       
   940 
       
   941 
       
   942 	status = name_buffer.set_buffer_length(MAX_LINE_LENGTH);
       
   943 	if (status != eap_status_ok)
       
   944 	{
       
   945 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   946 	}
       
   947 	name_buffer.set_data_length(0ul);
       
   948 
       
   949 	status = value_buffer.set_buffer_length(MAX_LINE_LENGTH);
       
   950 	if (status != eap_status_ok)
       
   951 	{
       
   952 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   953 	}
       
   954 	value_buffer.set_data_length(0ul);
       
   955 
       
   956 	eap_configure_type_e type = eap_configure_type_none;
       
   957 
       
   958 	if (line->compare(
       
   959 			EAP_FILECONFIG_SECTION_END,
       
   960 			EAP_FILECONFIG_SECTION_END_LENGTH) == 0)
       
   961 	{
       
   962 		EAP_TRACE_DEBUG(
       
   963 			m_am_tools,
       
   964 			TRACE_FLAGS_DEFAULT,
       
   965 			(EAPL("CONFIG: section ends.\n")));
       
   966 		return EAP_STATUS_RETURN(m_am_tools, eap_status_section_ends);
       
   967 	}
       
   968 
       
   969 	status = cnf_get_string(
       
   970 		line,
       
   971 		&name_buffer,
       
   972 		&value_buffer,
       
   973 		&type);
       
   974 	if (status != eap_status_ok)
       
   975 	{
       
   976 		return EAP_STATUS_RETURN(m_am_tools, status);
       
   977 	}
       
   978 
       
   979 
       
   980 	if (name_buffer.compare_length(
       
   981 			EAP_FILECONFIG_SECTION,
       
   982 			EAP_FILECONFIG_SECTION_LENGTH,
       
   983 			EAP_FILECONFIG_SECTION_LENGTH) == 0)
       
   984 	{
       
   985 		EAP_TRACE_DEBUG(
       
   986 			m_am_tools,
       
   987 			TRACE_FLAGS_DEFAULT,
       
   988 			(EAPL("CONFIG: section %s.\n"),
       
   989 			 name_buffer.get_data(name_buffer.get_data_length())));
       
   990 
       
   991 		status = name_buffer.set_start_offset(EAP_FILECONFIG_SECTION_LENGTH);
       
   992 		if (status != eap_status_ok)
       
   993 		{
       
   994 			return EAP_STATUS_RETURN(m_am_tools, status);
       
   995 		}
       
   996 
       
   997 		eap_core_map_c<eap_config_value_c,
       
   998 			abs_eap_core_map_c,
       
   999 			eap_variable_data_c> * const section_map
       
  1000 			= new eap_core_map_c<
       
  1001 			eap_config_value_c,
       
  1002 			abs_eap_core_map_c,
       
  1003 			eap_variable_data_c>(m_am_tools, this);
       
  1004 
       
  1005 		eap_automatic_variable_c<eap_core_map_c<
       
  1006 			eap_config_value_c,
       
  1007 			abs_eap_core_map_c,
       
  1008 			eap_variable_data_c> >
       
  1009 			automatic_section_map(m_am_tools, section_map);
       
  1010 
       
  1011 		if (section_map == 0
       
  1012 			|| section_map->get_is_valid() == false)
       
  1013 		{
       
  1014 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1015 		}
       
  1016 
       
  1017 		status = read_section(file, section_map);
       
  1018 		if (status == eap_status_section_ends)
       
  1019 		{
       
  1020 			// Add subsection.
       
  1021 			eap_config_value_c * config = new eap_config_value_c(m_am_tools);
       
  1022 
       
  1023 			eap_automatic_variable_c<eap_config_value_c>
       
  1024 				automatic_config(m_am_tools, config);
       
  1025 
       
  1026 			if (config == 0
       
  1027 				|| config->get_is_valid() == false)
       
  1028 			{
       
  1029 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1030 			}
       
  1031 			
       
  1032 			config->set_type(eap_configure_type_subsection);
       
  1033 
       
  1034 			config->set_subsection(section_map);
       
  1035 			automatic_section_map.do_not_free_variable();
       
  1036 			
       
  1037 			status = convert_value(
       
  1038 				&m_config_map, // Note here we use the global name space.
       
  1039 				&value_buffer,
       
  1040 				type,
       
  1041 				&value_data);
       
  1042 			if (status != eap_status_ok)
       
  1043 			{
       
  1044 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1045 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1046 			}
       
  1047 
       
  1048 			{
       
  1049 				// selector of the section is <name_buffer>:<value_data>.
       
  1050 				// section:example=string:match => example:match
       
  1051 				status = name_buffer.add_data(
       
  1052 					EAP_FILECONFIG_SECTION_SEPARATOR,
       
  1053 					EAP_FILECONFIG_SECTION_SEPARATOR_LENGTH);
       
  1054 				if (status != eap_status_ok)
       
  1055 				{
       
  1056 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1057 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  1058 				}
       
  1059 
       
  1060 				status = name_buffer.add_data(&value_data);
       
  1061 				if (status != eap_status_ok)
       
  1062 				{
       
  1063 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1064 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  1065 				}
       
  1066 
       
  1067 				status = name_buffer.add_end_null();
       
  1068 				if (status != eap_status_ok)
       
  1069 				{
       
  1070 					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1071 					return EAP_STATUS_RETURN(m_am_tools, status);
       
  1072 				}
       
  1073 			}
       
  1074 
       
  1075 			eap_variable_data_c selector(m_am_tools);
       
  1076 			if (selector.get_is_valid() == false)
       
  1077 			{
       
  1078 				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1079 			}
       
  1080 
       
  1081 			status = selector.set_copy_of_buffer(
       
  1082 				name_buffer.get_data(),
       
  1083 				name_buffer.get_data_length());
       
  1084 			if (status != eap_status_ok)
       
  1085 			{
       
  1086 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1087 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1088 			}
       
  1089 
       
  1090 			status = config_map->add_handler(&selector, config);
       
  1091 			if (status == eap_status_ok)
       
  1092 			{
       
  1093 				automatic_config.do_not_free_variable();
       
  1094 			}
       
  1095 			else if (status == eap_status_handler_exists_error)
       
  1096 			{
       
  1097 				// This is dublicate subsection.
       
  1098 				// We will skip this.
       
  1099 				EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  1100 								(EAPL("ERROR: CONFIG: section %s is already defined.\n"),
       
  1101 								 name_buffer.get_data(name_buffer.get_data_length())));
       
  1102 
       
  1103 				return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1104 			}
       
  1105 			else if (status != eap_status_ok)
       
  1106 			{
       
  1107 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1108 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1109 			}
       
  1110 
       
  1111 			EAP_TRACE_DATA_DEBUG(
       
  1112 				m_am_tools, 
       
  1113 				TRACE_FLAGS_DEFAULT, 
       
  1114 				(EAPL("CONFIG: subsection name"), 
       
  1115 				 name_buffer.get_data(), 
       
  1116 				 name_buffer.get_data_length()));
       
  1117 
       
  1118 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1119 		}
       
  1120 		else
       
  1121 		{
       
  1122 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1123 		}
       
  1124 	}
       
  1125 	else
       
  1126 	{
       
  1127 		EAP_TRACE_DEBUG(
       
  1128 			m_am_tools,
       
  1129 			TRACE_FLAGS_CONFIGURE_DATA,
       
  1130 			(EAPL("CONFIG: check subsection %s.\n"),
       
  1131 			 name_buffer.get_data(name_buffer.get_data_length())));
       
  1132 
       
  1133 		eap_configuration_field_template_c<MAX_LINE_LENGTH> * const tmp_name
       
  1134 			= new eap_configuration_field_template_c<MAX_LINE_LENGTH>;
       
  1135 	
       
  1136 		eap_automatic_variable_c<eap_configuration_field_template_c<MAX_LINE_LENGTH> >
       
  1137 			automatic_tmp_name(m_am_tools, tmp_name);
       
  1138 	
       
  1139 		if (tmp_name == 0
       
  1140 			|| tmp_name->get_is_valid() == false)
       
  1141 		{
       
  1142 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1143 		}
       
  1144 
       
  1145 		status = tmp_name->set_fields(
       
  1146 			m_am_tools,
       
  1147 			name_buffer.get_data(name_buffer.get_data_length()),
       
  1148 			type,
       
  1149 			false);
       
  1150 		if (status != eap_status_ok)
       
  1151 		{
       
  1152 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1153 		}
       
  1154 
       
  1155 		eap_variable_data_c check(m_am_tools);
       
  1156 		if (check.get_is_valid() == false)
       
  1157 		{
       
  1158 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1159 		}
       
  1160 
       
  1161 		status = read_configure(
       
  1162 			config_map,
       
  1163 			tmp_name->get_field(),
       
  1164 			&check,
       
  1165 			&type,
       
  1166 			true);
       
  1167 		if (status == eap_status_ok)
       
  1168 		{
       
  1169 			status = name_buffer.add_end_null();
       
  1170 			if (status != eap_status_ok)
       
  1171 			{
       
  1172 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1173 			}
       
  1174 			// This subsection is already defined.
       
  1175 #if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
  1176 			printf("WARNING: CONFIG: subsection %s is already defined.\n",
       
  1177 				   name_buffer.get_data(name_buffer.get_data_length()));
       
  1178 #endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
  1179 			
       
  1180 			EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  1181 							(EAPL("WARNING: CONFIG: subsection %s is already defined.\n"),
       
  1182 							 name_buffer.get_data(name_buffer.get_data_length())));
       
  1183 
       
  1184 			// We will skip the dublicate section.
       
  1185 			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1186 		}
       
  1187 
       
  1188 		//-------------------------------------------------------------------------------
       
  1189 
       
  1190 		eap_config_value_c * config = new eap_config_value_c(m_am_tools);
       
  1191 
       
  1192 		eap_automatic_variable_c<eap_config_value_c>
       
  1193 			automatic_config(m_am_tools, config);
       
  1194 
       
  1195 		if (config == 0
       
  1196 			|| config->get_is_valid() == false)
       
  1197 		{
       
  1198 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1199 		}
       
  1200 
       
  1201 		config->set_type(type);
       
  1202 
       
  1203 		status = convert_value(
       
  1204 			&m_config_map, // Note here we use the global name space.
       
  1205 			&value_buffer,
       
  1206 			type,
       
  1207 			&value_data);
       
  1208 		if (status != eap_status_ok)
       
  1209 		{
       
  1210 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1211 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1212 		}
       
  1213 
       
  1214 		status = config->get_data()->set_copy_of_buffer(
       
  1215 			&value_data);
       
  1216 		if (status != eap_status_ok)
       
  1217 		{
       
  1218 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1219 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1220 		}
       
  1221 
       
  1222 		eap_variable_data_c selector(m_am_tools);
       
  1223 		if (selector.get_is_valid() == false)
       
  1224 		{
       
  1225 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1226 		}
       
  1227 
       
  1228 		status = selector.set_copy_of_buffer(
       
  1229 			tmp_name->get_field()->get_field(),
       
  1230 			tmp_name->get_field()->get_field_length());
       
  1231 		if (status != eap_status_ok)
       
  1232 		{
       
  1233 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1234 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1235 		}
       
  1236 		
       
  1237 		status = config_map->add_handler(&selector, config);
       
  1238 		if (status == eap_status_ok)
       
  1239 		{
       
  1240 			automatic_config.do_not_free_variable();
       
  1241 		}
       
  1242 		else //if (status != eap_status_ok)
       
  1243 		{
       
  1244 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1245 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1246 		}
       
  1247 
       
  1248 		EAP_TRACE_DATA_DEBUG(
       
  1249 			m_am_tools,
       
  1250 			TRACE_FLAGS_DEFAULT,
       
  1251 			(EAPL("CONFIG: option added"),
       
  1252 			 tmp_name->get_field()->get_field(),
       
  1253 			 tmp_name->get_field()->get_field_length()));
       
  1254 		
       
  1255 		EAP_TRACE_DATA_DEBUG(
       
  1256 			m_am_tools, 
       
  1257 			TRACE_FLAGS_DEFAULT, 
       
  1258 			(EAPL("CONFIG: data"), 
       
  1259 			 config->get_data()->get_data(), 
       
  1260 			 config->get_data()->get_data_length()));
       
  1261 
       
  1262 		//-----------------------------------------------------------------------------
       
  1263 
       
  1264 	}
       
  1265 
       
  1266 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1267 }
       
  1268 
       
  1269 //-----------------------------------------------------------------
       
  1270 
       
  1271 eap_status_e eap_file_config_c::find_rvalue(
       
  1272 	const eap_variable_data_c * const config_param,
       
  1273 	bool * const read_env_value,
       
  1274 	eap_variable_data_c * const param_name,
       
  1275 	eap_variable_data_c * const param_value
       
  1276 	)
       
  1277 {
       
  1278 	const u8_t * rvalue = 0;
       
  1279 	const u8_t *env_value = 0;
       
  1280 
       
  1281 	if (config_param == 0
       
  1282 		|| read_env_value == 0
       
  1283 		|| param_name == 0
       
  1284 		|| param_value == 0)
       
  1285 	{
       
  1286 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1287 	}
       
  1288 
       
  1289 	const u8_t * const param = config_param->get_data(config_param->get_data_length());
       
  1290 	if (param == 0)
       
  1291 	{
       
  1292 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1293 	}
       
  1294 
       
  1295 	const u8_t * const param_end
       
  1296 		= config_param->get_data(config_param->get_data_length())
       
  1297 		+ config_param->get_data_length();
       
  1298 	if (param_end == 0)
       
  1299 	{
       
  1300 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1301 	}
       
  1302 
       
  1303 	for (rvalue = param; *rvalue; rvalue++)
       
  1304 	{
       
  1305 		if (*rvalue == '=')
       
  1306 		{
       
  1307 			break;
       
  1308 		}
       
  1309 	}
       
  1310 	
       
  1311 	if (*rvalue == 0)
       
  1312 	{
       
  1313 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1314 	}
       
  1315 
       
  1316 	// Check are there defined environment variable to override the file configuration.
       
  1317 	{
       
  1318 		// backup spaces.
       
  1319 		const u8_t *tmp_param_end = rvalue;
       
  1320 
       
  1321 		for (tmp_param_end--
       
  1322 				 ; m_am_tools->isspace(*tmp_param_end)
       
  1323 				 || *tmp_param_end == '\r'
       
  1324 				 || *tmp_param_end == '\n'
       
  1325 				 || *tmp_param_end == '='
       
  1326 				 ; tmp_param_end--)
       
  1327 		{
       
  1328 			/* empty */
       
  1329 		}
       
  1330 
       
  1331 		tmp_param_end++;
       
  1332 		u32_t length = tmp_param_end - param;
       
  1333 
       
  1334 
       
  1335 		eap_status_e status = param_name->add_data(param, length);
       
  1336 		if (status != eap_status_ok)
       
  1337 		{
       
  1338 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1339 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1340 		}
       
  1341 		status = param_name->add_end_null();
       
  1342 		if (status != eap_status_ok)
       
  1343 		{
       
  1344 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1345 		}
       
  1346 
       
  1347 		eap_variable_data_c env_value_buffer(m_am_tools);
       
  1348 		if (env_value_buffer.get_is_valid() == false)
       
  1349 		{
       
  1350 			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1351 		}
       
  1352 
       
  1353 		eap_status_e env_status = m_am_tools->getenv(
       
  1354 			param_name,
       
  1355 			&env_value_buffer);
       
  1356 		if (env_status == eap_status_ok)
       
  1357 		{
       
  1358 			env_value = env_value_buffer.get_data(env_value_buffer.get_data_length());
       
  1359 		}
       
  1360 		else
       
  1361 		{
       
  1362 			env_value = 0;
       
  1363 		}
       
  1364 
       
  1365 		if (env_value != 0)
       
  1366 		{
       
  1367 			rvalue = env_value;
       
  1368 			length = m_am_tools->strlen(reinterpret_cast<const char *>(rvalue));
       
  1369 			*read_env_value = true;
       
  1370 		}
       
  1371 		else
       
  1372 		{
       
  1373 			rvalue = tmp_param_end;
       
  1374 
       
  1375 			for (; *rvalue; rvalue++)
       
  1376 			{
       
  1377 				if (*rvalue == '=')
       
  1378 				{
       
  1379 					break;
       
  1380 				}
       
  1381 			}
       
  1382 			
       
  1383 			for (rvalue++; m_am_tools->isspace(*rvalue) || *rvalue == '\r' || *rvalue == '\n'; rvalue++){
       
  1384 				/* empty */
       
  1385 			}
       
  1386 
       
  1387 			if (*rvalue == 0)
       
  1388 			{
       
  1389 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1390 			}
       
  1391 
       
  1392 			length = param_end - rvalue;
       
  1393 		}
       
  1394 
       
  1395 		// There is overriding environment variable.
       
  1396 		status = param_value->set_copy_of_buffer(rvalue, length);
       
  1397 		if (status != eap_status_ok)
       
  1398 		{
       
  1399 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1400 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1401 		}
       
  1402 		status = param_value->add_end_null();
       
  1403 		if (status != eap_status_ok)
       
  1404 		{
       
  1405 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1406 		}
       
  1407 	}
       
  1408 
       
  1409 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1410 }
       
  1411 
       
  1412 //-----------------------------------------------------------------
       
  1413 
       
  1414 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::cnf_parse_value(
       
  1415 	const eap_variable_data_c * const found_type_value,
       
  1416 	const eap_variable_data_c * const found_type_name,
       
  1417 	eap_configure_type_e * const parsed_type,
       
  1418 	eap_variable_data_c * const parsed_type_value,
       
  1419 	const bool is_environment_variable)
       
  1420 {
       
  1421 	if (found_type_value == 0
       
  1422 		|| found_type_name == 0
       
  1423 		|| parsed_type == 0
       
  1424 		|| parsed_type_value == 0)
       
  1425 	{
       
  1426 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1427 	}
       
  1428 
       
  1429 	*parsed_type = eap_configure_type_none;
       
  1430 
       
  1431 	u32_t ind;
       
  1432 	for (ind = 0u; ind < sizeof(eap_configure_type_id)/sizeof(eap_configure_type_id[0]); ind++)
       
  1433 	{
       
  1434 		if (!m_am_tools->memcmp(
       
  1435 				eap_configure_type_id[ind].id,
       
  1436 				found_type_value->get_data(found_type_value->get_data_length()),
       
  1437 				eap_configure_type_id[ind].id_length))
       
  1438 		{
       
  1439 			*parsed_type = eap_configure_type_id[ind].type;
       
  1440 			break;
       
  1441 		}
       
  1442 	}
       
  1443 
       
  1444 	u32_t value_length = found_type_value->get_data_length();
       
  1445 
       
  1446 	eap_variable_data_c tmp_buffer(m_am_tools);
       
  1447 	if (tmp_buffer.get_is_valid() == false)
       
  1448 	{
       
  1449 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1450 	}
       
  1451 
       
  1452 	eap_status_e status = tmp_buffer.set_buffer_length(MAX_LINE_LENGTH);
       
  1453 	if (status != eap_status_ok)
       
  1454 	{
       
  1455 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1456 	}
       
  1457 	tmp_buffer.set_data_length(MAX_LINE_LENGTH);
       
  1458 
       
  1459 	u8_t * const tmp_value_buffer = tmp_buffer.get_buffer(MAX_LINE_LENGTH);
       
  1460 	if (tmp_value_buffer == 0)
       
  1461 	{
       
  1462 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1463 	}
       
  1464 
       
  1465 	const u8_t * used_type_value = found_type_value->get_data(found_type_value->get_data_length());
       
  1466 	if (used_type_value == 0)
       
  1467 	{
       
  1468 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1469 	}
       
  1470 
       
  1471 	if (*parsed_type == eap_configure_type_none)
       
  1472 	{
       
  1473 		// No type defined.
       
  1474 		if (is_environment_variable == true)
       
  1475 		{
       
  1476 			// Environment variable without type is handled as a string type.
       
  1477 			*parsed_type = eap_configure_type_string;
       
  1478 			ind = *parsed_type;
       
  1479 			m_am_tools->memmove(
       
  1480 				tmp_value_buffer,
       
  1481 				eap_configure_type_id[ind].id,
       
  1482 				eap_configure_type_id[ind].id_length);
       
  1483 			m_am_tools->memmove(
       
  1484 				tmp_value_buffer+eap_configure_type_id[ind].id_length,
       
  1485 				found_type_value->get_data(found_type_value->get_data_length()),
       
  1486 				value_length);
       
  1487 			value_length = eap_configure_type_id[ind].id_length+value_length;
       
  1488 			tmp_value_buffer[value_length] = 0;
       
  1489 			used_type_value = tmp_value_buffer;
       
  1490 		}
       
  1491 		else
       
  1492 		{
       
  1493 			#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
  1494 				printf("ERROR: CONFIG: no subsection type: %s=%s\n",
       
  1495 					found_type_name->get_data(found_type_name->get_data_length()),
       
  1496 					found_type_value->get_data(found_type_value->get_data_length()));
       
  1497 			#endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
  1498 
       
  1499 			EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  1500 							(EAPL("ERROR: CONFIG: no subsection type: %s=%s\n"),
       
  1501 							found_type_name->get_data(found_type_name->get_data_length()),
       
  1502 							found_type_value->get_data(found_type_value->get_data_length())));
       
  1503 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
  1504 		}
       
  1505 	}
       
  1506 
       
  1507 
       
  1508 	const u8_t * value_end = used_type_value+value_length;
       
  1509 
       
  1510 	// Remove separator and spaces.
       
  1511 	for (value_end--
       
  1512 			 ; used_type_value < value_end
       
  1513 			 && (m_am_tools->isspace(*value_end)
       
  1514 				 || *value_end == '='
       
  1515 				 || *value_end == '\r'
       
  1516 				 || *value_end == '\n')
       
  1517 			 ; value_end--)
       
  1518 	{
       
  1519 		/* empty */
       
  1520 		--value_length;
       
  1521 	}
       
  1522 	++value_end;
       
  1523 
       
  1524 	const u32_t tmp_length = value_end - used_type_value;
       
  1525 
       
  1526 	u32_t len = tmp_length - eap_configure_type_id[ind].id_length;
       
  1527 
       
  1528 	status = parsed_type_value->add_data(
       
  1529 		used_type_value+eap_configure_type_id[ind].id_length,
       
  1530 		len);
       
  1531 	if (status != eap_status_ok)
       
  1532 	{
       
  1533 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1534 	}
       
  1535 
       
  1536 	status = parsed_type_value->add_end_null();
       
  1537 	if (status != eap_status_ok)
       
  1538 	{
       
  1539 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1540 	}
       
  1541 	
       
  1542 	if (is_environment_variable == true)
       
  1543 	{
       
  1544 		#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
  1545 			printf("CONFIG: %s=%s%s; from environment variable\n",
       
  1546 				   found_type_name->get_data(found_type_name->get_data_length()),
       
  1547 				   eap_configure_type_id[ind].id,
       
  1548 				   parsed_type_value->get_data(parsed_type_value->get_data_length()));
       
  1549 		#endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
  1550 
       
  1551 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  1552 						(EAPL("CONFIG: %s=%s%s; from environment variable\n"),
       
  1553 						 found_type_name->get_data(found_type_name->get_data_length()),
       
  1554 						 eap_configure_type_id[ind].id,
       
  1555 						 parsed_type_value->get_data(parsed_type_value->get_data_length())));
       
  1556 	}
       
  1557 	else
       
  1558 	{
       
  1559 		#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
  1560 			printf("CONFIG: %s=%s%s\n",
       
  1561 				   found_type_name->get_data(found_type_name->get_data_length()),
       
  1562 				   eap_configure_type_id[ind].id,
       
  1563 				   parsed_type_value->get_data(parsed_type_value->get_data_length()));
       
  1564 		#endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
  1565 
       
  1566 		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
       
  1567 						(EAPL("CONFIG: %s=%s%s\n"),
       
  1568 						 found_type_name->get_data(found_type_name->get_data_length()),
       
  1569 						 eap_configure_type_id[ind].id,
       
  1570 						 parsed_type_value->get_data(parsed_type_value->get_data_length())));
       
  1571 	}
       
  1572 	
       
  1573 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1574 }
       
  1575 
       
  1576 //-----------------------------------------------------------------
       
  1577 
       
  1578 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::cnf_get_string(
       
  1579 	const eap_variable_data_c * const param,
       
  1580 	eap_variable_data_c * const param_name,
       
  1581 	eap_variable_data_c * const param_value,
       
  1582 	eap_configure_type_e * const type)
       
  1583 {
       
  1584 	if (param == 0
       
  1585 		|| param_name == 0
       
  1586 		|| param_value == 0
       
  1587 		|| type == 0)
       
  1588 	{
       
  1589 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1590 	}
       
  1591 
       
  1592 	bool env_value = false;
       
  1593 
       
  1594 	*type = eap_configure_type_none;
       
  1595 
       
  1596 	// Returned value could be pointer to environment value.
       
  1597 	// Do not modify returned value.
       
  1598 	eap_status_e status = find_rvalue(
       
  1599 		param,
       
  1600 		&env_value,
       
  1601 		param_name,
       
  1602 		param_value
       
  1603 		);
       
  1604 	
       
  1605 	if (status != eap_status_ok)
       
  1606 	{
       
  1607 		#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
  1608 			printf("ERROR: CONFIG: illegal subsection: %s\n",
       
  1609 				   param->get_data(param->get_data_length()));
       
  1610 		#endif //#if defined(EAP_FILE_CONFIG_USE_CONSOLE_PRINTS)
       
  1611 
       
  1612 		EAP_TRACE_DEBUG(
       
  1613 			m_am_tools,
       
  1614 			TRACE_FLAGS_DEFAULT,
       
  1615 			(EAPL("ERROR: CONFIG: illegal subsection: %s\n"),
       
  1616 			 param->get_data(param->get_data_length())));
       
  1617 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
  1618 	}
       
  1619 
       
  1620 	eap_variable_data_c parsed_value(m_am_tools);
       
  1621 	if (parsed_value.get_is_valid() == false)
       
  1622 	{
       
  1623 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1624 	}
       
  1625 
       
  1626 	status = cnf_parse_value(
       
  1627 		param_value,
       
  1628 		param_name,
       
  1629 		type,
       
  1630 		&parsed_value,
       
  1631 		env_value);
       
  1632 	if (status != eap_status_ok)
       
  1633 	{
       
  1634 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1635 	}
       
  1636 
       
  1637 	status = param_value->set_copy_of_buffer(&parsed_value);
       
  1638 	if (status != eap_status_ok)
       
  1639 	{
       
  1640 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1641 	}
       
  1642 
       
  1643 	status = param_value->add_end_null();
       
  1644 	if (status != eap_status_ok)
       
  1645 	{
       
  1646 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1647 	}
       
  1648 
       
  1649 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1650 }
       
  1651 
       
  1652 //-----------------------------------------------------------------
       
  1653 
       
  1654 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::read_subsections(
       
  1655 	abs_eap_am_file_input_c * const file,
       
  1656 	eap_core_map_c<eap_config_value_c, abs_eap_core_map_c, eap_variable_data_c> * const config_map)
       
  1657 {
       
  1658 	eap_variable_data_c line(m_am_tools);
       
  1659 	if (line.get_is_valid() == false)
       
  1660 	{
       
  1661 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1662 	}
       
  1663 
       
  1664 	eap_status_e status = eap_status_ok;
       
  1665 
       
  1666 	// This sets the pre-allocated buffer.
       
  1667 	status = line.set_buffer_length(MAX_LINE_LENGTH);
       
  1668 
       
  1669 	for (;status == eap_status_ok;)
       
  1670 	{
       
  1671 		status = get_subsect(file, &line);
       
  1672 		if (status == eap_status_end_of_file)
       
  1673 		{
       
  1674 			// End of file reached.
       
  1675 			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1676 		}
       
  1677 		else if (status != eap_status_ok)
       
  1678 		{
       
  1679 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1680 		}
       
  1681 
       
  1682 		status = store_configure(file, &line, config_map);
       
  1683 	}
       
  1684 
       
  1685 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1686 }
       
  1687 
       
  1688 //-----------------------------------------------------------------
       
  1689 
       
  1690 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::read_section(
       
  1691 	abs_eap_am_file_input_c * const file,
       
  1692 	eap_core_map_c<eap_config_value_c, abs_eap_core_map_c, eap_variable_data_c> * const config_map)
       
  1693 {
       
  1694 	eap_variable_data_c line(m_am_tools);
       
  1695 	if (line.get_is_valid() == false)
       
  1696 	{
       
  1697 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1698 	}
       
  1699 
       
  1700 	eap_status_e status = eap_status_ok;
       
  1701 
       
  1702 	// This sets the pre-allocated buffer.
       
  1703 	status = line.set_buffer_length(MAX_LINE_LENGTH);
       
  1704 
       
  1705 	while (status == eap_status_ok)
       
  1706 	{
       
  1707 		status = get_subsect(file, &line);
       
  1708 		if (status == eap_status_end_of_file)
       
  1709 		{
       
  1710 			// End of file reached.
       
  1711 			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1712 		}
       
  1713 		else if (status != eap_status_ok)
       
  1714 		{
       
  1715 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1716 		}
       
  1717 
       
  1718 		if (line.compare(
       
  1719 				EAP_FILECONFIG_SECTION_START,
       
  1720 				EAP_FILECONFIG_SECTION_START_LENGTH) == 0)
       
  1721 		{
       
  1722 			// Starts new section block.
       
  1723 			status = read_subsections(
       
  1724 				file,
       
  1725 				config_map);
       
  1726 
       
  1727 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1728 		}
       
  1729 		else
       
  1730 		{
       
  1731 			EAP_TRACE_DEBUG(
       
  1732 				m_am_tools,
       
  1733 				TRACE_FLAGS_DEFAULT,
       
  1734 				(EAPL("ERROR: CONFIG: section start '{' is missing.\n")));
       
  1735 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
  1736 		}
       
  1737 	}
       
  1738 
       
  1739 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1740 }
       
  1741 
       
  1742 //-----------------------------------------------------------------
       
  1743 
       
  1744 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::remove_spaces(eap_variable_data_c * const buffer)
       
  1745 {
       
  1746 	eap_variable_data_c tmp(m_am_tools);
       
  1747 	if (tmp.get_is_valid() == false)
       
  1748 	{
       
  1749 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1750 	}
       
  1751 
       
  1752 	eap_status_e status(eap_status_ok);
       
  1753 
       
  1754 	for (u32_t ind = 0ul; ind < buffer->get_data_length(); ind++)
       
  1755 	{
       
  1756 		u8_t * const character = buffer->get_data_offset(ind, sizeof(u8_t));
       
  1757 		if (character == 0)
       
  1758 		{
       
  1759 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1760 		}
       
  1761 
       
  1762 		if (m_am_tools->isspace(*character) == false)
       
  1763 		{
       
  1764 			status = tmp.add_data(character, sizeof(*character));
       
  1765 			if (status != eap_status_ok)
       
  1766 			{
       
  1767 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1768 			}
       
  1769 		}
       
  1770 	} // for()
       
  1771 
       
  1772 	status = buffer->set_copy_of_buffer(&tmp);
       
  1773 
       
  1774 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1775 }
       
  1776 
       
  1777 //-----------------------------------------------------------------
       
  1778 
       
  1779 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::remove_leading_spaces(
       
  1780 	eap_variable_data_c * const line)
       
  1781 {
       
  1782 	if (line->get_data_length() == 0)
       
  1783 	{
       
  1784 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1785 		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1786 	}
       
  1787 
       
  1788 	u8_t * const begin = line->get_data(line->get_data_length());
       
  1789 	if(begin == 0)
       
  1790 	{
       
  1791 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1792 		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  1793 	}
       
  1794 
       
  1795 	for (u32_t ind = 0; ind < line->get_data_length(); ind++)
       
  1796 	{
       
  1797 		if (begin[ind] != ' '
       
  1798 			&& begin[ind] != '\t')
       
  1799 		{
       
  1800 			eap_status_e status = line->set_start_offset(ind);
       
  1801 			if (status != eap_status_ok)
       
  1802 			{
       
  1803 				return EAP_STATUS_RETURN(m_am_tools, status);
       
  1804 			}
       
  1805 			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1806 		}
       
  1807 	}
       
  1808 
       
  1809 	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
       
  1810 }
       
  1811 
       
  1812 //-----------------------------------------------------------------
       
  1813 
       
  1814 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::file_read_line(
       
  1815 	abs_eap_am_file_input_c * const file,
       
  1816 	eap_variable_data_c * const line)
       
  1817 {
       
  1818 	eap_status_e status(eap_status_ok);
       
  1819 	bool line_continues(true);
       
  1820 
       
  1821 	eap_variable_data_c tmp_line(m_am_tools);
       
  1822 	if (tmp_line.get_is_valid() == false)
       
  1823 	{
       
  1824 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  1825 	}
       
  1826 
       
  1827 	const u32_t TMP_LINE_BUFFER_INITIAL_LENGTH = 256ul;
       
  1828 
       
  1829 	status = tmp_line.set_buffer_length(TMP_LINE_BUFFER_INITIAL_LENGTH);
       
  1830 	if (status != eap_status_ok)
       
  1831 	{
       
  1832 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1833 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1834 	}
       
  1835 
       
  1836 
       
  1837 	// This is small optimization that does not free the old buffer.
       
  1838 	status = line->reset_start_offset_and_data_length();
       
  1839 	if (status != eap_status_ok)
       
  1840 	{
       
  1841 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1842 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  1843 	}
       
  1844 
       
  1845 
       
  1846 	do
       
  1847 	{
       
  1848 		status = tmp_line.reset_start_offset_and_data_length();
       
  1849 		if (status != eap_status_ok)
       
  1850 		{
       
  1851 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1852 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1853 		}
       
  1854 
       
  1855 		status = file->file_read_line(&tmp_line);
       
  1856 		if (status != eap_status_ok)
       
  1857 		{
       
  1858 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1859 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1860 		}
       
  1861 
       
  1862 		EAP_TRACE_DATA_DEBUG(
       
  1863 			m_am_tools, 
       
  1864 			TRACE_FLAGS_CONFIGURE_DATA,
       
  1865 			(EAPL("Configure line"), 
       
  1866 			 tmp_line.get_data(), 
       
  1867 			 tmp_line.get_data_length()));
       
  1868 
       
  1869 		status = remove_leading_spaces(&tmp_line);
       
  1870 		if (status != eap_status_ok)
       
  1871 		{
       
  1872 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1873 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1874 		}
       
  1875 
       
  1876 		EAP_TRACE_DATA_DEBUG(
       
  1877 			m_am_tools, 
       
  1878 			TRACE_FLAGS_CONFIGURE_DATA,
       
  1879 			(EAPL("No spaces line"), 
       
  1880 			 tmp_line.get_data(), 
       
  1881 			 tmp_line.get_data_length()));
       
  1882 
       
  1883 		if (tmp_line.get_data_length() > 0ul)
       
  1884 		{
       
  1885 			u8_t * last_char = tmp_line.get_buffer_offset(
       
  1886 				tmp_line.get_data_length() - 1ul,
       
  1887 				sizeof(u8_t));
       
  1888 
       
  1889 			if (last_char  != 0
       
  1890 				&& *last_char == '\\')
       
  1891 			{
       
  1892 				// If the last character in the line is '\' then the line continues to the next line.
       
  1893 				tmp_line.set_data_length(tmp_line.get_data_length() - 1ul);
       
  1894 			}
       
  1895 			else
       
  1896 			{
       
  1897 				line_continues = false;
       
  1898 			}
       
  1899 		}
       
  1900 		else
       
  1901 		{
       
  1902 			line_continues = false;
       
  1903 		}
       
  1904 
       
  1905 		status = line->add_data(&tmp_line);
       
  1906 		if (status != eap_status_ok)
       
  1907 		{
       
  1908 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1909 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1910 		}
       
  1911 
       
  1912 	} while(line_continues == true);
       
  1913 
       
  1914 
       
  1915 	EAP_TRACE_DATA_DEBUG(
       
  1916 		m_am_tools, 
       
  1917 		TRACE_FLAGS_CONFIGURE_DATA,
       
  1918 		(EAPL("Configure line"), 
       
  1919 		 tmp_line.get_data(), 
       
  1920 		 tmp_line.get_data_length()));
       
  1921 
       
  1922 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1923 }
       
  1924 
       
  1925 //-----------------------------------------------------------------
       
  1926 
       
  1927 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::get_subsect(
       
  1928 	abs_eap_am_file_input_c * const file,
       
  1929 	eap_variable_data_c * const line)
       
  1930 {
       
  1931 	if( file == 0
       
  1932 		|| line == 0)
       
  1933 	{
       
  1934 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1935 		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
       
  1936 	}
       
  1937 
       
  1938 	eap_status_e status(eap_status_ok);
       
  1939 	
       
  1940 	for(;status == eap_status_ok;)
       
  1941 	{
       
  1942 		status = file_read_line(file, line);
       
  1943 
       
  1944 		EAP_TRACE_DATA_DEBUG(
       
  1945 			m_am_tools, 
       
  1946 			TRACE_FLAGS_CONFIGURE_DATA,
       
  1947 			(EAPL("Configure line"), 
       
  1948 			 line->get_data(line->get_data_length()), 
       
  1949 			 line->get_data_length()));
       
  1950 
       
  1951 		// error or end of file
       
  1952 		if(status != eap_status_ok)
       
  1953 		{
       
  1954 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1955 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1956 		}
       
  1957 
       
  1958 		status = remove_leading_spaces(line);
       
  1959 		if(status != eap_status_ok)
       
  1960 		{
       
  1961 			// Skip this error.
       
  1962 			status = eap_status_ok;
       
  1963 			continue;
       
  1964 		}
       
  1965 
       
  1966 		// too short line, ignore
       
  1967 		if(line->get_data_length() < 1ul)
       
  1968 		{
       
  1969 			continue;
       
  1970 		}
       
  1971 
       
  1972 		u8_t * const result = line->get_data(line->get_data_length());
       
  1973 		if(result == 0)
       
  1974 		{
       
  1975 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1976 			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
       
  1977 		}
       
  1978 		
       
  1979 		// ignore the lines starting with newline, space, tab or '#'
       
  1980 		if ((*result == '\r')
       
  1981 			|| (*result == '\n')
       
  1982 			|| (*result == ' ')
       
  1983 			|| (*result == '\t')
       
  1984 			|| (*result == '#'))
       
  1985 		{
       
  1986 			continue;
       
  1987 		}
       
  1988 		else
       
  1989 		{
       
  1990 			// OK we get a line.
       
  1991 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1992 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  1993 		}
       
  1994 	}
       
  1995 
       
  1996 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  1997 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  1998 }
       
  1999 
       
  2000 //-----------------------------------------------------------------
       
  2001 
       
  2002 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::read_configure(
       
  2003 	eap_core_map_c<eap_config_value_c, abs_eap_core_map_c, eap_variable_data_c> * const config_map,
       
  2004 	const eap_configuration_field_c * const field,
       
  2005 	eap_variable_data_c* const data,
       
  2006 	eap_configure_type_e * const configuration_data_type,
       
  2007 	const bool existence_test)
       
  2008 {
       
  2009 	eap_status_e status = eap_status_process_general_error;
       
  2010 
       
  2011 	eap_variable_data_c selector(m_am_tools);
       
  2012 	if (selector.get_is_valid() == false)
       
  2013 	{
       
  2014 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2015 	}
       
  2016 
       
  2017 	status = selector.set_buffer(
       
  2018 		field->get_field(),
       
  2019 		field->get_field_length(),
       
  2020 		false,
       
  2021 		false);
       
  2022 	if (status != eap_status_ok)
       
  2023 	{
       
  2024 		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2025 		return EAP_STATUS_RETURN(m_am_tools, status);
       
  2026 	}
       
  2027 
       
  2028 	eap_config_value_c *config = config_map->get_handler(&selector);
       
  2029 
       
  2030 	if (config != 0)
       
  2031 	{
       
  2032 		status = data->set_copy_of_buffer(config->get_data());
       
  2033 
       
  2034 		if (status == eap_status_ok)
       
  2035 		{
       
  2036 			*configuration_data_type = config->get_type();
       
  2037 		}
       
  2038 		else
       
  2039 		{
       
  2040 			*configuration_data_type = eap_configure_type_none;
       
  2041 		}
       
  2042 	}
       
  2043 	else
       
  2044 	{
       
  2045 		if (existence_test == false)
       
  2046 		{
       
  2047 			EAP_TRACE_DATA_DEBUG(
       
  2048 				m_am_tools,
       
  2049 				TRACE_FLAGS_DEFAULT,
       
  2050 				(EAPL("WARNING: CONFIG: unknown option"),
       
  2051 				 field->get_field(),
       
  2052 				 field->get_field_length()));
       
  2053 		}
       
  2054 		status = eap_status_illegal_configure_field;
       
  2055 	}
       
  2056 
       
  2057 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2058 	return status; // Here EAP_STATUS_RETURN() macro is too noisy.
       
  2059 }
       
  2060 
       
  2061 //-----------------------------------------------------------------
       
  2062 
       
  2063 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::read_configure(
       
  2064 	const eap_configuration_field_c * const field,
       
  2065 	eap_variable_data_c* const data,
       
  2066 	eap_core_map_c<eap_config_value_c, abs_eap_core_map_c, eap_variable_data_c> * const config_map,
       
  2067 	const bool check_subsection_when_true)
       
  2068 {
       
  2069 	eap_status_e status = eap_status_process_general_error;
       
  2070 
       
  2071 	eap_variable_data_c selector(m_am_tools);
       
  2072 	if (selector.get_is_valid() == false)
       
  2073 	{
       
  2074 		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
       
  2075 	}
       
  2076 
       
  2077 	if (check_subsection_when_true == true
       
  2078 		&& field->get_subsection() != 0)
       
  2079 	{
       
  2080 		status = selector.set_buffer(
       
  2081 			field->get_subsection());
       
  2082 		if (status != eap_status_ok)
       
  2083 		{
       
  2084 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2085 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2086 		}
       
  2087 
       
  2088 		EAP_TRACE_DATA_DEBUG(
       
  2089 			m_am_tools, 
       
  2090 			TRACE_FLAGS_DEFAULT, 
       
  2091 			(EAPL("CONFIG: finds subsection name"), 
       
  2092 			 field->get_subsection()->get_data(), 
       
  2093 			 field->get_subsection()->get_data_length()));
       
  2094 
       
  2095 		eap_config_value_c *config = config_map->get_handler(&selector);
       
  2096 
       
  2097 		if (config != 0)
       
  2098 		{
       
  2099 			if (check_subsection_when_true == true
       
  2100 				&& config->get_type() == eap_configure_type_subsection)
       
  2101 			{
       
  2102 				if (config->get_subsection() != 0)
       
  2103 				{
       
  2104 					status = read_configure(
       
  2105 						field,
       
  2106 						data,
       
  2107 						config->get_subsection(),
       
  2108 						false);
       
  2109 					if (status == eap_status_ok)
       
  2110 					{
       
  2111 						// OK, section configuration found.
       
  2112 						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2113 						return EAP_STATUS_RETURN(m_am_tools, status);
       
  2114 					}
       
  2115 				}
       
  2116 				else
       
  2117 				{
       
  2118 					EAP_TRACE_DATA_DEBUG(
       
  2119 						m_am_tools,
       
  2120 						TRACE_FLAGS_DEFAULT,
       
  2121 						(EAPL("WARNING: CONFIG: subsection not found"),
       
  2122 						 field->get_field(),
       
  2123 						 field->get_field_length()));
       
  2124 				}
       
  2125 			}
       
  2126 		}
       
  2127 		else
       
  2128 		{
       
  2129 			EAP_TRACE_DATA_DEBUG(
       
  2130 				m_am_tools,
       
  2131 				TRACE_FLAGS_DEFAULT,
       
  2132 				(EAPL("WARNING: CONFIG: subsection not found"),
       
  2133 				 field->get_field(),
       
  2134 				 field->get_field_length()));
       
  2135 		}
       
  2136 	}
       
  2137 
       
  2138 
       
  2139 
       
  2140 	{
       
  2141 		status = selector.set_buffer(
       
  2142 			field->get_field(),
       
  2143 			field->get_field_length(),
       
  2144 			false,
       
  2145 			false);
       
  2146 		if (status != eap_status_ok)
       
  2147 		{
       
  2148 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2149 			return EAP_STATUS_RETURN(m_am_tools, status);
       
  2150 		}
       
  2151 
       
  2152 		eap_config_value_c *config = config_map->get_handler(&selector);
       
  2153 
       
  2154 		if (config != 0)
       
  2155 		{
       
  2156 			if (field->get_type() != config->get_type())
       
  2157 			{
       
  2158 				EAP_TRACE_DEBUG(
       
  2159 					m_am_tools,
       
  2160 					TRACE_FLAGS_DEFAULT,
       
  2161 					(EAPL("WARNING: CONFIG: option type failed: required %d != actual %d\n"),
       
  2162 					 field->get_type(),
       
  2163 					 config->get_type()));
       
  2164 				EAP_TRACE_DEBUG(
       
  2165 					m_am_tools,
       
  2166 					TRACE_FLAGS_DEFAULT,
       
  2167 					(EAPL("WARNING: CONFIG: rear option type failed: %s\n"),
       
  2168 					 field->get_field()));
       
  2169 				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2170 				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_type);
       
  2171 			}
       
  2172 
       
  2173 			status = data->set_copy_of_buffer(config->get_data());
       
  2174 
       
  2175 			EAP_TRACE_DEBUG(
       
  2176 				m_am_tools,
       
  2177 				TRACE_FLAGS_DEFAULT,
       
  2178 				(EAPL("CONFIG: value read from eap_file_config_c: %s\n"),
       
  2179 				 field->get_field()));
       
  2180 
       
  2181 			EAP_TRACE_DATA_DEBUG(
       
  2182 				m_am_tools,
       
  2183 				TRACE_FLAGS_DEFAULT,
       
  2184 				(EAPL("value"),
       
  2185 				 data->get_data(),
       
  2186 				 data->get_data_length()));
       
  2187 		}
       
  2188 		else
       
  2189 		{
       
  2190 			EAP_TRACE_DATA_DEBUG(
       
  2191 				m_am_tools,
       
  2192 				TRACE_FLAGS_DEFAULT,
       
  2193 				(EAPL("WARNING: CONFIG: option not found"),
       
  2194 				 field->get_field(),
       
  2195 				 field->get_field_length()));
       
  2196 			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2197 			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field);
       
  2198 		}
       
  2199 
       
  2200 	}
       
  2201 
       
  2202 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2203 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2204 }
       
  2205 
       
  2206 //-----------------------------------------------------------------
       
  2207 
       
  2208 EAP_FUNC_EXPORT eap_status_e eap_file_config_c::read_configure(
       
  2209 	const eap_configuration_field_c * const field,
       
  2210 	eap_variable_data_c* const data)
       
  2211 {
       
  2212 	EAP_TRACE_DATA_DEBUG(
       
  2213 		m_am_tools,
       
  2214 		TRACE_FLAGS_DEFAULT,
       
  2215 		(EAPL("eap_file_config_c::read_configure()"),
       
  2216 		 field->get_field(),
       
  2217 		 field->get_field_length()));
       
  2218 
       
  2219 	eap_status_e status = read_configure(
       
  2220 		field,
       
  2221 		data,
       
  2222 		&m_config_map,
       
  2223 		true);
       
  2224 
       
  2225 	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
       
  2226 	return EAP_STATUS_RETURN(m_am_tools, status);
       
  2227 }
       
  2228 
       
  2229 //-----------------------------------------------------------------