Revision: 201007
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 19 Mar 2010 09:29:58 +0200
changeset 17 8840d3e38314
parent 2 1c7bc153c08e
child 18 7aac0b9e8906
Revision: 201007 Kit: 201011
eapol/eapol_framework/eapol_symbian/group/eapaka.mmp
eapol/eapol_framework/eapol_symbian/group/eapmschapv2.mmp
eapol/eapol_framework/eapol_symbian/group/eapprotectedsetup.mmp
eapol/eapol_framework/eapol_symbian/group/eapsecurid.mmp
eapol/eapol_framework/eapol_symbian/group/eapsim.mmp
eapol/eapol_framework/eapol_symbian/group/eaptlspeap.mmp
eapol/eapol_framework/wapi_common/include/abs_ec_am_algorithms.h
eapol/eapol_framework/wapi_common/include/abs_ec_am_certificate_store.h
eapol/eapol_framework/wapi_common/include/abs_ec_certificate_store.h
eapol/eapol_framework/wapi_common/include/abs_wapi_am_core.h
eapol/eapol_framework/wapi_common/include/abs_wapi_am_wlan_authentication.h
eapol/eapol_framework/wapi_common/include/abs_wapi_core.h
eapol/eapol_framework/wapi_common/include/abs_wapi_ethernet_core.h
eapol/eapol_framework/wapi_common/include/abs_wapi_message_wlan_authentication.h
eapol/eapol_framework/wapi_common/include/abs_wapi_wlan_authentication.h
eapol/eapol_framework/wapi_common/include/dummy_wapi_core.h
eapol/eapol_framework/wapi_common/include/ec_am_algorithms_direct_nrc.h
eapol/eapol_framework/wapi_common/include/ec_am_base_algorithms.h
eapol/eapol_framework/wapi_common/include/ec_am_base_certificate_store.h
eapol/eapol_framework/wapi_common/include/ec_base_certificate_store.h
eapol/eapol_framework/wapi_common/include/ec_certificate_store.h
eapol/eapol_framework/wapi_common/include/ec_cs_compare_certificate_id.h
eapol/eapol_framework/wapi_common/include/ec_cs_compare_certificate_issuer_name.h
eapol/eapol_framework/wapi_common/include/ec_cs_compare_certificate_reference.h
eapol/eapol_framework/wapi_common/include/ec_cs_compare_reference.h
eapol/eapol_framework/wapi_common/include/ec_cs_compare_reference_id.h
eapol/eapol_framework/wapi_common/include/ec_cs_compare_reference_issuer_name.h
eapol/eapol_framework/wapi_common/include/ec_cs_completion.h
eapol/eapol_framework/wapi_common/include/ec_cs_data.h
eapol/eapol_framework/wapi_common/include/ec_cs_strings.h
eapol/eapol_framework/wapi_common/include/ec_cs_tlv.h
eapol/eapol_framework/wapi_common/include/ec_cs_tlv_header.h
eapol/eapol_framework/wapi_common/include/ec_cs_tlv_message.h
eapol/eapol_framework/wapi_common/include/ec_cs_tlv_payloads.h
eapol/eapol_framework/wapi_common/include/ec_cs_types.h
eapol/eapol_framework/wapi_common/include/wai_message.h
eapol/eapol_framework/wapi_common/include/wai_message_payloads.h
eapol/eapol_framework/wapi_common/include/wai_protocol_packet_header.h
eapol/eapol_framework/wapi_common/include/wai_tlv_header.h
eapol/eapol_framework/wapi_common/include/wai_usksa.h
eapol/eapol_framework/wapi_common/include/wai_variable_data.h
eapol/eapol_framework/wapi_common/include/wapi_am_base_core.h
eapol/eapol_framework/wapi_common/include/wapi_am_crypto_sms4.h
eapol/eapol_framework/wapi_common/include/wapi_am_wlan_authentication.h
eapol/eapol_framework/wapi_common/include/wapi_asn1_der_parser.h
eapol/eapol_framework/wapi_common/include/wapi_certificate_asn1_der_parser.h
eapol/eapol_framework/wapi_common/include/wapi_core.h
eapol/eapol_framework/wapi_common/include/wapi_core_retransmission.h
eapol/eapol_framework/wapi_common/include/wapi_ethernet_core.h
eapol/eapol_framework/wapi_common/include/wapi_message_wlan_authentication.h
eapol/eapol_framework/wapi_common/include/wapi_session_core.h
eapol/eapol_framework/wapi_common/include/wapi_strings.h
eapol/eapol_framework/wapi_common/include/wapi_types.h
eapol/eapol_framework/wapi_common/include/wapi_wlan_authentication.h
eapol/eapol_framework/wapi_common/src/abs_ec_am_algorithms.cpp
eapol/eapol_framework/wapi_common/src/abs_ec_certificate_store.cpp
eapol/eapol_framework/wapi_common/src/dummy_wapi_core.cpp
eapol/eapol_framework/wapi_common/src/ec_am_algorithms_direct_nrc.cpp
eapol/eapol_framework/wapi_common/src/ec_am_base_algorithms.cpp
eapol/eapol_framework/wapi_common/src/ec_base_certificate_store.cpp
eapol/eapol_framework/wapi_common/src/ec_certificate_store.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_compare_certificate_id.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_compare_certificate_issuer_name.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_compare_certificate_reference.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_compare_reference.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_compare_reference_id.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_compare_reference_issuer_name.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_completion.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_data.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_strings.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_tlv.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_tlv_header.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_tlv_message.cpp
eapol/eapol_framework/wapi_common/src/ec_cs_tlv_payloads.cpp
eapol/eapol_framework/wapi_common/src/makefile
eapol/eapol_framework/wapi_common/src/wai_message.cpp
eapol/eapol_framework/wapi_common/src/wai_message_payloads.cpp
eapol/eapol_framework/wapi_common/src/wai_protocol_packet_header.cpp
eapol/eapol_framework/wapi_common/src/wai_tlv_header.cpp
eapol/eapol_framework/wapi_common/src/wai_usksa.cpp
eapol/eapol_framework/wapi_common/src/wai_variable_data.cpp
eapol/eapol_framework/wapi_common/src/wapi_am_crypto_sms4.cpp
eapol/eapol_framework/wapi_common/src/wapi_am_wlan_authentication.cpp
eapol/eapol_framework/wapi_common/src/wapi_asn1_der_parser.cpp
eapol/eapol_framework/wapi_common/src/wapi_certificate_asn1_der_parser.cpp
eapol/eapol_framework/wapi_common/src/wapi_core.cpp
eapol/eapol_framework/wapi_common/src/wapi_core_retransmission.cpp
eapol/eapol_framework/wapi_common/src/wapi_ethernet_core.cpp
eapol/eapol_framework/wapi_common/src/wapi_message_wlan_authentication.cpp
eapol/eapol_framework/wapi_common/src/wapi_session_core.cpp
eapol/eapol_framework/wapi_common/src/wapi_strings.cpp
eapol/eapol_framework/wapi_common/src/wapi_wlan_authentication.cpp
eapol/eapol_framework/wapi_symbian/bwins/wapiu.def
eapol/eapol_framework/wapi_symbian/eabi/wapiu.def
eapol/eapol_framework/wapi_symbian/group/20021357.SPD
eapol/eapol_framework/wapi_symbian/group/20021357.txt
eapol/eapol_framework/wapi_symbian/group/bld.inf
eapol/eapol_framework/wapi_symbian/group/wapi.mmh
eapol/eapol_framework/wapi_symbian/group/wapi.mmp
eapol/eapol_framework/wapi_symbian/group/wlanwapiif.mmp
eapol/eapol_framework/wapi_symbian/include/WapiDbDefaults.h
eapol/eapol_framework/wapi_symbian/include/certificate_store_db_parameters.h
eapol/eapol_framework/wapi_symbian/include/certificate_store_db_symbian.h
eapol/eapol_framework/wapi_symbian/include/wapi_am_core_symbian.h
eapol/eapol_framework/wapi_symbian/include/wapi_am_wlan_authentication_symbian.h
eapol/eapol_framework/wapi_symbian/rom/wapi.iby
eapol/eapol_framework/wapi_symbian/wapi_core/symbian/WapiCertificates.cpp
eapol/eapol_framework/wapi_symbian/wapi_core/symbian/certificate_store_db_symbian.cpp
eapol/eapol_framework/wapi_symbian/wapi_core/symbian/file_config/wapi_symbian.conf
eapol/eapol_framework/wapi_symbian/wapi_core/symbian/wapi_am_core_symbian.cpp
eapol/eapol_framework/wapi_symbian/wapi_core/symbian/wapi_am_wlan_authentication_symbian.cpp
eapol/eapol_framework/wapi_symbian/wlanwapiif/data/2001959f.rss
eapol/eapol_framework/wapi_symbian/wlanwapiif/inc/wlan_wapi_if_implementation.h
eapol/eapol_framework/wapi_symbian/wlanwapiif/src/wlan_wapi_if_implementation.cpp
wlansecuritysettings/wapisecuritysettingsui/data/wapisecuritysettingsui.rss
wlansecuritysettings/wapisecuritysettingsui/group/bld.inf
wlansecuritysettings/wapisecuritysettingsui/group/wapisecuritysettingsui.mmp
wlansecuritysettings/wapisecuritysettingsui/help/data/xhtml.zip
wlansecuritysettings/wapisecuritysettingsui/help/group/bld.inf
wlansecuritysettings/wapisecuritysettingsui/help/inc/wapi.hlp.hrh
wlansecuritysettings/wapisecuritysettingsui/help/rom/wapisecuritysettingsuihelps_variant.iby
wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsdefs.h
wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsdlg.h
wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsimpl.h
wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsimpl.inl
wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsui.hrh
wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsuiimpl.h
wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsuipanic.h
wlansecuritysettings/wapisecuritysettingsui/loc/wapisecuritysettingsui.loc
wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettings.cpp
wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettingsdlg.cpp
wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettingsimpl.cpp
wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettingsui.cpp
wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettingsuiimpl.cpp
wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettingsuipanic.cpp
wlansecuritysettings/wepsecuritysettingsui/group/wepsecuritysettingsuistub.mmp
wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsDlg.cpp
wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsImpl.cpp
wlansecuritysettings/wepsecuritysettingsui/src/wepsecuritysettingsstub.cpp
wlansecuritysettings/wepsecuritysettingsui/src/wepsecuritysettingsuistub.cpp
wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotactiverunner.cpp
wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUi.cpp
wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUiView.cpp
wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUi.cpp
wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUiView.cpp
wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/src/GtcNotifDlgPlugin.cpp
wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2Ui.cpp
wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2UiView.cpp
wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/src/MsChapv2NotifDialog.cpp
wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/src/MsChapv2NotifDlgPlugin.cpp
wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUi.cpp
wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUiView.cpp
wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPlugInConfigurationDlg.cpp
wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPluginConfiguration.cpp
wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUi.cpp
wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUiView.cpp
wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUi.cpp
wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUiView.cpp
wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUi.cpp
wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUiView.cpp
wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papuiview.cpp
wlansecuritysettings/wpasecuritysettingsui/group/wpasecuritysettingsuistub.mmp
wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsDlg.cpp
--- a/eapol/eapol_framework/eapol_symbian/group/eapaka.mmp	Mon Jan 18 20:22:35 2010 +0200
+++ b/eapol/eapol_framework/eapol_symbian/group/eapaka.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 17.2.2 %
+* %version: 17.2.3 %
 */
 
 #include <platform_paths.hrh>
@@ -94,8 +94,6 @@
 		
 #endif // End of #if !defined(WINS) && defined(USE_EAP_AKA_INTERFACE)
 
-MACRO EAP_NO_EXPORTS
-
 LIBRARY     eikdlg.lib
 LIBRARY     eikcore.lib
 LIBRARY     hlplch.lib
--- a/eapol/eapol_framework/eapol_symbian/group/eapmschapv2.mmp	Mon Jan 18 20:22:35 2010 +0200
+++ b/eapol/eapol_framework/eapol_symbian/group/eapmschapv2.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 15.2.2 %
+* %version: 15.2.3 %
 */
 
 #include <platform_paths.hrh>
@@ -98,8 +98,6 @@
 
 LANG		  SC
 
-MACRO EAP_NO_EXPORTS=1
-
 //-------------------------------------------------------------------
 
 //-------------------------------------------------------------------
--- a/eapol/eapol_framework/eapol_symbian/group/eapprotectedsetup.mmp	Mon Jan 18 20:22:35 2010 +0200
+++ b/eapol/eapol_framework/eapol_symbian/group/eapprotectedsetup.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 12.2.2 %
+* %version: 12.2.3 %
 */
 
 #include <platform_paths.hrh>
@@ -149,8 +149,6 @@
 LIBRARY		featmgr.lib
 */
 
-MACRO EAP_NO_EXPORTS=1
-
 //-------------------------------------------------------------------
 
 //-------------------------------------------------------------------
--- a/eapol/eapol_framework/eapol_symbian/group/eapsecurid.mmp	Mon Jan 18 20:22:35 2010 +0200
+++ b/eapol/eapol_framework/eapol_symbian/group/eapsecurid.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 16.2.2 %
+* %version: 16.2.3 %
 */
 
 #include <platform_paths.hrh>
@@ -89,8 +89,6 @@
 
 LANG		  SC
 
-MACRO EAP_NO_EXPORTS=1
-
 //-------------------------------------------------------------------
 
 //-------------------------------------------------------------------
--- a/eapol/eapol_framework/eapol_symbian/group/eapsim.mmp	Mon Jan 18 20:22:35 2010 +0200
+++ b/eapol/eapol_framework/eapol_symbian/group/eapsim.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 18.2.2 %
+* %version: 18.2.3 %
 */
 
 #include <platform_paths.hrh>
@@ -94,8 +94,6 @@
 	LIBRARY		CustomAPI.lib etelmm.lib etel.lib	// For ETel connection	
 #endif // End of #if !defined(WINS) && defined(USE_EAP_GSMSIM_INTERFACE)
 
-MACRO EAP_NO_EXPORTS
-
 LIBRARY     eikdlg.lib
 LIBRARY     eikcore.lib
 LIBRARY     hlplch.lib
--- a/eapol/eapol_framework/eapol_symbian/group/eaptlspeap.mmp	Mon Jan 18 20:22:35 2010 +0200
+++ b/eapol/eapol_framework/eapol_symbian/group/eaptlspeap.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 44.2.2 %
+* %version: 44.2.3 %
 */
 
 #include <platform_paths.hrh>
@@ -159,8 +159,6 @@
 
 LIBRARY     charconv.lib
 
-MACRO EAP_NO_EXPORTS=1
-
 //-------------------------------------------------------------------
 
 //-------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/abs_ec_am_algorithms.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,88 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/abs_ec_am_algorithms.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 7 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_ABS_EC_AM_ALGORITHMS_H_)
+#define _ABS_EC_AM_ALGORITHMS_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_cs_types.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------
+
+class abs_eap_am_tools_c;
+class eap_configuration_field_c;
+
+
+class EAP_EXPORT abs_ec_am_algorithms_c
+{
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the abs_ec_am_algorithms_c class does nothing special.
+	 */
+	EAP_FUNC_IMPORT virtual ~abs_ec_am_algorithms_c();
+
+	virtual eap_status_e complete_create_signature_with_private_key(
+		const eap_variable_data_c * const signature,
+		const eap_status_e signature_status) = 0;
+
+	virtual eap_status_e complete_verify_signature_with_public_key(
+		const eap_status_e verification_status) = 0;
+
+	virtual eap_status_e complete_create_ecdh_temporary_keys(
+		const eap_variable_data_c * const private_key_d,
+		const eap_variable_data_c * const public_key_x,
+		const eap_variable_data_c * const public_key_y) = 0;
+
+	virtual eap_status_e complete_create_ecdh(
+		const eap_variable_data_c * const K_AB_x4,
+		const eap_variable_data_c * const K_AB_y4) = 0;
+
+	/**
+	 * The read_configure() function reads the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the query to some persistent store.
+	 * @param field is generic configure string idenfying the required configure data.
+	 * @param field_length is length of the field string.
+	 * @param data is pointer to existing eap_variable_data object.
+	 */
+	virtual eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	//--------------------------------------------------
+}; // abs_ec_am_algorithms_c
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_ABS_EC_AM_ALGORITHMS_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/abs_ec_am_certificate_store.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,115 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/abs_ec_am_certificate_store.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 11 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_ABS_EC_AM_CERTIFICATE_STORE_H_)
+#define _ABS_EC_AM_CERTIFICATE_STORE_H_
+
+#if defined(USE_EC_CERTIFICATE_STORE)
+
+#include "eap_am_export.h"
+#include "eap_array.h"
+#include "wapi_types.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+
+/// This class declares the functions adaptation module of elliptic curve sertificate store
+/// requires from the elliptic curve sertificate store.
+class EAP_EXPORT abs_ec_am_certificate_store_c
+{
+private:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/// Destructor does nothing.
+	virtual ~abs_ec_am_certificate_store_c()
+	{
+	}
+
+	/// Constructor does nothing.
+	abs_ec_am_certificate_store_c()
+	{
+	}
+
+	/**
+	 * This function call completes initialize_certificate_store() function call.
+	 * After all imported certificate files are handled, AM must call this function.
+	 * WAPI authentication will continue within this function call.
+	 */
+	virtual eap_status_e complete_initialize_certificate_store(
+		const wapi_completion_operation_e completion_operation) = 0;
+
+	/**
+	 * This function call removes cached certificate store data.
+	 */
+	virtual eap_status_e remove_cached_certificate_store_data() = 0;
+
+	/**
+	 * This function call adds certificate to certificate store.
+	 * this function call is completed with complete_add_imported_certificate_file() function.
+	 */
+	virtual eap_status_e add_imported_certificate_file(
+		const eap_variable_data_c * const in_imported_certificate_file_data,
+		const eap_variable_data_c * const in_imported_certificate_filename) = 0;
+
+	/**
+	 * This function call completes read_certificate_store_data() function call.
+	 */
+	virtual eap_status_e complete_read_certificate_store_data(
+		const eap_status_e in_completion_status,
+		const ec_cs_pending_operation_e in_pending_operation,
+		EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references_and_data_blocks) = 0;
+	
+	/**
+	 * This function call completes write_certificate_store_data() function call.
+	 */
+	virtual eap_status_e complete_write_certificate_store_data(
+		const eap_status_e in_completion_status,
+		const ec_cs_pending_operation_e in_pending_operation) = 0;
+
+	/**
+	 * This function call queries list of certificates.
+	 */
+	virtual eap_status_e query_certificate_list() = 0;
+
+	/**
+	 * This function call starts import of certificate files.
+	 */
+	virtual eap_status_e start_certificate_import() = 0;
+
+	//--------------------------------------------------
+}; // class abs_ec_am_certificate_store_c
+
+#endif //#if defined(USE_EC_CERTIFICATE_STORE)
+
+#endif //#if !defined(_ABS_EC_AM_CERTIFICATE_STORE_H_)
+
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/abs_ec_certificate_store.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,127 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/abs_ec_certificate_store.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 11 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_ABS_EC_CERTIFICATE_STORE_H_)
+#define _ABS_EC_CERTIFICATE_STORE_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_cs_types.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------
+
+class abs_eap_am_tools_c;
+class eap_configuration_field_c;
+class abs_eap_state_notification_c;
+
+
+class EAP_EXPORT abs_ec_certificate_store_c
+{
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the abs_ec_certificate_store_c class does nothing.
+	 */
+	EAP_FUNC_IMPORT virtual ~abs_ec_certificate_store_c();
+
+	virtual eap_status_e complete_get_own_certificate(
+		const eap_variable_data_c * const own_certificate) = 0;
+
+	virtual eap_status_e complete_query_asu_id(
+		const eap_variable_data_c * const asn1_der_subject_name,
+		const eap_variable_data_c * const asn1_der_issuer_name,
+		const eap_variable_data_c * const asn1_der_sequence_number,
+		const eap_status_e id_status) = 0;
+
+	virtual eap_status_e complete_select_certificate(
+		const eap_variable_data_c * const issuer_ID,
+		const eap_variable_data_c * const certificate_ID,
+		const eap_variable_data_c * const certificate) = 0;
+
+	virtual eap_status_e complete_read_id_of_certificate(
+		const eap_variable_data_c * const ID) = 0;
+
+	virtual eap_status_e complete_create_signature_with_private_key(
+		const eap_variable_data_c * const signature,
+		const eap_status_e signature_status) = 0;
+
+	virtual eap_status_e complete_verify_signature_with_public_key(
+		const eap_status_e verification_status) = 0;
+
+	virtual eap_status_e complete_create_ecdh_temporary_keys(
+		const eap_variable_data_c * const private_key_d,
+		const eap_variable_data_c * const public_key_x,
+		const eap_variable_data_c * const public_key_y) = 0;
+
+	virtual eap_status_e complete_create_ecdh(
+		const eap_variable_data_c * const K_AB_x4,
+		const eap_variable_data_c * const K_AB_y4) = 0;
+
+	/**
+	 * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds.
+	 */
+	virtual eap_status_e set_session_timeout(
+		const u32_t session_timeout_ms) = 0;
+
+	/**
+	 * This is notification of internal state transition.
+	 * This is used for notifications, debugging and protocol testing.
+	 * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully
+	 * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. CS MUST send these
+	 * two notifications to lower layer.
+	 * These two notifications are sent using WAPI-protocol layer (eap_protocol_layer_e::eap_protocol_layer_wapi).
+	 * See also eap_state_notification_c.
+	 */
+	virtual void state_notification(
+		const abs_eap_state_notification_c * const state) = 0;
+
+	/**
+	 * The read_configure() function reads the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the query to some persistent store.
+	 * @param field is generic configure string idenfying the required configure data.
+	 * @param field_length is length of the field string.
+	 * @param data is pointer to existing eap_variable_data object.
+	 * 
+	 * WAPI should store it's parameters to an own database. The own database should be accessed
+	 * through adaptation module of WAPI. See eap_am_type_gsmsim_simulator_c::type_configure_read.
+	 */
+	virtual eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	//--------------------------------------------------
+}; // abs_ec_certificate_store_c
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_ABS_EC_CERTIFICATE_STORE_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/abs_wapi_am_core.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,113 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/abs_wapi_am_core.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 11 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_ABS_WAPI_AM_CORE_H_)
+#define _ABS_WAPI_AM_CORE_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+
+/// This class declares the functions adaptation module of WAPI core
+/// requires from the WAPI core.
+class EAP_EXPORT abs_wapi_am_core_c
+{
+private:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	// 
+	virtual ~abs_wapi_am_core_c()
+	{
+	}
+
+	// 
+	abs_wapi_am_core_c()
+	{
+	}
+
+	/**
+	 * The set_timer() function initializes timer to be elapsed after time_ms milliseconds.
+	 * @param initializer is pointer to object which timer_expired() function will
+	 * be called after timer elapses.
+	 * @param id is identifier which will be returned in timer_expired() function.
+	 * The user selects and interprets the id for this timer.
+	 * @param data is pointer to any user selected data which will be returned in timer_expired() function.
+	 * @param time_ms is the time of timer in milli seconds.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e set_timer(
+		abs_eap_base_timer_c * const initializer, 
+		const u32_t id, 
+		void * const data,
+		const u32_t time_ms) = 0;
+
+	/**
+	 * The cancel_timer() function cancels the timer id initiated by initializer.
+	 * @param initializer is pointer to object which set the cancelled timer.
+	 * @param id is identifier which will be returned in timer_expired() function.
+	 * The user selects and interprets the id for this timer.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e cancel_timer(
+		abs_eap_base_timer_c * const initializer, 
+		const u32_t id) = 0;
+
+	/**
+	 * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds.
+	 */
+	virtual eap_status_e set_session_timeout(
+		const u32_t session_timeout_ms) = 0;
+
+	/**
+	 * The read_configure() function reads the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the query to some persistent store.
+	 * @param field is generic configure string idenfying the required configure data.
+	 * @param field_length is length of the field string.
+	 * @param data is pointer to existing eap_variable_data object.
+	 * 
+	 * WAPI should store it's parameters to an own database. The own database should be accessed
+	 * through adaptation module of WAPI. See eap_am_type_gsmsim_simulator_c::type_configure_read.
+	 */
+	virtual eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	//--------------------------------------------------
+}; // class abs_wapi_am_core_c
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_ABS_WAPI_AM_CORE_H_)
+
+//--------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/abs_wapi_am_wlan_authentication.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,89 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/abs_wapi_am_wlan_authentication.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 5 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_ABS_WAPI_AM_WLAN_AUTHENTICATION_H_)
+#define _ABS_WAPI_AM_WLAN_AUTHENTICATION_H_
+
+#include "eap_am_export.h"
+#include "eapol_key_types.h"
+
+/// This class declares the functions the adaptation module of WAPI
+/// requires from wapi_wlan_authentication_c
+class EAP_EXPORT abs_wapi_am_wlan_authentication_c
+{
+private:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	// 
+	virtual ~abs_wapi_am_wlan_authentication_c()
+	{
+	}
+
+	// 
+	abs_wapi_am_wlan_authentication_c()
+	{
+	}
+
+	/**
+	 *	This function disassociates the connection.
+	 */
+	virtual eap_status_e disassociation(
+		const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address.
+		) = 0;
+
+
+	/**
+	 *	This function indicates the state of WLAN authentication.
+	 */
+	virtual eap_status_e wapi_indication(
+		const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+		const eapol_wlan_authentication_state_e wlan_authentication_state) = 0;
+
+	/**
+	 * This is notification of internal state transition.
+	 * This is used for notifications, debugging and protocol testing.
+	 * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully
+	 * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. WAPI MUST send these
+	 * two notifications to lower layer.
+	 * These two notifications are sent using WAPI-protocol layer (eap_protocol_layer_e::eap_protocol_layer_wapi).
+	 * See also eap_state_notification_c.
+	 */
+	virtual void state_notification(
+		const abs_eap_state_notification_c * const state) = 0;
+
+	//--------------------------------------------------
+}; // class abs_wapi_am_wlan_authentication_c
+
+#endif //#if !defined(_ABS_WAPI_AM_WLAN_AUTHENTICATION_H_)
+
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/abs_wapi_core.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,210 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/abs_wapi_core.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 9.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_ABS_WAPI_CORE_H_)
+#define _ABS_WAPI_CORE_H_
+
+#include "eap_header.h"
+#include "eap_array.h"
+
+class eap_am_network_id_c;
+class eap_buf_chain_wr_c;
+class eap_configuration_field_c;
+class eap_variable_data_c;
+class abs_eap_state_notification_c;
+class eap_master_session_key_c;
+class eapol_session_key_c;
+
+
+/// This class defines the interface the wapi_core_c class
+/// will use with the partner class (lower layer).
+class EAP_EXPORT abs_wapi_core_c
+{
+private:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the abs_eap_core class does nothing special.
+	 */
+	virtual ~abs_wapi_core_c()
+	{
+	}
+
+	/**
+	 * The constructor of the abs_eap_core class does nothing special.
+	 */
+	abs_wapi_core_c()
+	{
+	}
+
+	/**
+	 * The derived class could send packets to partner class with this function.
+	 * @see abs_eap_base_type_c::packet_send().
+	 */
+	virtual eap_status_e packet_send(
+		const eap_am_network_id_c * const network_id,
+		eap_buf_chain_wr_c * const sent_packet,
+		const u32_t header_offset,
+		const u32_t data_length,
+		const u32_t buffer_length) = 0;
+
+	/**
+	 * The get_header_offset() function obtains the header offset of WAPI-packet.
+	 * @see abs_eap_base_type_c::get_header_offset().
+	 */
+	virtual u32_t get_header_offset(
+		u32_t * const MTU,
+		u32_t * const trailer_length) = 0;
+
+	/**
+	 * The session calls the restart_authentication() function
+	 * when WAPI-authentication is needed with another peer.
+	 * This is also used when session restarts authentication.
+	 * @param receive_network_id includes the addresses (network identity) and packet type.
+	 * @param is_client_when_true indicates whether the WAPI should act as a client or server,
+	 * in terms of WAPI whether this network entity is WAPI-ASUE (true) or WAPI-ASU (false).
+	 * @param force_clean_restart this selects whether the server removes this session (true) or not (false).
+	 * @param from_timer tells whether the timer calls this function (true) or not (false).
+	 */
+	virtual eap_status_e restart_authentication(
+		const eap_am_network_id_c * const receive_network_id,
+		const bool is_client_when_true,
+		const bool force_clean_restart,
+		const bool from_timer = false) = 0;
+
+	/**
+	 * The packet_data_session_key() function passes one traffic encryption key to 
+	 * the lower layers. Ultimately the key can end up to the WLAN hardware.
+	 * @param send_network_id carries the addresses (network identity) and type of the packet.
+	 * @param key is the encryption key
+	 * @param key_length is the length of the key
+	 * @param key_type describes the type of the key (WEP or something else...)
+	 * @param key_index is the index of the encryption key (there can be four broadcast keys in WEP for example)
+	 */
+	virtual eap_status_e packet_data_session_key(
+		const eap_am_network_id_c * const send_network_id,
+		const eapol_session_key_c * const key
+		) = 0;
+
+	/**
+	 * The read_configure() function reads the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the query to some persistent store.
+	 * @see abs_eap_base_type_c::read_configure().
+	 */
+	virtual eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	/**
+	 * The write_configure() function writes the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the action to some persistent store.
+	 * @see abs_eap_base_type_c::write_configure().
+	 */
+	virtual eap_status_e write_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	/**
+	 * This is notification of internal state transition.
+	 * This is used for notifications, debugging and protocol testing.
+	 * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully
+	 * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully.
+	 * These two notifications are sent from WAPI layer (eap_protocol_layer_e::eap_protocol_layer_wapi).
+	 * These two notifications tells the end state of authentication session. These are the only
+	 * reliable indications of the final status of authentication session.
+	 * You MUST NOT make decision based on the return value of abs_eap_stack_interface_c::packet_process().
+	 */
+	virtual void state_notification(
+		const abs_eap_state_notification_c * const state) = 0;
+
+	/**
+	 * This function tells lower layer to remove WAPI-session object asyncronously.
+	 * @param eap_type is pointer to selector that identifies the removed WAPI-session.
+	 */
+	virtual eap_status_e asynchronous_init_remove_wapi_session(
+		const eap_am_network_id_c * const send_network_id) = 0;
+
+	/**
+	 * The set_timer() function initializes timer to be elapsed after time_ms milliseconds.
+	 * @param initializer is pointer to object which timer_expired() function will
+	 * be called after timer elapses.
+	 * @param id is identifier which will be returned in timer_expired() function.
+	 * The user selects and interprets the id for this timer.
+	 * @param data is pointer to any user selected data which will be returned in timer_expired() function.
+	 * @param time_ms is the time of timer in milli seconds.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e set_timer(
+		abs_eap_base_timer_c * const initializer, 
+		const u32_t id, 
+		void * const data,
+		const u32_t time_ms) = 0;
+
+	/**
+	 * The cancel_timer() function cancels the timer id initiated by initializer.
+	 * @param initializer is pointer to object which set the cancelled timer.
+	 * @param id is identifier which will be returned in timer_expired() function.
+	 * The user selects and interprets the id for this timer.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e cancel_timer(
+		abs_eap_base_timer_c * const initializer, 
+		const u32_t id) = 0;
+
+	/**
+	 * The cancel_all_timers() function cancels all timers.
+	 * User should use this in termination of the stack before
+	 * the adaptation module of tools is deleted.
+	 * Preferred mode is to cancel each timer directly
+	 * using cancel_timer() function.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e cancel_all_timers() = 0;
+
+	/**
+	 * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds.
+	 */
+	virtual eap_status_e set_session_timeout(
+		const u32_t session_timeout_ms) = 0;
+
+	//--------------------------------------------------
+}; // class abs_wapi_core_c
+
+#endif //#if !defined(_ABS_WAPI_CORE_H_)
+
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/abs_wapi_ethernet_core.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,148 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/abs_wapi_ethernet_core.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 4.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_ABS_WAPI_ETHERNET_CORE_H_)
+#define _ABS_WAPI_ETHERNET_CORE_H_
+
+#include "eap_header.h"
+#include "eap_array.h"
+
+
+class abs_wapi_core_c;
+class eap_am_network_id_c;
+class eap_buf_chain_wr_c;
+class eapol_session_key_c;
+class abs_eap_state_notification_c;
+
+/// The abs_wapi_ethernet_core_c class defines the interface the wapi_ethernet_core_c class
+/// will use with the partner class.
+class EAP_EXPORT abs_wapi_ethernet_core_c
+{
+private:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	// 
+	virtual ~abs_wapi_ethernet_core_c()
+	{
+	}
+
+	// 
+	abs_wapi_ethernet_core_c()
+	{
+	}
+
+	// 
+	virtual eap_status_e packet_send(
+		const eap_am_network_id_c * const network_id,
+		eap_buf_chain_wr_c * const sent_packet,
+		const u32_t header_offset,
+		const u32_t data_length,
+		const u32_t buffer_length) = 0;
+
+	//
+	virtual u32_t get_header_offset(
+		u32_t * const MTU,
+		u32_t * const trailer_length) = 0;
+
+	/**
+	 * The packet_data_session_key() function passes one traffic encryption key to 
+	 * the lower layers. Ultimately the key can end up to the WLAN hardware.
+	 * @see abs_eapol_core_c::packet_data_session_key(). 
+	 */
+	virtual eap_status_e packet_data_session_key(
+		const eap_am_network_id_c * const send_network_id,
+		const eapol_session_key_c * const key
+		) = 0;
+
+	virtual eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	virtual eap_status_e write_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	/**
+	 * This is notification of internal state transition.
+	 * This is used for notifications, debugging and protocol testing.
+	 * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully
+	 * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully.
+	 * These two notifications are sent from WAPI layer (eap_protocol_layer_e::eap_protocol_layer_wapi).
+	 */
+	virtual void state_notification(
+		const abs_eap_state_notification_c * const state) = 0;
+
+	virtual bool get_is_client() = 0;
+
+	/**
+	 * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds.
+	 * @param initializer is pointer to object which timer_expired() function will
+	 * be called after timer elapses.
+	 * @param id is identifier which will be returned in timer_expired() function.
+	 * The user selects and interprets the id for this timer.
+	 * @param data is pointer to any user selected data which will be returned in timer_expired() function.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e set_timer(
+		abs_eap_base_timer_c * const initializer, 
+		const u32_t id, 
+		void * const data,
+		const u32_t p_time_ms) = 0;
+
+	/**
+	 * The cancel_timer() function cancels the timer id initiated by initializer.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e cancel_timer(
+		abs_eap_base_timer_c * const initializer, 
+		const u32_t id) = 0;
+
+	/**
+	 * The cancel_all_timers() function cancels all timers.
+	 * User should use this in termination of the stack before
+	 * the adaptation module of tools is deleted.
+	 * Preferred mode is to cancel each timer directly
+	 * using cancel_timer() function.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e cancel_all_timers() = 0;
+
+	//--------------------------------------------------
+}; // class abs_wapi_ethernet_core_c
+
+#endif //#if !defined(_ABS_WAPI_ETHERNET_CORE_H_)
+
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/abs_wapi_message_wlan_authentication.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,63 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/abs_wapi_message_wlan_authentication.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 4 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+#if !defined(_ABS_WAPI_MESSAGE_WLAN_AUTHENTICATION_H_)
+#define _ABS_WAPI_MESSAGE_WLAN_AUTHENTICATION_H_
+
+//--------------------------------------------------
+
+#include "eap_am_export.h"
+#include "eap_am_types.h"
+#include "eap_status.h"
+#include "wlan_eap_if_send_status.h"
+
+/** @file */
+
+/// This class is abstract interface to send data messages through abstract interface.
+class EAP_EXPORT abs_wapi_message_wlan_authentication_c
+{
+
+private:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	virtual ~abs_wapi_message_wlan_authentication_c()
+	{
+	}
+
+	/// Function sends the data message to lower layer.
+	/// Data is formatted to Attribute-Value Pairs.
+	/// Look at eap_tlv_header_c and eap_tlv_message_data_c.
+	virtual wlan_eap_if_send_status_e send_data(const void * const data, const u32_t length) = 0;
+
+}; // class abs_wapi_message_wlan_authentication_c
+
+
+#endif //#if !defined(_ABS_WAPI_MESSAGE_WLAN_AUTHENTICATION_H_)
+
+//--------------------------------------------------
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/abs_wapi_wlan_authentication.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,127 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/abs_wapi_wlan_authentication.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 6.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_ABS_WAPI_WLAN_AUTHENTICATION_H_)
+#define _ABS_WAPI_WLAN_AUTHENTICATION_H_
+
+#include "eap_header.h" // << TODO: this needs to be created
+#include "eap_array.h"
+
+class abs_wapi_core_c;
+class eap_am_network_id_c;
+class eap_buf_chain_wr_c;
+class eapol_session_key_c;
+class abs_eap_state_notification_c;
+
+/// The abs_wapi_wlan_authentication_c class defines the interface 
+/// the wapi_wlan_authentication_c class will use with its partner class.
+class EAP_EXPORT abs_wapi_wlan_authentication_c
+{
+private:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	// 
+	virtual ~abs_wapi_wlan_authentication_c()
+	{
+	}
+
+	// 
+	abs_wapi_wlan_authentication_c()
+	{
+	}
+
+	// Look at abs_eap_base_type_c::packet_send().
+	virtual eap_status_e packet_send(
+		const eap_am_network_id_c * const send_network_id, ///< source includes local address, destination includes remote address.
+		eap_buf_chain_wr_c * const sent_packet,
+		const u32_t header_offset,
+		const u32_t data_length,
+		const u32_t buffer_length) = 0;
+
+	// Look at abs_eap_base_type_c::get_header_offset().
+	virtual u32_t get_header_offset(
+		u32_t * const MTU,
+		u32_t * const trailer_length) = 0;
+
+	/**
+	 * This function call tells lower layer to associate with 
+	 * the selected 802.11 authentication mode.
+	 * In WAPI only the open mode is allowed.
+	 */
+	virtual eap_status_e associate(
+		eapol_key_802_11_authentication_mode_e authentication_mode) = 0;
+
+	/**
+	 * Lower layer must return value of self_disassociation when
+	 * it calls eapol_wlan_authentication_c::disassociation().
+	 * This tells eapol_wlan_authentication_c object the cause
+	 * of disassociation.
+	 */
+	virtual eap_status_e disassociate(
+		const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+		const bool self_disassociation) = 0;
+
+	/**
+	 * The packet_data_session_key() function passes one traffic encryption key to 
+	 * the lower layers. Ultimately the key can end up to the WLAN hardware.
+	 * @see abs_wapi_core_c::packet_data_session_key(). 
+	 */
+	virtual eap_status_e packet_data_session_key(
+		const eap_am_network_id_c * const send_network_id, ///< source includes local address, destination includes remote address.
+		const eapol_session_key_c * const key 
+		) = 0;
+
+	/**
+	 * This is notification of internal state transition.
+	 * This is used for notifications, debugging and protocol testing.
+	 * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully
+	 * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully.
+	 * These two notifications are sent from WAPI layer (eap_protocol_layer_e::eap_protocol_layer_wapi).
+	 */
+	virtual void state_notification(
+		const abs_eap_state_notification_c * const state) = 0;
+
+	/**
+	 * This function call tells lower layer to re-associate with the selected network ID,
+	 * authentication type and WAPI BKID.
+	 */
+	virtual eap_status_e reassociate(
+		const eap_am_network_id_c * const send_network_id,
+		const eapol_key_authentication_type_e authentication_type,
+		const eap_variable_data_c * const BKID) = 0;
+
+	//--------------------------------------------------
+}; // class abs_wapi_wlan_authentication_c
+
+#endif //#if !defined(_ABS_WAPI_WLAN_AUTHENTICATION_H_)
+
+//--------------------------------------------------
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/dummy_wapi_core.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,173 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/dummy_wapi_core.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 7 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+#ifndef _DUMMY_WAPI_CORE_H_
+#define _DUMMY_WAPI_CORE_H_
+
+#include "eap_am_types.h"
+#include "abs_eap_base_timer.h"
+#include "abs_wapi_am_core.h"
+#include "abs_ec_certificate_store.h"
+
+
+class abs_wapi_am_core_c;
+class abs_ec_certificate_store_c;
+
+
+/**
+*  This is a class to create a dummy wapi core object which can be used in the 
+*  generation of the platform-specific wapi AM objects in the class that provides 
+*  direct access to certificate store 
+*/
+
+class dummy_wapi_core_c : public abs_wapi_am_core_c, public abs_ec_certificate_store_c
+{
+
+public:
+
+    dummy_wapi_core_c();
+    ~dummy_wapi_core_c();
+    
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::get_is_valid()
+    // ---------------------------------------------------------
+    //
+    bool get_is_valid();
+    
+    /*******************************************************
+     ***********Inhertited from abs_wapi_am_core_c *********
+     * *****************************************************/
+    
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::set_timer()
+    // ---------------------------------------------------------
+    //
+    eap_status_e set_timer(
+            abs_eap_base_timer_c * const initializer, 
+            const u32_t id, 
+            void * const data,
+            const u32_t time_ms);
+
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::cancel_timer()
+    // ---------------------------------------------------------
+    //
+    eap_status_e cancel_timer(
+            abs_eap_base_timer_c * const initializer, 
+            const u32_t id);
+    
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::set_session_timeout()
+    // ---------------------------------------------------------
+    //
+    eap_status_e set_session_timeout(const u32_t session_timeout_ms);
+
+    /************************************************************
+     ********Inhertited from abs_ec_certificate_store_c *********
+     ************************************************************/
+    
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::complete_get_own_certificate()
+    // ---------------------------------------------------------
+    //
+    eap_status_e complete_get_own_certificate(
+        const eap_variable_data_c * const own_certificate);
+
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::complete_query_asu_id()
+    // ---------------------------------------------------------
+    //
+    eap_status_e complete_query_asu_id(
+        const eap_variable_data_c * const asn1_der_subject_name,
+        const eap_variable_data_c * const asn1_der_issuer_name,
+        const eap_variable_data_c * const asn1_der_sequence_number,
+        const eap_status_e id_status);
+
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::complete_select_certificate()
+    // ---------------------------------------------------------
+    //
+    eap_status_e complete_select_certificate(
+        const eap_variable_data_c * const issuer_ID,
+        const eap_variable_data_c * const certificate_ID,
+        const eap_variable_data_c * const certificate);
+
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::complete_read_id_of_certificate()
+    // ---------------------------------------------------------
+    //
+    eap_status_e complete_read_id_of_certificate(
+        const eap_variable_data_c * const ID);
+
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::complete_create_signature_with_private_key()
+    // ---------------------------------------------------------
+    //
+    eap_status_e complete_create_signature_with_private_key(
+        const eap_variable_data_c * const signature,
+        const eap_status_e signature_status);
+
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::complete_verify_signature_with_public_key()
+    // ---------------------------------------------------------
+    //
+    eap_status_e complete_verify_signature_with_public_key(
+        const eap_status_e verification_status);
+
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::complete_create_ecdh_temporary_keys()
+    // ---------------------------------------------------------
+    //
+    eap_status_e complete_create_ecdh_temporary_keys(
+        const eap_variable_data_c * const private_key_d,
+        const eap_variable_data_c * const public_key_x,
+        const eap_variable_data_c * const public_key_y);
+
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::complete_create_ecdh()
+    // ---------------------------------------------------------
+    //
+    eap_status_e complete_create_ecdh(
+        const eap_variable_data_c * const K_AB_x4,
+        const eap_variable_data_c * const K_AB_y4);
+
+
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::state_notification()
+    // ---------------------------------------------------------
+    //
+    void state_notification( const abs_eap_state_notification_c * const state);
+
+    // ---------------------------------------------------------
+    // dummy_wapi_core_c::read_configure()
+    // ---------------------------------------------------------
+    //
+    eap_status_e read_configure(
+        const eap_configuration_field_c * const field,
+        eap_variable_data_c * const data);
+        
+private:
+
+	// Nothing
+
+};
+
+#endif
+
+// end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_am_algorithms_direct_nrc.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,107 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_algorithms.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 10 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_AM_ALGORITHMS_DIRECT_NRC_H_)
+#define _EC_AM_ALGORITHMS_DIRECT_NRC_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_cs_types.h"
+#include "ec_am_base_algorithms.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------
+
+class abs_eap_am_tools_c;
+class eap_configuration_field_c;
+class abs_ec_am_algorithms_c;
+
+
+class EAP_EXPORT ec_am_algorithms_direct_nrc_c
+: public ec_am_base_algorithms_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	abs_ec_am_algorithms_c * const m_partner;
+
+	eap_variable_data_c m_e_curve;
+
+	eap_variable_data_c m_nc_rand_state;
+
+	bool m_is_client;
+
+	bool m_is_valid;
+
+	
+	eap_status_e initialize_curve();
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the ec_am_algorithms_direct_nrc_c class does nothing special.
+	 */
+	EAP_FUNC_IMPORT virtual ~ec_am_algorithms_direct_nrc_c();
+
+	EAP_FUNC_IMPORT ec_am_algorithms_direct_nrc_c(
+		abs_eap_am_tools_c * const tools,
+		abs_ec_am_algorithms_c * const partner,
+		const bool is_client_when_true);
+
+	EAP_FUNC_IMPORT eap_status_e configure();
+
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+	EAP_FUNC_IMPORT eap_status_e create_signature_with_private_key(
+		const eap_variable_data_c * const hash_of_message,
+		const eap_variable_data_c * const private_key);
+
+	EAP_FUNC_IMPORT eap_status_e verify_signature_with_public_key(
+		const eap_variable_data_c * const public_key,
+		const eap_variable_data_c * const hash_of_message,
+		const eap_variable_data_c * const signature);
+
+	EAP_FUNC_IMPORT eap_status_e create_ecdh_temporary_keys();
+
+	EAP_FUNC_IMPORT eap_status_e create_ecdh(
+		const eap_variable_data_c * const own_private_key_d,
+		const eap_variable_data_c * const peer_public_key_x,
+		const eap_variable_data_c * const peer_public_key_y);
+
+	//--------------------------------------------------
+}; // ec_am_algorithms_direct_nrc_c
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_AM_ALGORITHMS_DIRECT_NRC_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_am_base_algorithms.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,89 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_base_algorithms.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 8 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_AM_BASE_ALGORITHMS_H_)
+#define _EC_AM_BASE_ALGORITHMS_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_cs_types.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------
+
+class abs_eap_am_tools_c;
+class eap_configuration_field_c;
+class abs_ec_am_algorithms_c;
+
+
+class EAP_EXPORT ec_am_base_algorithms_c
+{
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the ec_am_base_algorithms_c class does nothing special.
+	 */
+	EAP_FUNC_IMPORT virtual ~ec_am_base_algorithms_c();
+
+	/**
+	 * Function creates a new object.
+	 */
+	EAP_FUNC_IMPORT static ec_am_base_algorithms_c * new_ec_base_algorithms_c(
+		abs_eap_am_tools_c * const tools,
+		abs_ec_am_algorithms_c * const partner,
+		const bool is_client_when_true);
+
+	virtual eap_status_e configure() = 0;
+
+	virtual bool get_is_valid() const = 0;
+
+	virtual eap_status_e create_signature_with_private_key(
+		const eap_variable_data_c * const hash_of_message,
+		const eap_variable_data_c * const private_key) = 0;
+
+	virtual eap_status_e verify_signature_with_public_key(
+		const eap_variable_data_c * const public_key,
+		const eap_variable_data_c * const hash_of_message,
+		const eap_variable_data_c * const signature) = 0;
+
+	virtual eap_status_e create_ecdh_temporary_keys() = 0;
+
+	virtual eap_status_e create_ecdh(
+		const eap_variable_data_c * const own_private_key_d,
+		const eap_variable_data_c * const peer_public_key_x,
+		const eap_variable_data_c * const peer_public_key_y) = 0;
+
+	//--------------------------------------------------
+}; // ec_am_base_algorithms_c
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_AM_BASE_ALGORITHMS_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_am_base_certificate_store.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,119 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_am_base_certificate_store.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 12 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_AM_BASE_CERTIFICATE_STORE_H_)
+#define _EC_AM_BASE_CERTIFICATE_STORE_H_
+
+#if defined(USE_EC_CERTIFICATE_STORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "wapi_types.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+#include "eap_array.h"
+
+class eap_variable_data_c;
+class abs_eap_state_notification_c;
+class abs_ec_am_certificate_store_c;
+
+/** @file */
+
+//----------------------------------------------------------------------------
+
+/// This class defines interface of elliptic curve certificate store AM.
+/**
+ * Interface of elliptic curve certificate store AM.
+ */
+class EAP_EXPORT ec_am_base_certificate_store_c
+{
+private:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	virtual ~ec_am_base_certificate_store_c() {}
+
+	/** Function sets partner object of adaptation module of certificate store.
+	 *  Partner object is the certificate store object.
+	 */
+	virtual void set_am_certificate_store_partner(abs_ec_am_certificate_store_c * const partner) = 0;
+
+	/**
+	 * Function initializes the certificate store.
+	 * This function is completed by complete_initialize_certificate_store() function call.
+	 */
+	virtual eap_status_e initialize_certificate_store(
+		const wapi_completion_operation_e completion_operation) = 0;
+
+	/**
+	 * Function reads the certificate store data referenced by parameter in_references.
+	 * This function is completed by complete_read_certificate_store_data() function call.
+	 */
+	virtual eap_status_e read_certificate_store_data(
+		const ec_cs_pending_operation_e in_pending_operation,
+		EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references) = 0;
+
+	/**
+	 * Function writes the certificate store data referenced by parameter in_references_and_data_blocks.
+	 * This function is completed by complete_write_certificate_store_data() function call.
+	 */
+	virtual eap_status_e write_certificate_store_data(
+		const bool when_true_must_be_synchronous_operation,
+		const ec_cs_pending_operation_e in_pending_operation,
+		EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references_and_data_blocks) = 0;
+
+	/**
+	 * Function completes the add_imported_certificate_file() function call.
+	 */
+	virtual eap_status_e complete_add_imported_certificate_file(
+		const eap_status_e in_completion_status,
+		const eap_variable_data_c * const in_imported_certificate_filename) = 0;
+
+	/**
+	 * Function completes the remove_certificate_store() function call.
+	 */
+	virtual eap_status_e complete_remove_certificate_store(
+		const eap_status_e in_completion_status) = 0;
+
+	/**
+	 * Function cancels all certificate_store store operations.
+	 */
+	virtual eap_status_e cancel_certificate_store_store_operations() = 0;
+
+	virtual eap_status_e complete_query_certificate_list(
+		EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const ca_certificates,
+		EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const user_certificates) = 0;
+
+	virtual eap_status_e complete_start_certificate_import() = 0;
+
+	//--------------------------------------------------
+}; // class ec_am_base_certificate_store_c
+
+
+#endif //#if defined(USE_EC_CERTIFICATE_STORE)
+
+#endif //#if !defined(_EC_AM_BASE_CERTIFICATE_STORE_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_base_certificate_store.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,115 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_base_certificate_store.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 18 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_BASE_CERTIFICATE_STORE_H_)
+#define _EC_BASE_CERTIFICATE_STORE_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_cs_types.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------
+
+class abs_eap_am_tools_c;
+class abs_ec_certificate_store_c;
+class ec_am_base_certificate_store_c;
+class eap_am_network_id_c;
+
+
+class EAP_EXPORT ec_base_certificate_store_c
+{
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the ec_base_certificate_store_c class does nothing.
+	 */
+	EAP_FUNC_IMPORT virtual ~ec_base_certificate_store_c();
+
+	/**
+	 * Function creates a new object.
+	 */
+	EAP_FUNC_IMPORT static ec_base_certificate_store_c * new_ec_base_certificate_store_c(
+		abs_eap_am_tools_c * const tools,
+		abs_ec_certificate_store_c * const partner,
+		ec_am_base_certificate_store_c * const am_certificate_store,
+		const bool is_client_when_true);
+
+	/**
+	 * Function initializes the certificate store.
+	 * This function is completed by complete_initialize_certificate_store() function call.
+	 */
+	virtual eap_status_e initialize_certificate_store() = 0;
+
+	virtual eap_status_e configure() = 0;
+
+	virtual eap_status_e shutdown() = 0;
+
+	virtual bool get_is_valid() const = 0;
+
+	virtual eap_status_e query_asu_id() = 0;
+
+	virtual eap_status_e get_own_certificate() = 0;
+
+	virtual eap_status_e set_ae_certificate(
+		const eap_variable_data_c * const ae_certificate) = 0;
+
+	virtual eap_status_e select_certificate(
+		const eap_variable_data_c * const issuer_ID) = 0;
+
+	virtual eap_status_e read_id_of_certificate(
+		const eap_variable_data_c * const certificate) = 0;
+
+	virtual eap_status_e create_signature_with_private_key(
+		const eap_variable_data_c * const hash_of_message,
+		const eap_variable_data_c * const id_of_certificate) = 0;
+
+	virtual eap_status_e verify_signature_with_public_key(
+		const eap_variable_data_c * const peer_identity,
+		const eap_variable_data_c * const hash_of_message,
+		const eap_variable_data_c * const signature,
+		const bool allow_use_of_ae_certificate) = 0;
+
+	virtual eap_status_e create_ecdh_temporary_keys() = 0;
+
+	virtual eap_status_e create_ecdh(
+		const eap_variable_data_c * const own_private_key_d,
+		const eap_variable_data_c * const peer_public_key_x,
+		const eap_variable_data_c * const peer_public_key_y) = 0;
+
+	virtual eap_status_e set_receive_network_id(const eap_am_network_id_c * const receive_network_id) = 0;
+
+	//--------------------------------------------------
+}; // ec_base_certificate_store_c
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_BASE_CERTIFICATE_STORE_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_certificate_store.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,533 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_certificate_store.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 52.1.10 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CERTIFICATE_STORE_H_)
+#define _EC_CERTIFICATE_STORE_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_cs_types.h"
+#include "ec_base_certificate_store.h"
+#include "eap_configuration_field.h"
+#include "abs_ec_am_algorithms.h"
+#include "abs_ec_am_certificate_store.h"
+#include "ec_cs_completion.h"
+#include "ec_cs_tlv_payloads.h"
+#include "eap_am_network_id.h"
+
+class abs_ec_certificate_store_c;
+
+
+/** @file */
+
+const u32_t WAPI_CS_KEY_TIMER_ID = 0ul;
+
+//----------------------------------------------------------------------------
+
+/**
+ *  This is the ASUE's ECC certificate file. It must be in DER format.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_ASUE_certificate_file,
+	"WAPI_ASUE_certificate_file",
+	eap_configure_type_string,
+	false);
+
+/**
+ *  This is the ASUE's ECC private key file. It must be in DER format.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_ASUE_private_key_file,
+	"WAPI_ASUE_private_key_file",
+	eap_configure_type_string,
+	false);
+
+
+/**
+ *  This is the AE's ECC certificate file. It must be in DER format.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_AE_certificate_file,
+	"WAPI_AE_certificate_file",
+	eap_configure_type_string,
+	false);
+
+/**
+ *  This is the AE's ECC private key file. It must be in DER format.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_AE_private_key_file,
+	"WAPI_AE_private_key_file",
+	eap_configure_type_string,
+	false);
+
+
+/**
+ *  This is the ASU's ECC certificate file. It must be in DER format.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_ASU_certificate_file,
+	"WAPI_ASU_certificate_file",
+	eap_configure_type_string,
+	false);
+
+/**
+ *  This is the ASU's ECC private key file. It must be in DER format.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_ASU_private_key_file,
+	"WAPI_ASU_private_key_file",
+	eap_configure_type_string,
+	false);
+
+/**
+ *  This u32_t data configuration option is the timeout of the PAC store key.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_EAP_FAST_PAC_store_key_timeout_ms,
+	"EAP_FAST_PAC_store_key_timeout_ms",
+	eap_configure_type_u32_t,
+	false);
+
+//----------------------------------------------------------------------------
+
+enum wapi_pem_read_state_e
+{
+	wapi_pem_read_state_header,
+	wapi_pem_read_state_data,
+	wapi_pem_read_state_end,
+};
+
+enum wapi_pem_data_type_e
+{
+	wapi_pem_data_type_none,
+	wapi_pem_data_type_certificate,
+	wapi_pem_data_type_private_key,
+};
+
+EAP_CONFIGURATION_FIELD(
+	wapi_pem_certificate_begin,
+	"-----BEGIN CERTIFICATE-----",
+	eap_configure_type_string,
+	false);
+
+EAP_CONFIGURATION_FIELD(
+	wapi_pem_certificate_end,
+	"-----END CERTIFICATE-----",
+	eap_configure_type_string,
+	false);
+
+EAP_CONFIGURATION_FIELD(
+	wapi_pem_ec_private_key_begin,
+	"-----BEGIN EC PRIVATE KEY-----",
+	eap_configure_type_string,
+	false);
+
+EAP_CONFIGURATION_FIELD(
+	wapi_pem_ec_private_key_end,
+	"-----END EC PRIVATE KEY-----",
+	eap_configure_type_string,
+	false);
+
+//----------------------------------------------------------------------------
+
+class abs_eap_am_tools_c;
+class ec_am_base_algorithms_c;
+class ec_am_base_certificate_store_c;
+
+
+class EAP_EXPORT ec_certificate_store_c
+: public abs_eap_base_timer_c
+, public ec_base_certificate_store_c
+, public abs_ec_am_algorithms_c
+, public abs_ec_am_certificate_store_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	abs_ec_certificate_store_c * const m_partner;
+
+	ec_am_base_algorithms_c * m_ec_algorithms;
+
+	ec_am_base_certificate_store_c * const m_am_certificate_store;
+
+	eap_am_network_id_c m_receive_network_id;
+
+	bool m_master_key_changed;
+	eap_variable_data_c m_PAC_store_master_key;
+
+	eap_variable_data_c m_PAC_store_password;
+
+	eap_variable_data_c m_PAC_store_device_seed;
+
+	/// This object includes pending asyncronous actions or it may be empty.
+	eap_array_c<ec_cs_completion_c> m_completion_queue;
+
+	ec_cs_pending_operation_e m_pending_operation;
+
+	eap_variable_data_c m_queried_issuer_ID;
+
+	eap_variable_data_c m_imported_certificate_wapi_id;
+	eap_variable_data_c m_imported_certificate_file_data;
+	eap_variable_data_c m_imported_certificate_filename;
+
+	eap_variable_data_c m_imported_certificate_data;
+	eap_variable_data_c m_imported_private_key_data;
+
+	eap_status_e m_ec_cs_completion_status;
+
+	eap_variable_data_c m_ae_certificate;
+
+	eap_variable_data_c m_selected_ca_id;
+	eap_variable_data_c m_selected_client_id;
+
+	eap_array_c<ec_cs_data_c> m_broken_cs_data_list;
+
+	eap_array_c<ec_cs_data_c> m_ca_asu_id_list;
+	bool m_read_ca_asu_id_list;
+
+	eap_array_c<ec_cs_data_c> m_client_asu_id_list;
+	bool m_read_client_asu_id_list;
+
+	eap_array_c<ec_cs_data_c> m_ca_certificates;
+	eap_array_c<ec_cs_data_c> m_client_certificates;
+	eap_array_c<ec_cs_data_c> m_client_private_keys;
+
+	eap_variable_data_c m_peer_identity;
+	eap_variable_data_c m_signature;
+
+	eap_variable_data_c m_hash_of_message;
+	eap_variable_data_c m_id_of_own_certificate;
+
+
+	eap_variable_data_c m_dummy_test_asu_certificate;
+
+	eap_variable_data_c m_dummy_test_asu_private_key;
+
+	eap_variable_data_c m_dummy_test_peer_certificate;
+
+	eap_variable_data_c m_dummy_test_own_certificate;
+
+	eap_variable_data_c m_dummy_test_own_private_key;
+
+
+
+	bool m_is_client;
+
+	bool m_is_valid;
+
+	bool m_shutdown_was_called;
+
+	bool m_reference_counter_read;
+	bool m_reference_counter_changed;
+	u32_t m_reference_counter;
+
+	u32_t m_PAC_store_key_timeout_ms;
+
+	bool m_already_in_completion_action_check;
+
+	bool m_pending_read_ec_cs_data;
+
+	bool m_complete_start_certificate_import;
+
+	bool m_certificate_store_initialized;
+
+	bool m_allow_use_of_ae_certificate;
+
+
+	eap_status_e create_unique_reference(
+		ec_cs_data_c * const out_reference);
+
+	eap_status_e cancel_operations();
+
+#if defined(USE_WAPI_CORE_SERVER) || !defined(WAPI_USE_CERTIFICATE_STORE)
+	eap_status_e read_test_certificate(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+#endif //#if defined(USE_WAPI_CORE_SERVER) || !defined(WAPI_USE_CERTIFICATE_STORE)
+
+	eap_status_e compare_id_and_certificate(
+		const eap_variable_data_c * const ID,
+		const eap_variable_data_c * const certificate);
+
+	eap_status_e compare_issuer_name_of_id_and_certificate(
+		const eap_variable_data_c * const issuer_ID,
+		const eap_variable_data_c * const certificate);
+
+	eap_status_e compare_issuer_common_name_and_certificate(
+		const eap_variable_data_c * const certificate,
+		const eap_variable_data_c * const subject_common_name);
+
+	eap_status_e convert_PEM_to_DER(
+		const wapi_pem_data_type_e key_type,
+		const eap_variable_data_c * const pem_data,
+		eap_array_c<ec_cs_data_c> * const der_data);
+
+	eap_status_e read_PEM_data_line(
+		const eap_variable_data_c * const in_imported_certificate_file_data,
+		u32_t * const offset,
+		eap_variable_data_c * const line);
+
+	eap_status_e parse_PEM_file_data(
+		const eap_variable_data_c * const in_imported_certificate_file_data,
+		eap_array_c<ec_cs_data_c> * const der_data);
+
+	eap_status_e read_certificate_wapi_identity(
+		const eap_variable_data_c * const certificate,
+		eap_variable_data_c * const certificate_wapi_identity);
+
+	eap_status_e copy_certificate_wapi_identities(
+		EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const certificates_id_list,
+		eap_array_c<eap_variable_data_c> * const wapi_identities_list);
+
+	eap_status_e read_certificate_type(
+		const eap_variable_data_c * const imported_certificate_file_data,
+		ec_cs_data_type_e * const data_type);
+
+	eap_status_e read_certificate(
+		const ec_cs_pending_operation_e pending_operation,
+		const ec_cs_data_type_e certificate_type,
+		const eap_variable_data_c * certificate_reference);
+
+	eap_status_e read_both_certificate_lists(
+		const ec_cs_pending_operation_e pending_operation);
+
+	eap_status_e read_ca_certificate_list(
+		const ec_cs_pending_operation_e pending_operation);
+
+	eap_status_e read_client_certificate_list(
+		const ec_cs_pending_operation_e pending_operation);
+
+	eap_status_e save_to_broken_cs_data_list(
+		const ec_cs_data_c * const ref_and_data);
+
+	eap_status_e save_to_ec_cs_list(
+		eap_array_c<ec_cs_data_c> * const ec_cs_list,
+		const ec_cs_data_c * const ref_and_data);
+
+	eap_status_e save_ec_cs_data(
+		EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references_and_data_blocks);
+
+	eap_status_e add_imported_certificate(
+		const ec_cs_data_type_e certificate_type,
+		const eap_variable_data_c * const in_imported_certificate_wapi_id,
+		const eap_variable_data_c * const in_imported_certificate_file_data,
+		const eap_variable_data_c * const in_imported_certificate_filename,
+		eap_array_c<ec_cs_data_c> * const out_asu_id_list,
+		eap_array_c<ec_cs_data_c> * const out_certificates,
+		ec_cs_variable_data_c * const out_certificate_reference);
+
+	eap_status_e add_imported_private_key(
+		const ec_cs_data_type_e private_key_type,
+		const eap_variable_data_c * const in_imported_private_key_file_data,
+		const eap_variable_data_c * const in_imported_private_key_filename,
+		const ec_cs_variable_data_c * const in_certificate_reference,
+		eap_array_c<ec_cs_data_c> * const out_private_keys);
+
+	eap_status_e read_certificate_reference(
+		const ec_cs_data_c * const reference_tlv,
+		eap_variable_data_c * const certificate_reference);
+
+	eap_status_e internal_create_signature_with_private_key();
+
+	eap_status_e internal_select_certificate_with_identity(
+		const eap_variable_data_c * const queried_issuer_ID);
+
+	eap_status_e internal_select_own_certificate_with_issuer_name();
+
+	eap_status_e internal_select_certificate();
+
+	eap_status_e add_asu_id_list(
+		EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const asu_id_list,
+		eap_array_c<ec_cs_data_c> * const data_references);
+
+	eap_status_e save_data_to_permanent_store();
+
+	eap_status_e internal_complete_add_imported_certificate_file();
+
+	eap_status_e query_PAC_store_password(
+		const ec_cs_pending_operation_e in_pending_operation);
+
+	eap_status_e add_password_qyery(
+		eap_array_c<ec_cs_data_c> * const in_references);
+
+
+	//--------------------------------------------------
+
+	eap_status_e are_pending_queries_completed();
+
+	void set_pending_operation(const ec_cs_pending_operation_e operation);
+
+	eap_status_e completion_action_add(
+		ec_cs_completion_e action);
+
+	eap_status_e completion_action_push(
+		ec_cs_completion_e action);
+
+	eap_status_e completion_action_pop();
+
+	eap_status_e completion_action_clenup();
+
+	void completion_action_trace();
+
+	eap_status_e completion_action_check();
+
+	//--------------------------------------------------
+
+	void send_error_notification(const eap_status_e error);
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the ec_certificate_store_c class does nothing.
+	 */
+	EAP_FUNC_IMPORT virtual ~ec_certificate_store_c();
+
+	/**
+	 * The constructor of the ec_certificate_store_c class simply initializes the attributes.
+	 */
+	EAP_FUNC_IMPORT ec_certificate_store_c(
+		abs_eap_am_tools_c * const tools,
+		abs_ec_certificate_store_c * const partner,
+		ec_am_base_certificate_store_c * const am_certificate_store,
+		const bool is_client_when_true);
+
+
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+
+	EAP_FUNC_IMPORT eap_status_e configure();
+
+	EAP_FUNC_IMPORT eap_status_e shutdown();
+
+	EAP_FUNC_IMPORT eap_status_e timer_expired(const u32_t id, void *data);
+
+	EAP_FUNC_IMPORT eap_status_e timer_delete_data(const u32_t id, void *data);
+
+	/**
+	 * Function initializes the certificate store.
+	 * This function is completed by complete_initialize_certificate_store() function call.
+	 */
+	EAP_FUNC_IMPORT eap_status_e initialize_certificate_store();
+
+	EAP_FUNC_IMPORT eap_status_e query_asu_id();
+
+	EAP_FUNC_IMPORT eap_status_e get_own_certificate();
+
+	EAP_FUNC_IMPORT eap_status_e set_ae_certificate(
+		const eap_variable_data_c * const ae_certificate);
+
+	EAP_FUNC_IMPORT eap_status_e select_certificate(
+		const eap_variable_data_c * const issuer_ID);
+
+	EAP_FUNC_IMPORT eap_status_e create_signature_with_private_key(
+		const eap_variable_data_c * const hash_of_message,
+		const eap_variable_data_c * const id_of_certificate);
+
+	EAP_FUNC_IMPORT eap_status_e verify_signature_with_public_key(
+		const eap_variable_data_c * const peer_identity,
+		const eap_variable_data_c * const hash_of_message,
+		const eap_variable_data_c * const signature,
+		const bool allow_use_of_ae_certificate);
+
+	EAP_FUNC_IMPORT eap_status_e read_id_of_certificate(
+		const eap_variable_data_c * const certificate);
+
+	EAP_FUNC_IMPORT eap_status_e create_ecdh_temporary_keys();
+
+	EAP_FUNC_IMPORT eap_status_e create_ecdh(
+		const eap_variable_data_c * const own_private_key_d,
+		const eap_variable_data_c * const peer_public_key_x,
+		const eap_variable_data_c * const peer_public_key_y);
+
+	// This is documented in abs_eap_base_type_c::read_configure().
+	EAP_FUNC_IMPORT virtual eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	// This is documented in abs_ec_algorithms_c::complete_create_signature_with_private_key().
+	EAP_FUNC_IMPORT eap_status_e complete_create_signature_with_private_key(
+		const eap_variable_data_c * const signature,
+		const eap_status_e signature_status);
+
+	// This is documented in abs_ec_algorithms_c::complete_verify_signature_with_public_key().
+	EAP_FUNC_IMPORT eap_status_e complete_verify_signature_with_public_key(
+		const eap_status_e verification_status);
+
+	// This is documented in abs_ec_algorithms_c::complete_create_ecdh_temporary_keys().
+	EAP_FUNC_IMPORT eap_status_e complete_create_ecdh_temporary_keys(
+		const eap_variable_data_c * const private_key_d,
+		const eap_variable_data_c * const public_key_x,
+		const eap_variable_data_c * const public_key_y);
+
+	// This is documented in abs_ec_algorithms_c::complete_create_ecdh().
+	EAP_FUNC_IMPORT eap_status_e complete_create_ecdh(
+		const eap_variable_data_c * const K_AB_x4,
+		const eap_variable_data_c * const K_AB_y4);
+
+	// This is documented in abs_ec_am_certificate_store_c::complete_initialize_certificate_store().
+	EAP_FUNC_IMPORT eap_status_e complete_initialize_certificate_store(
+		const wapi_completion_operation_e completion_operation);
+
+	// This is documented in abs_ec_am_certificate_store_c::remove_cached_certificate_store_data().
+	EAP_FUNC_IMPORT eap_status_e remove_cached_certificate_store_data();
+
+	// This is documented in abs_ec_am_certificate_store_c::add_imported_certificate_file().
+	EAP_FUNC_IMPORT eap_status_e add_imported_certificate_file(
+		const eap_variable_data_c * const in_imported_certificate_file_data,
+		const eap_variable_data_c * const in_imported_certificate_filename);
+
+	// This is documented in abs_ec_am_certificate_store_c::complete_read_certificate_store_data().
+	EAP_FUNC_IMPORT eap_status_e complete_read_certificate_store_data(
+		const eap_status_e in_completion_status,
+		const ec_cs_pending_operation_e in_pending_operation,
+		EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references_and_data_blocks);
+	
+	// This is documented in abs_ec_am_certificate_store_c::complete_write_certificate_store_data().
+	EAP_FUNC_IMPORT eap_status_e complete_write_certificate_store_data(
+		const eap_status_e in_completion_status,
+		const ec_cs_pending_operation_e in_pending_operation);
+
+	// This is documented in abs_ec_am_certificate_store_c::query_certificate_list().
+	EAP_FUNC_IMPORT eap_status_e query_certificate_list();
+
+	EAP_FUNC_IMPORT eap_status_e start_certificate_import();
+
+	EAP_FUNC_IMPORT eap_status_e set_receive_network_id(const eap_am_network_id_c * const receive_network_id);
+
+	//--------------------------------------------------
+}; // ec_certificate_store_c
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CERTIFICATE_STORE_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_compare_certificate_id.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,69 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_compare_certificate_id.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 5 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_COMPARE_CERTIFICATE_ID_H_)
+#define _EC_CS_COMPARE_CERTIFICATE_ID_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_general_header_base.h"
+#include "ec_cs_types.h"
+#include "eap_array_algorithms.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------------
+
+class EAP_EXPORT ec_cs_compare_certificate_id_c
+: public abs_eap_array_compare_c<ec_cs_data_c>
+{
+public:
+
+	EAP_FUNC_IMPORT virtual ~ec_cs_compare_certificate_id_c();
+
+	EAP_FUNC_IMPORT ec_cs_compare_certificate_id_c(
+		abs_eap_am_tools_c * const tools,
+		const eap_variable_data_c * const PAC_store_master_key,
+		const eap_variable_data_c * const PAC_store_device_seed);
+
+	EAP_FUNC_IMPORT i32_t compare(
+		const ec_cs_data_c * const certificate_from_array,
+		const ec_cs_data_c * const certificate_identity) const;
+
+private:
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+	const eap_variable_data_c * const m_PAC_store_master_key;
+
+	const eap_variable_data_c * const m_PAC_store_device_seed;
+};
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_COMPARE_CERTIFICATE_ID_H_)
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_compare_certificate_issuer_name.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,67 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_compare_certificate_issuer_name.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 5 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_COMPARE_CERTIFICATE_ISSUER_NAME_H_)
+#define _EC_CS_COMPARE_CERTIFICATE_ISSUER_NAME_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_general_header_base.h"
+#include "ec_cs_types.h"
+#include "eap_array_algorithms.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------------
+
+class EAP_EXPORT ec_cs_compare_certificate_issuer_name_c
+: public abs_eap_array_compare_c<ec_cs_data_c>
+{
+public:
+
+	EAP_FUNC_IMPORT virtual ~ec_cs_compare_certificate_issuer_name_c();
+
+	EAP_FUNC_IMPORT ec_cs_compare_certificate_issuer_name_c(
+		abs_eap_am_tools_c * const tools,
+		const eap_variable_data_c * const PAC_store_master_key,
+		const eap_variable_data_c * const PAC_store_device_seed);
+
+	EAP_FUNC_IMPORT i32_t compare(
+		const ec_cs_data_c * const certificate_from_array,
+		const ec_cs_data_c * const issuer_name) const;
+
+private:
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+	const eap_variable_data_c * const m_PAC_store_master_key;
+
+	const eap_variable_data_c * const m_PAC_store_device_seed;
+};
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_COMPARE_CERTIFICATE_ISSUER_NAME_H_)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_compare_certificate_reference.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,62 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_compare_certificate_reference.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 4 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_COMPARE_CERTIFICATE_REFERENCE_H_)
+#define _EC_CS_COMPARE_CERTIFICATE_REFERENCE_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_general_header_base.h"
+#include "ec_cs_types.h"
+#include "eap_array_algorithms.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------------
+
+class EAP_EXPORT ec_cs_compare_certificate_reference_c
+: public abs_eap_array_compare_c<ec_cs_data_c>
+{
+public:
+
+	EAP_FUNC_IMPORT virtual ~ec_cs_compare_certificate_reference_c();
+
+	EAP_FUNC_IMPORT ec_cs_compare_certificate_reference_c(
+		abs_eap_am_tools_c * const tools);
+
+	EAP_FUNC_IMPORT i32_t compare(
+		const ec_cs_data_c * const certificate_from_array,
+		const ec_cs_data_c * const certificate_reference) const;
+
+private:
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+};
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_COMPARE_CERTIFICATE_REFERENCE_H_)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_compare_reference.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,64 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_compare_reference_id.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 2 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_COMPARE_REFERENCE_H_)
+#define _EC_CS_COMPARE_REFERENCE_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_general_header_base.h"
+#include "ec_cs_types.h"
+#include "eap_array_algorithms.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------------
+
+class EAP_EXPORT ec_cs_compare_reference_c
+: public abs_eap_array_compare_c<ec_cs_data_c>
+{
+public:
+
+	EAP_FUNC_IMPORT virtual ~ec_cs_compare_reference_c();
+
+	EAP_FUNC_IMPORT ec_cs_compare_reference_c(
+		abs_eap_am_tools_c * const tools);
+
+	EAP_FUNC_IMPORT i32_t compare(
+		const ec_cs_data_c * const reference_from_array,
+		const ec_cs_data_c * const certificate_identity) const;
+
+private:
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+};
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_COMPARE_REFERENCE_H_)
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_compare_reference_id.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,64 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_compare_reference_id.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 3 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_COMPARE_REFERENCE_ID_H_)
+#define _EC_CS_COMPARE_REFERENCE_ID_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_general_header_base.h"
+#include "ec_cs_types.h"
+#include "eap_array_algorithms.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------------
+
+class EAP_EXPORT ec_cs_compare_reference_id_c
+: public abs_eap_array_compare_c<ec_cs_data_c>
+{
+public:
+
+	EAP_FUNC_IMPORT virtual ~ec_cs_compare_reference_id_c();
+
+	EAP_FUNC_IMPORT ec_cs_compare_reference_id_c(
+		abs_eap_am_tools_c * const tools);
+
+	EAP_FUNC_IMPORT i32_t compare(
+		const ec_cs_data_c * const reference_from_array,
+		const ec_cs_data_c * const certificate_identity) const;
+
+private:
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+};
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_COMPARE_REFERENCE_ID_H_)
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_compare_reference_issuer_name.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,64 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_compare_reference_issuer_name.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 3 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_COMPARE_REFERENCE_ISSUER_NAME_H_)
+#define _EC_CS_COMPARE_REFERENCE_ISSUER_NAME_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_general_header_base.h"
+#include "ec_cs_types.h"
+#include "eap_array_algorithms.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------------
+
+class EAP_EXPORT ec_cs_compare_reference_issuer_name_c
+: public abs_eap_array_compare_c<ec_cs_data_c>
+{
+public:
+
+	EAP_FUNC_IMPORT virtual ~ec_cs_compare_reference_issuer_name_c();
+
+	EAP_FUNC_IMPORT ec_cs_compare_reference_issuer_name_c(
+		abs_eap_am_tools_c * const tools);
+
+	EAP_FUNC_IMPORT i32_t compare(
+		const ec_cs_data_c * const reference_from_array,
+		const ec_cs_data_c * const certificate_identity) const;
+
+private:
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+};
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_COMPARE_REFERENCE_ISSUER_NAME_H_)
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_completion.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,131 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_completion.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 14 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_COMPLETION_H_)
+#define _EC_CS_COMPLETION_H_
+
+#include "eap_am_export.h"
+#include "eap_am_types.h"
+#include "eap_variable_data.h"
+#include "eap_array_algorithms.h"
+#include "ec_cs_tlv_header.h"
+#include "ec_cs_types.h"
+
+
+/** @file */
+
+//----------------------------------------------------------------------------
+
+/**
+ * This is enumeration of EC certificate store competion actions.
+ */
+enum ec_cs_completion_e
+{
+	ec_cs_completion_none,                           ///< Initialization value means no action.
+	ec_cs_completion_internal_select_certificate,
+	ec_cs_completion_internal_select_certificate_with_identity,
+	ec_cs_completion_internal_complete_add_imported_certificate_file,
+	ec_cs_completion_complete_add_imported_certificate_file,
+	ec_cs_completion_query_PAC_store_password,
+	ec_cs_completion_add_imported_ca_certificate,
+	ec_cs_completion_add_imported_client_certificate,
+	ec_cs_completion_internal_create_signature_with_private_key,
+	ec_cs_completion_complete_query_certificate_list,
+	ec_cs_completion_internal_verify_signature_with_public_key,
+};
+
+//----------------------------------------------------------------------------
+
+
+/// This class defines one EC certificate store completion action.
+class EAP_EXPORT ec_cs_completion_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class. @see abs_eap_am_tools_c.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	/// This variable stores the completion action.
+	ec_cs_completion_e m_completion_action;
+
+	/// This indicates whether this object was generated successfully.
+	bool m_is_valid;
+
+	/**
+	 * The set_is_valid() function sets the state of the object valid.
+	 * The creator of this object calls this function after it is initialized. 
+	 */
+	EAP_FUNC_IMPORT void set_is_valid();
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * Destructor does nothing special.
+	 */
+	EAP_FUNC_IMPORT virtual ~ec_cs_completion_c();
+
+	/**
+	 * Constructor initializes object.
+	 */
+	EAP_FUNC_IMPORT ec_cs_completion_c(
+		abs_eap_am_tools_c * const tools,
+		ec_cs_completion_e completion_action);
+
+	/**
+	 * Object must indicate it's validity.
+	 * If object initialization fails this function must return false.
+	 * @return This function returns the validity of this object.
+	 */
+	EAP_FUNC_IMPORT bool get_is_valid();
+
+	/**
+	 * This function sets the completion action type.
+	 */
+	EAP_FUNC_IMPORT void set_completion_action(ec_cs_completion_e completion_action);
+
+	/**
+	 * This function gets the completion action type.
+	 */
+	EAP_FUNC_IMPORT ec_cs_completion_e get_completion_action() const;
+
+	/**
+	 * This function gets the debug string of the completion action type.
+	 */
+	EAP_FUNC_IMPORT static eap_const_string get_completion_action_string(ec_cs_completion_e completion_action);
+
+	// 
+	//--------------------------------------------------
+}; // class ec_cs_completion_c
+
+
+//----------------------------------------------------------------------------
+
+#endif //#if !defined(_EC_CS_COMPLETION_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_data.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,121 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_data.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 5 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_DATA_H_)
+#define _EC_CS_DATA_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_cs_types.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------------
+
+class abs_eap_am_tools_c;
+
+
+class EAP_EXPORT ec_cs_data_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	ec_cs_data_change_status_e m_change_status;
+
+	ec_cs_data_type_e m_type;
+
+	eap_variable_data_c m_reference;
+
+	eap_variable_data_c m_data;
+
+	bool m_data_references_read;
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the ec_cs_data_c class does nothing.
+	 */
+	EAP_FUNC_IMPORT virtual ~ec_cs_data_c();
+
+	/**
+	 * The constructor of the ec_cs_data_c class simply initializes the attributes.
+	 */
+	EAP_FUNC_IMPORT ec_cs_data_c(
+		abs_eap_am_tools_c * const tools);
+
+
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+	EAP_FUNC_IMPORT bool get_is_valid_data() const;
+
+
+	EAP_FUNC_IMPORT ec_cs_data_change_status_e get_change_status() const;
+
+	EAP_FUNC_IMPORT void set_change_status(const ec_cs_data_change_status_e change_status);
+
+	
+	EAP_FUNC_IMPORT ec_cs_data_type_e get_type() const;
+
+	EAP_FUNC_IMPORT void set_type(const ec_cs_data_type_e type);
+
+
+	EAP_FUNC_IMPORT const eap_variable_data_c * get_reference() const;
+
+	EAP_FUNC_IMPORT const eap_variable_data_c * get_data() const;
+
+	EAP_FUNC_IMPORT eap_variable_data_c * get_writable_reference();
+
+	EAP_FUNC_IMPORT eap_variable_data_c * get_writable_data();
+
+	EAP_FUNC_IMPORT ec_cs_data_c * copy() const;
+
+	EAP_FUNC_IMPORT i32_t compare(const ec_cs_data_c * const data) const;
+
+	EAP_FUNC_IMPORT eap_status_e reset();
+
+	EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer(const ec_cs_data_c * const source);
+
+
+	EAP_FUNC_IMPORT bool get_data_references_read();
+
+	EAP_FUNC_IMPORT void set_data_references_read();
+
+	//--------------------------------------------------
+}; // ec_cs_data_c
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_DATA_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_strings.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,66 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_strings.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 7 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_STRINGS_H_)
+#define _EC_CS_STRINGS_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_general_header_base.h"
+#include "ec_cs_types.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------------
+
+/// This class includes the debug strings of the Elliptic curve certificate store.
+class EAP_EXPORT ec_cs_strings_c
+{
+public:
+
+	EAP_FUNC_IMPORT virtual ~ec_cs_strings_c();
+
+	EAP_FUNC_IMPORT ec_cs_strings_c();
+
+	EAP_FUNC_IMPORT static eap_const_string get_ec_cs_store_data_string(const ec_cs_data_type_e type);
+
+	EAP_FUNC_IMPORT static eap_const_string get_ec_cs_store_data_change_status_string(const ec_cs_data_change_status_e status);
+
+	EAP_FUNC_IMPORT static eap_const_string get_ec_cs_store_data_string(const ec_cs_pending_operation_e type);
+
+	/**
+	 * Function returns string of ec_cs_tlv_type_e.
+	 * @param status is the queried string.
+	 */
+	EAP_FUNC_IMPORT static eap_const_string get_ec_cs_tlv_header_string(const ec_cs_tlv_type_e type);
+
+};
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_STRINGS_H_)
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_tlv.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,223 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_tlv.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 9 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_TLV_H_)
+#define _EC_CS_TLV_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_cs_tlv_header.h"
+#include "ec_cs_types.h"
+
+
+/** @file */
+
+class ec_cs_variable_data_c;
+class tls_extension_c;
+class ec_cs_tlv_payloads_c;
+class ec_cs_data_c;
+
+//----------------------------------------------------------------------------
+
+
+/// This class defines EC CS TLV.
+/**
+ * EC CS TLV is constructed with Attribute-Value Pairs.
+ */
+class EAP_EXPORT ec_cs_tlv_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	ec_cs_tlv_payloads_c * m_payloads;
+
+	bool m_is_client;
+
+	bool m_is_valid;
+
+	//--------------------------------------------------
+
+	eap_status_e create_MAC(
+		eap_variable_data_c * const MAC,
+		const eap_variable_data_c * const server_opaque_mac_key,
+		const eap_variable_data_c * const protected_data);
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the ec_cs_tlv_c class does nothing.
+	 */
+	EAP_FUNC_IMPORT virtual ~ec_cs_tlv_c();
+
+	/**
+	 * The constructor of the ec_cs_tlv_c class simply initializes the attributes.
+	 */
+	EAP_FUNC_IMPORT ec_cs_tlv_c(
+		abs_eap_am_tools_c * const tools,
+		const bool true_when_is_client);
+
+
+	EAP_FUNC_IMPORT const ec_cs_tlv_payloads_c * get_payloads() const;
+
+
+	EAP_FUNC_IMPORT bool get_is_valid();
+
+	EAP_FUNC_IMPORT eap_status_e reset();
+
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT eap_status_e generate_data_key(
+		const bool in_true_when_encryption_key,
+		const ec_cs_data_type_e in_data_type,
+		eap_variable_data_c * const out_MAC_key,
+		const eap_variable_data_c * const in_base_key,
+		const eap_variable_data_c * const in_data_reference,
+		const eap_variable_data_c * const in_CS_store_device_seed);
+
+	/**
+	 * Function creates the Master key data block.
+	 * Parameter in_CS_master_key_or_null is optional.
+	 * Null parameter value generates a new Master key with random data.
+	 */
+	EAP_FUNC_IMPORT eap_status_e create_master_key_data(
+		const eap_variable_data_c * const in_CS_password,
+		const eap_variable_data_c * const in_CS_store_device_seed,
+		const eap_variable_data_c * const in_CS_master_key_or_null,
+		const eap_variable_data_c * const in_data_reference,
+		eap_variable_data_c * const master_key_data);
+
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT eap_status_e create_tlv(
+		ec_cs_variable_data_c *const new_tlv,
+		const ec_cs_tlv_type_e type,
+		const eap_variable_data_c * const pac_attributes);
+
+
+	EAP_FUNC_IMPORT eap_status_e create_generic_tlv(
+		ec_cs_variable_data_c * const new_tlv,
+		const ec_cs_tlv_type_e type,
+		const eap_variable_data_c * const payload);
+
+	EAP_FUNC_IMPORT eap_status_e create_u32_t_tlv(
+		ec_cs_variable_data_c * const new_tlv,
+		const ec_cs_tlv_type_e type,
+		const u32_t value);
+
+	EAP_FUNC_IMPORT eap_status_e create_u16_t_tlv(
+		ec_cs_variable_data_c * const new_tlv,
+		const ec_cs_tlv_type_e type,
+		const u16_t value);
+
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT eap_status_e read_generic_tlv(
+		const ec_cs_variable_data_c * const tlv,
+		const ec_cs_tlv_type_e type,
+		eap_variable_data_c * const payload);
+
+	EAP_FUNC_IMPORT eap_status_e read_u32_t_tlv(
+		const ec_cs_variable_data_c * const tlv,
+		const ec_cs_tlv_type_e type,
+		u32_t * const value);
+
+	EAP_FUNC_IMPORT eap_status_e read_u16_t_tlv(
+		const ec_cs_variable_data_c * const tlv,
+		const ec_cs_tlv_type_e type,
+		u16_t * const value);
+
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT eap_status_e create_encrypted_tlv(
+		const ec_cs_tlv_type_e in_TLV_Type,
+		const eap_variable_data_c * const in_encryption_key,
+		const ec_cs_variable_data_c * const in_plaintext_data_TLV,
+		ec_cs_variable_data_c * const out_new_tlv);
+
+	EAP_FUNC_IMPORT eap_status_e parse_encrypted_tlv(
+		const eap_variable_data_c * const in_decryption_key,
+		const ec_cs_variable_data_c * const in_encrypted_block_tlv,
+		ec_cs_variable_data_c * const out_plain_text_tlv);
+
+	EAP_FUNC_IMPORT eap_status_e create_data_with_MAC(
+		const eap_variable_data_c * const MAC_key,
+		const eap_variable_data_c * const in_data,
+		eap_variable_data_c * const out_data_tlv);
+
+	EAP_FUNC_IMPORT eap_status_e verify_data_with_MAC(
+		const eap_variable_data_c * const in_base_key,
+		const eap_variable_data_c * const in_CS_store_device_seed,
+		const ec_cs_data_c * const in_CS_data_with_MAC);
+
+	EAP_FUNC_IMPORT eap_status_e parse_data_with_MAC(
+		const eap_variable_data_c * const in_MAC_key,
+		const eap_variable_data_c * const in_CS_data_with_MAC);
+
+	EAP_FUNC_IMPORT eap_status_e parse_cs_tlv(
+		const ec_cs_variable_data_c * const in_PAC_tlv);
+
+	EAP_FUNC_IMPORT eap_status_e parse_encrypted_tlv_with_MAC(
+		const ec_cs_data_type_e in_data_type,
+		const eap_variable_data_c * const in_base_key,
+		const eap_variable_data_c * const in_data_reference,
+		const eap_variable_data_c * const in_CS_store_device_seed,
+		const eap_variable_data_c * const in_data_tlv,
+		ec_cs_variable_data_c * const out_plain_text_tlv);
+
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT eap_status_e create_encrypted_certificate(
+		const ec_cs_data_type_e in_data_type,
+		const eap_variable_data_c * const in_base_key,
+		const eap_variable_data_c * const in_data_reference,
+		const eap_variable_data_c * const in_CS_store_device_seed,
+		const eap_variable_data_c * const in_certificate_reference,
+		const ec_cs_tlv_type_e in_certificate_tlv_type,
+		const eap_variable_data_c * const in_certificate_data,
+		eap_variable_data_c * const out_certificate_data_block);
+
+	EAP_FUNC_IMPORT eap_status_e parse_encrypted_certificate(
+		const ec_cs_data_type_e in_data_type,
+		const eap_variable_data_c * const in_base_key,
+		const eap_variable_data_c * const in_data_reference,
+		const eap_variable_data_c * const in_CS_store_device_seed,
+		const eap_variable_data_c * const in_certificate_data_block,
+		eap_variable_data_c * const out_certificate_reference);
+
+	//--------------------------------------------------
+
+}; // class ec_cs_tlv_c
+
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_TLV_H_)
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_tlv_header.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,225 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_tlv_header.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 12 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_TLV_HEADER_H_)
+#define _EC_CS_TLV_HEADER_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_general_header_base.h"
+#include "ec_cs_types.h"
+
+/** @file */
+
+
+//----------------------------------------------------------------------------
+
+
+/// This class defines header of Attribute-Value Pairs.
+/**
+ * Here is a figure of header of Attribute-Value Pairs.
+ * Value data follows ec_cs_tlv_header_c.
+ * @code
+ *  TLV-header:
+ *  0                   1                   2                   3   
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |             Type              |            Length             |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                              Value...
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * @endcode
+ * 
+ * @code
+ * The fields of this header are:
+ * 16-bits Type;                   This is a TLV type.
+ * 16-bits value length (Length);  This is a length field, the length (in bytes) of the following value.
+ * @endcode
+ * 
+ * For details see <a href="../../../internal/doc/WAPI/WAPI_design.doc">WAPI_design.doc</a>.
+ */
+class EAP_EXPORT ec_cs_tlv_header_c
+: public eap_general_header_base_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	/// This is enumeration of offsets to data fields.
+	enum sizes
+	{
+		m_type_size = sizeof(u16_t),    ///< This is size of type 16-bit field.
+		m_length_size = sizeof(u16_t), ///< This is size of length 16-bit field.
+	};
+
+	/// This is enumeration of offsets to data fields.
+	enum offsets
+	{
+		m_type_offset = 0ul,                           ///< This is offset to type 16-bit field.
+		m_length_offset = m_type_offset+m_type_size,   ///< This is offset to length 16-bit field.
+		m_data_offset = m_length_offset+m_length_size, ///< This is offset to data field.
+	};
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the ec_cs_tlv_header_c class does nothing.
+	 */
+	virtual ~ec_cs_tlv_header_c();
+
+	/**
+	 * The constructor of the ec_cs_tlv_header_c class simply initializes the attributes.
+	 */
+	ec_cs_tlv_header_c(
+		abs_eap_am_tools_c * const tools,
+		void * const header_begin,
+		const u32_t header_buffer_length);
+
+	/**
+	 * This function returns the TLV Type.
+	 */
+	ec_cs_tlv_type_e get_type() const;
+
+	/**
+	 * This function returns the data length of TLV.
+	 */
+	u32_t get_data_length() const;
+
+	/**
+	 * This function returns the header length of TLV.
+	 */
+	static u32_t get_header_length();
+
+	/**
+	 * This function returns pointer to the offset of data of TLV.
+	 * @param offset is the offset of queried data in bytes.
+	 * @param contignuous_bytes is the length of queried data in bytes.
+	 */
+	u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const;
+
+
+	/**
+	 * This function returns pointer to the offset of data of TLV.
+	 * @param contignuous_bytes is the length of queried data in bytes.
+	 */
+	u8_t * get_data(const u32_t contignuous_bytes) const;
+
+
+	/**
+	 * This function return pointer to the next TLV header in the same buffer.
+	 */
+	u8_t * get_next_header() const;
+
+
+	/**
+	 * This function checks the header is valid.
+	 */
+	eap_status_e check_header() const;
+
+	/**
+	 * This function returns debug strings of the TLV type.
+	 */
+	static eap_const_string get_tlv_string(const ec_cs_tlv_type_e type);
+
+	/**
+	 * This function returns debug strings of the TLV type.
+	 */
+	eap_const_string get_tlv_string() const;
+
+	/**
+	 * This function sets the TLV Type.
+	 */
+	eap_status_e set_type(const ec_cs_tlv_type_e type);
+
+	/**
+	 * This function sets the TLV data length.
+	 */
+	eap_status_e set_data_length(const u32_t p_length);
+
+	/**
+	 * This function resets the TLV header.
+	 */
+	eap_status_e reset_header();
+
+	/**
+	 * This function resets the TLV header object.
+	 */
+	eap_status_e reset();
+
+	// 
+	//--------------------------------------------------
+}; // class ec_cs_tlv_header_c
+
+//----------------------------------------------------------------------------------
+
+/// Macro traces payload type and data.
+#define EC_CS_TLV_TRACE_PAYLOAD(prefix, payload, when_true_is_client) \
+	{ \
+		EAP_TRACE_DEBUG( \
+			m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v \n"))); \
+		if ((payload) != 0 && (payload)->get_is_valid() == true)									\
+		{ \
+			EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+				(EAPL("- buffer"), (payload)->get_header_buffer((payload)->get_header_buffer_length()), \
+				 (payload)->get_header_buffer_length()));				\
+			EAP_TRACE_DEBUG(											\
+				m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,		\
+				(EAPL("- %s %s (0x%08x): TLV type 0x%04x=%s, data length 0x%04x.\n"), \
+				 prefix,												\
+				 ((when_true_is_client) == true ? "client" : "server"), \
+				 (payload)->get_header_buffer((payload)->get_data_length()), \
+				 (payload)->get_type(),									\
+				 (payload)->get_tlv_string(),							\
+				 (payload)->get_data_length()));						\
+			EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+				((payload)->get_tlv_string(), (payload)->get_data((payload)->get_data_length()), \
+				 (payload)->get_data_length()));						\
+		} \
+		else \
+		{ \
+			EAP_TRACE_DEBUG(									\
+				m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,		\
+				(EAPL("payload=0x%08x is illegal.\n"), payload));				\
+		} \
+		EAP_TRACE_DEBUG( \
+			m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ \n"))); \
+	}
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_TLV_HEADER_H_)
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_tlv_message.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,119 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_tlv_message.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 6 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_TLV_MESSAGE_H_)
+#define _EC_CS_TLV_MESSAGE_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_array.h"
+
+/** @file */
+
+
+//----------------------------------------------------------------------------
+
+
+/// This class defines one EC-CS-message. One EC-CS message could include many EC-CS TLV attributes.
+/**
+ * This class defined one EC-CS-message.
+ * Parse and analyse of EC-CS-message is asyncronous.
+ * m_analyse_index tells the index of message where asyncronous
+ * analyse of EC-CS-message must continue.
+ * Analysed messages are skipped during the asyncronous
+ * analyse of messages. Asyncronous analyse is needed
+ * because of the PKI functions are asyncronous in
+ * Symbian.
+ */
+class EAP_EXPORT ec_cs_tlv_message_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class. @see abs_eap_am_tools_c.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	/// This buffer includes copy of the whole received EC-CS-message data.
+	eap_variable_data_c m_message_data;
+
+	/// This indicates whether this object is client (true) or server (false). This is mostly for traces.
+	const bool m_is_client;
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the ec_cs_tlv_message_c class does nothing special.
+	 */
+	EAP_FUNC_IMPORT virtual ~ec_cs_tlv_message_c();
+
+	/**
+	 * The constructor of the ec_cs_tlv_message_c class simply initializes the attributes.
+	 */
+	EAP_FUNC_IMPORT ec_cs_tlv_message_c(
+		abs_eap_am_tools_c * const tools,
+		const bool is_client);
+
+	/**
+	 * This function resets this object.
+	 */
+	EAP_FUNC_IMPORT eap_status_e reset();
+
+	/**
+	 * This function copies the received EC-CS-message data.
+	 */
+	EAP_FUNC_IMPORT eap_status_e set_ec_cs_message_data(
+		eap_variable_data_c * const ec_cs_message_data);
+
+	/**
+	 * This function returns the EC-CS-message data.
+	 */
+	EAP_FUNC_IMPORT eap_variable_data_c * get_ec_cs_message_data();
+
+	/**
+	 * Function adds padding for block size if it is needed.
+	 */
+	EAP_FUNC_IMPORT eap_status_e add_padding(const u32_t block_size);
+
+	/**
+	 * Object must indicate it's validity.
+	 * If object initialization fails this function must return false.
+	 * @return This function returns the validity of this object.
+	 */
+	EAP_FUNC_IMPORT bool get_is_valid();
+	// 
+	//--------------------------------------------------
+}; // class ec_cs_tlv_message_c
+
+
+//--------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_TLV_MESSAGE_H_)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_tlv_payloads.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,265 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_tlv_payloads.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 9 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_TLV_PAYLOADS_H_)
+#define _EC_CS_TLV_PAYLOADS_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_variable_data.h"
+#include "eap_am_export.h"
+#include "ec_cs_tlv_header.h"
+#include "eap_core_map.h"
+#include "eap_array.h"
+
+class ec_cs_tlv_message_c;
+class crypto_hmac_c;
+
+
+class EAP_EXPORT ec_cs_variable_data_c
+{
+private:
+	//--------------------------------------------------
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+	eap_variable_data_c m_data;
+
+	ec_cs_tlv_header_c m_header;
+
+	/// This is pointer to the next payload that have same tlv type.
+	/// This link is used when multiple instances of the same tlv types are included to a message.
+	ec_cs_variable_data_c * m_next_payload_with_same_tlv_type;
+
+	bool m_is_valid;
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT virtual ~ec_cs_variable_data_c();
+
+	EAP_FUNC_IMPORT ec_cs_variable_data_c(abs_eap_am_tools_c * const tools);
+
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+	EAP_FUNC_IMPORT bool get_is_valid_data() const;
+
+	EAP_FUNC_IMPORT eap_status_e reset();
+
+	EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer(
+		const ec_cs_tlv_type_e current_payload_code,
+		const void * const buffer,
+		const u32_t buffer_length);
+
+	EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer(
+		const ec_cs_variable_data_c * const source);
+
+	EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer(
+		const void * const buffer,
+		const u32_t buffer_length);
+
+	EAP_FUNC_IMPORT eap_status_e init_header(
+		const ec_cs_tlv_type_e current_payload,
+		const u32_t default_buffer_length);
+
+	EAP_FUNC_IMPORT eap_status_e add_data(
+		const void * const buffer,
+		const u32_t buffer_length);
+
+	EAP_FUNC_IMPORT eap_status_e add_data(
+		const ec_cs_variable_data_c * const data);
+
+	EAP_FUNC_IMPORT u32_t get_data_length() const;
+
+	EAP_FUNC_IMPORT u8_t * get_data(const u32_t data_length) const;
+
+	EAP_FUNC_IMPORT u8_t * get_data_offset(const u32_t offset, const u32_t data_length) const;
+
+	EAP_FUNC_IMPORT const ec_cs_tlv_header_c * get_header() const;
+
+	EAP_FUNC_IMPORT const eap_variable_data_c * get_full_tlv_buffer() const;
+
+	EAP_FUNC_IMPORT eap_variable_data_c * get_writable_full_tlv_buffer();
+
+	EAP_FUNC_IMPORT ec_cs_tlv_type_e get_type() const;
+
+	EAP_FUNC_IMPORT void set_type(const ec_cs_tlv_type_e type);
+
+	EAP_FUNC_IMPORT void add_next_payload_with_same_tlv_type(ec_cs_variable_data_c * const tlv);
+
+	EAP_FUNC_IMPORT void set_next_payload_with_same_tlv_type(ec_cs_variable_data_c * tlv);
+
+	EAP_FUNC_IMPORT ec_cs_variable_data_c * get_next_payload_with_same_tlv_type() const;
+
+	EAP_FUNC_IMPORT ec_cs_variable_data_c * copy() const;
+
+	EAP_FUNC_IMPORT void object_increase_reference_count();
+
+	EAP_FUNC_IMPORT eap_status_e check_header() const;
+
+	EAP_FUNC_IMPORT i32_t compare(const ec_cs_variable_data_c * right) const;
+
+	//--------------------------------------------------
+}; // class ec_cs_variable_data_c
+
+
+//--------------------------------------------------
+
+
+// 
+class EAP_EXPORT ec_cs_tlv_payloads_c
+: public abs_eap_core_map_c
+{
+private:
+	//--------------------------------------------------
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+	/// This stores the ec_cs_variable_data_c objects using eap_variable_data selector.
+	eap_core_map_c<ec_cs_variable_data_c, abs_eap_core_map_c, eap_variable_data_c> m_payload_map;
+
+	/// This stores the same ec_cs_variable_data_c objects to array.
+	/// This is to speed the sequential check of all payloads.
+	eap_array_c<ec_cs_variable_data_c> m_read_payloads;
+
+	/// This index is used when payloads are retrieved in order.
+	u32_t m_payload_index;
+
+	bool m_is_client;
+
+	bool m_is_valid;
+
+	eap_status_e verify_padding(
+		const u8_t * const possible_padding,
+		const u32_t possible_padding_length);
+
+	eap_status_e get_tlv_data(
+		const ec_cs_tlv_type_e copied_tlv_type,
+		void * const data,
+		const u32_t data_length) const;
+
+	/**
+	 * This function parses each payload tlvs.
+	 * @return If payload tlv is illegal function returns eap_status_header_corrupted.
+	 * If payload tlv is unknown function returns eap_status_unsupported_payload.
+	 */
+	EAP_FUNC_IMPORT eap_status_e parse_generic_payload(
+		const ec_cs_tlv_type_e current_payload, ///< This is the type of current payload tlv.
+		const ec_cs_tlv_header_c * const payload ///< This is the current parsed payload.
+		);
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT virtual ~ec_cs_tlv_payloads_c();
+
+	EAP_FUNC_IMPORT ec_cs_tlv_payloads_c(
+		abs_eap_am_tools_c * const tools,
+		const bool true_when_is_client);
+
+	EAP_FUNC_IMPORT ec_cs_variable_data_c * get_tlv_pointer(
+		const ec_cs_tlv_type_e current_payload,
+		u32_t index) const;
+
+	EAP_FUNC_IMPORT ec_cs_variable_data_c * get_tlv_pointer(
+		const ec_cs_tlv_type_e current_payload) const;
+
+
+	EAP_FUNC_IMPORT u32_t get_tlv_count() const;
+
+	EAP_FUNC_IMPORT ec_cs_variable_data_c * get_tlv(const u32_t tlv_index) const;
+
+	/**
+	 * This function adds new_payload object to payloads.
+	 * NOTE the data is NOT copied.
+	 */
+	EAP_FUNC_IMPORT eap_status_e add_tlv(
+		ec_cs_variable_data_c *new_payload);
+
+	/**
+	 * This function copies the selected tlv from source to payloads.
+	 */
+	EAP_FUNC_IMPORT eap_status_e copy_tlv(
+		const ec_cs_tlv_payloads_c * const source,
+		const ec_cs_tlv_type_e tlv);
+
+	/**
+	 * This function copies the tlv data to payloads.
+	 */
+	EAP_FUNC_IMPORT eap_status_e copy_tlv_data(
+		const ec_cs_tlv_type_e current_payload,
+		const void * const data,
+		const u32_t data_length);
+
+	/**
+	 * This function parses the payloads starting from specified payload (p_payload).
+	 * Function parses all payloads from the buffer.
+	 * Payloads are stored to member variables.
+	 * @return If the length of the buffer and sum of the length of all payloads does not match
+	 * function returns eap_status_header_corrupted.
+	 * Also error is returned when illegal payload tlv is recognised.
+	 */
+	EAP_FUNC_IMPORT eap_status_e parse_ec_cs_payloads(
+		void * const message_buffer, ///< This is the start of the message buffer.
+		u32_t * const buffer_length, ///< This is the length of the buffer. This must match with the length of all payloads.
+		u32_t * const padding_length ///< Length of possible padding is set to this variable.
+		);
+
+	EAP_FUNC_IMPORT eap_status_e check_payloads_existense(
+		const ec_cs_tlv_type_e * const needed_payloads,
+		const u32_t count_of_needed_payloads) const;
+
+	/**
+	 * This function checks all required AVPs are received.
+	 */
+	EAP_FUNC_IMPORT eap_status_e check_payloads_existense(
+		EAP_TEMPLATE_CONST eap_array_c<ec_cs_tlv_type_e> * const needed_payloads) const;
+
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+	EAP_FUNC_IMPORT eap_status_e create_ec_cs_tlv_message(
+		ec_cs_tlv_message_c * const new_ec_cs_tlv_message_data,
+		const bool add_payloads) const;
+
+	EAP_FUNC_IMPORT eap_status_e reset();
+
+	EAP_FUNC_IMPORT ec_cs_tlv_payloads_c * copy() const;
+
+	//--------------------------------------------------
+}; // class ec_cs_tlv_payloads_c
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_TLV_PAYLOADS_H_)
+
+//--------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/ec_cs_types.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,160 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/ec_cs_types.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 27 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_EC_CS_TYPES_H_)
+#define _EC_CS_TYPES_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------
+
+const u8_t EC_CS_ENCRYPTION_KEY_LABEL[] = "CS Encryption Key";
+const u32_t EC_CS_ENCRYPTION_KEY_LABEL_SIZE = sizeof(EC_CS_ENCRYPTION_KEY_LABEL)-1ul;
+
+const u8_t EC_CS_MAC_KEY_LABEL[] = "CS MAC Key";
+const u32_t EC_CS_MAC_KEY_LABEL_SIZE = sizeof(EC_CS_MAC_KEY_LABEL)-1ul;
+
+const u8_t EC_CS_SEED_SEPARATOR[] = { 0x00 };
+const u32_t EC_CS_SEED_SEPARATOR_SIZE = sizeof(EC_CS_SEED_SEPARATOR);
+
+const u8_t EC_CS_MASTER_KEY_SEED[] = "CS-Master-Key";
+const u32_t EC_CS_MASTER_KEY_SEED_SIZE = sizeof(EC_CS_MASTER_KEY_SEED);
+
+const u8_t EC_CS_REFERENCE_COUNTER_SEED[] = "Reference counter";
+const u32_t EC_CS_REFERENCE_COUNTER_SEED_SIZE = sizeof(EC_CS_REFERENCE_COUNTER_SEED);
+
+const u8_t EC_CS_CA_CERTIFICATE_DATA_DATA_SEED[] = "CA-Certificate-Data";
+const u32_t EC_CS_CA_CERTIFICATE_DATA_DATA_SEED_SIZE = sizeof(EC_CS_CA_CERTIFICATE_DATA_DATA_SEED);
+
+const u8_t EC_CS_USER_CERTIFICATE_DATA_DATA_SEED[] = "User-Certificate-Data";
+const u32_t EC_CS_USER_CERTIFICATE_DATA_DATA_SEED_SIZE = sizeof(EC_CS_USER_CERTIFICATE_DATA_DATA_SEED);
+
+const u8_t EC_CS_PRIVATE_KEY_DATA_SEED[] = "Private-Key-Data";
+const u32_t EC_CS_PRIVATE_KEY_DATA_SEED_SIZE = sizeof(EC_CS_PRIVATE_KEY_DATA_SEED);
+
+const u8_t EC_CS_CA_ASU_ID_DATA_SEED[] = "CA-ASU-ID";
+const u32_t EC_CS_CA_ASU_ID_DATA_SEED_SIZE = sizeof(EC_CS_CA_ASU_ID_DATA_SEED);
+
+const u8_t EC_CS_CLIENT_ASU_ID_DATA_SEED[] = "Client-ASU-ID";
+const u32_t EC_CS_CLIENT_ASU_ID_DATA_SEED_SIZE = sizeof(EC_CS_CLIENT_ASU_ID_DATA_SEED);
+
+const u32_t EC_CS_MASTER_KEY_SIZE = 32ul;
+const u32_t EC_CS_ENCRYPTION_KEY_SIZE = 16ul;
+const u32_t EC_CS_MAC_KEY_SIZE = 32ul;
+
+const u8_t EC_CS_ZERO_REFERENCE[] = { 0x00, 0x00, 0x00, 0x00, };
+
+const char WAPI_CS_MEMORY_STORE_KEY[] = "ec_certificate_store_c CS";
+
+const u32_t EAP_FAST_PAC_STORE_DEFAULT_KEY_CACHE_TIMEOUT = 43200000u; // in milliseconds = 12 hours
+
+const u32_t EAP_FAST_PAC_STORE_MASTER_KEY_SIZE = 32ul;
+const u32_t EAP_FAST_PAC_STORE_ENCRYPTION_KEY_SIZE = 16ul;
+const u32_t EAP_FAST_PAC_STORE_MAC_KEY_SIZE = 32ul;
+
+//----------------------------------------------------------------------------
+
+/// Enumeration describes the pending operation of Elliptic Curve Certificate Store.
+enum ec_cs_pending_operation_e
+{
+	ec_cs_pending_operation_none,
+	ec_cs_pending_operation_certificate_authentication,
+	ec_cs_pending_operation_import_ca_certificate_file,
+	ec_cs_pending_operation_import_client_certificate_file,
+	ec_cs_pending_operation_select_client_certificate,
+	ec_cs_pending_operation_query_certificate_list,
+	ec_cs_pending_operation_verify_signature_with_public_key,
+};
+
+/// Enumeration describes the valid types of ec_cs_data_type_e.
+enum ec_cs_data_type_e
+{
+	ec_cs_data_type_none,
+	ec_cs_data_type_master_key,
+	ec_cs_data_type_password,
+	ec_cs_data_type_device_seed,
+	ec_cs_data_type_reference_counter,
+	ec_cs_data_type_certificate_reference,
+	ec_cs_data_type_certificate_file_password,
+	ec_cs_data_type_ca_asu_id_list, // Read all ec_cs_data_type_ca_asu_id objects.
+	ec_cs_data_type_ca_asu_id,
+	ec_cs_data_type_client_asu_id_list, // Read all ec_cs_data_type_client_asu_id objects.
+	ec_cs_data_type_client_asu_id,
+	ec_cs_data_type_ca_certificate_data,
+	ec_cs_data_type_client_certificate_data,
+	ec_cs_data_type_private_key_data,
+	ec_cs_data_type_selected_ca_id,
+	ec_cs_data_type_selected_client_id,
+	ec_cs_data_type_user_authorization_reference, // This is used in internal RAM memory store.
+	ec_cs_data_type_user_authorization_data, // This is used in internal RAM memory store.
+};
+
+/// Enumeration describes the change status of written ec_cs_data_c.
+/// This value tells during write_certificate_store_data() whether the status is modified, new or delete.
+enum ec_cs_data_change_status_e
+{
+	ec_cs_data_change_status_none,
+	ec_cs_data_change_status_modified,
+	ec_cs_data_change_status_new,
+	ec_cs_data_change_status_delete,
+};
+
+/**
+ * This is enumeration of Certificate Store Type-Length-Value (TLV) values.
+ */
+enum ec_cs_tlv_type_e
+{
+	ec_cs_tlv_type_none,
+
+	ec_cs_tlv_type_Import_File,
+	ec_cs_tlv_type_Import_File_Password,
+
+	ec_cs_tlv_type_CS_certificate_data,
+	ec_cs_tlv_type_CS_private_key_data,
+
+	ec_cs_tlv_type_CS_ASU_ID,
+	ec_cs_tlv_type_CS_ID_reference,
+	ec_cs_tlv_type_CS_certificate_reference,
+	ec_cs_tlv_type_CS_encrypted_block,
+	ec_cs_tlv_type_CS_encryption_IV,
+	ec_cs_tlv_type_CS_encrypted_data,
+	ec_cs_tlv_type_CS_padding,
+	ec_cs_tlv_type_CS_MAC,
+	ec_cs_tlv_type_CS_master_key,
+	ec_cs_tlv_type_CS_reference_counter,
+
+	ec_cs_tlv_type_first_known         = ec_cs_tlv_type_Import_File, ///< First known TLV type.
+	ec_cs_tlv_type_last_known          = ec_cs_tlv_type_CS_reference_counter, ///< Last known TLV type.
+};
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_EC_CS_TYPES_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wai_message.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,121 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wai_message.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 10 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAI_MESSAGE_H_)
+#define _WAI_MESSAGE_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_array.h"
+
+/** @file */
+
+
+//----------------------------------------------------------------------------
+
+
+/// This class defines one WAI-message. One WAI message could include many WAI TLV attributes.
+/**
+ * This class defined one WAI-message.
+ * Parse and analyse of WAI-message is asyncronous.
+ * m_analyse_index tells the index of message where asyncronous
+ * analyse of WAI-message must continue.
+ * Analysed messages are skipped during the asyncronous
+ * analyse of messages. Asyncronous analyse is needed
+ * because of the PKI functions are asyncronous in
+ * Symbian.
+ */
+class EAP_EXPORT wai_message_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class. @see abs_eap_am_tools_c.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	/// This buffer includes copy of the whole received WAI-message data.
+	eap_variable_data_c m_message_data;
+
+	/// This indicates whether this object is client (true) or server (false). This is mostly for traces.
+	const bool m_is_client;
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the wai_message_c class does nothing special.
+	 */
+	EAP_FUNC_IMPORT virtual ~wai_message_c();
+
+	/**
+	 * The constructor of the wai_message_c class simply initializes the attributes.
+	 */
+	EAP_FUNC_IMPORT wai_message_c(
+		abs_eap_am_tools_c * const tools,
+		const bool is_client);
+
+	/**
+	 * This function resets this object.
+	 */
+	EAP_FUNC_IMPORT eap_status_e reset();
+
+	/**
+	 * This function copies the received WAI-message data.
+	 */
+	EAP_FUNC_IMPORT eap_status_e set_wai_message_data(
+		const eap_variable_data_c * const wai_message_data);
+
+	/**
+	 * This function returns the WAI-message data.
+	 */
+	EAP_FUNC_IMPORT const eap_variable_data_c * get_wai_message_data() const;
+
+	/**
+	 * This function returns the WAI-message data.
+	 */
+	EAP_FUNC_IMPORT eap_variable_data_c * get_wai_message_data_writable();
+
+	/**
+	 * Object must indicate it's validity.
+	 * If object initialization fails this function must return false.
+	 * @return This function returns the validity of this object.
+	 */
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+	EAP_FUNC_IMPORT wai_message_c * copy() const;
+	
+	//--------------------------------------------------
+}; // class wai_message_c
+
+
+//--------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_WAI_MESSAGE_H_)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wai_message_payloads.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,187 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wai_message_payloads.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 14 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAI_PAYLOADS_H_)
+#define _WAI_PAYLOADS_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_variable_data.h"
+#include "eap_am_export.h"
+#include "wai_tlv_header.h"
+#include "ec_cs_tlv_header.h"
+#include "eap_core_map.h"
+#include "wai_protocol_packet_header.h"
+#include "wai_variable_data.h"
+#include "eap_array.h"
+
+class wai_message_c;
+class crypto_hmac_c;
+
+//--------------------------------------------------
+
+// 
+class EAP_EXPORT wai_message_payloads_c
+: public abs_eap_core_map_c
+{
+private:
+	//--------------------------------------------------
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+	eap_variable_data_c m_message; ///< This is includes the whole message.
+
+	wai_protocol_packet_header_c m_wai_protocol_packet_header;
+
+	/// This stores the wai_variable_data_c objects using eap_variable_data selector.
+	eap_core_map_c<wai_variable_data_c, abs_eap_core_map_c, eap_variable_data_c> m_payload_map;
+
+	/// This stores the same wai_variable_data_c objects to array.
+	/// This is to speed the sequential check of all payloads.
+	eap_array_c<wai_variable_data_c> m_read_payloads;
+
+	/// This index is used when payloads are retrieved in order.
+	u32_t m_payload_index;
+
+	bool m_is_client;
+
+	bool m_is_valid;
+
+	eap_status_e get_tlv_data(
+		const wai_payload_type_e copied_tlv_type,
+		void * const data,
+		const u32_t data_length) const;
+
+	/**
+	 * This function parses each payload tlvs.
+	 * @return If payload tlv is illegal function returns eap_status_header_corrupted.
+	 * If payload tlv is unknown function returns eap_status_unsupported_payload.
+	 */
+	EAP_FUNC_IMPORT eap_status_e parse_generic_payload(
+		const wai_payload_type_e tlv_type,
+		const wai_variable_data_c * const wai_data,
+		u32_t * const prev_payload_length);
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT virtual ~wai_message_payloads_c();
+
+	EAP_FUNC_IMPORT wai_message_payloads_c(
+		abs_eap_am_tools_c * const tools,
+		const bool true_when_is_client);
+
+
+	EAP_FUNC_IMPORT eap_status_e initialise_header();
+
+	EAP_FUNC_IMPORT const wai_protocol_packet_header_c * get_wai_protocol_packet_header() const;
+
+	EAP_FUNC_IMPORT wai_protocol_packet_header_c * get_wai_protocol_packet_header_writable();
+
+
+	EAP_FUNC_IMPORT wai_variable_data_c * get_tlv_pointer(
+		const wai_payload_type_e current_payload,
+		u32_t index) const;
+
+	EAP_FUNC_IMPORT wai_variable_data_c * get_tlv_pointer(
+		const wai_payload_type_e current_payload) const;
+
+
+	EAP_FUNC_IMPORT u32_t get_tlv_count() const;
+
+	EAP_FUNC_IMPORT wai_variable_data_c * get_tlv(const u32_t tlv_index) const;
+
+	EAP_FUNC_IMPORT eap_status_e insert_payload(
+		const wai_variable_data_c * const new_payload);
+
+	/**
+	 * This function adds new_payload object to payloads.
+	 * NOTE the data is NOT copied.
+	 */
+	EAP_FUNC_IMPORT eap_status_e add_tlv(
+		wai_variable_data_c *new_payload);
+
+	/**
+	 * This function copies the selected tlv from source to payloads.
+	 */
+	EAP_FUNC_IMPORT eap_status_e copy_tlv(
+		const wai_message_payloads_c * const source,
+		const wai_payload_type_e tlv);
+
+	/**
+	 * This function copies the tlv data to payloads.
+	 */
+	EAP_FUNC_IMPORT eap_status_e copy_tlv_data(
+		const wai_payload_type_e current_payload,
+		const void * const data,
+		const u32_t data_length);
+
+	/**
+	 * This function parses the payloads starting from specified payload (p_payload).
+	 * Function parses all payloads from the buffer.
+	 * Payloads are stored to member variables.
+	 * @return If the length of the buffer and sum of the length of all payloads does not match
+	 * function returns eap_status_header_corrupted.
+	 * Also error is returned when illegal payload tlv is recognised.
+	 */
+	EAP_FUNC_IMPORT eap_status_e parse_wai_payloads(
+		void * const message_buffer, ///< This is the start of the message buffer.
+		const u32_t buffer_length, ///< This is the length of the buffer. This must match with the length of all payloads.
+		u32_t * const padding_length ///< Length of possible padding is set to this variable.
+		);
+
+#if 0
+	EAP_FUNC_IMPORT eap_status_e check_payloads_existense(
+		const wai_payload_type_e * const needed_payloads,
+		const u32_t count_of_needed_payloads) const;
+
+	/**
+	 * This function checks all required AVPs are received.
+	 */
+	EAP_FUNC_IMPORT eap_status_e check_payloads_existense(
+		EAP_TEMPLATE_CONST eap_array_c<wai_payload_type_e> * const needed_payloads) const;
+#endif
+
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+	EAP_FUNC_IMPORT eap_status_e create_wai_tlv_message(
+		wai_message_c * const new_ec_cs_tlv_message_data,
+		const bool add_payloads) const;
+
+	EAP_FUNC_IMPORT eap_status_e reset();
+
+	EAP_FUNC_IMPORT wai_message_payloads_c * copy() const;
+
+	//--------------------------------------------------
+}; // class wai_message_payloads_c
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_WAI_PAYLOADS_H_)
+
+//--------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wai_protocol_packet_header.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,308 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wai_protocol_packet_header.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 16 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAI_PROTOCOL_PACKET_HEADER_H_)
+#define _WAI_PROTOCOL_PACKET_HEADER_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "wapi_types.h"
+#include "eap_general_header_base.h"
+
+/** @file */
+
+
+//----------------------------------------------------------------------------
+
+
+/// This class defines header of WAI protocol packet.
+/**
+ * Here is a figure of header of WAI protocol packet.
+ * Data follows wai_protocol_packet_header_c.
+ * @code
+ *  TLV-header:
+ * 0                   1                   2                   3   
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |            Version            |     Type      |    Subtype    |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |            Reserved           |          Length               |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |    Packet sequence number     |Frag. Seg. No. |     Flag      |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Data ...                                                       
+ * +-+-+-+-+-                                                       
+ * @endcode
+ * 
+ * For details see <a href="../../../internal/doc/WAPI/WAPI_design.doc">WAPI_design.doc</a>.
+ */
+class EAP_EXPORT wai_protocol_packet_header_c
+: public eap_general_header_base_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/// This is enumeration of masks of Flag field.
+	enum flag_masks
+	{
+		m_flag_mask_fragment_exists = 0x01,
+	};
+
+	/// This is enumeration of sizes of fields.
+	enum sizes
+	{
+		m_version_size = sizeof(u16_t),                 ///< This is size of Version 16-bit field.
+		m_type_size = sizeof(u8_t),                     ///< This is size of Type 8-bit field.
+		m_subtype_size = sizeof(u8_t),                  ///< This is size of Subtype 8-bit field.
+		m_reserved_size = sizeof(u16_t),                ///< This is size of Reserved 16-bit field.
+		m_length_size = sizeof(u16_t),                  ///< This is size of Length 16-bit field.
+		m_packet_sequence_number_size = sizeof(u16_t),  ///< This is size of Packet sequence number 16-bit field.
+		m_fragment_sequence_number_size = sizeof(u8_t), ///< This is size of Fragment sequence number 8-bit field.
+		m_flag_size = sizeof(u8_t),                     ///< This is size of Flag 8-bit field.
+	};
+
+	/// This is enumeration of offsets to data fields.
+	enum offsets
+	{
+		m_version_offset = 0ul,                                                                            ///< This is offset to Version 16-bit field.
+		m_type_offset = m_version_offset+m_version_size,                                                   ///< This is offset to Type 8-bit field.
+		m_subtype_offset = m_type_offset+m_type_size,                                                      ///< This is offset to Subtype 8-bit field.
+		m_reserved_offset = m_subtype_offset+m_subtype_size,                                               ///< This is offset to Reserved 16-bit field.
+		m_length_offset = m_reserved_offset+m_reserved_size,                                               ///< This is offset to Length 16-bit field.
+		m_packet_sequence_number_offset = m_length_offset+m_length_size,                                   ///< This is offset to Packet sequence number 16-bit field.
+		m_fragment_sequence_number_offset = m_packet_sequence_number_offset+m_packet_sequence_number_size, ///< This is offset to Fragment sequence number 8-bit field.
+		m_flag_offset = m_fragment_sequence_number_offset+m_fragment_sequence_number_size,                 ///< This is offset to Flag 8-bit field.
+		m_data_offset = m_flag_offset+m_flag_size,                                                         ///< This is offset to Data.
+	};
+
+	/**
+	 * The destructor of the wai_protocol_packet_header_c class does nothing.
+	 */
+	virtual ~wai_protocol_packet_header_c();
+
+	/**
+	 * The constructor of the wai_protocol_packet_header_c class.
+	 */
+	wai_protocol_packet_header_c(
+		abs_eap_am_tools_c * const tools);
+
+	/**
+	 * The constructor of the wai_protocol_packet_header_c class simply initializes the attributes.
+	 */
+	wai_protocol_packet_header_c(
+		abs_eap_am_tools_c * const tools,
+		void * const header_begin,
+		const u32_t header_buffer_length);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	/**
+	 * This function sets the header buffer.
+	 */
+	eap_status_e set_header_buffer(
+		void * const header_begin,
+		const u32_t header_buffer_length);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	/**
+	 * This function returns the Version value.
+	 */
+	wai_protocol_version_e get_version() const;
+
+	/**
+	 * This function returns the Type value.
+	 */
+	wai_protocol_type_e get_type() const;
+
+	/**
+	 * This function returns the Subtype value.
+	 */
+	wai_protocol_subtype_e get_subtype() const;
+
+	/**
+	 * This function returns the Reserved value.
+	 */
+	u16_t get_reserved() const;
+
+	/**
+	 * This function returns the Length value.
+	 */
+	u32_t get_length() const;
+
+	/**
+	 * This function returns the Packet sequence number value.
+	 */
+	u16_t get_packet_sequence_number() const;
+
+	/**
+	 * This function returns the Fragment sequence number value.
+	 */
+	u8_t get_fragment_sequence_number() const;
+
+	/**
+	 * This function returns the Flag value.
+	 */
+	u8_t get_flag() const;
+
+	/**
+	 * This function returns the header length of WAI protocol packet.
+	 */
+	static u32_t get_header_length();
+
+	/**
+	 * This function returns the data length of WAI protocol packet.
+	 */
+	u32_t get_data_length() const;
+
+	/**
+	 * This function returns pointer to the offset of data of WAI protocol packet.
+	 * @param offset is the offset of queried data in bytes.
+	 * @param contignuous_bytes is the length of queried data in bytes.
+	 */
+	u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const;
+
+
+	/**
+	 * This function returns pointer to the begin of data of WAI protocol packet.
+	 * @param contignuous_bytes is the length of queried data in bytes.
+	 */
+	u8_t * get_data(const u32_t contignuous_bytes) const;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	/**
+	 * This function checks the header is valid.
+	 */
+	eap_status_e check_header() const;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	/**
+	 * This function sets the Version value.
+	 */
+	eap_status_e set_version(const wai_protocol_version_e version);
+
+	/**
+	 * This function sets the Type value.
+	 */
+	eap_status_e set_type(const wai_protocol_type_e type);
+
+	/**
+	 * This function sets the Subype value.
+	 */
+	eap_status_e set_subtype(const wai_protocol_subtype_e subtype);
+
+	/**
+	 * This function sets the Reserved value.
+	 */
+	eap_status_e set_reserved(const u16_t reserved);
+
+	/**
+	 * This function sets the Length value.
+	 */
+	eap_status_e set_length(const u32_t length);
+
+	/**
+	 * This function sets the Packet sequence number value.
+	 */
+	eap_status_e set_packet_sequence_number(const u16_t packet_sequence_number);
+
+	/**
+	 * This function sets the Fragment sequence number value.
+	 */
+	eap_status_e set_fragment_sequence_number(const u8_t fragment_sequence_number);
+
+	/**
+	 * This function sets the Flag value.
+	 */
+	eap_status_e set_flag(const u8_t flag);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	/**
+	 * This function resets the WAI protocol packet header.
+	 */
+	eap_status_e reset_header();
+
+	// 
+	//--------------------------------------------------
+}; // class wai_protocol_packet_header_c
+
+//----------------------------------------------------------------------------------
+
+/// Macro traces payload type and data.
+#define WAI_PROTOCOL_PACKET_TRACE_HEADER(prefix, header, when_true_is_client) \
+	{ \
+		EAP_TRACE_DEBUG( \
+			m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v \n"))); \
+		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("- buffer"), (header)->get_header_buffer((header)->get_header_buffer_length()), \
+			(header)->get_header_buffer_length())); \
+		EAP_TRACE_DEBUG( \
+			m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("- %s, %s (0x%08x): Version=%d, Type=%d, Subtype=%d=%s, Reserved=%d,\n"), \
+			prefix, \
+			((when_true_is_client) == true ? "client" : "server"), \
+			(header)->get_header_buffer((header)->get_header_buffer_length()), \
+			(header)->get_version(), \
+			(header)->get_type(), \
+			(header)->get_subtype(), \
+			wapi_strings_c::get_wai_protocol_subtype_string((header)->get_subtype()), \
+			(header)->get_reserved())); \
+		EAP_TRACE_DEBUG( \
+			m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("- %s, %s (0x%08x): Length=%d, Packet sequence number=%d, Fragment sequence number=%d, Flag=%d, data length 0x%04x.\n"), \
+			prefix, \
+			((when_true_is_client) == true ? "client" : "server"), \
+			(header)->get_header_buffer((header)->get_header_buffer_length()), \
+			(header)->get_length(), \
+			(header)->get_packet_sequence_number(), \
+			(header)->get_fragment_sequence_number(), \
+			(header)->get_flag(), \
+			(header)->get_data_length())); \
+		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(wapi_strings_c::get_wai_protocol_subtype_string((header)->get_subtype()), \
+			(header)->get_header_buffer((header)->get_header_buffer_length()), \
+			(header)->get_header_buffer_length())); \
+		EAP_TRACE_DEBUG( \
+			m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ \n"))); \
+	}
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_WAI_PROTOCOL_PACKET_HEADER_H_)
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wai_tlv_header.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,211 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wai_tlv_header.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 11 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAI_TLV_HEADER_H_)
+#define _WAI_TLV_HEADER_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_general_header_base.h"
+#include "wapi_types.h"
+
+/** @file */
+
+
+//----------------------------------------------------------------------------
+
+
+/// This class defines header of Attribute-Value Pairs.
+/**
+ * Here is a figure of header of Attribute-Value Pairs.
+ * Value data follows wai_tlv_header_c.
+ * @code
+ *  TLV-header:
+ *  0                   1                   2                   3   
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |     Type      |            Length             |  Value...
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * @endcode
+ * 
+ * @code
+ * The fields of this header are:
+ *  8-bits Type;               This is a TLV type.
+ * 16-bits value length (Length);  This is a length field, the length (in bytes) of the following value.
+ * @endcode
+ * 
+ * For details see <a href="../../../internal/doc/WAPI/WAPI_design.doc">WAPI_design.doc</a>.
+ */
+class EAP_EXPORT wai_tlv_header_c
+: public eap_general_header_base_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	/// This is enumeration of sizes of data fields.
+	enum size
+	{
+		m_type_size = sizeof(u8_t),    ///< This is size of tlv type 8-bit field.
+		m_length_size = sizeof(u16_t), ///< This is size of length 16-bit field.
+	};
+
+	/// This is enumeration of offsets to data fields.
+	enum offsets
+	{
+		m_type_offset = 0ul,                           ///< This is offset to fags and tlv type 8-bit field.
+		m_length_offset = m_type_offset+m_type_size,   ///< This is offset to length 16-bit field.
+		m_data_offset = m_length_offset+m_length_size, ///< This is offset to data field.
+	};
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the wai_tlv_header_c class does nothing.
+	 */
+	virtual ~wai_tlv_header_c();
+
+	/**
+	 * The constructor of the wai_tlv_header_c class simply initializes the attributes.
+	 */
+	wai_tlv_header_c(
+		abs_eap_am_tools_c * const tools,
+		void * const header_begin,
+		const u32_t header_buffer_length);
+
+	/**
+	 * This function returns the TLV type.
+	 */
+	wai_tlv_type_e get_type() const;
+
+	/**
+	 * This function returns the data length of TLV.
+	 */
+	u32_t get_data_length() const;
+
+	/**
+	 * This function returns the header length of TLV.
+	 */
+	static u32_t get_header_length();
+
+	/**
+	 * This function returns pointer to the offset of data of TLV.
+	 * @param offset is the offset of queried data in bytes.
+	 * @param contignuous_bytes is the length of queried data in bytes.
+	 */
+	u8_t * get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const;
+
+
+	/**
+	 * This function returns pointer to the offset of data of TLV.
+	 * @param contignuous_bytes is the length of queried data in bytes.
+	 */
+	u8_t * get_data(const u32_t contignuous_bytes) const;
+
+
+	/**
+	 * This function return pointer to the next TLV header in the same buffer.
+	 */
+	u8_t * get_next_header() const;
+
+
+	/**
+	 * This function checks the header is valid.
+	 */
+	eap_status_e check_header() const;
+
+	/**
+	 * This function returns debug strings of the TLV type.
+	 */
+	static eap_const_string get_tlv_type_string(const wai_tlv_type_e type);
+
+	/**
+	 * This function returns debug strings of the TLV type.
+	 */
+	eap_const_string get_tlv_type_string() const;
+
+	/**
+	 * This function sets the TLV type flag.
+	 */
+	eap_status_e set_type(const wai_tlv_type_e type);
+
+	/**
+	 * This function sets the TLV data length.
+	 */
+	eap_status_e set_data_length(const u32_t p_length);
+
+	/**
+	 * This function resets the TLV header.
+	 */
+	eap_status_e reset_header();
+
+	/**
+	 * This function resets the TLV header object.
+	 */
+	eap_status_e reset();
+
+	// 
+	//--------------------------------------------------
+}; // class wai_tlv_header_c
+
+//----------------------------------------------------------------------------------
+
+/// Macro traces wai_tlv_header_c type and data.
+#define WAI_TLV_HEADER_TRACE_PAYLOAD(prefix, wai_tlv, when_true_is_client) \
+	{ \
+		EAP_TRACE_DEBUG( \
+			m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v \n"))); \
+		EAP_TRACE_DEBUG( \
+			m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("- %s %s (0x%08x): TLV type 0x%04x=%s, data length 0x%04x.\n"), \
+			prefix, \
+			((when_true_is_client) == true ? "client" : "server"), \
+			(wai_tlv)->get_header_buffer((wai_tlv)->get_data_length()), \
+			(wai_tlv)->get_payload_type(), \
+			(wai_tlv)->get_tlv_type_string(), \
+			(wai_tlv)->get_data_length())); \
+		EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("- data"), (wai_tlv)->get_data((wai_tlv)->get_data_length()), \
+			(wai_tlv)->get_data_length())); \
+		EAP_TRACE_DEBUG( \
+			m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, \
+			(EAPL("^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ \n"))); \
+	}
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_WAI_TLV_HEADER_H_)
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wai_usksa.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,72 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wai_usksa.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 6 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+#if !defined(_WAI_USKSA_H_)
+#define _WAI_USKSA_H_
+
+#include "eap_am_export.h"
+#include "abs_eap_am_tools.h"
+#include "wapi_types.h"
+
+
+class wai_usksa_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	eap_variable_data_c m_USK;
+
+	u8_t m_USKID;
+
+	wai_unicast_cipher_suite_e m_unicast_cipher_suite;
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	virtual ~wai_usksa_c();
+
+	wai_usksa_c(abs_eap_am_tools_c * const tools);
+
+	bool get_is_valid() const;
+
+	bool get_is_valid_data() const;
+
+
+	u8_t get_USKID() const;
+
+	eap_variable_data_c * get_USK();
+
+	wai_unicast_cipher_suite_e get_cipher_suite() const;
+
+	
+	void set_USKID(const u8_t USKID);
+
+	void set_cipher_suite(const wai_unicast_cipher_suite_e cipher);
+
+	//--------------------------------------------------
+};
+
+#endif //#if !defined(_WAI_USKSA_H_)
+
+// End of file.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wai_variable_data.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,220 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wai_variable_data.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 15 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAI_VARIABLE_DATA_H_)
+#define _WAI_VARIABLE_DATA_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_variable_data.h"
+#include "eap_am_export.h"
+#include "wai_tlv_header.h"
+#include "ec_cs_tlv_header.h"
+#include "eap_core_map.h"
+#include "wai_protocol_packet_header.h"
+#include "wapi_strings.h"
+
+class wai_message_c;
+class crypto_hmac_c;
+
+
+class EAP_EXPORT wai_variable_data_c
+{
+private:
+	//--------------------------------------------------
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+	eap_variable_data_c m_data; ///< This is used for all payloads.
+
+	wai_tlv_header_c m_wai_tlv_header; ///< This is used for payloads with 8-bit type and 16-bit length fields.
+
+	ec_cs_tlv_header_c m_ec_cs_tlv_header; ///< This is used for payloads with 16-bit type and 16-bit length fields.
+
+	/// This tells which payload this is and what type the payload is.
+	wai_payload_type_e m_payload_type;
+
+	/// This is pointer to the next payload that have same tlv type.
+	/// This link is used when multiple instances of the same tlv types are included to a message.
+	wai_variable_data_c * m_next_payload_with_same_tlv_type;
+
+	bool m_is_valid;
+
+	eap_status_e set_header_buffer(
+		const wai_payload_type_e current_payload,
+		const bool write_header);
+
+	eap_status_e set_header_buffer(
+		const wai_payload_type_e current_payload,
+		const bool write_header,
+		const u32_t data_length);
+
+	wai_payload_type_size_e get_type_class(const wai_payload_type_e current_payload) const;
+
+	u32_t get_header_length(
+		const wai_payload_type_e current_payload) const;
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT virtual ~wai_variable_data_c();
+
+	EAP_FUNC_IMPORT wai_variable_data_c(abs_eap_am_tools_c * const tools);
+
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+	EAP_FUNC_IMPORT bool get_is_valid_data() const;
+
+	EAP_FUNC_IMPORT eap_status_e reset();
+
+	EAP_FUNC_IMPORT eap_status_e create(
+		const wai_payload_type_e current_payload,
+		const void * const buffer, // Buffer includes only data.
+		const u32_t buffer_length); // Buffer_length includes only data.
+
+	EAP_FUNC_IMPORT eap_status_e create(
+		const wai_payload_type_e current_payload,
+		const eap_variable_data_c * const buffer); // Buffer includes only data.
+
+	EAP_FUNC_IMPORT eap_status_e set_buffer(
+		const wai_payload_type_e current_payload,
+		const void * const buffer, // Buffer includes the header and data.
+		const u32_t buffer_length); // Buffer_length includes header and data.
+
+
+	EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer(
+		const wai_payload_type_e current_payload,
+		const void * const buffer, // Buffer includes the header and data.
+		const u32_t buffer_length); // Buffer_length includes header and data.
+
+	EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer(
+		const wai_payload_type_e current_payload,
+		const eap_variable_data_c * const buffer); // Buffer includes the header and data.
+
+	EAP_FUNC_IMPORT eap_status_e set_copy_of_buffer(
+		const wai_variable_data_c * const source); // Buffer includes the header and data.
+
+	EAP_FUNC_IMPORT eap_status_e init_header(
+		const wai_payload_type_e current_payload,
+		const u32_t default_buffer_length);
+
+
+	EAP_FUNC_IMPORT eap_status_e add_data(
+		const wai_payload_type_e new_payload,
+		const eap_variable_data_c * const buffer);
+
+	EAP_FUNC_IMPORT eap_status_e add_data(
+		const wai_payload_type_e new_payload,
+		const void * const buffer,
+		const u32_t buffer_length);
+
+	EAP_FUNC_IMPORT eap_status_e add_data(
+		const wai_variable_data_c * const data);
+
+
+	EAP_FUNC_IMPORT wai_payload_type_size_e get_type_class() const;
+
+	EAP_FUNC_IMPORT u32_t get_data_length() const;
+
+	EAP_FUNC_IMPORT u32_t get_type_data_length() const;
+
+	EAP_FUNC_IMPORT u32_t get_type_header_length() const;
+
+	EAP_FUNC_IMPORT u8_t * get_type_data_offset(
+		const u32_t offset,
+		const u32_t data_length) const;
+
+	EAP_FUNC_IMPORT u8_t * get_type_data(
+		const u32_t data_length) const;
+
+	EAP_FUNC_IMPORT u8_t * get_data(const u32_t data_length) const;
+
+	EAP_FUNC_IMPORT u8_t * get_data_offset(const u32_t offset, const u32_t data_length) const;
+
+	EAP_FUNC_IMPORT const wai_tlv_header_c * get_wai_tlv_header() const;
+
+	EAP_FUNC_IMPORT const ec_cs_tlv_header_c * get_ec_cs_tlv_header() const;
+
+	EAP_FUNC_IMPORT const eap_variable_data_c * get_full_tlv_buffer() const;
+
+	EAP_FUNC_IMPORT eap_variable_data_c * get_writable_full_tlv_buffer();
+
+	EAP_FUNC_IMPORT wai_payload_type_e get_payload_type() const;
+
+	EAP_FUNC_IMPORT wai_variable_data_c * get_next_payload_with_same_tlv_type() const;
+
+
+	EAP_FUNC_IMPORT eap_status_e set_payload_type(const wai_payload_type_e payload_type);
+
+	EAP_FUNC_IMPORT void add_next_payload_with_same_tlv_type(wai_variable_data_c * const tlv);
+
+	EAP_FUNC_IMPORT void set_next_payload_with_same_tlv_type(wai_variable_data_c * tlv);
+
+	EAP_FUNC_IMPORT wai_variable_data_c * copy() const;
+
+	EAP_FUNC_IMPORT void object_increase_reference_count();
+
+	EAP_FUNC_IMPORT eap_status_e check_header() const;
+
+	EAP_FUNC_IMPORT i32_t compare(const wai_variable_data_c * right) const;
+
+
+	EAP_FUNC_IMPORT static wai_payload_type_e convert_to_wai_payload_type(const wai_tlv_type_e tlv_type);
+
+	EAP_FUNC_IMPORT static wai_tlv_type_e convert_to_wai_tlv_type(const wai_payload_type_e payload_type);
+
+	EAP_FUNC_IMPORT static wai_certificate_identifier_e convert_to_wai_certificate_identifier(const wai_payload_type_e payload_type);
+
+	EAP_FUNC_IMPORT static ec_cs_tlv_type_e convert_to_ec_cs_tlv_type(const wai_payload_type_e payload_type);
+
+
+	EAP_FUNC_IMPORT eap_const_string get_wai_payload_type_string() const;
+
+	/// Function traces wai_tlv_header_c type and data.
+	static void wai_variable_data_trace(
+		abs_eap_am_tools_c * const tools,
+		eap_format_string prefix,
+		const wai_variable_data_c * const wai_data,
+		const bool when_true_is_client);
+
+
+	//--------------------------------------------------
+}; // class wai_variable_data_c
+
+//--------------------------------------------------
+
+
+#define WAI_VARIABLE_DATA_TRACE(tools, prefix, wai_data, when_true_is_client) { wai_variable_data_c::wai_variable_data_trace(tools, prefix, wai_data, when_true_is_client); }
+
+//--------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_WAI_VARIABLE_DATA_H_)
+
+//--------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_am_base_core.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,137 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_am_base_core.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 12 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_AM_BASE_CORE_H_)
+#define _WAPI_AM_BASE_CORE_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_variable_data.h"
+#include "eap_am_export.h"
+#include "eap_am_network_id.h"
+#include "ec_am_base_certificate_store.h"
+
+class abs_wapi_am_core_c;
+
+/// This class is interface to adaptation module of WAPI core.
+class EAP_EXPORT wapi_am_base_core_c
+: public ec_am_base_certificate_store_c
+{	
+private:
+	//--------------------------------------------------
+
+	/** Function returns partner object of adaptation module of WAPI.
+	 *  Partner object is the WAPI core object.
+	 */
+	//virtual abs_wapi_am_core_c * get_am_partner() = 0;
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	virtual ~wapi_am_base_core_c()
+	{
+	}
+
+	/**
+	 * This function creates a new instance of adaptation module of WAPI core.
+	 * @param tools is pointer to the abs_eap_am_tools class created by the adaptation module.
+	 * WAPI core AM will callback caller using the partner pointer.
+	 */
+	EAP_FUNC_IMPORT static wapi_am_base_core_c *new_wapi_am_core(
+		abs_eap_am_tools_c * const tools,
+		abs_wapi_am_core_c * const partner,
+		const bool is_client_when_true,
+		const eap_am_network_id_c * const receive_network_id);
+
+	/** Function sets partner object of adaptation module of WAPI.
+	 *  Partner object is the WAPI core object.
+	 */
+	//virtual void set_am_partner(abs_wapi_am_core_c * const partner) = 0;
+
+	virtual eap_status_e configure() = 0;
+
+	/**
+	 * The shutdown() function is called before the destructor of the 
+	 * object is executed. During the function call the object 
+	 * could shutdown the operations, for example cancel timers.
+	 * Each derived class must define this function.
+	 */
+	virtual eap_status_e shutdown() = 0;
+
+	virtual bool get_is_valid() = 0;
+
+	/** Client calls this function.
+	 *  WAPI AM could do finishing operations to databases etc. based on authentication status and type.
+	 */
+	virtual eap_status_e reset() = 0;
+
+	/** Client calls this function.
+	 *  WAPI AM could make some fast operations here, heavy operations should be done in the reset() function.
+	 */
+	virtual eap_status_e authentication_finished(
+		const bool true_when_successfull) = 0;
+
+	/**
+	 * The type_configure_read() function reads the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the query to some persistent store.
+	 * @param field is generic configure string idenfying the required configure data.
+	 * @param field_length is length of the field string.
+	 * @param data is pointer to existing eap_variable_data object.
+	 */
+	virtual eap_status_e type_configure_read(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	/**
+	 * The type_configure_write() function writes the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the action to some persistent store.
+	 * @param field is generic configure string idenfying the required configure data.
+	 * @param field_length is length of the field string.
+	 * @param data is pointer to existing eap_variable_data object.
+	 */
+	virtual eap_status_e type_configure_write(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	//--------------------------------------------------
+}; // class wapi_am_base_core_c
+
+
+/** @file */ 
+
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_WAPI_AM_BASE_CORE_H_)
+
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_am_crypto_sms4.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,169 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_am_crypto_sms4.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 5 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+//------------------------------------------------------------
+
+#if !defined(_WAPI_AM_CRYPTO_SMS4_H_)
+#define _WAPI_AM_CRYPTO_SMS4_H_
+
+#include "eap_am_types.h"
+#include "eap_variable_data.h"
+#include "eap_am_export.h"
+#include "eap_am_tools.h"
+
+#if defined(ecb_encrypt)
+#undef ecb_encrypt
+#endif //#if defined(ecb_encrypt)
+
+//------------------------------------------------------------
+
+/// This class implements the SMS4 block cipher used in WAPI
+class EAP_EXPORT wapi_am_crypto_sms4_c
+{
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+private:
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	enum wapi_sms4_sizes
+	{
+		WAPI_AM_CRYPTO_SMS4_KEY_u8_SIZE = 16ul, ///< 16 u8_t integers
+		WAPI_AM_CRYPTO_SMS4_BLOCK_u8_SIZE = 16ul, ///< 16 u8_t integers
+		WAPI_AM_CRYPTO_SMS4_CK_u32_COUNT = 32ul, ///< 32 u32_t integers
+		WAPI_AM_CRYPTO_SMS4_FK_u32_COUNT = 4ul, ///< 4 u32_t integers 
+		WAPI_AM_CRYPTO_SMS4_SBOX_u8_SIZE = 256ul, ///< 256 u8_t integers
+		WAPI_AM_CRYPTO_SMS4_KEY_SCHEDULE_u32_SIZE = 32ul ///< 32 u32_t integers
+	};
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	/// Round keys are stored into this variable.
+	u32_t m_key_schedule[WAPI_AM_CRYPTO_SMS4_KEY_SCHEDULE_u32_SIZE];
+
+	static const u32_t m_CK[WAPI_AM_CRYPTO_SMS4_CK_u32_COUNT];
+	static const u32_t m_FK[WAPI_AM_CRYPTO_SMS4_FK_u32_COUNT];
+	static const u8_t m_SBOX[WAPI_AM_CRYPTO_SMS4_SBOX_u8_SIZE];
+
+	/// This indicates whether this object was generated successfully.
+	bool m_is_valid;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	/**
+	 * The set_is_invalid() function sets the state of the object invalid. 
+	 */
+	EAP_FUNC_IMPORT void set_is_invalid();
+
+	/**
+	 * The set_is_valid() function sets the state of the object valid. 
+	 */
+	EAP_FUNC_IMPORT void set_is_valid();
+
+	EAP_FUNC_IMPORT void L_key( u32_t* data );
+
+	EAP_FUNC_IMPORT void L_data( u32_t* data );
+
+	EAP_FUNC_IMPORT void sms4_substitute( u32_t* data );
+
+	EAP_FUNC_IMPORT eap_status_e ecb_process_data(
+		const void * const data_in, 
+		void * const data_out,
+		const u32_t data_blocks,
+		bool encrypt);  /// < true for encrypt, false for decrypt
+
+	// cyclic left shift
+	inline u32_t sms4_rotate_left(
+		const u32_t value,
+		const u32_t shift)
+	{
+		return (value << shift) | (value >> (32ul - shift));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+public:
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	/**
+	 * Destructor resets the used internal buffers.
+	 */
+	EAP_FUNC_IMPORT virtual ~wapi_am_crypto_sms4_c();
+
+	/**
+	 * Constructor initializes the used internal buffers.
+	 */
+	EAP_FUNC_IMPORT wapi_am_crypto_sms4_c(abs_eap_am_tools_c * const tools);
+
+	/**
+	 * The get_is_valid() function returns the status of the object. 
+	 * True indicates the object is allocated successfully.
+	 */
+	EAP_FUNC_IMPORT bool get_is_valid();
+
+	/**
+	 * This function sets the SMS4 key
+	 * and generates the key schedule (i.e. intializes 
+	 * the context).
+	 */
+	EAP_FUNC_IMPORT eap_status_e set_key(
+		const eap_variable_data_c * const key);
+
+	/**
+	 * Returns the size of SMS4 key. 
+	 * This will be constant 16 bytes (128 bits).
+	 */
+	EAP_FUNC_IMPORT u32_t get_key_size();
+
+	/**
+	 * Returns the SMS4 block size. 
+	 * This will be constant 16 bytes (128 bits).
+	 */
+	EAP_FUNC_IMPORT u32_t get_block_size();
+
+	/**
+	 * This function performs SMS4 encryption
+	 * for input data blocks in ECB mode. The length of data must 
+	 * be aligned to the block size of SMS4.
+	 */
+	EAP_FUNC_IMPORT eap_status_e ecb_encrypt(
+		const void * const data_in, 
+		void * const data_out,
+		const u32_t data_blocks ///< This is the number of blocks to be processed
+		);
+
+	/**
+	 * This function performs SMS4 decryption
+	 * for input data blocks in ECB mode. The length of data must 
+	 * be aligned to the block size of SMS4.
+	 */
+	EAP_FUNC_IMPORT eap_status_e ecb_decrypt(
+		const void * const data_in, 
+		void * const data_out,
+		const u32_t data_blocks ///< This is the number of blocks to be processed
+		);
+};
+
+#endif //#if !defined(_WAPI_AM_CRYPTO_SMS4_H_)
+
+//------------------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_am_wlan_authentication.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,191 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_am_wlan_authentication.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 4.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_AM_WLAN_AUTHENTICATION_H_)
+#define _WAPI_AM_WLAN_AUTHENTICATION_H_
+
+#include "eap_am_export.h"
+#include "eap_status.h"
+#include "eap_header.h"
+#include "eap_array.h"
+#include "eapol_key_types.h"
+
+class abs_wapi_am_wlan_authentication_c;
+class abs_eap_am_tools_c;
+class eap_am_network_id_c;
+class abs_eapol_wlan_database_reference_if_c;
+class abs_eap_state_notification_c;
+
+
+/// This is interface to adaptation module of class wapi_wlan_authentication_c.
+class EAP_EXPORT wapi_am_wlan_authentication_c
+{
+private:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	// 
+	virtual ~wapi_am_wlan_authentication_c();
+
+	/// @param tools: Constructor takes parameter tools that is pointer to adaptation of the platform.
+	/// @param is_client_when_true: Second parameter is true when object is client and false when object is server.
+	/// @param wlan_database_reference: third parameter is pointer to interface to read the current database reference.
+	EAP_FUNC_IMPORT static wapi_am_wlan_authentication_c * new_wapi_am_wlan_authentication(
+		abs_eap_am_tools_c * const tools,
+		const bool is_client_when_true,
+		const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference
+		);
+
+	/// This is documented in abs_eap_stack_interface_c::get_is_valid().
+	virtual bool get_is_valid() = 0;
+
+	/// This is documented in abs_eap_stack_interface_c::configure().
+	virtual eap_status_e configure() = 0;
+
+	/// This is documented in abs_eap_stack_interface_c::shutdown().
+	virtual eap_status_e shutdown() = 0;
+
+	/// Function sets the parther object of this object.
+	virtual eap_status_e set_am_partner(
+		abs_wapi_am_wlan_authentication_c * am_partner
+		) = 0;
+
+	/// Function resets current WAPI-configuration.
+	virtual eap_status_e reset_wapi_configuration() = 0;
+
+	/// Function sets the new WLAN parameters.
+	virtual eap_status_e set_wlan_parameters(
+		const eap_variable_data_c * const SSID,
+		const bool WAPI_override_enabled,
+		const eap_variable_data_c * const preshared_key,
+		const eapol_key_authentication_type_e selected_eapol_key_authentication_type) = 0;
+
+	/// New association is completed.
+	virtual eap_status_e association(
+		const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address.
+		) = 0;
+
+	/// Previous connection was disassociated.
+	virtual eap_status_e disassociation(
+		const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address.
+		) = 0;
+
+	// ****
+	// TODO: Is this needed in WAPI?
+	/// Function gets the current WLAN configuration
+	virtual eap_status_e get_wlan_configuration(
+		eap_variable_data_c * const preshared_key) = 0;
+
+	/**
+	 * This function indicates finish of the authentication to adatation module.
+	 * @param when_true_successfull indicates whether authentication was successfull (true) or not (false).
+	 * @param authentication_type indicates the used WAPI authentication type (PSK or certificate).
+	 */
+	virtual eap_status_e authentication_finished(
+		const bool when_true_successfull,
+		const eapol_key_authentication_type_e authentication_type) = 0;
+
+	/**
+	 * The read_configure() function reads the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the query to some persistent store.
+	 * @see abs_eap_base_type_c::read_configure().
+	 */
+	virtual eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	/**
+	 * The write_configure() function writes the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the action to some persistent store.
+	 * @see abs_eap_base_type_c::write_configure().
+	 */
+	virtual eap_status_e write_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data) = 0;
+
+	/**
+	 * The set_timer() function initializes timer to be elapsed after p_time_ms milliseconds.
+	 * @param initializer is pointer to object which timer_expired() function will
+	 * be called after timer elapses.
+	 * @param id is identifier which will be returned in timer_expired() function.
+	 * The user selects and interprets the id for this timer.
+	 * @param data is pointer to any user selected data which will be returned in timer_expired() function.
+	 * @param p_time_ms is time of timer to elapse in milli seconds.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e set_timer(
+		abs_eap_base_timer_c * const initializer, 
+		const u32_t id, 
+		void * const data,
+		const u32_t p_time_ms) = 0;
+
+	/**
+	 * The cancel_timer() function cancels the timer id initiated by initializer.
+	 * @param initializer is the object that initialised the timer.
+	 * @param id is the identity of the timer.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e cancel_timer(
+		abs_eap_base_timer_c * const initializer, 
+		const u32_t id) = 0;
+
+	/**
+	 * The cancel_all_timers() function cancels all timers.
+	 * User should use this in termination of the stack before
+	 * the adaptation module of tools is deleted.
+	 * Preferred mode is to cancel each timer directly
+	 * using cancel_timer() function.
+	 *
+	 * Adaptation module internally implements the timer.
+	 */
+	virtual eap_status_e cancel_all_timers() = 0;
+
+	/**
+	 * This is notification of internal state transition.
+	 * This is used for notifications, debugging and protocol testing.
+	 * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully
+	 * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully.
+	 * These two notifications are sent from WAPI-protocol layer (eap_protocol_layer_e::eap_protocol_layer_wapi).
+	 */
+	virtual void state_notification(
+		const abs_eap_state_notification_c * const state) = 0;
+
+	//--------------------------------------------------
+}; // class wapi_am_wlan_authentication_c
+
+#endif //#if !defined(_WAPI_AM_WLAN_AUTHENTICATION_H_)
+
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_asn1_der_parser.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,110 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_asn1_der_parser.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 6 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_ASN1_DER_PARSER_H_)
+#define _WAPI_ASN1_DER_PARSER_H_
+
+#include "eap_variable_data.h"
+#include "eap_am_export.h"
+#include "eap_array.h"
+#include "asn1_der_type.h"
+
+//--------------------------------------------------
+
+class EAP_EXPORT wapi_asn1_der_parser_c
+{
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT virtual ~wapi_asn1_der_parser_c();
+
+	EAP_FUNC_IMPORT wapi_asn1_der_parser_c(
+		abs_eap_am_tools_c * const tools);
+
+	/**
+	 * The get_is_valid() function returns the status of the wapi_asn1_der_parser_c object.
+	 * @return True indicates the object is initialized.
+	 */
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+	EAP_FUNC_IMPORT u32_t get_index() const;
+
+	/**
+	 * The decode() function decodes ASN.1/DER data.
+	 * Data can include many ASN.1/DER objects.
+	 * @return eap_status_ok indicates successfull operation.
+	 */
+	EAP_FUNC_IMPORT eap_status_e decode(const eap_variable_data_c * const asn1_der_data);
+
+
+	EAP_FUNC_IMPORT const asn1_der_type_c * get_object(const u32_t index) const;
+
+	EAP_FUNC_IMPORT u32_t get_object_count() const;
+
+
+	/**
+	 * The get_wapi_identity() function copies the WAPI identity data.
+	 * First you must call decode() function with the input data.
+	 * @return eap_status_ok indicates successfull operation.
+	 */
+	EAP_FUNC_IMPORT eap_status_e get_wapi_identity(
+		eap_variable_data_c * const subject_name,
+		eap_variable_data_c * const issuer_name,
+		eap_variable_data_c * const sequence_number);
+
+	/**
+	 * The get_wapi_identity() function copies the WAPI identity data.
+	 * First you must call decode() function with the input data.
+	 * @return eap_status_ok indicates successfull operation.
+	 */
+	EAP_FUNC_IMPORT eap_status_e get_wapi_identity(
+		eap_variable_data_c * const wapi_identity);
+	/**
+	 * The get_decoded_subject_name() function parses and
+	 * returns the certificate identity subject name
+	 * @return eap_status_ok indicates successfull operation.
+	 */
+	EAP_FUNC_IMPORT eap_status_e get_decoded_subject_name(
+	    eap_variable_data_c * const identity_data,
+	    eap_variable_data_c * const decoded_data);
+	    
+
+	//--------------------------------------------------
+private:
+	//--------------------------------------------------
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+	bool m_is_valid;
+
+	eap_array_c<asn1_der_type_c> m_objects;
+
+	//--------------------------------------------------
+};
+
+//--------------------------------------------------------------------------------------------------
+
+#endif //#if !defined(_WAPI_ASN1_DER_PARSER_H_)
+
+//--------------------------------------------------------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_certificate_asn1_der_parser.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,84 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_certificate_asn1_der_parser.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 3 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_CERTIFICATE_ASN1_DER_PARSER_H_)
+#define _WAPI_CERTIFICATE_ASN1_DER_PARSER_H_
+
+#include "eap_variable_data.h"
+#include "eap_am_export.h"
+#include "eap_array.h"
+#include "asn1_der_type.h"
+
+//--------------------------------------------------
+
+class EAP_EXPORT wapi_certificate_asn1_der_parser_c
+{
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	EAP_FUNC_IMPORT virtual ~wapi_certificate_asn1_der_parser_c();
+
+	EAP_FUNC_IMPORT wapi_certificate_asn1_der_parser_c(
+		abs_eap_am_tools_c * const tools);
+
+	/**
+	 * The get_is_valid() function returns the status of the wapi_certificate_asn1_der_parser_c object.
+	 * @return True indicates the object is initialized.
+	 */
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+	/**
+	 * The decode() function decodes ASN.1/DER encoded certificate.
+	 * Data can include only one ASN.1/DER encoded certificate.
+	 * @return eap_status_ok indicates successfull operation.
+	 */
+	EAP_FUNC_IMPORT eap_status_e decode(const eap_variable_data_c * const asn1_der_certificate);
+
+
+	EAP_FUNC_IMPORT eap_status_e read_certificate_id(
+		eap_variable_data_c * const asn1_der_subject_name,
+		eap_variable_data_c * const asn1_der_issuer_name,
+		eap_variable_data_c * const asn1_der_sequence_number);
+
+	EAP_FUNC_IMPORT eap_status_e read_certificate_id(
+		eap_variable_data_c * const identity);
+
+	//--------------------------------------------------
+private:
+	//--------------------------------------------------
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+	bool m_is_valid;
+
+	asn1_der_type_c m_parser;
+
+	//--------------------------------------------------
+};
+
+//--------------------------------------------------------------------------------------------------
+
+#endif //#if !defined(_WAPI_CERTIFICATE_ASN1_DER_PARSER_H_)
+
+//--------------------------------------------------------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_core.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,856 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_core.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 68.1.2 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+/**
+ *  @mainpage WAPI Core documentation.
+ *  
+ *  @section intro Introduction
+ *  This is a WAPI Core documentation generated by doxygen.
+ *  First read <a href="../../doc/WAPI/WAPI_design.doc">WAPI_design.doc</a>
+ *  file from <a href="../../doc/WAPI/">WAPI documentation</a> directory.
+ *  
+ *  @section install Installation
+ *  Installation instructions are in file <a href="../../../../../wlaneapol/internal/wlaneapol_linux/readme.txt">readme.txt</a>.
+ *  
+ *  @section classes Most crucial classes
+ *  The most crucial classes are wapi_core_c, abs_wapi_core_c, ec_certificate_store_c, ec_algorithms_c.
+ *
+ *  Implementation of wapi_core_c class is in a file <a href="../src/wapi_core.cpp">
+ *  wapi_core.cpp</a>. 
+ *  
+ */
+
+
+#if !defined(_WAPI_CORE_H_)
+#define _WAPI_CORE_H_
+
+#include "eap_am_export.h"
+#include "eap_core_map.h"
+#include "eap_am_network_id.h"
+#include "abs_eap_stack_interface.h"
+#include "eap_configuration_field.h"
+#include "abs_eap_core_map.h"
+#include "wapi_types.h"
+#include "wai_usksa.h"
+#include "wai_message.h"
+#include "eapol_rsna_key_header.h"
+#include "abs_ec_certificate_store.h"
+#include "ec_certificate_store.h"
+#include "wai_message_payloads.h"
+#include "wapi_core_retransmission.h"
+#include "abs_wapi_am_core.h"
+
+class abs_wapi_core_c;
+class abs_eap_am_tools_c;
+class eap_core_retransmission_c;
+class eap_variable_data_c;
+class wai_protocol_packet_header_c;
+class wai_usksa_c;
+class wai_message_payloads_c;
+class wai_variable_data_c;
+class wapi_am_base_core_c;
+
+//--------------------------------------------------------------------------------------------------
+
+/**
+ *  @defgroup WAPI_Core_config_options Configuration options of WAPI Core.
+ *  The following configuration options are read through abs_eap_base_type_c::read_configure() function.
+ *  @{
+ */
+
+/**
+ *  This is u32_t configuration option.
+ *  This is the maximum count WAPI CORE Authenticator resents message again.
+ *  This is used in simulator testing.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_CORE_retransmission_counter,
+	"WAPI_CORE_retransmission_counter",
+	eap_configure_type_u32_t,
+	false);
+
+/**
+ *  This is u32_t configuration option.
+ *  This is the time after WAPI CORE Authenticator resents message again.
+ *  This is used in simulator testing.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_CORE_retransmission_time,
+	"WAPI_CORE_retransmission_time",
+	eap_configure_type_u32_t,
+	false);
+
+/**
+ *  This is u32_t configuration option.
+ *  This is the maximum time WAPI authentication could succeed.
+ *  Authentication is terminated after this time elapses.
+ *  Time is in milli secons.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_CORE_session_timeout,
+	"WAPI_CORE_session_timeout",
+	eap_configure_type_u32_t,
+	false);
+
+/**
+ *  This is optional and only valid for server.
+ *  This allows different values for client and server.
+ *  This is u32_t configuration option.
+ *  This is the maximum time WAPI authentication could succeed.
+ *  Authentication is terminated after this time elapses.
+ *  Time is in milli secons.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_CORE_server_session_timeout,
+	"WAPI_CORE_server_session_timeout",
+	eap_configure_type_u32_t,
+	false);
+
+/**
+ *  This is u32_t configuration option.
+ *  This is the time after failure is handled.
+ *  Zero means failure is handled immediately.
+ *  Time is in milli secons.
+ *  The default value is WAPI_CORE_FAILURE_RECEIVED_TIMEOUT.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_CORE_failure_received_timeout,
+	"WAPI_CORE_failure_received_timeout",
+	eap_configure_type_u32_t,
+	false);
+
+/**
+ *  This is Hex-data configuration option.
+ *  This is the PSK used in WAPI testing.
+ *  The default value is empty.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_CORE_PSK,
+	"WAPI_CORE_PSK",
+	eap_configure_type_hex_data,
+	false);
+
+/**
+ *  This is u32_t configuration option.
+ *  This is the index of used database row in current connection.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_database_reference_index,
+	"WAPI_database_reference_index",
+	eap_configure_type_u32_t,
+	false);
+
+/**
+ *  This boolean configuration option value true uses only initial authentication.
+ *  Default value is false, uses also rekeying.
+ */
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_CORE_server_only_initial_authentication,
+	"WAPI_CORE_server_only_initial_authentication",
+	eap_configure_type_boolean,
+	false);
+
+EAP_CONFIGURATION_FIELD(
+	cf_str_WAPI_CORE_server_test_other_asu_id,
+	"WAPI_CORE_server_test_other_asu_id",
+	eap_configure_type_hex_data,
+	false);
+
+/** @} */ // End of group WAPI_Core_config_options.
+
+
+//--------------------------------------------------------------------------------------------------
+
+
+/**
+ * This is the timer ID used with abs_eap_am_tools_c::set_timer() and abs_eap_am_tools_c::cancel_timer().
+ */
+enum wapi_core_timer_id
+{
+	WAPI_CORE_TIMER_RETRANSMISSION_ID,            ///< This is time after a WPI-message is resent again. This is for testing purposes. See USE_WAPI_CORE_RETRANSMISSION compilation flag.
+	WAPI_CORE_SESSION_TIMEOUT_ID, ///< See WAPI_CORE_TIMER_HANDLER_TIMEOUT.
+	WAPI_CORE_FAILURE_RECEIVED_ID, ///< See WAPI_CORE_FAILURE_RECEIVED_TIMEOUT.
+	WAPI_CORE_REMOVE_SESSION_TIMEOUT_ID,  ///< See WAPI_CORE_REMOVE_SESSION_TIMEOUT.
+};
+
+/**
+ * This is time after a failed message is handled.
+ */
+const u32_t WAPI_CORE_FAILURE_RECEIVED_TIMEOUT = 2000ul;
+
+/**
+ * This is the size of the local send buffer. Please use atleast minimum ethernet packet length 60 bytes.
+ */
+const u32_t WAPI_CORE_PACKET_BUFFER_LENGTH = 512u;
+
+
+/**
+ * Re-transmission is used to test protocols.
+ * This is the maximum count WAPI message is resent again.
+ * This is used in simulator testing.
+ * This is configurable parameter. See eap.conf WAPI_CORE_retransmission_counter.
+ */
+const u32_t WAPI_CORE_RETRANSMISSION_COUNTER = 5;
+
+/**
+ * Re-transmission is used to test protocols.
+ * This is the time after WAPI message is resent again.
+ * This is used in simulator testing.
+ * This is configurable parameter. See eap.conf WAPI_CORE_retransmission_time.
+ */
+const u32_t WAPI_CORE_RETRANSMISSION_TIME = 1000u; /* milli seconds */
+
+/**
+ * This is the maximum time WAPI authentication could succeed.
+ * Authentication is terminated after this time elapses.
+ * This is configurable parameter. See eap.conf WAPI_CORE_session_timeout.
+ * See WAPI_CORE_SESSION_TIMEOUT_ID.
+ * Time is in milli seconds. 
+ */
+const u32_t WAPI_CORE_SESSION_TIMEOUT = 120000u; /* milli seconds */
+
+/**
+ * This is the delay time after WAPI-session is removed after authentication finished.
+ * This is configurable parameter.
+ * See WAPI_CORE_REMOVE_SESSION_TIMEOUT_ID.
+ * Time is in milli seconds. 
+ */
+const u32_t WAPI_CORE_REMOVE_SESSION_TIMEOUT = 10000ul; /* milli seconds */
+
+
+//--------------------------------------------------------------------------------------------------
+
+
+/// A wapi_core_c class implements the basic functionality of WAPI-protocol.
+class EAP_EXPORT wapi_core_c
+: public abs_eap_core_map_c
+, public abs_eap_base_timer_c
+, public abs_eap_stack_interface_c
+, public abs_ec_certificate_store_c
+, public abs_wapi_am_core_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is back pointer to object which created this object.
+	/// Packets are sent to the partner.
+	abs_wapi_core_c *m_partner;
+
+	ec_base_certificate_store_c * m_ec_certificate_store;
+
+	wapi_am_base_core_c *m_am_wapi_core;
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	/// This is offset in bytes of the WAPI-header.
+	u32_t m_wapi_header_offset;
+
+	/// This is maximum transfer unit in bytes.
+	u32_t m_MTU;
+
+	/// This is length of the trailer in bytes.
+	u32_t m_trailer_length;
+
+	/// This is network identity of the received packet.
+	eap_am_network_id_c m_receive_network_id;
+
+	/// Re-transmission is used to test protocols.
+	/// This stores the information to resent a message. This is used for testing purposes.
+	eap_array_c<wapi_core_retransmission_c> m_retransmission;
+
+	/// Re-transmission is used to test protocols.
+	/// This is the time after resent a message. This is used for testing purposes.
+	u32_t m_retransmission_time;
+
+	/// Re-transmission is used to test protocols.
+	/// This is the maximum count of retransmission of one message. This is used for testing purposes.
+	u32_t m_retransmission_counter;
+
+	/// This is the maximum time authentication could succeed.
+	/// Authentication is terminated after this time elapses.
+	/// The WAPI could change the timeout by calling set_session_timeout() function.
+	u32_t m_session_timeout;
+
+	u32_t m_wapi_core_failure_received_timeout;
+
+	u32_t m_remove_session_timeout;
+
+	wapi_core_state_e m_wapi_state;
+
+	wai_message_c m_received_wai_message_data;
+
+	wai_message_payloads_c m_new_payloads;
+
+	eap_variable_data_c m_preshared_key_PSK;
+
+	eap_variable_data_c m_BK;
+
+	eap_variable_data_c m_BKID;
+
+	u8_t m_USKID;
+
+	u8_t m_MSKID;
+
+	wai_usksa_c * m_USKSA[WAPI_USKSA_COUNT];
+
+	wai_usksa_c * m_MSKSA[WAPI_MSKSA_COUNT];
+
+	eap_variable_data_c m_ae_certificate_challenge;
+	eap_variable_data_c m_asue_certificate_challenge;
+
+	eap_variable_data_c m_ae_unicast_challenge;
+	eap_variable_data_c m_asue_unicast_challenge;
+
+	eap_variable_data_c m_authentication_identifier;
+
+	eap_variable_data_c m_asue_id;
+	eap_variable_data_c m_asu_id;
+	eap_variable_data_c m_ae_id;
+
+	// This is for testing purposes.
+	eap_variable_data_c m_test_other_asu_id;
+
+	eap_variable_data_c m_own_certificate;
+	eap_variable_data_c m_peer_certificate;
+	eap_variable_data_c m_ae_certificate;
+
+	eap_variable_data_c m_wapi_ie_asue;
+	eap_variable_data_c m_wapi_ie_ae;
+
+	eap_variable_data_c m_unicast_encryption_key_UEK;
+	eap_variable_data_c m_unicast_integrity_check_key_UCK;
+	eap_variable_data_c m_message_authentication_key_MAK;
+	eap_variable_data_c m_key_encryption_key_KEK;
+
+	eap_variable_data_c m_next_unicast_challenge;
+
+	eap_variable_data_c m_multicast_key;
+	eap_variable_data_c m_packet_data_number;
+	eap_variable_data_c m_key_announcement;
+
+	eap_variable_data_c m_own_private_key_d;
+	eap_variable_data_c m_own_public_key_x;
+	eap_variable_data_c m_own_public_key_y;
+
+	eap_variable_data_c m_peer_public_key_x;
+	eap_variable_data_c m_peer_public_key_y;
+
+	wai_variable_data_c m_result_of_certificate_verification;
+	wai_variable_data_c m_server_signature_trusted_by_asue;
+	wai_variable_data_c m_server_signature_trusted_by_ae;
+
+	eap_variable_data_c m_reassemble_packet;
+
+	eapol_key_authentication_type_e m_authentication_type;
+
+	wapi_negotiation_state_e m_wapi_negotiation_state;
+
+	eapol_RSNA_key_header_c::eapol_RSNA_cipher_e m_wapi_pairwise_cipher;
+	eapol_RSNA_key_header_c::eapol_RSNA_cipher_e m_wapi_group_cipher;
+
+	u16_t m_packet_sequence_number;
+	u8_t m_fragment_sequence_number;
+
+	/// This indicates whether this object is client (true) or server (false).
+	/// In terms of WAPI-protocol whether this network entity is WAPI-ASUE (true) or WAPI-ASU (false).
+	bool m_is_client;
+
+	/// This indicates whether the authentication role of this object is client (true) or server (false).
+	/// In terms of WAPI-protocol whether this network entitys authentication role is WAPI-ASUE (true) or WAPI-ASU (false).
+	bool m_is_client_role;
+
+	/// This indicates whether this object was generated successfully.
+	bool m_is_valid;
+
+	/// Client has initiated restart.
+	bool m_client_restart_authentication_initiated;
+
+	/// This flag indicates that this object is marked to removed asynchronously.
+	/// The very same object could be taken use before the removing timer elapses.
+	bool m_marked_removed;
+
+	/// Function shutdown() is called already.
+	bool m_shutdown_was_called;
+
+	bool m_do_certificate_validation;
+
+#if defined(USE_WAPI_CORE_SERVER)
+	bool m_only_initial_authentication;
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e increase_u128_t_network_order(
+		eap_variable_data_c * const u128_t_integer) const;
+
+	void set_wapi_state(wapi_core_state_e wapi_state);
+
+	/**
+	 * Re-transmission is used to test protocols.
+	 * This function resends the packet.
+	 */
+	eap_status_e resend_packet(
+		const eap_am_network_id_c * const send_network_id,
+		const wai_message_c * const wai_message_data,
+		const u32_t retransmission_counter,
+		const u16_t packet_sequence_number
+		);
+
+	/** 
+	 * Re-transmission is used to test protocols.
+	 * This function cancels retransmissions.
+	 */
+	eap_status_e cancel_retransmission();
+
+	/**
+	 * Re-transmission is used to test protocols.
+	 * This function inits retransmission of sent packet.
+	 */
+	eap_status_e init_retransmission(
+		const eap_am_network_id_c * const send_network_id,
+		const wai_message_c * const received_wai_message_data,
+		const wai_message_c * const new_wai_message_data,
+		const u16_t packet_sequence_number,
+		const wai_protocol_subtype_e wapi_subtype
+		);
+
+	eap_status_e check_retransmission(const wai_protocol_packet_header_c * const wai);
+
+
+	/**
+	 * This function cancels previous session timeout and initializes new timeout for the session.
+	 */
+	eap_status_e initialize_session_timeout(
+		const u32_t session_timeout_ms);
+
+	/**
+	 * This function cancels timeout for a session.
+	 */
+	eap_status_e cancel_session_timeout();
+
+	/**
+	 * This function initializes timeout for received failure.
+	 */
+	eap_status_e set_wapi_failure_timeout();
+
+	/**
+	 * This function cancels timeout for received failure.
+	 */
+	eap_status_e cancel_wapi_failure_timeout();
+
+	eap_status_e asynchronous_init_remove_wapi_session();
+
+	eap_status_e initialize_asynchronous_init_remove_wapi_session(
+		const u32_t remove_session_timeout);
+
+	eap_status_e cancel_asynchronous_init_remove_wapi_session();
+
+	eap_status_e init_end_of_session(
+		const abs_eap_state_notification_c * const state);
+
+
+	eap_status_e create_BKID(
+		eap_variable_data_c * const BKID,
+		const eap_am_network_id_c * const receive_network_id);
+
+	eap_status_e packet_data_session_key(
+		eap_variable_data_c * const key, ///< Here is the key.
+		const eapol_key_type_e key_type, ///< This the type of the key.
+		const u32_t key_index, ///< This is the index of the key.
+		const bool key_tx_bit, ///< This is the TX bit of the key.
+		const u8_t * const key_RSC, ///< This is the RSC counter
+		const u32_t key_RSC_size ///< This is the size of RSC counter
+		);
+
+	eap_status_e create_unicast_key(
+		const eap_variable_data_c * const BK,
+		const eap_am_network_id_c * const receive_network_id,
+		const eap_variable_data_c * const ae_challenge,
+		const eap_variable_data_c * const asue_challenge,
+		eap_variable_data_c * const unicast_encryption_key_UEK,
+		eap_variable_data_c * const unicast_integrity_check_key_UCK,
+		eap_variable_data_c * const message_authentication_key_MAK,
+		eap_variable_data_c * const key_encryption_key_KEK,
+		eap_variable_data_c * const challenge_seed);
+
+	eap_status_e create_MAC(
+		const wai_message_payloads_c * const payloads,
+		eap_variable_data_c * const MAC);
+
+	eap_status_e create_HASH(
+		const wai_message_payloads_c * const payloads,
+		const bool hash_all_payloads,
+		eap_variable_data_c * const HASH);
+
+	eap_status_e packet_send(
+		wai_message_c * const m_new_wai_message_data,
+		const wai_protocol_subtype_e wapi_subtype);
+
+	eap_status_e packet_fragment(
+		wai_message_c * const new_wai_message_data,
+		const u16_t packet_sequence_number);
+
+	eap_status_e packet_reassemble(const wai_protocol_packet_header_c * const wai);
+
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+	eap_status_e start_certificate_negotiation();
+
+	eap_status_e start_unicast_key_negotiation();
+
+	eap_status_e start_multicast_key_announcement();
+
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+
+	eap_status_e handle_authentication_activation(
+		const eap_am_network_id_c * const receive_network_id,
+		const wai_protocol_packet_header_c * const wai);
+
+#if defined(USE_WAPI_CORE_SERVER)
+	eap_status_e handle_access_authentication_request(
+		const eap_am_network_id_c * const receive_network_id,
+		const wai_protocol_packet_header_c * const wai);
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+	eap_status_e handle_access_authentication_response(
+		const eap_am_network_id_c * const receive_network_id,
+		const wai_protocol_packet_header_c * const wai);
+
+	eap_status_e handle_unicast_key_negotiation_request(
+		const eap_am_network_id_c * const receive_network_id,
+		const wai_protocol_packet_header_c * const wai);
+
+#if defined(USE_WAPI_CORE_SERVER)
+	eap_status_e handle_unicast_key_negotiation_response(
+		const eap_am_network_id_c * const receive_network_id,
+		const wai_protocol_packet_header_c * const wai);
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+	eap_status_e handle_unicast_key_negotiation_confirmation(
+		const eap_am_network_id_c * const receive_network_id,
+		const wai_protocol_packet_header_c * const wai);
+
+
+	eap_status_e handle_multicast_key_announcement(
+		const eap_am_network_id_c * const receive_network_id,
+		const wai_protocol_packet_header_c * const wai);
+
+#if defined(USE_WAPI_CORE_SERVER)
+	eap_status_e handle_multicast_key_announcement_response(
+		const eap_am_network_id_c * const receive_network_id,
+		const wai_protocol_packet_header_c * const wai);
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+#if defined(USE_WAPI_CORE_SERVER)
+	eap_status_e encrypt_multicast_key_data(
+		const eap_variable_data_c * const multicast_key,
+		const eap_variable_data_c * const key_announcement,
+		wai_variable_data_c * const key_data);
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+	eap_status_e decrypt_multicast_key_data(
+		const wai_variable_data_c * const key_data,
+		const eap_variable_data_c * const key_announcement,
+		eap_variable_data_c * const multicast_key);
+
+	eap_status_e create_multicast_key(
+		const eap_variable_data_c * const notification_master_key,
+		eap_variable_data_c * const multicast_key);
+
+	eap_status_e create_signature_attributes(
+		wai_variable_data_c * const data_signature,
+		const eap_variable_data_c * const asue_id,
+		const eap_variable_data_c * const signature);
+
+	eap_status_e parse_signature_attributes(
+		const wai_variable_data_c * const data_signature,
+		eap_variable_data_c * const asue_id,
+		eap_variable_data_c * const signature);
+
+	eap_status_e create_result_of_certificate_verification(
+		wai_variable_data_c * const result_of_certificate_verification,
+		const eap_variable_data_c * const ae_challenge,
+		const eap_variable_data_c * const asue_challenge,
+		const wapi_certificate_result_e asue_certificate_result,
+		const eap_variable_data_c * const asue_certificate,
+		const wapi_certificate_result_e ae_certificate_result,
+		const eap_variable_data_c * const ae_certificate);
+
+	eap_status_e parse_result_of_certificate_verification(
+		const wai_variable_data_c * const result_of_certificate_verification,
+		eap_variable_data_c * const ae_challenge,
+		eap_variable_data_c * const asue_challenge,
+		wapi_certificate_result_e * const asue_certificate_result,
+		eap_variable_data_c * const asue_certificate,
+		wapi_certificate_result_e * const ae_certificate_result,
+		eap_variable_data_c * const ae_certificate);
+
+	bool compare_issuer_name(const eap_variable_data_c * const asue_id, const eap_variable_data_c * const ae_id);
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the eap_core class does nothing special.
+	 */
+	EAP_FUNC_IMPORT virtual ~wapi_core_c();
+
+	/**
+	 * The constructor initializes member attributes using parameters passed to it.
+	 * @param tools is pointer to the tools class. @see abs_eap_am_tools_c.
+	 * @param partner is back pointer to object which created this object.
+	 * @param is_client_when_true indicates whether the network entity should act
+	 * as a client (true) or server (false), in terms of WAPI-protocol
+	 * whether this network entity is WAPI-ASUE (true) or WAPI-ASU (false).
+	 */
+	EAP_FUNC_IMPORT wapi_core_c(
+		abs_eap_am_tools_c * const tools,
+		abs_wapi_core_c * const partner,
+		const bool is_client_when_true,
+		const eap_am_network_id_c * const receive_network_id);
+
+	EAP_FUNC_IMPORT eap_status_e initialize(
+		const eap_am_network_id_c * const receive_network_id,
+		const eapol_key_authentication_type_e authentication_type);
+
+	EAP_FUNC_IMPORT eap_status_e initialize(
+		const eap_am_network_id_c * const receive_network_id,
+		const eapol_key_authentication_type_e authentication_type,
+		const eap_variable_data_c * const wapi_ie_ae,
+		const eap_variable_data_c * const wapi_ie_asue,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher);
+
+	// This is documented in abs_eap_stack_interface_c::packet_process().
+	EAP_FUNC_IMPORT eap_status_e packet_process(
+		const eap_am_network_id_c * const receive_network_id,
+		eap_general_header_base_c * const packet_data,
+		const u32_t packet_length); 
+
+	// This is documented in abs_eap_base_type_c::packet_send().
+	EAP_FUNC_IMPORT eap_status_e packet_send(
+		const eap_am_network_id_c * const send_network_id,
+		eap_buf_chain_wr_c * const sent_packet,
+		const u32_t header_offset,
+		const u32_t data_length,
+		const u32_t buffer_length); 
+
+	/**
+	 * The get_partner() function returns pointer to partner class.
+	 */
+	EAP_FUNC_IMPORT abs_wapi_core_c * get_partner();
+
+	/**
+	 * The set_partner() function sets pointer to partner class.
+	 */
+	EAP_FUNC_IMPORT void set_partner(abs_wapi_core_c * const partner);
+
+	// This is documented in abs_eap_base_type_c::get_header_offset().
+	EAP_FUNC_IMPORT u32_t get_header_offset(
+		u32_t * const MTU,
+		u32_t * const trailer_length);
+
+	// This is documented in abs_eap_base_type_c::restart_authentication().
+	EAP_FUNC_IMPORT eap_status_e restart_authentication(
+		const eap_am_network_id_c * const send_network_id,
+		const bool is_client_when_true);
+
+	// This is documented in abs_eap_stack_interface_c::configure().
+	EAP_FUNC_IMPORT eap_status_e configure();
+
+	// This is documented in abs_eap_stack_interface_c::shutdown().
+	EAP_FUNC_IMPORT eap_status_e shutdown();
+
+	// This is documented in abs_eap_base_type_c::read_configure().
+	EAP_FUNC_IMPORT virtual eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	// This is documented in abs_eap_base_type_c::write_configure().
+	EAP_FUNC_IMPORT virtual eap_status_e write_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	// This is documented in abs_eap_stack_interface_c::set_is_valid().
+	EAP_FUNC_IMPORT void set_is_valid();
+
+	// This is documented in abs_eap_stack_interface_c::get_is_valid().
+	EAP_FUNC_IMPORT bool get_is_valid();
+
+	// This is documented in abs_eap_base_type_c::state_notification().
+	EAP_FUNC_IMPORT void state_notification(
+		const abs_eap_state_notification_c * const state);
+
+	// See abs_eap_base_timer_c::timer_expired().
+	EAP_FUNC_IMPORT eap_status_e timer_expired(
+		const u32_t id, void *data);
+
+	// See abs_eap_base_timer_c::timer_delete_data().
+	EAP_FUNC_IMPORT eap_status_e timer_delete_data(
+		const u32_t id, void *data);
+
+	/**
+	 * eap_core_map_c class increases reference count each time reference to stored object is get.
+	 * Here is always just one state for one session so no references are used.
+	 */
+	EAP_FUNC_IMPORT void object_increase_reference_count();
+
+	/**
+	 * eap_core_map_c class increases reference count each time reference to stored object is get.
+	 *  Here is always just one state for one session so no references are used.
+	 */
+	EAP_FUNC_IMPORT u32_t object_decrease_reference_count();
+
+	/**
+	 * Gets flag whether this session is marked removed.
+	 * Session is removed later if it is not reused.
+	 */
+	EAP_FUNC_IMPORT bool get_marked_removed();
+
+	/**
+	 * Marks this session removed.
+	 * Session is removed later if it is not reused.
+	 */
+	EAP_FUNC_IMPORT void set_marked_removed();
+
+	/**
+	 * Marks this session not removed.
+	 * Session is not removed it is reused.
+	 */
+	EAP_FUNC_IMPORT void unset_marked_removed();
+
+	/**
+	 * This function must reset the state of object to same as 
+	 * state was after the configure() function call.
+	 * If object reset succeeds this function must return eap_status_ok.
+	 * If object reset fails this function must return corresponding error status.
+	 * @return This function returns the status of reset operation.
+	 */
+	EAP_FUNC_IMPORT eap_status_e reset();
+
+	// This is documented in abs_eap_base_type_c::set_session_timeout().
+	EAP_FUNC_IMPORT eap_status_e set_session_timeout(
+		const u32_t session_timeout_ms);
+
+	// This is documented in abs_eap_base_type_c::set_timer().
+	EAP_FUNC_IMPORT eap_status_e set_timer(
+		abs_eap_base_timer_c * const p_initializer, 
+		const u32_t p_id, 
+		void * const p_data,
+		const u32_t p_time_ms);
+
+	// This is documented in abs_eap_base_type_c::cancel_timer().
+	EAP_FUNC_IMPORT eap_status_e cancel_timer(
+		abs_eap_base_timer_c * const p_initializer, 
+		const u32_t p_id);
+
+	// This is documented in abs_eap_base_type_c::cancel_all_timers().
+	EAP_FUNC_IMPORT eap_status_e cancel_all_timers();
+
+	// This is documented in abs_eap_base_type_c::set_authentication_role().
+	EAP_FUNC_IMPORT eap_status_e set_authentication_role(const bool when_true_set_client);
+
+	EAP_FUNC_IMPORT eap_status_e cancel_authentication_session();
+
+	EAP_FUNC_IMPORT eap_status_e check_bksa_cache(
+		// ****
+		// TODO: This needs to be updated for WAPI
+		const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite);
+
+	EAP_FUNC_IMPORT eap_status_e start_authentication();
+
+	EAP_FUNC_IMPORT eap_status_e allow_authentication();
+
+	EAP_FUNC_IMPORT eap_status_e init_bksa_caching_timeout();
+
+	EAP_FUNC_IMPORT eap_status_e reset_cached_bksa();
+
+	EAP_FUNC_IMPORT eap_status_e read_reassociation_parameters(
+		const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+		const eapol_key_authentication_type_e required_authentication_type,
+		eap_variable_data_c * const PMKID,
+		const eap_variable_data_c * const received_WPA_ie,
+		const eap_variable_data_c * const sent_WPA_ie);
+
+
+	// This is documented in abs_ec_certificate_store_c::complete_query_asu_id().
+	EAP_FUNC_IMPORT eap_status_e complete_query_asu_id(
+		const eap_variable_data_c * const asn1_der_subject_name,
+		const eap_variable_data_c * const asn1_der_issuer_name,
+		const eap_variable_data_c * const asn1_der_sequence_number,
+		const eap_status_e id_status);
+
+	// This is documented in abs_ec_certificate_store_c::complete_get_own_certificate().
+	EAP_FUNC_IMPORT eap_status_e complete_get_own_certificate(
+		const eap_variable_data_c * const own_certificate);
+
+	// This is documented in abs_ec_certificate_store_c::complete_select_certificate().
+	EAP_FUNC_IMPORT eap_status_e complete_select_certificate(
+		const eap_variable_data_c * const issuer_ID,
+		const eap_variable_data_c * const certificate_ID,
+		const eap_variable_data_c * const certificate);
+
+	// This is documented in abs_ec_certificate_store_c::complete_read_id_of_certificate().
+	EAP_FUNC_IMPORT eap_status_e complete_read_id_of_certificate(
+		const eap_variable_data_c * const ID);
+
+	// This is documented in abs_ec_certificate_store_c::complete_create_signature_with_private_key().
+	EAP_FUNC_IMPORT eap_status_e complete_create_signature_with_private_key(
+		const eap_variable_data_c * const signature,
+		const eap_status_e signature_status);
+
+	// This is documented in abs_ec_certificate_store_c::complete_verify_signature_with_public_key().
+	EAP_FUNC_IMPORT eap_status_e complete_verify_signature_with_public_key(
+		const eap_status_e verification_status);
+
+	// This is documented in abs_ec_certificate_store_c::complete_create_ecdh_temporary_keys().
+	EAP_FUNC_IMPORT eap_status_e complete_create_ecdh_temporary_keys(
+		const eap_variable_data_c * const private_key_d,
+		const eap_variable_data_c * const public_key_x,
+		const eap_variable_data_c * const public_key_y);
+
+	// This is documented in abs_ec_certificate_store_c::complete_create_ecdh().
+	EAP_FUNC_IMPORT eap_status_e complete_create_ecdh(
+		const eap_variable_data_c * const K_AB_x4,
+		const eap_variable_data_c * const K_AB_y4);
+
+
+	//--------------------------------------------------
+}; // class wapi_core_c
+
+
+#endif //#if !defined(_WAPI_CORE_H_)
+
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_core_retransmission.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,95 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_core_retransmission.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 8 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_CORE_RETRANSMISSION_H_)
+#define _WAPI_CORE_RETRANSMISSION_H_
+
+#include "eap_tools.h"
+#include "eap_am_export.h"
+#include "abs_eap_am_crypto.h"
+#include "wai_variable_data.h"
+
+class eap_am_network_id_c;
+class wai_message_c;
+
+
+/**
+ * This class stores the information of re-transmission of WAI-packet.
+ * @todo { Add more comments. }
+ */
+class wapi_core_retransmission_c
+{
+private:
+	
+	abs_eap_am_tools_c * const m_am_tools;
+
+	eap_am_network_id_c *m_send_network_id;
+
+	const wai_message_c * m_wai_message_data;
+
+	const wai_message_c * m_wai_received_message_data;
+
+	bool m_is_valid;
+
+	u32_t m_retransmission_time;
+	u32_t m_retransmission_counter;
+	u16_t m_packet_sequence_number;
+	wai_protocol_subtype_e m_wapi_subtype;
+
+public:
+
+	EAP_FUNC_IMPORT virtual ~wapi_core_retransmission_c();
+
+	EAP_FUNC_IMPORT wapi_core_retransmission_c(
+		abs_eap_am_tools_c * const tools,
+		const eap_am_network_id_c * const send_network_id,
+		const wai_message_c * const received_wai_message_data_or_null,
+		const wai_message_c * const wai_message_data,
+		const u32_t retransmission_time,
+		const u32_t retransmission_counter,
+		const u16_t packet_sequence_number,
+		const wai_protocol_subtype_e wapi_subtype);
+
+	EAP_FUNC_IMPORT bool get_is_valid() const;
+
+	EAP_FUNC_IMPORT u32_t get_next_retransmission_counter();
+
+	EAP_FUNC_IMPORT u32_t get_retransmission_counter() const;
+
+	EAP_FUNC_IMPORT u32_t get_next_retransmission_time();
+
+	EAP_FUNC_IMPORT eap_am_network_id_c *get_send_network_id() const;
+
+	EAP_FUNC_IMPORT const wai_message_c * get_wai_message_data() const;
+
+	EAP_FUNC_IMPORT const wai_message_c * get_wai_received_message_data() const;
+
+	EAP_FUNC_IMPORT u16_t get_packet_sequence_number() const;
+
+	EAP_FUNC_IMPORT wai_protocol_subtype_e get_wapi_subtype() const;
+};
+
+
+#endif //#if !defined(_WAPI_CORE_RETRANSMISSION_H_)
+
+//--------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_ethernet_core.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,258 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_ethernet_core.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 9.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_ETHERNET_CORE_H_)
+#define _WAPI_ETHERNET_CORE_H_
+
+#include "eap_tools.h"
+#include "eap_am_export.h"
+#include "abs_wapi_ethernet_core.h"
+#include "abs_wapi_core.h"
+#include "wapi_core.h"
+#include "wapi_session_core.h"
+#include "eap_variable_data.h"
+#include "eap_core_map.h"
+#include "abs_eap_stack_interface.h"
+#include "eapol_rsna_key_header.h"
+
+
+/// This class defines the ethernet protocol layer.
+class EAP_EXPORT wapi_ethernet_core_c
+: public abs_wapi_core_c
+, public abs_eap_stack_interface_c
+{
+private:
+	//--------------------------------------------------
+
+	abs_wapi_ethernet_core_c *m_partner;
+
+	wapi_session_core_c *m_wapi_core;
+
+	abs_eap_am_tools_c * const m_am_tools;
+
+	bool m_is_client;
+
+	bool m_is_valid;
+
+	bool m_shutdown_was_called;
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	// 
+	EAP_FUNC_IMPORT virtual ~wapi_ethernet_core_c();
+
+	// 
+	EAP_FUNC_IMPORT wapi_ethernet_core_c(
+		abs_eap_am_tools_c * const m_am_tools,
+		abs_wapi_ethernet_core_c * const partner,
+		const bool is_client_when_true);
+
+	EAP_FUNC_IMPORT eap_status_e cancel_all_authentication_sessions();
+
+
+	// This is documented in abs_eap_stack_interface_c::packet_process().
+	EAP_FUNC_IMPORT eap_status_e packet_process(
+		const eap_am_network_id_c * const receive_network_id,
+		eap_general_header_base_c * const packet_data,
+		const u32_t packet_length); 
+
+	//
+	EAP_FUNC_IMPORT eap_status_e packet_send(
+		const eap_am_network_id_c * const send_network_id,
+		eap_buf_chain_wr_c * const sent_packet,
+		const u32_t header_offset,
+		const u32_t data_length,
+		const u32_t buffer_length); 
+
+	//
+	EAP_FUNC_IMPORT u32_t get_header_offset(
+		u32_t * const MTU,
+		u32_t * const trailer_length);  
+
+	/**
+	 * This function checks whether WAPI BKID is cached to each eap_am_network_id_c object.
+	 * Function removes eap_am_network_id_c object from bssid_sta_receive_network_ids if there are
+	 * no cached BKID for eap_am_network_id_c object.
+	 * All eap_am_network_id_c objects that exist in bssid_sta_receive_network_ids
+	 * after function returns have BKID cached and read_reassociation_parameters() can be called
+	 * with those eap_am_network_id_c objects.
+	 */
+	EAP_FUNC_IMPORT eap_status_e check_bksa_cache(
+		eap_array_c<eap_am_network_id_c> * const bssid_sta_receive_network_ids,
+		const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite);
+
+	/**
+	 * This function removes BKID from cache.
+	 * @param receive_network_id carries the MAC addresses.
+	 * MAC address of Authenticator should be in source address.
+	 * MAC address of Supplicant should be in destination address.
+	 */
+	EAP_FUNC_IMPORT eap_status_e remove_bksa_from_cache(
+		const eap_am_network_id_c * const receive_network_id);
+
+	/**
+	 * This function starts the WAPI authentication.
+	 * The first parameter includes the network addresses of the protocol
+	 * over the WAPI packets are transmitted.
+	 * The type attribute of the eap_am_network_id_c object MUST be set
+	 * WAPI Ethernet type.
+	 * The second parameter is_client_when_true tells whether this stack
+	 * is client (true) or server (false).
+	 */ 
+	EAP_FUNC_IMPORT eap_status_e start_authentication(
+		const eap_am_network_id_c * const receive_network_id,
+		const bool is_client_when_true);
+
+	EAP_FUNC_IMPORT eap_status_e start_reassociation(
+		const eap_am_network_id_c * const receive_network_id,
+		const eapol_key_authentication_type_e authentication_type,
+		const eap_variable_data_c * const BKID);
+
+	EAP_FUNC_IMPORT eap_status_e read_reassociation_parameters(
+		const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address.
+		const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address.
+		const eapol_key_authentication_type_e authentication_type,
+		eap_variable_data_c * const BKID,
+		const eap_variable_data_c * const received_WAPI_ie,
+		const eap_variable_data_c * const sent_WAPI_ie);
+
+
+	EAP_FUNC_IMPORT eap_status_e complete_reassociation(
+		const eapol_wlan_authentication_state_e reassociation_result,
+		const eap_am_network_id_c * const receive_network_id,
+		const eapol_key_authentication_type_e authentication_type,
+		const eap_variable_data_c * const received_WAPI_IE,
+		const eap_variable_data_c * const sent_WAPI_IE,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite);
+
+	// This is documented in abs_eap_stack_interface_c::set_is_valid().
+	EAP_FUNC_IMPORT void set_is_valid();
+
+	// This is documented in abs_eap_stack_interface_c::get_is_valid().
+	EAP_FUNC_IMPORT bool get_is_valid();
+
+	// This is documented in abs_eap_stack_interface_c::configure().
+	EAP_FUNC_IMPORT eap_status_e configure();
+
+	// This is documented in abs_eap_stack_interface_c::shutdown().
+	EAP_FUNC_IMPORT eap_status_e shutdown();
+
+	EAP_FUNC_IMPORT eap_status_e packet_data_session_key(
+		const eap_am_network_id_c * const send_network_id,
+		const eapol_session_key_c * const key);
+
+	EAP_FUNC_IMPORT eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	EAP_FUNC_IMPORT eap_status_e write_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	// See abs_eap_base_type_c::state_notification().
+	EAP_FUNC_IMPORT void state_notification(
+		const abs_eap_state_notification_c * const state);
+
+
+	//
+	EAP_FUNC_IMPORT eap_status_e set_timer(
+		abs_eap_base_timer_c * const p_initializer, 
+		const u32_t p_id, 
+		void * const p_data,
+		const u32_t p_time_ms);
+
+	EAP_FUNC_IMPORT eap_status_e cancel_timer(
+		abs_eap_base_timer_c * const p_initializer, 
+		const u32_t p_id);
+
+	//
+	EAP_FUNC_IMPORT eap_status_e cancel_all_timers();
+
+	/**
+	 * Function creates a state for later use. This is for optimazing 4-Way Handshake.
+	 * @param receive_network_id carries the MAC addresses.
+	 * MAC address of Authenticator should be in source address. MAC address of 
+	 * Supplicant should be in destination address.
+	 * @param authentication_type is the selected authentication type.
+	 */
+	EAP_FUNC_IMPORT eap_status_e create_state(
+		const eap_am_network_id_c * const receive_network_id,
+		const eapol_key_authentication_type_e authentication_type
+		);
+
+	/**
+	 * This function need to be called when client STA (re)associates to AP.
+	 * @param receive_network_id carries the MAC addresses.
+	 * MAC address of Authenticator should be in source address. MAC address of Supplicant should be in destination address.
+	 * @param authenticator_RSNA_IE is RSN IE of authenticator. Authenticator sends this in Beacon or Probe message.
+	 * @param supplicant_RSNA_IE is RSN IE of supplicant. Supplicant sends this in (re)association request message.
+	 * @param eapol_pairwise_cipher is the selected pairwise cipher.
+	 * @param eapol_group_cipher is the selected group cipher.
+	 */
+	EAP_FUNC_IMPORT eap_status_e association(
+		const eap_am_network_id_c * const receive_network_id,
+		const eapol_key_authentication_type_e authentication_type,
+		const eap_variable_data_c * const authenticator_RSNA_IE,
+		const eap_variable_data_c * const supplicant_RSNA_IE,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher,
+		const eap_variable_data_c * const pre_shared_key);
+
+	/**
+	 * This function need to be called when client STA disassociates from AP.
+	 * @param receive_network_id carries the MAC addresses.
+	 * MAC address of Authenticator should be in source address. MAC address of Supplicant should be in destination address.
+	 */
+	EAP_FUNC_IMPORT eap_status_e disassociation(
+		const eap_am_network_id_c * const receive_network_id
+		);
+
+	EAP_FUNC_IMPORT eap_status_e restart_authentication(
+		const eap_am_network_id_c * const receive_network_id,
+		const bool is_client_when_true,
+		const bool force_clean_restart,
+		const bool from_timer = false);
+
+	EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_wapi_session(
+		const eap_am_network_id_c * const send_network_id);
+
+	EAP_FUNC_IMPORT eap_status_e set_session_timeout(
+		const u32_t session_timeout_ms);
+
+	//--------------------------------------------------
+}; // class wapi_ethernet_core_c
+
+#endif //#if !defined(_WAPI_ETHERNET_CORE_H_)
+
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_message_wlan_authentication.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,226 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_message_wlan_authentication.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 9.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+#if !defined(WAPI_MESSAGE_WLAN_AUTHENTICATION_H)
+#define WAPI_MESSAGE_WLAN_AUTHENTICATION_H
+
+// exports for ECOM plugin
+#if defined(__SYMBIAN32__)
+#undef EAP_NO_EXPORTS
+#endif
+
+#include "eap_am_export.h"
+#include "wapi_wlan_authentication.h"
+#include "eapol_ethernet_header.h"
+#include "eap_file_config.h"
+#include "abs_eapol_wlan_database_reference_if.h"
+#include "abs_wapi_message_wlan_authentication.h"
+// The same TLVs used as in EAPOL
+// so that WLAN engine can use existing functions (e.g. packet_send)
+#include "eapol_handle_tlv_message_data.h"  
+
+/** @file */
+
+class eap_tlv_header_c;
+
+/// This class is the common part of WAPI message interface.
+/// This class implements the message creation and parsing function.
+class EAP_EXPORT_INTERFACE wapi_message_wlan_authentication_c
+: public abs_wapi_wlan_authentication_c
+, public abs_eap_base_timer_c
+, public abs_eapol_wlan_database_reference_if_c
+{
+
+private:
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * m_am_tools;
+
+	/// This is pointer to the WLAN authentication implementation.
+	wapi_wlan_authentication_c * m_wauth;
+
+	/// Pointer to the lower layer in the stack
+	abs_wapi_message_wlan_authentication_c * m_partner;
+
+	eap_variable_data_c m_wlan_database_reference;
+
+	u32_t m_header_offset;
+	u32_t m_MTU;
+	u32_t m_trailer_length;
+
+	wlan_eap_if_send_status_e m_error_code;
+
+	eapol_tlv_message_type_function_e m_error_function;
+
+	bool m_is_valid;
+
+	// ----------------------------------------------------------------------
+
+	// This is used for checking BKSA cache in WAPI
+	// The function name is kept the same as in EAPOL.
+	EAP_FUNC_IMPORT eap_status_e check_bksa_cache(
+		EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const tlv_blocks);
+	
+	EAP_FUNC_IMPORT eap_status_e start_authentication(
+		EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters);
+
+	EAP_FUNC_IMPORT eap_status_e complete_association(
+		EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters);
+
+	EAP_FUNC_IMPORT eap_status_e disassociation(
+		EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters);
+
+	EAP_FUNC_IMPORT eap_status_e start_reassociation(
+		EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters);
+
+	EAP_FUNC_IMPORT eap_status_e complete_reassociation(
+		EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters);
+
+	EAP_FUNC_IMPORT eap_status_e packet_process(
+		EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters);
+
+	EAP_FUNC_IMPORT eap_status_e update_header_offset(
+		EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters);
+
+	EAP_FUNC_IMPORT eap_status_e update_wlan_database_reference_values(
+		EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters);
+
+	EAP_FUNC_IMPORT eap_status_e send_error_message(
+		const eap_status_e status,
+		const eapol_tlv_message_type_function_e function);
+
+	EAP_FUNC_IMPORT eap_status_e process_message_type_error(
+		EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters);
+
+	EAP_FUNC_IMPORT eap_status_e process_message(eapol_handle_tlv_message_data_c * const message);
+
+	EAP_FUNC_IMPORT eap_status_e send_message(eapol_handle_tlv_message_data_c * const message);
+
+	// ----------------------------------------------------------------------
+
+public:
+
+	EAP_FUNC_IMPORT_INTERFACE ~wapi_message_wlan_authentication_c();
+
+	EAP_FUNC_IMPORT_INTERFACE wapi_message_wlan_authentication_c(
+		abs_eap_am_tools_c * const tools,
+		abs_wapi_message_wlan_authentication_c * const partner);
+
+
+	/// This function configures the object and sets the initial values
+	/// of header offset, MTU and trailer length.
+	/// Look at the abs_eap_base_type_c::get_header_offset()
+	/// for description of header_offset, MTU and trailer_length.
+	EAP_FUNC_IMPORT_INTERFACE eap_status_e configure(
+		const u32_t header_offset,
+		const u32_t MTU,
+		const u32_t trailer_length);
+
+	// Look at abs_eap_stack_interface_c::shutdown().
+	EAP_FUNC_IMPORT_INTERFACE eap_status_e shutdown();
+
+	// Look at abs_eap_stack_interface_c::get_is_valid().
+	EAP_FUNC_IMPORT_INTERFACE bool get_is_valid();
+
+
+
+	// ------------------------------------------------------
+	// The following functions are from abs_eap_base_timer_c.
+
+	// Look at abs_eap_base_timer_c::timer_expired().
+	EAP_FUNC_IMPORT_INTERFACE eap_status_e timer_expired(
+		const u32_t id,
+		void *data);
+
+	// Look at abs_eap_base_timer_c::timer_delete_data().
+	EAP_FUNC_IMPORT_INTERFACE eap_status_e timer_delete_data(
+		const u32_t id,
+		void *data);
+
+	// The previous functions are from abs_eap_base_timer_c.
+	// ------------------------------------------------------
+
+
+	// ----------------------------------------------------------------
+	// The following functions are from abs_wapi_wlan_authentication_c.
+
+	// Look at abs_eapol_wlan_authentication_c::packet_send().
+	EAP_FUNC_IMPORT_INTERFACE eap_status_e packet_send(
+		const eap_am_network_id_c * const send_network_id,
+		eap_buf_chain_wr_c * const sent_packet,
+		const u32_t header_offset,
+		const u32_t data_length,
+		const u32_t buffer_length);
+
+	// Look at abs_wapi_wlan_authentication_c::get_header_offset().
+	EAP_FUNC_IMPORT_INTERFACE u32_t get_header_offset(
+		u32_t * const MTU,
+		u32_t * const trailer_length);
+
+	// Look at abs_wapi_wlan_authentication_c::associate().
+	// WAPI uses always open 802.11 authentication mode.
+	EAP_FUNC_IMPORT_INTERFACE eap_status_e associate(
+		eapol_key_802_11_authentication_mode_e authentication_mode);
+
+	// Look at abs_wapi_wlan_authentication_c::disassociate().
+	EAP_FUNC_IMPORT_INTERFACE eap_status_e disassociate(
+		const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+		const bool self_disassociation);
+
+	// Look at abs_wapi_wlan_authentication_c::packet_data_session_key().
+	EAP_FUNC_IMPORT_INTERFACE eap_status_e packet_data_session_key(
+		const eap_am_network_id_c * const send_network_id,
+		const eapol_session_key_c * const key);
+
+	// Look at abs_wapi_wlan_authentication_c::state_notification().
+	EAP_FUNC_IMPORT_INTERFACE void state_notification(
+		const abs_eap_state_notification_c * const state);
+
+	// Look at abs_wapi_wlan_authentication_c::reassociate().
+	EAP_FUNC_IMPORT_INTERFACE eap_status_e reassociate(
+		const eap_am_network_id_c * const send_network_id,
+		const eapol_key_authentication_type_e authentication_type,
+		const eap_variable_data_c * const BKID);
+
+
+	// ----------------------------------------------------------------------
+	// The following function is from abs_eapol_wlan_database_reference_if_c.
+
+	// Look at abs_eapol_wlan_database_reference_if_c::get_wlan_database_reference_values().
+	EAP_FUNC_IMPORT_INTERFACE eap_status_e get_wlan_database_reference_values(
+		eap_variable_data_c * const reference) const;
+
+	// The previous function is from abs_eapol_wlan_database_reference_if_c.
+	// ----------------------------------------------------------------------
+
+
+	/// Function receives the data message from lower layer.
+	/// Data is formatted to Attribute-Value Pairs.
+	/// Look at eap_tlv_header_c and eap_tlv_message_data_c.
+	EAP_FUNC_IMPORT_INTERFACE wlan_eap_if_send_status_e process_data(const void * const data, const u32_t length);
+
+	// ----------------------------------------------------------------------
+};
+
+#endif //#if !defined(WAPI_MESSAGE_WLAN_AUTHENTICATION_H)
+
+
+//--------------------------------------------------
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_session_core.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,365 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_session_core.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 9.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_SESSION_CORE_H_)
+#define _WAPI_SESSION_CORE_H_
+
+#include "eap_tools.h"
+#include "eap_am_export.h"
+#include "abs_wapi_core.h"
+#include "eap_core_map.h"
+#include "abs_eap_stack_interface.h"
+#include "eapol_rsna_key_header.h"
+
+class wapi_core_c;
+class eap_network_id_selector_c;
+
+
+/**
+ * This is the timer ID used with abs_eap_am_tools_c::set_timer() and abs_eap_am_tools_c::cancel_timer().
+ */
+enum wapi_session_core_timer_id
+{
+	WAPI_SESSION_CORE_REMOVE_SESSION_ID ///< See WAPI_SESSION_CORE_REMOVE_SESSION_TIMEOUT.
+};
+
+/**
+ * This is time after a WAPI session is removed. This must be zero.
+ */
+const u32_t WAPI_SESSION_CORE_REMOVE_SESSION_TIMEOUT = 0u;
+
+
+/// A wapi_session_core_c class implements mapping of WAPI authentication sessions.
+/// Network identity separates parallel WAPI authentication sessions.
+class EAP_EXPORT wapi_session_core_c
+: public abs_wapi_core_c
+, public abs_eap_core_map_c
+, public abs_eap_base_timer_c
+, public abs_eap_stack_interface_c
+{
+private:
+	//--------------------------------------------------
+
+	/// This is back pointer to object which created this object.
+	/// Packets are sent to the partner.
+	abs_wapi_core_c * const m_partner;
+
+	/// This is pointer to the tools class.
+	abs_eap_am_tools_c * const m_am_tools;
+
+	/// This stores WAPI authentication session objects using eap_variable_data selector.
+	eap_core_map_c<wapi_core_c, abs_eap_core_map_c, eap_variable_data_c> m_session_map;
+
+	u32_t m_remove_session_timeout;
+
+	/// This indicates whether this object is client (true) or server (false).
+	bool m_is_client;
+
+	/// This indicates whether this object was generated successfully.
+	bool m_is_valid;
+
+	bool m_use_wapi_session_core_reset_session;
+
+	bool m_shutdown_was_called;
+
+
+	/**
+	 * Function creates a new session.
+	 */
+	EAP_FUNC_IMPORT wapi_core_c * create_new_session(
+		const eap_am_network_id_c * const receive_network_id);
+
+	EAP_FUNC_IMPORT eap_status_e reset_or_remove_session(
+		wapi_core_c ** const session,
+		const eap_network_id_selector_c * const selector,
+		const bool reset_immediately);
+
+
+	EAP_FUNC_IMPORT static eap_status_e shutdown_operation(
+		wapi_core_c * const core,
+		abs_eap_am_tools_c * const m_am_tools);
+
+	static eap_status_e cancel_authentication_session(
+		wapi_core_c * const handler,
+		abs_eap_am_tools_c * const m_am_tools);
+
+	eap_status_e init_eapol_key_bksa_caching_timeout(
+		const eap_am_network_id_c * const send_network_id);
+
+	eap_status_e remove_wapi_state(
+		const eap_am_network_id_c * const send_network_id);
+
+	//--------------------------------------------------
+protected:
+	//--------------------------------------------------
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	/**
+	 * The destructor of the wapi_core class does nothing special.
+	 */
+	EAP_FUNC_IMPORT virtual ~wapi_session_core_c();
+
+	/**
+	 * The constructor initializes member attributes using parameters passed to it.
+	 * @param tools is pointer to the tools class. @see abs_eap_am_tools_c.
+	 * @param partner is back pointer to object which created this object.
+	 * @param is_client_when_true indicates whether the network entity should act
+	 * as a client (true) or server (false), in terms of WAPI-protocol
+	 * whether this network entity is WAPI-ASUE (true) or WAPI-ASU (false).
+	 */
+	EAP_FUNC_IMPORT wapi_session_core_c(
+		abs_eap_am_tools_c * const tools,
+		abs_wapi_core_c * const partner,
+		const bool is_client_when_true);
+
+	/**
+	 * This function must reset the state of object to same as 
+	 * state was after the configure() function call.
+	 * If object reset succeeds this function must return eap_status_ok.
+	 * If object reset fails this function must return corresponding error status.
+	 * @return This function returns the status of reset operation.
+	 */
+	EAP_FUNC_IMPORT eap_status_e reset();
+
+	/**
+	 * This function cancels all WAPI-sessions.
+	 * If this succeeds this function must return eap_status_ok.
+	 * If this fails this function must return corresponding error status.
+	 * @return This function returns the status of operation.
+	 */
+	EAP_FUNC_IMPORT eap_status_e synchronous_cancel_all_wapi_sessions();
+
+	// This is documented in abs_eap_stack_interface_c::packet_process().
+	EAP_FUNC_IMPORT eap_status_e packet_process(
+		const eap_am_network_id_c * const receive_network_id,
+		eap_general_header_base_c * const packet_data,
+		const u32_t packet_length); 
+
+	/**
+	 * The class could send packets to partner class with this function.
+	 * @param send_network_id carries the addresses (network identity) and type of the packet.
+	 * @param sent_packet includes the buffer for the whole packet and initialized 
+	 * packet in correct offset.
+	 * @param header_offset is offset of the header within the sent_packet.
+	 * @param data_length is length in bytes of the packet.
+	 * @param buffer_length is length in bytes of the whole packet buffer.
+	 */
+	EAP_FUNC_IMPORT eap_status_e packet_send(
+		const eap_am_network_id_c * const send_network_id,
+		eap_buf_chain_wr_c * const sent_packet,
+		const u32_t header_offset,
+		const u32_t data_length,
+		const u32_t buffer_length); 
+
+	/**
+	 * The get_partner() function returns pointer to partner class.
+	 */
+	EAP_FUNC_IMPORT abs_wapi_core_c * get_partner();
+
+	/**
+	 * The get_header_offset() function obtains the header offset of WAI-packet.
+	 * @param MTU_length is pointer to variable to store the maximum transfer unit (MTU).
+	 * MTU is the maximum packet length in bytes
+	 * @param trailer_length is pointer to the variable to store length
+	 * of trailer needed by lower levels.
+	 * @return Function returns the offset of header.
+	 * @see abs_eap_base_type_c::get_header_offset().
+	 */
+	EAP_FUNC_IMPORT u32_t get_header_offset(
+		u32_t * const MTU,
+		u32_t * const trailer_length);
+
+	/**
+	 * This function restarts authentication using current object.
+	 * This is used for testing.
+	 */
+	EAP_FUNC_IMPORT eap_status_e restart_authentication(
+		const eap_am_network_id_c * const send_network_id,
+		const bool is_client_when_true);
+
+	/**
+	 * The packet_data_session_key() function passes one traffic encryption key to 
+	 * the lower layers. Ultimately the key can end up to the WLAN hardware.
+	 * @param send_network_id carries the addresses (network identity) and type of the packet.
+	 * @param key is the encryption key
+	 * @param key_length is the length of the key
+	 * @param key_type describes the type of the key (WEP or something else...)
+	 * @param key_index is the index of the encryption key (there can be four broadcast keys in WEP for example)
+	 */
+	EAP_FUNC_IMPORT eap_status_e packet_data_session_key(
+		const eap_am_network_id_c * const send_network_id,
+		const eapol_session_key_c * const key);
+
+	// This is documented in abs_eap_stack_interface_c::configure().
+	EAP_FUNC_IMPORT eap_status_e configure();
+
+	// This is documented in abs_eap_stack_interface_c::shutdown().
+	EAP_FUNC_IMPORT eap_status_e shutdown();
+
+	/**
+	 * The read_configure() function reads the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the query to some persistent store.
+	 * @param field is generic configure string idenfying the required configure data.
+	 * @param field_length is length of the field string.
+	 * @param data is pointer to existing eap_variable_data object.
+	 */
+	EAP_FUNC_IMPORT virtual eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	/**
+	 * The write_configure() function writes the configuration data identified
+	 * by the field string of field_length bytes length. Adaptation module must direct
+	 * the action to some persistent store.
+	 * @param field is generic configure string idenfying the required configure data.
+	 * @param field_length is length of the field string.
+	 * @param data is pointer to existing eap_variable_data object.
+	 */
+	EAP_FUNC_IMPORT virtual eap_status_e write_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	// This is documented in abs_eap_stack_interface_c::set_is_valid().
+	EAP_FUNC_IMPORT void set_is_valid();
+
+	// This is documented in abs_eap_stack_interface_c::get_is_valid().
+	EAP_FUNC_IMPORT bool get_is_valid();
+
+	// See abs_eap_base_type_c::state_notification().
+	EAP_FUNC_IMPORT void state_notification(
+		const abs_eap_state_notification_c * const state);
+
+	// See abs_eap_base_timer_c::timer_expired().
+	EAP_FUNC_IMPORT eap_status_e timer_expired(
+		const u32_t id, void *data);
+
+	// See abs_eap_base_timer_c::timer_delete_data().
+	EAP_FUNC_IMPORT eap_status_e timer_delete_data(
+		const u32_t id, void *data);
+
+	/**
+	 * The adaptation module calls the restart_authentication() function
+	 * when WAPI-authentication is needed with another peer.
+	 * @see abs_eap_core_c::restart_authentication().
+	 */
+	EAP_FUNC_IMPORT eap_status_e restart_authentication(
+		const eap_am_network_id_c * const receive_network_id,
+		const bool is_client_when_true,
+		const bool force_clean_restart,
+		const bool from_timer = false);
+
+	/**
+	 * This function creates WAPI-session object synchronously.
+	 * @param receive_network_id identifies the removed WAPI-session.
+	 */
+	EAP_FUNC_IMPORT eap_status_e synchronous_create_wapi_session(
+		const eap_am_network_id_c * const receive_network_id);
+
+	/**
+	 * This function removes session object synchronously.
+	 * @param receive_network_id identifies the removed WAPI-session.
+	 */
+	EAP_FUNC_IMPORT eap_status_e synchronous_remove_wapi_session(
+		const eap_am_network_id_c * const receive_network_id);
+
+	/**
+	 * This function removes session object asynchronously.
+	 * @param send_network_id identifies the removed session.
+	 */
+	eap_status_e asynchronous_init_remove_wapi_session(
+		const eap_am_network_id_c * const send_network_id);
+
+	/**
+	 * This function tells lower layer to remove session object asynchronously.
+	 * @param eap_type is pointer to selector that identifies the removed session.
+	 */
+	EAP_FUNC_IMPORT eap_status_e asynchronous_init_remove_wapi_session(
+		const eap_network_id_selector_c * const state_selector);
+
+	//
+	EAP_FUNC_IMPORT eap_status_e set_timer(
+		abs_eap_base_timer_c * const p_initializer, 
+		const u32_t p_id, 
+		void * const p_data,
+		const u32_t p_time_ms);
+
+	EAP_FUNC_IMPORT eap_status_e cancel_timer(
+		abs_eap_base_timer_c * const p_initializer, 
+		const u32_t p_id);
+
+	//
+	EAP_FUNC_IMPORT eap_status_e cancel_all_timers();
+
+	// This is documented in abs_eap_core_c::set_session_timeout().
+	EAP_FUNC_IMPORT eap_status_e set_session_timeout(
+		const u32_t session_timeout_ms);
+
+	EAP_FUNC_IMPORT eap_status_e read_reassociation_parameters(
+		const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address.
+		const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address.
+		const eapol_key_authentication_type_e authentication_type,
+		eap_variable_data_c * const BKID,
+		const eap_variable_data_c * const received_WAPI_ie,
+		const eap_variable_data_c * const sent_WAPI_ie);
+
+	EAP_FUNC_IMPORT eap_status_e cancel_all_authentication_sessions();
+
+	EAP_FUNC_IMPORT eap_status_e check_bksa_cache(
+		eap_array_c<eap_am_network_id_c> * const bssid_sta_receive_network_ids,
+		const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite);
+
+	EAP_FUNC_IMPORT eap_status_e association(
+		const eap_am_network_id_c * const receive_network_id,
+		const eapol_key_authentication_type_e authentication_type,
+		const eap_variable_data_c * const wapi_ie_ae,
+		const eap_variable_data_c * const wapi_ie_asue,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher,
+		const eap_variable_data_c * const pre_shared_key);
+
+	EAP_FUNC_IMPORT eap_status_e disassociation(
+		const eap_am_network_id_c * const receive_network_id
+		);
+
+	EAP_FUNC_IMPORT eap_status_e create_state(
+		const eap_am_network_id_c * const receive_network_id,
+		const eapol_key_authentication_type_e authentication_type
+		);
+
+	EAP_FUNC_IMPORT eap_status_e remove_bksa_from_cache(
+		const eap_am_network_id_c * const receive_network_id);
+
+	//--------------------------------------------------
+}; // class wapi_session_core_c
+
+#endif //#if !defined(_WAPI_SESSION_CORE_H_)
+
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_strings.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,71 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_strings.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 10 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_STRINGS_H_)
+#define _WAPI_STRINGS_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_tools.h"
+#include "eap_general_header_base.h"
+#include "wapi_types.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------------
+
+/// This class includes the debug strings of the Elliptic curve certificate store.
+class EAP_EXPORT wapi_strings_c
+{
+public:
+
+	EAP_FUNC_IMPORT virtual ~wapi_strings_c();
+
+	EAP_FUNC_IMPORT wapi_strings_c();
+
+	EAP_FUNC_IMPORT static eap_const_string get_wapi_completion_operation_string(const wapi_completion_operation_e type);
+
+	EAP_FUNC_IMPORT static eap_const_string get_wai_protocol_version_string(const wai_protocol_version_e type);
+
+	EAP_FUNC_IMPORT static eap_const_string get_wai_protocol_type_string(const wai_protocol_type_e type);
+
+	EAP_FUNC_IMPORT static eap_const_string get_wai_protocol_subtype_string(const wai_protocol_subtype_e type);
+
+	EAP_FUNC_IMPORT static eap_const_string get_wai_tlv_header_string(const wai_tlv_type_e type);
+
+	EAP_FUNC_IMPORT static eap_const_string get_wai_payload_type_string(const wai_payload_type_e type);
+
+	EAP_FUNC_IMPORT static eap_const_string get_wapi_core_state_string(const wapi_core_state_e state);
+
+	EAP_FUNC_IMPORT static eap_const_string get_wapi_negotiation_state_string(const wapi_negotiation_state_e state);
+
+
+};
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_WAPI_STRINGS_H_)
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_types.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,501 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_types.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 39 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_TYPES_H_)
+#define _WAPI_TYPES_H_
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+
+/** @file */
+
+//----------------------------------------------------------------------------
+
+enum wapi_completion_operation_e
+{
+	wapi_completion_operation_none,
+	wapi_completion_operation_continue_certificate_authentication,
+};
+
+enum wai_protocol_version_e
+{
+	wai_protocol_version_none = 0,
+	wai_protocol_version_1 = 1,
+};
+
+enum wai_protocol_type_e
+{
+	wai_protocol_type_none,
+	wai_protocol_type_wai = 1,
+};
+
+enum wai_protocol_subtype_e
+{
+	wai_protocol_subtype_none,
+	wai_protocol_subtype_pre_authentication_start = 1,
+	wai_protocol_subtype_stakey_request,
+	wai_protocol_subtype_authentication_activation,
+	wai_protocol_subtype_access_authentication_request,
+	wai_protocol_subtype_access_authentication_response,
+	wai_protocol_subtype_certificate_authentication_request,
+	wai_protocol_subtype_certificate_authentication_response,
+	wai_protocol_subtype_unicast_key_negotiation_request,
+	wai_protocol_subtype_unicast_key_negotiation_response,
+	wai_protocol_subtype_unicast_key_negotiation_confirmation,
+	wai_protocol_subtype_multicast_key_announcement,
+	wai_protocol_subtype_multicast_key_announcement_response,
+};
+
+/// This enumerates wai_tlv_header_c types.
+enum wai_tlv_type_e
+{
+	wai_tlv_type_none,
+	wai_tlv_type_signature_attribute              = 1,
+	wai_tlv_type_echd_parameter                   = 1,
+	wai_tlv_type_result_of_certificate_validation = 2,
+	wai_tlv_type_identity_list                    = 3,
+
+	wai_tlv_type_first_known = wai_tlv_type_signature_attribute,
+	wai_tlv_type_last_known = wai_tlv_type_identity_list,
+};
+
+enum wai_certificate_identifier_e
+{
+	wai_certificate_identifier_none,
+	wai_certificate_identifier_x_509_v3 = 1,
+	wai_certificate_identifier_gbw      = 2,
+};
+
+enum wai_payload_type_e
+{
+	wai_payload_type_none,
+	wai_payload_type_flag, ///< This is type of 1 octet.
+	wai_payload_type_access_result, ///< This is type of 1 octet.
+	wai_payload_type_uskid, ///< This is type of 1 octet.
+	wai_payload_type_mskid_stakeyid, ///< This is type of 1 octet.
+	wai_payload_type_result, ///< This is type of 1 octet.
+
+	wai_payload_type_addid, ///< This is type of 12 octets. Two MAC addresses each 6 octet in length.
+
+	wai_payload_type_bkid, ///< This is type of 16 octets.
+	wai_payload_type_key_announcement_identifier, ///< This is type of 16 octets.
+	wai_payload_type_data_sequence_number, ///< This is type of 16 octets.
+
+	wai_payload_type_message_authentication_code, ///< This is type of 20 octets. Output from HMAC-SHA256.
+
+	wai_payload_type_authentication_identifier, ///< This is type of 32 octet.
+	wai_payload_type_nonce, ///< This is type of 32 octets.
+
+	wai_payload_type_key_data, ///< This is type of <1 octet length><length count of octets>
+
+	wai_payload_type_wie, ///< This is type of WIE <1 octet Element ID><1 octet length><length count of octets>.
+
+	wai_payload_type_echd_parameter, ///< This is type of wai_tlv_header_c.
+	wai_payload_type_signature_attributes, ///< This is type of wai_tlv_header_c.
+	wai_payload_type_result_of_certificate_verification, ///< This is type of wai_tlv_header_c.
+	wai_payload_type_identity_list, ///< This is type of wai_tlv_header_c.
+	wai_payload_type_optional, ///< This is type of wai_tlv_header_c.
+
+	wai_payload_type_certificate, ///< This is type of ec_cs_tlv_header_c.
+	wai_payload_type_identity, ///< This is type of ec_cs_tlv_header_c.
+
+	wai_payload_type_first_known = wai_payload_type_flag,
+	wai_payload_type_last_known = wai_payload_type_identity,
+
+	wai_payload_type_terminator = 0xffffffff,
+};
+
+enum wai_payload_type_size_e
+{
+	wai_payload_type_size_none = 0,
+
+	wai_payload_type_size_1_octet = 1, ///< This is type class of 1 octet.
+
+	wai_payload_type_size_12_octets = 12, ///< This is type class of 12 octets.
+
+	wai_payload_type_size_16_octets = 16, ///< This is type class of 16 octets.
+
+	wai_payload_type_size_20_octets = 20, ///< This is type class of 20 octets.
+
+	wai_payload_type_size_32_octets = 32, ///< This is type class of 32 octet.
+
+	wai_payload_type_size_1_octet_length_field = 0x7001, ///< This is type class of <1 octet length><length count of octets>
+
+	wai_payload_type_size_wie = 0x7002, ///< This is type of WIE <1 octet Element ID><1 octet length><length count of octets>.
+
+	wai_payload_type_size_wai_tlv_header = 0x7003, ///< This is type of wai_tlv_header_c.
+
+	wai_payload_type_size_ec_cs_tlv_header = 0x7004, ///< This is type of ec_cs_tlv_header_c.
+};
+
+//----------------------------------------------------------------------------
+
+struct wai_payload_type_to_size_map_s
+{
+	wai_payload_type_size_e m_size;
+	wai_payload_type_e       m_type;
+};
+
+const wai_payload_type_to_size_map_s wai_payload_type_to_class_map[] =
+{
+	{ wai_payload_type_size_none, wai_payload_type_none },
+
+	{ wai_payload_type_size_1_octet, wai_payload_type_flag },
+	{ wai_payload_type_size_1_octet, wai_payload_type_access_result },
+	{ wai_payload_type_size_1_octet, wai_payload_type_uskid },
+	{ wai_payload_type_size_1_octet, wai_payload_type_mskid_stakeyid },
+	{ wai_payload_type_size_1_octet, wai_payload_type_result },
+
+	{ wai_payload_type_size_12_octets, wai_payload_type_addid },
+
+	{ wai_payload_type_size_16_octets, wai_payload_type_bkid },
+	{ wai_payload_type_size_16_octets, wai_payload_type_key_announcement_identifier },
+	{ wai_payload_type_size_16_octets, wai_payload_type_data_sequence_number },
+
+	{ wai_payload_type_size_20_octets, wai_payload_type_message_authentication_code },
+
+	{ wai_payload_type_size_32_octets, wai_payload_type_authentication_identifier },
+	{ wai_payload_type_size_32_octets, wai_payload_type_nonce },
+
+	{ wai_payload_type_size_1_octet_length_field, wai_payload_type_key_data },
+
+	{ wai_payload_type_size_wie, wai_payload_type_wie },
+
+	{ wai_payload_type_size_wai_tlv_header, wai_payload_type_echd_parameter },
+	{ wai_payload_type_size_wai_tlv_header, wai_payload_type_signature_attributes },
+	{ wai_payload_type_size_wai_tlv_header, wai_payload_type_result_of_certificate_verification },
+	{ wai_payload_type_size_wai_tlv_header, wai_payload_type_identity_list },
+	{ wai_payload_type_size_wai_tlv_header, wai_payload_type_optional },
+
+	{ wai_payload_type_size_ec_cs_tlv_header, wai_payload_type_certificate },
+	{ wai_payload_type_size_ec_cs_tlv_header, wai_payload_type_identity },
+};
+
+//----------------------------------------------------------------------------
+
+const wai_payload_type_e required_payloads_authentication_activation[] =
+{
+	wai_payload_type_flag,
+	wai_payload_type_authentication_identifier,
+	wai_payload_type_identity,
+	wai_payload_type_certificate,
+	wai_payload_type_echd_parameter,
+	wai_payload_type_terminator
+};
+
+const wai_payload_type_e required_payloads_access_authentication_request[] =
+{
+	wai_payload_type_flag,
+	wai_payload_type_authentication_identifier,
+	wai_payload_type_nonce,
+	wai_payload_type_key_data,
+	wai_payload_type_identity,
+	wai_payload_type_certificate,
+	wai_payload_type_echd_parameter,
+	wai_payload_type_optional,
+	//wai_payload_type_signature_attributes,
+	wai_payload_type_terminator
+};
+
+const wai_payload_type_e required_payloads_access_authentication_response[] =
+{
+	wai_payload_type_flag,
+	wai_payload_type_nonce,
+	wai_payload_type_nonce,
+	wai_payload_type_access_result,
+	wai_payload_type_key_data,
+	wai_payload_type_key_data,
+	wai_payload_type_identity,
+	wai_payload_type_identity,
+	wai_payload_type_optional,
+	//wai_payload_type_signature_attributes,
+	wai_payload_type_terminator
+};
+
+const wai_payload_type_e required_payloads_certificate_authentication_request[] =
+{
+	wai_payload_type_addid,
+	wai_payload_type_nonce,
+	wai_payload_type_nonce,
+	wai_payload_type_certificate,
+	wai_payload_type_certificate,
+	wai_payload_type_optional,
+	wai_payload_type_terminator
+};
+
+const wai_payload_type_e required_payloads_certificate_authentication_response[] =
+{
+	wai_payload_type_addid,
+	wai_payload_type_result_of_certificate_verification,
+	wai_payload_type_signature_attributes,
+	wai_payload_type_signature_attributes,
+	wai_payload_type_terminator
+};
+
+const wai_payload_type_e required_payloads_unicast_key_negotiation_request[] =
+{
+	wai_payload_type_flag,
+	wai_payload_type_bkid,
+	wai_payload_type_uskid,
+	wai_payload_type_addid,
+	wai_payload_type_nonce,
+	wai_payload_type_terminator
+};
+
+const wai_payload_type_e required_payloads_unicast_key_negotiation_response[] =
+{
+	wai_payload_type_flag,
+	wai_payload_type_bkid,
+	wai_payload_type_uskid,
+	wai_payload_type_addid,
+	wai_payload_type_nonce,
+	wai_payload_type_nonce,
+	wai_payload_type_wie,
+	wai_payload_type_message_authentication_code,
+	wai_payload_type_terminator
+};
+
+const wai_payload_type_e required_payloads_unicast_key_negotiation_confirmation[] =
+{
+	wai_payload_type_flag,
+	wai_payload_type_bkid,
+	wai_payload_type_uskid,
+	wai_payload_type_addid,
+	wai_payload_type_nonce,
+	wai_payload_type_wie,
+	wai_payload_type_message_authentication_code,
+	wai_payload_type_terminator
+};
+
+const wai_payload_type_e required_payloads_multicast_key_announcement[] =
+{
+	wai_payload_type_flag,
+	wai_payload_type_mskid_stakeyid,
+	wai_payload_type_uskid,
+	wai_payload_type_addid,
+	wai_payload_type_data_sequence_number,
+	wai_payload_type_key_announcement_identifier,
+	wai_payload_type_key_data,
+	wai_payload_type_message_authentication_code,
+	wai_payload_type_terminator
+};
+
+const wai_payload_type_e required_payloads_multicast_key_announcement_response[] =
+{
+	wai_payload_type_flag,
+	wai_payload_type_mskid_stakeyid,
+	wai_payload_type_uskid,
+	wai_payload_type_addid,
+	wai_payload_type_key_announcement_identifier,
+	wai_payload_type_message_authentication_code,
+	wai_payload_type_terminator
+};
+
+//----------------------------------------------------------------------------
+
+enum wai_data_flag_mask_e
+{
+	wai_data_flag_mask_none                           = 0x00,
+	wai_data_flag_mask_BK_Rekeying                    = (1u << 0u),
+	wai_data_flag_mask_Pre_Authentication             = (1u << 1u),
+	wai_data_flag_mask_Certificate_Validation_Request = (1u << 2u),
+	wai_data_flag_mask_Optional_Field                 = (1u << 3u),
+	wai_data_flag_mask_USK_Rekeying                   = (1u << 4u),
+	wai_data_flag_mask_STAKey_Negotiation             = (1u << 5u),
+	wai_data_flag_mask_STAKey_Revoking                = (1u << 6u),
+};
+
+enum wai_data_uskid_mask_e
+{
+	wai_data_uskid_mask_none  = 0x00,
+	wai_data_uskid_mask_uskid = (1u << 0u),
+	wai_data_uskid_mask_mskid = (1u << 0u),
+};
+
+enum wai_unicast_cipher_suite_e
+{
+	wai_unicast_cipher_suite_none,
+	wai_unicast_cipher_suite_SMS4,
+};
+
+enum wapi_core_state_e
+{
+	wapi_core_state_none,
+	wapi_core_state_start_unicast_key_negotiation,
+	wapi_core_state_start_certificate_negotiation,
+	wapi_core_state_start_multicast_key_announcement,
+	wapi_core_state_wait_authentication_activation_message,
+	wapi_core_state_process_authentication_activation_message,
+	wapi_core_state_wait_access_authentication_request_message,
+	wapi_core_state_process_access_authentication_request_message,
+	wapi_core_state_process_access_authentication_request_message_ASU_signature_trusted_by_AE,
+	wapi_core_state_process_access_authentication_request_message_AE_signature_trusted_by_ASUE,
+	wapi_core_state_wait_certificate_authentication_request_message,
+	wapi_core_state_wait_certificate_authentication_response_message,
+	wapi_core_state_wait_access_authentication_response_message,
+	wapi_core_state_process_access_authentication_response_message,
+	wapi_core_state_process_access_authentication_response_message_ASU_signature,
+	wapi_core_state_wait_unicast_key_negotiation_request_message,
+	wapi_core_state_wait_unicast_key_negotiation_response_message,
+	wapi_core_state_wait_unicast_key_negotiation_confirmation_message,
+	wapi_core_state_wait_multicast_announcement_message,
+	wapi_core_state_wait_multicast_announcement_response_message,
+	wapi_core_state_authentication_ok,
+	wapi_core_state_authentication_failed,
+};
+
+enum wapi_negotiation_state_e
+{
+	wapi_negotiation_state_none,
+	wapi_negotiation_state_initial_negotiation,
+	wapi_negotiation_state_rekeying,
+};
+
+enum wapi_certificate_result_e
+{
+	wapi_certificate_result_none                                           = 0xff,
+	wapi_certificate_result_valid                                          = 0u,
+	wapi_certificate_result_issuer_is_unknown                              = 1u,
+	wapi_certificate_result_certificate_is_based_on_an_untrusted_root      = 2u,
+	wapi_certificate_result_certificate_is_not_time_valid                  = 3u,
+	wapi_certificate_result_certificate_have_not_a_valid_signature         = 4u,
+	wapi_certificate_result_certificate_is_revoked                         = 5u,
+	wapi_certificate_result_certificate_is_not_valid_for_proposed_usage    = 6u,
+	wapi_certificate_result_revocation_state_of_the_certificate_is_unknown = 7u,
+};
+
+enum wapi_access_result_e
+{
+	wapi_access_result_none                            = 0xff,
+	wapi_access_result_successfull_access              = 0u,
+	wapi_access_result_certificate_cannot_be_verified  = 1u,
+	wapi_access_result_certificate_error               = 2u,
+	wapi_access_result_prohibition_on_the_local_policy = 3u,
+};
+
+//----------------------------------------------------------------------------
+
+const u8_t WAPI_PRESHARED_KEY_LABEL[] = "preshared key expansion for authentication and key negotiation";
+
+const u32_t WAPI_PRESHARED_KEY_LABEL_LENGTH = sizeof(WAPI_PRESHARED_KEY_LABEL)-1ul;
+
+const u8_t WAPI_CERTIFICATE_KEY_LABEL[] = "base key expansion for key and additional nonce";
+
+const u32_t WAPI_CERTIFICATE_KEY_LABEL_LENGTH = sizeof(WAPI_CERTIFICATE_KEY_LABEL)-1ul;
+
+const u32_t WAPI_BK_LENGTH = 16ul;
+
+
+const u32_t WAPI_BKID_LENGTH = 16ul;
+
+const u32_t WAPI_USKSA_COUNT = 2ul;
+
+const u32_t WAPI_MSKSA_COUNT = 2ul;
+
+const u32_t WAPI_CHALLENGE_LENGTH = 32ul;
+
+const u32_t WAPI_AUTHENTICATION_IDENTIFIER_LENGTH = 32ul;
+
+
+const u8_t WAPI_UNICAST_KEY_LABEL[] = "pairwise key expansion for unicast and additional keys and nonce";
+
+const u32_t WAPI_UNICAST_KEY_LABEL_LENGTH = sizeof(WAPI_UNICAST_KEY_LABEL)-1ul;
+
+
+const u8_t WAPI_MULTICAST_KEY_EXPANSION_LABEL[] = "multicast or station key expansion for station unicast and multicast and broadcast";
+
+const u32_t WAPI_MULTICAST_KEY_EXPANSION_LABEL_LENGTH = sizeof(WAPI_MULTICAST_KEY_EXPANSION_LABEL)-1ul;
+
+
+const u32_t WAPI_UNICAST_ENCRYPTION_KEY_UEK_LENGTH = 16ul;
+
+const u32_t WAPI_UNICAST_INTEGRITY_CHECK_KEY_UCK_LENGTH = 16ul;
+
+const u32_t WAPI_MESSAGE_AUTHENTICATION_KEY_MAK_LENGTH = 16ul;
+
+const u32_t WAPI_KEY_ENCRYPTION_KEY_KEK_LENGTH = 16ul;
+
+const u32_t WAPI_CHALLENGE_SEED_LENGTH = 32ul;
+
+const u32_t WAPI_MESSAGE_AUTHENTICATION_CODE_LENGTH = 20ul;
+
+const u32_t WAPI_NOTIFICATION_MASTER_KEY_LENGTH = 16ul;
+
+const u32_t WAPI_MULTICAST_KEY_LENGTH = 32ul;
+
+
+const u32_t WAPI_UNICAST_KEY_LENGTH
+	= WAPI_UNICAST_ENCRYPTION_KEY_UEK_LENGTH
+	+ WAPI_UNICAST_INTEGRITY_CHECK_KEY_UCK_LENGTH
+	+ WAPI_MESSAGE_AUTHENTICATION_KEY_MAK_LENGTH
+	+ WAPI_KEY_ENCRYPTION_KEY_KEK_LENGTH
+	+ WAPI_CHALLENGE_SEED_LENGTH;
+
+const u16_t WAI_FIRST_SEQUENCE_NUMBER = 1u;
+
+const u16_t WAI_FIRST_FRAGMENT_NUMBER = 0u;
+
+const u32_t WIE_HEADER_LENGTH = 2ul*sizeof(u8_t);
+
+const u8_t WAPI_ECDH_OID_PARAMETER[] =
+{
+	0x06, 0x09, //# U, P, 0x06 = OBJECT IDENTIFIER, length 0x09 = 9 octets
+	0x2a,     //# = 42 = 40 * 1 + 2 => 1.2
+	0x81, 0x1c, //# 0x1 * 128^1 + 0x1c = 156 
+	0xd7, 0x63, //# 0x57 * 128^1 + 0x63 = 11235 
+	0x01,     //# 0x1 = 1 
+	0x01,     //# 0x1 = 1 
+	0x02,     //# 0x2 = 2 
+	0x01,     //# 0x1 = 1 : full OID = 1.2.156.11235.1.1.2.1 = elliptic curve parameters 
+};
+
+const u8_t WAI_HASH_ALGORITHM_ID = 1u;
+const u8_t WAI_SIGNATURE_ALGORITHM_ID = 1u;
+const u8_t WAI_SIGNATURE_PARAMETER_ID = 1u;
+
+const u8_t WAI_EC_POINT_TYPE_NO_COMPRESSION_ID = 4u;
+
+const u8_t WAPI_ORGANIZATIONAL_UNIT_NAME_OID_PARAMETER[] =
+{
+	0x06, 0x03, //# U, P, 0x06 = OBJECT IDENTIFIER, length 0x03 = 3 octets
+	0x55,       //# = 85 = 40 * 2 + 5 => 2.5
+	0x04,       //# 0x4 = 4
+	0x0b,     //# 0xb = 11 : full OID = 2.5.4.11 = organizational unit name 
+};
+
+const u8_t WAPI_COMMON_NAME_OID_PARAMETER[] =
+{
+	0x06, 0x03, //# U, P, 0x06 = OBJECT IDENTIFIER, length 0x03 = 3 octets
+	0x55,       //# = 85 = 40 * 2 + 5 => 2.5
+	0x04,       //# 0x4 = 4
+	0x03,     //# 0x3 = 3 : full OID = 2.5.4.3 = common name 
+};
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+#endif //#if !defined(_WAPI_TYPES_H_)
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/include/wapi_wlan_authentication.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,334 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/include/wapi_wlan_authentication.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 9.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_WLAN_AUTHENTICATION_H_)
+#define _WAPI_WLAN_AUTHENTICATION_H_
+
+// INCLUDES
+#include "wapi_am_wlan_authentication.h"
+#include "abs_wapi_am_wlan_authentication.h"
+#include "abs_wapi_ethernet_core.h"
+#include "abs_wapi_wlan_authentication.h"
+#include "eapol_key_types.h"
+#include "eap_array.h"
+#include "eapol_rsna_key_header.h"
+#include "eapol_test_stack_if.h"
+#include "eap_am_network_id.h"
+
+// FORWARD DECLARATIONS
+class wapi_ethernet_core_c;
+
+class eap_file_config_c;
+class eapol_wlan_database_reference_c;
+
+
+// CLASS DECLARATION
+class EAP_EXPORT wapi_wlan_authentication_c
+: public abs_wapi_am_wlan_authentication_c
+, public abs_wapi_ethernet_core_c
+, public abs_eap_base_timer_c
+#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+, public eapol_test_stack_if_c
+#endif
+{
+public:
+
+	EAP_FUNC_IMPORT static wapi_wlan_authentication_c * new_wapi_wlan_authentication(
+		abs_eap_am_tools_c * const tools,
+		abs_wapi_wlan_authentication_c * const partner,
+		const bool is_client_when_true,
+		const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference);
+
+	EAP_FUNC_IMPORT wapi_wlan_authentication_c(
+		abs_eap_am_tools_c * const tools,
+		abs_wapi_wlan_authentication_c * const partner,
+		wapi_am_wlan_authentication_c * const am_wauth, ///< wapi_wlan_authentication_c must always delete the am_wauth object.
+		const bool is_client_when_true);
+
+#if defined(EXPORT_DESTRUCTORS)
+	EAP_FUNC_IMPORT virtual ~wapi_wlan_authentication_c();	 // For GCC compilation
+#else
+	virtual ~wapi_wlan_authentication_c();	 // For RVCT compilation
+#endif
+	
+	
+	///////////////////////////////////////////////////////////////
+	/* These are called from WLM */
+
+	/**
+	 * This function checks whether WAPI BKSA is cached to each eap_am_network_id_c object.
+	 * Function removes eap_am_network_id_c object from bssid_sta_receive_network_ids if there are
+	 * no cached BKSA for removes eap_am_network_id_c object.
+	 * All eap_am_network_id_c objects that exist in bssid_sta_receive_network_ids
+	 * after function returns have BKSA cached and read_reassociation_parameters() can be called
+	 * with those eap_am_network_id_c objects.
+	 */
+	EAP_FUNC_IMPORT eap_status_e check_bksa_cache(
+		eap_array_c<eap_am_network_id_c> * const bssid_sta_receive_network_ids,
+		const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite);
+
+	EAP_FUNC_IMPORT eap_status_e start_authentication(
+		const eap_variable_data_c * const SSID,
+		const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+		// In WAPI these are used for the PSK mode
+		const eap_variable_data_c * const preshared_key,
+		const bool WAPI_override_enabled,
+		const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address.
+		);
+
+	EAP_FUNC_IMPORT eap_status_e complete_association(
+		const eapol_wlan_authentication_state_e association_result,
+		const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+		const eap_variable_data_c * const received_WAPI_IE,
+		const eap_variable_data_c * const sent_WAPI_IE,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite
+		);
+	
+	EAP_FUNC_IMPORT eap_status_e disassociation(
+		const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address.
+		);
+		
+	EAP_FUNC_IMPORT eap_status_e start_reassociation(
+		const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address.
+		const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address.
+		const eapol_key_authentication_type_e selected_eapol_key_authentication_type 
+		);
+
+	EAP_FUNC_IMPORT eap_status_e complete_reassociation(
+		const eapol_wlan_authentication_state_e reassociation_result,
+		const eap_am_network_id_c * const receive_network_id,
+		const eap_variable_data_c * const received_WAPI_IE,
+		const eap_variable_data_c * const sent_WAPI_IE,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+		const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite);
+
+	EAP_FUNC_IMPORT eap_status_e packet_process(
+		const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+		eap_general_header_base_c * const packet_data,
+		const u32_t packet_length
+		);
+
+
+	/////////////////////////////////////////
+	/* These are called from wapi_ethernet_core */
+	
+	/**
+	* Sends packet to lower layers
+	*/
+	EAP_FUNC_IMPORT eap_status_e packet_send(
+		const eap_am_network_id_c * const send_network_id, ///< source includes local address, destination includes remote address.
+		eap_buf_chain_wr_c * const sent_packet,
+		const u32_t header_offset,
+		const u32_t data_length,
+		const u32_t buffer_length); 
+
+	EAP_FUNC_IMPORT u32_t get_header_offset(
+		u32_t * const MTU,
+		u32_t * const trailer_length);
+
+	EAP_FUNC_IMPORT void set_is_valid();
+
+	EAP_FUNC_IMPORT bool get_is_valid();
+
+	EAP_FUNC_IMPORT void increment_authentication_counter();
+
+	EAP_FUNC_IMPORT u32_t get_authentication_counter();
+
+#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// For testing 
+
+	EAP_FUNC_IMPORT u32_t get_wrong_send_packet_index();
+
+	EAP_FUNC_IMPORT void set_authentication_can_succeed();
+
+	EAP_FUNC_IMPORT void reset_authentication_can_succeed();
+
+	EAP_FUNC_IMPORT void restore_authentication_can_succeed();
+
+	EAP_FUNC_IMPORT void set_authentication_must_not_succeed(
+        const u32_t wrong_packet_index,
+        const u32_t packet_index,
+        const void * const wrong_packet_stack);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#endif // #if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+	EAP_FUNC_IMPORT bool get_is_client();
+
+	/**
+	* This does the initial configuration of the class.
+	*/
+	EAP_FUNC_IMPORT eap_status_e configure();
+
+	EAP_FUNC_IMPORT eap_status_e shutdown();
+
+	/**
+	* Reads a configuration parameter value from the database. 
+	* In Symbian this function is only a TRAP wrapper for read_configure_L.
+	*/
+	EAP_FUNC_IMPORT eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	EAP_FUNC_IMPORT eap_status_e write_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	// See abs_eap_base_type_c::state_notification().
+	EAP_FUNC_IMPORT void state_notification(const abs_eap_state_notification_c * const state);
+	
+	EAP_FUNC_IMPORT eap_status_e set_timer(
+		abs_eap_base_timer_c * const p_initializer, 
+		const u32_t p_id, 
+		void * const p_data,
+		const u32_t p_time_ms);
+
+	EAP_FUNC_IMPORT eap_status_e cancel_timer(
+		abs_eap_base_timer_c * const p_initializer, 
+		const u32_t p_id);
+
+	EAP_FUNC_IMPORT eap_status_e cancel_all_timers();
+
+	/**
+	* Forwards the keys to lower layer (= WLM).
+	*/
+	EAP_FUNC_IMPORT eap_status_e packet_data_session_key(
+		const eap_am_network_id_c * const send_network_id, ///< source includes local address, destination includes remote address.
+		const eapol_session_key_c * const key);
+
+	EAP_FUNC_IMPORT eap_status_e timer_expired(const u32_t id, void *data);
+
+	EAP_FUNC_IMPORT eap_status_e timer_delete_data(const u32_t id, void *data);
+
+
+private:
+
+	EAP_FUNC_IMPORT eap_status_e wapi_indication(
+		const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+		const eapol_wlan_authentication_state_e notification);
+
+	EAP_FUNC_IMPORT eap_status_e create_upper_stack();
+
+	eap_status_e disassociation_mutex_must_be_reserved(
+		const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address.
+		);
+
+	eap_status_e cancel_all_authentication_sessions();
+
+	eap_status_e cancel_timer_this_ap_failed();
+
+	eap_status_e cancel_timer_failed_completely();
+
+	eap_status_e cancel_timer_no_response();
+
+	eap_status_e cancel_timer_authentication_cancelled();
+
+#if defined(USE_EAP_ERROR_TESTS)
+
+	eap_status_e random_error(
+		eap_buf_chain_wr_c * const sent_packet,
+		const bool forse_error,
+		const u32_t packet_index);
+
+#endif //#if defined(USE_EAP_ERROR_TESTS)
+
+
+private:
+
+
+	/// Pointer to the lower layer in the stack
+	abs_wapi_wlan_authentication_c * m_partner;
+
+	/// Pointer to the AM of WAUTH.
+	wapi_am_wlan_authentication_c * m_am_wauth;
+
+	/// Pointer to the upper layer in the stack
+	wapi_ethernet_core_c * m_ethernet_core;
+
+	/// Pointer to the tools class
+	abs_eap_am_tools_c * m_am_tools;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	
+	eap_variable_data_c m_preshared_key;
+	
+	eapol_key_authentication_type_e m_authentication_type;
+
+	eapol_key_802_11_authentication_mode_e m_802_11_authentication_mode;
+
+	eap_variable_data_c m_received_WAPI_IE;
+
+	eap_variable_data_c m_sent_WAPI_IE;
+
+	eapol_RSNA_key_header_c::eapol_RSNA_cipher_e m_group_key_cipher_suite;
+
+	eapol_RSNA_key_header_c::eapol_RSNA_cipher_e m_pairwise_key_cipher_suite;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	u32_t m_authentication_counter;
+
+	u32_t m_successful_authentications;
+
+	u32_t m_failed_authentications;
+
+	bool m_is_valid;
+
+	bool m_is_client;	
+
+	bool m_shutdown_was_called;
+
+#if defined(USE_EAP_ERROR_TESTS)
+
+	u32_t m_error_probability;
+
+	u32_t m_randomly_drop_packets_probability;
+
+	u32_t m_generate_multiple_error_packets;
+
+	bool m_enable_random_errors;
+
+	bool m_randomly_drop_packets;
+
+	bool m_manipulate_ethernet_header;
+
+	bool m_send_original_packet_first;
+
+#endif //#if defined(USE_EAP_ERROR_TESTS)
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	
+	//--------------------------------------------------
+}; // class wapi_wlan_authentication_c
+
+#endif //#if !defined(_WAPI_WLAN_AUTHENTICATION_H_)
+
+//--------------------------------------------------
+
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/abs_ec_am_algorithms.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,38 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/abs_ec_am_algorithms.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 4 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "abs_ec_am_algorithms.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT abs_ec_am_algorithms_c::~abs_ec_am_algorithms_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/abs_ec_certificate_store.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,38 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/abs_ec_certificate_store.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 3 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_cs_types.h"
+#include "abs_ec_certificate_store.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT abs_ec_certificate_store_c::~abs_ec_certificate_store_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/dummy_wapi_core.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,179 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/wapi_core/dummy_wapi_core.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 11 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+#include "eap_status.h"
+#include "eap_am_assert.h"
+#include "abs_eap_am_tools.h"
+#include "eap_am_types.h"
+#include "dummy_wapi_core.h"
+
+
+// Constructor
+dummy_wapi_core_c::dummy_wapi_core_c()
+    {
+    }
+    
+// Destructor
+dummy_wapi_core_c::~dummy_wapi_core_c()
+    {
+    }
+
+// Returns the status of the object
+bool dummy_wapi_core_c::get_is_valid()
+    {
+    return true;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+
+eap_status_e dummy_wapi_core_c::set_timer(
+    abs_eap_base_timer_c * const p_initializer, 
+    const u32_t p_id, 
+    void * const p_data,
+    const u32_t p_time_ms)
+    {
+    return eap_status_not_found;
+    }
+
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::cancel_timer( abs_eap_base_timer_c* const initializer, 
+                                            const u32_t id)
+    {
+    return eap_status_not_found;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::set_session_timeout(const u32_t session_timeout_ms)
+    {
+    return eap_status_not_found;
+    }
+
+
+/************************************************************
+ ********Inhertited from abs_ec_certificate_store_c *********
+ ************************************************************/
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::complete_get_own_certificate(
+    const eap_variable_data_c * const own_certificate)
+    {
+    return eap_status_not_found;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::complete_query_asu_id(
+    const eap_variable_data_c * const asn1_der_subject_name,
+    const eap_variable_data_c * const asn1_der_issuer_name,
+    const eap_variable_data_c * const asn1_der_sequence_number,
+    const eap_status_e id_status)
+    {
+    return eap_status_not_found;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::complete_select_certificate(
+    const eap_variable_data_c * const issuer_ID,
+    const eap_variable_data_c * const certificate_ID,
+    const eap_variable_data_c * const certificate)
+    {
+    return eap_status_not_found;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::complete_read_id_of_certificate(
+    const eap_variable_data_c * const ID)
+    {
+    return eap_status_not_found;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::complete_create_signature_with_private_key(
+    const eap_variable_data_c * const signature,
+    const eap_status_e signature_status)
+    {
+    return eap_status_not_found;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::complete_verify_signature_with_public_key(
+    const eap_status_e verification_status)
+    {
+    return eap_status_not_found;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::complete_create_ecdh_temporary_keys(
+    const eap_variable_data_c * const private_key_d,
+    const eap_variable_data_c * const public_key_x,
+    const eap_variable_data_c * const public_key_y)
+    {
+    return eap_status_not_found;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::complete_create_ecdh(
+    const eap_variable_data_c * const K_AB_x4,
+    const eap_variable_data_c * const K_AB_y4)
+    {
+    return eap_status_not_found;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+void dummy_wapi_core_c::state_notification( const abs_eap_state_notification_c * const state)
+    {
+    return;
+    }
+
+/********************************************************************
+ *  No functionality for inherited function
+ ********************************************************************/
+eap_status_e dummy_wapi_core_c::read_configure(
+    const eap_configuration_field_c * const field,
+    eap_variable_data_c * const data)
+    {
+    return eap_status_not_found;
+    }
+
+    
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_am_algorithms_direct_nrc.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,1102 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_algorithms.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 28.1.2 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 701 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_am_algorithms_direct_nrc.h"
+#include "ec_cs_types.h"
+#include "ec_cs_strings.h"
+#include "abs_ec_am_algorithms.h"
+#include "abs_eap_am_file_input.h"
+#include "asn1_der_type.h"
+#include "abs_ec_am_algorithms.h"
+#include "eap_crypto_api.h"
+
+#if defined(USE_NRC_ECC_ALGORITHMS)
+#include "nc_drmeccp256.h"
+#include "nc_pkcs1_5.h"
+#include "nc_hash.h"
+#include "nc_rand.h"
+#endif //#if defined(USE_NRC_ECC_ALGORITHMS)
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_am_algorithms_direct_nrc_c::~ec_am_algorithms_direct_nrc_c()
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::~ec_am_algorithms_direct_nrc_c():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_am_algorithms_direct_nrc_c::~ec_am_algorithms_direct_nrc_c()");
+
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_am_algorithms_direct_nrc_c::ec_am_algorithms_direct_nrc_c(
+	abs_eap_am_tools_c * const tools,
+	abs_ec_am_algorithms_c * const partner,
+	const bool is_client_when_true)
+	: m_am_tools(tools)
+	, m_partner(partner)
+	, m_e_curve(tools)
+	, m_nc_rand_state(tools)
+	, m_is_client(is_client_when_true)
+	, m_is_valid(false)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::ec_am_algorithms_direct_nrc_c():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_am_algorithms_direct_nrc_c::ec_am_algorithms_direct_nrc_c()");
+
+	m_is_valid = true;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_am_algorithms_direct_nrc_c::get_is_valid() const
+{
+	return m_is_valid;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_am_algorithms_direct_nrc_c::configure()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::configure():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_am_algorithms_direct_nrc_c::configure()");
+
+	eap_status_e status(eap_status_ok);
+
+	status = initialize_curve();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_am_algorithms_direct_nrc_c::create_signature_with_private_key(
+	const eap_variable_data_c * const hash_of_message,
+	const eap_variable_data_c * const private_key)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::create_signature_with_private_key():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_am_algorithms_direct_nrc_c::create_signature_with_private_key()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	asn1_der_type_c asn1(m_am_tools);
+	if (asn1.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = asn1.decode(private_key);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	static const asn1_type_const_c private_key_query[] =
+	{
+		ASN1_TYPE_OBJECT(
+			asn1_der_type_c::asn1_class_universal,
+			asn1_der_type_c::asn1_tag_sequence,
+			0),                                       // ECPrivateKey{CURVES:IOSet} ::= SEQUENCE
+		ASN1_TYPE_OBJECT(
+			asn1_der_type_c::asn1_class_universal,
+			asn1_der_type_c::asn1_tag_octet_string,
+			1),                                       // privateKey OCTET STRING
+		ASN1_TYPE_OBJECT_TERMINATOR
+	};
+
+	const asn1_der_type_c * const der_private_key = asn1.get_sub_type(private_key_query);
+
+	if (der_private_key != 0)
+	{
+
+#if defined(USE_NRC_ECC_ALGORITHMS)
+
+		gfp_coord private_key;
+
+		OS2IP(
+			private_key.a.d,
+			der_private_key->get_content(),
+			der_private_key->get_content_length());
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ECC Private key"),
+			der_private_key->get_content(),
+			der_private_key->get_content_length()));
+
+		gfp_point sign_point1;
+		gfp_point sign_point2;
+
+		gfp_curve * const e_curve = reinterpret_cast<gfp_curve *>(m_e_curve.get_data());
+		if (e_curve == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		struct nc_rand_state * const nc_rand_state = reinterpret_cast<struct nc_rand_state *>(m_nc_rand_state.get_data(sizeof(struct nc_rand_state)));
+		if (e_curve == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("hash_of_message"),
+			hash_of_message->get_data(),
+			hash_of_message->get_data_length()));
+
+
+		DRM_ECDSA_Sign_P256(
+			nc_rand_state,
+			sign_point1.x.a.d,
+			sign_point2.x.a.d,
+			hash_of_message->get_data(),
+			hash_of_message->get_data_length(),
+			private_key.a.d,
+			e_curve,
+			0);
+
+		u32_t sign_len(0ul);
+		u32_t sign_point_len((2ul * sign_point1.x.a.d[0]) + (2ul * sign_point2.x.a.d[0]));
+
+		eap_variable_data_c signature(m_am_tools);
+
+		if (signature.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = signature.set_buffer_length(sign_point_len);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = signature.set_data_length(sign_point_len);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+
+		/* Check the length of sign_point1.x.a.d and convert it to octet string. */
+		if (sign_point1.x.a.d[0] != 0)
+		{
+			sign_point_len = 2ul * sign_point1.x.a.d[0];
+
+			I2OSP(
+				signature.get_data_offset(sign_len, sign_point_len),
+				sign_point1.x.a.d,
+				sign_point_len);
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("sign_point1"),
+				signature.get_data_offset(sign_len, sign_point_len),
+				sign_point_len));
+
+			sign_len += sign_point_len;
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::create_signature_with_private_key(): ECDSA sign point 1 generation failed\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+
+		 /* Check the length of sign_point2.x.a.d and convert it to octet string. */
+		if (sign_point2.x.a.d[0] != 0)
+		{
+			sign_point_len = 2ul * sign_point2.x.a.d[0];
+
+			I2OSP(
+				signature.get_data_offset(sign_len, sign_point_len),
+				sign_point2.x.a.d,
+				sign_point_len);
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("sign_point2"),
+				signature.get_data_offset(sign_len, sign_point_len),
+				sign_point_len));
+
+			sign_len += sign_point_len;
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::create_signature_with_private_key(): ECDSA sign point 2 generation failed\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+
+		status = signature.set_data_length(sign_len);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+		
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("signature"),
+			 signature.get_data(),
+			 signature.get_data_length()));
+
+
+		status = m_partner->complete_create_signature_with_private_key(&signature, eap_status_ok);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+#endif //#if defined(USE_NRC_ECC_ALGORITHMS)
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("# Private key not found.\n")));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_am_algorithms_direct_nrc_c::verify_signature_with_public_key(
+	const eap_variable_data_c * const public_key,
+	const eap_variable_data_c * const hash_of_message,
+	const eap_variable_data_c * const signature)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::verify_signature_with_public_key():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_am_algorithms_direct_nrc_c::verify_signature_with_public_key()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	asn1_der_type_c asn1(m_am_tools);
+	if (asn1.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = asn1.decode(public_key);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	static const asn1_type_const_c public_key_query[] =
+	{
+		ASN1_TYPE_OBJECT(
+			asn1_der_type_c::asn1_class_universal,
+			asn1_der_type_c::asn1_tag_sequence,
+			0),                                       // Certificate  ::=  SEQUENCE
+		ASN1_TYPE_OBJECT(
+			asn1_der_type_c::asn1_class_universal,
+			asn1_der_type_c::asn1_tag_sequence,
+			0),                                       // TBSCertificate  ::=  SEQUENCE
+		ASN1_TYPE_OBJECT(
+			asn1_der_type_c::asn1_class_universal,
+			asn1_der_type_c::asn1_tag_sequence,
+			6),                                       // subjectPublicKeyInfo SubjectPublicKeyInfo, SubjectPublicKeyInfo  ::=  SEQUENCE
+		ASN1_TYPE_OBJECT(
+			asn1_der_type_c::asn1_class_universal,
+			asn1_der_type_c::asn1_tag_bit_string,
+			1),                                       // subjectPublicKey     BIT STRING
+		ASN1_TYPE_OBJECT_TERMINATOR
+	};
+
+	const asn1_der_type_c * const der_public_key = asn1.get_sub_type(public_key_query);
+
+	if (der_public_key != 0)
+	{
+
+#if defined(USE_NRC_ECC_ALGORITHMS)
+
+		gfp_point public_key;
+
+		{
+			const u8_t * const bit_string_public_key = der_public_key->get_content();
+			const u32_t bit_string_public_key_length(der_public_key->get_content_length());
+
+			if (bit_string_public_key != 0
+				&& bit_string_public_key_length > 0ul)
+			{
+				// bit_string_public_key[0]: number of unused bits
+				// bit_string_public_key[1]: format of bit string
+				// bit_string_public_key[2]: the public key starts
+				const u8_t * key = &(bit_string_public_key[2]);
+				const u32_t key_length(bit_string_public_key_length - 2ul);
+
+				const u32_t length = key_length / 2ul;
+
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("ECC Public key"),
+					key,
+					key_length));
+
+				OS2IP(
+					public_key.x.a.d,
+					key,
+					length);
+
+				key += length;
+
+				OS2IP(
+					public_key.y.a.d,
+					key,
+					key_length - length);
+			}
+		}
+
+		gfp_point sign_point1;
+		gfp_point sign_point2;
+
+		const u32_t length(signature->get_data_length() / 2ul);
+
+		OS2IP(
+			sign_point1.x.a.d,
+			signature->get_data(length),
+			length);
+
+		const u32_t remaining_length(signature->get_data_length() - length);
+
+		OS2IP(
+			sign_point2.x.a.d,
+			signature->get_data_offset(length, remaining_length),
+			remaining_length);
+
+		gfp_curve * const e_curve = reinterpret_cast<gfp_curve *>(m_e_curve.get_data());
+		if (e_curve == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+		
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("hash_of_message"),
+			hash_of_message->get_data(),
+			hash_of_message->get_data_length()));
+
+		u32_t verification_status = DRM_ECDSA_Verify_P256(
+			hash_of_message->get_data(),
+			hash_of_message->get_data_length(),
+			sign_point1.x.a.d,
+			sign_point2.x.a.d,
+			&public_key,
+			e_curve);
+
+		if (verification_status)
+		{
+			// OK signature.
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::verify_signature_with_public_key(): Signature OK, verification_status = %d .\n"),
+				 this,
+				 (m_is_client == true ? "client": "server"),
+				 verification_status));
+
+			status = m_partner->complete_verify_signature_with_public_key(eap_status_ok);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::verify_signature_with_public_key(): Wrong signature.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			status = m_partner->complete_verify_signature_with_public_key(eap_status_authentication_failure);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+#else
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+
+#endif //#if defined(USE_NRC_ECC_ALGORITHMS)
+
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("# Public key not found.\n")));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_am_algorithms_direct_nrc_c::initialize_curve()
+{
+
+#if defined(USE_NRC_ECC_ALGORITHMS)
+
+	const byte param_a192[24]=
+	{
+		0xBB, 0x8E, 0x5E, 0x8F, 0xBC, 0x11, 0x5E, 0x13,
+		0x9F, 0xE6, 0xA8, 0x14, 0xFE, 0x48, 0xAA, 0xA6,
+		0xF0, 0xAD, 0xA1, 0xAA, 0x5D, 0xF9, 0x19, 0x85
+	};
+
+	const byte param_b192[24]=
+	{
+		0x18, 0x54, 0xBE, 0xBD, 0xC3, 0x1B, 0x21, 0xB7,
+		0xAE, 0xFC, 0x80, 0xAB, 0x0E, 0xCD, 0x10, 0xD5,
+		0xB1, 0xB3, 0x30, 0x8E, 0x6D, 0xBF, 0x11, 0xC1
+	};
+
+	const byte param_p192[24]=
+	{
+		0xBD, 0xB6, 0xF4, 0xFE, 0x3E, 0x8B, 0x1D, 0x9E,
+		0x0D, 0xA8, 0xC0, 0xD4, 0x6F, 0x4C, 0x31, 0x8C,
+		0xEF, 0xE4, 0xAF, 0xE3, 0xB6, 0xB8, 0x55, 0x1F
+	};
+
+	const byte param_order192[24]=
+	{
+		0xBD, 0xB6, 0xF4, 0xFE, 0x3E, 0x8B, 0x1D, 0x9E,
+		0x0D, 0xA8, 0xC0, 0xD4, 0x0F, 0xC9, 0x62, 0x19,
+		0x5D, 0xFA, 0xE7, 0x6F, 0x56, 0x56, 0x46, 0x77
+	};
+
+	const byte param_gx192[24]=
+	{
+		0x4A, 0xD5, 0xF7, 0x04, 0x8D, 0xE7, 0x09, 0xAD,
+		0x51, 0x23, 0x6D, 0xE6, 0x5E, 0x4D, 0x4B, 0x48,
+		0x2C, 0x83, 0x6D, 0xC6, 0xE4, 0x10, 0x66, 0x40
+	};
+
+	const byte param_gy192[24]=
+	{
+		0x02, 0xBB, 0x3A, 0x02, 0xD4, 0xAA, 0xAD, 0xAC,
+		0xAE, 0x24, 0x81, 0x7A, 0x4C, 0xA3, 0xA1, 0xB0,
+		0x14, 0xB5, 0x27, 0x04, 0x32, 0xDB, 0x27, 0xD2
+	};
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("Initialize 192 bits elliptic curve\n")));
+	
+
+	gfp_curve local_e_curve;
+
+	OS2IP(local_e_curve.e.p.a.d,param_p192,24);
+	OS2IP(local_e_curve.order.a.d,param_order192,24);
+
+	OS2IP(local_e_curve.e.a.a.d,param_a192,24);
+	OS2IP(local_e_curve.e.b.a.d,param_b192,24);
+
+	OS2IP(local_e_curve.g.x.a.d,param_gx192,24);
+	OS2IP(local_e_curve.g.y.a.d,param_gy192,24);
+
+	eap_status_e status = m_e_curve.set_copy_of_buffer(&local_e_curve, sizeof(local_e_curve));
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	{
+		struct nc_rand_state local_state;
+
+		m_am_tools->memset(&local_state, 0, sizeof(local_state));
+
+		int i;
+		byte ZIPSeed[16];
+		byte random[20];
+
+		status = m_am_tools->get_crypto()->get_rand_bytes(
+			random,
+			sizeof(random));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("random"),
+			random,
+			sizeof(random)));
+
+		for(i=0;i<16;i++)
+		{
+			ZIPSeed[i]=i;
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ZIPSeed"),
+			ZIPSeed,
+			sizeof(ZIPSeed)));
+
+		random_init(&local_state, ZIPSeed, random);
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("local_state"),
+			&local_state,
+			sizeof(local_state)));
+
+		status = m_nc_rand_state.set_copy_of_buffer(&local_state, sizeof(local_state));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+
+#else
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+
+#endif //#if defined(USE_NRC_ECC_ALGORITHMS)
+
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_am_algorithms_direct_nrc_c::create_ecdh_temporary_keys()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::create_ecdh_temporary_keys():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_am_algorithms_direct_nrc_c::create_ecdh_temporary_keys()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	eap_variable_data_c private_key_d(m_am_tools);
+	eap_variable_data_c public_key_x(m_am_tools);
+	eap_variable_data_c public_key_y(m_am_tools);
+
+	if (private_key_d.get_is_valid() == false
+		|| public_key_x.get_is_valid() == false
+		|| public_key_y.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+#if defined(USE_NRC_ECC_ALGORITHMS)
+	{
+		gfp_coord tmp_user_priv_key;
+		gfp_point tmp_user_public_key;
+
+		gfp_curve * const e_curve = reinterpret_cast<gfp_curve *>(m_e_curve.get_data(sizeof(gfp_curve)));
+		if (e_curve == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		struct nc_rand_state * const nc_rand_state = reinterpret_cast<struct nc_rand_state *>(m_nc_rand_state.get_data(sizeof(struct nc_rand_state)));
+		if (nc_rand_state == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		DRM_ECC_GenKeyPair_P256(nc_rand_state, tmp_user_priv_key.a.d, &tmp_user_public_key, e_curve);
+
+		if (tmp_user_priv_key.a.d[0] != 0u)
+		{
+			u32_t key_len = 2 * tmp_user_priv_key.a.d[0];
+
+			status = private_key_d.set_buffer_length(key_len);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = private_key_d.set_data_length(key_len);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			I2OSP(
+				private_key_d.get_data(key_len),
+				tmp_user_priv_key.a.d,
+				key_len);
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ECDH: private_key_d"),
+				 private_key_d.get_data(),
+				 private_key_d.get_data_length()));
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::create_ecdh_temporary_keys(): ECDH private key generation failed\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+
+		if (tmp_user_public_key.x.a.d[0] != 0u)
+		{
+			u32_t key_len = 2 * tmp_user_public_key.x.a.d[0];
+
+			status = public_key_x.set_buffer_length(key_len);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = public_key_x.set_data_length(key_len);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			I2OSP(
+				public_key_x.get_data(key_len),
+				tmp_user_public_key.x.a.d,
+				key_len);
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ECDH: public_key_x"),
+				 public_key_x.get_data(),
+				 public_key_x.get_data_length()));
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::create_ecdh_temporary_keys(): ECDH public key x generation failed\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+
+		if (tmp_user_public_key.y.a.d[0] != 0u)
+		{
+			u32_t key_len = 2 * tmp_user_public_key.y.a.d[0];
+
+			status = public_key_y.set_buffer_length(key_len);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = public_key_y.set_data_length(key_len);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			I2OSP(
+				public_key_y.get_data(key_len),
+				tmp_user_public_key.y.a.d,
+				key_len);
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ECDH: public_key_y"),
+				 public_key_y.get_data(),
+				 public_key_y.get_data_length()));
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::create_ecdh_temporary_keys(): ECDH public key y generation failed\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+	}
+
+#else
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+
+#endif //#if defined(USE_NRC_ECC_ALGORITHMS)
+
+	status = m_partner->complete_create_ecdh_temporary_keys(
+		&private_key_d,
+		&public_key_x,
+		&public_key_y);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_am_algorithms_direct_nrc_c::create_ecdh(
+	const eap_variable_data_c * const own_private_key_d,
+	const eap_variable_data_c * const peer_public_key_x,
+	const eap_variable_data_c * const peer_public_key_y)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::create_ecdh():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_am_algorithms_direct_nrc_c::create_ecdh()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	eap_variable_data_c K_AB_x4(m_am_tools);
+	eap_variable_data_c K_AB_y4(m_am_tools);
+
+	if (K_AB_x4.get_is_valid() == false
+		|| K_AB_y4.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+#if defined(USE_NRC_ECC_ALGORITHMS)
+	{
+		gfp_point K_AB;
+		gfp_point user_b_public;
+		gfp_coord private_key;
+
+		gfp_curve * const e_curve = reinterpret_cast<gfp_curve *>(m_e_curve.get_data());
+		if (e_curve == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ECDH: own_private_key_d"),
+			 own_private_key_d->get_data(),
+			 own_private_key_d->get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ECDH: peer_public_key_x"),
+			 peer_public_key_x->get_data(),
+			 peer_public_key_x->get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ECDH: peer_public_key_y"),
+			 peer_public_key_y->get_data(),
+			 peer_public_key_y->get_data_length()));
+
+		OS2IP(
+			private_key.a.d,
+			own_private_key_d->get_data(),
+			own_private_key_d->get_data_length());
+
+		OS2IP(
+			user_b_public.x.a.d,
+			peer_public_key_x->get_data(),
+			peer_public_key_x->get_data_length());
+
+		OS2IP(
+			user_b_public.y.a.d,
+			peer_public_key_y->get_data(),
+			peer_public_key_y->get_data_length());
+
+
+		gfp_ecc_dh(
+			&K_AB,
+			&user_b_public,
+			private_key.a.d,
+			e_curve);
+
+		if (K_AB.x.a.d[0] != 0u)
+		{
+			u32_t key_len = 2 * K_AB.x.a.d[0];
+
+			status = K_AB_x4.set_buffer_length(key_len);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = K_AB_x4.set_data_length(key_len);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			I2OSP(
+				K_AB_x4.get_data(key_len),
+				K_AB.x.a.d,
+				key_len);
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ECDH: K_AB_x4"),
+				 K_AB_x4.get_data(),
+				 K_AB_x4.get_data_length()));
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::create_ecdh(): ECDH shared key x generation failed\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+
+		if (K_AB.y.a.d[0] != 0u)
+		{
+			u32_t key_len = 2 * K_AB.y.a.d[0];
+
+			status = K_AB_y4.set_buffer_length(key_len);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = K_AB_y4.set_data_length(key_len);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			I2OSP(
+				K_AB_y4.get_data(key_len),
+				K_AB.y.a.d,
+				key_len);
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ECDH: K_AB_y4"),
+				 K_AB_y4.get_data(),
+				 K_AB_y4.get_data_length()));
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s: ec_am_algorithms_direct_nrc_c::create_ecdh(): ECDH shared key y generation failed\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+	}
+#endif //#if defined(USE_NRC_ECC_ALGORITHMS)
+
+	status = m_partner->complete_create_ecdh(
+		&K_AB_x4,
+		&K_AB_y4);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+		
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_am_base_algorithms_c * ec_am_base_algorithms_c::new_ec_base_algorithms_c(
+	abs_eap_am_tools_c * const tools,
+	abs_ec_am_algorithms_c * const partner,
+	const bool is_client_when_true)
+{
+	ec_am_base_algorithms_c * store = new ec_am_algorithms_direct_nrc_c(
+		tools,
+		partner,
+		is_client_when_true);
+
+	if (store == 0)
+	{
+		return 0;
+	}
+
+	eap_status_e status(store->configure());
+
+	if (status != eap_status_ok)
+	{
+		delete store;
+		return 0;
+	}
+
+	return store;
+}
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_am_base_algorithms.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,38 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_base_algorithms.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 4 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_am_base_algorithms.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_am_base_algorithms_c::~ec_am_base_algorithms_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_base_certificate_store.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,38 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_base_certificate_store.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 3 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_export.h"
+#include "eap_tools.h"
+#include "ec_base_certificate_store.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_base_certificate_store_c::~ec_base_certificate_store_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_certificate_store.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,7284 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_certificate_store.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 109 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 701 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_certificate_store.h"
+#include "ec_cs_types.h"
+#include "ec_cs_strings.h"
+#include "abs_ec_certificate_store.h"
+#include "abs_eap_am_file_input.h"
+#include "asn1_der_type.h"
+#include "ec_am_base_algorithms.h"
+#include "wapi_asn1_der_parser.h"
+#include "ec_am_base_certificate_store.h"
+#include "ec_cs_tlv.h"
+#include "ec_cs_tlv_payloads.h"
+#include "eap_protocol_layer.h"
+#include "eap_state_notification.h"
+#include "ec_cs_compare_certificate_id.h"
+#include "wapi_certificate_asn1_der_parser.h"
+#include "ec_cs_compare_certificate_issuer_name.h"
+#include "ec_cs_compare_certificate_reference.h"
+#include "ec_cs_compare_reference_id.h"
+#include "ec_cs_compare_reference.h"
+#include "ec_cs_compare_reference_issuer_name.h"
+#include "eap_tlv_message_data.h"
+#include "eap_crypto_api.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_certificate_store_c::~ec_certificate_store_c()
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::~ec_certificate_store_c():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::~ec_certificate_store_c()");
+
+	delete m_ec_algorithms;
+	m_ec_algorithms = 0;
+
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_certificate_store_c::ec_certificate_store_c(
+	abs_eap_am_tools_c * const tools,
+	abs_ec_certificate_store_c * const partner,
+	ec_am_base_certificate_store_c * const am_certificate_store,
+	const bool is_client_when_true)
+	: m_am_tools(tools)
+	, m_partner(partner)
+	, m_ec_algorithms(0)
+	, m_am_certificate_store(am_certificate_store)
+	, m_receive_network_id(tools)
+	, m_master_key_changed(false)
+	, m_PAC_store_master_key(tools)
+	, m_PAC_store_password(tools)
+	, m_PAC_store_device_seed(tools)
+	, m_completion_queue(tools)
+	, m_pending_operation(ec_cs_pending_operation_none)
+	, m_queried_issuer_ID(tools)
+	, m_imported_certificate_wapi_id(tools)
+	, m_imported_certificate_file_data(tools)
+	, m_imported_certificate_filename(tools)
+	, m_imported_certificate_data(tools)
+	, m_imported_private_key_data(tools)
+	, m_ec_cs_completion_status(eap_status_process_general_error)
+	, m_ae_certificate(tools)
+
+	, m_selected_ca_id(tools)
+	, m_selected_client_id(tools)
+
+	, m_broken_cs_data_list(tools)
+	, m_ca_asu_id_list(tools)
+	, m_read_ca_asu_id_list(false)
+	, m_client_asu_id_list(tools)
+	, m_read_client_asu_id_list(false)
+	, m_ca_certificates(tools)
+	, m_client_certificates(tools)
+	, m_client_private_keys(tools)
+
+	, m_peer_identity(tools)
+	, m_signature(tools)
+
+	, m_hash_of_message(tools)
+	, m_id_of_own_certificate(tools)
+
+	, m_dummy_test_asu_certificate(tools)
+	, m_dummy_test_asu_private_key(tools)
+	, m_dummy_test_peer_certificate(tools)
+	, m_dummy_test_own_certificate(tools)
+	, m_dummy_test_own_private_key(tools)
+
+	, m_is_client(is_client_when_true)
+	, m_is_valid(false)
+	, m_shutdown_was_called(false)
+	, m_reference_counter_read(false)
+	, m_reference_counter_changed(false)
+	, m_reference_counter(0ul)
+	, m_PAC_store_key_timeout_ms(EAP_FAST_PAC_STORE_DEFAULT_KEY_CACHE_TIMEOUT)
+	, m_already_in_completion_action_check(false)
+	, m_pending_read_ec_cs_data(false)
+	, m_complete_start_certificate_import(false)
+	, m_certificate_store_initialized(false)
+	, m_allow_use_of_ae_certificate(false)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::ec_certificate_store_c():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::ec_certificate_store_c()");
+
+	if (partner == 0
+		|| am_certificate_store == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		return;
+	}
+
+	m_ec_algorithms = ec_am_base_algorithms_c::new_ec_base_algorithms_c(
+		tools,
+		this,
+		is_client_when_true);
+	if (m_ec_algorithms == 0
+		|| m_ec_algorithms->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return;
+	}
+
+	am_certificate_store->set_am_certificate_store_partner(this);
+
+	m_is_valid = true;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_certificate_store_c::get_is_valid() const
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::read_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = m_partner->read_configure(field, data);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+#if defined(USE_WAPI_CORE_SERVER) || !defined(WAPI_USE_CERTIFICATE_STORE)
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::read_test_certificate(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_test_certificate():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_test_certificate()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	{
+		eap_variable_data_c name(m_am_tools);
+		if (name.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = m_partner->read_configure(
+			field,
+			&name);
+		if (status == eap_status_ok
+			&& name.get_is_valid_data() == true)
+		{
+			// OK test certificate configured.
+
+			abs_eap_am_file_input_c * const file_input = abs_eap_am_file_input_c::new_abs_eap_am_file_input_c(m_am_tools);
+
+			eap_automatic_variable_c<abs_eap_am_file_input_c> automatic_file_input(m_am_tools, file_input);
+
+			if (file_input == 0
+				|| file_input->get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = file_input->file_open(&name, eap_file_io_direction_read);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			u32_t file_size = file_input->file_size();
+
+			status = data->set_buffer_length(file_size);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = file_input->file_read(data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		else
+		{
+			// Here we ignore missing configuration data.
+			status = eap_status_ok;
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+#endif //#if defined(USE_WAPI_CORE_SERVER) || !defined(WAPI_USE_CERTIFICATE_STORE)
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::configure()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::configure():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::configure()");
+
+	eap_status_e status(eap_status_not_supported);
+
+
+	{
+		eap_variable_data_c EAP_FAST_PAC_store_key_timeout_ms(m_am_tools);
+
+		eap_status_e status = m_partner->read_configure(
+			cf_str_EAP_FAST_PAC_store_key_timeout_ms.get_field(),
+			&EAP_FAST_PAC_store_key_timeout_ms);
+		if (status == eap_status_ok
+			&& EAP_FAST_PAC_store_key_timeout_ms.get_is_valid_data() == true)
+		{
+			u32_t *timeout_ms = reinterpret_cast<u32_t *>(
+				EAP_FAST_PAC_store_key_timeout_ms.get_data(sizeof(u32_t)));
+			if (timeout_ms != 0)
+			{
+				m_PAC_store_key_timeout_ms = *timeout_ms;
+			}
+		}
+	}
+
+
+	{
+		// Read CS store password from memory store if such exists.
+		eap_variable_data_c key(m_am_tools);
+
+		status = key.set_copy_of_buffer(
+			WAPI_CS_MEMORY_STORE_KEY,
+			sizeof(WAPI_CS_MEMORY_STORE_KEY));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		eap_tlv_message_data_c tlv_data(m_am_tools);
+
+		status = m_am_tools->memory_store_get_data(
+			&key,
+			&tlv_data);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ec_certificate_store_c::configure(): cannot get credentials\n")));
+
+			// Ignore the error.
+			status = eap_status_ok;
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ec_certificate_store_c::configure(): credentials found\n")));
+
+			// Parse read data.
+			eap_array_c<eap_tlv_header_c> tlv_blocks(m_am_tools);
+				
+			status = tlv_data.parse_message_data(&tlv_blocks);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			for (u32_t ind = 0ul; ind < tlv_blocks.get_object_count(); ind++)
+			{
+				eap_tlv_header_c * const tlv = tlv_blocks.get_object(ind);
+				if (tlv != 0)
+				{
+					if (tlv->get_type() == ec_cs_data_type_password)
+					{
+						status = m_PAC_store_password.set_copy_of_buffer(
+							tlv->get_value(tlv->get_value_length()),
+							tlv->get_value_length());
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						EAP_TRACE_DATA_DEBUG(
+							m_am_tools,
+							TRACE_FLAGS_DEFAULT,
+							(EAPL("CS store password"),
+							 m_PAC_store_password.get_data(),
+							 m_PAC_store_password.get_data_length()));
+					}
+					else if (tlv->get_type() == ec_cs_data_type_device_seed)
+					{
+						status = m_PAC_store_device_seed.set_copy_of_buffer(
+							tlv->get_value(tlv->get_value_length()),
+							tlv->get_value_length());
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						EAP_TRACE_DATA_DEBUG(
+							m_am_tools,
+							TRACE_FLAGS_DEFAULT,
+							(EAPL("CS store device seed"),
+							 m_PAC_store_device_seed.get_data(),
+							 m_PAC_store_device_seed.get_data_length()));
+					}
+					else if (tlv->get_type() == ec_cs_data_type_master_key)
+					{
+						status = m_PAC_store_master_key.set_copy_of_buffer(
+							tlv->get_value(tlv->get_value_length()),
+							tlv->get_value_length());
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						EAP_TRACE_DATA_DEBUG(
+							m_am_tools,
+							TRACE_FLAGS_DEFAULT,
+							(EAPL("CS store master key"),
+							 m_PAC_store_master_key.get_data(),
+							 m_PAC_store_master_key.get_data_length()));
+					}
+					else if (tlv->get_type() == ec_cs_data_type_reference_counter)
+					{
+						u32_t * data = reinterpret_cast<u32_t *>(tlv->get_value(sizeof(m_reference_counter)));
+						if (data != 0)
+						{
+							m_reference_counter = eap_read_u32_t_network_order(
+								data,
+								sizeof(m_reference_counter));
+						}
+					}
+					else
+					{
+						EAP_TRACE_DEBUG(
+							m_am_tools,
+							TRACE_FLAGS_DEFAULT,
+							(EAPL("ec_certificate_store_c::configure(): unknown credential type %d, length %d\n"),
+							 tlv->get_type(),
+							 tlv->get_value_length()));
+					}
+				}
+			} // for()
+
+			status = m_am_tools->memory_store_remove_data(&key);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ec_certificate_store_c::configure(): credentials removed from eapol\n")));
+		}
+	}
+
+
+#if !defined(WAPI_USE_CERTIFICATE_STORE)
+	if (m_is_client == true)
+	{
+		status = read_test_certificate(
+			cf_str_WAPI_ASU_certificate_file.get_field(),
+			&m_dummy_test_asu_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = read_test_certificate(
+			cf_str_WAPI_ASUE_certificate_file.get_field(),
+			&m_dummy_test_own_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = read_test_certificate(
+			cf_str_WAPI_ASUE_private_key_file.get_field(),
+			&m_dummy_test_own_private_key);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = read_test_certificate(
+			cf_str_WAPI_AE_certificate_file.get_field(),
+			&m_dummy_test_peer_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+#endif //#if !defined(WAPI_USE_CERTIFICATE_STORE)
+#if defined(USE_WAPI_CORE_SERVER)
+
+	if (m_is_client == false)
+	{
+		status = read_test_certificate(
+			cf_str_WAPI_ASU_certificate_file.get_field(),
+			&m_dummy_test_asu_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = read_test_certificate(
+			cf_str_WAPI_AE_certificate_file.get_field(),
+			&m_dummy_test_own_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = read_test_certificate(
+			cf_str_WAPI_AE_private_key_file.get_field(),
+			&m_dummy_test_own_private_key);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = read_test_certificate(
+			cf_str_WAPI_ASU_private_key_file.get_field(),
+			&m_dummy_test_asu_private_key);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = read_test_certificate(
+			cf_str_WAPI_ASUE_certificate_file.get_field(),
+			&m_dummy_test_peer_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+	{
+		status = eap_status_ok;
+	}
+
+	{
+		// Adds timer to delete CS store Key from member variable.
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ec_certificate_store_c::configure(): am_set_timer(): WAPI_CS_KEY_TIMER_ID\n")));
+
+		status = m_am_tools->am_set_timer(
+			this,
+			WAPI_CS_KEY_TIMER_ID,
+			0,
+			m_PAC_store_key_timeout_ms);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//------------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::cancel_operations()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: ec_certificate_store_c::cancel_operations()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::cancel_operations()");
+
+	eap_status_e status(eap_status_ok);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = m_am_certificate_store->cancel_certificate_store_store_operations();
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+
+//--------------------------------------------------
+
+eap_status_e ec_certificate_store_c::save_data_to_permanent_store()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s, ec_certificate_store_c::save_data_to_permanent_store()\n"),
+		this,
+		(m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::save_data_to_permanent_store()");
+
+	eap_status_e status(eap_status_ok);
+
+	if (m_is_client == true)
+	{
+		if (m_certificate_store_initialized == true)
+		{
+			// Save all data to permanent store.
+
+			eap_array_c<ec_cs_data_c> data_references(m_am_tools);
+
+			if (m_reference_counter_changed == true)
+			{
+				/*
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+				 * | Type=Referene counter TLV     |           Length=4            |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+				 * |                    reference counter (4 octets)               |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+				 * | Type=CS-MAC TLV               |           Length=32           |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+				 * |                              MAC (32 octets)                  |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+				 */
+
+				ec_cs_data_c * const refence_counter = new ec_cs_data_c(m_am_tools);
+
+				eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, refence_counter);
+
+				if (refence_counter == 0
+					|| refence_counter->get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("Wrote reference counter = 0x%08x\n"),
+					 m_reference_counter));
+
+				refence_counter->set_type(ec_cs_data_type_reference_counter);
+
+				status = refence_counter->get_writable_reference()->set_copy_of_buffer(
+					EC_CS_ZERO_REFERENCE,
+					sizeof(EC_CS_ZERO_REFERENCE));
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				eap_variable_data_c reference_counter_MAC_key(m_am_tools);
+				if (reference_counter_MAC_key.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				ec_cs_tlv_c pac_tlv_handler(m_am_tools, true);
+				if (pac_tlv_handler.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				status = pac_tlv_handler.generate_data_key(
+					false,
+					ec_cs_data_type_reference_counter,
+					&reference_counter_MAC_key,
+					&m_PAC_store_master_key,
+					refence_counter->get_reference(),
+					&m_PAC_store_device_seed);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				ec_cs_variable_data_c reference_counter_tlv(m_am_tools);
+				if (reference_counter_tlv.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				status = pac_tlv_handler.create_u32_t_tlv(
+					&reference_counter_tlv,
+					ec_cs_tlv_type_CS_reference_counter,
+					m_reference_counter);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = pac_tlv_handler.create_data_with_MAC(
+					&reference_counter_MAC_key,
+					reference_counter_tlv.get_full_tlv_buffer(),
+					refence_counter->get_writable_data());
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("New reference counter data"),
+					 refence_counter->get_data()->get_data(),
+					 refence_counter->get_data()->get_data_length()));
+
+				refence_counter->set_change_status(ec_cs_data_change_status_new);
+
+				status = data_references.add_object(refence_counter->copy(), true);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+			}
+
+			if (m_master_key_changed == true)
+			{
+				// Create encrypted Master key data block.
+				// NOTE this is the only data encrypted with CS store password.
+
+				/*
+				 * Master key data
+				 *
+ 				 * 0                   1                   2                   3   
+				 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    -+ -+
+				 * | Type=CS-Encrypted block TLV   |     Length=4+16+4+n+4+m       |     |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
+				 * | Type=CS-Encryption IV TLV     |           Length=16           |  |  |  | plain text
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  |
+				 * |                              IV (16 octets)                   |  |  |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
+				 * | Type=CS-Encrypted data TLV    |           Length=n+4+m        |  |  |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  | -+
+				 * |                          Master key TLV (n octets)            |  |  |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | encrypted
+				 * | Type=CS-padding TLV           |           Length=m            |  |  |  | multiple of
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | 16 octets
+				 * |                           padding (m octets)                  |  |  |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ -+ -+
+				 * | Type=CS-MAC TLV               |           Length=32           |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+				 * |                              MAC (32 octets)                  |  |
+				 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+				 */
+
+				ec_cs_data_c * const master_key = new ec_cs_data_c(m_am_tools);
+
+				eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, master_key);
+
+				if (master_key == 0
+					|| master_key->get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				master_key->set_type(ec_cs_data_type_master_key);
+
+				status = master_key->get_writable_reference()->set_copy_of_buffer(
+					EC_CS_ZERO_REFERENCE,
+					sizeof(EC_CS_ZERO_REFERENCE));
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				ec_cs_tlv_c pac_tlv_handler(m_am_tools, true);
+				if (pac_tlv_handler.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				status = pac_tlv_handler.create_master_key_data(
+					&m_PAC_store_password,
+					&m_PAC_store_device_seed,
+					&m_PAC_store_master_key,
+					master_key->get_reference(),
+					master_key->get_writable_data());
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				master_key->set_change_status(ec_cs_data_change_status_new);
+
+				status = data_references.add_object(master_key->copy(), true);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+			status = copy<ec_cs_data_c>(
+				&m_ca_certificates,
+				&data_references,
+				m_am_tools,
+				true);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = copy<ec_cs_data_c>(
+				&m_client_certificates,
+				&data_references,
+				m_am_tools,
+				true);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = copy<ec_cs_data_c>(
+				&m_client_private_keys,
+				&data_references,
+				m_am_tools,
+				true);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+			status = add_asu_id_list(
+				&m_ca_asu_id_list,
+				&data_references);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = add_asu_id_list(
+				&m_client_asu_id_list,
+				&data_references);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+			status = copy<ec_cs_data_c>(
+				&m_broken_cs_data_list,
+				&data_references,
+				m_am_tools,
+				true);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+				(EAPL("calls: ec_certificate_store_c::save_data_to_permanent_store(): m_am_pac_store_services->write_PAC_store_data(): %d.\n"),
+				__LINE__));
+
+			status = m_am_certificate_store->write_certificate_store_data(
+				true,
+				ec_cs_pending_operation_none,
+				&data_references);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s, ec_certificate_store_c::save_data_to_permanent_store(): Certificate store NOT initialized. Do not save data.\n"),
+				this,
+				(m_is_client == true ? "client": "server")));
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::shutdown()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s, ec_certificate_store_c::shutdown()\n"),
+		this,
+		(m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::shutdown()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (m_shutdown_was_called == true)
+	{
+		// Shutdown function was called already.
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	m_shutdown_was_called = true;
+
+	(void) m_am_tools->am_cancel_timer(
+			this,
+			WAPI_CS_KEY_TIMER_ID);
+
+	(void) cancel_operations();
+
+	(void) save_data_to_permanent_store();
+
+	(void) completion_action_clenup();
+
+	{
+		// Save the CS store password.
+		eap_variable_data_c key(m_am_tools);
+
+		status = key.set_copy_of_buffer(
+			WAPI_CS_MEMORY_STORE_KEY,
+			sizeof(WAPI_CS_MEMORY_STORE_KEY));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		(void) m_am_tools->memory_store_remove_data(&key);
+
+		eap_tlv_message_data_c tlv_data(m_am_tools);
+
+		if (m_PAC_store_password.get_is_valid_data() == true)
+		{
+			status = tlv_data.add_message_data(
+				ec_cs_data_type_password,
+				m_PAC_store_password.get_data_length(),
+				m_PAC_store_password.get_data());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		if (m_PAC_store_device_seed.get_is_valid_data() == true)
+		{
+			status = tlv_data.add_message_data(
+				ec_cs_data_type_device_seed,
+				m_PAC_store_device_seed.get_data_length(),
+				m_PAC_store_device_seed.get_data());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		if (m_PAC_store_master_key.get_is_valid_data() == true)
+		{
+			status = tlv_data.add_message_data(
+				ec_cs_data_type_master_key,
+				m_PAC_store_master_key.get_data_length(),
+				m_PAC_store_master_key.get_data());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		{
+			u32_t network_order_reference_counter = eap_htonl(m_reference_counter);
+
+			status = tlv_data.add_message_data(
+				ec_cs_data_type_reference_counter,
+				sizeof(network_order_reference_counter),
+				&network_order_reference_counter);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		status = m_am_tools->memory_store_add_data(
+			&key,
+			&tlv_data,
+			m_PAC_store_key_timeout_ms);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ec_certificate_store_c::shutdown(): cannot store credentials\n")));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e ec_certificate_store_c::add_asu_id_list(
+	EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const asu_id_list,
+	eap_array_c<ec_cs_data_c> * const data_references)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: ec_certificate_store_c::add_asu_id_list()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::add_asu_id_list()");
+
+	eap_status_e status(eap_status_ok);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	for (u32_t index = 0ul; index < asu_id_list->get_object_count(); ++index)
+	{
+		const ec_cs_data_c * const data = asu_id_list->get_object(index);
+		if (data != 0)
+		{
+			ec_cs_data_c * const new_ec_cd_data = data->copy();
+			if (new_ec_cd_data != 0)
+			{
+				status = data_references->add_object(new_ec_cd_data, true);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+	
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e ec_certificate_store_c::create_unique_reference(
+	ec_cs_data_c * const out_reference)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: ec_certificate_store_c::create_unique_reference()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::create_unique_reference()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	++m_reference_counter;
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("Increased reference counter = 0x%08x\n"),
+		 m_reference_counter));
+
+	m_reference_counter_changed = true;
+
+	u32_t network_order_counter = eap_htonl(m_reference_counter);
+
+	status = out_reference->get_writable_reference()->set_copy_of_buffer(
+		&network_order_counter,
+		sizeof(network_order_counter));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::initialize_certificate_store()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::initialize_certificate_store():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::initialize_certificate_store()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	status = m_am_certificate_store->initialize_certificate_store(wapi_completion_operation_continue_certificate_authentication);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::query_asu_id()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::query_asu_id():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::query_asu_id()");
+
+	eap_variable_data_c asn1_der_subject_name(m_am_tools);
+	eap_variable_data_c asn1_der_issuer_name(m_am_tools);
+	eap_variable_data_c asn1_der_sequence_number(m_am_tools);
+
+	wapi_certificate_asn1_der_parser_c parser(m_am_tools);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status(eap_status_ok);
+
+	if (m_selected_ca_id.get_is_valid_data() == true)
+	{
+		wapi_asn1_der_parser_c asn1_der_parser(m_am_tools);
+		if (asn1_der_parser.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = asn1_der_parser.decode(&m_selected_ca_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = asn1_der_parser.get_wapi_identity(
+			&asn1_der_subject_name,
+			&asn1_der_issuer_name,
+			&asn1_der_sequence_number);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		status = parser.decode(&m_dummy_test_asu_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = parser.read_certificate_id(
+			&asn1_der_subject_name,
+			&asn1_der_issuer_name,
+			&asn1_der_sequence_number);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	status = m_partner->complete_query_asu_id(
+		&asn1_der_subject_name,
+		&asn1_der_issuer_name,
+		&asn1_der_sequence_number,
+		status);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::compare_id_and_certificate(
+	const eap_variable_data_c * const ID,
+	const eap_variable_data_c * const certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::compare_id_and_certificate():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::compare_id_and_certificate()");
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wapi_certificate_asn1_der_parser_c parser(m_am_tools);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = parser.decode(certificate);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	eap_variable_data_c certificate_id(m_am_tools);
+	if (certificate_id.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = parser.read_certificate_id(
+		&certificate_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (certificate_id.compare(ID) == 0)
+	{
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("OK: compare_id_and_certificate(): match certificate_id"),
+			certificate_id.get_data(),
+			certificate_id.get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("OK: compare_id_and_certificate(): match ID"),
+			ID->get_data(),
+			ID->get_data_length()));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	else
+	{
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("INFO: compare_id_and_certificate(): mismatch certificate_id"),
+			certificate_id.get_data(),
+			certificate_id.get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("INFO: compare_id_and_certificate(): mismatch ID"),
+			ID->get_data(),
+			ID->get_data_length()));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_match);
+	}
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::compare_issuer_name_of_id_and_certificate(
+	const eap_variable_data_c * const issuer_ID,
+	const eap_variable_data_c * const certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::compare_issuer_name_of_id_and_certificate():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::compare_issuer_name_of_id_and_certificate()");
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c issuer_ID_subject_name(m_am_tools);
+	eap_variable_data_c issuer_ID_issuer_name(m_am_tools);
+	eap_variable_data_c issuer_ID_sequence_number(m_am_tools);
+
+	wapi_asn1_der_parser_c asn1_der_parser(m_am_tools);
+	if (asn1_der_parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = asn1_der_parser.decode(issuer_ID);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = asn1_der_parser.get_wapi_identity(
+		&issuer_ID_subject_name,
+		&issuer_ID_issuer_name,
+		&issuer_ID_sequence_number);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c certificate_subject_name(m_am_tools);
+	eap_variable_data_c certificate_issuer_name(m_am_tools);
+	eap_variable_data_c certificate_sequence_number(m_am_tools);
+
+	wapi_certificate_asn1_der_parser_c parser(m_am_tools);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = parser.decode(certificate);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = parser.read_certificate_id(
+		&certificate_subject_name,
+		&certificate_issuer_name,
+		&certificate_sequence_number);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (certificate_issuer_name.compare(&issuer_ID_issuer_name) == 0)
+	{
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("OK: compare_issuer_name_of_id_and_certificate(): match certificate_issuer_name"),
+			certificate_issuer_name.get_data(),
+			certificate_issuer_name.get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("OK: compare_issuer_name_of_id_and_certificate(): match issuer_ID_issuer_name"),
+			issuer_ID_issuer_name.get_data(),
+			issuer_ID_issuer_name.get_data_length()));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	else
+	{
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("INFO: compare_issuer_name_of_id_and_certificate(): mismatch certificate_issuer_name"),
+			certificate_issuer_name.get_data(),
+			certificate_issuer_name.get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("INFO: compare_issuer_name_of_id_and_certificate(): mismatch issuer_ID_issuer_name"),
+			issuer_ID_issuer_name.get_data(),
+			issuer_ID_issuer_name.get_data_length()));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_no_match);
+	}
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::compare_issuer_common_name_and_certificate(
+	const eap_variable_data_c * const certificate,
+	const eap_variable_data_c * const subject_common_name)
+{
+	eap_variable_data_c certificate_subject_name(m_am_tools);
+	eap_variable_data_c certificate_issuer_name(m_am_tools);
+	eap_variable_data_c certificate_sequence_number(m_am_tools);
+
+	wapi_certificate_asn1_der_parser_c parser(m_am_tools);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = parser.decode(certificate);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = parser.read_certificate_id(
+		&certificate_subject_name,
+		&certificate_issuer_name,
+		&certificate_sequence_number);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	wapi_asn1_der_parser_c parse_subject_name(m_am_tools);
+	if (parse_subject_name.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_variable_data_c subject_name(m_am_tools);
+
+	status = parse_subject_name.get_decoded_subject_name(
+		&certificate_subject_name,
+		&subject_name);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (subject_common_name->compare(&subject_name) == 0)
+	{
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("OK: compare_issuer_common_name_and_certificate(): match subject_common_name"),
+			subject_common_name->get_data(),
+			subject_common_name->get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("OK: compare_issuer_common_name_and_certificate(): match subject_name"),
+			subject_name.get_data(),
+			subject_name.get_data_length()));
+	}
+	else
+	{
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("INFO: compare_issuer_common_name_and_certificate(): mismatch subject_common_name"),
+			subject_common_name->get_data(),
+			subject_common_name->get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("INFO: compare_issuer_common_name_and_certificate(): mismatch subject_name"),
+			subject_name.get_data(),
+			subject_name.get_data_length()));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_user_certificate_unknown);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::get_own_certificate()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::get_own_certificate():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::get_own_certificate()");
+
+	eap_status_e status = m_partner->complete_get_own_certificate(&m_dummy_test_own_certificate);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::set_ae_certificate(
+	const eap_variable_data_c * const ae_certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::set_ae_certificate():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::set_ae_certificate()");
+
+	eap_status_e status = m_ae_certificate.set_copy_of_buffer(ae_certificate);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::select_certificate(
+	const eap_variable_data_c * const issuer_ID)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::select_certificate():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::select_certificate()");
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("issuer_ID"),
+		 issuer_ID->get_data(),
+		 issuer_ID->get_data_length()));
+
+	if (m_pending_operation != ec_cs_pending_operation_none)
+	{
+		// Some operation is already pending. Try again later.
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_device_busy);
+	}
+
+#if defined(WAPI_USE_CERTIFICATE_STORE)
+
+	eap_status_e status = m_queried_issuer_ID.set_copy_of_buffer(issuer_ID);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = completion_action_push(ec_cs_completion_internal_select_certificate);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = completion_action_push(ec_cs_completion_internal_select_certificate_with_identity);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = completion_action_push(ec_cs_completion_query_PAC_store_password);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = initialize_certificate_store();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = completion_action_check();
+
+#else
+
+	(void) EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+
+	eap_variable_data_c * selected_certificate = 0;
+
+	eap_variable_data_c certificate_id(m_am_tools);
+	if (certificate_id.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = compare_issuer_name_of_id_and_certificate(issuer_ID, &m_dummy_test_own_certificate);
+	if (status == eap_status_ok)
+	{
+		selected_certificate = &m_dummy_test_own_certificate;
+
+		wapi_certificate_asn1_der_parser_c parser(m_am_tools);
+		if (parser.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_status_e status = parser.decode(&m_dummy_test_asu_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = parser.read_certificate_id(
+			&certificate_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	status = m_partner->complete_select_certificate(
+		issuer_ID,
+		&certificate_id,
+		selected_certificate);
+
+#endif
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::internal_select_certificate_with_identity(
+	const eap_variable_data_c * const user_certificate_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate_with_identity():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::internal_select_certificate_with_identity()");
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("user_certificate_id"),
+		 user_certificate_id->get_data(),
+		 user_certificate_id->get_data_length()));
+
+	ec_cs_data_c search_id(m_am_tools);
+
+	eap_status_e status = search_id.get_writable_data()->set_buffer(
+		user_certificate_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	eap_variable_data_c certificate_reference(m_am_tools);
+
+	ec_cs_data_type_e certificate_type(ec_cs_data_type_none);
+
+	const ec_cs_data_c * reference_tlv = 0;
+
+	if (reference_tlv == 0
+		&& m_read_client_asu_id_list == true)
+	{
+		// Search client certificate that is selected by UI.
+
+		ec_cs_compare_reference_id_c compare_certificate_id(m_am_tools);
+
+		ec_cs_data_c search_user_certificate_id(m_am_tools);
+
+		status = search_user_certificate_id.get_writable_data()->set_buffer(
+			user_certificate_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate_with_identity(): count of m_client_asu_id_list = %d.\n"),
+			 this,
+			 (m_is_client == true ? "client": "server"),
+			 m_client_asu_id_list.get_object_count()));
+
+		// Search Certificate-reference with the issuer ID.
+		i32_t index = find_with_compare<ec_cs_data_c>(
+			&compare_certificate_id,
+			&m_client_asu_id_list,
+			&search_user_certificate_id,
+			m_am_tools);
+		if (index >= 0)
+		{
+			// Match.
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate_with_identity(): Certificate match.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			reference_tlv = m_client_asu_id_list.get_object(index);
+			certificate_type = ec_cs_data_type_client_certificate_data;
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate_with_identity(): No certificate match.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+		}
+	}
+
+
+	if (reference_tlv != 0)
+	{
+		status = read_certificate_reference(reference_tlv, &certificate_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// Read the certificate from database.
+		status = read_certificate(
+			ec_cs_pending_operation_select_client_certificate,
+			certificate_type,
+			&certificate_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::internal_select_own_certificate_with_issuer_name()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::internal_select_own_certificate_with_issuer_name():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::internal_select_own_certificate_with_issuer_name()");
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("m_id_of_own_certificate"),
+		 m_id_of_own_certificate.get_data(),
+		 m_id_of_own_certificate.get_data_length()));
+
+	eap_status_e status(eap_status_process_general_error);
+
+	ec_cs_data_c search_id(m_am_tools);
+
+	{
+		wapi_asn1_der_parser_c parser(m_am_tools);
+		if (parser.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = parser.decode(&m_id_of_own_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		eap_variable_data_c subject_name(m_am_tools);
+		eap_variable_data_c issuer_name(m_am_tools);
+		eap_variable_data_c sequence_number(m_am_tools);
+
+		status = parser.get_wapi_identity(
+			&subject_name,
+			&issuer_name,
+			&sequence_number);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = search_id.get_writable_data()->set_copy_of_buffer(
+			&issuer_name);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	eap_variable_data_c certificate_reference(m_am_tools);
+
+	ec_cs_compare_reference_issuer_name_c compare_reference_issuer_name(m_am_tools);
+
+	ec_cs_data_type_e certificate_type(ec_cs_data_type_none);
+
+	const ec_cs_data_c * reference_tlv = 0;
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_own_certificate_with_issuer_name(): count of m_client_asu_id_list = %d.\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 m_client_asu_id_list.get_object_count()));
+
+	if (reference_tlv == 0
+		&& m_read_client_asu_id_list == true)
+	{
+		// Search Certificate-reference with the issuer ID.
+		i32_t index = find_with_compare<ec_cs_data_c>(
+			&compare_reference_issuer_name,
+			&m_client_asu_id_list,
+			&search_id,
+			m_am_tools);
+		if (index >= 0)
+		{
+			// Match.
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_own_certificate_with_issuer_name(): Certificate match.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			reference_tlv = m_client_asu_id_list.get_object(index);
+			certificate_type = ec_cs_data_type_client_certificate_data;
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_own_certificate_with_issuer_name(): No certificate match.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+		}
+	}
+
+
+	if (reference_tlv != 0)
+	{
+		status = read_certificate_reference(reference_tlv, &certificate_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// Read the certificate from database.
+		status = read_certificate(
+			ec_cs_pending_operation_select_client_certificate,
+			certificate_type,
+			&certificate_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::internal_select_certificate()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::internal_select_certificate()");
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("m_queried_issuer_ID"),
+		 m_queried_issuer_ID.get_data(),
+		 m_queried_issuer_ID.get_data_length()));
+
+	if (m_pending_operation != ec_cs_pending_operation_none)
+	{
+		// Some operation is already pending. Try again later.
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_device_busy);
+	}
+
+	eap_status_e status(eap_status_not_supported);
+
+	ec_cs_compare_certificate_id_c compare_certificate_id(
+		m_am_tools,
+		&m_PAC_store_master_key,
+		&m_PAC_store_device_seed);
+
+	const ec_cs_data_c * match_certificate_data = 0;
+
+	ec_cs_data_c search_id(m_am_tools);
+
+	status = search_id.get_writable_data()->set_buffer(
+		&m_queried_issuer_ID);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	i32_t index(-1);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): count of m_ca_certificates = %d.\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 m_ca_certificates.get_object_count()));
+
+	if (m_is_client == false)
+	{
+		// Search certificate with the issuer ID from CA-certificates.
+		index = find_with_compare<ec_cs_data_c>(
+			&compare_certificate_id,
+			&m_ca_certificates,
+			&search_id,
+			m_am_tools);
+	}
+
+	if (index >= 0)
+	{
+		// Match.
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): CA certificate match.\n"),
+			 this,
+			 (m_is_client == true ? "client": "server")));
+
+		match_certificate_data = m_ca_certificates.get_object(index);
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): No CA certificate match.\n"),
+			 this,
+			 (m_is_client == true ? "client": "server")));
+
+		eap_variable_data_c issuer_name(m_am_tools);
+
+		{
+			wapi_asn1_der_parser_c parser(m_am_tools);
+			if (parser.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_status_e status = parser.decode(&m_queried_issuer_ID);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			eap_variable_data_c subject_name(m_am_tools);
+			eap_variable_data_c sequence_number(m_am_tools);
+
+			status = parser.get_wapi_identity(
+				&subject_name,
+				&issuer_name,
+				&sequence_number);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		ec_cs_compare_certificate_id_c compare_certificate_id(
+			m_am_tools,
+			&m_PAC_store_master_key,
+			&m_PAC_store_device_seed);
+
+		ec_cs_data_c search_certificate_id(m_am_tools);
+
+		status = search_certificate_id.get_writable_data()->set_buffer(
+			&m_selected_client_id);
+
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): count of m_client_certificates = %d.\n"),
+			 this,
+			 (m_is_client == true ? "client": "server"),
+			 m_client_certificates.get_object_count()));
+
+		// Search certificate with the issuer ID from client certificates.
+		index = find_with_compare<ec_cs_data_c>(
+			&compare_certificate_id,
+			&m_client_certificates,
+			&search_certificate_id,
+			m_am_tools);
+		if (index >= 0)
+		{
+			// Match.
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): Client certificate match.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			match_certificate_data = m_client_certificates.get_object(index);
+		}
+		else if (m_read_ca_asu_id_list == true
+				 && m_read_client_asu_id_list == true)
+		{
+			// Both certificate lists are already read, cannot continue.
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_select_certificate(): No client certificate match.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			(void) m_partner->set_session_timeout(0ul);
+
+			if (m_is_client == false)
+			{
+				status = eap_status_ca_certificate_unknown;
+			}
+			else
+			{
+				status = eap_status_user_certificate_unknown;
+			}
+
+			(void) send_error_notification(status);
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_no_match);
+		}
+		else
+		{
+			status = completion_action_push(ec_cs_completion_internal_select_certificate);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = completion_action_push(ec_cs_completion_internal_select_certificate_with_identity);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			// This function call must be asyncronous.
+			status = read_both_certificate_lists(ec_cs_pending_operation_select_client_certificate);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	const eap_variable_data_c * certificate_data = 0;
+
+	eap_variable_data_c certificate_data_buffer(m_am_tools);
+	eap_variable_data_c certificate_ID(m_am_tools);
+
+	if (certificate_data_buffer.get_is_valid() == false
+		|| certificate_ID.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	if (match_certificate_data != 0)
+	{
+		ec_cs_tlv_c handler(m_am_tools, true);
+		if (handler.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_variable_data_c certificate_reference(m_am_tools);
+		if (certificate_reference.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = handler.parse_encrypted_certificate(
+			match_certificate_data->get_type(),
+			&m_PAC_store_master_key,
+			match_certificate_data->get_reference(),
+			&m_PAC_store_device_seed,
+			match_certificate_data->get_data(),
+			&certificate_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		const ec_cs_variable_data_c * const certificate_data_tlv = handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_certificate_data);
+		if (certificate_data_tlv == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		status = certificate_data_buffer.set_copy_of_buffer(
+			certificate_data_tlv->get_data(certificate_data_tlv->get_data_length()),
+			certificate_data_tlv->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		certificate_data = &certificate_data_buffer;
+
+		// Read the certificate ID.
+		{
+			wapi_certificate_asn1_der_parser_c parser(m_am_tools);
+			if (parser.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_status_e status = parser.decode(certificate_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = parser.read_certificate_id(
+				&certificate_ID);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	status = m_partner->complete_select_certificate(
+		&m_queried_issuer_ID,
+		&certificate_ID,
+		certificate_data);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::internal_create_signature_with_private_key()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::internal_create_signature_with_private_key()");
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("m_id_of_own_certificate"),
+		m_id_of_own_certificate.get_data(),
+		m_id_of_own_certificate.get_data_length()));
+
+	const ec_cs_data_c * selected_private_key = 0;
+	const eap_variable_data_c * selected_private_key_data = 0;
+
+	eap_variable_data_c private_key_buffer(m_am_tools);
+
+	eap_status_e status(eap_status_not_supported);
+
+
+	if (m_is_client == true)
+	{
+
+#if defined(WAPI_USE_CERTIFICATE_STORE)
+
+		// Search client certificate that is issued by id_of_certificate,
+		// then read the private key with Certificate-Reference.
+
+		eap_variable_data_c issuer_name(m_am_tools);
+
+		{
+			wapi_asn1_der_parser_c parser(m_am_tools);
+			if (parser.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_status_e status = parser.decode(&m_id_of_own_certificate);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			eap_variable_data_c subject_name(m_am_tools);
+			eap_variable_data_c sequence_number(m_am_tools);
+
+			status = parser.get_wapi_identity(
+				&subject_name,
+				&issuer_name,
+				&sequence_number);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		ec_cs_compare_certificate_id_c compare_user_certificate_id(
+			m_am_tools,
+			&m_PAC_store_master_key,
+			&m_PAC_store_device_seed);
+
+		ec_cs_data_c search_user_certificate_id(m_am_tools);
+
+		status = search_user_certificate_id.get_writable_data()->set_buffer(
+			&m_id_of_own_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): count of m_client_certificates = %d.\n"),
+			 this,
+			 (m_is_client == true ? "client": "server"),
+			 m_client_certificates.get_object_count()));
+
+		// Search certificate with the issuer name from client-certificates.
+		i32_t index = find_with_compare<ec_cs_data_c>(
+			&compare_user_certificate_id,
+			&m_client_certificates,
+			&search_user_certificate_id,
+			m_am_tools);
+
+		if (index >= 0)
+		{
+			// Match.
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): Client certificate match.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			const ec_cs_data_c * const selected_certificate = m_client_certificates.get_object(index);
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+			// Read the Certificate-Reference.
+
+			ec_cs_tlv_c handler(m_am_tools, true);
+			if (handler.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_variable_data_c certificate_reference(m_am_tools);
+			if (certificate_reference.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = handler.parse_encrypted_certificate(
+				selected_certificate->get_type(),
+				&m_PAC_store_master_key,
+				selected_certificate->get_reference(),
+				&m_PAC_store_device_seed,
+				selected_certificate->get_data(),
+				&certificate_reference);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			if (certificate_reference.get_is_valid_data() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+			}
+
+			const ec_cs_variable_data_c * const certificate_data_tlv = handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_certificate_data);
+			if (certificate_data_tlv == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+			{
+				eap_variable_data_c certificate(
+					m_am_tools,
+					certificate_data_tlv->get_data(certificate_data_tlv->get_data_length()),
+					certificate_data_tlv->get_data_length(),
+					false,
+					false);
+				if (certificate.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				status = compare_id_and_certificate(
+					&m_selected_client_id,
+					&certificate);
+				if (status != eap_status_ok)
+				{
+					// Certificate selected by host does not match the certificate peer uses.
+					(void) m_partner->set_session_timeout(0ul);
+
+					if (m_is_client == false)
+					{
+						status = eap_status_ca_certificate_unknown;
+					}
+					else
+					{
+						status = eap_status_user_certificate_unknown;
+					}
+
+					(void) send_error_notification(status);
+
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+			ec_cs_compare_certificate_reference_c compare_certificate_reference(m_am_tools);
+
+			ec_cs_data_c search_reference(m_am_tools);
+
+			status = search_reference.get_writable_data()->set_buffer(
+				&certificate_reference);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): count of m_client_private_keys = %d.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server"),
+				 m_client_private_keys.get_object_count()));
+
+			// Search private key with the Certificate-Reference.
+			i32_t index = find_with_compare<ec_cs_data_c>(
+				&compare_certificate_reference,
+				&m_client_private_keys,
+				&search_reference,
+				m_am_tools);
+
+			if (index >= 0)
+			{
+				// Match.
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): Client certificate match.\n"),
+					 this,
+					 (m_is_client == true ? "client": "server")));
+
+				selected_private_key = m_client_private_keys.get_object(index);
+
+				if (selected_private_key == 0)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+				}
+
+				ec_cs_tlv_c handler(m_am_tools, true);
+				if (handler.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				eap_variable_data_c certificate_reference(m_am_tools);
+				if (certificate_reference.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				status = handler.parse_encrypted_certificate(
+					selected_private_key->get_type(),
+					&m_PAC_store_master_key,
+					selected_private_key->get_reference(),
+					&m_PAC_store_device_seed,
+					selected_private_key->get_data(),
+					&certificate_reference);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				const ec_cs_variable_data_c * const private_key_data = handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_private_key_data);
+				if (private_key_data == 0)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+				}
+
+				status = private_key_buffer.set_copy_of_buffer(
+					private_key_data->get_data(private_key_data->get_data_length()),
+					private_key_data->get_data_length());
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				selected_private_key_data = &private_key_buffer;
+			}
+			else
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): No client certificate match.\n"),
+					 this,
+					 (m_is_client == true ? "client": "server")));
+			}
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::internal_create_signature_with_private_key(): No client certificate match.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			status = completion_action_push(ec_cs_completion_internal_create_signature_with_private_key);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = internal_select_own_certificate_with_issuer_name();
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+#else
+
+		if (selected_private_key_data == 0)
+		{
+			status = compare_id_and_certificate(&m_id_of_own_certificate, &m_dummy_test_own_certificate);
+			if (status == eap_status_ok)
+			{
+				selected_private_key_data = &m_dummy_test_own_private_key;
+			}
+		}
+
+#endif //#if defined(WAPI_USE_CERTIFICATE_STORE)
+
+	}
+
+	if (m_is_client == false)
+	{
+		if (selected_private_key_data == 0)
+		{
+			status = compare_id_and_certificate(&m_id_of_own_certificate, &m_dummy_test_asu_certificate);
+			if (status == eap_status_ok)
+			{
+				selected_private_key_data = &m_dummy_test_asu_private_key;
+			}
+		}
+
+		if (selected_private_key_data == 0)
+		{
+			status = compare_id_and_certificate(&m_id_of_own_certificate, &m_dummy_test_own_certificate);
+			if (status == eap_status_ok)
+			{
+				selected_private_key_data = &m_dummy_test_own_private_key;
+			}
+		}
+	}
+
+	status = m_ec_algorithms->create_signature_with_private_key(&m_hash_of_message, selected_private_key_data);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::create_signature_with_private_key(
+	const eap_variable_data_c * const hash_of_message,
+	const eap_variable_data_c * const id_of_certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::create_signature_with_private_key():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::create_signature_with_private_key()");
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("id_of_certificate"),
+		id_of_certificate->get_data(),
+		id_of_certificate->get_data_length()));
+
+	eap_variable_data_c private_key_buffer(m_am_tools);
+
+	eap_status_e status(eap_status_not_supported);
+
+	status = m_hash_of_message.set_copy_of_buffer(hash_of_message);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_id_of_own_certificate.set_copy_of_buffer(id_of_certificate);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = internal_create_signature_with_private_key();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::verify_signature_with_public_key(
+	const eap_variable_data_c * const peer_identity,
+	const eap_variable_data_c * const hash_of_message,
+	const eap_variable_data_c * const signature,
+	const bool allow_use_of_ae_certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::verify_signature_with_public_key()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	eap_variable_data_c used_certificate_id(m_am_tools);
+
+	if (allow_use_of_ae_certificate == false
+		&& m_selected_ca_id.get_is_valid_data() == true)
+	{
+		status = used_certificate_id.set_copy_of_buffer(&m_selected_ca_id);
+	}
+	else
+	{
+		status = used_certificate_id.set_copy_of_buffer(peer_identity);
+	}
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("used_certificate_id"),
+		used_certificate_id.get_data(),
+		used_certificate_id.get_data_length()));
+
+	eap_variable_data_c * selected_certificate = 0;
+	eap_variable_data_c selected_certificate_buffer(m_am_tools);
+
+
+	if (selected_certificate == 0
+		&& m_ae_certificate.get_is_valid_data() == true
+		&& allow_use_of_ae_certificate == true)
+	{
+		status = compare_id_and_certificate(&used_certificate_id, &m_ae_certificate);
+		if (status == eap_status_ok)
+		{
+			selected_certificate = &m_ae_certificate;
+		}
+	}
+
+	if (m_is_client == true
+		&& selected_certificate == 0)
+	{
+
+#if defined(WAPI_USE_CERTIFICATE_STORE)
+
+		ec_cs_compare_certificate_id_c compare_certificate_id(
+			m_am_tools,
+			&m_PAC_store_master_key,
+			&m_PAC_store_device_seed);
+
+		const ec_cs_data_c * match_certificate_data = 0;
+
+		ec_cs_data_c search_peer_identity(m_am_tools);
+
+		status = search_peer_identity.get_writable_data()->set_buffer(
+			&used_certificate_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): count of m_ca_certificates = %d.\n"),
+			 this,
+			 (m_is_client == true ? "client": "server"),
+			 m_ca_certificates.get_object_count()));
+
+		// Search certificate with the issuer ID from CA-certificates.
+		i32_t index = find_with_compare<ec_cs_data_c>(
+			&compare_certificate_id,
+			&m_ca_certificates,
+			&search_peer_identity,
+			m_am_tools);
+
+		if (index >= 0)
+		{
+			// Match.
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): CA certificate match.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+
+			match_certificate_data = m_ca_certificates.get_object(index);
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): count of m_client_certificates = %d.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server"),
+				 m_client_certificates.get_object_count()));
+
+			// Search certificate with the issuer ID from client certificates.
+			index = find_with_compare<ec_cs_data_c>(
+				&compare_certificate_id,
+				&m_client_certificates,
+				&search_peer_identity,
+				m_am_tools);
+			if (index >= 0)
+			{
+				// Match.
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): Client certificate match.\n"),
+					 this,
+					 (m_is_client == true ? "client": "server")));
+
+				match_certificate_data = m_client_certificates.get_object(index);
+			}
+			else
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): No CA neither client certificate match.\n"),
+					 this,
+					 (m_is_client == true ? "client": "server")));
+			}
+		}
+
+		if (match_certificate_data != 0)
+		{
+			ec_cs_tlv_c handler(m_am_tools, true);
+			if (handler.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_variable_data_c certificate_reference(m_am_tools);
+			if (certificate_reference.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = handler.parse_encrypted_certificate(
+				match_certificate_data->get_type(),
+				&m_PAC_store_master_key,
+				match_certificate_data->get_reference(),
+				&m_PAC_store_device_seed,
+				match_certificate_data->get_data(),
+				&certificate_reference);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			const ec_cs_variable_data_c * const certificate_data_tlv = handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_certificate_data);
+			if (certificate_data_tlv == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+			}
+
+			{
+				eap_variable_data_c certificate(
+					m_am_tools,
+					certificate_data_tlv->get_data(certificate_data_tlv->get_data_length()),
+					certificate_data_tlv->get_data_length(),
+					false,
+					false);
+				if (certificate.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				status = compare_id_and_certificate(
+					&m_selected_ca_id,
+					&certificate);
+				if (status != eap_status_ok)
+				{
+					// Certificate selected by host does not match the certificate peer uses.
+					(void) m_partner->set_session_timeout(0ul);
+
+					if (m_is_client == false)
+					{
+						status = eap_status_ca_certificate_unknown;
+					}
+					else
+					{
+						status = eap_status_user_certificate_unknown;
+					}
+
+					(void) send_error_notification(status);
+
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+
+			status = selected_certificate_buffer.set_copy_of_buffer(
+				certificate_data_tlv->get_data(certificate_data_tlv->get_data_length()),
+				certificate_data_tlv->get_data_length());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			selected_certificate = &selected_certificate_buffer;
+		}
+		else
+		{
+			if (m_ca_certificates.get_object_count() == 0)
+			{
+				ec_cs_data_c search_id(m_am_tools);
+
+				eap_status_e status = search_id.get_writable_data()->set_buffer(
+					&used_certificate_id);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				eap_variable_data_c certificate_reference(m_am_tools);
+
+				ec_cs_compare_reference_id_c compare_reference_id(m_am_tools);
+
+				ec_cs_data_type_e certificate_type(ec_cs_data_type_none);
+
+				const ec_cs_data_c * reference_tlv = 0;
+
+				if (m_read_ca_asu_id_list == true)
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools,
+						TRACE_FLAGS_DEFAULT,
+						(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): count of m_ca_asu_id_list = %d.\n"),
+						 this,
+						 (m_is_client == true ? "client": "server"),
+						 m_ca_asu_id_list.get_object_count()));
+
+					// Search Certificate-reference with the issuer ID.
+					i32_t index = find_with_compare<ec_cs_data_c>(
+						&compare_reference_id,
+						&m_ca_asu_id_list,
+						&search_id,
+						m_am_tools);
+					if (index >= 0)
+					{
+						// Match.
+						EAP_TRACE_DEBUG(
+							m_am_tools,
+							TRACE_FLAGS_DEFAULT,
+							(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): CA certificate ID list match.\n"),
+							 this,
+							 (m_is_client == true ? "client": "server")));
+
+						reference_tlv = m_ca_asu_id_list.get_object(index);
+						certificate_type = ec_cs_data_type_ca_certificate_data;
+					}
+					else
+					{
+						EAP_TRACE_DEBUG(
+							m_am_tools,
+							TRACE_FLAGS_DEFAULT,
+							(EAPL("WARNING: WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::verify_signature_with_public_key(): NO CA certificate ID list match.\n"),
+							 this,
+							 (m_is_client == true ? "client": "server")));
+					}
+
+					if (reference_tlv != 0)
+					{
+						status = read_certificate_reference(reference_tlv, &certificate_reference);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						status = m_peer_identity.set_copy_of_buffer(&used_certificate_id);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						status = m_hash_of_message.set_copy_of_buffer(hash_of_message);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						status = m_signature.set_copy_of_buffer(signature);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						m_allow_use_of_ae_certificate = allow_use_of_ae_certificate;
+
+						status = completion_action_push(ec_cs_completion_internal_verify_signature_with_public_key);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						// Read the certificate from database.
+						status = read_certificate(
+							ec_cs_pending_operation_verify_signature_with_public_key,
+							certificate_type,
+							&certificate_reference);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+					}
+				}
+			}
+			else
+			{
+				// No certificate found. Cannot continue.
+				(void) m_partner->set_session_timeout(0ul);
+
+				if (m_is_client == false)
+				{
+					status = eap_status_ca_certificate_unknown;
+				}
+				else
+				{
+					status = eap_status_user_certificate_unknown;
+				}
+
+				(void) send_error_notification(status);
+
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+#else
+
+		if (selected_certificate == 0)
+		{
+			status = compare_id_and_certificate(&used_certificate_id, &m_dummy_test_asu_certificate);
+			if (status == eap_status_ok)
+			{
+				selected_certificate = &m_dummy_test_asu_certificate;
+			}
+		}
+
+		if (selected_certificate == 0)
+		{
+			status = compare_id_and_certificate(&used_certificate_id, &m_dummy_test_own_certificate);
+			if (status == eap_status_ok)
+			{
+				selected_certificate = &m_dummy_test_own_certificate;
+			}
+		}
+
+#endif //#if defined(WAPI_USE_CERTIFICATE_STORE)
+
+	}
+
+
+	if (m_is_client == false)
+	{
+		if (selected_certificate == 0)
+		{
+			status = compare_id_and_certificate(&used_certificate_id, &m_dummy_test_asu_certificate);
+			if (status == eap_status_ok)
+			{
+				selected_certificate = &m_dummy_test_asu_certificate;
+			}
+		}
+
+		if (selected_certificate == 0)
+		{
+			status = compare_id_and_certificate(&used_certificate_id, &m_dummy_test_own_certificate);
+			if (status == eap_status_ok)
+			{
+				selected_certificate = &m_dummy_test_own_certificate;
+			}
+		}
+
+		if (m_is_client == false // Only test server could have this certificate.
+			&& selected_certificate == 0)
+		{
+			status = compare_id_and_certificate(&used_certificate_id, &m_dummy_test_peer_certificate);
+			if (status == eap_status_ok)
+			{
+				selected_certificate = &m_dummy_test_peer_certificate;
+			}
+		}
+	}
+
+	status = m_ec_algorithms->verify_signature_with_public_key(
+		selected_certificate,
+		hash_of_message,
+		signature);
+
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::read_certificate_wapi_identity(
+	const eap_variable_data_c * const certificate,
+	eap_variable_data_c * const certificate_wapi_identity)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_certificate_wapi_identity():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_certificate_wapi_identity()");
+
+	if (certificate_wapi_identity == 0
+		|| certificate_wapi_identity->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wapi_certificate_asn1_der_parser_c parser(m_am_tools);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = parser.decode(certificate);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = parser.read_certificate_id(
+		certificate_wapi_identity);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::copy_certificate_wapi_identities(
+	EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const certificates_id_list,
+	eap_array_c<eap_variable_data_c> * const wapi_identities_list)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::copy_certificate_wapi_identities():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::copy_certificate_wapi_identities()");
+
+	eap_status_e status(eap_status_ok);
+
+	if (certificates_id_list == 0
+		|| wapi_identities_list == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	ec_cs_tlv_c master_key_handler(m_am_tools, true);
+	if (master_key_handler.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	for (u32_t ind = 0; ind < certificates_id_list->get_object_count(); ++ind)
+	{
+		eap_variable_data_c * const certificate_wapi_identity = new eap_variable_data_c(m_am_tools);
+
+		eap_automatic_variable_c<eap_variable_data_c> automatic_certificate_wapi_identity(m_am_tools, certificate_wapi_identity);
+
+		if (certificate_wapi_identity == 0
+			|| certificate_wapi_identity->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		const ec_cs_data_c * const id_reference = certificates_id_list->get_object(ind);
+
+		if (id_reference != 0
+			&& id_reference->get_is_valid() == true)
+		{
+			ec_cs_tlv_payloads_c parser(
+				m_am_tools,
+				true);
+			if (parser.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_variable_data_c id_reference_MAC_key(m_am_tools);
+			if (id_reference_MAC_key.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = master_key_handler.generate_data_key(
+				false,
+				id_reference->get_type(),
+				&id_reference_MAC_key,
+				&m_PAC_store_master_key,
+				id_reference->get_reference(),
+				&m_PAC_store_device_seed);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = master_key_handler.parse_data_with_MAC(
+				&id_reference_MAC_key,
+				id_reference->get_data() ///< This is the start of the message buffer.
+				);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			const ec_cs_variable_data_c * const ID_reference_data_tlv = master_key_handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_ID_reference);
+			if (ID_reference_data_tlv == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+			}
+
+			ec_cs_tlv_payloads_c id_parser(
+				m_am_tools,
+				true);
+			if (id_parser.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			{
+				u32_t length(ID_reference_data_tlv->get_header()->get_data_length());
+				u32_t padding_length(0ul);
+
+				status = id_parser.parse_ec_cs_payloads(
+					ID_reference_data_tlv->get_header()->get_data(ID_reference_data_tlv->get_data_length()), ///< This is the start of the message buffer.
+					&length, ///< This is the length of the buffer. This must match with the length of all payloads.
+					&padding_length ///< Length of possible padding is set to this variable.
+					);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+
+
+			const ec_cs_variable_data_c * const asu_id_data_tlv = id_parser.get_tlv_pointer(ec_cs_tlv_type_CS_ASU_ID);
+			if (asu_id_data_tlv == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+			}
+
+			status = certificate_wapi_identity->set_copy_of_buffer(
+				asu_id_data_tlv->get_data(asu_id_data_tlv->get_data_length()),
+				asu_id_data_tlv->get_data_length());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("certificate_wapi_identity"),
+				certificate_wapi_identity->get_data(),
+				certificate_wapi_identity->get_data_length()));
+
+			automatic_certificate_wapi_identity.do_not_free_variable();
+
+			status = wapi_identities_list->add_object(certificate_wapi_identity, true);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::read_id_of_certificate(
+	const eap_variable_data_c * const certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_id_of_certificate():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_id_of_certificate()");
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c certificate_wapi_id(m_am_tools);
+	if (certificate_wapi_id.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = read_certificate_wapi_identity(
+		certificate,
+		&certificate_wapi_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = m_partner->complete_read_id_of_certificate(&certificate_wapi_id);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::create_ecdh_temporary_keys()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::create_ecdh_temporary_keys():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::create_ecdh_temporary_keys()");
+
+	eap_status_e status = m_ec_algorithms->create_ecdh_temporary_keys();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::create_ecdh(
+	const eap_variable_data_c * const own_private_key_d,
+	const eap_variable_data_c * const peer_public_key_x,
+	const eap_variable_data_c * const peer_public_key_y)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::create_ecdh():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::create_ecdh()");
+
+	eap_status_e status = m_ec_algorithms->create_ecdh(
+		own_private_key_d,
+		peer_public_key_x,
+		peer_public_key_y);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_create_signature_with_private_key(
+	const eap_variable_data_c * const signature,
+	const eap_status_e signature_status)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_create_signature_with_private_key():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_create_signature_with_private_key()");
+
+	eap_status_e status = m_partner->complete_create_signature_with_private_key(signature, signature_status);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_verify_signature_with_public_key(
+	const eap_status_e verification_status)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_verify_signature_with_public_key():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_verify_signature_with_public_key()");
+
+	eap_status_e status = m_partner->complete_verify_signature_with_public_key(verification_status);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_create_ecdh_temporary_keys(
+	const eap_variable_data_c * const private_key_d,
+	const eap_variable_data_c * const public_key_x,
+	const eap_variable_data_c * const public_key_y)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_create_ecdh_temporary_keys():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_create_ecdh_temporary_keys()");
+
+	eap_status_e status = m_partner->complete_create_ecdh_temporary_keys(private_key_d, public_key_x, public_key_y);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_create_ecdh(
+	const eap_variable_data_c * const K_AB_x4,
+	const eap_variable_data_c * const K_AB_y4)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_create_ecdh():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_create_ecdh()");
+
+	eap_status_e status = m_partner->complete_create_ecdh(K_AB_x4, K_AB_y4);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_initialize_certificate_store(
+	const wapi_completion_operation_e completion_operation)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_initialize_certificate_store():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_initialize_certificate_store()");
+
+	eap_status_e status(eap_status_ok);
+
+	m_certificate_store_initialized = true;
+
+	if (m_complete_start_certificate_import == true)
+	{
+		set_pending_operation(ec_cs_pending_operation_none);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls: ec_certificate_store_c::complete_initialize_certificate_store(): %d.\n"),
+			__LINE__));
+
+		status = m_am_certificate_store->complete_start_certificate_import();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	status = completion_action_check();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::remove_cached_certificate_store_data()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::remove_cached_certificate_store_data():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::remove_cached_certificate_store_data()");
+
+	eap_status_e status(eap_status_ok);
+
+	save_data_to_permanent_store();
+
+	m_certificate_store_initialized = false;
+
+	m_master_key_changed = false;
+
+	m_PAC_store_master_key.reset();
+
+	m_PAC_store_password.reset();
+
+	m_PAC_store_device_seed.reset();
+
+	eap_variable_data_c key(m_am_tools);
+
+	status = key.set_copy_of_buffer(
+		WAPI_CS_MEMORY_STORE_KEY,
+		sizeof(WAPI_CS_MEMORY_STORE_KEY));
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	(void) m_am_tools->memory_store_remove_data(&key);
+
+	status = m_imported_certificate_wapi_id.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_imported_certificate_data.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_imported_certificate_file_data.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_imported_certificate_filename.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	status = m_imported_private_key_data.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	status = m_ae_certificate.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	status = m_selected_ca_id.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_selected_client_id.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	status = m_ca_asu_id_list.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	m_read_ca_asu_id_list = false;
+
+	status = m_client_asu_id_list.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	m_read_client_asu_id_list = false;
+
+	status = m_ca_certificates.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_client_certificates.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_client_private_keys.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_broken_cs_data_list.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::read_PEM_data_line(
+	const eap_variable_data_c * const in_imported_certificate_file_data,
+	u32_t * const offset,
+	eap_variable_data_c * const line)
+{
+	if (in_imported_certificate_file_data == 0
+		|| offset == 0
+		|| in_imported_certificate_file_data->get_data_length() < *offset)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (*offset >= in_imported_certificate_file_data->get_data_length())
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_end_of_file);
+	}
+
+	u32_t remain_data_size(in_imported_certificate_file_data->get_data_length() - *offset);
+
+	const u8_t * const start = in_imported_certificate_file_data->get_data_offset(*offset, remain_data_size);
+	if (start == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	const u8_t * data = start;
+	if (data == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+
+	const u8_t * const end = start + remain_data_size;
+	if (end == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	while (data < end && *data != '\n' && *data != '\r')
+	{
+		++data;
+	}
+
+	eap_status_e status = line->set_buffer(start, (data - start), false, false);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (data < end)
+	{
+		if (*data == '\r')
+		{
+			++data;
+		}
+
+		if (*data == '\n')
+		{
+			++data;
+		}
+	}
+
+	*offset += (data - start);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::convert_PEM_to_DER(
+	const wapi_pem_data_type_e key_type,
+	const eap_variable_data_c * const pem_data,
+	eap_array_c<ec_cs_data_c> * const der_data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::convert_PEM_to_DER():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::convert_PEM_to_DER()");
+
+	ec_cs_data_c data(m_am_tools);
+	if (data.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = data.get_writable_data()->set_buffer_length(pem_data->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = data.get_writable_data()->set_data_length(data.get_writable_data()->get_buffer_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	u32_t der_data_length(data.get_writable_data()->get_data_length());
+
+	status = m_am_tools->restore_bytes_from_ascii_armor(
+		pem_data->get_data(),
+		pem_data->get_data_length(),
+		data.get_writable_data()->get_data(der_data_length),
+		&der_data_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = data.get_writable_data()->set_data_length(der_data_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("data"),
+		data.get_writable_data()->get_data(),
+		data.get_writable_data()->get_data_length()));
+
+	if (key_type == wapi_pem_data_type_certificate)
+	{
+		eap_variable_data_c certificate_wapi_id(m_am_tools);
+		if (certificate_wapi_id.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = read_certificate_wapi_identity(
+			data.get_data(),
+			&certificate_wapi_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("certificate_wapi_id"),
+			certificate_wapi_id.get_data(),
+			certificate_wapi_id.get_data_length()));
+
+		ec_cs_data_type_e data_type(ec_cs_data_type_none);
+
+		status = read_certificate_type(&certificate_wapi_id, &data_type);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data.set_type(data_type);
+	}
+	else if (key_type == wapi_pem_data_type_private_key)
+	{
+		data.set_type(ec_cs_data_type_private_key_data);
+	}
+	else
+	{
+		EAP_ASSERT_ANYWAY_TOOLS(m_am_tools);
+	}
+
+	status = der_data->add_object(data.copy(), true);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+#if defined(USE_WAPI_PEM_TO_DER_TEST)
+
+	{
+		// This is test code for PEM decode/encode.
+
+		eap_variable_data_c pem_data_2(m_am_tools);
+		if (pem_data_2.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = pem_data_2.set_buffer_length(3ul + data.get_data()->get_data_length() * 8 / 6);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = pem_data_2.set_data_length(pem_data_2.get_buffer_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		u32_t pem_data_length(pem_data->get_data_length());
+
+		status = m_am_tools->convert_bytes_to_ascii_armor(
+			data.get_data()->get_data(),
+			data.get_data()->get_data_length(),
+			pem_data_2.get_data(der_data_length),
+			&pem_data_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = pem_data_2.set_data_length(pem_data_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("pem_data_2"),
+			pem_data_2.get_data(),
+			pem_data_2.get_data_length()));
+
+		if (pem_data->compare(&pem_data_2) != 0)
+		{
+			EAP_ASSERT_ANYWAY_TOOLS(m_am_tools);
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
+		}
+	}
+
+#endif //#if defined(USE_WAPI_PEM_TO_DER_TEST)
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::parse_PEM_file_data(
+	const eap_variable_data_c * const in_imported_certificate_file_data,
+	eap_array_c<ec_cs_data_c> * const der_data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::parse_PEM_file_data():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::parse_PEM_file_data()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	u32_t offset(0ul);
+
+	eap_variable_data_c line(m_am_tools);
+	if (line.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_variable_data_c pem_data(m_am_tools);
+	if (pem_data.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	wapi_pem_data_type_e data_type(wapi_pem_data_type_none);
+	wapi_pem_read_state_e state(wapi_pem_read_state_header);
+
+	do
+	{
+		status = read_PEM_data_line(in_imported_certificate_file_data, &offset, &line);
+		if (status == eap_status_end_of_file)
+		{
+			// In the end of file status is eap_status_end_of_file. We change that to OK status.
+			status = eap_status_ok;
+			break;
+		}
+		else if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		if (state == wapi_pem_read_state_header)
+		{
+			if (wapi_pem_certificate_begin.get_field()->compare(
+					m_am_tools,
+					&line) == true)
+			{
+				state = wapi_pem_read_state_data;
+				data_type = wapi_pem_data_type_certificate;
+			}
+			else if (wapi_pem_ec_private_key_begin.get_field()->compare(
+					m_am_tools,
+					&line) == true)
+			{
+				state = wapi_pem_read_state_data;
+				data_type = wapi_pem_data_type_private_key;
+			}
+		}
+		else if (state == wapi_pem_read_state_data)
+		{
+			if (data_type == wapi_pem_data_type_certificate
+				&& wapi_pem_certificate_end.get_field()->compare(
+					m_am_tools,
+					&line) == true)
+			{
+				status = convert_PEM_to_DER(
+					data_type,
+					&pem_data,
+					der_data);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				pem_data.reset_start_offset_and_data_length();
+
+				state = wapi_pem_read_state_header;
+			}
+			else if (data_type == wapi_pem_data_type_private_key
+				&& wapi_pem_ec_private_key_end.get_field()->compare(
+					m_am_tools,
+					&line) == true)
+			{
+				status = convert_PEM_to_DER(
+					data_type,
+					&pem_data,
+					der_data);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				pem_data.reset_start_offset_and_data_length();
+
+				state = wapi_pem_read_state_header;
+			}
+			else
+			{
+				status = pem_data.add_data(&line);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+		}
+	}
+	while(status == eap_status_ok);
+
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::read_certificate_type(
+	const eap_variable_data_c * const imported_certificate_wapi_id,
+	ec_cs_data_type_e * const data_type)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_certificate_type():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_certificate_type()");
+
+	eap_status_e status(eap_status_not_supported);
+
+
+	wapi_asn1_der_parser_c wapi_asn1_der_parser(m_am_tools);
+
+	if (wapi_asn1_der_parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = wapi_asn1_der_parser.decode(imported_certificate_wapi_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	eap_variable_data_c asn1_der_subject_name(m_am_tools);
+	eap_variable_data_c asn1_der_issuer_name(m_am_tools);
+	eap_variable_data_c asn1_der_sequence_number(m_am_tools);
+
+	status = wapi_asn1_der_parser.get_wapi_identity(
+		&asn1_der_subject_name,
+		&asn1_der_issuer_name,
+		&asn1_der_sequence_number);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (asn1_der_subject_name.compare(&asn1_der_issuer_name) == 0)
+	{
+		*data_type = ec_cs_data_type_ca_certificate_data;
+	}
+	else
+	{
+		*data_type = ec_cs_data_type_client_certificate_data;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::read_certificate_reference(
+	const ec_cs_data_c * const reference_tlv,
+	eap_variable_data_c * const certificate_reference)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_certificate_reference():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_certificate_reference()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	ec_cs_tlv_header_c id_reference_tlv(
+		m_am_tools,
+		reference_tlv->get_data()->get_data(),
+		reference_tlv->get_data()->get_data_length());
+	if (id_reference_tlv.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	ec_cs_tlv_payloads_c parser(
+		m_am_tools,
+		true);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t length(id_reference_tlv.get_data_length());
+	u32_t padding_length(0ul);
+
+	status = parser.parse_ec_cs_payloads(
+		id_reference_tlv.get_data(length), ///< This is the start of the message buffer.
+		&length, ///< This is the length of the buffer. This must match with the length of all payloads.
+		&padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	const ec_cs_variable_data_c * const certificate_reference_tlv = parser.get_tlv_pointer(ec_cs_tlv_type_CS_certificate_reference);
+	if (certificate_reference_tlv == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	status = certificate_reference->set_copy_of_buffer(
+		certificate_reference_tlv->get_data(certificate_reference_tlv->get_data_length()),
+		certificate_reference_tlv->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::read_certificate(
+	const ec_cs_pending_operation_e pending_operation,
+	const ec_cs_data_type_e certificate_type,
+	const eap_variable_data_c * certificate_reference)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_certificate():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_certificate()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	eap_array_c<ec_cs_data_c> in_references(m_am_tools);
+
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data->get_writable_reference()->set_copy_of_buffer(certificate_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(certificate_type);
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references.add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	if (certificate_type == ec_cs_data_type_client_certificate_data)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data->get_writable_reference()->set_copy_of_buffer(certificate_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_private_key_data);
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references.add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	status = m_am_certificate_store->read_certificate_store_data(
+		pending_operation,
+		&in_references);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::read_both_certificate_lists(
+	const ec_cs_pending_operation_e pending_operation)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_both_certificate_lists():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_both_certificate_lists()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	eap_array_c<ec_cs_data_c> in_references(m_am_tools);
+
+	status = add_password_qyery(&in_references);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (m_read_ca_asu_id_list == false)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_ca_asu_id_list);
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references.add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+	}
+	else
+	{
+		status = eap_status_ok;
+	}
+
+	if (m_read_client_asu_id_list == false)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_client_asu_id_list);
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references.add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		status = eap_status_ok;
+	}
+
+	if (in_references.get_object_count() > 0ul)
+	{
+		m_read_ca_asu_id_list = true;
+		m_read_client_asu_id_list = true;
+
+		status = m_am_certificate_store->read_certificate_store_data(
+			pending_operation,
+			&in_references);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::read_ca_certificate_list(
+	const ec_cs_pending_operation_e pending_operation)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_ca_certificate_list():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_ca_certificate_list()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	eap_array_c<ec_cs_data_c> in_references(m_am_tools);
+
+	status = add_password_qyery(&in_references);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (m_read_ca_asu_id_list == false)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_ca_asu_id_list);
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references.add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		status = eap_status_ok;
+	}
+
+	if (in_references.get_object_count() > 0ul)
+	{
+		status = m_am_certificate_store->read_certificate_store_data(
+			pending_operation,
+			&in_references);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+eap_status_e ec_certificate_store_c::read_client_certificate_list(
+	const ec_cs_pending_operation_e pending_operation)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::read_client_certificate_list():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::read_client_certificate_list()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	eap_array_c<ec_cs_data_c> in_references(m_am_tools);
+
+	status = add_password_qyery(&in_references);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (m_read_client_asu_id_list == false)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_client_asu_id_list);
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references.add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		status = eap_status_ok;
+	}
+
+
+	if (in_references.get_object_count() > 0ul)
+	{
+		status = m_am_certificate_store->read_certificate_store_data(
+			pending_operation,
+			&in_references);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::add_imported_certificate_file(
+	const eap_variable_data_c * const in_imported_certificate_file_data,
+	const eap_variable_data_c * const in_imported_certificate_filename)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::add_imported_certificate_file():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::add_imported_certificate_file()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	if (in_imported_certificate_file_data == 0
+		|| in_imported_certificate_file_data->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (in_imported_certificate_filename == 0
+		|| in_imported_certificate_filename->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("in_imported_certificate_filename"),
+		in_imported_certificate_filename->get_data(),
+		in_imported_certificate_filename->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("in_imported_certificate_file_data"),
+		in_imported_certificate_file_data->get_data(),
+		in_imported_certificate_file_data->get_data_length()));
+
+	eap_array_c<ec_cs_data_c> der_data(m_am_tools);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = m_imported_certificate_file_data.set_copy_of_buffer(in_imported_certificate_file_data);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_imported_certificate_filename.set_copy_of_buffer(in_imported_certificate_filename);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_imported_certificate_data.reset_start_offset_and_data_length();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_imported_private_key_data.reset_start_offset_and_data_length();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = completion_action_push(ec_cs_completion_complete_add_imported_certificate_file);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (m_PAC_store_master_key.get_is_valid_data() == true
+		&& m_PAC_store_password.get_is_valid_data() == true
+		&& m_PAC_store_device_seed.get_is_valid_data() == true)
+	{
+		status = internal_complete_add_imported_certificate_file();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		status = completion_action_push(ec_cs_completion_internal_complete_add_imported_certificate_file);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = completion_action_push(ec_cs_completion_query_PAC_store_password);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// If there were no asyncronous calls operations continue here.
+	status = completion_action_check();
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::internal_complete_add_imported_certificate_file()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::internal_complete_add_imported_certificate_file():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::internal_complete_add_imported_certificate_file()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	if (m_imported_certificate_file_data.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (m_imported_certificate_filename.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("m_imported_certificate_filename"),
+		m_imported_certificate_filename.get_data(),
+		m_imported_certificate_filename.get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("m_imported_certificate_file_data"),
+		m_imported_certificate_file_data.get_data(),
+		m_imported_certificate_file_data.get_data_length()));
+
+	eap_array_c<ec_cs_data_c> der_data(m_am_tools);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = parse_PEM_file_data(&m_imported_certificate_file_data, &der_data);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	ec_cs_data_type_e data_type(ec_cs_data_type_none);
+
+	for (u32_t index = 0ul; index < der_data.get_object_count(); ++index)
+	{
+		ec_cs_data_c * const data = der_data.get_object(index);
+		if (data == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+		}
+
+		if (data->get_type() == ec_cs_data_type_ca_certificate_data
+			|| data->get_type() == ec_cs_data_type_client_certificate_data)
+		{
+			data_type = data->get_type();
+
+			status = read_certificate_wapi_identity(
+				data->get_data(),
+				&m_imported_certificate_wapi_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("m_imported_certificate_wapi_id"),
+				m_imported_certificate_wapi_id.get_data(),
+				m_imported_certificate_wapi_id.get_data_length()));
+
+			status = m_imported_certificate_data.set_copy_of_buffer(data->get_data());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		else if (data->get_type() == ec_cs_data_type_private_key_data)
+		{
+			status = m_imported_private_key_data.set_copy_of_buffer(data->get_data());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+	} // for()
+
+
+	if (data_type == ec_cs_data_type_ca_certificate_data)
+	{
+		status = completion_action_push(ec_cs_completion_add_imported_ca_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = read_ca_certificate_list(ec_cs_pending_operation_import_ca_certificate_file);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else //if (data_type == ec_cs_data_type_client_certificate_data)
+	{
+		status = completion_action_push(ec_cs_completion_add_imported_client_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = read_client_certificate_list(ec_cs_pending_operation_import_client_certificate_file);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// If there were no asyncronous calls operations continue here.
+	status = completion_action_check();
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e ec_certificate_store_c::save_to_broken_cs_data_list(
+	const ec_cs_data_c * const ref_and_data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: ec_certificate_store_c::save_to_broken_cs_data_list():\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::save_to_broken_cs_data_list()");
+
+	eap_status_e status(eap_status_ok);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (ref_and_data != 0)
+	{
+		ec_cs_data_c * const new_ec_cd_data = ref_and_data->copy();
+		if (new_ec_cd_data != 0)
+		{
+			new_ec_cd_data->set_change_status(ec_cs_data_change_status_delete);
+
+			status = m_broken_cs_data_list.add_object(new_ec_cd_data, true);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		if (ref_and_data->get_type() == ec_cs_data_type_ca_certificate_data)
+		{
+			// We must remove the broken ID-Reference too.
+			ec_cs_data_c search_id(m_am_tools);
+
+			eap_status_e status = search_id.get_writable_data()->set_buffer(
+				ref_and_data->get_reference());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			eap_variable_data_c certificate_reference(m_am_tools);
+
+			ec_cs_compare_reference_c compare_reference(m_am_tools);
+
+			const ec_cs_data_c * identity_reference_tlv = 0;
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::save_to_broken_cs_data_list(): count of m_ca_asu_id_list = %d.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server"),
+				 m_ca_asu_id_list.get_object_count()));
+
+			// Search CA-Certificate identity.
+			i32_t index = find_with_compare<ec_cs_data_c>(
+				&compare_reference,
+				&m_ca_asu_id_list,
+				&search_id,
+				m_am_tools);
+			if (index >= 0)
+			{
+				// Match.
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::save_to_broken_cs_data_list(): CA certificate ID list match.\n"),
+					 this,
+					 (m_is_client == true ? "client": "server")));
+
+				identity_reference_tlv = m_ca_asu_id_list.get_object(index);
+
+				if (identity_reference_tlv != 0)
+				{
+					ec_cs_data_c * const new_ec_cd_data = identity_reference_tlv->copy();
+					if (new_ec_cd_data != 0)
+					{
+						new_ec_cd_data->set_change_status(ec_cs_data_change_status_delete);
+
+						status = m_broken_cs_data_list.add_object(new_ec_cd_data, true);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+					}
+				}
+			}
+		}
+		else if (ref_and_data->get_type() == ec_cs_data_type_client_certificate_data
+			|| ref_and_data->get_type() == ec_cs_data_type_private_key_data)
+		{
+			// We must remove the broken ID-Reference too.
+			ec_cs_data_c search_id(m_am_tools);
+
+			eap_status_e status = search_id.get_writable_data()->set_buffer(
+				ref_and_data->get_reference());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			eap_variable_data_c certificate_reference(m_am_tools);
+
+			ec_cs_compare_reference_c compare_reference(m_am_tools);
+
+			const ec_cs_data_c * identity_reference_tlv = 0;
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::save_to_broken_cs_data_list(): count of m_client_asu_id_list = %d.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server"),
+				 m_client_asu_id_list.get_object_count()));
+
+			// Search CA-Certificate identity.
+			i32_t index = find_with_compare<ec_cs_data_c>(
+				&compare_reference,
+				&m_client_asu_id_list,
+				&search_id,
+				m_am_tools);
+			if (index >= 0)
+			{
+				// Match.
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::save_to_broken_cs_data_list(): CA certificate ID list match.\n"),
+					 this,
+					 (m_is_client == true ? "client": "server")));
+
+				identity_reference_tlv = m_client_asu_id_list.get_object(index);
+
+				if (identity_reference_tlv != 0)
+				{
+					ec_cs_data_c * const new_ec_cd_data = identity_reference_tlv->copy();
+					if (new_ec_cd_data != 0)
+					{
+						new_ec_cd_data->set_change_status(ec_cs_data_change_status_delete);
+
+						status = m_broken_cs_data_list.add_object(new_ec_cd_data, true);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e ec_certificate_store_c::save_to_ec_cs_list(
+	eap_array_c<ec_cs_data_c> * const ec_cs_list,
+	const ec_cs_data_c * const ref_and_data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: ec_certificate_store_c::save_to_ec_cs_list():\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::save_to_ec_cs_list()");
+
+	eap_status_e status(eap_status_ok);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (ref_and_data != 0)
+	{
+		ec_cs_data_c * const new_ec_cd_data = ref_and_data->copy();
+		if (new_ec_cd_data != 0)
+		{
+			status = ec_cs_list->add_object(new_ec_cd_data, true);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e ec_certificate_store_c::save_ec_cs_data(
+	EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references_and_data_blocks)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: ec_certificate_store_c::save_ec_cs_data(): data_block_count %d\n"),
+		in_references_and_data_blocks->get_object_count()));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::save_ec_cs_data()");
+
+	eap_status_e status(eap_status_ok);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	ec_cs_tlv_c handler(m_am_tools, true);
+
+	for (u32_t ind = 0ul; ind < in_references_and_data_blocks->get_object_count(); ++ind)
+	{
+		const ec_cs_data_c * const ref_and_data = in_references_and_data_blocks->get_object(ind);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI_Core: ec_certificate_store_c::save_ec_cs_data(): ref_and_data=0x%08x\n"),
+			ref_and_data));
+
+		if (ref_and_data != 0)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("reference 0x%08x: type %d=%s, change status %d=%s\n"),
+				ref_and_data,
+				ref_and_data->get_type(),
+				ec_cs_strings_c::get_ec_cs_store_data_string(ref_and_data->get_type()),
+				ref_and_data->get_change_status(),
+				ec_cs_strings_c::get_ec_cs_store_data_change_status_string(ref_and_data->get_change_status())));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("reference"),
+				 ref_and_data->get_reference()->get_data(),
+				 ref_and_data->get_reference()->get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("data"),
+				 ref_and_data->get_data()->get_data(),
+				 ref_and_data->get_data()->get_data_length()));
+		}
+
+		if (ref_and_data != 0
+			&& ref_and_data->get_is_valid() == true)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("reference 0x%08x: type %d=%s, change status %d=%s\n"),
+				ref_and_data,
+				ref_and_data->get_type(),
+				ec_cs_strings_c::get_ec_cs_store_data_string(ref_and_data->get_type()),
+				ref_and_data->get_change_status(),
+				ec_cs_strings_c::get_ec_cs_store_data_change_status_string(ref_and_data->get_change_status())));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("reference"),
+				 ref_and_data->get_reference()->get_data(),
+				 ref_and_data->get_reference()->get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("data"),
+				 ref_and_data->get_data()->get_data(),
+				 ref_and_data->get_data()->get_data_length()));
+
+			if (ref_and_data->get_type() == ec_cs_data_type_ca_asu_id)
+			{
+				if (ref_and_data->get_data() != 0
+					&& ref_and_data->get_data()->get_is_valid_data() == true
+					&& ref_and_data->get_data()->get_data_length() > 0ul)
+				{
+					status = handler.verify_data_with_MAC(
+						&m_PAC_store_master_key,
+						&m_PAC_store_device_seed,
+						ref_and_data);
+					if (status != eap_status_ok)
+					{
+						status = save_to_broken_cs_data_list(ref_and_data);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						continue;
+					}
+
+					status = save_to_ec_cs_list(&m_ca_asu_id_list, ref_and_data);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+				}
+
+				m_read_ca_asu_id_list = true;
+			}
+			else if (ref_and_data->get_type() == ec_cs_data_type_client_asu_id)
+			{
+				if (ref_and_data->get_data() != 0
+					&& ref_and_data->get_data()->get_is_valid_data() == true
+					&& ref_and_data->get_data()->get_data_length() > 0ul)
+				{
+					status = handler.verify_data_with_MAC(
+						&m_PAC_store_master_key,
+						&m_PAC_store_device_seed,
+						ref_and_data);
+					if (status != eap_status_ok)
+					{
+						status = save_to_broken_cs_data_list(ref_and_data);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						continue;
+					}
+
+					status = save_to_ec_cs_list(&m_client_asu_id_list, ref_and_data);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+				}
+
+				m_read_client_asu_id_list = true;
+			}
+
+			else if (ref_and_data->get_type() == ec_cs_data_type_reference_counter)
+			{
+				if (ref_and_data->get_data() != 0
+					&& ref_and_data->get_data()->get_is_valid_data() == true
+					&& ref_and_data->get_reference()->get_is_valid_data() == true
+					&& ref_and_data->get_data()->get_data_length() > 0ul
+					&& ref_and_data->get_reference()->get_data_length() > 0ul)
+				{
+					/*
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+					 * | Type=Referene counter TLV     |           Length=4            |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+					 * |                    reference counter (4 octets)               |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+					 * | Type=CS-MAC TLV               |           Length=32           |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+					 * |                              MAC (32 octets)                  |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+					 */
+
+					ec_cs_tlv_c master_key_handler(m_am_tools, true);
+					if (master_key_handler.get_is_valid() == false)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+					}
+
+					eap_variable_data_c MAC_key(m_am_tools);
+					if (MAC_key.get_is_valid() == false)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+					}
+
+					status = master_key_handler.generate_data_key(
+						false,
+						ec_cs_data_type_reference_counter,
+						&MAC_key,
+						&m_PAC_store_master_key,
+						ref_and_data->get_reference(),
+						&m_PAC_store_device_seed);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					status = master_key_handler.parse_data_with_MAC(
+						&MAC_key,
+						ref_and_data->get_data());
+					if (status != eap_status_ok)
+					{
+						// Cannot continue, terminate authentication.
+						(void) m_partner->set_session_timeout(0ul);
+						(void) send_error_notification(eap_status_pac_store_corrupted);
+
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					const ec_cs_variable_data_c * const master_key_encrypted_block_tlv
+						= master_key_handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_reference_counter);
+					if (master_key_encrypted_block_tlv == 0)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+					}
+
+					void * const network_order_counter = master_key_encrypted_block_tlv->get_data(sizeof(m_reference_counter));
+
+					if (network_order_counter != 0)
+					{
+						m_reference_counter = eap_read_u32_t_network_order(
+							network_order_counter,
+							sizeof(m_reference_counter));
+
+						status = eap_status_ok;
+					}
+				}
+				else
+				{
+					// No data.
+					status = eap_status_ok;
+				}
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("Read reference counter = 0x%08x\n"),
+					 m_reference_counter));
+
+				m_reference_counter_read = true;
+			}
+			else if (ref_and_data->get_type() == ec_cs_data_type_master_key)
+			{
+				if (ref_and_data->get_data() != 0
+					&& ref_and_data->get_data()->get_is_valid_data() == true
+					&& ref_and_data->get_reference()->get_is_valid_data() == true
+					&& ref_and_data->get_data()->get_data_length() > 0ul
+					&& ref_and_data->get_reference()->get_data_length() > 0ul)
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools,
+						TRACE_FLAGS_DEFAULT,
+						(EAPL("ec_certificate_store_c::save_ec_cs_data(): Read master key from database.\n")));
+
+					/*
+					 * Master key data
+					 *
+ 					 * 0                   1                   2                   3   
+					 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    -+ -+
+					 * | Type=CS-Encrypted block TLV   |     Length=4+16+4+n+4+m       |     |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
+					 * | Type=CS-Encryption IV TLV     |           Length=16           |  |  |  | plain text
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  |
+					 * |                              IV (16 octets)                   |  |  |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
+					 * | Type=CS-Encrypted data TLV    |           Length=n+4+m        |  |  |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  | -+
+					 * |                          Master key TLV (n octets)            |  |  |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | encrypted
+					 * | Type=CS-padding TLV           |           Length=m            |  |  |  | multiple of
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | 16 octets
+					 * |                           padding (m octets)                  |  |  |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ -+ -+
+					 * | Type=CS-MAC TLV               |           Length=32           |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+					 * |                              MAC (32 octets)                  |  |
+					 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+					 */
+
+					ec_cs_tlv_c master_key_handler(m_am_tools, true);
+					if (master_key_handler.get_is_valid() == false)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+					}
+
+					eap_variable_data_c MAC_key(m_am_tools);
+					if (MAC_key.get_is_valid() == false)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+					}
+
+					status = master_key_handler.generate_data_key(
+						false,
+						ec_cs_data_type_master_key,
+						&MAC_key,
+						&m_PAC_store_password,
+						ref_and_data->get_reference(),
+						&m_PAC_store_device_seed);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					status = master_key_handler.parse_data_with_MAC(
+						&MAC_key,
+						ref_and_data->get_data());
+					if (status == eap_status_authentication_failure)
+					{
+						// Ask password again.
+						(void) m_PAC_store_password.reset();
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+					}
+					else if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					const ec_cs_variable_data_c * const master_key_encrypted_block_tlv
+						= master_key_handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_encrypted_block);
+					if (master_key_encrypted_block_tlv == 0)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+					}
+
+					ec_cs_variable_data_c master_key_plain_data_tlv(m_am_tools);
+					if (master_key_plain_data_tlv.get_is_valid() == false)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+					}
+
+					eap_variable_data_c master_key_decryption_key(m_am_tools);
+					if (master_key_decryption_key.get_is_valid() == false)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+					}
+
+					status = master_key_handler.generate_data_key(
+						true,
+						ec_cs_data_type_master_key,
+						&master_key_decryption_key,
+						&m_PAC_store_password,
+						ref_and_data->get_reference(),
+						&m_PAC_store_device_seed);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					ec_cs_tlv_c decrypt_handler(m_am_tools, true);
+					if (decrypt_handler.get_is_valid() == false)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+					}
+
+					status = decrypt_handler.parse_encrypted_tlv(
+						&master_key_decryption_key,
+						master_key_encrypted_block_tlv,
+						&master_key_plain_data_tlv);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					status = decrypt_handler.parse_cs_tlv(
+						&master_key_plain_data_tlv);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					const ec_cs_variable_data_c * const master_key_tlv
+						= decrypt_handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_master_key);
+					if (master_key_tlv == 0)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+					}
+
+					status = m_PAC_store_master_key.set_copy_of_buffer(
+						master_key_tlv->get_data(master_key_tlv->get_data_length()),
+						master_key_tlv->get_data_length());
+				}
+				else
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools,
+						TRACE_FLAGS_DEFAULT,
+						(EAPL("ec_certificate_store_c::save_ec_cs_data(): Creates new master key.\n")));
+
+					// Create a new master key.
+					crypto_random_c rand(m_am_tools);
+
+					if (rand.get_is_valid() == false)
+					{
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					status = m_PAC_store_master_key.set_buffer_length(EAP_FAST_PAC_STORE_MASTER_KEY_SIZE);
+					if (status != eap_status_ok)
+					{
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					status = m_PAC_store_master_key.set_data_length(EAP_FAST_PAC_STORE_MASTER_KEY_SIZE);
+					if (status != eap_status_ok)
+					{
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					status = rand.get_rand_bytes(
+						m_PAC_store_master_key.get_data(
+							m_PAC_store_master_key.get_data_length()),
+						m_PAC_store_master_key.get_data_length());
+					if (status != eap_status_ok)
+					{
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+
+					m_master_key_changed = true;
+				}
+
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("CS store master key"),
+					 m_PAC_store_master_key.get_data(),
+					 m_PAC_store_master_key.get_data_length()));
+			}
+			else if (ref_and_data->get_type() == ec_cs_data_type_password)
+			{
+				if (ref_and_data->get_data() != 0
+					&& ref_and_data->get_data()->get_is_valid_data() == true
+					&& ref_and_data->get_data()->get_data_length() > 0ul)
+				{
+					status = m_PAC_store_password.set_copy_of_buffer(ref_and_data->get_data());
+				}
+
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("Read CS store password"),
+					 m_PAC_store_password.get_data(),
+					 m_PAC_store_password.get_data_length()));
+			}
+			else if (ref_and_data->get_type() == ec_cs_data_type_device_seed)
+			{
+				if (ref_and_data->get_data() != 0
+					&& ref_and_data->get_data()->get_is_valid_data() == true
+					&& ref_and_data->get_data()->get_data_length() > 0ul)
+				{
+					status = m_PAC_store_device_seed.set_copy_of_buffer(ref_and_data->get_data());
+				}
+
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("Read CS store device seed"),
+					 m_PAC_store_device_seed.get_data(),
+					 m_PAC_store_device_seed.get_data_length()));
+			}
+			else if (ref_and_data->get_type() == ec_cs_data_type_ca_certificate_data)
+			{
+				if (ref_and_data->get_data() != 0
+					&& ref_and_data->get_data()->get_is_valid_data() == true
+					&& ref_and_data->get_data()->get_data_length() > 0ul)
+				{
+					status = handler.verify_data_with_MAC(
+						&m_PAC_store_master_key,
+						&m_PAC_store_device_seed,
+						ref_and_data);
+					if (status != eap_status_ok)
+					{
+						status = save_to_broken_cs_data_list(ref_and_data);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						continue;
+					}
+
+					status = m_ca_certificates.add_object(ref_and_data->copy(), true);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+				}
+			}
+			else if (ref_and_data->get_type() == ec_cs_data_type_client_certificate_data)
+			{
+				if (ref_and_data->get_data() != 0
+					&& ref_and_data->get_data()->get_is_valid_data() == true
+					&& ref_and_data->get_data()->get_data_length() > 0ul)
+				{
+					status = handler.verify_data_with_MAC(
+						&m_PAC_store_master_key,
+						&m_PAC_store_device_seed,
+						ref_and_data);
+					if (status != eap_status_ok)
+					{
+						status = save_to_broken_cs_data_list(ref_and_data);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						continue;
+					}
+
+					status = m_client_certificates.add_object(ref_and_data->copy(), true);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+				}
+			}
+			else if (ref_and_data->get_type() == ec_cs_data_type_private_key_data)
+			{
+				if (ref_and_data->get_data() != 0
+					&& ref_and_data->get_data()->get_is_valid_data() == true
+					&& ref_and_data->get_data()->get_data_length() > 0ul)
+				{
+					status = handler.verify_data_with_MAC(
+						&m_PAC_store_master_key,
+						&m_PAC_store_device_seed,
+						ref_and_data);
+					if (status != eap_status_ok)
+					{
+						status = save_to_broken_cs_data_list(ref_and_data);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+							return EAP_STATUS_RETURN(m_am_tools, status);
+						}
+
+						continue;
+					}
+
+					status = m_client_private_keys.add_object(ref_and_data->copy(), true);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+				}
+			}
+			else if (ref_and_data->get_type() == ec_cs_data_type_selected_ca_id)
+			{
+				status = m_selected_ca_id.set_copy_of_buffer(ref_and_data->get_data());
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("m_selected_ca_id"),
+					 m_selected_ca_id.get_data(),
+					 m_selected_ca_id.get_data_length()));
+			}
+			else if (ref_and_data->get_type() == ec_cs_data_type_selected_client_id)
+			{
+				status = m_selected_client_id.set_copy_of_buffer(ref_and_data->get_data());
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("m_selected_client_id"),
+					 m_selected_client_id.get_data(),
+					 m_selected_client_id.get_data_length()));
+			}
+			else
+			{
+				status = eap_status_illegal_data_payload;
+				(void) EAP_STATUS_RETURN(m_am_tools, status);
+				EAP_ASSERT_ANYWAY_TOOLS(m_am_tools);
+			}
+
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("WARNING: WAPI_Core: ec_certificate_store_c::save_ec_cs_data(): ignored broken data.\n")));
+				status = eap_status_ok;
+			}
+
+		}
+	} // for()
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = completion_action_check();
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_read_certificate_store_data(
+	const eap_status_e in_completion_status,
+	const ec_cs_pending_operation_e in_pending_operation,
+	EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references_and_data_blocks)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_read_certificate_store_data():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_read_certificate_store_data()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	m_pending_read_ec_cs_data = false;
+
+	if (in_completion_status == eap_status_ok
+		&& in_references_and_data_blocks != 0)
+	{
+		status = save_ec_cs_data(in_references_and_data_blocks);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else if (in_completion_status != eap_status_ok)
+	{
+		// Cannot continue, terminate authentication.
+		(void) m_partner->set_session_timeout(0ul);
+
+		(void) send_error_notification(in_completion_status);
+
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+
+	status = completion_action_check();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::complete_write_certificate_store_data(
+	const eap_status_e in_completion_status,
+	const ec_cs_pending_operation_e in_pending_operation)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::complete_write_certificate_store_data():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::complete_write_certificate_store_data()");
+
+	// Here we do nothing. Return still OK status that caller does not disturb.
+	eap_status_e status(eap_status_ok);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::query_certificate_list()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::query_certificate_list():\n"),
+		 this,
+		 (m_is_client == true ? "client": "server")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::query_certificate_list()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	status = completion_action_push(ec_cs_completion_complete_query_certificate_list);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = read_both_certificate_lists(ec_cs_pending_operation_query_certificate_list);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e ec_certificate_store_c::query_PAC_store_password(
+	const ec_cs_pending_operation_e in_pending_operation)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EAP-FAST: ec_certificate_store_c::query_PAC_store_password()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::query_PAC_store_password()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_array_c<ec_cs_data_c> in_references(m_am_tools);
+
+	status = add_password_qyery(&in_references);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (in_references.get_object_count() > 0ul)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls: ec_certificate_store_c::query_PAC_store_password(): m_am_pac_store_services->read_PAC_store_data(): %d.\n"),
+			__LINE__));
+
+		m_pending_read_ec_cs_data = true;
+
+		status = m_am_certificate_store->read_certificate_store_data(
+			in_pending_operation,
+			&in_references);
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: ec_certificate_store_c::query_PAC_store_password(): Skips m_am_pac_store_services->read_PAC_store_data(): %d.\n"),
+			__LINE__));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e ec_certificate_store_c::add_password_qyery(
+	eap_array_c<ec_cs_data_c> * const in_references)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EAP-FAST: ec_certificate_store_c::add_password_qyery()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::add_password_qyery()");
+
+	eap_status_e status(eap_status_ok);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (m_PAC_store_password.get_is_valid_data() == false)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_password);
+
+		status = data->get_writable_reference()->set_copy_of_buffer(
+			EC_CS_ZERO_REFERENCE,
+			sizeof(EC_CS_ZERO_REFERENCE));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references->add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	if (m_PAC_store_device_seed.get_is_valid_data() == false)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_device_seed);
+
+		status = data->get_writable_reference()->set_copy_of_buffer(
+			EC_CS_ZERO_REFERENCE,
+			sizeof(EC_CS_ZERO_REFERENCE));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references->add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	if (m_PAC_store_master_key.get_is_valid_data() == false)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data->get_writable_reference()->set_copy_of_buffer(
+			EC_CS_ZERO_REFERENCE,
+			sizeof(EC_CS_ZERO_REFERENCE));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_master_key);
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references->add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	if (m_reference_counter_read == false)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_reference_counter);
+
+		status = data->get_writable_reference()->set_copy_of_buffer(
+			EC_CS_ZERO_REFERENCE,
+			sizeof(EC_CS_ZERO_REFERENCE));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references->add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	if (m_selected_client_id.get_is_valid_data() == false)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_selected_client_id);
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references->add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+	}
+
+	if (m_selected_ca_id.get_is_valid_data() == false)
+	{
+		ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+		if (data == 0
+			|| data->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		data->set_type(ec_cs_data_type_selected_ca_id);
+
+		automatic_data.do_not_free_variable();
+
+		status = in_references->add_object(data, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::start_certificate_import()
+{
+    EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+     EAP_TRACE_DEBUG(
+         m_am_tools,
+         TRACE_FLAGS_DEFAULT,
+         (EAPL("WAPI_Core: this = 0x%08x, %s: ec_certificate_store_c::start_certificate_import():\n"),
+          this,
+          (m_is_client == true ? "client": "server")));
+
+     EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::start_certificate_import()");
+
+     eap_status_e status(eap_status_not_supported);
+
+	if (m_pending_operation != ec_cs_pending_operation_none)
+	{
+		// Some operation is already pending. Try again later.
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_device_busy);
+	}
+
+#if defined(WAPI_USE_CERTIFICATE_STORE)
+
+	m_complete_start_certificate_import = true;
+
+	status = initialize_certificate_store();
+
+#endif //#if defined(WAPI_USE_CERTIFICATE_STORE)
+
+     EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+     return EAP_STATUS_RETURN(m_am_tools, status);
+   
+}
+
+//------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT void ec_certificate_store_c::set_pending_operation(const ec_cs_pending_operation_e operation)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: ec_certificate_store_c::set_pending_operation(): %s => %s\n"),
+		ec_cs_strings_c::get_ec_cs_store_data_string(m_pending_operation),
+		ec_cs_strings_c::get_ec_cs_store_data_string(operation)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::set_pending_operation()");
+
+
+	m_pending_operation = operation;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::are_pending_queries_completed()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = eap_status_pending_request;
+
+	eap_status_string_c status_string;
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: pending_function: starts: ec_certificate_store_c::are_pending_queries_completed(): %s\n"),
+		status_string.get_status_string(status)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::are_pending_queries_completed()");
+
+	if (m_pending_read_ec_cs_data == false)
+	{
+		status = eap_status_ok;
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: pending_function: are_pending_queries_completed(): %s\n"),
+		status_string.get_status_string(status)));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::completion_action_pop()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI EC CS DB: ec_certificate_store_c::completion_action_pop()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_pop()");
+
+	const ec_cs_completion_c * const removed_completion_action = m_completion_queue.get_object(0ul);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: encrypt_function: starts: ec_certificate_store_c::completion_action_pop(): removes action[%d] %s=%d\n"),
+		0ul,
+		removed_completion_action->get_completion_action_string(removed_completion_action->get_completion_action()),
+		removed_completion_action->get_completion_action()));
+
+	eap_status_e remove_status = m_completion_queue.remove_object(0ul);
+	if (remove_status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, remove_status);
+	}
+
+	completion_action_trace();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, remove_status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::completion_action_push(
+	ec_cs_completion_e action)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI EC CS DB: ec_certificate_store_c::completion_action_push()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_push()");
+
+	ec_cs_completion_c *completion_action = new ec_cs_completion_c(
+		m_am_tools,
+		action);
+
+	if (completion_action == 0
+		|| completion_action->get_is_valid() == false)
+	{
+		delete completion_action;
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	// add_object_to_begin() will delete completion_action if operation fails.
+	eap_status_e status = m_completion_queue.add_object_to_begin(completion_action, true);
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI EC CS DB: send_function: completion_action_push(): action %s\n"),
+					 completion_action->get_completion_action_string(completion_action->get_completion_action())));
+
+	completion_action_trace();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::completion_action_add(
+	ec_cs_completion_e action)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI EC CS DB: ec_certificate_store_c::completion_action_add()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_add()");
+
+	ec_cs_completion_c *completion_action = new ec_cs_completion_c(
+		m_am_tools,
+		action);
+
+	if (completion_action == 0
+		|| completion_action->get_is_valid() == false)
+	{
+		delete completion_action;
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	// add_object() will delete completion_action if operation fails.
+	eap_status_e status = m_completion_queue.add_object(completion_action, true);
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI EC CS DB: send_function: completion_action_add(): action %s\n"),
+					 completion_action->get_completion_action_string(completion_action->get_completion_action())));
+
+	completion_action_trace();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::completion_action_clenup()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI EC CS DB: ec_certificate_store_c::completion_action_clenup()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_clenup()");
+
+	eap_status_e final_status = eap_status_ok;
+	u32_t counter = 0ul;
+
+	while(m_completion_queue.get_object_count() > 0ul)
+	{
+		ec_cs_completion_c * const completion_action = m_completion_queue.get_object(0ul);
+		EAP_UNREFERENCED_PARAMETER(completion_action); // Not referenced without trace.
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ERROR: WAPI EC CS DB: send_function: completion_action_clenup(): ")
+			 EAPL("action[%u] %s not completed.\n"),
+			 counter,
+			 completion_action->get_completion_action_string(completion_action->get_completion_action())));
+
+		final_status = m_completion_queue.remove_object(0ul);
+		if (final_status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, final_status);
+		}
+
+		++counter;
+
+	} // while()
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, final_status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void ec_certificate_store_c::completion_action_trace()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI EC CS DB: ec_certificate_store_c::completion_action_trace()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_trace()");
+
+	for (u32_t trace_ind = 0ul; trace_ind < m_completion_queue.get_object_count(); ++trace_ind)
+	{
+		ec_cs_completion_c * const completion_action = m_completion_queue.get_object(trace_ind);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI EC CS DB: send_function: completion_action_trace(): pending action[%d] %s=%d\n"),
+			 trace_ind,
+			 completion_action->get_completion_action_string(completion_action->get_completion_action()),
+			 completion_action->get_completion_action()));
+	} // for()
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e ec_certificate_store_c::add_imported_certificate(
+	const ec_cs_data_type_e certificate_type,
+	const eap_variable_data_c * const in_imported_certificate_wapi_id,
+	const eap_variable_data_c * const in_imported_certificate_file_data,
+	const eap_variable_data_c * const in_imported_certificate_filename,
+	eap_array_c<ec_cs_data_c> * const out_asu_id_list,
+	eap_array_c<ec_cs_data_c> * const out_certificates,
+	ec_cs_variable_data_c * const out_certificate_reference)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
+	EAP_TRACE_DEBUG(
+		m_am_tools, TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: send_function: starts: ec_certificate_store_c::add_imported_certificate()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::add_imported_certificate()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (in_imported_certificate_filename->get_is_valid_data() == true)
+	{
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("filename"),
+			 in_imported_certificate_filename->get_data(),
+			 in_imported_certificate_filename->get_data_length()));
+	}
+
+	if (in_imported_certificate_file_data->get_is_valid_data() == false
+		|| in_imported_certificate_file_data->get_data_length() == 0ul)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
+	}
+
+	// First check this is unique certificate.
+
+	ec_cs_compare_reference_id_c compare_reference_id(m_am_tools);
+
+	ec_cs_data_c search_id(m_am_tools);
+
+	status = search_id.get_writable_data()->set_buffer(
+		in_imported_certificate_wapi_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: CERTIFICATE SELECTION: this = 0x%08x, %s: ec_certificate_store_c::add_imported_certificate(): count of out_certificates = %d.\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 out_asu_id_list->get_object_count()));
+
+	// Search certificate with the issuer ID from CA-certificates.
+	i32_t index = find_with_compare<ec_cs_data_c>(
+		&compare_reference_id,
+		out_asu_id_list,
+		&search_id,
+		m_am_tools);
+
+	if (index >= 0)
+	{
+		// Match, do not add a copy.
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WARNING: WAPI_Core: CERTIFICATE IMPORT: this = 0x%08x, %s: ec_certificate_store_c::add_imported_certificate(): Certificate alredy installed.\n"),
+			 this,
+			 (m_is_client == true ? "client": "server")));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_already_exists);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	ec_cs_data_type_e id_reference_type(ec_cs_data_type_none);
+
+	if (certificate_type == ec_cs_data_type_ca_certificate_data)
+	{
+		id_reference_type = ec_cs_data_type_ca_asu_id;
+	}
+	else if (certificate_type == ec_cs_data_type_client_certificate_data)
+	{
+		id_reference_type = ec_cs_data_type_client_asu_id;
+	}
+	else
+	{
+		EAP_ASSERT_ANYWAY_TOOLS(m_am_tools);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	ec_cs_data_c certificate_reference(m_am_tools);
+	if (certificate_reference.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	{
+		status = create_unique_reference(&certificate_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		certificate_reference.set_type(ec_cs_data_type_certificate_reference);
+
+		status = out_certificate_reference->set_copy_of_buffer(
+			ec_cs_tlv_type_CS_certificate_reference,
+			certificate_reference.get_reference()->get_data(),
+			certificate_reference.get_reference()->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("out_certificate_reference"),
+			 out_certificate_reference->get_full_tlv_buffer()->get_data(),
+			 out_certificate_reference->get_full_tlv_buffer()->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+		ec_cs_variable_data_c * const id_reference = new ec_cs_variable_data_c(m_am_tools);
+
+		eap_automatic_variable_c<ec_cs_variable_data_c> automatic_id_reference(m_am_tools, id_reference);
+
+		if (id_reference == 0
+			|| id_reference->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = id_reference->init_header(
+			ec_cs_tlv_type_CS_ID_reference,
+			0ul);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		{
+			ec_cs_variable_data_c asu_id(m_am_tools);
+
+			if (asu_id.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = asu_id.set_copy_of_buffer(
+				ec_cs_tlv_type_CS_ASU_ID,
+				in_imported_certificate_wapi_id->get_data(),
+				in_imported_certificate_wapi_id->get_data_length());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = id_reference->add_data(&asu_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EC_CS_TLV_TRACE_PAYLOAD("add_imported_certificate()", id_reference->get_header(), m_is_client);
+		}
+
+		{
+			status = id_reference->add_data(out_certificate_reference);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EC_CS_TLV_TRACE_PAYLOAD("add_imported_certificate()", id_reference->get_header(), m_is_client);
+		}
+
+		ec_cs_data_c reference_data(m_am_tools);
+
+		status = reference_data.get_writable_data()->set_copy_of_buffer(id_reference->get_full_tlv_buffer());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = reference_data.get_writable_reference()->set_copy_of_buffer(certificate_reference.get_reference());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		reference_data.set_type(id_reference_type);
+
+		{
+			eap_variable_data_c id_reference_MAC_key(m_am_tools);
+			if (id_reference_MAC_key.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			ec_cs_tlv_c pac_tlv_handler(m_am_tools, true);
+			if (pac_tlv_handler.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = pac_tlv_handler.generate_data_key(
+				false,
+				id_reference_type,
+				&id_reference_MAC_key,
+				&m_PAC_store_master_key,
+				certificate_reference.get_reference(),
+				&m_PAC_store_device_seed);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = pac_tlv_handler.create_data_with_MAC(
+				&id_reference_MAC_key,
+				id_reference->get_full_tlv_buffer(),
+				reference_data.get_writable_data());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("New reference data"),
+				 reference_data.get_data()->get_data(),
+				 reference_data.get_data()->get_data_length()));
+		}
+
+		reference_data.set_change_status(ec_cs_data_change_status_new);
+
+		status = out_asu_id_list->add_object(reference_data.copy(), true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+		eap_variable_data_c certificate(m_am_tools);
+
+		if (certificate.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		ec_cs_tlv_c handler(m_am_tools, true);
+		if (handler.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = handler.create_encrypted_certificate(
+			certificate_type,
+			&m_PAC_store_master_key,
+			certificate_reference.get_reference(),
+			&m_PAC_store_device_seed,
+			certificate_reference.get_reference(),
+			ec_cs_tlv_type_CS_certificate_data,
+			in_imported_certificate_file_data,
+			&certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		ec_cs_data_c certificate_data(m_am_tools);
+
+		status = certificate_data.get_writable_data()->set_copy_of_buffer(&certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = certificate_data.get_writable_reference()->set_copy_of_buffer(certificate_reference.get_reference());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		certificate_data.set_type(certificate_type);
+
+		certificate_data.set_change_status(ec_cs_data_change_status_new);
+
+		status = out_certificates->add_object(certificate_data.copy(), true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e ec_certificate_store_c::add_imported_private_key(
+	const ec_cs_data_type_e private_key_type,
+	const eap_variable_data_c * const in_imported_private_key_file_data,
+	const eap_variable_data_c * const in_imported_private_key_filename,
+	const ec_cs_variable_data_c * const in_certificate_reference,
+	eap_array_c<ec_cs_data_c> * const out_private_keys)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
+	EAP_TRACE_DEBUG(
+		m_am_tools, TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: send_function: starts: ec_certificate_store_c::add_imported_private_key()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::add_imported_private_key()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	ec_cs_data_c certificate_reference(m_am_tools);
+	if (certificate_reference.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	{
+		status = certificate_reference.get_writable_reference()->set_copy_of_buffer(
+			in_certificate_reference->get_data(in_certificate_reference->get_data_length()),
+			in_certificate_reference->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	{
+		eap_variable_data_c private_key(m_am_tools);
+
+		if (private_key.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		ec_cs_tlv_c handler(m_am_tools, true);
+		if (handler.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = handler.create_encrypted_certificate(
+			private_key_type,
+			&m_PAC_store_master_key,
+			certificate_reference.get_reference(),
+			&m_PAC_store_device_seed,
+			certificate_reference.get_reference(),
+			ec_cs_tlv_type_CS_private_key_data,
+			in_imported_private_key_file_data,
+			&private_key);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		ec_cs_data_c private_key_data(m_am_tools);
+
+		status = private_key_data.get_writable_data()->set_copy_of_buffer(&private_key);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = private_key_data.get_writable_reference()->set_copy_of_buffer(certificate_reference.get_reference());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		private_key_data.set_type(private_key_type);
+
+		private_key_data.set_change_status(ec_cs_data_change_status_new);
+
+		status = out_private_keys->add_object(private_key_data.copy(), true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::completion_action_check()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("\n")));
+	EAP_TRACE_DEBUG(
+		m_am_tools, TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: send_function: starts: ec_certificate_store_c::completion_action_check()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::completion_action_check()");
+
+	if (m_already_in_completion_action_check == true)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		// This is recursive call of completion_action_check().
+		// This MUST return eap_status_ok. Other return values will skip
+		// further prosessing of completion action list.
+		EAP_TRACE_DEBUG(
+			m_am_tools, TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI EC CS DB: send_function: completion_action_check(): skip recursion\n")));
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	m_already_in_completion_action_check = true;
+
+	eap_automatic_simple_value_c<bool> restore_already_in_completion_action_check(
+		m_am_tools,
+		&m_already_in_completion_action_check,
+		false);
+
+
+	eap_status_e status = are_pending_queries_completed();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI_Core: are_pending_queries_completed(): still pending\n")));
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	bool continue_with_next_action = true;
+	u32_t counter = 0ul;
+
+	completion_action_trace();
+
+	while(continue_with_next_action == true
+		&& m_completion_queue.get_object_count() > 0ul)
+	{
+		status = eap_status_ok;
+
+		ec_cs_completion_c * const completion_action = m_completion_queue.get_object(0ul);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI EC CS DB: send_function: completion_action_check(): action[%d] %s=%d\n"),
+			 counter,
+			 completion_action->get_completion_action_string(completion_action->get_completion_action()),
+			 completion_action->get_completion_action()));
+
+		ec_cs_completion_e current_action = completion_action->get_completion_action();
+
+		// This will remove the current completion action.
+		status = completion_action_pop();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		switch(current_action)
+		{
+		case ec_cs_completion_none:
+			break;
+		case ec_cs_completion_complete_add_imported_certificate_file:
+			{
+				set_pending_operation(ec_cs_pending_operation_none);
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls: ec_certificate_store_c::completion_action_check(): m_am_pac_store_services->complete_add_imported_certificate_file(): %d.\n"),
+					__LINE__));
+
+				status = m_am_certificate_store->complete_add_imported_certificate_file(
+					m_ec_cs_completion_status,
+					&m_imported_certificate_filename);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+			break;
+		case ec_cs_completion_add_imported_ca_certificate:
+			{
+				set_pending_operation(ec_cs_pending_operation_none);
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls: ec_certificate_store_c::completion_action_check(): add_imported_ca_certificate_file(): %d.\n"),
+					__LINE__));
+
+				ec_cs_variable_data_c certificate_reference(m_am_tools);
+				if (certificate_reference.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				status = add_imported_certificate(
+					ec_cs_data_type_ca_certificate_data,
+					&m_imported_certificate_wapi_id,
+					&m_imported_certificate_data,
+					&m_imported_certificate_filename,
+					&m_ca_asu_id_list,
+					&m_ca_certificates,
+					&certificate_reference);
+
+				m_ec_cs_completion_status = status;
+
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools,
+						TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+						(EAPL("ERROR: ec_certificate_store_c::completion_action_check(): add_imported_ca_certificate_file(): Failed status = %d.\n"),
+						status));
+					status = eap_status_ok;
+				}
+			}
+			break;
+		case ec_cs_completion_add_imported_client_certificate:
+			{
+				set_pending_operation(ec_cs_pending_operation_none);
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls: ec_certificate_store_c::completion_action_check(): add_imported_ca_certificate_file(): %d.\n"),
+					__LINE__));
+
+				ec_cs_variable_data_c certificate_reference(m_am_tools);
+				if (certificate_reference.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				status = add_imported_certificate(
+					ec_cs_data_type_client_certificate_data,
+					&m_imported_certificate_wapi_id,
+					&m_imported_certificate_data,
+					&m_imported_certificate_filename,
+					&m_client_asu_id_list,
+					&m_client_certificates,
+					&certificate_reference);
+
+				m_ec_cs_completion_status = status;
+
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools,
+						TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+						(EAPL("ERROR: ec_certificate_store_c::completion_action_check(): add_imported_certificate(): Failed status = %d.\n"),
+						status));
+					status = eap_status_ok;
+				}
+				else 
+				{
+					status = add_imported_private_key(
+						ec_cs_data_type_private_key_data,
+						&m_imported_private_key_data,
+						&m_imported_certificate_filename,
+						&certificate_reference,
+						&m_client_private_keys);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_DEBUG(
+							m_am_tools,
+							TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+							(EAPL("ERROR: ec_certificate_store_c::completion_action_check(): add_imported_private_key(): Failed status = %d.\n"),
+							status));
+						status = eap_status_ok;
+					}
+				}
+			}
+			break;
+		case ec_cs_completion_internal_select_certificate:
+			{
+				set_pending_operation(ec_cs_pending_operation_none);
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls: ec_certificate_store_c::completion_action_check(): internal_select_certificate(): %d.\n"),
+					__LINE__));
+
+				status = internal_select_certificate();
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+			break;
+		case ec_cs_completion_internal_select_certificate_with_identity:
+			{
+				set_pending_operation(ec_cs_pending_operation_none);
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls: ec_certificate_store_c::completion_action_check(): internal_select_certificate_with_identity(): %d.\n"),
+					__LINE__));
+
+				status = internal_select_certificate_with_identity(&m_selected_client_id);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+			break;
+		case ec_cs_completion_internal_create_signature_with_private_key:
+			{
+				set_pending_operation(ec_cs_pending_operation_none);
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls: ec_certificate_store_c::completion_action_check(): internal_create_signature_with_private_key(): %d.\n"),
+					__LINE__));
+
+				status = internal_create_signature_with_private_key();
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+			break;
+		case ec_cs_completion_complete_query_certificate_list:
+			{
+				set_pending_operation(ec_cs_pending_operation_none);
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls: ec_certificate_store_c::completion_action_check(): complete_query_certificate_list(): %d.\n"),
+					__LINE__));
+
+				eap_array_c<eap_variable_data_c> ca_certificates_identities(m_am_tools);
+				eap_array_c<eap_variable_data_c> user_certificates_identities(m_am_tools);
+
+				status = copy_certificate_wapi_identities(
+					&m_ca_asu_id_list,
+					&ca_certificates_identities);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = copy_certificate_wapi_identities(
+					&m_client_asu_id_list,
+					&user_certificates_identities);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = m_am_certificate_store->complete_query_certificate_list(
+					&ca_certificates_identities,
+					&user_certificates_identities);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+			break;
+
+		case ec_cs_completion_internal_verify_signature_with_public_key:
+			{
+				set_pending_operation(ec_cs_pending_operation_none);
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls: ec_certificate_store_c::completion_action_check(): verify_signature_with_public_key(): %d.\n"),
+					__LINE__));
+
+				status = verify_signature_with_public_key(
+					&m_peer_identity,
+					&m_hash_of_message,
+					&m_signature,
+					m_allow_use_of_ae_certificate);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+			break;
+
+		case ec_cs_completion_internal_complete_add_imported_certificate_file:
+			{
+				set_pending_operation(ec_cs_pending_operation_none);
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls: ec_certificate_store_c::completion_action_check(): internal_complete_add_imported_certificate_file(): %d.\n"),
+					__LINE__));
+
+				status = internal_complete_add_imported_certificate_file();
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+			break;
+
+		case ec_cs_completion_query_PAC_store_password:
+			{
+				set_pending_operation(ec_cs_pending_operation_none);
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls: ec_certificate_store_c::completion_action_check(): query_PAC_store_password(): %d.\n"),
+					__LINE__));
+
+				status = query_PAC_store_password(m_pending_operation);
+				if (status == eap_status_pending_request)
+				{
+					// Cannot continue yet.
+					continue_with_next_action = false;
+				}
+			}
+			break;
+
+		default:
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("EROR: WAPI EC CS DB: send_function: completion_action_check(): unknown action[%d] %s=%d\n"),
+					 counter,
+					 ec_cs_completion_c::get_completion_action_string(current_action),
+					 current_action));
+			}
+			break;
+		} // switch()
+
+		if (status == eap_status_user_cancel_authentication)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		++counter;
+
+	} // while()
+
+	if (continue_with_next_action == false)
+	{
+		status = eap_status_pending_request;
+	}
+
+	completion_action_trace();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::timer_expired(
+	const u32_t id,
+	void * data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: ec_certificate_store_c::timer_expired(): id = %d, data = 0x%08x.\n"),
+		id,
+		data));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::timer_expired()");
+
+	switch (id)
+	{
+	case WAPI_CS_KEY_TIMER_ID:
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_CS_KEY_TIMER_ID elapsed\n")));
+
+			m_PAC_store_password.reset();
+			m_PAC_store_device_seed.reset();
+			m_PAC_store_master_key.reset();
+		}
+		break;
+	
+	default:
+		break;
+	}
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::timer_delete_data(
+	const u32_t id,
+	void *data)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: ec_certificate_store_c::timer_delete_data(): id = %d, data = 0x%08x.\n"),
+		id,
+		data));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_certificate_store_c::timer_delete_data()");
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+void ec_certificate_store_c::send_error_notification(const eap_status_e error)
+{
+	// Notifies the lower level of an authentication error.
+
+	eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error);
+
+	if (error == eap_status_user_cancel_authentication)
+	{
+		general_state_variable = eap_general_state_authentication_cancelled;
+	}
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(m_am_tools,
+		m_receive_network_id.get_destination_id(),
+		m_receive_network_id.get_source_id(),
+		m_receive_network_id.get_type());
+
+	eap_state_notification_c notification(
+		m_am_tools,
+		&send_network_id,
+		true,
+		eap_state_notification_eap,
+		eap_protocol_layer_general,
+		eap_type_none,
+		eap_state_none,
+		general_state_variable,
+		0,
+		false);
+
+	notification.set_authentication_error(error);
+
+	m_partner->state_notification(&notification);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_certificate_store_c::set_receive_network_id(const eap_am_network_id_c * const receive_network_id)
+{
+	return m_receive_network_id.set_copy_of_network_id(receive_network_id);
+}
+
+//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_base_certificate_store_c * ec_base_certificate_store_c::new_ec_base_certificate_store_c(
+	abs_eap_am_tools_c * const tools,
+	abs_ec_certificate_store_c * const partner,
+	ec_am_base_certificate_store_c * const am_certificate_store,
+	const bool is_client_when_true)
+{
+	ec_base_certificate_store_c * store = new ec_certificate_store_c(
+		tools,
+		partner,
+		am_certificate_store,
+		is_client_when_true);
+
+	if (store == 0)
+	{
+		return 0;
+	}
+
+	eap_status_e status(store->configure());
+
+	if (status != eap_status_ok)
+	{
+		delete store;
+		return 0;
+	}
+
+	return store;
+}
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_compare_certificate_id.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,174 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_compare_certificate_id.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 7 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 700 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+#include "ec_cs_compare_certificate_id.h"
+#include "wapi_certificate_asn1_der_parser.h"
+#include "wapi_asn1_der_parser.h"
+#include "ec_cs_tlv_header.h"
+#include "ec_cs_tlv_payloads.h"
+#include "ec_cs_tlv.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_certificate_id_c::~ec_cs_compare_certificate_id_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_certificate_id_c::ec_cs_compare_certificate_id_c(
+	abs_eap_am_tools_c * const tools,
+	const eap_variable_data_c * const PAC_store_master_key,
+	const eap_variable_data_c * const PAC_store_device_seed)
+	: m_am_tools(tools)
+	, m_PAC_store_master_key(PAC_store_master_key)
+	, m_PAC_store_device_seed(PAC_store_device_seed)
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT i32_t ec_cs_compare_certificate_id_c::compare(
+	const ec_cs_data_c * const certificate_from_array,
+	const ec_cs_data_c * const certificate_identity) const
+{
+	// certificate_from_array includes data of Certificate Data which include full certificate in ASN.1/DER encoded and certificate reference.
+	// certificate_identity includes identity of certificate. Data is concatenation of subject name, issuer name and serial number, each ASN.1/DER encoded.
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_certificate_id_c::compare(): certificate_from_array"),
+		 certificate_from_array->get_data()->get_data(),
+		 certificate_from_array->get_data()->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_certificate_id_c::compare(): certificate_identity"),
+		 certificate_identity->get_data()->get_data(),
+		 certificate_identity->get_data()->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c certificate_id(m_am_tools);
+	if (certificate_id.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	{
+		ec_cs_tlv_c handler(m_am_tools, true);
+		if (handler.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_variable_data_c certificate_reference(m_am_tools);
+		if (certificate_reference.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_status_e status = handler.parse_encrypted_certificate(
+			certificate_from_array->get_type(),
+			m_PAC_store_master_key,
+			certificate_from_array->get_reference(),
+			m_PAC_store_device_seed,
+			certificate_from_array->get_data(),
+			&certificate_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		const ec_cs_variable_data_c * const certificate_data_tlv = handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_certificate_data);
+		if (certificate_data_tlv == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		{
+			wapi_certificate_asn1_der_parser_c parser(m_am_tools);
+			if (parser.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_variable_data_c id_data(
+				m_am_tools,
+				certificate_data_tlv->get_data(certificate_data_tlv->get_data_length()),
+				certificate_data_tlv->get_data_length(),
+				false,
+				false);
+			if (id_data.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_status_e status = parser.decode(&id_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = parser.read_certificate_id(
+				&certificate_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	return certificate_id.compare(certificate_identity->get_data());
+}
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_compare_certificate_issuer_name.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,179 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_compare_certificate_issuer_name.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 7 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 700 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+#include "ec_cs_compare_certificate_issuer_name.h"
+#include "wapi_certificate_asn1_der_parser.h"
+#include "wapi_asn1_der_parser.h"
+#include "ec_cs_tlv_header.h"
+#include "ec_cs_tlv_payloads.h"
+#include "ec_cs_tlv.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_certificate_issuer_name_c::~ec_cs_compare_certificate_issuer_name_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_certificate_issuer_name_c::ec_cs_compare_certificate_issuer_name_c(
+	abs_eap_am_tools_c * const tools,
+	const eap_variable_data_c * const PAC_store_master_key,
+	const eap_variable_data_c * const PAC_store_device_seed)
+	: m_am_tools(tools)
+	, m_PAC_store_master_key(PAC_store_master_key)
+	, m_PAC_store_device_seed(PAC_store_device_seed)
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT i32_t ec_cs_compare_certificate_issuer_name_c::compare(
+	const ec_cs_data_c * const certificate_from_array,
+	const ec_cs_data_c * const issuer_name) const
+{
+	// certificate_from_array includes data of Certificate Data which include full certificate in ASN.1/DER encoded and certificate reference.
+	// issuer_name includes issuer name ASN.1/DER encoded.
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_certificate_issuer_name_c::compare(): certificate_from_array"),
+		 certificate_from_array->get_data()->get_data(),
+		 certificate_from_array->get_data()->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_certificate_issuer_name_c::compare(): issuer_name"),
+		 issuer_name->get_data()->get_data(),
+		 issuer_name->get_data()->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c certificate_issuer_name(m_am_tools);
+	if (certificate_issuer_name.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	{
+		ec_cs_tlv_c handler(m_am_tools, true);
+		if (handler.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_variable_data_c certificate_reference(m_am_tools);
+		if (certificate_reference.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_status_e status = handler.parse_encrypted_certificate(
+			certificate_from_array->get_type(),
+			m_PAC_store_master_key,
+			certificate_from_array->get_reference(),
+			m_PAC_store_device_seed,
+			certificate_from_array->get_data(),
+			&certificate_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		const ec_cs_variable_data_c * const certificate_data_tlv = handler.get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_certificate_data);
+		if (certificate_data_tlv == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		{
+			wapi_certificate_asn1_der_parser_c parser(m_am_tools);
+			if (parser.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_variable_data_c id_data(
+				m_am_tools,
+				certificate_data_tlv->get_data(certificate_data_tlv->get_data_length()),
+				certificate_data_tlv->get_data_length(),
+				false,
+				false);
+			if (id_data.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_status_e status = parser.decode(&id_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			eap_variable_data_c certificate_subject_name(m_am_tools);
+			eap_variable_data_c certificate_sequence_number(m_am_tools);
+
+			status = parser.read_certificate_id(
+				&certificate_subject_name,
+				&certificate_issuer_name,
+				&certificate_sequence_number);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	return certificate_issuer_name.compare(issuer_name->get_data());
+}
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_compare_certificate_reference.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,130 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_compare_certificate_reference.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 7 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 700 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+#include "ec_cs_compare_certificate_reference.h"
+#include "wapi_certificate_asn1_der_parser.h"
+#include "wapi_asn1_der_parser.h"
+#include "ec_cs_tlv_header.h"
+#include "ec_cs_tlv_payloads.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_certificate_reference_c::~ec_cs_compare_certificate_reference_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_certificate_reference_c::ec_cs_compare_certificate_reference_c(
+	abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT i32_t ec_cs_compare_certificate_reference_c::compare(
+	const ec_cs_data_c * const certificate_from_array,
+	const ec_cs_data_c * const certificate_reference) const
+{
+	// certificate_from_array includes data of Certificate Data which include full certificate in ASN.1/DER encoded and Certificate-Reference TLV.
+	// certificate_reference includes Certificate-Reference TLV.
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_certificate_reference_c::compare(): certificate_from_array"),
+		 certificate_from_array->get_data()->get_data(),
+		 certificate_from_array->get_data()->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_certificate_reference_c::compare(): certificate_reference"),
+		 certificate_reference->get_data()->get_data(),
+		 certificate_reference->get_data()->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c certificate_issuer_name(m_am_tools);
+	if (certificate_issuer_name.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	{
+		ec_cs_tlv_payloads_c parser(
+			m_am_tools,
+			true);
+		if (parser.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t length(certificate_from_array->get_data()->get_data_length());
+		u32_t padding_length(0ul);
+
+		eap_status_e status = parser.parse_ec_cs_payloads(
+			certificate_from_array->get_data()->get_data(), ///< This is the start of the message buffer.
+			&length, ///< This is the length of the buffer. This must match with the length of all payloads.
+			&padding_length ///< Length of possible padding is set to this variable.
+			);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		const ec_cs_variable_data_c * const reference = parser.get_tlv_pointer(ec_cs_tlv_type_CS_certificate_reference);
+		if (reference == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		return reference->get_full_tlv_buffer()->compare(certificate_reference->get_data());
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+}
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_compare_reference.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,134 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_compare_reference_id.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 2 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 700 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+#include "ec_cs_compare_reference.h"
+#include "wapi_certificate_asn1_der_parser.h"
+#include "wapi_asn1_der_parser.h"
+#include "ec_cs_tlv_header.h"
+#include "ec_cs_tlv_payloads.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_reference_c::~ec_cs_compare_reference_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_reference_c::ec_cs_compare_reference_c(
+	abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT i32_t ec_cs_compare_reference_c::compare(
+	const ec_cs_data_c * const reference_tlv_from_array,
+	const ec_cs_data_c * const reference) const
+{
+	// reference_tlv_from_array includes ID-Reference TLV which includes ASU-ID TLV and Certificate-reference TLV.
+	// reference includes identity of certificate. Data is concatenation of subject name, issuer name and serial number, each ASN.1/DER encoded.
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_reference_c::compare(): reference_tlv_from_array"),
+		 reference_tlv_from_array->get_data()->get_data(),
+		 reference_tlv_from_array->get_data()->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_reference_c::compare(): reference"),
+		 reference->get_data()->get_data(),
+		 reference->get_data()->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	ec_cs_tlv_header_c id_reference_tlv(
+		m_am_tools,
+		reference_tlv_from_array->get_data()->get_data(),
+		reference_tlv_from_array->get_data()->get_data_length());
+	if (id_reference_tlv.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+
+	{
+		ec_cs_tlv_payloads_c parser(
+			m_am_tools,
+			true);
+		if (parser.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t length(id_reference_tlv.get_data_length());
+		u32_t padding_length(0ul);
+
+		eap_status_e status = parser.parse_ec_cs_payloads(
+			id_reference_tlv.get_data(length), ///< This is the start of the message buffer.
+			&length, ///< This is the length of the buffer. This must match with the length of all payloads.
+			&padding_length ///< Length of possible padding is set to this variable.
+			);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		const ec_cs_variable_data_c * const asu_id = parser.get_tlv_pointer(ec_cs_tlv_type_CS_certificate_reference);
+		if (asu_id == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		return reference->get_data()->compare(asu_id->get_data(asu_id->get_data_length()), asu_id->get_data_length());
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+}
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_compare_reference_id.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,176 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_compare_reference_id.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 6 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 700 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+#include "ec_cs_compare_reference_id.h"
+#include "wapi_certificate_asn1_der_parser.h"
+#include "wapi_asn1_der_parser.h"
+#include "ec_cs_tlv_header.h"
+#include "ec_cs_tlv_payloads.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_reference_id_c::~ec_cs_compare_reference_id_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_reference_id_c::ec_cs_compare_reference_id_c(
+	abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT i32_t ec_cs_compare_reference_id_c::compare(
+	const ec_cs_data_c * const reference_tlv_from_array,
+	const ec_cs_data_c * const certificate_identity) const
+{
+	// reference_tlv_from_array includes ID-Reference TLV which includes ASU-ID TLV and Certificate-reference TLV.
+	// certificate_identity includes identity of certificate. Data is concatenation of subject name, issuer name and serial number, each ASN.1/DER encoded.
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_reference_id_c::compare(): reference_tlv_from_array"),
+		 reference_tlv_from_array->get_data()->get_data(),
+		 reference_tlv_from_array->get_data()->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_reference_id_c::compare(): certificate_identity"),
+		 certificate_identity->get_data()->get_data(),
+		 certificate_identity->get_data()->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c certificate_id(m_am_tools);
+	if (certificate_id.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	ec_cs_tlv_header_c id_reference_tlv(
+		m_am_tools,
+		reference_tlv_from_array->get_data()->get_data(),
+		reference_tlv_from_array->get_data()->get_data_length());
+	if (id_reference_tlv.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+
+	{
+		ec_cs_tlv_payloads_c parser(
+			m_am_tools,
+			true);
+		if (parser.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t length(id_reference_tlv.get_data_length());
+		u32_t padding_length(0ul);
+
+		eap_status_e status = parser.parse_ec_cs_payloads(
+			id_reference_tlv.get_data(length), ///< This is the start of the message buffer.
+			&length, ///< This is the length of the buffer. This must match with the length of all payloads.
+			&padding_length ///< Length of possible padding is set to this variable.
+			);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		const ec_cs_variable_data_c * const asu_id = parser.get_tlv_pointer(ec_cs_tlv_type_CS_ASU_ID);
+		if (asu_id == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		{
+			wapi_asn1_der_parser_c parser(m_am_tools);
+			if (parser.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_variable_data_c id_data(
+				m_am_tools,
+				asu_id->get_data(asu_id->get_data_length()),
+				asu_id->get_data_length(),
+				false,
+				false);
+			if (id_data.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_status_e status = parser.decode(&id_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = parser.get_wapi_identity(
+				&certificate_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	return certificate_id.compare(certificate_identity->get_data());
+}
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_compare_reference_issuer_name.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,181 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_compare_reference_issuer_name.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 5 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 700 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+#include "ec_cs_compare_reference_issuer_name.h"
+#include "wapi_certificate_asn1_der_parser.h"
+#include "wapi_asn1_der_parser.h"
+#include "ec_cs_tlv_header.h"
+#include "ec_cs_tlv_payloads.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_reference_issuer_name_c::~ec_cs_compare_reference_issuer_name_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_compare_reference_issuer_name_c::ec_cs_compare_reference_issuer_name_c(
+	abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT i32_t ec_cs_compare_reference_issuer_name_c::compare(
+	const ec_cs_data_c * const reference_tlv_from_array,
+	const ec_cs_data_c * const in_issuer_name) const
+{
+	// reference_tlv_from_array includes ID-Reference TLV which includes ASU-ID TLV and Certificate-reference TLV.
+	// certificate_identity includes issuer name of certificate in ASN.1/DER encoded.
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_reference_issuer_name_c::compare(): reference_tlv_from_array"),
+		 reference_tlv_from_array->get_data()->get_data(),
+		 reference_tlv_from_array->get_data()->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("ec_cs_compare_reference_issuer_name_c::compare(): in_issuer_name"),
+		 in_issuer_name->get_data()->get_data(),
+		 in_issuer_name->get_data()->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c reference_issuer_name(m_am_tools);
+	if (reference_issuer_name.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	ec_cs_tlv_header_c id_reference_tlv(
+		m_am_tools,
+		reference_tlv_from_array->get_data()->get_data(),
+		reference_tlv_from_array->get_data()->get_data_length());
+	if (id_reference_tlv.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+
+	{
+		ec_cs_tlv_payloads_c parser(
+			m_am_tools,
+			true);
+		if (parser.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t length(id_reference_tlv.get_data_length());
+		u32_t padding_length(0ul);
+
+		eap_status_e status = parser.parse_ec_cs_payloads(
+			id_reference_tlv.get_data(length), ///< This is the start of the message buffer.
+			&length, ///< This is the length of the buffer. This must match with the length of all payloads.
+			&padding_length ///< Length of possible padding is set to this variable.
+			);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		const ec_cs_variable_data_c * const asu_id = parser.get_tlv_pointer(ec_cs_tlv_type_CS_ASU_ID);
+		if (asu_id == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		{
+			wapi_asn1_der_parser_c parser(m_am_tools);
+			if (parser.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_variable_data_c id_data(
+				m_am_tools,
+				asu_id->get_data(asu_id->get_data_length()),
+				asu_id->get_data_length(),
+				false,
+				false);
+			if (id_data.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_status_e status = parser.decode(&id_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			eap_variable_data_c certificate_subject_name(m_am_tools);
+			eap_variable_data_c certificate_sequence_number(m_am_tools);
+
+			status = parser.get_wapi_identity(
+				&certificate_subject_name,
+				&reference_issuer_name,
+				&certificate_sequence_number);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	return reference_issuer_name.compare(in_issuer_name->get_data());
+}
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_completion.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,128 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_completion.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 10 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 128 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#include "eap_tools.h"
+#include "eap_array.h"
+#include "ec_cs_completion.h"
+
+/** @file */
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_completion_c::~ec_cs_completion_c()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_completion_c::ec_cs_completion_c(
+	abs_eap_am_tools_c * const tools,
+	ec_cs_completion_e completion_action)
+: m_am_tools(tools)
+, m_completion_action(completion_action)
+, m_is_valid(false)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	set_is_valid();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void ec_cs_completion_c::set_is_valid()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	m_is_valid = true;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_cs_completion_c::get_is_valid()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void ec_cs_completion_c::set_completion_action(ec_cs_completion_e completion_action)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	m_completion_action = completion_action;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_completion_e ec_cs_completion_c::get_completion_action() const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_completion_action;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_const_string ec_cs_completion_c::get_completion_action_string(ec_cs_completion_e completion_action)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_none)
+	else EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_internal_select_certificate)
+	else EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_internal_select_certificate_with_identity)
+	else EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_internal_complete_add_imported_certificate_file)
+	else EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_complete_add_imported_certificate_file)
+	else EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_query_PAC_store_password)
+	else EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_add_imported_ca_certificate)
+	else EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_add_imported_client_certificate)
+	else EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_internal_create_signature_with_private_key)
+	else EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_complete_query_certificate_list)
+	else EAP_IF_RETURN_STRING(completion_action, ec_cs_completion_internal_verify_signature_with_public_key)
+	else
+#else
+	EAP_UNREFERENCED_PARAMETER(completion_action);
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		return EAPL("Unknown completion_action");
+	}
+}
+
+//--------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_data.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,264 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_data.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 8 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 701 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+#include "ec_cs_strings.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_data_c::~ec_cs_data_c()
+{
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_data_c::ec_cs_data_c(
+	abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+	, m_change_status(ec_cs_data_change_status_none)
+	, m_type(ec_cs_data_type_none)
+	, m_reference(tools)
+	, m_data(tools)
+	, m_data_references_read(false)
+{
+	eap_status_e status = m_reference.set_copy_of_buffer(
+		EC_CS_ZERO_REFERENCE,
+		sizeof(EC_CS_ZERO_REFERENCE));
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, status);
+		return;
+	}
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_cs_data_c::get_is_valid() const
+{
+	return(m_reference.get_is_valid() && m_data.get_is_valid());
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_cs_data_c::get_is_valid_data() const
+{
+	return(m_reference.get_is_valid_data() && m_data.get_is_valid_data());
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_data_change_status_e ec_cs_data_c::get_change_status() const
+{
+	return m_change_status;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT void ec_cs_data_c::set_change_status(const ec_cs_data_change_status_e change_status)
+{
+	m_change_status = change_status;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_data_type_e ec_cs_data_c::get_type() const
+{
+	return m_type;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT void ec_cs_data_c::set_type(const ec_cs_data_type_e type)
+{
+	m_type = type;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT const eap_variable_data_c * ec_cs_data_c::get_reference() const
+{
+	return &m_reference;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT const eap_variable_data_c * ec_cs_data_c::get_data() const
+{
+	return &m_data;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_variable_data_c * ec_cs_data_c::get_writable_reference()
+{
+	return &m_reference;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_variable_data_c * ec_cs_data_c::get_writable_data()
+{
+	return &m_data;
+}
+
+//----------------------------------------------------------------------------
+
+ec_cs_data_c * ec_cs_data_c::copy() const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	ec_cs_data_c * const data = new ec_cs_data_c(m_am_tools);
+
+	eap_automatic_variable_c<ec_cs_data_c> automatic_data(m_am_tools, data);
+
+	if (data == 0)
+	{
+		return 0;
+	}
+
+	data->set_change_status(get_change_status());
+
+	data->set_type(get_type());
+
+	eap_status_e status = data->get_writable_data()->set_copy_of_buffer(get_data());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, status);
+		return 0;
+	}
+
+	status = data->get_writable_reference()->set_copy_of_buffer(get_reference());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, status);
+		return 0;
+	}
+
+	automatic_data.do_not_free_variable();
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS: ec_cs_data_c::copy(): type %d=%s, change status %d=%s\n"),
+		data->get_type(),
+		ec_cs_strings_c::get_ec_cs_store_data_string(data->get_type()),
+		data->get_change_status(),
+		ec_cs_strings_c::get_ec_cs_store_data_change_status_string(data->get_change_status())));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS: ec_cs_data_c::copy(): reference"),
+		 data->get_reference()->get_data(),
+		 data->get_reference()->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS: ec_cs_data_c::copy(): data"),
+		 data->get_data()->get_data(),
+		 data->get_data()->get_data_length()));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return data;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT i32_t ec_cs_data_c::compare(const ec_cs_data_c * const data) const
+{
+	return get_reference()->compare(data->get_reference());
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_data_c::reset()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	m_change_status = ec_cs_data_change_status_none;
+
+	m_type = ec_cs_data_type_none;
+
+	(void)m_reference.reset();
+
+	(void)m_data.reset();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_data_c::set_copy_of_buffer(const ec_cs_data_c * const source)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	m_change_status = source->get_change_status();
+
+	m_type = source->get_type();
+
+	eap_status_e status = m_reference.set_copy_of_buffer(source->get_reference());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_data.set_copy_of_buffer(source->get_data());
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_cs_data_c::get_data_references_read()
+{
+	return m_data_references_read;
+}
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT void ec_cs_data_c::set_data_references_read()
+{
+	m_data_references_read = true;
+}
+
+//----------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_strings.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,142 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_strings.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 14 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 700 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+#include "ec_cs_strings.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_strings_c::~ec_cs_strings_c()
+{
+}
+
+EAP_FUNC_EXPORT ec_cs_strings_c::ec_cs_strings_c()
+{
+}
+
+EAP_FUNC_EXPORT eap_const_string ec_cs_strings_c::get_ec_cs_store_data_string(const ec_cs_data_type_e type)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(type, ec_cs_data_type_none)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_master_key)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_password)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_device_seed)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_reference_counter)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_certificate_reference)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_certificate_file_password)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_ca_asu_id_list)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_ca_asu_id)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_client_asu_id_list)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_client_asu_id)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_ca_certificate_data)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_client_certificate_data)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_private_key_data)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_selected_ca_id)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_selected_client_id)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_user_authorization_reference)
+	else EAP_IF_RETURN_STRING(type, ec_cs_data_type_user_authorization_data)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(type);
+		return EAPL("Unknown EC CS data type string");
+	}
+}
+
+EAP_FUNC_EXPORT eap_const_string ec_cs_strings_c::get_ec_cs_store_data_change_status_string(const ec_cs_data_change_status_e status)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(status, ec_cs_data_change_status_none)
+	else EAP_IF_RETURN_STRING(status, ec_cs_data_change_status_modified)
+	else EAP_IF_RETURN_STRING(status, ec_cs_data_change_status_new)
+	else EAP_IF_RETURN_STRING(status, ec_cs_data_change_status_delete)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(status);
+		return EAPL("Unknown EC CS data change status string");
+	}
+}
+
+EAP_FUNC_EXPORT eap_const_string ec_cs_strings_c::get_ec_cs_store_data_string(const ec_cs_pending_operation_e type)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(type, ec_cs_pending_operation_none)
+	else EAP_IF_RETURN_STRING(type, ec_cs_pending_operation_certificate_authentication)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(type);
+		return EAPL("Unknown EC CS data change status string");
+	}
+}
+
+/**
+ * Function returns string of ec_cs_tlv_type_e.
+ * @param status is the queried string.
+ */
+EAP_FUNC_EXPORT eap_const_string ec_cs_strings_c::get_ec_cs_tlv_header_string(
+	const ec_cs_tlv_type_e type)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_none)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_Import_File)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_Import_File_Password)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_certificate_data)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_private_key_data)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_ASU_ID)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_ID_reference)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_certificate_reference)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_encrypted_block)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_encryption_IV)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_encrypted_data)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_padding)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_MAC)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_master_key)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_CS_reference_counter)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_first_known)
+	else EAP_IF_RETURN_STRING(type, ec_cs_tlv_type_last_known)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(type);
+		return EAPL("Unknown EC CS TLV header string");
+	}
+}
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_tlv.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,2173 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_tlv.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 19 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 706 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_memory.h"
+#include "eap_crypto_api.h"
+#include "ec_cs_tlv.h"
+#include "eap_automatic_variable.h"
+#include "ec_cs_tlv_payloads.h"
+#include "ec_cs_strings.h"
+#include "ec_cs_data.h"
+
+
+/** @file */
+
+//------------------------------------------------------------------------------
+
+/**
+ * The destructor of the ec_cs_tlv_c class does nothing.
+ */
+ec_cs_tlv_c::~ec_cs_tlv_c()
+{
+	delete m_payloads;
+	m_payloads = 0;
+}
+
+//--------------------------------------------------
+
+/**
+ * The constructor of the ec_cs_tlv_c class simply initializes the attributes.
+ */
+ec_cs_tlv_c::ec_cs_tlv_c(
+	abs_eap_am_tools_c * const tools,
+	const bool true_when_is_client)
+	: m_am_tools(tools)
+	, m_payloads(0)
+	, m_is_client(true_when_is_client)
+	, m_is_valid(true)
+{
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const ec_cs_tlv_payloads_c * ec_cs_tlv_c::get_payloads() const
+{
+	return m_payloads;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_cs_tlv_c::get_is_valid()
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::reset()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::reset()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::reset()");
+
+	if (m_payloads == 0)
+	{
+		m_payloads = new ec_cs_tlv_payloads_c(m_am_tools, m_is_client);
+
+		if (m_payloads == 0
+			|| m_payloads->get_is_valid() == false)
+		{
+			delete m_payloads;
+			m_payloads = 0;
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+		}
+	}
+
+	eap_status_e status = m_payloads->reset();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::generate_data_key(
+	const bool in_true_when_encryption_key,
+	const ec_cs_data_type_e in_data_type,
+	eap_variable_data_c * const out_key,
+	const eap_variable_data_c * const in_base_key,
+	const eap_variable_data_c * const in_data_reference,
+	const eap_variable_data_c * const in_CS_store_device_seed)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS: ec_cs_tlv_c::generate_data_key()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::generate_data_key()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (in_base_key == 0
+		|| in_base_key->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (in_CS_store_device_seed->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (out_key == 0
+		|| out_key->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c label(m_am_tools);
+	if (label.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	if (in_true_when_encryption_key == true)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS: ec_cs_store_c::generate_data_key(): creates encyption key\n")));
+
+		status = label.set_copy_of_buffer(EC_CS_ENCRYPTION_KEY_LABEL, EC_CS_ENCRYPTION_KEY_LABEL_SIZE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS: ec_cs_store_c::generate_data_key(): creates MAC key\n")));
+
+		status = label.set_copy_of_buffer(EC_CS_MAC_KEY_LABEL, EC_CS_MAC_KEY_LABEL_SIZE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c seed(m_am_tools);
+	if (seed.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = seed.set_copy_of_buffer(in_CS_store_device_seed);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = seed.add_data(EC_CS_SEED_SEPARATOR, EC_CS_SEED_SEPARATOR_SIZE);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (in_data_type == ec_cs_data_type_master_key)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS: ec_cs_store_c::generate_data_key(): creates a key for master key :-)\n")));
+
+		status = seed.add_data(EC_CS_MASTER_KEY_SEED, EC_CS_MASTER_KEY_SEED_SIZE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else if (in_data_type == ec_cs_data_type_reference_counter)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS: ec_cs_store_c::generate_data_key(): creates reference counter key\n")));
+
+		status = seed.add_data(EC_CS_REFERENCE_COUNTER_SEED, EC_CS_REFERENCE_COUNTER_SEED_SIZE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else if (in_data_type == ec_cs_data_type_ca_certificate_data)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS: ec_cs_store_c::generate_data_key(): creates CA certificate data key\n")));
+
+		status = seed.add_data(EC_CS_CA_CERTIFICATE_DATA_DATA_SEED, EC_CS_CA_CERTIFICATE_DATA_DATA_SEED_SIZE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else if (in_data_type == ec_cs_data_type_client_certificate_data)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS: ec_cs_store_c::generate_data_key(): creates client certificate data key\n")));
+
+		status = seed.add_data(EC_CS_USER_CERTIFICATE_DATA_DATA_SEED, EC_CS_USER_CERTIFICATE_DATA_DATA_SEED_SIZE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else if (in_data_type == ec_cs_data_type_private_key_data)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS: ec_cs_store_c::generate_data_key(): creates private key data key\n")));
+
+		status = seed.add_data(EC_CS_PRIVATE_KEY_DATA_SEED, EC_CS_PRIVATE_KEY_DATA_SEED_SIZE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else if (in_data_type == ec_cs_data_type_ca_asu_id)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS: ec_cs_store_c::generate_data_key(): creates CA ASU-ID data key\n")));
+
+		status = seed.add_data(EC_CS_CA_ASU_ID_DATA_SEED, EC_CS_CA_ASU_ID_DATA_SEED_SIZE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else if (in_data_type == ec_cs_data_type_client_asu_id)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS: ec_cs_store_c::generate_data_key(): creates client ASU-ID data key\n")));
+
+		status = seed.add_data(EC_CS_CLIENT_ASU_ID_DATA_SEED, EC_CS_CLIENT_ASU_ID_DATA_SEED_SIZE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	status = seed.add_data(in_data_reference);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = out_key->set_buffer_length(EC_CS_MAC_KEY_SIZE);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = out_key->set_data_length(EC_CS_MAC_KEY_SIZE);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	crypto_tls_prf_c t_prf(m_am_tools);
+
+	if (t_prf.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC CS store base key"),
+		 in_base_key->get_data(),
+		 in_base_key->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC CS store device seed"),
+		 in_CS_store_device_seed->get_data(),
+		 in_CS_store_device_seed->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC CS store reference"),
+		 in_data_reference->get_data(),
+		 in_data_reference->get_data_length()));
+
+	status = t_prf.tls_prf_init(
+		in_base_key,
+		&label,
+		&seed);
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = t_prf.tls_prf_output(
+		out_key->get_data(),
+		static_cast<u16_t>(out_key->get_data_length()));
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	EAP_ASSERT((EC_CS_MAC_KEY_SIZE >= EC_CS_ENCRYPTION_KEY_SIZE));
+
+	if (in_true_when_encryption_key == true)
+	{
+		status = out_key->set_data_length(EC_CS_ENCRYPTION_KEY_SIZE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC CS store key"),
+		 out_key->get_data(),
+		 out_key->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::create_tlv(
+	ec_cs_variable_data_c * const new_tlv,
+	const ec_cs_tlv_type_e type,
+	const eap_variable_data_c * const pac_attributes)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::create_tlv()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::create_tlv()");
+
+	if (new_tlv == 0
+		|| new_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (pac_attributes == 0
+		|| pac_attributes->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	/*  EC CS TLV
+	 *  0                   1                   2                   3   
+	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * |      TLV Type (AVP Type)      |            Length             |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * |            EC CS Attributes ...                  
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 */
+
+	eap_status_e status = new_tlv->set_copy_of_buffer(
+		type,
+		pac_attributes->get_data(),
+		pac_attributes->get_data_length());
+
+	EC_CS_TLV_TRACE_PAYLOAD("Creates EC CS TLV", (new_tlv->get_header()), m_is_client);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::create_generic_tlv(
+	ec_cs_variable_data_c * const new_tlv,
+	const ec_cs_tlv_type_e type,
+	const eap_variable_data_c * const payload)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::create_generic_tlv()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::create_generic_tlv()");
+
+	if (new_tlv == 0
+		|| new_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	/*  CS-generic TLV
+	 *  0                   1                   2                   3   
+	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * |      TLV Type (AVP Type)      |            Length             |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * |                                                               |
+	 * |                            Payload                            |
+	 * |                                                               |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 */
+
+	eap_status_e status(eap_status_ok);
+
+	if (payload != 0
+		&& payload->get_is_valid_data() == true)
+	{
+		status = new_tlv->set_copy_of_buffer(
+			type,
+			payload->get_data(),
+			payload->get_data_length());
+	}
+	else
+	{
+		status = new_tlv->set_copy_of_buffer(
+			type,
+			0,
+			0ul);
+	}
+
+	EC_CS_TLV_TRACE_PAYLOAD("Creates CS-generic TLV", (new_tlv->get_header()), m_is_client);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::create_u32_t_tlv(
+	ec_cs_variable_data_c * const new_tlv,
+	const ec_cs_tlv_type_e type,
+	const u32_t value)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::create_u32_t_tlv(%s)\n"),
+		ec_cs_tlv_header_c::get_tlv_string(type)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::create_u32_t_tlv()");
+
+	if (new_tlv == 0
+		|| new_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	/*  CS-u32_t TLV
+	 *  0                   1                   2                   3   
+	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * |      TLV Type (AVP Type)      |            Length             |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * |       any 32-bit value                                        |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 */
+
+	u32_t network_order_value(eap_htonl(value));
+
+	eap_status_e status = new_tlv->set_copy_of_buffer(
+		type,
+		&network_order_value,
+		sizeof(network_order_value));
+
+	EC_CS_TLV_TRACE_PAYLOAD("Creates CS-32-bit TLV", (new_tlv->get_header()), m_is_client);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::create_u16_t_tlv(
+	ec_cs_variable_data_c * const new_tlv,
+	const ec_cs_tlv_type_e type,
+	const u16_t value)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::create_u16_t_tlv(%s)\n"),
+		ec_cs_tlv_header_c::get_tlv_string(type)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::create_u16_t_tlv()");
+
+	if (new_tlv == 0
+		|| new_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	/*  CS-u16_t TLV
+	 *  0                   1                   2                   3   
+	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * |      TLV Type (AVP Type)      |            Length             |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * |       any 16-bit value        |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 */
+
+	u16_t network_order_value(eap_htons(value));
+
+	eap_status_e status = new_tlv->set_copy_of_buffer(
+		type,
+		&network_order_value,
+		sizeof(network_order_value));
+
+	EC_CS_TLV_TRACE_PAYLOAD("Creates CS-16-bit lifetime TLV", (new_tlv->get_header()), m_is_client);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::read_generic_tlv(
+	const ec_cs_variable_data_c * const tlv,
+	const ec_cs_tlv_type_e type,
+	eap_variable_data_c * const payload)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::read_generic_tlv()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::read_generic_tlv()");
+
+	if (tlv != 0
+		&& tlv->get_type() == type
+		&& payload != 0
+		&& payload->get_is_valid() == true)
+	{
+		u8_t * type_data = tlv->get_data(sizeof(u16_t));
+		if (type_data == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		eap_status_e status = payload->set_copy_of_buffer(type_data, tlv->get_data_length());
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+	else
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::read_u32_t_tlv(
+	const ec_cs_variable_data_c * const tlv,
+	const ec_cs_tlv_type_e type,
+	u32_t * const value)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::read_u32_t_tlv()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::read_u32_t_tlv()");
+
+	if (tlv != 0
+		&& tlv->get_type() == type
+		&& value != 0)
+	{
+		u8_t * type_data = tlv->get_data(sizeof(u16_t));
+		if (type_data == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		*value = eap_read_u16_t_network_order(
+			type_data,
+			sizeof(u32_t));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	else
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::read_u16_t_tlv(
+	const ec_cs_variable_data_c * const tlv,
+	const ec_cs_tlv_type_e type,
+	u16_t * const value)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::read_u16_t_tlv()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::read_u16_t_tlv()");
+
+	if (tlv != 0
+		&& tlv->get_type() == type
+		&& value != 0)
+	{
+		u8_t * type_data = tlv->get_data(sizeof(u16_t));
+		if (type_data == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		*value = eap_read_u16_t_network_order(
+			type_data,
+			sizeof(u16_t));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	else
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::create_MAC(
+	eap_variable_data_c * const MAC,
+	const eap_variable_data_c * const server_opaque_mac_key,
+	const eap_variable_data_c * const protected_data)
+{
+	crypto_sha_256_c sha256(m_am_tools);
+	crypto_hmac_c hmac(m_am_tools, &sha256, false);
+
+	eap_status_e status = hmac.hmac_set_key(
+		server_opaque_mac_key);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS Compound MAC over data"),
+		protected_data->get_data(),
+		protected_data->get_data_length()));
+
+	status = hmac.hmac_update(
+		protected_data->get_data(),
+		protected_data->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (MAC == 0
+		|| MAC->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = MAC->set_buffer_length(hmac.get_digest_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = MAC->set_data_length(hmac.get_digest_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	u32_t mac_length = hmac.get_digest_length();
+
+	status = hmac.hmac_final(
+		MAC->get_data(),
+		&mac_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+	else if (mac_length != hmac.get_digest_length())
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS Compound MAC"),
+		 MAC->get_data(),
+		 hmac.get_digest_length()));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::create_encrypted_tlv(
+	const ec_cs_tlv_type_e new_tlv_type,
+	const eap_variable_data_c * const encryption_key,
+	const ec_cs_variable_data_c * const plaintext_data_tlvs,
+	ec_cs_variable_data_c * const new_tlv)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::create_encrypted_tlv()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::create_encrypted_tlv()");
+
+	if (new_tlv == 0
+		|| new_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	EC_CS_TLV_TRACE_PAYLOAD("Plain text TLV", (plaintext_data_tlvs->get_header()), m_is_client);
+
+	eap_status_e status(eap_status_process_general_error);
+
+	//----------------------------------------------------------------------
+
+	/*
+	 * EC CS Encrypted block TLV
+	 *
+ 	 * 0                   1                   2                   3   
+	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    -+ -+
+	 * | Type=CS-Encrypted block TLV   |    Length=4+16+4+n+4+m        |     |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
+	 * | Type=CS-Encryption IV TLV     |          Length=16            |  |  |  | plain text
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  |
+	 * |                              IV (16 octets)                   |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
+	 * | Type=CS-Encrypted data TLV    |          Length=n+4+m         |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  | -+
+	 * |                           data TLVs (n octets)                |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | encrypted
+	 * | Type=CS-padding TLV           |          Length=m             |  |  |  | multiple of
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | 16 octets
+	 * |                           padding (m octets)                  |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ -+ -+
+	 */
+
+	//----------------------------------------------------------------------
+
+	crypto_aes_c aes(m_am_tools);
+	crypto_cbc_c aes_cbc(m_am_tools, &aes, false);
+
+	if (aes.get_is_valid() == false
+		|| aes_cbc.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	ec_cs_variable_data_c temporary_encrypt_tlv(m_am_tools);
+	if (temporary_encrypt_tlv.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = temporary_encrypt_tlv.set_copy_of_buffer(plaintext_data_tlvs);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	//----------------------------------------------------------------------
+	// Create IV.
+	// IV will be added to the begin of the encypted data.
+
+	ec_cs_variable_data_c  * const IV_tlv = new ec_cs_variable_data_c(m_am_tools);
+	eap_automatic_variable_c<ec_cs_variable_data_c> automatic_IV_tlv(m_am_tools, IV_tlv);
+	if (IV_tlv == 0
+		|| IV_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	{
+		eap_variable_data_c IV(m_am_tools);
+		if (IV.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = IV.set_buffer_length(aes_cbc.get_block_size());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = IV.set_data_length(aes_cbc.get_block_size());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		crypto_random_c rand(m_am_tools);
+		if (rand.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = rand.get_rand_bytes(
+			IV.get_data(),
+			IV.get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = create_generic_tlv(
+			IV_tlv,
+			ec_cs_tlv_type_CS_encryption_IV,
+			&IV);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	//----------------------------------------------------------------------
+	// Create padding.
+
+	{
+		u32_t padding_length(
+			aes_cbc.get_block_size()
+				- ((temporary_encrypt_tlv.get_data_length() + ec_cs_tlv_header_c::get_header_length())
+					% aes_cbc.get_block_size()));
+
+		u8_t max_padding[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+
+		eap_variable_data_c padding(m_am_tools);
+		if (padding.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = padding.set_buffer(
+			max_padding,
+			padding_length,
+			false,
+			false);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		ec_cs_variable_data_c  * const padding_tlv = new ec_cs_variable_data_c(m_am_tools);
+		eap_automatic_variable_c<ec_cs_variable_data_c> automatic_padding_tlv(m_am_tools, padding_tlv);
+		if (padding_tlv == 0
+			|| padding_tlv->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_generic_tlv(
+			padding_tlv,
+			ec_cs_tlv_type_CS_padding,
+			&padding);
+
+		// Add padding TLV to plaintext data.
+		status = temporary_encrypt_tlv.add_data(
+			padding_tlv->get_full_tlv_buffer()->get_data(),
+			padding_tlv->get_full_tlv_buffer()->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	//----------------------------------------------------------------------
+	// Encrypt data.
+
+	{
+		status = aes_cbc.set_encryption_key(
+			IV_tlv->get_data(IV_tlv->get_data_length()),
+			IV_tlv->get_data_length(),
+			encryption_key->get_data(),
+			encryption_key->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// NOTE, only the data field including padding TLV is encrypted.
+		status = aes_cbc.encrypt_data(
+			temporary_encrypt_tlv.get_data(temporary_encrypt_tlv.get_data_length()),
+			temporary_encrypt_tlv.get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	//----------------------------------------------------------------------
+	// Combine TLVs.
+
+	{
+		status = create_generic_tlv(
+			new_tlv,
+			new_tlv_type,
+			IV_tlv->get_full_tlv_buffer());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = new_tlv->add_data(
+			temporary_encrypt_tlv.get_full_tlv_buffer()->get_data(),
+			temporary_encrypt_tlv.get_full_tlv_buffer()->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	//----------------------------------------------------------------------
+
+	EC_CS_TLV_TRACE_PAYLOAD("EC CS Encrypted block TLV", (new_tlv->get_header()), m_is_client);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::parse_encrypted_tlv(
+	const eap_variable_data_c * const in_decryption_key,
+	const ec_cs_variable_data_c * const in_encrypted_block_tlv,
+	ec_cs_variable_data_c * const plain_text_tlv)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::parse_encrypted_tlv()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::parse_encrypted_tlv()");
+
+	if (plain_text_tlv == 0
+		|| plain_text_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	//----------------------------------------------------------------------
+
+	EC_CS_TLV_TRACE_PAYLOAD("EC CS Encrypted block TLV", (in_encrypted_block_tlv->get_header()), m_is_client);
+
+	/*
+	 * EC CS Encrypted block TLV
+	 *
+ 	 * 0                   1                   2                   3   
+	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    -+ -+
+	 * | Type=CS-Encrypted block TLV   |     Length=4+16+4+n+4+m       |     |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
+	 * | Type=CS-Encryption IV TLV     |           Length=16           |  |  |  | plain text
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  |
+	 * |                              IV (16 octets)                   |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |  |
+	 * | Type=CS-Encrypted data TLV    |           Length=n+4+m        |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  | -+
+	 * |                           data TLVs (n octets)                |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | encrypted
+	 * | Type=CS-padding TLV           |           Length=m            |  |  |  | multiple of
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | 16 octets
+	 * |                           padding (m octets)                  |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ -+ -+
+	 */
+
+	//----------------------------------------------------------------------
+
+	eap_status_e status(eap_status_process_general_error);
+
+	ec_cs_tlv_payloads_c * const CS_encrypted_block_payloads = new ec_cs_tlv_payloads_c(m_am_tools, m_is_client);
+	eap_automatic_variable_c<ec_cs_tlv_payloads_c> automatic_CS_encrypted_block_payloads(m_am_tools, CS_encrypted_block_payloads);
+	if (CS_encrypted_block_payloads == 0
+		|| CS_encrypted_block_payloads->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t encrypted_block_payloads_length(in_encrypted_block_tlv->get_data_length());
+	u32_t encrypted_block_payloads_padding_length(0ul);
+
+	status = CS_encrypted_block_payloads->parse_ec_cs_payloads(
+		in_encrypted_block_tlv->get_data(in_encrypted_block_tlv->get_data_length()), ///< This is the start of the IV TLV and Encrypted data TLV.
+		&encrypted_block_payloads_length, ///< This is the length of the buffer. This must match with the length of all payloads.
+		&encrypted_block_payloads_padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	ec_cs_variable_data_c * const IV_tlv = CS_encrypted_block_payloads->get_tlv_pointer(ec_cs_tlv_type_CS_encryption_IV);
+
+	if (IV_tlv == 0
+		|| IV_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
+	}
+
+	ec_cs_variable_data_c * const encrypted_data_tlv = CS_encrypted_block_payloads->get_tlv_pointer(ec_cs_tlv_type_CS_encrypted_data);
+
+	if (encrypted_data_tlv == 0
+		|| encrypted_data_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
+	}
+
+	// Decrypt EC CS Encrypted data TLV
+
+	crypto_aes_c aes(m_am_tools);
+	crypto_cbc_c aes_cbc(m_am_tools, &aes, false);
+
+	if (aes.get_is_valid() == false
+		|| aes_cbc.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = aes_cbc.set_decryption_key(
+		IV_tlv->get_data(IV_tlv->get_data_length()),
+		IV_tlv->get_data_length(),
+		in_decryption_key->get_data(),
+		in_decryption_key->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = aes_cbc.decrypt_data(
+		encrypted_data_tlv->get_data(encrypted_data_tlv->get_data_length()),
+		encrypted_data_tlv->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = plain_text_tlv->set_copy_of_buffer(
+		encrypted_data_tlv->get_full_tlv_buffer()->get_data(),
+		encrypted_data_tlv->get_full_tlv_buffer()->get_data_length());
+
+	EC_CS_TLV_TRACE_PAYLOAD("EC CS plain text TLV", (plain_text_tlv->get_header()), m_is_client);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::create_data_with_MAC(
+	const eap_variable_data_c * const MAC_key,
+	const eap_variable_data_c * const in_data,
+	eap_variable_data_c * const out_data_tlv)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::create_data_with_MAC()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::create_data_with_MAC()");
+
+	if (out_data_tlv == 0
+		|| out_data_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (in_data == 0
+		|| in_data->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+
+	eap_status_e status(eap_status_process_general_error);
+
+	//----------------------------------------------------------------------
+
+	/*
+	 * data in EC CS store
+	 *
+	 *  0                   1                   2                   3   
+	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+	 * | Type=data TLV                 |           Length              |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  | protected
+	 * |                             data (n octets)                   |  | by MAC
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+	 * | Type=CS-MAC TLV               |           Length=32           |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+	 * |                              MAC (32 octets)                  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+	 */
+
+	status = out_data_tlv->set_copy_of_buffer(in_data);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	//----------------------------------------------------------------------
+	// Add MAC TLV.
+
+	ec_cs_variable_data_c  * const MAC_tlv = new ec_cs_variable_data_c(m_am_tools);
+	eap_automatic_variable_c<ec_cs_variable_data_c> automatic_MAC_tlv(m_am_tools, MAC_tlv);
+	if (MAC_tlv == 0
+		|| MAC_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	{
+		eap_variable_data_c MAC(m_am_tools);
+
+		status = create_MAC(
+			&MAC,
+			MAC_key,
+			out_data_tlv);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = create_generic_tlv(
+			MAC_tlv,
+			ec_cs_tlv_type_CS_MAC,
+			&MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EC_CS_TLV_TRACE_PAYLOAD("CS-MAC TLV", (MAC_tlv->get_header()), m_is_client);
+
+		status = out_data_tlv->add_data(MAC_tlv->get_full_tlv_buffer());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::verify_data_with_MAC(
+	const eap_variable_data_c * const in_base_key,
+	const eap_variable_data_c * const in_CS_store_device_seed,
+	const ec_cs_data_c * const in_CS_data_with_MAC)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::verify_data_with_MAC()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::verify_data_with_MAC()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	eap_variable_data_c MAC_key(m_am_tools);
+	if (MAC_key.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = generate_data_key(
+		false,
+		in_CS_data_with_MAC->get_type(),
+		&MAC_key,
+		in_base_key,
+		in_CS_data_with_MAC->get_reference(),
+		in_CS_store_device_seed);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = parse_data_with_MAC(
+		&MAC_key,
+		in_CS_data_with_MAC->get_data());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::parse_data_with_MAC(
+	const eap_variable_data_c * const MAC_key,
+	const eap_variable_data_c * const CS_data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::parse_data_with_MAC()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::parse_data_with_MAC()");
+
+	if (CS_data == 0
+		|| CS_data->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	//----------------------------------------------------------------------
+
+	delete m_payloads;
+	m_payloads = new ec_cs_tlv_payloads_c(m_am_tools, m_is_client);
+
+	if (m_payloads == 0
+		|| m_payloads->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t encrypted_block_payloads_length(CS_data->get_data_length());
+	u32_t encrypted_block_payloads_padding_length(0ul);
+
+	status = m_payloads->parse_ec_cs_payloads(
+		CS_data->get_data(CS_data->get_data_length()), ///< This is the start of TLVs, the last one must be MAC TLV.
+		&encrypted_block_payloads_length, ///< This is the length of the buffer. This must match with the length of all payloads.
+		&encrypted_block_payloads_padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	ec_cs_variable_data_c * const CS_MAC_tlv = m_payloads->get_tlv_pointer(ec_cs_tlv_type_CS_MAC);
+
+	if (CS_MAC_tlv == 0
+		|| CS_MAC_tlv->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
+	}
+
+	{
+		eap_variable_data_c MAC_data(m_am_tools);
+		if (MAC_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		// MAC data includes all data except MAC TLV.
+		u32_t MAC_data_length
+			= CS_data->get_data_length() - CS_MAC_tlv->get_full_tlv_buffer()->get_data_length();
+
+		status = MAC_data.set_buffer(
+			CS_data->get_data(),
+			MAC_data_length,
+			false,
+			false);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		eap_variable_data_c MAC(m_am_tools);
+		if (MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_MAC(
+			&MAC,
+			MAC_key,
+			&MAC_data);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		if (MAC.compare(CS_MAC_tlv->get_data(CS_MAC_tlv->get_data_length()), CS_MAC_tlv->get_data_length()) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
+		}
+	}
+
+	//----------------------------------------------------------------------
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::create_master_key_data(
+	const eap_variable_data_c * const in_CS_password,
+	const eap_variable_data_c * const in_CS_store_device_seed,
+	const eap_variable_data_c * const in_CS_master_key_or_null,
+	const eap_variable_data_c * const in_data_reference,
+	eap_variable_data_c * const master_key_data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::create_master_key_data()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::create_master_key_data()");
+
+	if (in_CS_password == 0
+		|| in_CS_password->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (in_CS_store_device_seed == 0
+		|| in_CS_store_device_seed->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (in_CS_master_key_or_null != 0
+		&& in_CS_master_key_or_null->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (master_key_data == 0
+		|| master_key_data->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	//----------------------------------------------------------------------
+
+	eap_variable_data_c master_key_encryption_key(m_am_tools);
+	if (master_key_encryption_key.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = generate_data_key(
+		true,
+		ec_cs_data_type_master_key,
+		&master_key_encryption_key,
+		in_CS_password,
+		in_data_reference,
+		in_CS_store_device_seed);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	eap_variable_data_c master_key_MAC_key(m_am_tools);
+	if (master_key_MAC_key.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = generate_data_key(
+		false,
+		ec_cs_data_type_master_key,
+		&master_key_MAC_key,
+		in_CS_password,
+		in_data_reference,
+		in_CS_store_device_seed);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	ec_cs_variable_data_c encrypted_data_tlv(m_am_tools);
+	if (encrypted_data_tlv.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	ec_cs_variable_data_c master_key_tlv(m_am_tools);
+	if (master_key_tlv.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_variable_data_c CS_master_key(m_am_tools);
+	if (CS_master_key.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	if (in_CS_master_key_or_null == 0)
+	{
+		// Create a new EC CS Store Master Key.
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ec_cs_tlv_c::create_master_key_data(): Creates new master key.\n")));
+
+		crypto_random_c rand(m_am_tools);
+
+		if (rand.get_is_valid() == false)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = CS_master_key.set_buffer_length(EC_CS_MASTER_KEY_SIZE);
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = CS_master_key.set_data_length(EC_CS_MASTER_KEY_SIZE);
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = rand.get_rand_bytes(
+			CS_master_key.get_data(
+				CS_master_key.get_data_length()),
+			CS_master_key.get_data_length());
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ec_cs_tlv_c::create_master_key_data(): Uses existing master key.\n")));
+
+		status = CS_master_key.set_buffer(in_CS_master_key_or_null);
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	status = create_generic_tlv(
+		&master_key_tlv,
+		ec_cs_tlv_type_CS_master_key,
+		&CS_master_key);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = create_generic_tlv(
+		&encrypted_data_tlv,
+		ec_cs_tlv_type_CS_encrypted_data,
+		master_key_tlv.get_full_tlv_buffer());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	ec_cs_variable_data_c CS_encrypted_block_tlv(m_am_tools);
+	if (CS_encrypted_block_tlv.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = create_encrypted_tlv(
+		ec_cs_tlv_type_CS_encrypted_block,
+		&master_key_encryption_key,
+		&encrypted_data_tlv,
+		&CS_encrypted_block_tlv);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = create_data_with_MAC(
+		&master_key_MAC_key,
+		CS_encrypted_block_tlv.get_full_tlv_buffer(),
+		master_key_data);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("New Master key data"),
+		 master_key_data->get_data(),
+		 master_key_data->get_data_length()));
+
+	//----------------------------------------------------------------------
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::parse_cs_tlv(
+	const ec_cs_variable_data_c * const PAC_tlv)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::parse_cs_tlv()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::parse_cs_tlv()");
+
+	if (PAC_tlv == 0
+		|| PAC_tlv->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	status = PAC_tlv->get_header()->check_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if ((PAC_tlv->get_header()->get_header_length() + PAC_tlv->get_header()->get_data_length()) > PAC_tlv->get_header()->get_header_buffer_length())
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	EC_CS_TLV_TRACE_PAYLOAD("Parse CS TLV", (PAC_tlv->get_header()), m_is_client);
+
+
+	{
+		delete m_payloads;
+		m_payloads = 0;
+		m_payloads = new ec_cs_tlv_payloads_c(m_am_tools, m_is_client);
+
+		if (m_payloads == 0
+			|| m_payloads->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t buffer_length(PAC_tlv->get_data_length());
+		u32_t padding_length(0ul);
+
+		status = m_payloads->parse_ec_cs_payloads(
+			PAC_tlv->get_data(PAC_tlv->get_data_length()), ///< This is the start of the message buffer.
+			&buffer_length, ///< This is the length of the buffer. This must match with the length of all payloads.
+			&padding_length ///< Length of possible padding is set to this variable.
+			);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::parse_encrypted_tlv_with_MAC(
+	const ec_cs_data_type_e in_data_type,
+	const eap_variable_data_c * const in_base_key,
+	const eap_variable_data_c * const in_data_reference,
+	const eap_variable_data_c * const in_CS_store_device_seed,
+	const eap_variable_data_c * const in_data_tlv,
+	ec_cs_variable_data_c * const out_plain_text_tlv)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::parse_encrypted_tlv_with_MAC()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::parse_encrypted_tlv_with_MAC()");
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("parse_encrypted_tlv_with_MAC(): in_data_tlv"),
+		 in_data_tlv->get_data(),
+		 in_data_tlv->get_data_length()));
+
+	/*
+	 * Encrypted data with MAC.
+	 *
+ 	 * 0                   1                   2                   3   
+	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ -+ -+
+	 * | Type=Any pre-selected TLVs    | Length=4+l+4+16+4+n+4+m       |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |M |
+	 * |                     Any pre-selected data (l octets)          |  |  |A |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+  |C |
+	 * | Type=CS-Encrypted-Block TLV   |  Length=4+16+4+n+4+m          |  |  |  | plain text
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |d |
+	 * | Type=CS-Encryption IV TLV     |           Length=16           |  |  |a |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |t |
+	 * |                              IV (16 octets)                   |  |  |a |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  |
+	 * | Type=CS-Encrypted data TLV    |           Length=n+4+m        |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  | -+
+	 * |                          Master key TLV (n octets)            |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | encrypted
+	 * | Type=CS-padding TLV           |           Length=m            |  |  |  | multiple of
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |  |  | 16 octets
+	 * |                           padding (m octets)                  |  |  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+ -+ -+
+	 * | Type=CS-MAC TLV               |           Length=32           |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+	 * |                              MAC (32 octets)                  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+	 */
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// First check the MAC is correct.
+
+	{
+		eap_variable_data_c MAC_key(m_am_tools);
+		if (MAC_key.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = generate_data_key(
+			false,
+			in_data_type,
+			&MAC_key,
+			in_base_key,
+			in_data_reference,
+			in_CS_store_device_seed);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = parse_data_with_MAC(
+			&MAC_key,
+			in_data_tlv);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	const ec_cs_variable_data_c * const encrypted_block_tlv = get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_encrypted_block);
+	if (encrypted_block_tlv == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// Second, decrypt encrypted block.
+
+	{
+		eap_variable_data_c decryption_key(m_am_tools);
+		if (decryption_key.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = generate_data_key(
+			true,
+			in_data_type,
+			&decryption_key,
+			in_base_key,
+			in_data_reference,
+			in_CS_store_device_seed);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = parse_encrypted_tlv(
+			&decryption_key,
+			encrypted_block_tlv,
+			out_plain_text_tlv);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::create_encrypted_certificate(
+	const ec_cs_data_type_e in_data_type,
+	const eap_variable_data_c * const in_base_key,
+	const eap_variable_data_c * const in_data_reference,
+	const eap_variable_data_c * const in_CS_store_device_seed,
+	const eap_variable_data_c * const in_certificate_reference,
+	const ec_cs_tlv_type_e in_certificate_tlv_type,
+	const eap_variable_data_c * const in_certificate_data,
+	eap_variable_data_c * const out_certificate_data_block)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::create_encrypted_certificate()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::create_encrypted_certificate()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	/**
+	 *  0                   1                   2                   3   
+	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+	 * | Type=Certificate-ref. TLV     |           Length              |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  | protected
+	 * |                    Certificate-reference                      |  | by MAC
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+	 * | Type=CS-Encrypted-Block TLV   |           Length              |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+	 * |      CS-Encrypted block TLVs (Certificate-Data TLV) ...          |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+	 * | Type=CS-MAC TLV               |           Length=32           |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  |
+	 * |                           CS MAC (32 octets)                  |  |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -+
+	 */
+
+	ec_cs_variable_data_c encrypted_block_tlv(m_am_tools);
+
+	if (encrypted_block_tlv.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	{
+		eap_variable_data_c encryption_key(m_am_tools);
+		if (encryption_key.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = generate_data_key(
+			true,
+			in_data_type,
+			&encryption_key,
+			in_base_key,
+			in_data_reference,
+			in_CS_store_device_seed);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		ec_cs_variable_data_c certificate_data_tlv(m_am_tools);
+
+		if (certificate_data_tlv.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = certificate_data_tlv.set_copy_of_buffer(
+			in_certificate_tlv_type,
+			in_certificate_data->get_data(),
+			in_certificate_data->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		ec_cs_variable_data_c plain_text_block_tlv(m_am_tools);
+
+		if (plain_text_block_tlv.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = plain_text_block_tlv.set_copy_of_buffer(
+			ec_cs_tlv_type_CS_encrypted_data,
+			certificate_data_tlv.get_full_tlv_buffer()->get_data(),
+			certificate_data_tlv.get_full_tlv_buffer()->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = create_encrypted_tlv(
+			ec_cs_tlv_type_CS_encrypted_block,
+			&encryption_key,
+			&plain_text_block_tlv,
+			&encrypted_block_tlv);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	eap_variable_data_c MAC_data_buffer(m_am_tools);
+	if (MAC_data_buffer.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	{
+		ec_cs_variable_data_c certificate_reference_tlv(m_am_tools);
+
+		if (certificate_reference_tlv.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = certificate_reference_tlv.set_copy_of_buffer(
+			ec_cs_tlv_type_CS_certificate_reference,
+			in_certificate_reference->get_data(),
+			in_certificate_reference->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = MAC_data_buffer.set_copy_of_buffer(certificate_reference_tlv.get_full_tlv_buffer());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	status = MAC_data_buffer.add_data(encrypted_block_tlv.get_full_tlv_buffer());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	{
+		eap_variable_data_c MAC_key(m_am_tools);
+		if (MAC_key.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = generate_data_key(
+			false,
+			in_data_type,
+			&MAC_key,
+			in_base_key,
+			in_data_reference,
+			in_CS_store_device_seed);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = create_data_with_MAC(
+			&MAC_key,
+			&MAC_data_buffer,
+			out_certificate_data_block);
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("New encrypted certificate data"),
+			 out_certificate_data_block->get_data(),
+			 out_certificate_data_block->get_data_length()));
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_c::parse_encrypted_certificate(
+	const ec_cs_data_type_e in_data_type,
+	const eap_variable_data_c * const in_base_key,
+	const eap_variable_data_c * const in_data_reference,
+	const eap_variable_data_c * const in_CS_store_device_seed,
+	const eap_variable_data_c * const in_certificate_data_block,
+	eap_variable_data_c * const out_certificate_reference)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("ec_cs_tlv_c::parse_encrypted_certificate()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: ec_cs_tlv_c::parse_encrypted_certificate()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	ec_cs_variable_data_c decrypted_block_tlv(m_am_tools);
+	if (decrypted_block_tlv.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = parse_encrypted_tlv_with_MAC(
+		in_data_type,
+		in_base_key,
+		in_data_reference,
+		in_CS_store_device_seed,
+		in_certificate_data_block,
+		&decrypted_block_tlv);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	const ec_cs_variable_data_c * const certificate_reference_tlv = get_payloads()->get_tlv_pointer(ec_cs_tlv_type_CS_certificate_reference);
+	if (certificate_reference_tlv == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	status = out_certificate_reference->set_copy_of_buffer(certificate_reference_tlv->get_full_tlv_buffer());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = parse_cs_tlv(&decrypted_block_tlv);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_tlv_header.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,263 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_tlv_header.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 10 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 705 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_memory.h"
+#include "ec_cs_tlv_header.h"
+#include "ec_cs_strings.h"
+
+/** @file */
+
+
+/**
+ * The destructor of the ec_cs_tlv_header_c class does nothing.
+ */
+ec_cs_tlv_header_c::~ec_cs_tlv_header_c()
+{
+}
+
+/**
+ * The constructor of the ec_cs_tlv_header_c class simply initializes the attributes.
+ */
+ec_cs_tlv_header_c::ec_cs_tlv_header_c(
+	abs_eap_am_tools_c * const tools,
+	void * const header_begin,
+	const u32_t header_buffer_length)
+	: eap_general_header_base_c(tools, header_begin, header_buffer_length)
+	, m_am_tools(tools)
+{
+}
+
+/**
+ * This function returns the TLV Type.
+ */
+ec_cs_tlv_type_e ec_cs_tlv_header_c::get_type() const
+{
+	const u8_t * const data = get_header_offset(m_type_offset, m_type_size);
+	if (data != 0)
+	{
+		const u16_t value(eap_read_u16_t_network_order(data, m_type_size));
+
+		EAP_STATIC_ASSERT(m_type_size == sizeof(value));
+
+		return static_cast<ec_cs_tlv_type_e>(value);
+	}
+	else
+	{
+		return ec_cs_tlv_type_none;
+	}
+}
+
+/**
+ * This function returns the data length of TLV.
+ */
+u32_t ec_cs_tlv_header_c::get_data_length() const
+{
+	const u8_t * const length_data = get_header_offset(m_length_offset, m_length_size);
+	if (length_data != 0)
+	{
+		return static_cast<u32_t>(eap_read_u16_t_network_order(length_data, m_length_size));
+	}
+	else
+	{
+		return 0ul;
+	}
+}
+
+/**
+ * This function returns the header length of TLV.
+ */
+u32_t ec_cs_tlv_header_c::get_header_length()
+{
+	return m_data_offset;
+}
+
+/**
+ * This function returns pointer to the offset of data of TLV.
+ * @param offset is the offset of queried data in bytes.
+ * @param contignuous_bytes is the length of queried data in bytes.
+ */
+u8_t * ec_cs_tlv_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const
+{
+	EAP_UNREFERENCED_PARAMETER(m_am_tools);
+
+	u32_t data_length = get_data_length(); 
+
+	if (data_length >= offset+contignuous_bytes)
+	{
+		u8_t * const data = get_header_offset(m_data_offset, offset+contignuous_bytes);
+		if (data != 0)
+		{
+			return &data[offset];
+		}
+		else
+		{
+			return 0;
+		}
+	}
+	else
+	{
+		EAP_ASSERT_ALWAYS(data_length >= offset+contignuous_bytes);
+	}
+	return 0;
+}
+
+
+/**
+ * This function returns pointer to the offset of data of TLV.
+ * @param contignuous_bytes is the length of queried data in bytes.
+ */
+u8_t * ec_cs_tlv_header_c::get_data(const u32_t contignuous_bytes) const
+{
+	return get_data_offset(0u, contignuous_bytes);
+}
+
+
+/**
+ * This function return pointer to the next TLV header in the same buffer.
+ */
+u8_t * ec_cs_tlv_header_c::get_next_header() const
+{
+	if (get_header_buffer_length() >= 2ul*get_header_length()+get_data_length())
+	{
+		return get_data_offset(get_data_length(), get_header_length());
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+
+/**
+ * This function checks the header is valid.
+ */
+eap_status_e ec_cs_tlv_header_c::check_header() const
+{
+	if (get_type() == ec_cs_tlv_type_none)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+/**
+ * This function returns debug strings of the TLV type.
+ */
+eap_const_string ec_cs_tlv_header_c::get_tlv_string(const ec_cs_tlv_type_e type)
+{
+	return ec_cs_strings_c::get_ec_cs_tlv_header_string(type);
+}
+
+/**
+ * This function returns debug strings of the TLV type.
+ */
+eap_const_string ec_cs_tlv_header_c::get_tlv_string() const
+{
+	const ec_cs_tlv_type_e type = get_type();
+	return get_tlv_string(type);
+}
+
+/**
+ * This function sets the TLV type flag.
+ */
+eap_status_e ec_cs_tlv_header_c::set_type(const ec_cs_tlv_type_e type)
+{
+	u8_t * const data = get_header_offset(m_type_offset, m_type_size);
+	if (data != 0)
+	{
+		const u16_t value(static_cast<u16_t>(type));
+
+		EAP_STATIC_ASSERT(m_type_size == sizeof(value));
+
+		return EAP_STATUS_RETURN(m_am_tools, eap_write_u16_t_network_order(
+			data,
+			sizeof(value),
+			value));
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function sets the TLV data length.
+ */
+eap_status_e ec_cs_tlv_header_c::set_data_length(const u32_t p_length)
+{
+	u8_t * const data = get_header_offset(m_length_offset, m_length_size);
+	if (data != 0)
+	{
+		const u16_t value(static_cast<u16_t>(p_length));
+
+		EAP_STATIC_ASSERT(m_length_offset == sizeof(value));
+
+		return EAP_STATUS_RETURN(m_am_tools, eap_write_u16_t_network_order(
+			data,
+			sizeof(value),
+			value));
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function resets the TLV header.
+ */
+eap_status_e ec_cs_tlv_header_c::reset_header()
+{
+	eap_status_e status = set_type(ec_cs_tlv_type_none);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = set_data_length(0ul);
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+/**
+ * This function resets the TLV header object.
+ */
+eap_status_e ec_cs_tlv_header_c::reset()
+{
+	eap_general_header_base_c::set_header_buffer(0, 0ul);
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_tlv_message.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,154 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_tlv_message.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 6 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 704 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_memory.h"
+#include "eap_tools.h"
+#include "eap_array.h"
+#include "ec_cs_tlv_message.h"
+
+/** @file */
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_tlv_message_c::~ec_cs_tlv_message_c()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_tlv_message_c::ec_cs_tlv_message_c(
+	abs_eap_am_tools_c * const tools,
+	const bool is_client)
+	: m_am_tools(tools)
+	, m_message_data(tools)
+	, m_is_client(is_client)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_message_c::reset()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = m_message_data.reset();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_message_c::set_ec_cs_message_data(
+	eap_variable_data_c * const ec_cs_message_data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = m_message_data.set_copy_of_buffer(ec_cs_message_data);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_variable_data_c * ec_cs_tlv_message_c::get_ec_cs_message_data()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return &m_message_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_message_c::add_padding(const u32_t block_size)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = eap_status_ok;
+
+	u32_t data_length = m_message_data.get_data_length();
+	u32_t remaining_bytes = data_length % block_size;
+
+	{
+		const u32_t padding_length = block_size - remaining_bytes;
+
+		status = m_message_data.set_buffer_length(data_length + padding_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_message_data.set_data_length(data_length + padding_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		const u8_t padding_byte = static_cast<u8_t>(padding_length);
+
+		m_am_tools->memset(m_message_data.get_data_offset(data_length, padding_length), padding_byte, padding_length);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS: %s: message_function: ec_cs_tlv_message_c::add_padding(): %d bytes\n"),
+			(m_is_client == true ? "client": "server"),
+			padding_length));
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_cs_tlv_message_c::get_is_valid()
+{
+	return m_message_data.get_is_valid();
+}
+
+//--------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/ec_cs_tlv_payloads.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,1194 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/ec_cs_tlv_payloads.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 12 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 703 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+
+#include "eap_am_memory.h"
+#include "ec_cs_tlv_payloads.h"
+#include "ec_cs_tlv_message.h"
+#include "abs_eap_am_tools.h"
+#include "eap_tools.h"
+#include "eap_array_algorithms.h"
+#include "eap_automatic_variable.h"
+#include "eap_crypto_api.h"
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_variable_data_c::~ec_cs_variable_data_c()
+{
+	delete m_next_payload_with_same_tlv_type;
+	m_next_payload_with_same_tlv_type = 0;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_variable_data_c::ec_cs_variable_data_c(
+	abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+	  , m_data(tools)
+	  , m_header(tools, 0, 0ul)
+	  , m_next_payload_with_same_tlv_type(0)
+	  , m_is_valid(false)
+{
+	if (m_data.get_is_valid() == false)
+	{
+		return;
+	}
+
+	m_is_valid = true;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_cs_variable_data_c::get_is_valid() const
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_cs_variable_data_c::get_is_valid_data() const
+{
+	return get_is_valid() && m_data.get_is_valid_data() && m_header.get_is_valid();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_variable_data_c::init_header(
+	const ec_cs_tlv_type_e current_payload,
+	const u32_t default_buffer_length)
+{
+	if (default_buffer_length > 0xffff)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	eap_status_e status = m_data.set_buffer_length(
+		ec_cs_tlv_header_c::get_header_length() + default_buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_data.set_data_length(
+		ec_cs_tlv_header_c::get_header_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	m_header.set_header_buffer(
+		m_data.get_buffer(m_data.get_buffer_length()),
+		m_data.get_buffer_length());
+
+	status = m_header.reset_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_header.set_type(current_payload);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_variable_data_c::reset()
+{
+	(void) m_data.reset();
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_variable_data_c::set_copy_of_buffer(
+	const ec_cs_tlv_type_e current_payload,
+	const void * const buffer,
+	const u32_t buffer_length)
+{
+	eap_status_e status = init_header(
+		current_payload,
+		buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	m_header.set_data_length(static_cast<u16_t>(buffer_length));
+
+	status = m_data.add_data(buffer, buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_variable_data_c::set_copy_of_buffer(
+	const ec_cs_variable_data_c * const source)
+{
+	eap_status_e status = set_copy_of_buffer(
+			source->get_type(),
+			source->get_data(source->get_data_length()),
+			source->get_data_length());
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	ec_cs_variable_data_c * previous = this;
+
+	const ec_cs_variable_data_c * next = source->get_next_payload_with_same_tlv_type();
+
+	while (next != 0)
+	{
+		// Copy the next payload in a list too.
+		ec_cs_variable_data_c * const new_payload = next->copy();
+		if (new_payload == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		previous->set_next_payload_with_same_tlv_type(new_payload);
+
+		previous = new_payload;
+
+		next = next->get_next_payload_with_same_tlv_type();
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_variable_data_c::add_data(
+	const void * const buffer,
+	const u32_t buffer_length)
+{
+	const ec_cs_tlv_type_e current_payload = m_header.get_type();
+
+	eap_status_e status = m_data.add_data(
+		buffer,
+		buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	m_header.set_header_buffer(
+		m_data.get_buffer(m_data.get_buffer_length()),
+		m_data.get_buffer_length());
+
+	status = m_header.set_type(current_payload);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if ((m_header.get_data_length() + buffer_length) > 0xffff)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	m_header.set_data_length(static_cast<u16_t>(m_header.get_data_length() + buffer_length));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_variable_data_c::add_data(
+	const ec_cs_variable_data_c * const data)
+{
+	eap_status_e status = add_data(
+		data->get_full_tlv_buffer()->get_data(),
+		data->get_full_tlv_buffer()->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_variable_data_c::set_copy_of_buffer(
+	const void * const buffer,
+	const u32_t buffer_length)
+{
+	eap_status_e status = m_data.set_copy_of_buffer(buffer, buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	m_header.set_header_buffer(
+		m_data.get_buffer(m_data.get_buffer_length()),
+		m_data.get_buffer_length());
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t ec_cs_variable_data_c::get_data_length() const
+{
+	return m_header.get_data_length();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u8_t * ec_cs_variable_data_c::get_data(
+	const u32_t data_length) const
+{
+	return m_header.get_data(data_length);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u8_t * ec_cs_variable_data_c::get_data_offset(const u32_t offset, const u32_t data_length) const
+{
+	return m_header.get_data_offset(offset, data_length);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const eap_variable_data_c * ec_cs_variable_data_c::get_full_tlv_buffer() const
+{
+	return &m_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_variable_data_c * ec_cs_variable_data_c::get_writable_full_tlv_buffer()
+{
+	return &m_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const ec_cs_tlv_header_c * ec_cs_variable_data_c::get_header() const
+{
+	return &m_header;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_tlv_type_e ec_cs_variable_data_c::get_type() const
+{
+	return m_header.get_type();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void ec_cs_variable_data_c::set_type(
+	const ec_cs_tlv_type_e type)
+{
+	m_header.set_type(type);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void ec_cs_variable_data_c::set_next_payload_with_same_tlv_type(
+	ec_cs_variable_data_c * const tlv)
+{
+	m_next_payload_with_same_tlv_type = tlv;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_variable_data_c * ec_cs_variable_data_c::get_next_payload_with_same_tlv_type() const
+{
+	return m_next_payload_with_same_tlv_type;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void ec_cs_variable_data_c::add_next_payload_with_same_tlv_type(
+	ec_cs_variable_data_c * const tlv)
+{
+	ec_cs_variable_data_c *payload = get_next_payload_with_same_tlv_type();
+	ec_cs_variable_data_c *prev_payload = this;
+
+	while (payload != 0)
+	{
+		prev_payload = payload;
+		payload = payload->get_next_payload_with_same_tlv_type();
+	}
+
+	if (prev_payload != 0)
+	{
+		prev_payload->set_next_payload_with_same_tlv_type(tlv);
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_variable_data_c * ec_cs_variable_data_c::copy() const
+{
+	ec_cs_variable_data_c * new_data = new ec_cs_variable_data_c(m_am_tools);
+
+	if (new_data != 0)
+	{
+		eap_status_e status = new_data->set_copy_of_buffer(
+			get_type(),
+			get_data(get_data_length()),
+			get_data_length());
+		if (status != eap_status_ok)
+		{
+			delete new_data;
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			return 0;
+		}
+	}
+
+	return new_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT  void ec_cs_variable_data_c::object_increase_reference_count()
+{
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT i32_t ec_cs_variable_data_c::compare(const ec_cs_variable_data_c * right) const
+{
+	if (get_type() != right->get_type())
+	{
+		return -1;
+	}
+	else if (get_data_length() != right->get_data_length())
+	{
+		return -1;
+	}
+	else
+	{
+		return m_am_tools->memcmp(get_data(get_data_length()), right->get_data(right->get_data_length()), get_data_length());
+	}
+}
+
+//--------------------------------------------------
+//--------------------------------------------------
+//--------------------------------------------------
+
+
+EAP_FUNC_EXPORT ec_cs_tlv_payloads_c::~ec_cs_tlv_payloads_c()
+{
+}
+
+//--------------------------------------------------
+
+#if defined(_WIN32) && !defined(__GNUC__)
+	#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
+#endif
+
+EAP_FUNC_EXPORT ec_cs_tlv_payloads_c::ec_cs_tlv_payloads_c(
+	abs_eap_am_tools_c * const tools,
+	const bool true_when_is_client)
+	: m_am_tools(tools)
+	  , m_payload_map(tools, this)
+	  , m_read_payloads(tools)
+	  , m_payload_index(0ul)
+	  , m_is_client(true_when_is_client)
+	  , m_is_valid(false)
+{
+	m_is_valid = true;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_variable_data_c * ec_cs_tlv_payloads_c::get_tlv_pointer(
+	const ec_cs_tlv_type_e current_payload,
+	u32_t index) const
+{
+	eap_variable_data_c selector(m_am_tools);
+
+	if (selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return 0;
+	}
+
+	selector.set_buffer(
+		&current_payload,
+		sizeof(current_payload),
+		false,
+		false);
+
+	ec_cs_variable_data_c *payload = m_payload_map.get_handler(&selector);
+
+	while (index != 0ul && payload != 0)
+	{
+		--index;
+		payload = payload->get_next_payload_with_same_tlv_type();
+	}
+
+	return payload;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_variable_data_c * ec_cs_tlv_payloads_c::get_tlv_pointer(
+	const ec_cs_tlv_type_e current_payload) const
+{
+	return get_tlv_pointer(current_payload, 0ul);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t ec_cs_tlv_payloads_c::get_tlv_count() const
+{
+	return m_read_payloads.get_object_count();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_variable_data_c * ec_cs_tlv_payloads_c::get_tlv(
+	const u32_t tlv_index) const
+{
+	ec_cs_variable_data_c *payload = m_read_payloads.get_object(tlv_index);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::get_tlv(index %d, max %d) = %s\n"),
+		tlv_index,
+		m_read_payloads.get_object_count(),
+		payload->get_header()->get_tlv_string()));
+
+	return payload;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_payloads_c::check_payloads_existense(
+	const ec_cs_tlv_type_e * const needed_payloads,
+	const u32_t count_of_needed_payloads) const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::check_payloads_existense()\n")));
+
+	for (u32_t ind = 0ul; ind < count_of_needed_payloads; ind++)
+	{
+		const ec_cs_tlv_type_e required_avp_code = needed_payloads[ind];
+		if (required_avp_code == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		if (get_tlv_pointer(required_avp_code) == 0)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("not received TLV 0x%08x.\n"),
+				 required_avp_code));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_payloads_c::check_payloads_existense(
+	EAP_TEMPLATE_CONST eap_array_c<ec_cs_tlv_type_e> * const needed_payloads) const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::check_payloads_existense()\n")));
+
+	for (u32_t ind = 0ul; ind < needed_payloads->get_object_count(); ind++)
+	{
+		const ec_cs_tlv_type_e * const required_avp_code = needed_payloads->get_object(ind);
+		if (required_avp_code == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		if (get_tlv_pointer(*required_avp_code) == 0)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("not received TLV 0x%08x.\n"),
+				 *required_avp_code));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_payloads_c::copy_tlv(
+	const ec_cs_tlv_payloads_c * const source,
+	const ec_cs_tlv_type_e tlv)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::copy_tlv(TLV 0x%08x)\n"),
+		tlv));
+
+	const ec_cs_variable_data_c * const payload
+		= source->get_tlv_pointer(tlv, 0ul);
+	if (payload == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
+	}
+
+	eap_status_e status = add_tlv(
+		payload->copy());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_payloads_c::add_tlv(
+	ec_cs_variable_data_c * const new_payload)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::add_tlv()\n")));
+
+	if (new_payload == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	eap_automatic_variable_c<ec_cs_variable_data_c>
+		automatic_new_payload(m_am_tools, new_payload);
+
+	const ec_cs_tlv_type_e new_payload_type(new_payload->get_type());
+		
+	ec_cs_variable_data_c *old_payload = get_tlv_pointer(
+		new_payload_type);
+
+	{
+		eap_variable_data_c selector(m_am_tools);
+
+		if (selector.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		selector.set_copy_of_buffer(
+			&new_payload_type,
+			sizeof(new_payload_type));
+		
+		if (old_payload == 0)
+		{
+			status = m_payload_map.add_handler(&selector, new_payload);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		else
+		{
+			// Cannot add dublicate payload to m_payload_map.
+			// Instead we add apointer to the next payload with the same tlv type.
+			old_payload->add_next_payload_with_same_tlv_type(new_payload);
+		}
+
+		automatic_new_payload.do_not_free_variable();
+
+		// Note the same payload object is added to m_read_payloads as to m_payload_map.
+		status = m_read_payloads.add_object(new_payload, false);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_payloads_c::copy_tlv_data(
+	const ec_cs_tlv_type_e current_payload,
+	const void * const data,
+	const u32_t data_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::copy_tlv_data(TLV 0x%08x)\n"),
+		current_payload));
+
+	eap_status_e status(eap_status_process_general_error);
+
+	ec_cs_variable_data_c *new_payload = new ec_cs_variable_data_c(
+		m_am_tools);
+	if (new_payload == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_automatic_variable_c<ec_cs_variable_data_c>
+		automatic_new_payload(m_am_tools, new_payload);
+
+	status = new_payload->set_copy_of_buffer(
+		current_payload,
+		data,
+		data_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+	
+	automatic_new_payload.do_not_free_variable();
+
+	status = add_tlv(new_payload);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool ec_cs_tlv_payloads_c::get_is_valid() const
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_payloads_c::parse_generic_payload(
+	const ec_cs_tlv_type_e tlv_type,
+	const ec_cs_tlv_header_c * const header)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status(eap_status_process_general_error);
+
+	/*
+	 *  TLV-header:
+	 *  0                   1                   2                   3   
+	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * |M|R|   TLV Type                |         Data Length           |
+	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+	 * |         Data ... 
+	 * +-+-+-+-+-+-+-+-+-+-
+	 */
+	if (header->get_header_buffer_length() < header->get_header_length())
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools,
+			TRACE_FLAGS_ERROR,
+			(EAPL("ERROR: ec_cs_tlv_payloads_c::parse_generic_payload(0x%08x): ")
+			 EAPL("current header 0x%08x=%s, required length 0x%08x, packet length too less 0x%08x.\n"),
+			 header,
+			 tlv_type,
+			 header->get_tlv_string(),
+			 header->get_header_length(),
+			 header->get_header_buffer_length()));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	u32_t data_length = header->get_data_length();
+
+	u8_t * const data
+		= static_cast<u8_t *>(header->get_data_offset(0ul, data_length));
+
+	if (data == 0)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools, 
+			TRACE_FLAGS_ERROR, 
+			(EAPL("ERROR: ec_cs_tlv_payloads_c::parse_generic_payload(0x%08x): ")
+			 EAPL("current header 0x%08x=%s, length 0x%04x, data buffer incorrect.\n"),
+			 header,
+			 tlv_type,
+			 header->get_tlv_string(),
+			 header->get_data_length()));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	EC_CS_TLV_TRACE_PAYLOAD("Parse EC-CS-TLV", header, m_is_client);
+
+	status = copy_tlv_data(
+		tlv_type,
+		data,
+		data_length);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_payloads_c::verify_padding(
+	const u8_t * const possible_padding,
+	const u32_t possible_padding_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::verify_padding()\n")));
+
+	const u8_t padding_byte = static_cast<u8_t>(possible_padding_length);
+
+	for (u32_t ind = 0ul; ind < possible_padding_length; ind++)
+	{
+		if (possible_padding[ind] != padding_byte)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_padding);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_payloads_c::parse_ec_cs_payloads(
+	void * const message_buffer,
+	u32_t * const buffer_length,
+	u32_t * const padding_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::parse_ec_cs_payloads()\n")));
+
+	*padding_length = 0ul;
+
+	if (*buffer_length == 0)
+	{
+		// Empty payload.
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("parse_ec_cs_payloads"),
+		 message_buffer,
+		 *buffer_length));
+
+	ec_cs_tlv_header_c payload(
+		m_am_tools,
+		message_buffer,
+		*buffer_length); // Const correctness is gone.
+
+	ec_cs_tlv_type_e current_payload = payload.get_type();
+
+	eap_status_e status = eap_status_header_corrupted;
+
+	if (payload.get_is_valid() == true
+		&& current_payload >= ec_cs_tlv_type_first_known
+		&& current_payload <= ec_cs_tlv_type_last_known)
+	{
+		if (*buffer_length < payload.get_header_buffer_length())
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_ERROR,
+				(EAPL("ERROR: ec_cs_tlv_payloads_c::parse_ec_cs_payloads(0x%08x): ")
+				 EAPL("current payload 0x%08x=%s, data length 0x%04x, buffer length 0x%04x.\n"),
+				 payload.get_header_buffer(0ul),
+				 current_payload,
+				 payload.get_tlv_string(),
+				 payload.get_data_length(),
+				 *buffer_length));
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_ERROR,
+				(EAPL("ERROR: ec_cs_tlv_payloads_c::parse_ec_cs_payloads(): ")
+				 EAPL("EC-CS-payload header is corrupted.\n")));
+			EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"),
+				payload.get_header_buffer(*buffer_length),
+				*buffer_length));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+		}
+
+		status = parse_generic_payload(
+			current_payload,
+			&payload);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		u32_t prev_avp_length = payload.get_header_length() + payload.get_data_length();
+		if (*buffer_length < prev_avp_length)
+		{
+			// We do have only the current payload. So not padding is included.
+			prev_avp_length = payload.get_header_length() + payload.get_data_length();
+		}
+
+		EAP_ASSERT_ALWAYS(*buffer_length >= prev_avp_length);
+		*buffer_length -= prev_avp_length;
+
+		u32_t remaining_data_length(0ul);
+
+		remaining_data_length = payload.get_header_buffer_length() - prev_avp_length;
+
+		payload.set_header_buffer(
+			payload.get_header_offset(prev_avp_length, remaining_data_length),
+			remaining_data_length);
+
+		while(*buffer_length >= payload.get_header_length()
+			&& payload.get_is_valid() == true
+			&& payload.get_header_buffer_length() >= payload.get_header_buffer_length())
+		{
+			current_payload = payload.get_type();
+			if (current_payload == ec_cs_tlv_type_none)
+			{
+				// This might be padding in the end of the message.
+				break;
+			}
+
+			if (*buffer_length < payload.get_header_buffer_length())
+			{
+				EAP_TRACE_ERROR(
+					m_am_tools,
+					TRACE_FLAGS_ERROR,
+					(EAPL("ERROR: ec_cs_tlv_payloads_c::parse_ec_cs_payloads(0x%08x): ")
+					 EAPL("current payload 0x%08x=%s, payload data length 0x%04x, payload length 0x%04x, buffer length 0x%04x.\n"),
+					 payload.get_header_buffer(0ul),
+					 current_payload,
+					 payload.get_tlv_string(),
+					 payload.get_data_length(),
+					 payload.get_data_length(),
+					 *buffer_length));
+				EAP_TRACE_ERROR(
+					m_am_tools,
+					TRACE_FLAGS_ERROR,
+					(EAPL("ERROR: ec_cs_tlv_payloads_c::parse_ec_cs_payloads(): ")
+					 EAPL("EC-CS-payload header is corrupted.\n")));
+				EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"),
+					payload.get_header_buffer(*buffer_length),
+					*buffer_length));
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+			}
+
+			status = parse_generic_payload(
+				current_payload,
+				&payload);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			prev_avp_length = payload.get_header_length() + payload.get_data_length();
+			if (*buffer_length < prev_avp_length)
+			{
+				// We do have only the current payload. So not padding is included.
+				prev_avp_length = payload.get_header_length() + payload.get_data_length();
+			}
+
+			EAP_ASSERT_ALWAYS(*buffer_length >= prev_avp_length);
+			*buffer_length -= prev_avp_length;
+
+			remaining_data_length = payload.get_header_buffer_length() - prev_avp_length;
+
+			payload.set_header_buffer(
+				payload.get_header_offset(prev_avp_length, remaining_data_length),
+				remaining_data_length);
+		} // while()
+
+		if (*buffer_length != 0u)
+		{
+			const u8_t * const possible_padding = payload.get_header_buffer(remaining_data_length);
+					
+			// First check is this padding
+			if (possible_padding == 0
+				|| remaining_data_length != *buffer_length
+				|| verify_padding(possible_padding, remaining_data_length) != eap_status_ok)
+			{
+				EAP_TRACE_ERROR(
+					m_am_tools,
+					TRACE_FLAGS_ERROR,
+					(EAPL("ERROR: ec_cs_tlv_payloads_c::parse_ec_cs_payloads(): ")
+					 EAPL("EC-CS-header is corrupted. Buffer length and payload ")
+					 EAPL("length does not match. %lu illegal bytes.\n"),
+					 *buffer_length));
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+			}
+			else
+			{
+				// OK, we get correct padding.
+				*padding_length = remaining_data_length;
+			}
+		}
+	}
+	else
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_payloads_c::create_ec_cs_tlv_message(
+	ec_cs_tlv_message_c * const new_ec_cs_tlv_message_data,
+	const bool add_payloads) const
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::create_ec_cs_tlv_message()\n")));
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (add_payloads == false)
+	{
+		status = new_ec_cs_tlv_message_data->reset();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	const u32_t tlv_count(get_tlv_count());
+	u32_t tlv_index(0ul);
+
+	while (tlv_index < tlv_count)
+	{
+		ec_cs_variable_data_c * tlv = get_tlv(tlv_index);
+		if (tlv == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		status = new_ec_cs_tlv_message_data->get_ec_cs_message_data()->add_data(tlv->get_full_tlv_buffer());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EC_CS_TLV_TRACE_PAYLOAD("Added EC-CS-TLV payload", tlv->get_header(), m_is_client);
+
+		++tlv_index;
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::create_ec_cs_tlv_message(): index %d\n"),
+			tlv_index));
+
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::create_ec_cs_tlv_message() returns\n")));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e ec_cs_tlv_payloads_c::reset()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = m_payload_map.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_read_payloads.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_tlv_payloads_c * ec_cs_tlv_payloads_c::copy() const
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("EC-CS:     message_function: ec_cs_tlv_payloads_c::copy()\n")));
+
+	ec_cs_tlv_payloads_c * copy_payloads = new ec_cs_tlv_payloads_c(m_am_tools, m_is_client);
+
+	if (copy_payloads == 0
+		|| copy_payloads->get_is_valid() == false)
+	{
+		delete copy_payloads;
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return 0;
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	const u32_t tlv_count(get_tlv_count());
+	u32_t tlv_index(0ul);
+
+	while (tlv_index < tlv_count)
+	{
+		ec_cs_variable_data_c * tlv = get_tlv(tlv_index);
+		if (tlv == 0)
+		{
+			delete copy_payloads;
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return 0;
+		}
+
+		status = copy_payloads->add_tlv(
+			tlv->copy());
+
+		if (status != eap_status_ok)
+		{
+			delete copy_payloads;
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return 0;
+		}
+
+		++tlv_index;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return copy_payloads;
+}
+
+//--------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/makefile	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,40 @@
+#.EXPORT_ALL_VARIABLES:
+
+DLL_TARGET = do_dll
+
+LIBRARY_NAME := $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_wapi
+
+ifdef USE_WAPI_CORE
+SRC_FILES_CPP = \
+	$(WAPI_COMMON)/src/ec_cs_data.cpp \
+	$(WAPI_COMMON)/src/ec_cs_strings.cpp \
+	$(WAPI_COMMON)/src/ec_cs_tlv.cpp \
+	$(WAPI_COMMON)/src/ec_cs_tlv_header.cpp \
+	$(WAPI_COMMON)/src/ec_cs_tlv_message.cpp \
+	$(WAPI_COMMON)/src/ec_cs_tlv_payloads.cpp \
+	$(WAPI_COMMON)/src/wai_message.cpp \
+	$(WAPI_COMMON)/src/wai_message_payloads.cpp \
+	$(WAPI_COMMON)/src/wai_protocol_packet_header.cpp \
+	$(WAPI_COMMON)/src/wai_tlv_header.cpp \
+	$(WAPI_COMMON)/src/wai_usksa.cpp \
+	$(WAPI_COMMON)/src/wai_variable_data.cpp \
+	$(WAPI_COMMON)/src/wapi_core.cpp \
+	$(WAPI_COMMON)/src/wapi_strings.cpp \
+	$(WAPI_COMMON)/src/wapi_core_retransmission.cpp \
+
+#	$(WAPI_COMMON)/src/wapi_message_wlan_authentication.cpp \
+#	$(WAPI_COMMON)/src/wapi_wlan_authentication.cpp \
+
+SRC_FILES_C = 
+
+endif
+
+
+LIBS = $(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_am_common.$(LIB) \
+	$(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_eap_core.$(LIB) \
+	$(WLAN_LINUX)/project/$(EAP_OSTYPE)/gcc_tls_tools.$(LIB) \
+	-lstdc++
+
+include $(WLAN_LINUX)/base.mak
+
+# end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wai_message.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,144 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wai_message.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 11 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 711 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_memory.h"
+#include "eap_tools.h"
+#include "eap_array.h"
+#include "wai_message.h"
+
+/** @file */
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_message_c::~wai_message_c()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_message_c::wai_message_c(
+	abs_eap_am_tools_c * const tools,
+	const bool is_client)
+	: m_am_tools(tools)
+	, m_message_data(tools)
+	, m_is_client(is_client)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_message_c::reset()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = m_message_data.reset();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_message_c::set_wai_message_data(
+	const eap_variable_data_c * const wai_message_data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = m_message_data.set_copy_of_buffer(wai_message_data);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const eap_variable_data_c * wai_message_c::get_wai_message_data() const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return &m_message_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_variable_data_c * wai_message_c::get_wai_message_data_writable()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return &m_message_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool wai_message_c::get_is_valid() const
+{
+	return m_message_data.get_is_valid();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_message_c * wai_message_c::copy() const
+{
+	wai_message_c * new_message = new wai_message_c(
+		m_am_tools,
+		m_is_client);
+	if (new_message == 0
+		|| new_message->get_is_valid() == false)
+	{
+		return 0;
+	}
+
+	eap_status_e status = new_message->set_wai_message_data(get_wai_message_data());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, status);
+		return 0;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return new_message;
+}
+
+//--------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wai_message_payloads.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,1031 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wai_message_payloads.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 35 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 709 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+
+#include "eap_am_memory.h"
+#include "wai_message_payloads.h"
+#include "wai_message.h"
+#include "abs_eap_am_tools.h"
+#include "eap_tools.h"
+#include "eap_array_algorithms.h"
+#include "eap_automatic_variable.h"
+#include "eap_crypto_api.h"
+#include "wapi_strings.h"
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_message_payloads_c::~wai_message_payloads_c()
+{
+}
+
+//--------------------------------------------------
+
+#if defined(_WIN32) && !defined(__GNUC__)
+	#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
+#endif
+
+EAP_FUNC_EXPORT wai_message_payloads_c::wai_message_payloads_c(
+	abs_eap_am_tools_c * const tools,
+	const bool true_when_is_client)
+	: m_am_tools(tools)
+	, m_message(tools)
+	, m_wai_protocol_packet_header(tools, 0, 0ul)
+	, m_payload_map(tools, this)
+	, m_read_payloads(tools)
+	, m_payload_index(0ul)
+	, m_is_client(true_when_is_client)
+	, m_is_valid(false)
+{
+	m_is_valid = true;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::initialise_header()
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAI:     message_function: wai_message_payloads_c::initialise_header()\n")));
+
+	eap_status_e status = m_message.init(m_wai_protocol_packet_header.get_header_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_message.set_data_length(m_wai_protocol_packet_header.get_header_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_wai_protocol_packet_header.set_header_buffer(
+		m_message.get_data(),
+		m_message.get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_wai_protocol_packet_header.reset_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const wai_protocol_packet_header_c * wai_message_payloads_c::get_wai_protocol_packet_header() const
+{
+	EAP_ASSERT_TOOLS(m_am_tools, (m_message.get_is_valid_data() == true));
+
+	return &m_wai_protocol_packet_header;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_protocol_packet_header_c * wai_message_payloads_c::get_wai_protocol_packet_header_writable()
+{
+	EAP_ASSERT_TOOLS(m_am_tools, (m_message.get_is_valid_data() == true));
+
+	return &m_wai_protocol_packet_header;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_variable_data_c * wai_message_payloads_c::get_tlv_pointer(
+	const wai_payload_type_e current_payload,
+	u32_t index) const
+{
+	eap_variable_data_c selector(m_am_tools);
+
+	if (selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return 0;
+	}
+
+	selector.set_buffer(
+		&current_payload,
+		sizeof(current_payload),
+		false,
+		false);
+
+	wai_variable_data_c *payload = m_payload_map.get_handler(&selector);
+
+	while (index != 0ul && payload != 0)
+	{
+		--index;
+		payload = payload->get_next_payload_with_same_tlv_type();
+	}
+
+	return payload;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_variable_data_c * wai_message_payloads_c::get_tlv_pointer(
+	const wai_payload_type_e current_payload) const
+{
+	return get_tlv_pointer(current_payload, 0ul);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wai_message_payloads_c::get_tlv_count() const
+{
+	return m_read_payloads.get_object_count();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_variable_data_c * wai_message_payloads_c::get_tlv(
+	const u32_t tlv_index) const
+{
+	wai_variable_data_c *payload = m_read_payloads.get_object(tlv_index);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAI:     message_function: wai_message_payloads_c::get_tlv(index %d, count %d) = %s\n"),
+		tlv_index,
+		m_read_payloads.get_object_count(),
+		payload->get_wai_payload_type_string()));
+
+	return payload;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::insert_payload(
+	const wai_variable_data_c * const new_payload)
+{
+	wai_variable_data_c * const copy_payload = new_payload->copy();
+	if (copy_payload == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	return m_read_payloads.add_object(copy_payload, true);
+}
+
+//--------------------------------------------------
+
+#if 0
+
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::check_payloads_existense(
+	const wai_payload_type_e * const needed_payloads,
+	const u32_t count_of_needed_payloads) const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAI:     message_function: wai_message_payloads_c::check_payloads_existense()\n")));
+
+	for (u32_t ind = 0ul; ind < count_of_needed_payloads; ind++)
+	{
+		const wai_payload_type_e required_avp_code = needed_payloads[ind];
+		if (required_avp_code == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		if (get_tlv_pointer(required_avp_code) == 0)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("not received TLV 0x%08x.\n"),
+				 required_avp_code));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+#endif
+
+//--------------------------------------------------
+
+#if 0
+
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::check_payloads_existense(
+	EAP_TEMPLATE_CONST eap_array_c<wai_payload_type_e> * const needed_payloads) const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAI:     message_function: wai_message_payloads_c::check_payloads_existense()\n")));
+
+	for (u32_t ind = 0ul; ind < needed_payloads->get_object_count(); ind++)
+	{
+		const wai_payload_type_e * const required_avp_code = needed_payloads->get_object(ind);
+		if (required_avp_code == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		if (get_tlv_pointer(*required_avp_code) == 0)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("not received TLV 0x%08x.\n"),
+				 *required_avp_code));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+#endif
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::copy_tlv(
+	const wai_message_payloads_c * const source,
+	const wai_payload_type_e tlv)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAI:     message_function: wai_message_payloads_c::copy_tlv(TLV 0x%08x)\n"),
+		tlv));
+
+	const wai_variable_data_c * const payload
+		= source->get_tlv_pointer(tlv, 0ul);
+	if (payload == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_missing_payload);
+	}
+
+	eap_status_e status = add_tlv(
+		payload->copy());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::add_tlv(
+	wai_variable_data_c * const new_payload)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAI:     message_function: wai_message_payloads_c::add_tlv(): %s\n"),
+		wapi_strings_c::get_wai_payload_type_string(new_payload->get_payload_type())));
+
+	if (new_payload == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	WAI_VARIABLE_DATA_TRACE(m_am_tools, "wai_message_payloads_c::add_tlv()", new_payload, m_is_client);
+
+	wai_variable_data_c * const copy_payload = new_payload->copy();
+	if (copy_payload == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	WAI_VARIABLE_DATA_TRACE(m_am_tools, "wai_message_payloads_c::add_tlv() copy", copy_payload, m_is_client);
+
+	eap_status_e status(eap_status_process_general_error);
+
+	eap_automatic_variable_c<wai_variable_data_c>
+		automatic_new_payload(m_am_tools, copy_payload);
+
+	const wai_payload_type_e new_payload_type(copy_payload->get_payload_type());
+		
+	wai_variable_data_c *old_payload = get_tlv_pointer(
+		new_payload_type);
+
+	{
+		eap_variable_data_c selector(m_am_tools);
+
+		if (selector.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = selector.set_copy_of_buffer(
+			&new_payload_type,
+			sizeof(new_payload_type));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+		
+		if (old_payload == 0)
+		{
+			status = m_payload_map.add_handler(&selector, copy_payload);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		else
+		{
+			// Cannot add dublicate payload to m_payload_map.
+			// Instead we add apointer to the next payload with the same tlv type.
+			old_payload->add_next_payload_with_same_tlv_type(copy_payload);
+		}
+
+		automatic_new_payload.do_not_free_variable();
+
+		// Note the same payload object is added to m_read_payloads as to m_payload_map.
+		status = m_read_payloads.add_object(copy_payload, false);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	status = m_wai_protocol_packet_header.set_length(m_wai_protocol_packet_header.get_length() + copy_payload->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::copy_tlv_data(
+	const wai_payload_type_e current_payload,
+	const void * const data,
+	const u32_t data_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAI:     message_function: wai_message_payloads_c::copy_tlv_data(TLV 0x%08x)\n"),
+		current_payload));
+
+	eap_status_e status(eap_status_process_general_error);
+
+	wai_variable_data_c new_payload(m_am_tools);
+	if (new_payload.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = new_payload.set_copy_of_buffer(
+		current_payload,
+		data,
+		data_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+	
+	status = add_tlv(&new_payload);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool wai_message_payloads_c::get_is_valid() const
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::parse_generic_payload(
+	const wai_payload_type_e payload_type,
+	const wai_variable_data_c * const wai_data,
+	u32_t * const prev_payload_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (wai_data == 0
+		|| wai_data->get_is_valid() == false)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools,
+			TRACE_FLAGS_ERROR,
+			(EAPL("ERROR: wai_message_payloads_c::parse_generic_payload(): illegal wai_data=0x%08x")
+			 EAPL("current header 0x%08x=%s.\n"),
+			 wai_data,
+			 payload_type,
+			 wapi_strings_c::get_wai_payload_type_string(payload_type)));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	const u32_t data_length(wai_data->get_data_length());
+	const u32_t type_length(wai_data->get_type_header_length() + wai_data->get_type_data_length());
+	const u8_t * const data = wai_data->get_data(type_length);
+
+	*prev_payload_length = 0ul;
+
+	if (data_length < type_length)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools,
+			TRACE_FLAGS_ERROR,
+			(EAPL("ERROR: wai_message_payloads_c::parse_generic_payload(0x%08x): wai_data=0x%08x")
+			 EAPL("current header 0x%08x=%s, required length 0x%08x, packet length too less 0x%08x.\n"),
+			 data,
+			 wai_data,
+			 payload_type,
+			 wapi_strings_c::get_wai_payload_type_string(payload_type),
+			 type_length,
+			 data_length));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	if (data == 0)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools, 
+			TRACE_FLAGS_ERROR, 
+			(EAPL("ERROR: wai_message_payloads_c::parse_generic_payload(0x%08x): wai_data=0x%08x")
+			 EAPL("current header 0x%08x=%s, type length 0x%04x, data buffer incorrect.\n"),
+			 data,
+			 wai_data,
+			 payload_type,
+			 wapi_strings_c::get_wai_payload_type_string(payload_type),
+			 type_length));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	WAI_VARIABLE_DATA_TRACE(m_am_tools, "Parse WAI-TLV payload", wai_data, m_is_client);
+
+	status = copy_tlv_data(
+		wai_data->get_payload_type(),
+		data,
+		data_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	*prev_payload_length = type_length;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::parse_wai_payloads(
+	void * const message_buffer,
+	const u32_t buffer_length,
+	u32_t * const padding_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAI:     message_function: wai_message_payloads_c::parse_wai_payloads()\n")));
+
+	eap_status_e status = eap_status_header_corrupted;
+
+	*padding_length = 0ul;
+
+	if (buffer_length == 0)
+	{
+		// Empty payload.
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+
+	u32_t remaining_data_length(buffer_length);
+	u32_t remaining_data_offset(0ul);
+
+
+	status = m_message.set_copy_of_buffer(message_buffer, remaining_data_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_wai_protocol_packet_header.set_header_buffer(
+		m_message.get_data(),
+		m_message.get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_wai_protocol_packet_header.check_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	remaining_data_length -= m_wai_protocol_packet_header.get_header_length();
+	remaining_data_offset += m_wai_protocol_packet_header.get_header_length();
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("parse_wai_payloads"),
+		 m_message.get_data(),
+		 m_message.get_data_length()));
+
+	const wai_payload_type_e * required_payloads = 0;
+
+	switch(m_wai_protocol_packet_header.get_subtype())
+	{
+
+	case wai_protocol_subtype_pre_authentication_start:
+	case wai_protocol_subtype_stakey_request:
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+
+	case wai_protocol_subtype_authentication_activation:
+		required_payloads = required_payloads_authentication_activation;
+		break;
+	case wai_protocol_subtype_access_authentication_request:
+		required_payloads = required_payloads_access_authentication_request;
+		break;
+	case wai_protocol_subtype_access_authentication_response:
+		required_payloads = required_payloads_access_authentication_response;
+		break;
+	case wai_protocol_subtype_certificate_authentication_request:
+		required_payloads = required_payloads_certificate_authentication_request;
+		break;
+	case wai_protocol_subtype_certificate_authentication_response:
+		required_payloads = required_payloads_certificate_authentication_response;
+		break;
+	case wai_protocol_subtype_unicast_key_negotiation_request:
+		required_payloads = required_payloads_unicast_key_negotiation_request;
+		break;
+	case wai_protocol_subtype_unicast_key_negotiation_response:
+		required_payloads = required_payloads_unicast_key_negotiation_response;
+		break;
+	case wai_protocol_subtype_unicast_key_negotiation_confirmation:
+		required_payloads = required_payloads_unicast_key_negotiation_confirmation;
+		break;
+	case wai_protocol_subtype_multicast_key_announcement:
+		required_payloads = required_payloads_multicast_key_announcement;
+		break;
+	case wai_protocol_subtype_multicast_key_announcement_response:
+		required_payloads = required_payloads_multicast_key_announcement_response;
+		break;
+	default:
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+
+	}; // switch()
+
+
+	u32_t payload_index(0ul);
+
+	wai_variable_data_c payload(
+		m_am_tools);
+
+	status = payload.set_buffer(
+		required_payloads[payload_index],
+		m_wai_protocol_packet_header.get_data(m_wai_protocol_packet_header.get_data_length()),
+		m_wai_protocol_packet_header.get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	if (payload.get_is_valid() == true
+		&& required_payloads[payload_index] >= wai_tlv_type_first_known
+		&& required_payloads[payload_index] <= wai_tlv_type_last_known)
+	{
+		if (remaining_data_length < payload.get_data_length())
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_ERROR,
+				(EAPL("ERROR: wai_message_payloads_c::parse_wai_payloads(0x%08x): ")
+				 EAPL("current payload 0x%08x=%s, buffer length 0x%04x.\n"),
+				 payload.get_data(0ul),
+				 required_payloads[payload_index],
+				 wapi_strings_c::get_wai_payload_type_string(required_payloads[payload_index]),
+				 remaining_data_length));
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_ERROR,
+				(EAPL("ERROR: wai_message_payloads_c::parse_wai_payloads(): ")
+				 EAPL("WAI-payload header is corrupted.\n")));
+			EAP_TRACE_DATA_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("payload"),
+				payload.get_data(remaining_data_length),
+				remaining_data_length));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+		}
+
+		u32_t prev_payload_length(0ul);
+
+		status = parse_generic_payload(
+			required_payloads[payload_index],
+			&payload,
+			&prev_payload_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		bool optional_payload_is_included(false);
+
+		{
+			// Check whether the optional payload is included.
+
+			const u8_t * const flag = payload.get_data(sizeof(*flag));
+			if (flag == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			if (((*flag) & wai_data_flag_mask_Optional_Field) != 0)
+			{
+				optional_payload_is_included = true;
+			}
+		}
+
+		if (remaining_data_length < prev_payload_length)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		remaining_data_length -= prev_payload_length;
+		remaining_data_offset += prev_payload_length;
+
+		++payload_index;
+		if (required_payloads[payload_index] == wai_payload_type_terminator)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (optional_payload_is_included == false
+			&& required_payloads[payload_index] == wai_payload_type_optional)
+		{
+			++payload_index;
+			if (required_payloads[payload_index] == wai_payload_type_terminator)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+		}
+
+		status = payload.set_buffer(
+			required_payloads[payload_index],
+			m_message.get_data_offset(remaining_data_offset, remaining_data_length),
+			remaining_data_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		u32_t type_length(payload.get_type_header_length() + payload.get_type_data_length());
+
+		while(remaining_data_length > 0ul
+			&& remaining_data_length >= type_length
+			&& payload.get_is_valid() == true)
+		{
+			status = parse_generic_payload(
+				required_payloads[payload_index],
+				&payload,
+				&prev_payload_length);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			if (remaining_data_length < prev_payload_length
+				|| prev_payload_length == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			remaining_data_length -= prev_payload_length;
+			remaining_data_offset += prev_payload_length;
+
+#if 1
+			if (required_payloads[payload_index] != wai_payload_type_optional)
+			{
+				++payload_index;
+			}
+			else
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("WAI:     message_function: wai_message_payloads_c::parse_wai_payloads(): parse optional payload.\n")));
+			}
+#else
+			if (optional_payload_is_included == false
+				|| required_payloads[payload_index] != wai_payload_type_optional)
+			{
+				++payload_index;
+				if (required_payloads[payload_index] == wai_payload_type_terminator)
+				{
+					break;
+				}
+
+				if (optional_payload_is_included == false
+					&& required_payloads[payload_index] == wai_payload_type_optional)
+				{
+					++payload_index;
+					if (required_payloads[payload_index] == wai_payload_type_terminator)
+					{
+						break;
+					}
+				}
+			}
+#endif
+
+			status = payload.set_buffer(
+				required_payloads[payload_index],
+				m_message.get_data_offset(remaining_data_offset, remaining_data_length),
+				remaining_data_length);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			type_length = (payload.get_type_header_length() + payload.get_type_data_length());
+
+		} // while()
+
+
+		if (remaining_data_length != 0u)
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_ERROR,
+				(EAPL("ERROR: wai_message_payloads_c::parse_wai_payloads(): ")
+				 EAPL("WAI-header is corrupted. Buffer length and payload ")
+				 EAPL("length does not match. %lu illegal bytes.\n"),
+				 remaining_data_length));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+		}
+	}
+	else
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::create_wai_tlv_message(
+	wai_message_c * const new_wai_message_data,
+	const bool add_payloads) const
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAI:     message_function: wai_message_payloads_c::create_wai_tlv_message()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wai_message_payloads_c::create_wai_tlv_message()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (add_payloads == false)
+	{
+		status = new_wai_message_data->reset();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = new_wai_message_data->get_wai_message_data_writable()->add_data(
+			m_wai_protocol_packet_header.get_header_buffer(m_wai_protocol_packet_header.get_header_length()),
+			m_wai_protocol_packet_header.get_header_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	const u32_t tlv_count(get_tlv_count());
+	u32_t tlv_index(0ul);
+
+	while (tlv_index < tlv_count)
+	{
+		wai_variable_data_c * wai_data = get_tlv(tlv_index);
+		if (wai_data == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		status = new_wai_message_data->get_wai_message_data_writable()->add_data(wai_data->get_full_tlv_buffer());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		WAI_VARIABLE_DATA_TRACE(m_am_tools, "Added WAI-TLV payload", wai_data, m_is_client);
+
+		++tlv_index;
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAI:     message_function: wai_message_payloads_c::create_wai_tlv_message(): index %d\n"),
+			tlv_index));
+
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_message_payloads_c::reset()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = m_message.reset_start_offset_and_data_length();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+		
+	status = m_payload_map.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_read_payloads.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_message_payloads_c * wai_message_payloads_c::copy() const
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAI:     message_function: wai_message_payloads_c::copy()\n")));
+
+	wai_message_payloads_c * copy_payloads = new wai_message_payloads_c(m_am_tools, m_is_client);
+
+	if (copy_payloads == 0
+		|| copy_payloads->get_is_valid() == false)
+	{
+		delete copy_payloads;
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return 0;
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	const u32_t tlv_count(get_tlv_count());
+	u32_t tlv_index(0ul);
+
+	while (tlv_index < tlv_count)
+	{
+		wai_variable_data_c * wai_data = get_tlv(tlv_index);
+		if (wai_data == 0)
+		{
+			delete copy_payloads;
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return 0;
+		}
+
+		status = copy_payloads->add_tlv(
+			wai_data->copy());
+
+		if (status != eap_status_ok)
+		{
+			delete copy_payloads;
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return 0;
+		}
+
+		++tlv_index;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return copy_payloads;
+}
+
+//--------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wai_protocol_packet_header.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,542 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wai_protocol_packet_header.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 18 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 702 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_memory.h"
+#include "wai_protocol_packet_header.h"
+
+/** @file */
+
+
+/**
+ * The destructor of the wai_protocol_packet_header_c class does nothing.
+ */
+wai_protocol_packet_header_c::~wai_protocol_packet_header_c()
+{
+}
+
+/**
+ * The constructor of the wai_protocol_packet_header_c class.
+ */
+wai_protocol_packet_header_c::wai_protocol_packet_header_c(
+	abs_eap_am_tools_c * const tools)
+	: eap_general_header_base_c(tools, 0, 0)
+	, m_am_tools(tools)
+{
+}
+
+/**
+ * The constructor of the wai_protocol_packet_header_c class simply initializes the attributes.
+ */
+wai_protocol_packet_header_c::wai_protocol_packet_header_c(
+	abs_eap_am_tools_c * const tools,
+	void * const header_begin,
+	const u32_t header_buffer_length)
+	: eap_general_header_base_c(tools, header_begin, header_buffer_length)
+	, m_am_tools(tools)
+{
+}
+
+/**
+ * This function sets the header buffer.
+ */
+eap_status_e wai_protocol_packet_header_c::set_header_buffer(
+	void * const header_begin,
+	const u32_t header_buffer_length)
+{
+	eap_general_header_base_c::set_header_buffer(reinterpret_cast<u8_t *>(header_begin), header_buffer_length);
+
+	if (get_is_valid() == false)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wai_protocol_packet_header_c::set_header_buffer(): packet buffer corrupted.\n")));
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+/**
+ * This function returns the Version value.
+ */
+wai_protocol_version_e wai_protocol_packet_header_c::get_version() const
+{
+	const u8_t * const data = get_header_offset(m_version_offset, m_version_size);
+	if (data != 0)
+	{
+		u16_t value = eap_read_u16_t_network_order(
+			data, m_version_size);
+
+		EAP_STATIC_ASSERT(m_version_size == sizeof(value));
+
+		return static_cast<wai_protocol_version_e>(value);
+	}
+
+	return wai_protocol_version_none;
+}
+
+/**
+ * This function returns the Type value.
+ */
+wai_protocol_type_e wai_protocol_packet_header_c::get_type() const
+{
+	const u8_t * const data = get_header_offset(m_type_offset, m_type_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_type_size == sizeof(*data));
+
+		return static_cast<wai_protocol_type_e>(*data);
+	}
+
+	return wai_protocol_type_none;
+}
+
+/**
+ * This function returns the Subtype value.
+ */
+wai_protocol_subtype_e wai_protocol_packet_header_c::get_subtype() const
+{
+	const u8_t * const data = get_header_offset(m_subtype_offset, m_subtype_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_subtype_size == sizeof(*data));
+
+		return static_cast<wai_protocol_subtype_e>(*data);
+	}
+
+	return wai_protocol_subtype_none;
+}
+
+/**
+ * This function returns the Reserved value.
+ */
+u16_t wai_protocol_packet_header_c::get_reserved() const
+{
+	const u8_t * const data = get_header_offset(m_reserved_offset, m_reserved_size);
+	if (data != 0)
+	{
+		u16_t value = eap_read_u16_t_network_order(
+			data, m_reserved_size);
+
+		EAP_STATIC_ASSERT(m_reserved_size == sizeof(value));
+
+		return value;
+	}
+
+	return 0xffff;
+}
+
+/**
+ * This function returns the Length value.
+ */
+u32_t wai_protocol_packet_header_c::get_length() const
+{
+	const u8_t * const data = get_header_offset(m_length_offset, m_length_size);
+	if (data != 0)
+	{
+		u16_t value = eap_read_u16_t_network_order(
+			data, m_length_size);
+
+		EAP_STATIC_ASSERT(m_length_size == sizeof(value));
+
+		return value;
+	}
+
+	return 0u;
+}
+
+/**
+ * This function returns the Packet sequence number value.
+ */
+u16_t wai_protocol_packet_header_c::get_packet_sequence_number() const
+{
+	const u8_t * const data = get_header_offset(m_packet_sequence_number_offset, m_packet_sequence_number_size);
+	if (data != 0)
+	{
+		u16_t value = eap_read_u16_t_network_order(
+			data, m_packet_sequence_number_size);
+
+		EAP_STATIC_ASSERT(m_packet_sequence_number_size == sizeof(value));
+
+		return value;
+	}
+
+	return 0u;
+}
+
+/**
+ * This function returns the Fragment sequence number value.
+ */
+u8_t wai_protocol_packet_header_c::get_fragment_sequence_number() const
+{
+	const u8_t * const data = get_header_offset(m_fragment_sequence_number_offset, m_fragment_sequence_number_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_fragment_sequence_number_size == sizeof(*data));
+
+		return (*data);
+	}
+
+	return 0xff;
+}
+
+/**
+ * This function returns the Flag value.
+ */
+u8_t wai_protocol_packet_header_c::get_flag() const
+{
+	const u8_t * const data = get_header_offset(m_flag_offset, m_flag_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_flag_size == sizeof(*data));
+
+		return (*data);
+	}
+
+	return 0xff;
+}
+
+/**
+ * This function returns the header length of WAI protocol packet.
+ */
+u32_t wai_protocol_packet_header_c::get_header_length()
+{
+	return m_data_offset;
+}
+
+/**
+ * This function returns the data length of WAI protocol packet.
+ */
+u32_t wai_protocol_packet_header_c::get_data_length() const
+{
+	u32_t length = get_length();
+
+	if (length >= get_header_length())
+	{
+		return (length - get_header_length());
+	}
+	else
+	{
+		return 0ul;
+	}
+}
+
+/**
+ * This function returns pointer to the offset of data of WAI protocol packet.
+ * @param offset is the offset of queried data in bytes.
+ * @param contignuous_bytes is the length of queried data in bytes.
+ */
+u8_t * wai_protocol_packet_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const
+{
+	u32_t data_length = get_data_length();
+
+	if (data_length >= offset+contignuous_bytes)
+	{
+		u8_t * const data = get_header_offset(m_data_offset, offset+contignuous_bytes);
+		if (data != 0)
+		{
+			return &data[offset];
+		}
+		else
+		{
+			return 0;
+		}
+	}
+	else
+	{
+		EAP_ASSERT_ALWAYS(data_length >= offset+contignuous_bytes);
+	}
+	return 0;
+}
+
+/**
+ * This function returns pointer to the begin of data of WAI protocol packet.
+ * @param contignuous_bytes is the length of queried data in bytes.
+ */
+u8_t * wai_protocol_packet_header_c::get_data(const u32_t contignuous_bytes) const
+{
+	return get_data_offset(0u, contignuous_bytes);
+}
+
+/**
+ * This function checks the header is valid.
+ */
+eap_status_e wai_protocol_packet_header_c::check_header() const
+{
+	if (get_version() != wai_protocol_version_1)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+	else if (get_reserved() != 0)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+	else if (get_length() < get_header_length())
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+	else if (get_length() > get_header_buffer_length())
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+/**
+ * This function sets the Version value.
+ */
+eap_status_e wai_protocol_packet_header_c::set_version(const wai_protocol_version_e version)
+{
+	const u16_t value = static_cast<u16_t>(version);
+
+	u8_t * const data = get_header_offset(m_version_offset, m_version_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_version_size == sizeof(value));
+
+		return EAP_STATUS_RETURN(m_am_tools, eap_write_u16_t_network_order(
+			data,
+			sizeof(value),
+			value));
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function sets the Type value.
+ */
+eap_status_e wai_protocol_packet_header_c::set_type(const wai_protocol_type_e type)
+{
+	const u8_t value = static_cast<u8_t>(type);
+
+	u8_t * const data = get_header_offset(m_type_offset, m_type_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_type_size == sizeof(*data));
+
+		*data = value;
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function sets the Subype value.
+ */
+eap_status_e wai_protocol_packet_header_c::set_subtype(const wai_protocol_subtype_e subtype)
+{
+	const u8_t value = static_cast<u8_t>(subtype);
+
+	u8_t * const data = get_header_offset(m_subtype_offset, m_subtype_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_subtype_size == sizeof(*data));
+
+		*data = value;
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function sets the Reserved value.
+ */
+eap_status_e wai_protocol_packet_header_c::set_reserved(const u16_t reserved)
+{
+	u8_t * const data = get_header_offset(m_reserved_offset, m_reserved_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_version_size == sizeof(reserved));
+
+		return EAP_STATUS_RETURN(m_am_tools, eap_write_u16_t_network_order(
+			data,
+			sizeof(reserved),
+			reserved));
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function sets the Length value.
+ */
+eap_status_e wai_protocol_packet_header_c::set_length(const u32_t length)
+{
+	u8_t * const data = get_header_offset(m_length_offset, m_length_size);
+	if (data != 0
+		&& length <= 0xffff)
+	{
+		const u16_t value = static_cast<u16_t>(length);
+
+		EAP_STATIC_ASSERT(m_length_size == sizeof(value));
+
+		return EAP_STATUS_RETURN(m_am_tools, eap_write_u16_t_network_order(
+			data,
+			sizeof(value),
+			value));
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function sets the Packet sequence number value.
+ */
+eap_status_e wai_protocol_packet_header_c::set_packet_sequence_number(const u16_t packet_sequence_number)
+{
+	u8_t * const data = get_header_offset(m_packet_sequence_number_offset, m_packet_sequence_number_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_packet_sequence_number_size == sizeof(packet_sequence_number));
+
+		return EAP_STATUS_RETURN(m_am_tools, eap_write_u16_t_network_order(
+			data,
+			sizeof(packet_sequence_number),
+			packet_sequence_number));
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function sets the Fragment sequence number value.
+ */
+eap_status_e wai_protocol_packet_header_c::set_fragment_sequence_number(const u8_t fragment_sequence_number)
+{
+	u8_t * const data = get_header_offset(m_fragment_sequence_number_offset, m_fragment_sequence_number_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_fragment_sequence_number_size == sizeof(fragment_sequence_number));
+
+		*data = fragment_sequence_number;
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function sets the Subype value.
+ */
+eap_status_e wai_protocol_packet_header_c::set_flag(const u8_t flag)
+{
+	u8_t * const data = get_header_offset(m_flag_offset, m_flag_size);
+	if (data != 0)
+	{
+		EAP_STATIC_ASSERT(m_flag_size == sizeof(flag));
+
+		*data = flag;
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function resets the WAI protocol packet header.
+ */
+eap_status_e wai_protocol_packet_header_c::reset_header()
+{
+	eap_status_e status = set_version(wai_protocol_version_1);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = set_type(wai_protocol_type_wai);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+	
+	status = set_subtype(wai_protocol_subtype_none);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+	
+	status = set_reserved(0u);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = set_length(get_header_length());
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = set_packet_sequence_number(WAI_FIRST_SEQUENCE_NUMBER);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = set_fragment_sequence_number(WAI_FIRST_FRAGMENT_NUMBER);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = set_flag(0u);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wai_tlv_header.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,258 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wai_tlv_header.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 13 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 708 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_am_memory.h"
+#include "wai_tlv_header.h"
+#include "wapi_strings.h"
+
+/** @file */
+
+
+/**
+ * The destructor of the wai_tlv_header_c class does nothing.
+ */
+wai_tlv_header_c::~wai_tlv_header_c()
+{
+}
+
+/**
+ * The constructor of the wai_tlv_header_c class simply initializes the attributes.
+ */
+wai_tlv_header_c::wai_tlv_header_c(
+	abs_eap_am_tools_c * const tools,
+	void * const header_begin,
+	const u32_t header_buffer_length)
+	: eap_general_header_base_c(tools, header_begin, header_buffer_length)
+	, m_am_tools(tools)
+{
+}
+
+/**
+ * This function returns the TLV Type.
+ */
+wai_tlv_type_e wai_tlv_header_c::get_type() const
+{
+	const u8_t * const data = get_header_offset(m_type_offset, m_type_size);
+	if (data != 0)
+	{
+		u8_t type = data[0];
+
+		return static_cast<wai_tlv_type_e>(type);
+	}
+	else
+	{
+		return wai_tlv_type_none;
+	}
+}
+
+/**
+ * This function returns the data length of TLV.
+ */
+u32_t wai_tlv_header_c::get_data_length() const
+{
+	const u8_t * const length_data = get_header_offset(m_length_offset, m_length_size);
+	if (length_data != 0)
+	{
+		return static_cast<u32_t>(eap_read_u16_t_network_order(length_data, m_length_size));
+	}
+	else
+	{
+		return 0ul;
+	}
+}
+
+/**
+ * This function returns the header length of TLV.
+ */
+u32_t wai_tlv_header_c::get_header_length()
+{
+	return m_data_offset;
+}
+
+/**
+ * This function returns pointer to the offset of data of TLV.
+ * @param offset is the offset of queried data in bytes.
+ * @param contignuous_bytes is the length of queried data in bytes.
+ */
+u8_t * wai_tlv_header_c::get_data_offset(const u32_t offset, const u32_t contignuous_bytes) const
+{
+	EAP_UNREFERENCED_PARAMETER(m_am_tools);
+
+	u32_t data_length = get_data_length(); 
+
+	if (data_length >= offset+contignuous_bytes)
+	{
+		u8_t * const data = get_header_offset(m_data_offset, offset+contignuous_bytes);
+		if (data != 0)
+		{
+			return &data[offset];
+		}
+		else
+		{
+			return 0;
+		}
+	}
+	else
+	{
+		EAP_ASSERT_ALWAYS(data_length >= offset+contignuous_bytes);
+	}
+	return 0;
+}
+
+
+/**
+ * This function returns pointer to the offset of data of TLV.
+ * @param contignuous_bytes is the length of queried data in bytes.
+ */
+u8_t * wai_tlv_header_c::get_data(const u32_t contignuous_bytes) const
+{
+	return get_data_offset(0u, contignuous_bytes);
+}
+
+
+/**
+ * This function return pointer to the next TLV header in the same buffer.
+ */
+u8_t * wai_tlv_header_c::get_next_header() const
+{
+	if (get_header_buffer_length() >= 2ul*get_header_length()+get_data_length())
+	{
+		return get_data_offset(get_data_length(), get_header_length());
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+
+/**
+ * This function checks the header is valid.
+ */
+eap_status_e wai_tlv_header_c::check_header() const
+{
+	if (get_type() == wai_tlv_type_none)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+/**
+ * This function returns debug strings of the TLV type.
+ */
+eap_const_string wai_tlv_header_c::get_tlv_type_string(const wai_tlv_type_e type)
+{
+	return wapi_strings_c::get_wai_tlv_header_string(type);
+}
+
+/**
+ * This function returns debug strings of the TLV type.
+ */
+eap_const_string wai_tlv_header_c::get_tlv_type_string() const
+{
+	const wai_tlv_type_e type = get_type();
+	return get_tlv_type_string(type);
+}
+
+/**
+ * This function sets the TLV Type.
+ */
+eap_status_e wai_tlv_header_c::set_type(const wai_tlv_type_e type)
+{
+	u8_t * const data = get_header_offset(m_type_offset, m_type_size);
+	if (data != 0)
+	{
+		*data = static_cast<u8_t>(type);
+
+		EAP_STATIC_ASSERT(m_type_size == sizeof(u8_t));
+
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function sets the TLV data length.
+ */
+eap_status_e wai_tlv_header_c::set_data_length(const u32_t p_length)
+{
+	u8_t * const data = get_header_offset(m_length_offset, m_length_size);
+	if (data != 0)
+	{
+		const u16_t value(static_cast<u16_t>(p_length));
+
+		EAP_STATIC_ASSERT(m_length_size == sizeof(value));
+
+		return EAP_STATUS_RETURN(m_am_tools, eap_write_u16_t_network_order(
+			data,
+			sizeof(value),
+			value));
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+}
+
+/**
+ * This function resets the TLV header.
+ */
+eap_status_e wai_tlv_header_c::reset_header()
+{
+	eap_status_e status = set_type(wai_tlv_type_none);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = set_data_length(0ul);
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+/**
+ * This function resets the TLV header object.
+ */
+eap_status_e wai_tlv_header_c::reset()
+{
+	eap_general_header_base_c::set_header_buffer(0, 0ul);
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wai_usksa.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,88 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wai_usksa.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 4 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+#include "wai_usksa.h"
+
+//--------------------------------------------------
+
+wai_usksa_c::~wai_usksa_c()
+{
+}
+
+//--------------------------------------------------
+
+wai_usksa_c::wai_usksa_c(abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+	, m_USK(tools)
+	, m_USKID(0ul)
+	, m_unicast_cipher_suite(wai_unicast_cipher_suite_none)
+{
+}
+
+//--------------------------------------------------
+
+bool wai_usksa_c::get_is_valid() const
+{
+	return m_USK.get_is_valid();
+}
+
+//--------------------------------------------------
+
+bool wai_usksa_c::get_is_valid_data() const
+{
+	return m_USK.get_is_valid_data();
+}
+
+//--------------------------------------------------
+
+u8_t wai_usksa_c::get_USKID() const
+{
+	return m_USKID;
+}
+
+//--------------------------------------------------
+
+eap_variable_data_c * wai_usksa_c::get_USK()
+{
+	return &m_USK;
+}
+
+//--------------------------------------------------
+
+wai_unicast_cipher_suite_e wai_usksa_c::get_cipher_suite() const
+{
+	return m_unicast_cipher_suite;
+}
+
+//--------------------------------------------------
+
+void wai_usksa_c::set_USKID(const u8_t USKID)
+{
+	m_USKID = USKID;
+}
+
+//--------------------------------------------------
+
+void wai_usksa_c::set_cipher_suite(const wai_unicast_cipher_suite_e cipher)
+{
+	m_unicast_cipher_suite = cipher;
+}
+
+//--------------------------------------------------
+// End of file.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wai_variable_data.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,1230 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wai_variable_data.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 20 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 710 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+
+#include "eap_am_memory.h"
+#include "wai_message_payloads.h"
+#include "wai_message.h"
+#include "abs_eap_am_tools.h"
+#include "eap_tools.h"
+#include "eap_array_algorithms.h"
+#include "eap_automatic_variable.h"
+#include "eap_crypto_api.h"
+#include "wapi_strings.h"
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_variable_data_c::~wai_variable_data_c()
+{
+	delete get_next_payload_with_same_tlv_type();
+	set_next_payload_with_same_tlv_type(0);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_variable_data_c::wai_variable_data_c(
+	abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+	  , m_data(tools)
+	  , m_wai_tlv_header(tools, 0, 0ul)
+	  , m_ec_cs_tlv_header(tools, 0, 0ul)
+	  , m_payload_type(wai_payload_type_none)
+	  , m_next_payload_with_same_tlv_type(0)
+	  , m_is_valid(false)
+{
+	if (m_data.get_is_valid() == false)
+	{
+		return;
+	}
+
+	m_is_valid = true;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool wai_variable_data_c::get_is_valid() const
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool wai_variable_data_c::get_is_valid_data() const
+{
+	return get_is_valid() && m_data.get_is_valid_data();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_payload_type_e wai_variable_data_c::convert_to_wai_payload_type(const wai_tlv_type_e tlv_type)
+{
+	switch(tlv_type)
+	{
+	case wai_tlv_type_signature_attribute:
+		return wai_payload_type_signature_attributes;
+	case wai_tlv_type_result_of_certificate_validation:
+		return wai_payload_type_result_of_certificate_verification;
+	case wai_tlv_type_identity_list:
+		return wai_payload_type_identity_list;
+	default:
+		return wai_payload_type_none;
+	};
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_tlv_type_e wai_variable_data_c::convert_to_wai_tlv_type(const wai_payload_type_e payload_type)
+{
+	switch(payload_type)
+	{
+	case wai_payload_type_signature_attributes:
+		return wai_tlv_type_signature_attribute;
+	case wai_payload_type_result_of_certificate_verification:
+		return wai_tlv_type_result_of_certificate_validation;
+	case wai_payload_type_identity_list:
+		return wai_tlv_type_identity_list;
+	case wai_payload_type_echd_parameter:
+		return wai_tlv_type_echd_parameter;
+	default:
+		return wai_tlv_type_none;
+	};
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_certificate_identifier_e wai_variable_data_c::convert_to_wai_certificate_identifier(const wai_payload_type_e payload_type)
+{
+	switch(payload_type)
+	{
+	case wai_payload_type_certificate:
+	case wai_payload_type_identity:
+		return wai_certificate_identifier_x_509_v3;
+	default:
+		return wai_certificate_identifier_none;
+	};
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT ec_cs_tlv_type_e wai_variable_data_c::convert_to_ec_cs_tlv_type(const wai_payload_type_e payload_type)
+{
+	switch(payload_type)
+	{
+	case wai_payload_type_certificate:
+	case wai_payload_type_identity:
+		return static_cast<ec_cs_tlv_type_e>(convert_to_wai_certificate_identifier(payload_type));
+	default:
+		return static_cast<ec_cs_tlv_type_e>(payload_type);
+	};
+}
+
+//--------------------------------------------------
+
+eap_status_e wai_variable_data_c::set_header_buffer(
+	const wai_payload_type_e current_payload,
+	const bool write_header)
+{
+	if (m_data.get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+	}
+
+	switch (get_type_class())
+	{
+	case wai_payload_type_size_ec_cs_tlv_header:
+		{
+			m_ec_cs_tlv_header.set_header_buffer(
+				m_data.get_buffer(m_data.get_buffer_length()),
+				m_data.get_buffer_length());
+
+			if (write_header == true)
+			{
+				eap_status_e status = m_ec_cs_tlv_header.reset_header();
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = m_ec_cs_tlv_header.set_type(convert_to_ec_cs_tlv_type(current_payload));
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+		}
+		break;
+	case wai_payload_type_size_wai_tlv_header:
+		{
+			m_wai_tlv_header.set_header_buffer(
+				m_data.get_buffer(m_data.get_buffer_length()),
+				m_data.get_buffer_length());
+
+			if (current_payload == wai_payload_type_optional)
+			{
+				m_payload_type = convert_to_wai_payload_type(m_wai_tlv_header.get_type());
+			}
+			else if (write_header == true)
+			{
+				eap_status_e status = m_wai_tlv_header.reset_header();
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = m_wai_tlv_header.set_type(convert_to_wai_tlv_type(current_payload));
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+		}
+		break;
+	default:
+		;
+	}; // switch
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+eap_status_e wai_variable_data_c::set_header_buffer(
+	const wai_payload_type_e current_payload,
+	const bool write_header,
+	const u32_t data_length)
+{
+	eap_status_e status = set_header_buffer(
+		current_payload,
+		write_header);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	switch (get_type_class())
+	{
+	case wai_payload_type_size_ec_cs_tlv_header:
+		m_ec_cs_tlv_header.set_data_length(static_cast<u16_t>(data_length));
+		break;
+	case wai_payload_type_size_wai_tlv_header:
+		m_wai_tlv_header.set_data_length(static_cast<u16_t>(data_length));
+		break;
+	case wai_payload_type_size_1_octet_length_field:
+		{
+			u8_t * data = m_data.get_data(sizeof(u8_t));
+			if (data == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			if (data_length > 0xff)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short);
+			}
+
+			data[0ul] = static_cast<u8_t>(data_length);
+
+		}
+		break;
+	default:
+		;
+	}; // switch
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::init_header(
+	const wai_payload_type_e current_payload,
+	const u32_t default_buffer_length)
+{
+	if (default_buffer_length > 0xffff)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	eap_status_e status = set_payload_type(current_payload);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_data.set_buffer_length(
+		default_buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	switch (get_type_class())
+	{
+	case wai_payload_type_size_wai_tlv_header:
+		{
+			status = m_data.set_data_length(
+				wai_tlv_header_c::get_header_length());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_wai_tlv_header.reset();
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		break;
+	case wai_payload_type_size_ec_cs_tlv_header:
+		{
+			status = m_data.set_data_length(
+				ec_cs_tlv_header_c::get_header_length());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_ec_cs_tlv_header.reset();
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		break;
+	case wai_payload_type_size_1_octet_length_field:
+		{
+			status = m_data.set_data_length(sizeof(u8_t));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			u8_t * data = m_data.get_data(sizeof(u8_t));
+			if (data == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			data[0ul] = 0u;
+
+		}
+		break;
+	default:
+		break;
+	}; // switch
+
+
+	status = set_header_buffer(current_payload, true);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::reset()
+{
+	(void) m_data.reset();
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::set_buffer(
+	const wai_payload_type_e current_payload,
+	const void * const buffer,
+	const u32_t buffer_length)
+{
+	if (buffer_length > 0xffff)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	eap_status_e status = m_data.set_buffer(
+		buffer,
+		buffer_length,
+		false,
+		false);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = set_payload_type(current_payload);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_wai_tlv_header.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_ec_cs_tlv_header.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = set_header_buffer(current_payload, false);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+u32_t wai_variable_data_c::get_header_length(
+	const wai_payload_type_e current_payload) const
+{
+	switch (get_type_class(current_payload))
+	{
+	case wai_payload_type_size_ec_cs_tlv_header:
+		{
+			return m_ec_cs_tlv_header.get_header_length();
+		}
+	case wai_payload_type_size_wai_tlv_header:
+		{
+			return m_wai_tlv_header.get_header_length();
+		}
+	case wai_payload_type_size_1_octet_length_field:
+		{
+			return sizeof(u8_t);
+		}
+	case wai_payload_type_size_wie:
+		{
+			return WIE_HEADER_LENGTH;
+		}
+	default:
+		{
+			return 0ul;
+		}
+	}; // switch
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::create(
+	const wai_payload_type_e current_payload,
+	const void * const buffer, // Buffer includes only data.
+	const u32_t buffer_length) // Buffer_length includes only data.
+{
+	eap_status_e status = init_header(
+		current_payload,
+		get_header_length(current_payload) + buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_data.add_data(buffer, buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	switch (get_type_class())
+	{
+	case wai_payload_type_size_ec_cs_tlv_header:
+		m_ec_cs_tlv_header.set_data_length(static_cast<u16_t>(buffer_length));
+		break;
+	case wai_payload_type_size_wai_tlv_header:
+		m_wai_tlv_header.set_data_length(static_cast<u16_t>(buffer_length));
+		break;
+	case wai_payload_type_size_1_octet_length_field:
+		{
+			u8_t * data = m_data.get_data(sizeof(u8_t));
+			if (data == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			if (buffer_length > 0xff)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short);
+			}
+
+			data[0ul] = static_cast<u8_t>(buffer_length);
+
+		}
+		break;
+	default:
+		;
+	}; // switch
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::create(
+	const wai_payload_type_e current_payload,
+	const eap_variable_data_c * const buffer) // Buffer includes only data.
+{
+	eap_status_e status = create(
+		current_payload,
+		buffer->get_data(),
+		buffer->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::set_copy_of_buffer(
+	const wai_payload_type_e current_payload,
+	const void * const buffer, // Buffer does include header and data.
+	const u32_t buffer_length) // Buffer_length does include header and data.
+{
+	eap_status_e status = init_header(
+		current_payload,
+		buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_data.set_copy_of_buffer(buffer, buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	switch (get_type_class())
+	{
+	case wai_payload_type_size_ec_cs_tlv_header:
+		m_ec_cs_tlv_header.set_data_length(static_cast<u16_t>(buffer_length - get_type_header_length()));
+		break;
+	case wai_payload_type_size_wai_tlv_header:
+		m_wai_tlv_header.set_data_length(static_cast<u16_t>(buffer_length - get_type_header_length()));
+		break;
+	case wai_payload_type_size_1_octet_length_field:
+		{
+			u8_t * data = m_data.get_data(sizeof(u8_t));
+			if (data == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			if (buffer_length > 0xff)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_buffer_too_short);
+			}
+
+			data[0ul] = static_cast<u8_t>(buffer_length - get_type_header_length());
+
+		}
+		break;
+	default:
+		;
+	}; // switch
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::set_copy_of_buffer(
+	const wai_payload_type_e current_payload,
+	const eap_variable_data_c * const buffer)
+{
+	eap_status_e status = set_copy_of_buffer(
+		current_payload,
+		buffer->get_data(),
+		buffer->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::set_copy_of_buffer(
+	const wai_variable_data_c * const source)
+{
+	eap_status_e status = set_copy_of_buffer(
+			source->get_payload_type(),
+			source->get_data(source->get_data_length()),
+			source->get_data_length());
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	delete get_next_payload_with_same_tlv_type();
+	set_next_payload_with_same_tlv_type(0);
+
+	wai_variable_data_c * previous = this;
+
+	const wai_variable_data_c * next = source->get_next_payload_with_same_tlv_type();
+
+	while (next != 0)
+	{
+		// Copy the next payload in a list too.
+		wai_variable_data_c * const new_payload = next->copy();
+		if (new_payload == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		previous->set_next_payload_with_same_tlv_type(new_payload);
+
+		previous = new_payload;
+
+		next = next->get_next_payload_with_same_tlv_type();
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::add_data(
+	const wai_payload_type_e new_payload,
+	const void * const buffer,
+	const u32_t buffer_length)
+{
+	const wai_payload_type_e current_payload = get_payload_type();
+
+	if (new_payload != current_payload)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+	}
+
+	const u32_t type_data_length(get_type_data_length());
+
+	eap_status_e status = m_data.add_data(
+		buffer,
+		buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = set_header_buffer(current_payload, true, (type_data_length + buffer_length));
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::add_data(
+	const wai_payload_type_e new_payload,
+	const eap_variable_data_c * const buffer)
+{
+	eap_status_e status = add_data(
+		new_payload,
+		buffer->get_data(),
+		buffer->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::add_data(
+	const wai_variable_data_c * const data)
+{
+	eap_status_e status = add_data(
+		data->get_payload_type(),
+		data->get_full_tlv_buffer()->get_data(),
+		data->get_full_tlv_buffer()->get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+wai_payload_type_size_e wai_variable_data_c::get_type_class(const wai_payload_type_e current_payload) const
+{
+	if (current_payload <= wai_payload_type_last_known
+		&& current_payload == wai_payload_type_to_class_map[current_payload].m_type)
+	{
+		return wai_payload_type_to_class_map[current_payload].m_size;
+	}
+	else
+	{
+		return wai_payload_type_size_none;
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_payload_type_size_e wai_variable_data_c::get_type_class() const
+{
+	const wai_payload_type_e current_payload(get_payload_type());
+
+	return get_type_class(current_payload);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wai_variable_data_c::get_type_data_length() const
+{
+	switch (get_type_class())
+	{
+	case wai_payload_type_size_ec_cs_tlv_header:
+		{
+			if (m_data.get_data_length() >= m_ec_cs_tlv_header.get_header_length())
+			{
+				return m_ec_cs_tlv_header.get_data_length();
+			}
+			else
+			{
+				return 0ul;
+			}
+		}
+	case wai_payload_type_size_wai_tlv_header:
+		{
+			if (m_data.get_data_length() >= m_wai_tlv_header.get_header_length())
+			{
+				return m_wai_tlv_header.get_data_length();
+			}
+			else
+			{
+				return 0ul;
+			}
+		}
+	case wai_payload_type_size_1_octet_length_field:
+		{
+			if (m_data.get_data_length() >= sizeof(u8_t))
+			{
+				const u8_t * data = m_data.get_data(sizeof(u8_t));
+				return data[0ul];
+			}
+			else
+			{
+				return 0ul;
+			}
+		}
+	case wai_payload_type_size_wie:
+		{
+			if (m_data.get_data_length() >= WIE_HEADER_LENGTH)
+			{
+				const u8_t * data = m_data.get_data(WIE_HEADER_LENGTH);
+				return data[1ul];
+			}
+			else
+			{
+				return 0ul;
+			}
+		}
+	default:
+		{
+			if (m_data.get_data_length() >= static_cast<u32_t>(get_type_class()))
+			{
+				return get_type_class();
+			}
+			else
+			{
+				return 0ul;
+			}
+		}
+	}; // switch
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wai_variable_data_c::get_type_header_length() const
+{
+	switch (get_type_class())
+	{
+	case wai_payload_type_size_ec_cs_tlv_header:
+		{
+			if (m_data.get_data_length() >= m_ec_cs_tlv_header.get_header_length())
+			{
+				return m_ec_cs_tlv_header.get_header_length();
+			}
+			else
+			{
+				return 0ul;
+			}
+		}
+	case wai_payload_type_size_wai_tlv_header:
+		{
+			if (m_data.get_data_length() >= m_wai_tlv_header.get_header_length())
+			{
+				return m_wai_tlv_header.get_header_length();
+			}
+			else
+			{
+				return 0ul;
+			}
+		}
+	case wai_payload_type_size_1_octet_length_field:
+		{
+			if (m_data.get_data_length() >= sizeof(u8_t))
+			{
+				return sizeof(u8_t);
+			}
+			else
+			{
+				return 0ul;
+			}
+		}
+	case wai_payload_type_size_wie:
+		{
+			if (m_data.get_data_length() >= WIE_HEADER_LENGTH)
+			{
+				return WIE_HEADER_LENGTH;
+			}
+			else
+			{
+				return 0ul;
+			}
+		}
+	default:
+		{
+			return 0ul;
+		}
+	}; // switch
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u8_t * wai_variable_data_c::get_type_data_offset(
+	const u32_t offset,
+	const u32_t data_length) const
+{
+	return m_data.get_data_offset(get_type_header_length()+offset, data_length);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u8_t * wai_variable_data_c::get_type_data(
+	const u32_t data_length) const
+{
+	return get_type_data_offset(0ul, data_length);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wai_variable_data_c::get_data_length() const
+{
+	return get_type_header_length() + get_type_data_length();
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u8_t * wai_variable_data_c::get_data(
+	const u32_t data_length) const
+{
+#if 1
+
+	return m_data.get_data(data_length);
+
+#else
+
+	switch (get_type_class())
+	{
+	case wai_payload_type_size_ec_cs_tlv_header:
+		{
+			return m_ec_cs_tlv_header.get_data(data_length);
+		}
+	case wai_payload_type_size_wai_tlv_header:
+		{
+			return m_wai_tlv_header.get_data(data_length);
+		}
+	case wai_payload_type_size_1_octet_length_field:
+		{
+			if (m_data.get_data_length() >= (sizeof(u8_t) + data_length))
+			{
+				return m_data.get_data_offset(sizeof(u8_t), data_length);
+			}
+			else
+			{
+				return 0;
+			}
+		}
+	case wai_payload_type_size_wie:
+		{
+			if (m_data.get_data_length() >= (WIE_HEADER_LENGTH + data_length))
+			{
+				return m_data.get_data(data_length);
+			}
+			else
+			{
+				return 0;
+			}
+		}
+	case wai_payload_type_size_1_octet:
+	case wai_payload_type_size_12_octets:
+	case wai_payload_type_size_16_octets:
+	case wai_payload_type_size_20_octets:
+	case wai_payload_type_size_32_octets:
+		{
+			return m_data.get_data(data_length);
+		}
+	default:
+		{
+			return 0;
+		}
+	}; // switch
+
+#endif
+
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u8_t * wai_variable_data_c::get_data_offset(const u32_t offset, const u32_t data_length) const
+{
+
+#if 1
+
+	return m_data.get_data_offset(offset, data_length);
+
+#else
+
+	switch (get_type_class())
+	{
+	case wai_payload_type_size_ec_cs_tlv_header:
+		{
+			return m_ec_cs_tlv_header.get_data_offset(offset, data_length);
+		}
+	case wai_payload_type_size_wai_tlv_header:
+		{
+			return m_wai_tlv_header.get_data_offset(offset, data_length);
+		}
+	case wai_payload_type_size_1_octet_length_field:
+		{
+			if (m_data.get_data_length() >= (sizeof(u8_t) + offset + data_length))
+			{
+				return m_data.get_data_offset(offset + sizeof(u8_t), data_length);
+			}
+			else
+			{
+				return 0;
+			}
+		}
+	case wai_payload_type_size_wie:
+		{
+			if (m_data.get_data_length() >= (WIE_HEADER_LENGTH + offset + data_length))
+			{
+				return m_data.get_data_offset(offset + WIE_HEADER_LENGTH, data_length);
+			}
+			else
+			{
+				return 0;
+			}
+		}
+	case wai_payload_type_size_1_octet:
+	case wai_payload_type_size_12_octets:
+	case wai_payload_type_size_16_octets:
+	case wai_payload_type_size_20_octets:
+	case wai_payload_type_size_32_octets:
+		{
+			return m_data.get_data_offset(offset, data_length);
+		}
+	default:
+		{
+			return 0;
+		}
+	}; // switch
+
+#endif
+
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const eap_variable_data_c * wai_variable_data_c::get_full_tlv_buffer() const
+{
+	return &m_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_variable_data_c * wai_variable_data_c::get_writable_full_tlv_buffer()
+{
+	return &m_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const wai_tlv_header_c * wai_variable_data_c::get_wai_tlv_header() const
+{
+	if (get_type_class() == wai_payload_type_size_wai_tlv_header)
+	{
+		return &m_wai_tlv_header;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const ec_cs_tlv_header_c * wai_variable_data_c::get_ec_cs_tlv_header() const
+{
+	if (get_type_class() == wai_payload_type_size_ec_cs_tlv_header)
+	{
+		return &m_ec_cs_tlv_header;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_payload_type_e wai_variable_data_c::get_payload_type() const
+{
+	return m_payload_type;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wai_variable_data_c::set_payload_type(
+	const wai_payload_type_e payload_type)
+{
+	eap_status_e status(eap_status_ok);
+
+	m_payload_type = payload_type;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void wai_variable_data_c::set_next_payload_with_same_tlv_type(
+	wai_variable_data_c * const tlv)
+{
+	m_next_payload_with_same_tlv_type = tlv;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_variable_data_c * wai_variable_data_c::get_next_payload_with_same_tlv_type() const
+{
+	return m_next_payload_with_same_tlv_type;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void wai_variable_data_c::add_next_payload_with_same_tlv_type(
+	wai_variable_data_c * const tlv)
+{
+	wai_variable_data_c *payload = get_next_payload_with_same_tlv_type();
+	wai_variable_data_c *prev_payload = this;
+
+	while (payload != 0)
+	{
+		prev_payload = payload;
+		payload = payload->get_next_payload_with_same_tlv_type();
+	}
+
+	if (prev_payload != 0)
+	{
+		prev_payload->set_next_payload_with_same_tlv_type(tlv);
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_variable_data_c * wai_variable_data_c::copy() const
+{
+	wai_variable_data_c * new_data = new wai_variable_data_c(m_am_tools);
+
+	if (new_data != 0)
+	{
+		eap_status_e status = new_data->set_copy_of_buffer(
+			get_payload_type(),
+			get_data(get_data_length()),
+			get_data_length());
+		if (status != eap_status_ok)
+		{
+			delete new_data;
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			return 0;
+		}
+	}
+
+	return new_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT  void wai_variable_data_c::object_increase_reference_count()
+{
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT i32_t wai_variable_data_c::compare(const wai_variable_data_c * right) const
+{
+	if (get_payload_type() != right->get_payload_type())
+	{
+		return -1;
+	}
+	else if (get_data_length() != right->get_data_length())
+	{
+		return -1;
+	}
+	else
+	{
+		// Compares the (possible) header and data.
+		return m_am_tools->memcmp(get_data(get_data_length()), right->get_data(right->get_data_length()), get_data_length());
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_const_string wai_variable_data_c::get_wai_payload_type_string() const
+{
+	return wapi_strings_c::get_wai_payload_type_string(get_payload_type());
+}
+
+//--------------------------------------------------
+
+void wai_variable_data_c::wai_variable_data_trace(abs_eap_am_tools_c * const tools, eap_format_string prefix, const wai_variable_data_c * const wai_data, const bool when_true_is_client)
+{
+	EAP_TRACE_DEBUG(
+		tools,
+		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
+		(EAPL("v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v \n")));
+
+	EAP_TRACE_DEBUG(
+		tools,
+		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
+		(EAPL("- %s %s (0x%08x): TLV type 0x%04x=%s, data length 0x%04x.\n"),
+		prefix,
+		((when_true_is_client) == true ? "client" : "server"),
+		(wai_data)->get_data((wai_data)->get_data_length()),
+		(wai_data)->get_payload_type(),
+		wapi_strings_c::get_wai_payload_type_string((wai_data)->get_payload_type()),
+		(wai_data)->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		tools,
+		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
+		(wapi_strings_c::get_wai_payload_type_string((wai_data)->get_payload_type()),
+		(wai_data)->get_data((wai_data)->get_data_length()),
+		(wai_data)->get_data_length()));
+
+	EAP_TRACE_DEBUG(
+		tools,
+		TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS,
+		(EAPL("^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ \n")));
+}
+
+//--------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_am_crypto_sms4.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,362 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_am_crypto_sms4.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 4 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 20010 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#include "eap_am_memory.h"
+#include "wapi_am_crypto_sms4.h"
+
+
+//------------------------------------------------------------
+// SMS4 constants 
+
+// CK
+const u32_t wapi_am_crypto_sms4_c::m_CK[wapi_am_crypto_sms4_c::WAPI_AM_CRYPTO_SMS4_CK_u32_COUNT] =
+{
+	0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
+	0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
+	0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
+	0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
+	0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
+	0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
+	0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
+	0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
+};
+
+// FK
+const u32_t wapi_am_crypto_sms4_c::m_FK[wapi_am_crypto_sms4_c::WAPI_AM_CRYPTO_SMS4_FK_u32_COUNT] =
+{
+	0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc
+};
+
+
+// S-box
+const u8_t wapi_am_crypto_sms4_c::m_SBOX[wapi_am_crypto_sms4_c::WAPI_AM_CRYPTO_SMS4_SBOX_u8_SIZE] =
+{
+	0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
+	0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
+	0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
+	0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
+	0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
+	0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
+	0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
+	0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
+	0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
+	0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
+	0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
+	0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
+	0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
+	0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
+	0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
+	0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
+};
+
+//------------------------------------------------------------
+
+
+
+EAP_FUNC_EXPORT wapi_am_crypto_sms4_c::~wapi_am_crypto_sms4_c()
+{
+	m_is_valid = false;
+}
+
+//------------------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_am_crypto_sms4_c::wapi_am_crypto_sms4_c(
+	abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+	, m_is_valid(false)
+{
+	set_is_valid();
+}
+
+//------------------------------------------------------------
+
+EAP_FUNC_EXPORT void wapi_am_crypto_sms4_c::set_is_invalid()
+{
+	m_is_valid = false;
+}
+
+//------------------------------------------------------------
+
+EAP_FUNC_EXPORT void wapi_am_crypto_sms4_c::set_is_valid()
+{
+	m_is_valid = true;
+}
+
+//------------------------------------------------------------
+
+EAP_FUNC_EXPORT bool wapi_am_crypto_sms4_c::get_is_valid()
+{
+	return m_is_valid;
+}
+
+//------------------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wapi_am_crypto_sms4_c::get_key_size()
+{
+	return WAPI_AM_CRYPTO_SMS4_KEY_u8_SIZE;
+}
+
+//------------------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wapi_am_crypto_sms4_c::get_block_size()
+{
+	return WAPI_AM_CRYPTO_SMS4_BLOCK_u8_SIZE;
+}
+
+//------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_crypto_sms4_c::set_key(
+	const eap_variable_data_c * const p_key)
+{
+
+	// key in network order
+
+	// check if key is ok
+	if( p_key == 0 ||
+		p_key->get_is_valid() == false ||
+		p_key->get_data_length() != WAPI_AM_CRYPTO_SMS4_KEY_u8_SIZE )
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_encryption_parameter_size);
+	}
+
+	// temporary table to hold the currently
+	// needed key data words
+	u32_t key_table[WAPI_AM_CRYPTO_SMS4_KEY_u8_SIZE/4];
+	u32_t ind = 0;
+
+	for( ind = 0; ind < WAPI_AM_CRYPTO_SMS4_KEY_u8_SIZE/4; ++ind )
+	{
+		// read key from variable data to a u32_t table for faster processing
+		// TODO: Is this ok for endianness on other platforms?
+		key_table[ind] = eap_read_u32_t_network_order(p_key->get_data() + ind*4, 4);
+	}
+		
+	// temporary variable to hold the current
+	// expansion result (one word)
+	u32_t tmp_K;
+
+	// XOR key words with FKs
+	for( ind = 0; ind < WAPI_AM_CRYPTO_SMS4_KEY_u8_SIZE/4; ++ind )
+	{
+		key_table[ind] = key_table[ind] ^ m_FK[ind];
+	}
+
+	// compute the key expansion
+	for( ind = 0; ind < WAPI_AM_CRYPTO_SMS4_KEY_SCHEDULE_u32_SIZE; ++ind )
+	{
+
+		// See SMS4 spec for these
+		tmp_K = key_table[1] ^ key_table[2] ^ key_table[3] ^ m_CK[ind];
+		sms4_substitute( &tmp_K );
+		L_key( &tmp_K );
+		tmp_K ^= key_table[0];
+
+		// store the result for the next round
+		key_table[0] = key_table[1];
+		key_table[1] = key_table[2];
+		key_table[2] = key_table[3];
+		key_table[3] = tmp_K;
+
+		// store the expansion result
+		m_key_schedule[ind] = tmp_K;
+
+	} // for()
+
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//------------------------------------------------------------
+
+/*
+ * Performs L' function for a key word.
+ */
+
+EAP_FUNC_EXPORT void wapi_am_crypto_sms4_c::L_key( u32_t* data )
+{
+	*data ^= sms4_rotate_left(*data, 13) ^ sms4_rotate_left(*data, 23);
+	return;
+}
+
+//------------------------------------------------------------
+
+/*
+ * Performs S-box substitution for a data word,
+ * i.e. four S-box substitutions.
+ */
+
+EAP_FUNC_EXPORT void wapi_am_crypto_sms4_c::sms4_substitute( u32_t* data )
+{	
+	u8_t* tmp = reinterpret_cast<u8_t*>(data);
+
+	// S-box substitution to the bytes of the word
+	*tmp = m_SBOX[*tmp];
+	*(tmp+1) = m_SBOX[*(tmp+1)];
+	*(tmp+2) = m_SBOX[*(tmp+2)];
+	*(tmp+3) = m_SBOX[*(tmp+3)];
+
+	return;
+}
+
+//------------------------------------------------------------
+
+/*
+ * Performs L function for a data word.
+ */
+
+EAP_FUNC_EXPORT void wapi_am_crypto_sms4_c::L_data( u32_t* data )
+{
+	*data ^= 
+		sms4_rotate_left(*data, 2) ^ 
+		sms4_rotate_left(*data, 10) ^ 
+		sms4_rotate_left(*data, 18) ^
+		sms4_rotate_left(*data, 24);
+	return;
+}
+
+//------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_crypto_sms4_c::ecb_process_data(
+	const void * const data_in, 
+	void * const data_out,
+	const u32_t data_blocks,
+	bool encrypt)
+{
+
+	// data in network order
+
+	// check if data is ok
+	if( data_in == 0 ||
+		data_out == 0 ||
+		data_blocks <= 0 )
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_encryption_parameter_size);
+	}
+
+	// temporary pointers to data_in and data_out
+	const u8_t* p_data_in = reinterpret_cast<const u8_t*>(data_in);
+	u8_t* p_data_out = reinterpret_cast<u8_t*>(data_out);
+
+	// count of the processed blocks
+	u32_t blocks_processed = 0;
+
+	// temporary table to hold the currently needed data words
+	u32_t data_table[WAPI_AM_CRYPTO_SMS4_BLOCK_u8_SIZE/4];
+	u32_t ind = 0;
+	eap_status_e status(eap_status_ok);
+
+	// temporary variable to hold the current result (one word)
+	u32_t tmp_X;
+
+	// ecrypt data in ECB mode
+	while( blocks_processed < data_blocks ) 
+	{
+
+		for( ind = 0; ind < 4; ++ind )
+		{
+			// read network order data to a u32_t table for faster processing
+			// TODO: Is this ok for endianness on other platforms?
+			data_table[ind] = eap_read_u32_t_network_order(p_data_in + ind*4, 4);
+		}
+		
+		// execute the SMS4 rounds
+		for( ind = 0; ind < 32; ++ind )
+		{
+
+			// See SMS4 spec for these
+			tmp_X = data_table[1] ^ data_table[2] ^ data_table[3];
+
+			if( encrypt == true )
+			{
+				tmp_X ^= m_key_schedule[ind];
+			}
+			else
+			{
+				// in decryption the key schedule is reversed
+				tmp_X ^= m_key_schedule[WAPI_AM_CRYPTO_SMS4_KEY_SCHEDULE_u32_SIZE-1-ind];
+			}
+
+			sms4_substitute( &tmp_X );
+			L_data( &tmp_X );
+			tmp_X ^= data_table[0];
+
+			// store the result for the next round
+			data_table[0] = data_table[1];
+			data_table[1] = data_table[2];
+			data_table[2] = data_table[3];
+			data_table[3] = tmp_X;
+
+		} // for()
+
+		// the result of the final round is the output,
+		// except that the order of the words is reversed 
+		// (R function in the SMS4 spec)
+		for( ind = 0; ind < 4; ++ind )
+		{
+			status = eap_write_u32_t_network_order( p_data_out+4*ind, 4, data_table[3-ind] );
+			if( status != eap_status_ok )
+			{
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		++blocks_processed;
+		// take the next data block for processing
+		p_data_in += 16;
+		p_data_out += 16;
+
+	} // for()
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_crypto_sms4_c::ecb_encrypt(
+	const void * const data_in, 
+	void * const data_out,
+	const u32_t data_blocks)
+{
+	eap_status_e status = ecb_process_data( data_in, data_out, data_blocks, true );
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_crypto_sms4_c::ecb_decrypt(
+	const void * const data_in, 
+	void * const data_out,
+	const u32_t data_blocks)
+{
+	eap_status_e status = ecb_process_data( data_in, data_out, data_blocks, false );
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//------------------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_am_wlan_authentication.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,40 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_am_wlan_authentication.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 5 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 20002 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#include "wapi_am_wlan_authentication.h"
+
+// 
+wapi_am_wlan_authentication_c::~wapi_am_wlan_authentication_c()
+{
+}
+ 
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_asn1_der_parser.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,554 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_asn1_der_parser.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 12 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+#include "wapi_asn1_der_parser.h"
+#include "eap_automatic_variable.h"
+#include "wapi_types.h"
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_asn1_der_parser_c::~wapi_asn1_der_parser_c()
+{
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_asn1_der_parser_c::wapi_asn1_der_parser_c(
+	abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+	, m_is_valid(false)
+	, m_objects(tools)
+{
+	m_is_valid = true;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT bool wapi_asn1_der_parser_c::get_is_valid() const
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_asn1_der_parser_c::decode(const eap_variable_data_c * const asn1_der_data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	ASN1_TYPE_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x: wapi_asn1_der_parser_c::decode()\n"),
+		 this));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_asn1_der_parser_c::decode()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	bool data_continues(true);
+
+	status = m_objects.reset();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	eap_variable_data_c input(m_am_tools);
+	if (input.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t input_offset(0ul);
+	const u32_t input_length(asn1_der_data->get_data_length());
+	u32_t input_remain_length(input_length);
+
+	while(data_continues == true)
+	{
+		asn1_der_type_c * const asn1_der_object = new asn1_der_type_c(m_am_tools);
+
+		eap_automatic_variable_c<asn1_der_type_c> automatic_asn1_der_object(m_am_tools, asn1_der_object);
+
+		if (asn1_der_object == 0
+			|| asn1_der_object->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = input.set_buffer(
+			asn1_der_data->get_data_offset(input_offset, input_remain_length),
+			input_remain_length,
+			false,
+			false);
+
+		status = asn1_der_object->decode(&input);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		automatic_asn1_der_object.do_not_free_variable();
+
+		status = m_objects.add_object(asn1_der_object, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		input_offset += asn1_der_object->get_full_data_length();
+
+		if (input_remain_length < asn1_der_object->get_full_data_length())
+		{
+			data_continues = false;
+		}
+		else
+		{
+			input_remain_length -= asn1_der_object->get_full_data_length();
+
+			if (input_remain_length >= input_length
+				|| input_offset >= input_length)
+			{
+				data_continues = false;
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT const asn1_der_type_c * wapi_asn1_der_parser_c::get_object(const u32_t index) const
+{
+	if (m_objects.get_object_count() <= index)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+		return 0;
+	}
+
+	return m_objects.get_object(index);
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wapi_asn1_der_parser_c::get_object_count() const
+{
+	return m_objects.get_object_count();
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_asn1_der_parser_c::get_wapi_identity(
+	eap_variable_data_c * const subject_name,
+	eap_variable_data_c * const issuer_name,
+	eap_variable_data_c * const sequence_number)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	ASN1_TYPE_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x: wapi_asn1_der_parser_c::get_wapi_identity()\n"),
+		 this));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_asn1_der_parser_c::get_wapi_identity()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (subject_name == 0
+		|| issuer_name == 0
+		|| sequence_number == 0
+		|| subject_name->get_is_valid() == false
+		|| issuer_name->get_is_valid() == false
+		|| sequence_number->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	const asn1_type_const_c type_object_identifier[] =
+		{
+			ASN1_TYPE_OBJECT(
+				asn1_der_type_c::asn1_class_universal,
+				asn1_der_type_c::asn1_tag_sequence,
+				0),										// Name ::= CHOICE { RDNSequence } 
+														// ::= RDNSequence 
+														// ::= SEQUENCE OF RelativeDistinguishedName
+														// ::= {organizationalUnitName[0], commonName[1]}
+			ASN1_TYPE_OBJECT(
+				asn1_der_type_c::asn1_class_universal,
+				asn1_der_type_c::asn1_tag_set,
+				1),										// commonName ::= SET OF AttributeTypeAndValue
+			ASN1_TYPE_OBJECT(
+				asn1_der_type_c::asn1_class_universal,
+				asn1_der_type_c::asn1_tag_sequence,
+				0),										// AttributeTypeAndValue ::= SEQUENCE {
+														//		type     AttributeType,
+														//		value    AttributeValue }
+			ASN1_TYPE_OBJECT(
+				asn1_der_type_c::asn1_class_universal,
+				asn1_der_type_c::asn1_tag_object_identifier,
+				0),										// AttributeType ::= OBJECT IDENTIFIER
+			ASN1_TYPE_OBJECT_TERMINATOR
+		};
+
+	u32_t index(0ul);
+
+	{
+		const asn1_der_type_c * const der_subject_name = get_object(index);
+
+		if (der_subject_name == 0
+			|| der_subject_name->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+		}
+
+		const asn1_der_type_c * const der_object_identifier = der_subject_name->get_sub_type(type_object_identifier);
+
+		if (der_object_identifier == 0
+			|| der_object_identifier->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+		}
+
+		if (der_object_identifier->get_full_data_length() != sizeof(WAPI_COMMON_NAME_OID_PARAMETER)
+			|| m_am_tools->memcmp(WAPI_COMMON_NAME_OID_PARAMETER,
+			der_object_identifier->get_full_data(),
+			sizeof(WAPI_COMMON_NAME_OID_PARAMETER)) != 0)
+		{
+			// ERROR: wrong payload.
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
+		}
+
+		status = subject_name->set_copy_of_buffer(
+			der_subject_name->get_full_data(),
+			der_subject_name->get_full_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("subject_name"),
+			subject_name->get_data(),
+			subject_name->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	++index;
+
+	{
+		const asn1_der_type_c * const der_issuer_name = get_object(index);
+
+		if (der_issuer_name == 0
+			|| der_issuer_name->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+		}
+
+		const asn1_der_type_c * const der_object_identifier = der_issuer_name->get_sub_type(type_object_identifier);
+
+		if (der_object_identifier == 0
+			|| der_object_identifier->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+		}
+
+		if (der_object_identifier->get_full_data_length() != sizeof(WAPI_COMMON_NAME_OID_PARAMETER)
+			|| m_am_tools->memcmp(WAPI_COMMON_NAME_OID_PARAMETER,
+			der_object_identifier->get_full_data(),
+			sizeof(WAPI_COMMON_NAME_OID_PARAMETER)) != 0)
+		{
+			// ERROR: wrong payload.
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
+		}
+
+		status = issuer_name->set_copy_of_buffer(
+			der_issuer_name->get_full_data(),
+			der_issuer_name->get_full_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("issuer_name"),
+			issuer_name->get_data(),
+			issuer_name->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	++index;
+
+	{
+		const asn1_der_type_c * const der_sequence_number = get_object(index);
+
+		if (der_sequence_number == 0
+			|| der_sequence_number->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+		}
+
+		switch(der_sequence_number->get_tag())
+		{
+		case asn1_der_type_c::asn1_tag_integer:
+			// OK
+			break;
+		default:
+			// ERROR: wrong payload.
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload);
+		};
+
+		status = sequence_number->set_copy_of_buffer(
+			der_sequence_number->get_full_data(),
+			der_sequence_number->get_full_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("sequence_number"),
+			sequence_number->get_data(),
+			sequence_number->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_asn1_der_parser_c::get_wapi_identity(
+	eap_variable_data_c * const wapi_identity)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	ASN1_TYPE_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x: wapi_asn1_der_parser_c::get_wapi_identity()\n"),
+		 this));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_asn1_der_parser_c::get_wapi_identity()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (wapi_identity == 0
+		|| wapi_identity->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c subject_name(m_am_tools);
+	eap_variable_data_c issuer_name(m_am_tools);
+	eap_variable_data_c sequence_number(m_am_tools);
+
+	if (subject_name.get_is_valid() == false
+		|| issuer_name.get_is_valid() == false
+		|| sequence_number.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = get_wapi_identity(
+		&subject_name,
+		&issuer_name,
+		&sequence_number);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = wapi_identity->set_copy_of_buffer(&subject_name);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = wapi_identity->add_data(&issuer_name);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = wapi_identity->add_data(&sequence_number);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_asn1_der_parser_c::get_decoded_subject_name(
+    eap_variable_data_c * const identity_data,
+    eap_variable_data_c * const decoded_data)
+{
+    
+    eap_status_e status = eap_status_ok;
+    eap_variable_data_c subject_name(m_am_tools);
+   
+	if ( subject_name.get_is_valid() == false )
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+    
+    // The data is stored to this objects internal variables with decode
+    status = decode(identity_data);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+    
+	const asn1_type_const_c type_name_sequence[] =
+		{
+			ASN1_TYPE_OBJECT(
+				asn1_der_type_c::asn1_class_universal,
+				asn1_der_type_c::asn1_tag_sequence,
+				0),										// Name ::= CHOICE { RDNSequence } 
+														// ::= RDNSequence 
+														// ::= SEQUENCE OF RelativeDistinguishedName
+														// ::= {organizationalUnitName[0], commonName[1]}
+			ASN1_TYPE_OBJECT(
+				asn1_der_type_c::asn1_class_universal,
+				asn1_der_type_c::asn1_tag_set,
+				1),										// commonName ::= SET OF AttributeTypeAndValue
+			ASN1_TYPE_OBJECT(
+				asn1_der_type_c::asn1_class_universal,
+				asn1_der_type_c::asn1_tag_sequence,
+				0),										// AttributeTypeAndValue ::= SEQUENCE {
+														//		type     AttributeType,
+														//		value    AttributeValue }
+#if 0
+			// This last object is variable type and it is handled later.
+			ASN1_TYPE_OBJECT(
+				asn1_der_type_c::asn1_class_universal,
+				asn1_der_type_c::asn1_tag_printable_string,
+				0),										// AttributeValue ::= ANY DEFINED BY AttributeType
+														// ::= DirectoryString ::= CHOICE {
+														// teletexString           TeletexString (SIZE (1..MAX)),
+														// printableString         PrintableString (SIZE (1..MAX)),
+														// universalString         UniversalString (SIZE (1..MAX)),
+														// utf8String              UTF8String (SIZE (1..MAX)),
+														// bmpString               BMPString (SIZE (1..MAX)) }
+#endif
+			ASN1_TYPE_OBJECT_TERMINATOR
+		};
+
+	if (get_object_count() == 0ul)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+	}
+
+	const asn1_der_type_c * const der_name_sequence = get_object(0ul)->get_sub_type(type_name_sequence);
+
+	if (der_name_sequence == 0
+		|| der_name_sequence->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+	}
+
+	// Second object (index 1) in SEQUENCE is AttributeValue.
+	const asn1_der_type_c * const der_name = der_name_sequence->get_sub_types()->get_object(1ul);
+
+	if (der_name == 0
+		|| der_name->get_is_valid() == false
+		|| (/* der_name->get_tag() != asn1_der_type_c::asn1_tag_teletex_string // This is not defined yet.
+			&& */
+			der_name->get_tag() != asn1_der_type_c::asn1_tag_printable_string
+			&& der_name->get_tag() != asn1_der_type_c::asn1_tag_universal_string
+			&& der_name->get_tag() != asn1_der_type_c::asn1_tag_utf8_string
+			&& der_name->get_tag() != asn1_der_type_c::asn1_tag_bmp_string
+			&& der_name->get_tag() != asn1_der_type_c::asn1_tag_t61_string))
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_index);
+	}
+
+    // Copy the decoded data into the returned parameter
+    status = decoded_data->set_copy_of_buffer(
+		der_name->get_content(), 
+		der_name->get_content_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+    
+    EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+    return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+
+//--------------------------------------------------------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_certificate_asn1_der_parser.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,336 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_certificate_asn1_der_parser.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 3 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+#include "wapi_certificate_asn1_der_parser.h"
+#include "eap_automatic_variable.h"
+#include "wapi_types.h"
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_certificate_asn1_der_parser_c::~wapi_certificate_asn1_der_parser_c()
+{
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_certificate_asn1_der_parser_c::wapi_certificate_asn1_der_parser_c(
+	abs_eap_am_tools_c * const tools)
+	: m_am_tools(tools)
+	, m_is_valid(false)
+	, m_parser(tools)
+{
+	m_is_valid = true;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT bool wapi_certificate_asn1_der_parser_c::get_is_valid() const
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_certificate_asn1_der_parser_c::decode(const eap_variable_data_c * const asn1_der_certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	ASN1_TYPE_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x: wapi_certificate_asn1_der_parser_c::decode()\n"),
+		 this));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_certificate_asn1_der_parser_c::decode()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (asn1_der_certificate == 0
+		|| asn1_der_certificate->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = m_parser.decode(asn1_der_certificate);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_certificate_asn1_der_parser_c::read_certificate_id(
+	eap_variable_data_c * const asn1_der_subject_name,
+	eap_variable_data_c * const asn1_der_issuer_name,
+	eap_variable_data_c * const asn1_der_sequence_number)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x: wapi_certificate_asn1_der_parser_c::read_certificate_id():\n"),
+		 this));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_certificate_asn1_der_parser_c::read_certificate_id()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	if (asn1_der_subject_name == 0
+		|| asn1_der_subject_name->get_is_valid() == false
+		|| asn1_der_issuer_name == 0
+		|| asn1_der_issuer_name->get_is_valid() == false
+		|| asn1_der_sequence_number == 0
+		|| asn1_der_sequence_number->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (m_parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_certificate);
+	}
+
+	{
+		const asn1_type_const_c type_subject_name[] =
+			{
+				ASN1_TYPE_OBJECT(
+					asn1_der_type_c::asn1_class_universal,
+					asn1_der_type_c::asn1_tag_sequence,
+					0),                                       // Certificate  ::=  SEQUENCE
+				ASN1_TYPE_OBJECT(
+					asn1_der_type_c::asn1_class_universal,
+					asn1_der_type_c::asn1_tag_sequence,
+					0),                                       // TBSCertificate  ::=  SEQUENCE
+				ASN1_TYPE_OBJECT(
+					asn1_der_type_c::asn1_class_universal,
+					asn1_der_type_c::asn1_tag_sequence,
+					5),                                       // subject Name, Name ::= CHOICE { RDNSequence }, RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+				ASN1_TYPE_OBJECT_TERMINATOR
+			};
+
+		eap_status_e status(eap_status_not_supported);
+
+		const asn1_der_type_c * const type = m_parser.get_sub_type(type_subject_name);
+
+		if (type == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_identity_query_failed);
+		}
+
+		status = asn1_der_subject_name->set_copy_of_buffer(
+			type->get_full_data(),
+			type->get_full_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("asn1_der_subject_name"),
+			asn1_der_subject_name->get_data(),
+			asn1_der_subject_name->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+		const asn1_type_const_c type_issuer_name[] =
+			{
+				ASN1_TYPE_OBJECT(
+					asn1_der_type_c::asn1_class_universal,
+					asn1_der_type_c::asn1_tag_sequence,
+					0),                                       // Certificate  ::=  SEQUENCE
+				ASN1_TYPE_OBJECT(
+					asn1_der_type_c::asn1_class_universal,
+					asn1_der_type_c::asn1_tag_sequence,
+					0),                                       // TBSCertificate  ::=  SEQUENCE
+				ASN1_TYPE_OBJECT(
+					asn1_der_type_c::asn1_class_universal,
+					asn1_der_type_c::asn1_tag_sequence,
+					3),                                       // issuer Name, Name ::= CHOICE { RDNSequence }, RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+				ASN1_TYPE_OBJECT_TERMINATOR
+			};
+
+		const asn1_der_type_c * const type = m_parser.get_sub_type(type_issuer_name);
+
+		if (type == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_identity_query_failed);
+		}
+
+		status = asn1_der_issuer_name->set_copy_of_buffer(
+			type->get_full_data(),
+			type->get_full_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("asn1_der_issuer_name"),
+			asn1_der_issuer_name->get_data(),
+			asn1_der_issuer_name->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+		const asn1_type_const_c type_serial_number[] =
+			{
+				ASN1_TYPE_OBJECT(
+					asn1_der_type_c::asn1_class_universal,
+					asn1_der_type_c::asn1_tag_sequence,
+					0),                                       // Certificate  ::=  SEQUENCE
+				ASN1_TYPE_OBJECT(
+					asn1_der_type_c::asn1_class_universal,
+					asn1_der_type_c::asn1_tag_sequence,
+					0),                                       // TBSCertificate  ::=  SEQUENCE
+				ASN1_TYPE_OBJECT(
+					asn1_der_type_c::asn1_class_universal,
+					asn1_der_type_c::asn1_tag_integer,
+					1),                                       // serialNumber CertificateSerialNumber, CertificateSerialNumber  ::=  INTEGER
+				ASN1_TYPE_OBJECT_TERMINATOR
+			};
+
+		const asn1_der_type_c * const type = m_parser.get_sub_type(type_serial_number);
+
+		if (type == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_identity_query_failed);
+		}
+
+		status = asn1_der_sequence_number->set_copy_of_buffer(
+			type->get_full_data(),
+			type->get_full_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("asn1_der_sequence_number"),
+			asn1_der_sequence_number->get_data(),
+			asn1_der_sequence_number->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_certificate_asn1_der_parser_c::read_certificate_id(
+	eap_variable_data_c * const identity)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x: wapi_certificate_asn1_der_parser_c::read_certificate_id():\n"),
+		 this));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_certificate_asn1_der_parser_c::read_certificate_id()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	if (identity == 0
+		|| identity->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c certificate_subject_name(m_am_tools);
+	eap_variable_data_c certificate_issuer_name(m_am_tools);
+	eap_variable_data_c certificate_sequence_number(m_am_tools);
+
+	status = read_certificate_id(
+		&certificate_subject_name,
+		&certificate_issuer_name,
+		&certificate_sequence_number);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = identity->set_copy_of_buffer(&certificate_subject_name);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = identity->add_data(&certificate_issuer_name);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = identity->add_data(&certificate_sequence_number);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_core.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,12821 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_core.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 131.1.4 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 712 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+
+#include "eap_am_memory.h"
+#include "eap_tools.h"
+#include "abs_wapi_core.h"
+#include "abs_eap_am_mutex.h"
+#include "wapi_core.h"
+#include "eap_state_notification.h"
+#include "eap_network_id_selector.h"
+#include "eap_buffer.h"
+#include "eap_automatic_variable.h"
+#include "wapi_core_retransmission.h"
+#include "wai_protocol_packet_header.h"
+#include "wapi_strings.h"
+#include "eap_crypto_api.h"
+#include "eap_automatic_variable.h"
+#include "eapol_session_key.h"
+#include "wapi_am_crypto_sms4.h"
+#include "asn1_der_type.h"
+#include "wapi_asn1_der_parser.h"
+#include "wapi_am_base_core.h"
+
+//#define WAPI_SKIP_BKID_TEST // This is for testing.
+
+//--------------------------------------------------
+
+// 
+EAP_FUNC_EXPORT wapi_core_c::~wapi_core_c()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::~wapi_core_c(): %s, this = 0x%08x => 0x%08x.\n"),
+		(m_is_client == true) ? "client": "server",
+		this,
+		dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	EAP_ASSERT(m_shutdown_was_called == true);
+
+	{
+		for (u32_t ind = 0ul; ind < WAPI_USKSA_COUNT; ++ind)
+		{
+			delete m_USKSA[ind];
+			m_USKSA[ind] = 0;
+		} // for()
+	}
+
+	{
+		for (u32_t ind = 0ul; ind < WAPI_MSKSA_COUNT; ++ind)
+		{
+			delete m_MSKSA[ind];
+			m_MSKSA[ind] = 0;
+		} // for()
+	}
+
+	delete m_ec_certificate_store;
+	m_ec_certificate_store = 0;
+
+	delete m_am_wapi_core;
+	m_am_wapi_core = 0;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+#if defined(_WIN32) && !defined(__GNUC__)
+	#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
+#endif
+
+// 
+EAP_FUNC_EXPORT wapi_core_c::wapi_core_c(
+	abs_eap_am_tools_c * const tools,
+	abs_wapi_core_c * const partner,
+	const bool is_client_when_true,
+	const eap_am_network_id_c * const receive_network_id)
+	: m_partner(partner)
+	, m_ec_certificate_store(0)
+	, m_am_wapi_core(0)
+	, m_am_tools(tools)
+	, m_wapi_header_offset(0u)
+	, m_MTU(0u)
+	, m_trailer_length(0u)
+	, m_receive_network_id(tools)
+	, m_retransmission(0)
+	, m_retransmission_time(WAPI_CORE_RETRANSMISSION_TIME)
+	, m_retransmission_counter(WAPI_CORE_RETRANSMISSION_COUNTER)
+	, m_session_timeout(WAPI_CORE_SESSION_TIMEOUT)
+	, m_wapi_core_failure_received_timeout(WAPI_CORE_FAILURE_RECEIVED_TIMEOUT)
+	, m_remove_session_timeout(WAPI_CORE_REMOVE_SESSION_TIMEOUT)
+	, m_wapi_state(wapi_core_state_none)
+	, m_received_wai_message_data(tools, is_client_when_true)
+	, m_new_payloads(tools, is_client_when_true)
+	, m_preshared_key_PSK(tools)
+	, m_BK(tools)
+	, m_BKID(tools)
+	, m_USKID(0u)
+	, m_MSKID(0u)
+	, m_ae_certificate_challenge(tools)
+	, m_asue_certificate_challenge(tools)
+	, m_ae_unicast_challenge(tools)
+	, m_asue_unicast_challenge(tools)
+	, m_authentication_identifier(tools)
+	, m_asue_id(tools)
+	, m_asu_id(tools)
+	, m_ae_id(tools)
+	, m_test_other_asu_id(tools)
+	, m_own_certificate(tools)
+	, m_peer_certificate(tools)
+	, m_ae_certificate(tools)
+	, m_wapi_ie_asue(tools)
+	, m_wapi_ie_ae(tools)
+	, m_unicast_encryption_key_UEK(tools)
+	, m_unicast_integrity_check_key_UCK(tools)
+	, m_message_authentication_key_MAK(tools)
+	, m_key_encryption_key_KEK(tools)
+	, m_next_unicast_challenge(tools)
+	, m_multicast_key(tools)
+	, m_packet_data_number(tools)
+	, m_key_announcement(tools)
+	, m_own_private_key_d(tools)
+	, m_own_public_key_x(tools)
+	, m_own_public_key_y(tools)
+	, m_peer_public_key_x(tools)
+	, m_peer_public_key_y(tools)
+	, m_result_of_certificate_verification(tools)
+	, m_server_signature_trusted_by_asue(tools)
+	, m_server_signature_trusted_by_ae(tools)
+	, m_reassemble_packet(tools)
+	, m_authentication_type(eapol_key_authentication_type_none)
+	, m_wapi_negotiation_state(wapi_negotiation_state_none)
+	, m_wapi_pairwise_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)
+	, m_wapi_group_cipher(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)
+	, m_packet_sequence_number(0u)
+	, m_fragment_sequence_number(0u)
+	, m_is_client(is_client_when_true)
+	, m_is_client_role(is_client_when_true)
+	, m_is_valid(false)
+	, m_client_restart_authentication_initiated(false)
+	, m_marked_removed(false)
+	, m_shutdown_was_called(false)
+	, m_do_certificate_validation(false)
+#if defined(USE_WAPI_CORE_SERVER)
+	, m_only_initial_authentication(false)
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::wapi_core_c(): %s, this = 0x%08x => 0x%08x, compiled %s %s.\n"),
+		(m_is_client == true) ? "client": "server",
+		this,
+		dynamic_cast<abs_eap_base_timer_c *>(this),
+		__DATE__,
+		__TIME__));
+
+	eap_status_e status = m_receive_network_id.set_copy_of_network_id(receive_network_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return;
+	}
+
+	{
+		for (u32_t ind = 0ul; ind < WAPI_USKSA_COUNT; ++ind)
+		{
+			m_USKSA[ind] = 0;
+		} // for()
+	}
+
+	{
+		for (u32_t ind = 0ul; ind < WAPI_MSKSA_COUNT; ++ind)
+		{
+			m_MSKSA[ind] = 0;
+		}
+	}
+
+	{
+		for (u32_t ind = 0ul; ind < WAPI_USKSA_COUNT; ++ind)
+		{
+			m_USKSA[ind] = 0;
+
+			wai_usksa_c * const usksa = new wai_usksa_c(m_am_tools);
+			if (usksa == 0
+				|| usksa->get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				return;
+			}
+
+			m_USKSA[ind] = usksa;
+
+		} // for()
+	}
+
+	{
+		for (u32_t ind = 0ul; ind < WAPI_MSKSA_COUNT; ++ind)
+		{
+			m_MSKSA[ind] = 0;
+
+			wai_usksa_c * const msksa = new wai_usksa_c(m_am_tools);
+			if (msksa == 0
+				|| msksa->get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				return;
+			}
+
+			m_MSKSA[ind] = msksa;
+
+		} // for()
+	}
+
+	m_am_wapi_core = wapi_am_base_core_c::new_wapi_am_core(
+		tools,
+		this,
+		is_client_when_true,
+		&m_receive_network_id);
+	if (m_am_wapi_core == 0
+		|| m_am_wapi_core->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return;
+	}
+
+	m_ec_certificate_store = ec_base_certificate_store_c::new_ec_base_certificate_store_c(
+		tools,
+		this,
+		m_am_wapi_core,
+		is_client_when_true);
+	if (m_ec_certificate_store == 0
+		|| m_ec_certificate_store->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return;
+	}
+
+	status = m_ec_certificate_store->set_receive_network_id(&m_receive_network_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, status);
+		return;
+	}
+
+	set_is_valid();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::initialize(
+	const eap_am_network_id_c * const receive_network_id,
+	const eapol_key_authentication_type_e authentication_type)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = m_receive_network_id.set_copy_of_network_id(receive_network_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	m_authentication_type = authentication_type;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::initialize(
+	const eap_am_network_id_c * const receive_network_id,
+	const eapol_key_authentication_type_e authentication_type,
+	const eap_variable_data_c * const wapi_ie_ae,
+	const eap_variable_data_c * const wapi_ie_asue,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e wapi_pairwise_cipher,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e wapi_group_cipher)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = m_receive_network_id.set_copy_of_network_id(receive_network_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	m_authentication_type = authentication_type;
+
+	status = m_wapi_ie_ae.set_copy_of_buffer(wapi_ie_ae);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_wapi_ie_asue.set_copy_of_buffer(wapi_ie_asue);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	m_wapi_pairwise_cipher = wapi_pairwise_cipher;
+	m_wapi_group_cipher = wapi_group_cipher;
+	
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+void wapi_core_c::set_wapi_state(wapi_core_state_e wapi_state)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAI: %s: wapi_core_c::set_wapi_state(): State from %s to %s, %s.\n"),
+		 (m_is_client == true) ? "client": "server",
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+		 wapi_strings_c::get_wapi_core_state_string(wapi_state),
+		 wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+	m_wapi_state = wapi_state;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT abs_wapi_core_c * wapi_core_c::get_partner()
+{
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	return m_partner;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void wapi_core_c::set_partner(abs_wapi_core_c * const partner)
+{
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	m_partner = partner;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void wapi_core_c::set_is_valid()
+{
+	m_is_valid = true;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT bool wapi_core_c::get_is_valid()
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void wapi_core_c::object_increase_reference_count()
+{
+	// This is an empty function to implement here unused interface function.
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT u32_t wapi_core_c::object_decrease_reference_count()
+{
+	return 0u;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT bool wapi_core_c::get_marked_removed()
+{
+	return m_marked_removed;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void wapi_core_c::set_marked_removed()
+{
+	m_marked_removed = true;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void wapi_core_c::unset_marked_removed()
+{
+	m_marked_removed = false;
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_core_c::initialize_asynchronous_init_remove_wapi_session(
+	const u32_t remove_session_timeout)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::initialize_asynchronous_init_remove_wapi_session(): %s.\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	eap_status_e status = eap_status_process_general_error;
+
+
+	if (m_is_client_role == false)
+	{
+		// Server stops re-transmissions.
+		// Client can re-transmit until session is removed.
+		cancel_retransmission();
+	}
+
+	cancel_wapi_failure_timeout();
+
+	cancel_session_timeout();
+
+	set_marked_removed();
+
+
+	if (remove_session_timeout == 0ul)
+	{
+		status = asynchronous_init_remove_wapi_session();
+	}
+	else
+	{
+		EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+		cancel_asynchronous_init_remove_wapi_session();
+
+		status = m_partner->set_timer(
+			this,
+			WAPI_CORE_REMOVE_SESSION_TIMEOUT_ID,
+			0,
+			remove_session_timeout);
+
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("TIMER: %s: WAPI_CORE_REMOVE_SESSION_TIMEOUT_ID set %d ms, this = 0x%08x.\n"),
+			 (m_is_client == true) ? "client": "server",
+			 remove_session_timeout,
+			 this));
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::cancel_asynchronous_init_remove_wapi_session()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = m_partner->cancel_timer(
+		this,
+		WAPI_CORE_REMOVE_SESSION_TIMEOUT_ID);
+
+	EAP_UNREFERENCED_PARAMETER(status); // in release
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("TIMER: %s: WAPI_CORE_REMOVE_SESSION_TIMEOUT_ID cancelled status %d, this = 0x%08x.\n"),
+		 (m_is_client == true ? "client": "server"),
+		 status,
+		 this));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_core_c::asynchronous_init_remove_wapi_session()
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::asynchronous_init_remove_wapi_session(): %s.\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+		eap_am_network_id_c send_network_id(
+			m_am_tools,
+			m_receive_network_id.get_destination_id(),
+			m_receive_network_id.get_source_id(),
+			m_receive_network_id.get_type());
+
+		eap_status_e status = m_partner->asynchronous_init_remove_wapi_session(
+			&send_network_id);
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_core_c::init_end_of_session(
+	const abs_eap_state_notification_c * const state)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::init_end_of_session(): %s.\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// Normally we will remove session after authentication ends.
+	// Remove session only if the stack is not already being deleted
+	if (m_shutdown_was_called == false)
+	{
+
+		#if defined(USE_WAPI_CORE_SIMULATOR_VERSION) && defined(USE_WAPI_CORE_RESTART_AUTHENTICATION)
+
+			// Simulator reuses current session.
+			status = restart_authentication(
+				state->get_send_network_id(),
+				m_is_client);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+		#elif defined(USE_WAPI_CORE_SIMULATOR_VERSION)
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("wapi_core_c::state_notification(): %s, %s, Ignored notification: ")
+				 EAPL("Protocol layer %d, State transition from ")
+				 EAPL("%d=%s to %d=%s, client %d.\n"),
+				 (m_is_client == true) ? "client": "server",
+				 (m_is_tunneled_eap == true) ? "tunneled": "outer most",
+				 state->get_protocol_layer(), 
+				 state->get_previous_state(), 
+				 state->get_previous_state_string(), 
+				 state->get_current_state(), 
+				 state->get_current_state_string(),
+				 state->get_is_client()));
+
+		#endif //#if defined(USE_WAPI_CORE_SIMULATOR_VERSION)
+
+		status = initialize_asynchronous_init_remove_wapi_session(m_remove_session_timeout);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("wapi_core_c::state_notification(): %s, Ignored notification: ")
+			 EAPL("Protocol layer %d, State transition from ")
+			 EAPL("%d=%s to %d=%s, client %d when shutdown was called.\n"),
+			 (m_is_client == true) ? "client": "server",
+			 state->get_protocol_layer(), 
+			 state->get_previous_state(), 
+			 state->get_previous_state_string(), 
+			 state->get_current_state(), 
+			 state->get_current_state_string(),
+			 state->get_is_client()));
+
+		status = eap_status_ok;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void wapi_core_c::state_notification(
+	const abs_eap_state_notification_c * const state)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_string_c status_string;
+	EAP_UNREFERENCED_PARAMETER(status_string); // in release
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::state_notification(), %s, protocol_layer %d=%s, protocol %d=%s.\n"),
+		(m_is_client == true) ? "client": "server",
+		state->get_protocol_layer(),
+		state->get_protocol_layer_string(),
+		state->get_protocol(),
+		state->get_protocol_string()));
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::state_notification(), %s, current_state %d=%s, error %d=%s.\n"),
+		(m_is_client == true) ? "client": "server",
+		state->get_current_state(),
+		state->get_current_state_string(),
+		state->get_authentication_error(),
+		status_string.get_status_string(state->get_authentication_error())));
+
+	m_partner->state_notification(state);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::initialize_session_timeout(const u32_t session_timeout_ms)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	cancel_session_timeout();
+
+	eap_status_e status = m_partner->set_timer(
+		this,
+		WAPI_CORE_SESSION_TIMEOUT_ID,
+		0,
+		session_timeout_ms);
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("TIMER: %s: WAPI_CORE_SESSION_TIMEOUT_ID set %d ms, this = 0x%08x.\n"),
+		 (m_is_client == true) ? "client": "server",
+		 session_timeout_ms,
+		 this));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::cancel_session_timeout()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = m_partner->cancel_timer(
+		this,
+		WAPI_CORE_SESSION_TIMEOUT_ID);
+	
+	EAP_UNREFERENCED_PARAMETER(status); // in release
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("TIMER: %s: WAPI_CORE_SESSION_TIMEOUT_ID cancelled status %d, this = 0x%08x.\n"),
+		 (m_is_client == true ? "client": "server"),
+		 status,
+		 this));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::create_BKID(
+	eap_variable_data_c * const BKID,
+	const eap_am_network_id_c * const receive_network_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::create_BKID(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::create_BKID()");
+
+	if (BKID == 0
+		|| BKID->get_is_valid() == false
+		|| receive_network_id == 0
+		|| receive_network_id->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// BKID = KD_HMAC_SHA256(BK, MACAE || MACASUE)
+
+	crypto_kd_hmac_sha256_c kd_hmac(m_am_tools);
+	if (kd_hmac.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_variable_data_c label(m_am_tools);
+	if (label.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	const eap_variable_data_c * MAC_1 = receive_network_id->get_destination_id();
+	const eap_variable_data_c * MAC_2 = receive_network_id->get_source_id();
+
+	if (m_is_client == true)
+	{
+		MAC_1 = receive_network_id->get_source_id();
+		MAC_2 = receive_network_id->get_destination_id();
+	}
+
+	status = label.set_copy_of_buffer(MAC_1);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = label.add_data(MAC_2);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = kd_hmac.expand_key(
+		BKID,
+		WAPI_BKID_LENGTH,
+		&m_BK,
+		&label);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_core_c::packet_data_session_key(
+	eap_variable_data_c * const key, ///< Here is the key.
+	const eapol_key_type_e key_type, ///< This the type of the key.
+	const u32_t key_index, ///< This is the index of the key.
+	const bool key_tx_bit, ///< This is the TX bit of the key.
+	const u8_t * const key_RSC, ///< This is the RSC counter
+	const u32_t key_RSC_size ///< This is the size of RSC counter
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eapol_session_key_c * eapol_session_key = new eapol_session_key_c(
+		m_am_tools,
+		key,
+		key_type,
+		key_index,
+		key_tx_bit,
+		key_RSC,
+		key_RSC_size
+		);
+	if (eapol_session_key == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	if (eapol_session_key->get_is_valid() == false)
+	{
+		delete eapol_session_key;
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(m_am_tools,
+		m_receive_network_id.get_destination_id(),
+		m_receive_network_id.get_source_id(),
+		m_receive_network_id.get_type());
+
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = m_partner->packet_data_session_key(
+		&send_network_id,
+		eapol_session_key);
+
+	delete eapol_session_key;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::create_unicast_key(
+	const eap_variable_data_c * const BK,
+	const eap_am_network_id_c * const receive_network_id,
+	const eap_variable_data_c * const ae_challenge,
+	const eap_variable_data_c * const asue_challenge,
+	eap_variable_data_c * const unicast_encryption_key_UEK,
+	eap_variable_data_c * const unicast_integrity_check_key_UCK,
+	eap_variable_data_c * const message_authentication_key_MAK,
+	eap_variable_data_c * const key_encryption_key_KEK,
+	eap_variable_data_c * const challenge_seed)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::create_unicast_key(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::create_unicast_key()");
+
+	if (BK == 0
+		|| BK->get_is_valid_data() == false
+		|| receive_network_id == 0
+		|| receive_network_id->get_is_valid() == false
+		|| ae_challenge == 0
+		|| ae_challenge->get_is_valid_data() == false
+		|| asue_challenge == 0
+		|| asue_challenge->get_is_valid_data() == false
+		|| unicast_encryption_key_UEK == 0
+		|| unicast_encryption_key_UEK->get_is_valid() == false
+		|| unicast_integrity_check_key_UCK == 0
+		|| unicast_integrity_check_key_UCK->get_is_valid() == false
+		|| message_authentication_key_MAK == 0
+		|| message_authentication_key_MAK->get_is_valid() == false
+		|| key_encryption_key_KEK == 0
+		|| key_encryption_key_KEK->get_is_valid() == false
+		|| challenge_seed == 0
+		|| challenge_seed->get_is_valid() == false
+		)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// Output (96) = KD-HMAC-SHA256(BK, ADDID||N_AE||N_ASUE||Label, Length);
+
+	crypto_kd_hmac_sha256_c kd_hmac(m_am_tools);
+	if (kd_hmac.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_variable_data_c label(m_am_tools);
+	if (label.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	const eap_variable_data_c * MAC_1 = receive_network_id->get_destination_id();
+	const eap_variable_data_c * MAC_2 = receive_network_id->get_source_id();
+
+	if (m_is_client == true)
+	{
+		MAC_1 = receive_network_id->get_source_id();
+		MAC_2 = receive_network_id->get_destination_id();
+	}
+
+	status = label.set_copy_of_buffer(MAC_1);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = label.add_data(MAC_2);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = label.add_data(ae_challenge);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = label.add_data(asue_challenge);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = label.add_data(WAPI_UNICAST_KEY_LABEL, WAPI_UNICAST_KEY_LABEL_LENGTH);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	eap_variable_data_c unicast_key(m_am_tools);
+	if (unicast_key.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = kd_hmac.expand_key(
+		&unicast_key,
+		WAPI_UNICAST_KEY_LENGTH,
+		BK,
+		&label);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// {unicast_encryption_key_UEK (16)
+	//  || unicast_integrity_check_key_UCK (16)
+	//  || message_authentication_key_MAK (16)
+	//  || key_encryption_key_KEK (16)
+	//  || Challenge seed (32)}
+	// = Output (96)
+
+	u32_t offset(0ul);
+	u32_t required_data_length(WAPI_UNICAST_ENCRYPTION_KEY_UEK_LENGTH);
+
+	status = unicast_encryption_key_UEK->set_copy_of_buffer(
+		unicast_key.get_data_offset(offset, required_data_length),
+		required_data_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	offset += required_data_length;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	required_data_length = WAPI_UNICAST_INTEGRITY_CHECK_KEY_UCK_LENGTH;
+
+	status = unicast_integrity_check_key_UCK->set_copy_of_buffer(
+		unicast_key.get_data_offset(offset, required_data_length),
+		required_data_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	offset += required_data_length;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	required_data_length = WAPI_MESSAGE_AUTHENTICATION_KEY_MAK_LENGTH;
+
+	status = message_authentication_key_MAK->set_copy_of_buffer(
+		unicast_key.get_data_offset(offset, required_data_length),
+		required_data_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	offset += required_data_length;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	required_data_length = WAPI_KEY_ENCRYPTION_KEY_KEK_LENGTH;
+
+	status = key_encryption_key_KEK->set_copy_of_buffer(
+		unicast_key.get_data_offset(offset, required_data_length),
+		required_data_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	offset += required_data_length;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	required_data_length = WAPI_CHALLENGE_SEED_LENGTH;
+
+	{
+		eap_variable_data_c next_challenge(m_am_tools);
+		if (next_challenge.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		crypto_sha_256_c sha_256(m_am_tools);
+		if (sha_256.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = sha_256.hash_init();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = sha_256.hash_update(
+			unicast_key.get_data_offset(offset, required_data_length),
+			required_data_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		u32_t md_length(sha_256.get_digest_length());
+
+		status = challenge_seed->set_buffer_length(md_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = challenge_seed->set_data_length(md_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = sha_256.hash_final(
+			challenge_seed->get_data(),
+			&md_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("next challenge_seed"),
+			 challenge_seed->get_data(),
+			 challenge_seed->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::create_MAC(
+	const wai_message_payloads_c * const payloads,
+	eap_variable_data_c * const MAC)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::create_MAC(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::create_MAC()");
+
+	if (payloads == 0
+		|| payloads->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (MAC == 0
+		|| MAC->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	crypto_sha_256_c sha_256(m_am_tools);
+	if (sha_256.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	crypto_hmac_c hmac_sha_256(
+		m_am_tools,
+		&sha_256,
+		false);
+	if (hmac_sha_256.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: m_message_authentication_key_MAK"),
+		 m_message_authentication_key_MAK.get_data(),
+		 m_message_authentication_key_MAK.get_data_length()));
+
+	status = hmac_sha_256.hmac_set_key(&m_message_authentication_key_MAK);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	for (u32_t tlv_index = 0ul; tlv_index < payloads->get_tlv_count(); ++tlv_index)
+	{
+		const wai_variable_data_c * tlv = payloads->get_tlv(tlv_index);
+		if (tlv == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		if (tlv->get_payload_type() != wai_payload_type_message_authentication_code)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("WAPI_Core: MAC: input data"),
+				tlv->get_data(tlv->get_data_length()),
+				tlv->get_data_length()));
+
+			status = hmac_sha_256.hmac_update(
+				tlv->get_data(tlv->get_data_length()),
+				tlv->get_data_length());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	} // for()
+
+	status = MAC->set_buffer_length(hmac_sha_256.get_digest_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = MAC->set_data_length(hmac_sha_256.get_digest_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	u32_t md_length(hmac_sha_256.get_digest_length());
+	
+	status = hmac_sha_256.hmac_final(
+		MAC->get_data(hmac_sha_256.get_digest_length()),
+		&md_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = MAC->set_data_length(WAPI_MESSAGE_AUTHENTICATION_CODE_LENGTH);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: MAC"),
+		 MAC->get_data(),
+		 MAC->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::create_HASH(
+	const wai_message_payloads_c * const payloads,
+	const bool hash_all_payloads,
+	eap_variable_data_c * const HASH)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::create_HASH(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::create_HASH()");
+
+	if (payloads == 0
+		|| payloads->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (HASH == 0
+		|| HASH->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	crypto_sha_256_c sha_256(m_am_tools);
+	if (sha_256.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = sha_256.hash_init();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	for (u32_t tlv_index = 0ul; tlv_index < payloads->get_tlv_count(); ++tlv_index)
+	{
+		const wai_variable_data_c * tlv = payloads->get_tlv(tlv_index);
+		if (tlv == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		if (hash_all_payloads == true
+			|| (tlv->get_payload_type() != wai_payload_type_message_authentication_code
+				&& tlv->get_payload_type() != wai_payload_type_signature_attributes))
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("WAPI_Core: HASH: input data"),
+				tlv->get_data(tlv->get_data_length()),
+				tlv->get_data_length()));
+
+			status = sha_256.hash_update(
+				tlv->get_data(tlv->get_data_length()),
+				tlv->get_data_length());
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	} // for()
+
+	status = HASH->set_buffer_length(sha_256.get_digest_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = HASH->set_data_length(sha_256.get_digest_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	u32_t md_length(sha_256.get_digest_length());
+	
+	status = sha_256.hash_final(
+		HASH->get_data(sha_256.get_digest_length()),
+		&md_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: HASH"),
+		 HASH->get_data(),
+		 HASH->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+eap_status_e wapi_core_c::encrypt_multicast_key_data(
+	const eap_variable_data_c * const multicast_key,
+	const eap_variable_data_c * const key_announcement,
+	wai_variable_data_c * const key_data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("TODO: WAPI_Core: this = 0x%08x, %s: wapi_core_c::encrypt_multicast_key_data(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::encrypt_multicast_key_data()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: multicast_key"),
+		 multicast_key->get_data(),
+		 multicast_key->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: m_key_encryption_key_KEK"),
+		 m_key_encryption_key_KEK.get_data(),
+		 m_key_encryption_key_KEK.get_data_length()));
+
+	wapi_am_crypto_sms4_c sms4(m_am_tools);
+
+	status = sms4.set_key(&m_key_encryption_key_KEK);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	eap_variable_data_c encrypted_multicast_key(m_am_tools);
+
+	status = encrypted_multicast_key.set_buffer_length(multicast_key->get_data_length());
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = encrypted_multicast_key.set_data_length(encrypted_multicast_key.get_buffer_length());
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	{
+		eap_variable_data_c iv_block(m_am_tools);
+
+		status = iv_block.set_buffer_length(multicast_key->get_data_length());
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = iv_block.set_data_length(iv_block.get_buffer_length());
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = sms4.ecb_encrypt(
+			key_announcement->get_data(multicast_key->get_data_length()),
+			iv_block.get_data(multicast_key->get_data_length()),
+			multicast_key->get_data_length()/16);
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WAPI_Core: iv_block"),
+			 iv_block.get_data(),
+			 iv_block.get_data_length()));
+
+		// encrypted_multicast_key = multicast_key XOR iv_block.
+		const u8_t * const pIV = iv_block.get_data(multicast_key->get_data_length());
+		const u8_t * const pdata = multicast_key->get_data(multicast_key->get_data_length());
+		u8_t * const output = encrypted_multicast_key.get_data(multicast_key->get_data_length());
+
+		if (pIV == 0
+			|| pdata == 0
+			|| output == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		for (u32_t ind = 0u; ind < multicast_key->get_data_length(); ind++)
+		{
+			output[ind] = pdata[ind] ^ pIV[ind];
+		}
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: encrypted_multicast_key"),
+		 encrypted_multicast_key.get_data(),
+		 encrypted_multicast_key.get_data_length()));
+
+	status = key_data->create(
+		wai_payload_type_key_data,
+		encrypted_multicast_key.get_data(),
+		encrypted_multicast_key.get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::decrypt_multicast_key_data(
+	const wai_variable_data_c * const key_data,
+	const eap_variable_data_c * const key_announcement,
+	eap_variable_data_c * const multicast_key)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("TODO: WAPI_Core: this = 0x%08x, %s: wapi_core_c::decrypt_multicast_key_data(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::decrypt_multicast_key_data()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: key_data"),
+		 key_data->get_type_data(key_data->get_type_data_length()),
+		 key_data->get_type_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: m_key_encryption_key_KEK"),
+		 m_key_encryption_key_KEK.get_data(),
+		 m_key_encryption_key_KEK.get_data_length()));
+
+	wapi_am_crypto_sms4_c sms4(m_am_tools);
+
+	status = sms4.set_key(&m_key_encryption_key_KEK);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = multicast_key->set_buffer_length(key_data->get_type_data_length());
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = multicast_key->set_data_length(multicast_key->get_buffer_length());
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	{
+		eap_variable_data_c iv_block(m_am_tools);
+		if (iv_block.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = iv_block.set_buffer_length(key_data->get_type_data_length());
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = iv_block.set_data_length(iv_block.get_buffer_length());
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = sms4.ecb_encrypt(
+			key_announcement->get_data(key_data->get_type_data_length()),
+			iv_block.get_data(key_data->get_type_data_length()),
+			key_data->get_type_data_length()/16);
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WAPI_Core: iv_block"),
+			 iv_block.get_data(),
+			 iv_block.get_data_length()));
+
+		// multicast_key = encrypted_multicast_key XOR iv_block.
+		const u8_t * const pIV = iv_block.get_data(key_data->get_type_data_length());
+		const u8_t * const pdata = key_data->get_type_data(key_data->get_type_data_length());
+		u8_t * const output = multicast_key->get_data(key_data->get_type_data_length());
+
+		if (pIV == 0
+			|| pdata == 0
+			|| output == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		for (u32_t ind = 0u; ind < key_data->get_type_data_length(); ind++)
+		{
+			output[ind] = pdata[ind] ^ pIV[ind];
+		}
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: multicast_key"),
+		 multicast_key->get_data(),
+		 multicast_key->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::create_multicast_key(
+	const eap_variable_data_c * const notification_master_key,
+	eap_variable_data_c * const multicast_key)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("TODO: WAPI_Core: this = 0x%08x, %s: wapi_core_c::create_multicast_key(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::create_multicast_key()");
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: notification_master_key"),
+		 notification_master_key->get_data(),
+		 notification_master_key->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: m_key_encryption_key_KEK"),
+		 m_key_encryption_key_KEK.get_data(),
+		 m_key_encryption_key_KEK.get_data_length()));
+
+	// multicas_key = KD_HMAC_SHA256(notification_master_key, string label)
+
+	crypto_kd_hmac_sha256_c kd_hmac(m_am_tools);
+	if (kd_hmac.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_variable_data_c label(m_am_tools);
+	if (label.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = label.add_data(WAPI_MULTICAST_KEY_EXPANSION_LABEL, WAPI_MULTICAST_KEY_EXPANSION_LABEL_LENGTH);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: label"),
+		 label.get_data(),
+		 label.get_data_length()));
+
+	status = kd_hmac.expand_key(
+		multicast_key,
+		WAPI_MULTICAST_KEY_LENGTH,
+		notification_master_key,
+		&label);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAPI_Core: multicast_key"),
+		 multicast_key->get_data(),
+		 multicast_key->get_data_length()));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::create_signature_attributes(
+	wai_variable_data_c * const data_signature,
+	const eap_variable_data_c * const signer_id,
+	const eap_variable_data_c * const signature)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::create_signature_attributes(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::create_signature_attributes()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wai_variable_data_c data_identity(m_am_tools);
+	if (data_identity.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = data_identity.create(
+		wai_payload_type_identity,
+		signer_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("data_identity"),
+		 data_identity.get_full_tlv_buffer()->get_data(),
+		 data_identity.get_full_tlv_buffer()->get_data_length()));
+
+	status = data_signature->create(
+		wai_payload_type_signature_attributes,
+		data_identity.get_full_tlv_buffer());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("data_signature"),
+		 data_signature->get_full_tlv_buffer()->get_data(),
+		 data_signature->get_full_tlv_buffer()->get_data_length()));
+
+	u8_t hash_algorithm_id(WAI_HASH_ALGORITHM_ID);
+	u8_t signature_algorithm_id(WAI_SIGNATURE_ALGORITHM_ID);
+	u8_t signature_parameter_id(WAI_SIGNATURE_PARAMETER_ID);
+	u16_t signature_parameter_content_length(sizeof(WAPI_ECDH_OID_PARAMETER));
+	u16_t signature_length(static_cast<u16_t>(signature->get_data_length()));
+
+	u16_t signature_algorithm_length(
+		sizeof(hash_algorithm_id)
+		+ sizeof(signature_algorithm_id)
+		+ sizeof(signature_parameter_id)
+		+ sizeof(signature_parameter_content_length)
+		+ signature_parameter_content_length);
+
+
+	{
+		u16_t network_order_signature_algorithm_length(eap_htons(signature_algorithm_length));
+
+		status = data_signature->add_data(
+			wai_payload_type_signature_attributes,
+			&network_order_signature_algorithm_length,
+			sizeof(network_order_signature_algorithm_length));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("data_signature"),
+			 data_signature->get_full_tlv_buffer()->get_data(),
+			 data_signature->get_full_tlv_buffer()->get_data_length()));
+	}
+
+	status = data_signature->add_data(
+		wai_payload_type_signature_attributes,
+		&hash_algorithm_id,
+		sizeof(hash_algorithm_id));
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("data_signature"),
+		 data_signature->get_full_tlv_buffer()->get_data(),
+		 data_signature->get_full_tlv_buffer()->get_data_length()));
+
+	status = data_signature->add_data(
+		wai_payload_type_signature_attributes,
+		&signature_algorithm_id,
+		sizeof(signature_algorithm_id));
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("data_signature"),
+		 data_signature->get_full_tlv_buffer()->get_data(),
+		 data_signature->get_full_tlv_buffer()->get_data_length()));
+
+	status = data_signature->add_data(
+		wai_payload_type_signature_attributes,
+		&signature_parameter_id,
+		sizeof(signature_parameter_id));
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("data_signature"),
+		 data_signature->get_full_tlv_buffer()->get_data(),
+		 data_signature->get_full_tlv_buffer()->get_data_length()));
+
+	{
+		u16_t network_order_signature_parameter_content_length(eap_htons(signature_parameter_content_length));
+
+		status = data_signature->add_data(
+			wai_payload_type_signature_attributes,
+			&network_order_signature_parameter_content_length,
+			sizeof(network_order_signature_parameter_content_length));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("data_signature"),
+			 data_signature->get_full_tlv_buffer()->get_data(),
+			 data_signature->get_full_tlv_buffer()->get_data_length()));
+	}
+
+	status = data_signature->add_data(
+		wai_payload_type_signature_attributes,
+		WAPI_ECDH_OID_PARAMETER,
+		sizeof(WAPI_ECDH_OID_PARAMETER));
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("data_signature"),
+		 data_signature->get_full_tlv_buffer()->get_data(),
+		 data_signature->get_full_tlv_buffer()->get_data_length()));
+
+	{
+		u16_t network_order_signature_length(eap_htons(signature_length));
+
+		status = data_signature->add_data(
+			wai_payload_type_signature_attributes,
+			&network_order_signature_length,
+			sizeof(network_order_signature_length));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("data_signature"),
+			 data_signature->get_full_tlv_buffer()->get_data(),
+			 data_signature->get_full_tlv_buffer()->get_data_length()));
+	}
+
+	status = data_signature->add_data(
+		wai_payload_type_signature_attributes,
+		signature);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("data_signature"),
+		 data_signature->get_full_tlv_buffer()->get_data(),
+		 data_signature->get_full_tlv_buffer()->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::parse_signature_attributes(
+	const wai_variable_data_c * const data_signature,
+	eap_variable_data_c * const signer_id,
+	eap_variable_data_c * const signature)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::parse_signature_attributes(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::parse_signature_attributes()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (signer_id == 0
+		|| signer_id->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	u16_t signature_length(0ul);
+
+	u16_t signature_algorithm_length(0ul);
+
+	u32_t offset(0ul);
+	u32_t remaining_data(data_signature->get_type_data_length());
+
+	if (remaining_data > data_signature->get_full_tlv_buffer()->get_data_length())
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+	}
+
+	status = signer_id->reset_start_offset_and_data_length();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	{
+		// Read the ASN1/DER encoded Identity (Subject name, Issuer name, and Sequence number).
+
+		if (data_signature->get_data_length() < (offset+remaining_data))
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		void * const identity_header_begins = data_signature->get_type_data_offset(
+			offset,
+			remaining_data);
+		if (identity_header_begins == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		ec_cs_tlv_header_c identity_header(
+			m_am_tools,
+			identity_header_begins,
+			remaining_data);
+		if (identity_header.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_variable_data_c input_data(
+			m_am_tools,
+			identity_header.get_data(identity_header.get_data_length()),
+			identity_header.get_data_length(),
+			false,
+			false);
+		if (input_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		wapi_asn1_der_parser_c asn1_der_parser(m_am_tools);
+		if (asn1_der_parser.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = asn1_der_parser.decode(&input_data);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = asn1_der_parser.get_wapi_identity(
+			signer_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		const u32_t used_data_length(identity_header.get_header_length() + identity_header.get_data_length());
+
+		offset += used_data_length;
+		remaining_data -= used_data_length;
+
+	}
+
+	{
+		if (data_signature->get_data_length() < (offset+sizeof(u16_t)))
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u16_t * const network_order_signature_algorithm_length =
+			reinterpret_cast<u16_t *>(data_signature->get_type_data_offset(
+										  offset,
+										  sizeof(*network_order_signature_algorithm_length)));
+		if (network_order_signature_algorithm_length == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		signature_algorithm_length = eap_read_u16_t_network_order(
+			network_order_signature_algorithm_length,
+			sizeof(*network_order_signature_algorithm_length));
+
+		offset += sizeof(*network_order_signature_algorithm_length) + signature_algorithm_length;
+	}
+
+	// NOTE, we skip all the Signature algorithm content.
+
+	{
+		if (data_signature->get_data_length() < (offset+sizeof(u16_t)))
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u16_t * const network_order_signature_length = reinterpret_cast<u16_t *>(data_signature->get_type_data_offset(
+			offset,
+			sizeof(*network_order_signature_length)));
+		if (network_order_signature_length == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		signature_length = eap_read_u16_t_network_order(
+			network_order_signature_length,
+			sizeof(*network_order_signature_length));
+
+		offset += sizeof(*network_order_signature_length);
+	}
+
+
+	{
+		if (data_signature->get_data_length() < (offset+signature_length))
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const pointer_to_signature = data_signature->get_type_data_offset(
+			offset,
+			signature_length);
+		if (pointer_to_signature == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = signature->set_copy_of_buffer(
+			pointer_to_signature,
+			signature_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		offset += signature_length;
+	}
+
+	if (offset != data_signature->get_type_data_length())
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::create_result_of_certificate_verification(
+	wai_variable_data_c * const result_of_certificate_verification,
+	const eap_variable_data_c * const ae_challenge,
+	const eap_variable_data_c * const asue_challenge,
+	const wapi_certificate_result_e asue_certificate_result,
+	const eap_variable_data_c * const asue_certificate,
+	const wapi_certificate_result_e ae_certificate_result,
+	const eap_variable_data_c * const ae_certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::create_result_of_certificate_verification(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::create_result_of_certificate_verification()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (result_of_certificate_verification == 0
+		|| result_of_certificate_verification->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (ae_challenge == 0
+		|| ae_challenge->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (asue_challenge == 0
+		|| asue_challenge->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (asue_certificate == 0
+		|| asue_certificate->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (ae_certificate == 0
+		|| ae_certificate->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::create_result_of_certificate_verification(): ae_challenge"),
+		 ae_challenge->get_data(),
+		 ae_challenge->get_data_length()));
+
+	status = result_of_certificate_verification->create(
+		wai_payload_type_result_of_certificate_verification,
+		ae_challenge);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::create_result_of_certificate_verification(): asue_challenge"),
+		 asue_challenge->get_data(),
+		 asue_challenge->get_data_length()));
+
+	status = result_of_certificate_verification->add_data(
+		wai_payload_type_result_of_certificate_verification,
+		asue_challenge);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	{
+		u8_t verification_result_1(asue_certificate_result);
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_core_c::create_result_of_certificate_verification(): verification_result_1"),
+			 &verification_result_1,
+			 sizeof(verification_result_1)));
+
+		status = result_of_certificate_verification->add_data(
+			wai_payload_type_result_of_certificate_verification,
+			&verification_result_1,
+			sizeof(verification_result_1));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	{
+		wai_variable_data_c data_asue_certificate(m_am_tools);
+		if (data_asue_certificate.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_core_c::create_result_of_certificate_verification(): asue_certificate"),
+			 asue_certificate->get_data(),
+			 asue_certificate->get_data_length()));
+
+		status = data_asue_certificate.create(
+			wai_payload_type_certificate,
+			asue_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = result_of_certificate_verification->add_data(
+			wai_payload_type_result_of_certificate_verification,
+			data_asue_certificate.get_full_tlv_buffer());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	{
+		u8_t verification_result_2(ae_certificate_result);
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_core_c::create_result_of_certificate_verification(): verification_result_2"),
+			 &verification_result_2,
+			 sizeof(verification_result_2)));
+
+		status = result_of_certificate_verification->add_data(
+			wai_payload_type_result_of_certificate_verification,
+			&verification_result_2,
+			sizeof(verification_result_2));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	{
+		wai_variable_data_c data_ae_certificate(m_am_tools);
+		if (data_ae_certificate.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_core_c::create_result_of_certificate_verification(): ae_certificate"),
+			 ae_certificate->get_data(),
+			 ae_certificate->get_data_length()));
+
+		status = data_ae_certificate.create(
+			wai_payload_type_certificate,
+			ae_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = result_of_certificate_verification->add_data(
+			wai_payload_type_result_of_certificate_verification,
+			data_ae_certificate.get_full_tlv_buffer());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::parse_result_of_certificate_verification(
+	const wai_variable_data_c * const result_of_certificate_verification,
+	eap_variable_data_c * const ae_challenge,
+	eap_variable_data_c * const asue_challenge,
+	wapi_certificate_result_e * const asue_certificate_result,
+	eap_variable_data_c * const asue_certificate,
+	wapi_certificate_result_e * const ae_certificate_result,
+	eap_variable_data_c * const ae_certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::parse_result_of_certificate_verification(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::parse_result_of_certificate_verification()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (result_of_certificate_verification == 0
+		|| result_of_certificate_verification->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (ae_challenge == 0
+		|| ae_challenge->get_is_valid() == false
+		|| asue_challenge == 0
+		|| asue_challenge->get_is_valid() == false
+		|| asue_certificate == 0
+		|| asue_certificate->get_is_valid() == false
+		|| ae_certificate == 0
+		|| ae_certificate->get_is_valid() == false
+		|| asue_certificate_result == 0
+		|| ae_certificate_result == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	u32_t offset(0ul);
+
+	if (result_of_certificate_verification->get_type_data_length() < (offset+WAPI_CHALLENGE_LENGTH))
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+	}
+
+	status = ae_challenge->set_copy_of_buffer(
+		result_of_certificate_verification->get_type_data_offset(offset, WAPI_CHALLENGE_LENGTH),
+		WAPI_CHALLENGE_LENGTH);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	offset += WAPI_CHALLENGE_LENGTH;
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::parse_result_of_certificate_verification(): ae_challenge"),
+		 ae_challenge->get_data(),
+		 ae_challenge->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (result_of_certificate_verification->get_type_data_length() < (offset+WAPI_CHALLENGE_LENGTH))
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+	}
+
+	status = asue_challenge->set_copy_of_buffer(
+		result_of_certificate_verification->get_type_data_offset(offset, WAPI_CHALLENGE_LENGTH),
+		WAPI_CHALLENGE_LENGTH);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	offset += WAPI_CHALLENGE_LENGTH;
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::parse_result_of_certificate_verification(): asue_challenge"),
+		 asue_challenge->get_data(),
+		 asue_challenge->get_data_length()));
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	
+	{
+		if (result_of_certificate_verification->get_type_data_length() < (offset+sizeof(u8_t)))
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const verification_result_1 = result_of_certificate_verification->get_type_data_offset(offset, sizeof(*verification_result_1));
+
+		if (verification_result_1 == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		*asue_certificate_result = static_cast<wapi_certificate_result_e>(*verification_result_1);
+
+		offset += sizeof(*verification_result_1);
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_core_c::parse_result_of_certificate_verification(): verification_result_1"),
+			 verification_result_1,
+			 sizeof(*verification_result_1)));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+		if (result_of_certificate_verification->get_type_data_length() < offset)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		u32_t data_length(result_of_certificate_verification->get_type_data_length() - offset);
+
+		if (result_of_certificate_verification->get_type_data_length() < (offset+data_length))
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		ec_cs_tlv_header_c certificate_1(
+			m_am_tools,
+			result_of_certificate_verification->get_type_data_offset(offset, data_length),
+			data_length);
+		if (certificate_1.get_is_valid() == false
+			|| certificate_1.check_header() != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = asue_certificate->set_copy_of_buffer(
+			certificate_1.get_data(certificate_1.get_data_length()),
+			certificate_1.get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		offset += (certificate_1.get_header_length() + certificate_1.get_data_length());
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_core_c::parse_result_of_certificate_verification(): asue_certificate"),
+			 asue_certificate->get_data(),
+			 asue_certificate->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+		if (result_of_certificate_verification->get_type_data_length() < (offset+sizeof(u8_t)))
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const verification_result_2 = result_of_certificate_verification->get_type_data_offset(offset, sizeof(*verification_result_2));
+
+		if (verification_result_2 == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		*ae_certificate_result = static_cast<wapi_certificate_result_e>(*verification_result_2);
+
+		offset += sizeof(*verification_result_2);
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_core_c::parse_result_of_certificate_verification(): verification_result_2"),
+			 verification_result_2,
+			 sizeof(*verification_result_2)));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+		if (result_of_certificate_verification->get_type_data_length() < offset)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		u32_t data_length(result_of_certificate_verification->get_type_data_length() - offset);
+
+		if (result_of_certificate_verification->get_type_data_length() < (offset+data_length))
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		ec_cs_tlv_header_c certificate_2(
+			m_am_tools,
+			result_of_certificate_verification->get_type_data_offset(offset, data_length),
+			data_length);
+		if (certificate_2.get_is_valid() == false
+			|| certificate_2.check_header() != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = ae_certificate->set_copy_of_buffer(
+			certificate_2.get_data(certificate_2.get_data_length()),
+			certificate_2.get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		offset += (certificate_2.get_header_length() + certificate_2.get_data_length());
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_core_c::parse_result_of_certificate_verification(): ae_certificate"),
+			 ae_certificate->get_data(),
+			 ae_certificate->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::packet_send(
+	wai_message_c * const new_wai_message_data,
+	const wai_protocol_subtype_e wapi_subtype)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::packet_send(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::packet_send()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (new_wai_message_data == 0
+		|| new_wai_message_data->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(m_am_tools,
+		m_receive_network_id.get_destination_id(),
+		m_receive_network_id.get_source_id(),
+		m_receive_network_id.get_type());
+
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_ASSERT_ALWAYS(m_MTU > m_trailer_length);
+
+#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == false)
+	{
+		++m_packet_sequence_number;
+	}
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+	// Both client and server initializes re-transmission.
+	// Client will process re-transmitted request again.
+	// Server will re-transmit the packet when timer elapses and no response is received.
+	init_retransmission(
+		&send_network_id,
+		&m_received_wai_message_data,
+		new_wai_message_data,
+		m_packet_sequence_number,
+		wapi_subtype);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = packet_fragment(new_wai_message_data, m_packet_sequence_number);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::packet_fragment(
+	wai_message_c * const new_wai_message_data,
+	const u16_t packet_sequence_number)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::packet_fragment(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::packet_fragment()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (new_wai_message_data == 0
+		|| new_wai_message_data->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(m_am_tools,
+		m_receive_network_id.get_destination_id(),
+		m_receive_network_id.get_source_id(),
+		m_receive_network_id.get_type());
+
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_ASSERT_ALWAYS(m_MTU > m_trailer_length);
+
+	wai_protocol_packet_header_c wai(
+		m_am_tools,
+		new_wai_message_data->get_wai_message_data()->get_data(),
+		new_wai_message_data->get_wai_message_data()->get_data_length());
+
+	if (wai.get_is_valid() == false)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_core_c::packet_fragment(): %s, packet buffer corrupted.\n"),
+			 (m_is_client_role == true) ? "client": "server"
+			 ));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	WAI_PROTOCOL_PACKET_TRACE_HEADER("full packet", &wai, m_is_client);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	const u32_t data_length(wai.get_data_length());
+	const u32_t header_length(wai.get_header_length());
+	const u32_t FRAGMENT_MULTIPLIER = 8ul;
+	const u32_t header_remainder_length(header_length % FRAGMENT_MULTIPLIER);
+	const u32_t data_mtu(m_MTU - header_length - header_remainder_length);
+	const u32_t data_mtu_8(data_mtu - (data_mtu % FRAGMENT_MULTIPLIER));
+
+	u32_t data_fragment_length = (header_remainder_length + data_mtu_8);
+	const u32_t fragment_count = ((data_length + data_fragment_length - 1) / data_fragment_length);
+
+	if (fragment_count == 1ul
+		&& data_length < data_fragment_length)
+	{
+		data_fragment_length = data_length;
+	}
+
+	const u32_t last_data_fragment_length = (data_length - ((fragment_count-1) * data_fragment_length));
+	const u32_t one_packet_length = (header_length + data_fragment_length);
+	EAP_UNREFERENCED_PARAMETER(one_packet_length);
+
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_core_c::packet_fragment(): packet_sequence_number=%d, m_MTU=%d, packet_length=%d, data_length=%d, fragment_count=%d, data_fragment_length=%d, last_data_fragment_length=%d, one_packet_length=%d\n"),
+		packet_sequence_number,
+		m_MTU,
+		(header_length+data_length),
+		data_length,
+		fragment_count,
+		data_fragment_length,
+		last_data_fragment_length,
+		one_packet_length));
+
+	EAP_ASSERT(last_data_fragment_length <= data_fragment_length);
+
+	u32_t current_fragment_length(data_fragment_length);
+
+	for (u32_t frag_ind = 0ul; frag_ind < fragment_count; ++frag_ind)
+	{
+		u32_t buffer_size = m_wapi_header_offset + wai.get_header_length() + current_fragment_length + m_trailer_length;
+
+		// Creates a fragment.
+		eap_buf_chain_wr_c wai_packet(
+			eap_write_buffer, 
+			m_am_tools, 
+			buffer_size);
+
+		if (wai_packet.get_is_valid() == false)
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("wapi_core_c::packet_fragment(): %s, packet buffer corrupted.\n"),
+				 (m_is_client == true) ? "client": "server"
+				 ));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = wai_packet.add_data_to_offset(
+			m_wapi_header_offset,
+			wai.get_header_buffer(wai.get_header_length()),
+			wai.get_header_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = wai_packet.add_data_to_offset(
+			m_wapi_header_offset+wai.get_header_length(),
+			wai.get_data_offset(frag_ind * data_fragment_length, current_fragment_length),
+			current_fragment_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		wai_protocol_packet_header_c wai_fragment_header(
+			m_am_tools,
+			wai_packet.get_data_offset(m_wapi_header_offset, wai.get_header_length() + current_fragment_length),
+			wai.get_header_length() + current_fragment_length);
+
+		if (wai_fragment_header.get_is_valid() == false)
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("wapi_core_c::packet_fragment(): %s, packet buffer corrupted.\n"),
+				 (m_is_client_role == true) ? "client": "server"
+				 ));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+		}
+
+		status = wai_fragment_header.set_packet_sequence_number(packet_sequence_number);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = wai_fragment_header.set_fragment_sequence_number(static_cast<u8_t>(frag_ind));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = wai_fragment_header.set_length(wai.get_header_length() + current_fragment_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		if ((frag_ind+1ul) < fragment_count)
+		{
+			// Not last fragment.
+			wai_fragment_header.set_flag(wai_fragment_header.get_flag() | wai_protocol_packet_header_c::m_flag_mask_fragment_exists);
+		}
+		else
+		{
+			// Last fragment.
+			wai_fragment_header.set_flag(wai_fragment_header.get_flag() & ~wai_protocol_packet_header_c::m_flag_mask_fragment_exists);
+		}
+
+		if ((frag_ind+2ul) == fragment_count)
+		{
+			current_fragment_length = last_data_fragment_length;
+		}
+
+		WAI_PROTOCOL_PACKET_TRACE_HEADER("fragment", &wai_fragment_header, m_is_client);
+
+		status = packet_send(
+			&send_network_id,
+			&wai_packet,
+			m_wapi_header_offset,
+			wai_fragment_header.get_length(),
+			buffer_size);
+
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::packet_reassemble(const wai_protocol_packet_header_c * const wai)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::packet_reassemble(): wait fragment number %d, packet fragment number %d, state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 m_fragment_sequence_number,
+		 wai->get_fragment_sequence_number(),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("           %s: wapi_core_c::packet_reassemble(): sequence number %d, required sequence number %d.\n"),
+		(m_is_client == true) ? "client": "server",
+		wai->get_packet_sequence_number(),
+		m_packet_sequence_number));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::packet_reassemble()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (wai == 0
+		|| wai->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	status = wai->check_header();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (wai->get_fragment_sequence_number() != m_fragment_sequence_number)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::packet_reassemble(): fragment sequence number %d != required fragment sequence number %d.\n"),
+			(m_is_client == true) ? "client": "server",
+			wai->get_fragment_sequence_number(),
+			m_fragment_sequence_number));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+
+	wai_protocol_packet_header_c reass_wai(
+		m_am_tools);
+	
+	if (wai->get_fragment_sequence_number() == 0u)
+	{
+		m_reassemble_packet.reset();
+
+		// Add header and data.
+		status = m_reassemble_packet.set_copy_of_buffer(
+			wai->get_header_buffer(wai->get_length()),
+			wai->get_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = reass_wai.set_header_buffer(
+			m_reassemble_packet.get_data(),
+			m_reassemble_packet.get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		status = reass_wai.set_header_buffer(
+			m_reassemble_packet.get_data(),
+			m_reassemble_packet.get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		if (wai->get_packet_sequence_number() != reass_wai.get_packet_sequence_number())
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: WAI: %s: wapi_core_c::packet_reassemble(): sequence number %d != required sequence number %d.\n"),
+				(m_is_client == true) ? "client": "server",
+				wai->get_packet_sequence_number(),
+				reass_wai.get_packet_sequence_number()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+		}
+
+		if (wai->get_subtype() != reass_wai.get_subtype())
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: WAI: %s: wapi_core_c::packet_reassemble(): sub-type %d != required sub-type %d.\n"),
+				(m_is_client == true) ? "client": "server",
+				wai->get_subtype(),
+				reass_wai.get_subtype()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+		}
+
+		// Add data.
+		status = m_reassemble_packet.add_data(
+			wai->get_data(wai->get_data_length()),
+			wai->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = reass_wai.set_header_buffer(
+			m_reassemble_packet.get_data(),
+			m_reassemble_packet.get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = reass_wai.set_length(reass_wai.get_length() + wai->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = reass_wai.set_fragment_sequence_number(wai->get_fragment_sequence_number());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	status = reass_wai.set_flag(wai->get_flag());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	++m_fragment_sequence_number;
+
+	WAI_PROTOCOL_PACKET_TRACE_HEADER("reassembled packet", &reass_wai, m_is_client_role);
+
+	if ((reass_wai.get_flag() & wai_protocol_packet_header_c::m_flag_mask_fragment_exists) != 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request);
+	}
+
+	status = m_received_wai_message_data.set_wai_message_data(&m_reassemble_packet);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	// This is the last fragment.
+
+	m_fragment_sequence_number = 0ul;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::start_authentication()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::start_authentication(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::start_authentication()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	m_fragment_sequence_number = 0ul;
+	m_packet_sequence_number = 0ul;
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+	if (m_wapi_negotiation_state == wapi_negotiation_state_none
+		|| m_only_initial_authentication == true)
+	{
+		m_wapi_negotiation_state = wapi_negotiation_state_initial_negotiation;
+	}
+	else if (m_wapi_negotiation_state == wapi_negotiation_state_initial_negotiation)
+	{
+		m_wapi_negotiation_state = wapi_negotiation_state_rekeying;
+	}
+	else if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+	{
+		// Randomly change to initial negotiation.
+		crypto_random_c rand(m_am_tools);
+		if (rand.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		const u32_t MIN_LIMIT = 0ul;
+		const u32_t MAX_LIMIT = 100ul;
+		const u32_t SELECTION_LIMIT = MAX_LIMIT/2ul;
+
+		if (rand.get_rand_integer(MIN_LIMIT, MAX_LIMIT) <= SELECTION_LIMIT)
+		{
+			m_wapi_negotiation_state = wapi_negotiation_state_initial_negotiation;
+		}
+	}
+
+	if (m_is_client == false
+		&& (m_wapi_state == wapi_core_state_none
+			|| m_wapi_state == wapi_core_state_authentication_ok
+			|| m_wapi_state == wapi_core_state_authentication_failed))
+	{
+		if (m_authentication_type == eapol_key_authentication_type_WAI_PSK)
+		{
+			set_wapi_state(wapi_core_state_start_unicast_key_negotiation);
+
+			status = start_unicast_key_negotiation();
+		}
+		else if (m_authentication_type == eapol_key_authentication_type_WAI_certificate)
+		{
+			set_wapi_state(wapi_core_state_start_certificate_negotiation);
+
+			status = start_certificate_negotiation();
+		}
+		else
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+		}
+	}
+	else
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::start_authentication(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_none),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		status =  eap_status_unexpected_message;
+		(void) EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::allow_authentication()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::allow_authentication(): state=%s, negotiation_state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+		 wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::allow_authentication()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	m_fragment_sequence_number = 0ul;
+
+	if (m_wapi_negotiation_state == wapi_negotiation_state_none)
+	{
+		m_wapi_negotiation_state = wapi_negotiation_state_initial_negotiation;
+	}
+	else if (m_wapi_negotiation_state == wapi_negotiation_state_initial_negotiation)
+	{
+		m_wapi_negotiation_state = wapi_negotiation_state_rekeying;
+	}
+
+	if (m_wapi_state == wapi_core_state_none)
+	{
+		if (m_authentication_type == eapol_key_authentication_type_WAI_PSK)
+		{
+			set_wapi_state(wapi_core_state_wait_unicast_key_negotiation_request_message);
+			status = eap_status_ok;
+		}
+		else if (m_authentication_type == eapol_key_authentication_type_WAI_certificate)
+		{
+			set_wapi_state(wapi_core_state_wait_authentication_activation_message);
+			status = eap_status_ok;
+		}
+		else
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+		}
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::allow_authentication(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_none),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::init_bksa_caching_timeout()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::init_bksa_caching_timeout(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::init_bksa_caching_timeout()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("%s: Removes BKSA cache\n"),
+		 (m_is_client == true ? "client": "server")));
+
+	// Now we do not use BKSA cache, clean-up state.
+	(void) reset();
+
+	// Timeout value zero will remove state immediately.
+	status = set_session_timeout(0ul);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::reset_cached_bksa()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::reset_cached_bksa(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::reset_cached_bksa()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	// Now we do not use BKSA cache, clean-up state.
+	status = reset();
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::read_reassociation_parameters(
+	const eap_am_network_id_c * const /* receive_network_id */, ///< source includes remote address, destination includes local address.
+	const eapol_key_authentication_type_e /* required_authentication_type */,
+	eap_variable_data_c * const /* BKSA */,
+	const eap_variable_data_c * const /* received_ie */,
+	const eap_variable_data_c * const /* sent_ie */)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::read_reassociation_parameters(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::read_reassociation_parameters()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	// Now we do not support cached BKSAs.
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+eap_status_e wapi_core_c::increase_u128_t_network_order(
+	eap_variable_data_c * const u128_t_integer) const
+{
+	u64_t half_integer[2];
+
+	half_integer[1ul] = eap_read_u64_t_network_order(
+		u128_t_integer->get_data(sizeof(u64_t)),
+		sizeof(u64_t));
+
+	half_integer[0ul] = eap_read_u64_t_network_order(
+		u128_t_integer->get_data_offset(sizeof(u64_t), sizeof(u64_t)),
+		sizeof(u64_t));
+
+	if (half_integer[0ul] == (~0UL))
+	{
+		++half_integer[1ul];
+	}
+	++half_integer[0ul];
+
+	eap_status_e status = eap_write_u64_t_network_order(
+		u128_t_integer->get_data(sizeof(u64_t)),
+		sizeof(u64_t),
+		half_integer[1ul]);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = eap_write_u64_t_network_order(
+		u128_t_integer->get_data_offset(sizeof(u64_t), sizeof(u64_t)),
+		sizeof(u64_t),
+		half_integer[0ul]);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+//--------------------------------------------------
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+eap_status_e wapi_core_c::start_certificate_negotiation()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::start_certificate_negotiation(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::start_certificate_negotiation()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	m_packet_sequence_number = 0u;
+
+	status = m_ec_certificate_store->query_asu_id();
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+//--------------------------------------------------
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+eap_status_e wapi_core_c::start_unicast_key_negotiation()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::start_unicast_key_negotiation(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::start_unicast_key_negotiation()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (m_authentication_type != eapol_key_authentication_type_WAI_PSK
+		&& m_authentication_type != eapol_key_authentication_type_WAI_certificate)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+	}
+
+	if (m_wapi_state != wapi_core_state_start_unicast_key_negotiation)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::start_unicast_key_negotiation(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_start_unicast_key_negotiation),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create BKID.
+
+	status = create_BKID(&m_BKID, &m_receive_network_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create AE challenge.
+
+	if (m_wapi_negotiation_state == wapi_negotiation_state_initial_negotiation)
+	{
+		crypto_random_c rand(m_am_tools);
+		if (rand.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = rand.get_rand_bytes(
+			&m_ae_unicast_challenge,
+			WAPI_CHALLENGE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		status = m_ae_unicast_challenge.set_copy_of_buffer(&m_next_unicast_challenge);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create the Unicast Key Negotiation Request message.
+
+	wai_message_payloads_c * const payloads = new wai_message_payloads_c(m_am_tools, m_is_client);
+	eap_automatic_variable_c<wai_message_payloads_c> automatic_payloads(m_am_tools, payloads);
+
+	if (payloads == 0
+		|| payloads->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = payloads->initialise_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = payloads->get_wai_protocol_packet_header_writable()->set_subtype(wai_protocol_subtype_unicast_key_negotiation_request);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds FLAG to data field.
+
+	{
+		wai_variable_data_c data_flag(m_am_tools);
+		if (data_flag.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u8_t flag(wai_data_flag_mask_none);
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			flag = wai_data_flag_mask_USK_Rekeying;
+		}
+
+		status = data_flag.create(
+			wai_payload_type_flag,
+			&flag,
+			sizeof(flag));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_flag);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds BKID to data field.
+
+	{
+		wai_variable_data_c data_BKID(m_am_tools);
+		if (data_BKID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_BKID.create(
+			wai_payload_type_bkid,
+			&m_BKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_BKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds USKID to data field.
+
+	{
+		wai_variable_data_c data_USKID(m_am_tools);
+		if (data_USKID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			m_USKID = (m_USKID + 1u) % 2;
+		}
+
+		status = data_USKID.create(
+			wai_payload_type_uskid,
+			&m_USKID,
+			sizeof(m_USKID));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_USKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds ADDID to data field.
+
+	{
+		wai_variable_data_c data_ADDID(m_am_tools);
+		if (data_ADDID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		const eap_variable_data_c * MAC_1 = m_receive_network_id.get_source_id();
+		const eap_variable_data_c * MAC_2 = m_receive_network_id.get_destination_id();
+
+		if (m_is_client == true)
+		{
+			MAC_1 = m_receive_network_id.get_destination_id();
+			MAC_2 = m_receive_network_id.get_source_id();
+		}
+
+		status = data_ADDID.create(
+			wai_payload_type_addid,
+			MAC_1);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data_ADDID.add_data(
+			wai_payload_type_addid,
+			MAC_2);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_ADDID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds AE Challenge to data field.
+
+	{
+		wai_variable_data_c data_AE_challenge(m_am_tools);
+		if (data_AE_challenge.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_AE_challenge.create(
+			wai_payload_type_nonce,
+			&m_ae_unicast_challenge);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_AE_challenge);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create and send message.
+
+	wai_message_c new_wai_message_data(m_am_tools, m_is_client);
+	if (new_wai_message_data.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = payloads->create_wai_tlv_message(&new_wai_message_data, false);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	//m_packet_sequence_number = 0u;
+
+	//cancel_retransmission();
+
+	status = packet_send(
+		&new_wai_message_data,
+		payloads->get_wai_protocol_packet_header_writable()->get_subtype());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	set_wapi_state(wapi_core_state_wait_unicast_key_negotiation_response_message);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+//--------------------------------------------------
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+eap_status_e wapi_core_c::start_multicast_key_announcement()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::start_multicast_key_announcement(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::start_multicast_key_announcement()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (m_authentication_type != eapol_key_authentication_type_WAI_PSK
+		&& m_authentication_type != eapol_key_authentication_type_WAI_certificate)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+	}
+
+	if (m_wapi_state != wapi_core_state_start_multicast_key_announcement)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::start_multicast_key_announcement(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_start_multicast_key_announcement),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create multicast key.
+
+	crypto_random_c rand(m_am_tools);
+	if (rand.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_variable_data_c notification_master_key(m_am_tools);
+	if (notification_master_key.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = rand.get_rand_bytes(
+		&notification_master_key,
+		WAPI_NOTIFICATION_MASTER_KEY_LENGTH);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = create_multicast_key(&notification_master_key, &m_multicast_key);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create the Multicast Key announcement message.
+
+	wai_message_payloads_c * const payloads = new wai_message_payloads_c(m_am_tools, m_is_client);
+	eap_automatic_variable_c<wai_message_payloads_c> automatic_payloads(m_am_tools, payloads);
+
+	if (payloads == 0
+		|| payloads->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = payloads->initialise_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = payloads->get_wai_protocol_packet_header_writable()->set_subtype(wai_protocol_subtype_multicast_key_announcement);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds FLAG to data field.
+
+	{
+		wai_variable_data_c data_flag(m_am_tools);
+		if (data_flag.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u8_t flag(wai_data_flag_mask_none);
+
+		status = data_flag.create(
+			wai_payload_type_flag,
+			&flag,
+			sizeof(flag));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_flag);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds MSKID to data field.
+
+	{
+		wai_variable_data_c data_flag(m_am_tools);
+		if (data_flag.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_initial_negotiation)
+		{
+			m_MSKID = 0u;
+		}
+		else
+		{
+			m_MSKID = (m_MSKID + 1u) % 2;
+		}
+
+		status = data_flag.create(
+			wai_payload_type_mskid_stakeyid,
+			&m_MSKID,
+			sizeof(m_MSKID));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_flag);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds USKID to data field.
+
+	{
+		wai_variable_data_c data_USKID(m_am_tools);
+		if (data_USKID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_USKID.create(
+			wai_payload_type_uskid,
+			&m_USKID,
+			sizeof(m_USKID));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_USKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds ADDID to data field.
+
+	{
+		wai_variable_data_c data_ADDID(m_am_tools);
+		if (data_ADDID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		const eap_variable_data_c * MAC_1 = m_receive_network_id.get_source_id();
+		const eap_variable_data_c * MAC_2 = m_receive_network_id.get_destination_id();
+
+		if (m_is_client == true)
+		{
+			MAC_1 = m_receive_network_id.get_destination_id();
+			MAC_2 = m_receive_network_id.get_source_id();
+		}
+
+		status = data_ADDID.create(
+			wai_payload_type_addid,
+			MAC_1);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data_ADDID.add_data(
+			wai_payload_type_addid,
+			MAC_2);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_ADDID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds Data Packet Number to data field.
+
+	{
+		wai_variable_data_c data_packet_number(m_am_tools);
+		if (data_packet_number.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_initial_negotiation)
+		{
+			const u8_t TEST_DATA_PACKET_NUMBER[] =
+			{
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			};
+
+			status = m_packet_data_number.set_copy_of_buffer(
+				TEST_DATA_PACKET_NUMBER,
+				sizeof(TEST_DATA_PACKET_NUMBER));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		else
+		{
+			status = increase_u128_t_network_order(
+				&m_packet_data_number);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		status = data_packet_number.create(
+			wai_payload_type_data_sequence_number,
+			&m_packet_data_number);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_packet_number);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds Key Announcement to data field.
+
+	{
+		wai_variable_data_c key_announcement(m_am_tools);
+		if (key_announcement.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_initial_negotiation)
+		{
+			const u8_t TEST_KEY_ANNOUNCEMENT[] =
+			{
+				0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
+				0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36, 0x5c, 0x36,
+			};
+
+			status = m_key_announcement.set_copy_of_buffer(
+				TEST_KEY_ANNOUNCEMENT,
+				sizeof(TEST_KEY_ANNOUNCEMENT));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		else
+		{
+			status = increase_u128_t_network_order(
+				&m_key_announcement);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		status = key_announcement.create(
+			wai_payload_type_key_announcement_identifier,
+			&m_key_announcement);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&key_announcement);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds Key Data to data field.
+
+		{
+			wai_variable_data_c key_data(m_am_tools);
+			if (key_data.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = encrypt_multicast_key_data(&notification_master_key, &m_key_announcement, &key_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = payloads->add_tlv(&key_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds MAC to data field.
+
+	{
+		wai_variable_data_c data_MAC(m_am_tools);
+		if (data_MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_variable_data_c MAC(m_am_tools);
+		if (MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_MAC(payloads, &MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = MAC.set_data_length(WAPI_MESSAGE_AUTHENTICATION_CODE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data_MAC.create(
+			wai_payload_type_message_authentication_code,
+			&MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create and send message.
+
+	wai_message_c new_wai_message_data(m_am_tools, m_is_client);
+	if (new_wai_message_data.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = payloads->create_wai_tlv_message(&new_wai_message_data, false);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	//m_packet_sequence_number = 0u;
+
+	//cancel_retransmission();
+
+	status = packet_send(
+		&new_wai_message_data,
+		payloads->get_wai_protocol_packet_header_writable()->get_subtype());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	set_wapi_state(wapi_core_state_wait_multicast_announcement_response_message);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::handle_authentication_activation(
+	const eap_am_network_id_c * const receive_network_id,
+	const wai_protocol_packet_header_c * const wai)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_authentication_activation(): state=%s, negotiation state = %s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+		 wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::handle_authentication_activation()");
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (m_authentication_type != eapol_key_authentication_type_WAI_certificate)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+	}
+
+	if (m_wapi_state != wapi_core_state_wait_authentication_activation_message
+		&& m_wapi_state != wapi_core_state_wait_access_authentication_response_message
+		&& m_wapi_state != wapi_core_state_authentication_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_authentication_activation(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_wait_authentication_activation_message),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	if (receive_network_id == 0
+		|| receive_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (wai == 0
+		|| wai->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	status = wai->check_header();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (wai->get_packet_sequence_number() != WAI_FIRST_SEQUENCE_NUMBER)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_authentication_activation(): sequence number %d != required sequence number %d.\n"),
+			(m_is_client == true) ? "client": "server",
+			wai->get_packet_sequence_number(),
+			WAI_FIRST_SEQUENCE_NUMBER));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	m_packet_sequence_number = WAI_FIRST_SEQUENCE_NUMBER;
+
+	set_wapi_state(wapi_core_state_process_authentication_activation_message);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (m_authentication_type == eapol_key_authentication_type_WAI_certificate)
+	{
+		// Here we swap the addresses.
+		eap_am_network_id_c send_network_id(m_am_tools,
+			m_receive_network_id.get_destination_id(),
+			m_receive_network_id.get_source_id(),
+			m_receive_network_id.get_type());
+
+		if (send_network_id.get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		// This is notification to eapol_core_c object.
+		// WAI unicast negotiation started successfully.
+		eap_state_notification_c * notification = new eap_state_notification_c(
+			m_am_tools,
+			&send_network_id,
+			m_is_client,
+			eap_state_notification_generic,
+			eap_protocol_layer_wai,
+			eapol_key_handshake_type_wai_handshake,
+			eapol_key_state_wapi_authentication_running,
+			eapol_key_state_wapi_authentication_running,
+			0ul,
+			false);
+		if (notification == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+		m_partner->state_notification(notification);
+
+		delete notification;
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wai_message_payloads_c parser(
+		m_am_tools,
+		m_is_client);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t padding_length(0ul);
+
+	status = parser.parse_wai_payloads(
+		wai->get_header_buffer(wai->get_header_buffer_length()), ///< This is the start of the message buffer.
+		wai->get_header_buffer_length(), ///< This is the length of the buffer. This must match with the length of all payloads.
+		&padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify BK rekeying flag.
+
+	{
+		wai_variable_data_c * const flag_payload = parser.get_tlv_pointer(wai_payload_type_flag);
+		if (flag_payload == 0
+			|| flag_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const flag = flag_payload->get_data(sizeof(*flag));
+		if (flag == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			if (((*flag) & wai_data_flag_mask_BK_Rekeying) == 0)
+			{
+				m_wapi_negotiation_state = wapi_negotiation_state_initial_negotiation;
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("WARNING: WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_authentication_activation(): changed to %s.\n"),
+					 this,
+					 (m_is_client == true ? "client": "server"),
+					 wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+			}
+		}
+		else
+		{
+			if (((*flag) & wai_data_flag_mask_BK_Rekeying) != 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Save Authentication Identifier.
+
+	{
+		wai_variable_data_c * const authentication_identifier = parser.get_tlv_pointer(wai_payload_type_authentication_identifier);
+		if (authentication_identifier == 0
+			|| authentication_identifier->get_is_valid_data() == false
+			|| authentication_identifier->get_data_length() < WAPI_AUTHENTICATION_IDENTIFIER_LENGTH)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			// Verify the Authentication Identifier.
+			if (m_am_tools->memcmp(
+				m_authentication_identifier.get_data(WAPI_AUTHENTICATION_IDENTIFIER_LENGTH),
+				authentication_identifier->get_data(WAPI_AUTHENTICATION_IDENTIFIER_LENGTH),
+				WAPI_AUTHENTICATION_IDENTIFIER_LENGTH) != 0)
+			{
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("ERROR: local m_authentication_identifier"),
+					 m_authentication_identifier.get_data(),
+					 m_authentication_identifier.get_data_length()));
+
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("ERROR: received authentication_identifier"),
+					authentication_identifier->get_data(WAPI_AUTHENTICATION_IDENTIFIER_LENGTH),
+					WAPI_AUTHENTICATION_IDENTIFIER_LENGTH));
+
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+		}
+		else
+		{
+			status = m_authentication_identifier.set_copy_of_buffer(
+				authentication_identifier->get_type_data(WAPI_AUTHENTICATION_IDENTIFIER_LENGTH),
+				WAPI_AUTHENTICATION_IDENTIFIER_LENGTH);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Save ASU-ID.
+
+	{
+		wai_variable_data_c * const asu_id = parser.get_tlv_pointer(wai_payload_type_identity);
+		if (asu_id == 0
+			|| asu_id->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		status = m_asu_id.set_copy_of_buffer(
+			asu_id->get_type_data(asu_id->get_type_data_length()),
+			asu_id->get_type_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("m_asu_id"),
+			 m_asu_id.get_data(),
+			 m_asu_id.get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Save STA_AE certificate.
+
+	{
+		wai_variable_data_c * const sta_ae_certificate = parser.get_tlv_pointer(wai_payload_type_certificate);
+		if (sta_ae_certificate == 0
+			|| sta_ae_certificate->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		status = m_peer_certificate.set_copy_of_buffer(
+			sta_ae_certificate->get_type_data(sta_ae_certificate->get_type_data_length()),
+			sta_ae_certificate->get_type_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify the ECDH parameter.
+
+	{
+		wai_variable_data_c * const echd_parameter = parser.get_tlv_pointer(wai_payload_type_echd_parameter);
+		if (echd_parameter == 0
+			|| echd_parameter->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (sizeof(WAPI_ECDH_OID_PARAMETER) != echd_parameter->get_type_data_length()
+			|| m_am_tools->memcmp(
+				WAPI_ECDH_OID_PARAMETER,
+				echd_parameter->get_type_data(sizeof(WAPI_ECDH_OID_PARAMETER)),
+				sizeof(WAPI_ECDH_OID_PARAMETER)) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create ASUE challenge.
+
+	if (m_asue_certificate_challenge.get_is_valid_data() == false)
+	{
+		crypto_random_c rand(m_am_tools);
+		if (rand.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = rand.get_rand_bytes(
+			&m_asue_certificate_challenge,
+			WAPI_CHALLENGE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Selects own certificate issued by ASU-ID.
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("m_asu_id"),
+		 m_asu_id.get_data(),
+		 m_asu_id.get_data_length()));
+
+	status = m_ec_certificate_store->select_certificate(&m_asu_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::handle_access_authentication_response(
+	const eap_am_network_id_c * const receive_network_id,
+	const wai_protocol_packet_header_c * const wai)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_access_authentication_response(): state=%s, negotiation state = %s\n"),
+		this,
+		(m_is_client == true ? "client": "server"),
+		wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+		wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::handle_access_authentication_response()");
+
+	if (m_authentication_type != eapol_key_authentication_type_WAI_certificate)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+	}
+
+	if (m_wapi_state != wapi_core_state_wait_access_authentication_response_message
+		&& m_wapi_state != wapi_core_state_wait_unicast_key_negotiation_request_message
+		&& m_wapi_state != wapi_core_state_wait_unicast_key_negotiation_confirmation_message
+		&& m_wapi_state != wapi_core_state_authentication_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_access_authentication_response(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_wait_access_authentication_response_message),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (receive_network_id == 0
+		|| receive_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (wai == 0
+		|| wai->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	status = wai->check_header();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (wai->get_packet_sequence_number() != (m_packet_sequence_number + 1u))
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_access_authentication_response(): sequence number %d != required sequence number %d.\n"),
+			(m_is_client == true) ? "client": "server",
+			wai->get_packet_sequence_number(),
+			(m_packet_sequence_number + 1u)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	++m_packet_sequence_number;
+
+	set_wapi_state(wapi_core_state_process_access_authentication_response_message);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wai_message_payloads_c parser(
+		m_am_tools,
+		m_is_client);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t padding_length(0ul);
+
+	status = parser.parse_wai_payloads(
+		wai->get_header_buffer(wai->get_header_buffer_length()), ///< This is the start of the message buffer.
+		wai->get_header_buffer_length(), ///< This is the length of the buffer. This must match with the length of all payloads.
+		&padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify BK rekeying flag.
+
+	{
+		wai_variable_data_c * const flag_payload = parser.get_tlv_pointer(wai_payload_type_flag);
+		if (flag_payload == 0
+			|| flag_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const pointer_to_flag = flag_payload->get_data(sizeof(*pointer_to_flag));
+		if (pointer_to_flag == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		m_do_certificate_validation = false;
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			if (((*pointer_to_flag) & wai_data_flag_mask_BK_Rekeying) == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			if (((*pointer_to_flag) & wai_data_flag_mask_Certificate_Validation_Request) != 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_access_authentication_response(): no certificate validation\n"),
+				this,
+				(m_is_client == true ? "client": "server")));
+		}
+		else
+		{
+			if (((*pointer_to_flag) & wai_data_flag_mask_BK_Rekeying) != 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_access_authentication_response(): does certificate validation\n"),
+				this,
+				(m_is_client == true ? "client": "server")));
+
+			m_do_certificate_validation = true;
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify AE identity.
+
+	{
+
+		wai_variable_data_c * const ae_identity = parser.get_tlv_pointer(wai_payload_type_identity);
+		if (ae_identity == 0
+			|| ae_identity->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_ae_id.compare(
+				ae_identity->get_type_data(ae_identity->get_type_data_length()),
+				ae_identity->get_type_data_length()) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local m_ae_id"),
+				 m_ae_id.get_data(),
+				 m_ae_id.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received AE-ID"),
+				 ae_identity->get_type_data(ae_identity->get_type_data_length()),
+				 ae_identity->get_type_data_length()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Verify ASUE identity.
+
+		wai_variable_data_c * const asue_identity = ae_identity->get_next_payload_with_same_tlv_type();
+		if (asue_identity == 0
+			|| asue_identity->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_asue_id.compare(
+				asue_identity->get_type_data(asue_identity->get_type_data_length()),
+				asue_identity->get_type_data_length()) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local m_asue_id"),
+				 m_asue_id.get_data(),
+				 m_asue_id.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received ASUE-ID"),
+				 asue_identity->get_type_data(asue_identity->get_type_data_length()),
+				 asue_identity->get_type_data_length()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify ASUE challenge.
+
+	{
+
+		wai_variable_data_c * const asue_challenge = parser.get_tlv_pointer(wai_payload_type_nonce);
+		if (asue_challenge == 0
+			|| asue_challenge->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_asue_certificate_challenge.compare(
+				asue_challenge->get_type_data(asue_challenge->get_type_data_length()),
+				asue_challenge->get_type_data_length()) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local m_asue_certificate_challenge"),
+				 m_asue_certificate_challenge.get_data(),
+				 m_asue_certificate_challenge.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received ASUE-challenge"),
+				 asue_challenge->get_type_data(asue_challenge->get_type_data_length()),
+				 asue_challenge->get_type_data_length()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Save AE challenge.
+
+		wai_variable_data_c * const ae_challenge = asue_challenge->get_next_payload_with_same_tlv_type();
+		if (ae_challenge == 0
+			|| ae_challenge->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		status = m_ae_certificate_challenge.set_copy_of_buffer(ae_challenge->get_data(WAPI_CHALLENGE_LENGTH), WAPI_CHALLENGE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	wai_variable_data_c * ae_signature_trusted_by_asue = 0;
+
+	if (m_do_certificate_validation == true)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_access_authentication_response(): does certificate validation\n"),
+			this,
+			(m_is_client == true ? "client": "server")));
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Save result of certificate_verification.
+
+		{
+			wai_variable_data_c * const result_of_certificate_verification = parser.get_tlv_pointer(wai_payload_type_result_of_certificate_verification);
+			if (result_of_certificate_verification == 0
+				|| result_of_certificate_verification->get_is_valid_data() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			status = m_result_of_certificate_verification.set_copy_of_buffer(result_of_certificate_verification);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			{
+				eap_variable_data_c ae_challenge(m_am_tools);
+				eap_variable_data_c asue_challenge(m_am_tools);
+				eap_variable_data_c asue_certificate(m_am_tools);
+
+				wapi_certificate_result_e asue_certificate_result(wapi_certificate_result_none);
+				wapi_certificate_result_e ae_certificate_result(wapi_certificate_result_none);
+
+				status = parse_result_of_certificate_verification(
+					&m_result_of_certificate_verification,
+					&ae_challenge,
+					&asue_challenge,
+					&asue_certificate_result,
+					&asue_certificate,
+					&ae_certificate_result,
+					&m_ae_certificate);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				// Verify AE-Challenge.
+				if (m_ae_certificate_challenge.compare(&ae_challenge) != 0)
+				{
+					EAP_TRACE_DATA_DEBUG(
+						m_am_tools, 
+						TRACE_FLAGS_DEFAULT, 
+						(EAPL("ERROR: local m_ae_certificate_challenge"),
+						 m_ae_certificate_challenge.get_data(),
+						 m_ae_certificate_challenge.get_data_length()));
+
+					EAP_TRACE_DATA_DEBUG(
+						m_am_tools, 
+						TRACE_FLAGS_DEFAULT, 
+						(EAPL("ERROR: received AE-challenge"),
+						 ae_challenge.get_data(),
+						 ae_challenge.get_data_length()));
+
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+				}
+
+				// Verify ASUE-Challenge.
+				if (m_asue_certificate_challenge.compare(&asue_challenge) != 0)
+				{
+					EAP_TRACE_DATA_DEBUG(
+						m_am_tools, 
+						TRACE_FLAGS_DEFAULT, 
+						(EAPL("ERROR: local m_asue_certificate_challenge"),
+						 m_asue_certificate_challenge.get_data(),
+						 m_asue_certificate_challenge.get_data_length()));
+
+					EAP_TRACE_DATA_DEBUG(
+						m_am_tools, 
+						TRACE_FLAGS_DEFAULT, 
+						(EAPL("ERROR: received ASUE-challenge"),
+						 asue_challenge.get_data(),
+						 asue_challenge.get_data_length()));
+
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+				}
+
+				// Verify ASUE-Certificate.
+				if (m_own_certificate.compare(&asue_certificate) != 0)
+				{
+					EAP_TRACE_DATA_DEBUG(
+						m_am_tools, 
+						TRACE_FLAGS_DEFAULT, 
+						(EAPL("ERROR: local m_own_certificate"),
+						 m_own_certificate.get_data(),
+						 m_own_certificate.get_data_length()));
+
+					EAP_TRACE_DATA_DEBUG(
+						m_am_tools, 
+						TRACE_FLAGS_DEFAULT, 
+						(EAPL("ERROR: received ASUE-Certificate"),
+						 asue_certificate.get_data(),
+						 asue_certificate.get_data_length()));
+
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+				}
+
+				if (asue_certificate_result != wapi_certificate_result_valid)
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools,
+						TRACE_FLAGS_DEFAULT,
+						(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_access_authentication_response(): asue_certificate_result=%d\n"),
+						this,
+						(m_is_client == true ? "client": "server"),
+						asue_certificate_result));
+
+					switch (asue_certificate_result)
+					{
+					case wapi_certificate_result_issuer_is_unknown:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_unknown_ca);
+					case wapi_certificate_result_certificate_is_based_on_an_untrusted_root:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_unknown_ca);
+					case wapi_certificate_result_certificate_is_not_time_valid:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_certificate_expired);
+					case wapi_certificate_result_certificate_have_not_a_valid_signature:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_certificate);
+					case wapi_certificate_result_certificate_is_revoked:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_certificate_revoked);
+					case wapi_certificate_result_certificate_is_not_valid_for_proposed_usage:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_certificate);
+					case wapi_certificate_result_revocation_state_of_the_certificate_is_unknown:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_certificate);
+					default:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
+					}
+				}
+
+				if (ae_certificate_result != wapi_certificate_result_valid)
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools,
+						TRACE_FLAGS_DEFAULT,
+						(EAPL("ERROR: WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_access_authentication_response(): ae_certificate_result=%d\n"),
+						this,
+						(m_is_client == true ? "client": "server"),
+						ae_certificate_result));
+
+					switch (ae_certificate_result)
+					{
+					case wapi_certificate_result_issuer_is_unknown:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_unknown_ca);
+					case wapi_certificate_result_certificate_is_based_on_an_untrusted_root:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_unknown_ca);
+					case wapi_certificate_result_certificate_is_not_time_valid:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_certificate_expired);
+					case wapi_certificate_result_certificate_have_not_a_valid_signature:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_certificate);
+					case wapi_certificate_result_certificate_is_revoked:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_certificate_revoked);
+					case wapi_certificate_result_certificate_is_not_valid_for_proposed_usage:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_certificate);
+					case wapi_certificate_result_revocation_state_of_the_certificate_is_unknown:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_certificate);
+					default:
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
+					}
+				}
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Save server signature trusted by ASUE.
+
+		{
+			wai_variable_data_c * const server_signature_trusted_by_asue = parser.get_tlv_pointer(wai_payload_type_signature_attributes);
+			if (server_signature_trusted_by_asue == 0
+				|| server_signature_trusted_by_asue->get_is_valid_data() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			status = m_server_signature_trusted_by_asue.set_copy_of_buffer(server_signature_trusted_by_asue);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+			// Save server signature trusted by AE.
+			// NOTE: This is used only when server trusted by ASUE is different than server trusted by AE.
+
+			wai_variable_data_c * const server_signature_trusted_by_ae = server_signature_trusted_by_asue->get_next_payload_with_same_tlv_type();
+			if (server_signature_trusted_by_ae == 0
+				|| server_signature_trusted_by_ae->get_is_valid_data() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+			// Save Signature of AE. This is always the last signature.
+
+			ae_signature_trusted_by_asue = server_signature_trusted_by_ae->get_next_payload_with_same_tlv_type();
+
+			if ((ae_signature_trusted_by_asue == 0
+				|| ae_signature_trusted_by_asue->get_is_valid_data() == false))
+			{
+				// Server trusted by AE is the same as server trusted by ASUE.
+				status = m_server_signature_trusted_by_ae.set_copy_of_buffer(server_signature_trusted_by_asue);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				// Signature of AE is always the last signature.
+				ae_signature_trusted_by_asue = server_signature_trusted_by_ae;
+			}
+			else
+			{
+				// Server trusted by AE is different than server trusted by ASUE.
+				status = m_server_signature_trusted_by_ae.set_copy_of_buffer(server_signature_trusted_by_ae);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+		}
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_access_authentication_response(): no certificate validation\n"),
+			this,
+			(m_is_client == true ? "client": "server")));
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Save Signature of AE.
+
+		ae_signature_trusted_by_asue = parser.get_tlv_pointer(wai_payload_type_signature_attributes);
+		if (ae_signature_trusted_by_asue == 0
+			|| ae_signature_trusted_by_asue->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+		wai_variable_data_c * ae_key_data = 0;
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Compare ASUE key data.
+		{
+			wai_variable_data_c * const asue_key_data = parser.get_tlv_pointer(wai_payload_type_key_data);
+			if (asue_key_data == 0
+				|| asue_key_data->get_is_valid_data() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			u32_t offset(0ul);
+
+			const u8_t * const point_type = asue_key_data->get_type_data_offset(offset, sizeof(u8_t));
+			if (point_type == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			if (*point_type != WAI_EC_POINT_TYPE_NO_COMPRESSION_ID)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			offset += sizeof(*point_type);
+
+			const u32_t x_key_element_length((1ul + asue_key_data->get_type_data_length() - sizeof(*point_type)) / 2ul);
+			const u32_t y_key_element_length(asue_key_data->get_type_data_length() - sizeof(*point_type) - x_key_element_length);
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: sizeof(*point_type)=%d, *point_type=0x%02x, get_type_data_length()=%d, x_key_element_length=%d, y_key_element_length=%d\n"),
+				 this,
+				 (m_is_client == true ? "client": "server"),
+				 sizeof(*point_type),
+				 *point_type,
+				 asue_key_data->get_type_data_length(),
+				 x_key_element_length,
+				 y_key_element_length));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_own_public_key_x"),
+				 m_own_public_key_x.get_data(),
+				 m_own_public_key_x.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("received public_key_x"),
+				 asue_key_data->get_type_data_offset(offset, x_key_element_length),
+				 x_key_element_length));
+
+			if (m_own_public_key_x.compare(
+				asue_key_data->get_type_data_offset(offset, x_key_element_length),
+				x_key_element_length) != 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			offset += x_key_element_length;
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_own_public_key_y"),
+				 m_own_public_key_y.get_data(),
+				 m_own_public_key_y.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("received public_key_y"),
+				 asue_key_data->get_type_data_offset(offset, y_key_element_length),
+				 y_key_element_length));
+
+			if (m_own_public_key_y.compare(
+				asue_key_data->get_type_data_offset(offset, y_key_element_length),
+				y_key_element_length) != 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			ae_key_data = asue_key_data->get_next_payload_with_same_tlv_type();
+			if (asue_key_data == 0
+				|| asue_key_data->get_is_valid_data() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Save AE key data.
+		{
+			u32_t offset(0ul);
+
+			const u8_t * const point_type = ae_key_data->get_type_data_offset(offset, sizeof(u8_t));
+			if (point_type == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			if (*point_type != WAI_EC_POINT_TYPE_NO_COMPRESSION_ID)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			offset += sizeof(*point_type);
+
+			const u32_t x_key_element_length((1ul + ae_key_data->get_type_data_length() - sizeof(*point_type)) / 2ul);
+			const u32_t y_key_element_length(ae_key_data->get_type_data_length() - sizeof(*point_type) - x_key_element_length);
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: sizeof(*point_type)=%d, *point_type=0x%02x, get_type_data_length()=%d, x_key_element_length=%d, y_key_element_length=%d\n"),
+				 this,
+				 (m_is_client == true ? "client": "server"),
+				 sizeof(*point_type),
+				 *point_type,
+				 ae_key_data->get_type_data_length(),
+				 x_key_element_length,
+				 y_key_element_length));
+
+			status = m_peer_public_key_x.set_copy_of_buffer(
+				ae_key_data->get_type_data_offset(offset, x_key_element_length),
+				x_key_element_length);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_peer_public_key_x"),
+				 m_peer_public_key_x.get_data(),
+				 m_peer_public_key_x.get_data_length()));
+
+			offset += x_key_element_length;
+
+			status = m_peer_public_key_y.set_copy_of_buffer(
+				ae_key_data->get_type_data_offset(offset, y_key_element_length),
+				y_key_element_length);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_peer_public_key_y"),
+				 m_peer_public_key_y.get_data(),
+				 m_peer_public_key_y.get_data_length()));
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify Signature of AE.
+
+	{
+		if (ae_signature_trusted_by_asue == 0
+			|| ae_signature_trusted_by_asue->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		eap_variable_data_c signature_data(m_am_tools);
+		if (signature_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_variable_data_c received_ae_id(m_am_tools);
+		if (received_ae_id.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = parse_signature_attributes(
+			ae_signature_trusted_by_asue,
+			&received_ae_id,
+			&signature_data);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("received_ae_id"),
+			 received_ae_id.get_data(),
+			 received_ae_id.get_data_length()));
+
+		if (received_ae_id.compare(&m_ae_id) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local m_ae_id"),
+				 m_ae_id.get_data(),
+				 m_ae_id.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received AE-ID"),
+				 received_ae_id.get_data(received_ae_id.get_data_length()),
+				 received_ae_id.get_data_length()));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		eap_variable_data_c HASH(m_am_tools);
+		if (HASH.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		{
+			wai_message_payloads_c * const signature_payload = new wai_message_payloads_c(m_am_tools, m_is_client);
+			eap_automatic_variable_c<wai_message_payloads_c> automatic_signature_payload(m_am_tools, signature_payload);
+
+			if (signature_payload == 0
+				|| signature_payload->get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			// Copy all payloads except the last signature.
+			for (u32_t index = 0ul; (index+1ul) < parser.get_tlv_count(); ++index)
+			{
+				const wai_variable_data_c * const payload = parser.get_tlv(index);
+
+				if (payload != 0)
+				{
+					status = signature_payload->insert_payload(payload);
+					if (status != eap_status_ok)
+					{
+						EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+						return EAP_STATUS_RETURN(m_am_tools, status);
+					}
+				}
+			}
+
+			status = create_HASH(signature_payload, true, &HASH);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		status = m_ec_certificate_store->set_ae_certificate(
+			&m_ae_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_ec_certificate_store->verify_signature_with_public_key(
+			&m_ae_id,
+			&HASH,
+			&signature_data,
+			true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+eap_status_e wapi_core_c::handle_access_authentication_request(
+	const eap_am_network_id_c * const receive_network_id,
+	const wai_protocol_packet_header_c * const wai)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_access_authentication_request(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::handle_access_authentication_request()");
+
+	if (m_authentication_type != eapol_key_authentication_type_WAI_certificate)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+	}
+
+	if (m_wapi_state != wapi_core_state_wait_access_authentication_request_message
+		&& m_wapi_state != wapi_core_state_wait_unicast_key_negotiation_response_message
+		&& m_wapi_state != wapi_core_state_authentication_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_access_authentication_request(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_wait_multicast_announcement_message),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (receive_network_id == 0
+		|| receive_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (wai == 0
+		|| wai->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	status = wai->check_header();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (wai->get_packet_sequence_number() != m_packet_sequence_number)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_access_authentication_request(): sequence number %d != required sequence number %d.\n"),
+			(m_is_client == true) ? "client": "server",
+			wai->get_packet_sequence_number(),
+			m_packet_sequence_number));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	set_wapi_state(wapi_core_state_process_access_authentication_request_message);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wai_message_payloads_c parser(
+		m_am_tools,
+		m_is_client);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t padding_length(0ul);
+
+	status = parser.parse_wai_payloads(
+		wai->get_header_buffer(wai->get_header_buffer_length()), ///< This is the start of the message buffer.
+		wai->get_header_buffer_length(), ///< This is the length of the buffer. This must match with the length of all payloads.
+		&padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify BK rekeying flag.
+
+	{
+		wai_variable_data_c * const flag_payload = parser.get_tlv_pointer(wai_payload_type_flag);
+		if (flag_payload == 0
+			|| flag_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const flag = flag_payload->get_data(sizeof(*flag));
+		if (flag == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		m_do_certificate_validation = false;
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			if (((*flag) & wai_data_flag_mask_BK_Rekeying) == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			if (((*flag) & wai_data_flag_mask_Certificate_Validation_Request) != 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_access_authentication_request(): no certificate validation\n"),
+				this,
+				(m_is_client == true ? "client": "server")));
+		}
+		else
+		{
+			if (((*flag) & wai_data_flag_mask_BK_Rekeying) != 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			if (((*flag) & wai_data_flag_mask_Certificate_Validation_Request) == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_access_authentication_request(): does certificate validation\n"),
+				this,
+				(m_is_client == true ? "client": "server")));
+
+			m_do_certificate_validation = true;
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify the Authentication identifier parameter.
+
+	{
+		wai_variable_data_c * const authentication_identifier = parser.get_tlv_pointer(wai_payload_type_authentication_identifier);
+		if (authentication_identifier == 0
+			|| authentication_identifier->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (authentication_identifier->get_type_data_length() != m_authentication_identifier.get_data_length()
+			|| m_am_tools->memcmp(
+				m_authentication_identifier.get_data(),
+				authentication_identifier->get_type_data(authentication_identifier->get_type_data_length()),
+				authentication_identifier->get_type_data_length()) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local m_authentication_identifier"),
+				 m_authentication_identifier.get_data(),
+				 m_authentication_identifier.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received Authentication identifier"),
+				 authentication_identifier->get_type_data(authentication_identifier->get_type_data_length()),
+				 authentication_identifier->get_type_data_length()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify the ECDH parameter.
+
+	{
+		wai_variable_data_c * const echd_parameter = parser.get_tlv_pointer(wai_payload_type_echd_parameter);
+		if (echd_parameter == 0
+			|| echd_parameter->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (sizeof(WAPI_ECDH_OID_PARAMETER) != echd_parameter->get_type_data_length()
+			|| m_am_tools->memcmp(
+				WAPI_ECDH_OID_PARAMETER,
+				echd_parameter->get_type_data(sizeof(WAPI_ECDH_OID_PARAMETER)),
+				sizeof(WAPI_ECDH_OID_PARAMETER)) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local ECDH parameter"),
+				 WAPI_ECDH_OID_PARAMETER,
+				 sizeof(WAPI_ECDH_OID_PARAMETER)));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received ECDH parameter"),
+				 echd_parameter->get_type_data(echd_parameter->get_type_data_length()),
+				 echd_parameter->get_type_data_length()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify the ID of STA_AE parameter.
+
+	{
+		wai_variable_data_c * const ae_id = parser.get_tlv_pointer(wai_payload_type_identity);
+		if (ae_id == 0
+			|| ae_id->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_ae_id.get_data_length() != ae_id->get_type_data_length()
+			|| m_am_tools->memcmp(
+				ae_id->get_type_data(m_ae_id.get_data_length()),
+				m_ae_id.get_data(),
+				m_ae_id.get_data_length()) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local m_ae_id"),
+				 m_ae_id.get_data(),
+				 m_ae_id.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received AE-ID"),
+				 ae_id->get_type_data(ae_id->get_type_data_length()),
+				 ae_id->get_type_data_length()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+		else
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_ae_id"),
+				 m_ae_id.get_data(),
+				 m_ae_id.get_data_length()));
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Save ASUE challenge.
+
+	{
+		wai_variable_data_c * const asue_challenge = parser.get_tlv_pointer(wai_payload_type_nonce);
+		if (asue_challenge == 0
+			|| asue_challenge->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		status = m_asue_certificate_challenge.set_copy_of_buffer(
+			asue_challenge->get_type_data(asue_challenge->get_type_data_length()),
+			asue_challenge->get_type_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Save ASUE key data.
+
+	{
+		wai_variable_data_c * const asue_key_data = parser.get_tlv_pointer(wai_payload_type_key_data);
+		if (asue_key_data == 0
+			|| asue_key_data->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		u32_t offset(0ul);
+
+		const u8_t * const point_type = asue_key_data->get_type_data_offset(offset, sizeof(u8_t));
+		if (point_type == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (*point_type != WAI_EC_POINT_TYPE_NO_COMPRESSION_ID)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		offset += sizeof(*point_type);
+
+		const u32_t x_key_element_length((1ul + asue_key_data->get_type_data_length() - sizeof(*point_type)) / 2ul);
+		const u32_t y_key_element_length(asue_key_data->get_type_data_length() - sizeof(*point_type) - x_key_element_length);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI_Core: this = 0x%08x, %s: sizeof(*point_type)=%d, *point_type=0x%02x, get_type_data_length()=%d, x_key_element_length=%d, y_key_element_length=%d\n"),
+			 this,
+			 (m_is_client == true ? "client": "server"),
+			 sizeof(*point_type),
+			 *point_type,
+			 asue_key_data->get_type_data_length(),
+			 x_key_element_length,
+			 y_key_element_length));
+
+		status = m_peer_public_key_x.set_copy_of_buffer(
+			asue_key_data->get_type_data_offset(offset, x_key_element_length),
+			x_key_element_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("m_peer_public_key_x"),
+			 m_peer_public_key_x.get_data(),
+			 m_peer_public_key_x.get_data_length()));
+
+		offset += x_key_element_length;
+
+		status = m_peer_public_key_y.set_copy_of_buffer(
+			asue_key_data->get_type_data_offset(offset, y_key_element_length),
+			y_key_element_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("m_peer_public_key_y"),
+			 m_peer_public_key_y.get_data(),
+			 m_peer_public_key_y.get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Save STA_ASUE certificate.
+
+	{
+		wai_variable_data_c * const sta_asue_certificate = parser.get_tlv_pointer(wai_payload_type_certificate);
+		if (sta_asue_certificate == 0
+			|| sta_asue_certificate->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		status = m_peer_certificate.set_copy_of_buffer(
+			sta_asue_certificate->get_type_data(sta_asue_certificate->get_type_data_length()),
+			sta_asue_certificate->get_type_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify Signature of ASUE.
+
+	{
+		wai_variable_data_c * const signature_payload = parser.get_tlv_pointer(wai_payload_type_signature_attributes);
+		if (signature_payload == 0
+			|| signature_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		eap_variable_data_c signature_data(m_am_tools);
+		if (signature_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = parse_signature_attributes(
+			signature_payload,
+			&m_asue_id,
+			&signature_data);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("m_asue_id"),
+			 m_asue_id.get_data(),
+			 m_asue_id.get_data_length()));
+
+		eap_variable_data_c HASH(m_am_tools);
+		if (HASH.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_HASH(&parser, false, &HASH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_ec_certificate_store->verify_signature_with_public_key(
+			&m_asue_id,
+			&HASH,
+			&signature_data,
+			false);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::handle_unicast_key_negotiation_request(
+	const eap_am_network_id_c * const receive_network_id,
+	const wai_protocol_packet_header_c * const wai)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_unicast_key_negotiation_request(): state=%s, negotiation state = %s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+		 wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::handle_unicast_key_negotiation_request()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (m_wapi_state != wapi_core_state_wait_unicast_key_negotiation_request_message
+		&& m_wapi_state != wapi_core_state_wait_unicast_key_negotiation_confirmation_message
+		&& m_wapi_state != wapi_core_state_authentication_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_unicast_key_negotiation_request(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_wait_unicast_key_negotiation_request_message),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	if (m_authentication_type != eapol_key_authentication_type_WAI_PSK
+		&& m_authentication_type != eapol_key_authentication_type_WAI_certificate)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+	}
+
+	if (receive_network_id == 0
+		|| receive_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (wai == 0
+		|| wai->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	status = wai->check_header();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (wai->get_packet_sequence_number() != (m_packet_sequence_number + 1u))
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_unicast_key_negotiation_request(): sequence number %d != required sequence number %d.\n"),
+			(m_is_client == true) ? "client": "server",
+			wai->get_packet_sequence_number(),
+			(m_packet_sequence_number + 1u)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	++m_packet_sequence_number;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (m_authentication_type == eapol_key_authentication_type_WAI_PSK)
+	{
+		// Here we swap the addresses.
+		eap_am_network_id_c send_network_id(m_am_tools,
+			m_receive_network_id.get_destination_id(),
+			m_receive_network_id.get_source_id(),
+			m_receive_network_id.get_type());
+
+		if (send_network_id.get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		// This is notification to eapol_core_c object.
+		// WAI unicast negotiation started successfully.
+		eap_state_notification_c * notification = new eap_state_notification_c(
+			m_am_tools,
+			&send_network_id,
+			m_is_client,
+			eap_state_notification_generic,
+			eap_protocol_layer_wai,
+			eapol_key_handshake_type_wai_handshake,
+			eapol_key_state_wapi_authentication_running,
+			eapol_key_state_wapi_authentication_running,
+			0ul,
+			false);
+		if (notification == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+		m_partner->state_notification(notification);
+
+		delete notification;
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = create_BKID(&m_BKID, receive_network_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wai_message_payloads_c parser(
+		m_am_tools,
+		m_is_client);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t padding_length(0ul);
+
+	status = parser.parse_wai_payloads(
+		wai->get_header_buffer(wai->get_header_buffer_length()), ///< This is the start of the message buffer.
+		wai->get_header_buffer_length(), ///< This is the length of the buffer. This must match with the length of all payloads.
+		&padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify BKID.
+
+	{
+		wai_variable_data_c * const BKID_payload = parser.get_tlv_pointer(wai_payload_type_bkid);
+		if (BKID_payload == 0
+			|| BKID_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_BKID.compare(
+			BKID_payload->get_data(BKID_payload->get_data_length()),
+			BKID_payload->get_data_length()) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local m_BKID"),
+				 m_BKID.get_data(),
+				 m_BKID.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received BKID"),
+				 BKID_payload->get_data(BKID_payload->get_data_length()),
+				 BKID_payload->get_data_length()));
+
+#if defined(WAPI_SKIP_BKID_TEST)
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WARNING: WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_unicast_key_negotiation_request(): Skips BKID test.\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+#else
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+#endif //#if !defined(WAPI_SKIP_BKID_TEST)
+
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify USK rekeying flag.
+
+	{
+		wai_variable_data_c * const flag_payload = parser.get_tlv_pointer(wai_payload_type_flag);
+		if (flag_payload == 0
+			|| flag_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const flag = flag_payload->get_data(sizeof(*flag));
+		if (flag == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			if (((*flag) & wai_data_flag_mask_USK_Rekeying) == 0)
+			{
+				m_wapi_negotiation_state = wapi_negotiation_state_initial_negotiation;
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("WARNING: WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_unicast_key_negotiation_request(): change to %s.\n"),
+					 this,
+					 (m_is_client == true ? "client": "server"),
+					 wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+			}
+		}
+		else
+		{
+			if (((*flag) & wai_data_flag_mask_USK_Rekeying) != 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify USKID.
+
+	{
+		wai_variable_data_c * const USKID_payload = parser.get_tlv_pointer(wai_payload_type_uskid);
+		if (USKID_payload == 0
+			|| USKID_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const USKID_pointer = USKID_payload->get_data(sizeof(*USKID_pointer));
+		if (USKID_pointer == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		u8_t USKID = (*USKID_pointer) & wai_data_uskid_mask_uskid;
+
+		if (USKID >= WAPI_USKSA_COUNT
+			|| m_USKSA[USKID] == 0
+			|| m_USKSA[USKID]->get_is_valid_data() == true)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		m_USKID = USKID;
+
+		m_USKSA[USKID]->set_USKID(m_USKID);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Save AE challenge.
+
+	{
+		wai_variable_data_c * const ae_challenge = parser.get_tlv_pointer(wai_payload_type_nonce);
+		if (ae_challenge == 0
+			|| ae_challenge->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			// Verify the AE challenge.
+			if (m_am_tools->memcmp(m_next_unicast_challenge.get_data(WAPI_CHALLENGE_LENGTH), ae_challenge->get_data(WAPI_CHALLENGE_LENGTH), WAPI_CHALLENGE_LENGTH) != 0)
+			{
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("ERROR: local m_next_unicast_challenge"),
+					 m_next_unicast_challenge.get_data(),
+					 m_next_unicast_challenge.get_data_length()));
+
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("ERROR: received AE Challenge"),
+					 ae_challenge->get_data(WAPI_CHALLENGE_LENGTH),
+					 WAPI_CHALLENGE_LENGTH));
+
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+		}
+
+		status = m_ae_unicast_challenge.set_copy_of_buffer(ae_challenge->get_data(WAPI_CHALLENGE_LENGTH), WAPI_CHALLENGE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create ASUE challenge.
+
+	{
+		crypto_random_c rand(m_am_tools);
+		if (rand.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = rand.get_rand_bytes(
+			&m_asue_unicast_challenge,
+			WAPI_CHALLENGE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create unicast session key.
+
+	status = create_unicast_key(
+		&m_BK,
+		receive_network_id,
+		&m_ae_unicast_challenge,
+		&m_asue_unicast_challenge,
+		&m_unicast_encryption_key_UEK,
+		&m_unicast_integrity_check_key_UCK,
+		&m_message_authentication_key_MAK,
+		&m_key_encryption_key_KEK,
+		&m_next_unicast_challenge);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create the Unicast Key Negotiation Response message.
+
+	wai_message_payloads_c * const payloads = new wai_message_payloads_c(m_am_tools, m_is_client);
+	// Automatic variable deletes payloads when control returns from this function.
+	eap_automatic_variable_c<wai_message_payloads_c> automatic_payloads(m_am_tools, payloads);
+
+	if (payloads == 0
+		|| payloads->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = payloads->initialise_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = payloads->get_wai_protocol_packet_header_writable()->set_subtype(wai_protocol_subtype_unicast_key_negotiation_response);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds FLAG to data field.
+
+	{
+		wai_variable_data_c data_flag(m_am_tools);
+		if (data_flag.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u8_t flag(wai_data_flag_mask_none);
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			flag = wai_data_flag_mask_USK_Rekeying;
+		}
+
+		status = data_flag.create(
+			wai_payload_type_flag,
+			&flag,
+			sizeof(flag));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_flag);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds BKID to data field.
+
+	{
+		wai_variable_data_c data_BKID(m_am_tools);
+		if (data_BKID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_BKID.create(
+			wai_payload_type_bkid,
+			&m_BKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_BKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds USKID to data field.
+
+	{
+		wai_variable_data_c data_USKID(m_am_tools);
+		if (data_USKID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_USKID.create(
+			wai_payload_type_uskid,
+			&m_USKID,
+			sizeof(m_USKID));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_USKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds ADDID to data field.
+
+	{
+		wai_variable_data_c data_ADDID(m_am_tools);
+		if (data_ADDID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		const eap_variable_data_c * MAC_1 = receive_network_id->get_destination_id();
+		const eap_variable_data_c * MAC_2 = receive_network_id->get_source_id();
+
+		if (m_is_client == true)
+		{
+			MAC_1 = receive_network_id->get_source_id();
+			MAC_2 = receive_network_id->get_destination_id();
+		}
+
+		status = data_ADDID.create(
+			wai_payload_type_addid,
+			MAC_1);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data_ADDID.add_data(
+			wai_payload_type_addid,
+			MAC_2);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_ADDID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds ASUE Challenge to data field.
+
+	{
+		wai_variable_data_c data_ASUE_challenge(m_am_tools);
+		if (data_ASUE_challenge.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_ASUE_challenge.create(
+			wai_payload_type_nonce,
+			&m_asue_unicast_challenge);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_ASUE_challenge);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds AE Challenge to data field.
+
+	{
+		wai_variable_data_c data_AE_challenge(m_am_tools);
+		if (data_AE_challenge.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_AE_challenge.create(
+			wai_payload_type_nonce,
+			&m_ae_unicast_challenge);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_AE_challenge);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds WIE ASUE to data field.
+
+	{
+		wai_variable_data_c data_WIE_ASUE(m_am_tools);
+		if (data_WIE_ASUE.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		EAP_ASSERT_TOOLS(m_am_tools, m_wapi_ie_asue.get_is_valid() == true && m_wapi_ie_asue.get_data_length() > 0ul);
+
+		status = data_WIE_ASUE.create(
+			wai_payload_type_wie,
+			&m_wapi_ie_asue);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_WIE_ASUE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds MAC to data field.
+
+	{
+		wai_variable_data_c data_MAC(m_am_tools);
+		if (data_MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_variable_data_c MAC(m_am_tools);
+		if (MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_MAC(payloads, &MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = MAC.set_data_length(WAPI_MESSAGE_AUTHENTICATION_CODE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data_MAC.create(
+			wai_payload_type_message_authentication_code,
+			&MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create and send message.
+
+	{
+		wai_message_c new_wai_message_data(m_am_tools, m_is_client);
+		if (new_wai_message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->create_wai_tlv_message(&new_wai_message_data, false);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		//cancel_retransmission();
+
+		status = packet_send(
+			&new_wai_message_data,
+			payloads->get_wai_protocol_packet_header_writable()->get_subtype());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	set_wapi_state(wapi_core_state_wait_unicast_key_negotiation_confirmation_message);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+eap_status_e wapi_core_c::handle_unicast_key_negotiation_response(
+	const eap_am_network_id_c * const receive_network_id,
+	const wai_protocol_packet_header_c * const wai)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_unicast_key_negotiation_response(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::handle_unicast_key_negotiation_response()");
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (m_wapi_state != wapi_core_state_wait_unicast_key_negotiation_response_message
+		&& m_wapi_state != wapi_core_state_wait_multicast_announcement_response_message)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_unicast_key_negotiation_response(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_wait_unicast_key_negotiation_response_message),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	if (m_authentication_type != eapol_key_authentication_type_WAI_PSK
+		&& m_authentication_type != eapol_key_authentication_type_WAI_certificate)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (receive_network_id == 0
+		|| receive_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (wai == 0
+		|| wai->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	status = wai->check_header();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (wai->get_packet_sequence_number() != m_packet_sequence_number)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_unicast_key_negotiation_response(): sequence number %d != required sequence number %d.\n"),
+			(m_is_client == true) ? "client": "server",
+			wai->get_packet_sequence_number(),
+			m_packet_sequence_number));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wai_message_payloads_c parser(
+		m_am_tools,
+		m_is_client);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t padding_length(0ul);
+
+	status = parser.parse_wai_payloads(
+		wai->get_header_buffer(wai->get_header_buffer_length()), ///< This is the start of the message buffer.
+		wai->get_header_buffer_length(), ///< This is the length of the buffer. This must match with the length of all payloads.
+		&padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify BKID.
+
+	{
+		wai_variable_data_c * const BKID_payload = parser.get_tlv_pointer(wai_payload_type_bkid);
+		if (BKID_payload == 0
+			|| BKID_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_BKID.compare(
+			BKID_payload->get_data(BKID_payload->get_data_length()),
+			BKID_payload->get_data_length()) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local m_BKID"),
+				 m_BKID.get_data(),
+				 m_BKID.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received BKID"),
+				 BKID_payload->get_data(BKID_payload->get_data_length()),
+				 BKID_payload->get_data_length()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify USK rekeying flag.
+
+	{
+		wai_variable_data_c * const flag_payload = parser.get_tlv_pointer(wai_payload_type_flag);
+		if (flag_payload == 0
+			|| flag_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const flag = flag_payload->get_data(sizeof(*flag));
+		if (flag == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			if (((*flag) & wai_data_flag_mask_USK_Rekeying) == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+		}
+		else
+		{
+			if (((*flag) & wai_data_flag_mask_USK_Rekeying) != 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify USKID.
+
+	{
+		wai_variable_data_c * const USKID_payload = parser.get_tlv_pointer(wai_payload_type_uskid);
+		if (USKID_payload == 0
+			|| USKID_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const USKID_pointer = USKID_payload->get_data(sizeof(*USKID_pointer));
+		if (USKID_pointer == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		u8_t USKID = (*USKID_pointer) & wai_data_uskid_mask_uskid;
+
+		if (USKID >= WAPI_USKSA_COUNT
+			|| m_USKSA[USKID] == 0
+			|| m_USKSA[USKID]->get_is_valid_data() == true)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		m_USKID = USKID;
+
+		m_USKSA[USKID]->set_USKID(m_USKID);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Save ASUE challenge.
+
+	{
+		wai_variable_data_c * const asue_challenge = parser.get_tlv_pointer(wai_payload_type_nonce);
+		if (asue_challenge == 0
+			|| asue_challenge->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		status = m_asue_unicast_challenge.set_copy_of_buffer(asue_challenge->get_data(WAPI_CHALLENGE_LENGTH), WAPI_CHALLENGE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Verify AE challenge.
+
+		wai_variable_data_c * const ae_challenge = asue_challenge->get_next_payload_with_same_tlv_type();
+		if (ae_challenge == 0
+			|| ae_challenge->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_ae_unicast_challenge.compare(
+			ae_challenge->get_data(ae_challenge->get_data_length()),
+			ae_challenge->get_data_length()) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify WIE_ASUE.
+
+	if (m_wapi_negotiation_state == wapi_negotiation_state_initial_negotiation)
+	{
+		wai_variable_data_c * const wie_asue = parser.get_tlv_pointer(wai_payload_type_wie);
+		if (wie_asue == 0
+			|| wie_asue->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_wapi_ie_asue.compare(
+			wie_asue->get_data(wie_asue->get_data_length()),
+			wie_asue->get_data_length()) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create unicast session key.
+
+	status = create_unicast_key(
+		&m_BK,
+		receive_network_id,
+		&m_ae_unicast_challenge,
+		&m_asue_unicast_challenge,
+		&m_unicast_encryption_key_UEK,
+		&m_unicast_integrity_check_key_UCK,
+		&m_message_authentication_key_MAK,
+		&m_key_encryption_key_KEK,
+		&m_next_unicast_challenge);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify MAC.
+
+	{
+		wai_variable_data_c * const received_MAC = parser.get_tlv_pointer(wai_payload_type_message_authentication_code);
+		if (received_MAC == 0
+			|| received_MAC->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		eap_variable_data_c local_MAC(m_am_tools);
+		if (local_MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_MAC(&parser, &local_MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = local_MAC.set_data_length(WAPI_MESSAGE_AUTHENTICATION_CODE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		if (local_MAC.compare(
+			received_MAC->get_data(received_MAC->get_data_length()),
+			received_MAC->get_data_length()) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("WAI: %s: wapi_core_c::handle_unicast_key_negotiation_response(): MAC OK.\n"),
+				(m_is_client == true) ? "client": "server"));
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create the Unicast Key Negotiation Confirmation message.
+
+	wai_message_payloads_c * const payloads = new wai_message_payloads_c(m_am_tools, m_is_client);
+	eap_automatic_variable_c<wai_message_payloads_c> automatic_payloads(m_am_tools, payloads);
+
+	if (payloads == 0
+		|| payloads->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = payloads->initialise_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = payloads->get_wai_protocol_packet_header_writable()->set_subtype(wai_protocol_subtype_unicast_key_negotiation_confirmation);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds FLAG to data field.
+
+	{
+		wai_variable_data_c data_flag(m_am_tools);
+		if (data_flag.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u8_t flag(wai_data_flag_mask_none);
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			flag = wai_data_flag_mask_USK_Rekeying;
+		}
+
+		status = data_flag.create(
+			wai_payload_type_flag,
+			&flag,
+			sizeof(flag));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_flag);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds BKID to data field.
+
+	{
+		wai_variable_data_c data_BKID(m_am_tools);
+		if (data_BKID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_BKID.create(
+			wai_payload_type_bkid,
+			&m_BKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_BKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds USKID to data field.
+
+	{
+		wai_variable_data_c data_USKID(m_am_tools);
+		if (data_USKID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_USKID.create(
+			wai_payload_type_uskid,
+			&m_USKID,
+			sizeof(m_USKID));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_USKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds ADDID to data field.
+
+	{
+		wai_variable_data_c data_ADDID(m_am_tools);
+		if (data_ADDID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		const eap_variable_data_c * MAC_1 = receive_network_id->get_source_id();
+		const eap_variable_data_c * MAC_2 = receive_network_id->get_destination_id();
+
+		if (m_is_client == true)
+		{
+			MAC_1 = receive_network_id->get_destination_id();
+			MAC_2 = receive_network_id->get_source_id();
+		}
+
+		status = data_ADDID.create(
+			wai_payload_type_addid,
+			MAC_1);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data_ADDID.add_data(
+			wai_payload_type_addid,
+			MAC_2);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_ADDID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds ASUE Challenge to data field.
+
+	{
+		wai_variable_data_c data_ASUE_challenge(m_am_tools);
+		if (data_ASUE_challenge.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_ASUE_challenge.create(
+			wai_payload_type_nonce,
+			&m_asue_unicast_challenge);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_ASUE_challenge);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds WIE AE to data field.
+
+	{
+		wai_variable_data_c data_WIE_AE(m_am_tools);
+		if (data_WIE_AE.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_WIE_AE.create(
+			wai_payload_type_wie,
+			&m_wapi_ie_ae);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_WIE_AE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds MAC to data field.
+
+	{
+		wai_variable_data_c data_MAC(m_am_tools);
+		if (data_MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_variable_data_c MAC(m_am_tools);
+		if (MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_MAC(payloads, &MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = MAC.set_data_length(WAPI_MESSAGE_AUTHENTICATION_CODE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data_MAC.create(
+			wai_payload_type_message_authentication_code,
+			&MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create and send message.
+
+	wai_message_c new_wai_message_data(m_am_tools, m_is_client);
+	if (new_wai_message_data.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = payloads->create_wai_tlv_message(&new_wai_message_data, false);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	//cancel_retransmission();
+
+	status = packet_send(
+		&new_wai_message_data,
+		payloads->get_wai_protocol_packet_header_writable()->get_subtype());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Install unicast session key.
+
+	{
+		eap_variable_data_c unicast_session_key(m_am_tools);
+		if (unicast_session_key.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = unicast_session_key.set_copy_of_buffer(&m_unicast_encryption_key_UEK);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = unicast_session_key.add_data(&m_unicast_integrity_check_key_UCK);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = packet_data_session_key(
+			&unicast_session_key,
+			eapol_key_type_unicast,
+			m_USKID,
+			false,
+			m_packet_data_number.get_data(),
+			m_packet_data_number.get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	set_wapi_state(wapi_core_state_start_multicast_key_announcement);
+
+	status = start_multicast_key_announcement();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::handle_unicast_key_negotiation_confirmation(
+	const eap_am_network_id_c * const receive_network_id,
+	const wai_protocol_packet_header_c * const wai)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_unicast_key_negotiation_confirmation(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::handle_unicast_key_negotiation_confirmation()");
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (m_wapi_state != wapi_core_state_wait_unicast_key_negotiation_confirmation_message
+		&& m_wapi_state != wapi_core_state_wait_multicast_announcement_message)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_unicast_key_negotiation_confirmation(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_wait_unicast_key_negotiation_confirmation_message),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	if (m_authentication_type != eapol_key_authentication_type_WAI_PSK
+		&& m_authentication_type != eapol_key_authentication_type_WAI_certificate)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (receive_network_id == 0
+		|| receive_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (wai == 0
+		|| wai->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	status = wai->check_header();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (wai->get_packet_sequence_number() != (m_packet_sequence_number + 1u))
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_unicast_key_negotiation_confirmation(): sequence number %d != required sequence number %d.\n"),
+			(m_is_client == true) ? "client": "server",
+			wai->get_packet_sequence_number(),
+			(m_packet_sequence_number + 1u)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	++m_packet_sequence_number;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wai_message_payloads_c parser(
+		m_am_tools,
+		m_is_client);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t padding_length(0ul);
+
+	status = parser.parse_wai_payloads(
+		wai->get_header_buffer(wai->get_header_buffer_length()), ///< This is the start of the message buffer.
+		wai->get_header_buffer_length(), ///< This is the length of the buffer. This must match with the length of all payloads.
+		&padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify BKID.
+
+	{
+		wai_variable_data_c * const BKID_payload = parser.get_tlv_pointer(wai_payload_type_bkid);
+		if (BKID_payload == 0
+			|| BKID_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_BKID.compare(
+			BKID_payload->get_data(BKID_payload->get_data_length()),
+			BKID_payload->get_data_length()) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local m_BKID"),
+				 m_BKID.get_data(),
+				 m_BKID.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received BKID"),
+				 BKID_payload->get_data(BKID_payload->get_data_length()),
+				 BKID_payload->get_data_length()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify MAC.
+
+	{
+		wai_variable_data_c * const received_MAC = parser.get_tlv_pointer(wai_payload_type_message_authentication_code);
+		if (received_MAC == 0
+			|| received_MAC->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		eap_variable_data_c local_MAC(m_am_tools);
+		if (local_MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_MAC(&parser, &local_MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = local_MAC.set_data_length(WAPI_MESSAGE_AUTHENTICATION_CODE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		if (local_MAC.compare(
+			received_MAC->get_data(received_MAC->get_data_length()),
+			received_MAC->get_data_length()) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("WAI: %s: wapi_core_c::handle_unicast_key_negotiation_confirmation(): MAC OK.\n"),
+				(m_is_client == true) ? "client": "server"));
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify USK rekeying flag.
+
+	{
+		wai_variable_data_c * const flag_payload = parser.get_tlv_pointer(wai_payload_type_flag);
+		if (flag_payload == 0
+			|| flag_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const flag = flag_payload->get_data(sizeof(*flag));
+		if (flag == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+		{
+			if (((*flag) & wai_data_flag_mask_USK_Rekeying) == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+		}
+		else
+		{
+			if (((*flag) & wai_data_flag_mask_USK_Rekeying) != 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify USKID.
+
+	{
+		wai_variable_data_c * const USKID_payload = parser.get_tlv_pointer(wai_payload_type_uskid);
+		if (USKID_payload == 0
+			|| USKID_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const USKID_pointer = USKID_payload->get_data(sizeof(*USKID_pointer));
+		if (USKID_pointer == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		u8_t USKID = (*USKID_pointer) & wai_data_uskid_mask_uskid;
+
+		if (USKID >= WAPI_USKSA_COUNT
+			|| m_USKSA[USKID] == 0
+			|| m_USKSA[USKID]->get_is_valid_data() == true)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		m_USKID = USKID;
+
+		m_USKSA[USKID]->set_USKID(m_USKID);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify ASUE challenge.
+
+	{
+
+		wai_variable_data_c * const asue_challenge = parser.get_tlv_pointer(wai_payload_type_nonce);
+		if (asue_challenge == 0
+			|| asue_challenge->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_asue_unicast_challenge.compare(
+			asue_challenge->get_data(asue_challenge->get_data_length()),
+			asue_challenge->get_data_length()) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify WIE_AE.
+
+	{
+		wai_variable_data_c * const wie_ae = parser.get_tlv_pointer(wai_payload_type_wie);
+		if (wie_ae == 0
+			|| wie_ae->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_wapi_ie_ae.compare(
+			wie_ae->get_data(wie_ae->get_data_length()),
+			wie_ae->get_data_length()) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Install unicast session key.
+
+	{
+		eap_variable_data_c unicast_session_key(m_am_tools);
+		if (unicast_session_key.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = unicast_session_key.set_copy_of_buffer(&m_unicast_encryption_key_UEK);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = unicast_session_key.add_data(&m_unicast_integrity_check_key_UCK);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = packet_data_session_key(
+			&unicast_session_key,
+			eapol_key_type_unicast,
+			m_USKID,
+			false,
+			m_packet_data_number.get_data(),
+			m_packet_data_number.get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (m_wapi_negotiation_state == wapi_negotiation_state_initial_negotiation)
+	{
+	    set_wapi_state(wapi_core_state_wait_multicast_announcement_message);
+	}
+	else if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+	{
+        // Here we swap the addresses.
+        eap_am_network_id_c send_network_id(m_am_tools,
+            m_receive_network_id.get_destination_id(),
+            m_receive_network_id.get_source_id(),
+            m_receive_network_id.get_type());
+
+        if (send_network_id.get_is_valid_data() == false)
+        {
+            EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+            return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+        }
+
+        eap_state_notification_c * notification = new eap_state_notification_c(
+            m_am_tools,
+            &send_network_id,
+            m_is_client,
+            eap_state_notification_generic,
+            eap_protocol_layer_wai,
+            eapol_key_handshake_type_wai_handshake,
+            eapol_key_state_wapi_authentication_running,
+            eapol_key_state_wapi_authentication_finished_successfull,
+            0ul,
+            false);
+        if (notification == 0)
+        {
+            EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+            return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+        }
+
+        state_notification(notification);
+
+        delete notification;
+
+		set_wapi_state(wapi_core_state_authentication_ok);
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_unicast_key_negotiation_confirmation(): negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+        EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+        return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::handle_multicast_key_announcement(
+	const eap_am_network_id_c * const receive_network_id,
+	const wai_protocol_packet_header_c * const wai)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_multicast_key_announcement(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::handle_multicast_key_announcement()");
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (m_wapi_state != wapi_core_state_wait_multicast_announcement_message
+		&& m_wapi_state != wapi_core_state_authentication_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_multicast_key_announcement(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_wait_multicast_announcement_message),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	if (m_authentication_type != eapol_key_authentication_type_WAI_PSK
+		&& m_authentication_type != eapol_key_authentication_type_WAI_certificate)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (receive_network_id == 0
+		|| receive_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (wai == 0
+		|| wai->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	status = wai->check_header();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (wai->get_packet_sequence_number() != (m_packet_sequence_number + 1u))
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_multicast_key_announcement(): sequence number %d != required sequence number %d.\n"),
+			(m_is_client == true) ? "client": "server",
+			wai->get_packet_sequence_number(),
+			(m_packet_sequence_number + 1u)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	++m_packet_sequence_number;
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wai_message_payloads_c parser(
+		m_am_tools,
+		m_is_client);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t padding_length(0ul);
+
+	status = parser.parse_wai_payloads(
+		wai->get_header_buffer(wai->get_header_buffer_length()), ///< This is the start of the message buffer.
+		wai->get_header_buffer_length(), ///< This is the length of the buffer. This must match with the length of all payloads.
+		&padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify MAC.
+
+	{
+		wai_variable_data_c * const received_MAC = parser.get_tlv_pointer(wai_payload_type_message_authentication_code);
+		if (received_MAC == 0
+			|| received_MAC->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		eap_variable_data_c local_MAC(m_am_tools);
+		if (local_MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_MAC(&parser, &local_MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = local_MAC.set_data_length(WAPI_MESSAGE_AUTHENTICATION_CODE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		if (local_MAC.compare(
+			received_MAC->get_data(received_MAC->get_data_length()),
+			received_MAC->get_data_length()) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("WAI: %s: wapi_core_c::handle_multicast_key_announcement(): MAC OK.\n"),
+				(m_is_client == true) ? "client": "server"));
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify USK rekeying flag.
+
+	{
+		wai_variable_data_c * const flag_payload = parser.get_tlv_pointer(wai_payload_type_flag);
+		if (flag_payload == 0
+			|| flag_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const flag = flag_payload->get_data(sizeof(*flag));
+		if (flag == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (((*flag) & wai_data_flag_mask_USK_Rekeying) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify MSKID.
+
+	{
+		wai_variable_data_c * const MSKID_payload = parser.get_tlv_pointer(wai_payload_type_mskid_stakeyid);
+		if (MSKID_payload == 0
+			|| MSKID_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const MSKID_pointer = MSKID_payload->get_data(sizeof(*MSKID_pointer));
+		if (MSKID_pointer == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		u8_t MSKID = (*MSKID_pointer) & wai_data_uskid_mask_mskid;
+
+		if (MSKID >= WAPI_MSKSA_COUNT
+			|| m_MSKSA[MSKID] == 0
+			|| m_MSKSA[MSKID]->get_is_valid_data() == true)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		m_MSKID = MSKID;
+
+		m_MSKSA[MSKID]->set_USKID(m_MSKID);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify USKID.
+
+	{
+		wai_variable_data_c * const USKID_payload = parser.get_tlv_pointer(wai_payload_type_uskid);
+		if (USKID_payload == 0
+			|| USKID_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const USKID_pointer = USKID_payload->get_data(sizeof(*USKID_pointer));
+		if (USKID_pointer == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		u8_t USKID = (*USKID_pointer) & wai_data_uskid_mask_uskid;
+
+		if (USKID >= WAPI_USKSA_COUNT
+			|| m_USKSA[USKID] == 0
+			|| m_USKSA[USKID]->get_is_valid_data() == true)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		m_USKID = USKID;
+
+		m_USKSA[USKID]->set_USKID(m_USKID);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Read Data Packet Number.
+
+	{
+
+		wai_variable_data_c * const packet_data_number = parser.get_tlv_pointer(wai_payload_type_data_sequence_number);
+		if (packet_data_number == 0
+			|| packet_data_number->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		status = m_packet_data_number.set_copy_of_buffer(
+			packet_data_number->get_data(packet_data_number->get_data_length()),
+			packet_data_number->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Read Key Announcement.
+
+	{
+
+		wai_variable_data_c * const key_announcement = parser.get_tlv_pointer(wai_payload_type_key_announcement_identifier);
+		if (key_announcement == 0
+			|| key_announcement->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		status = m_key_announcement.set_copy_of_buffer(
+			key_announcement->get_data(key_announcement->get_data_length()),
+			key_announcement->get_data_length());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Read and decrypt Key Data.
+
+		{
+
+			wai_variable_data_c * const key_data = parser.get_tlv_pointer(wai_payload_type_key_data);
+			if (key_data == 0
+				|| key_data->get_is_valid_data() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			eap_variable_data_c notification_master_key(m_am_tools);
+			if (notification_master_key.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = decrypt_multicast_key_data(key_data, &m_key_announcement, &notification_master_key);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = create_multicast_key(&notification_master_key, &m_multicast_key);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create the Multicast Key announcement response message.
+
+	wai_message_payloads_c * const payloads = new wai_message_payloads_c(m_am_tools, m_is_client);
+	eap_automatic_variable_c<wai_message_payloads_c> automatic_payloads(m_am_tools, payloads);
+
+	if (payloads == 0
+		|| payloads->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = payloads->initialise_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = payloads->get_wai_protocol_packet_header_writable()->set_subtype(wai_protocol_subtype_multicast_key_announcement_response);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds FLAG to data field.
+
+	{
+		wai_variable_data_c data_flag(m_am_tools);
+		if (data_flag.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u8_t flag(wai_data_flag_mask_none);
+
+		status = data_flag.create(
+			wai_payload_type_flag,
+			&flag,
+			sizeof(flag));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_flag);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds MSKID to data field.
+
+	{
+		wai_variable_data_c data_flag(m_am_tools);
+		if (data_flag.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_flag.create(
+			wai_payload_type_mskid_stakeyid,
+			&m_MSKID,
+			sizeof(m_MSKID));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_flag);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds USKID to data field.
+
+	{
+		wai_variable_data_c data_USKID(m_am_tools);
+		if (data_USKID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = data_USKID.create(
+			wai_payload_type_uskid,
+			&m_USKID,
+			sizeof(m_USKID));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_USKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds ADDID to data field.
+
+	{
+		wai_variable_data_c data_ADDID(m_am_tools);
+		if (data_ADDID.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		const eap_variable_data_c * MAC_1 = receive_network_id->get_destination_id();
+		const eap_variable_data_c * MAC_2 = receive_network_id->get_source_id();
+
+		if (m_is_client == true)
+		{
+			MAC_1 = receive_network_id->get_source_id();
+			MAC_2 = receive_network_id->get_destination_id();
+		}
+
+		status = data_ADDID.create(
+			wai_payload_type_addid,
+			MAC_1);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data_ADDID.add_data(
+			wai_payload_type_addid,
+			MAC_2);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_ADDID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds Key Announcement to data field.
+
+	{
+		wai_variable_data_c key_announcement(m_am_tools);
+		if (key_announcement.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = key_announcement.create(
+			wai_payload_type_data_sequence_number,
+			&m_key_announcement);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&key_announcement);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Adds MAC to data field.
+
+	{
+		wai_variable_data_c data_MAC(m_am_tools);
+		if (data_MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_variable_data_c MAC(m_am_tools);
+		if (MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_MAC(payloads, &MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = MAC.set_data_length(WAPI_MESSAGE_AUTHENTICATION_CODE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = data_MAC.create(
+			wai_payload_type_message_authentication_code,
+			&MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->add_tlv(&data_MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Create and send message.
+
+	wai_message_c new_wai_message_data(m_am_tools, m_is_client);
+	if (new_wai_message_data.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = payloads->create_wai_tlv_message(&new_wai_message_data, false);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	//cancel_retransmission();
+
+	status = packet_send(
+		&new_wai_message_data,
+		payloads->get_wai_protocol_packet_header_writable()->get_subtype());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Install multicast session key.
+
+	status = packet_data_session_key(
+		&m_multicast_key,
+		eapol_key_type_broadcast,
+		m_MSKID,
+		false,
+		m_packet_data_number.get_data(),
+		m_packet_data_number.get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+	    m_wapi_negotiation_state = wapi_negotiation_state_rekeying;
+
+		// Here we swap the addresses.
+		eap_am_network_id_c send_network_id(m_am_tools,
+			m_receive_network_id.get_destination_id(),
+			m_receive_network_id.get_source_id(),
+			m_receive_network_id.get_type());
+
+		if (send_network_id.get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		// This notification to eapol_core_c object.
+		// WAPI authentication finished successfully.
+		eap_state_notification_c * notification = new eap_state_notification_c(
+			m_am_tools,
+			&send_network_id,
+			m_is_client,
+			eap_state_notification_generic,
+			eap_protocol_layer_wai,
+			eapol_key_handshake_type_wai_handshake,
+			eapol_key_state_wapi_authentication_running,
+			eapol_key_state_wapi_authentication_finished_successfull,
+			0ul,
+			false);
+		if (notification == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		state_notification(notification);
+
+		delete notification;
+	}
+
+	cancel_session_timeout();
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	set_wapi_state(wapi_core_state_authentication_ok);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+eap_status_e wapi_core_c::handle_multicast_key_announcement_response(
+	const eap_am_network_id_c * const receive_network_id,
+	const wai_protocol_packet_header_c * const wai)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::handle_multicast_key_announcement_response(): state=%s, negotiation state = %s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+		 wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::handle_multicast_key_announcement_response()");
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (m_wapi_state != wapi_core_state_wait_multicast_announcement_response_message
+		&& m_wapi_state != wapi_core_state_authentication_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::handle_multicast_key_announcement_response(): Verify state %s != %s, negotiation state = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_wait_multicast_announcement_response_message),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message);
+	}
+
+	if (m_authentication_type != eapol_key_authentication_type_WAI_PSK
+		&& m_authentication_type != eapol_key_authentication_type_WAI_certificate)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type);
+	}
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (receive_network_id == 0
+		|| receive_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (wai == 0
+		|| wai->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	status = wai->check_header();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	wai_message_payloads_c parser(
+		m_am_tools,
+		m_is_client);
+	if (parser.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	u32_t padding_length(0ul);
+
+	status = parser.parse_wai_payloads(
+		wai->get_header_buffer(wai->get_header_buffer_length()), ///< This is the start of the message buffer.
+		wai->get_header_buffer_length(), ///< This is the length of the buffer. This must match with the length of all payloads.
+		&padding_length ///< Length of possible padding is set to this variable.
+		);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify MAC.
+
+	{
+		wai_variable_data_c * const received_MAC = parser.get_tlv_pointer(wai_payload_type_message_authentication_code);
+		if (received_MAC == 0
+			|| received_MAC->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		eap_variable_data_c local_MAC(m_am_tools);
+		if (local_MAC.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = create_MAC(&parser, &local_MAC);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = local_MAC.set_data_length(WAPI_MESSAGE_AUTHENTICATION_CODE_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		if (local_MAC.compare(
+			received_MAC->get_data(received_MAC->get_data_length()),
+			received_MAC->get_data_length()) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("WAI: %s: wapi_core_c::handle_multicast_key_announcement_response(): MAC OK.\n"),
+				(m_is_client == true) ? "client": "server"));
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify USK rekeying flag.
+
+	{
+		wai_variable_data_c * const flag_payload = parser.get_tlv_pointer(wai_payload_type_flag);
+		if (flag_payload == 0
+			|| flag_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const flag = flag_payload->get_data(sizeof(*flag));
+		if (flag == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (((*flag) & wai_data_flag_mask_USK_Rekeying) != 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify MSKID.
+
+	{
+		wai_variable_data_c * const MSKID_payload = parser.get_tlv_pointer(wai_payload_type_mskid_stakeyid);
+		if (MSKID_payload == 0
+			|| MSKID_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const MSKID_pointer = MSKID_payload->get_data(sizeof(*MSKID_pointer));
+		if (MSKID_pointer == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		u8_t MSKID = (*MSKID_pointer) & wai_data_uskid_mask_mskid;
+
+		if (MSKID != m_MSKID
+			|| m_MSKSA[MSKID] == 0
+			|| m_MSKSA[MSKID]->get_is_valid_data() == true)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify USKID.
+
+	{
+		wai_variable_data_c * const USKID_payload = parser.get_tlv_pointer(wai_payload_type_uskid);
+		if (USKID_payload == 0
+			|| USKID_payload->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		const u8_t * const USKID_pointer = USKID_payload->get_data(sizeof(*USKID_pointer));
+		if (USKID_pointer == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		u8_t USKID = (*USKID_pointer) & wai_data_uskid_mask_uskid;
+
+		if (USKID >= WAPI_USKSA_COUNT
+			|| m_USKSA[USKID] == 0
+			|| m_USKSA[USKID]->get_is_valid_data() == true)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Verify Key Announcement.
+
+	{
+
+		wai_variable_data_c * const key_announcement = parser.get_tlv_pointer(wai_payload_type_key_announcement_identifier);
+		if (key_announcement == 0
+			|| key_announcement->get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+
+		if (m_key_announcement.compare(
+			key_announcement->get_data(key_announcement->get_data_length()),
+			key_announcement->get_data_length()) != 0)
+		{
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: local m_key_announcement"),
+				 m_key_announcement.get_data(),
+				 m_key_announcement.get_data_length()));
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: received key_announcement"),
+				key_announcement->get_data(key_announcement->get_data_length()),
+				key_announcement->get_data_length()));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Install multicast session key.
+
+	status = packet_data_session_key(
+		&m_multicast_key,
+		eapol_key_type_broadcast,
+		m_MSKID,
+		false,
+		m_packet_data_number.get_data(),
+		m_packet_data_number.get_data_length());
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+	    m_wapi_negotiation_state = wapi_negotiation_state_rekeying;
+
+		// Here we swap the addresses.
+		eap_am_network_id_c send_network_id(m_am_tools,
+			m_receive_network_id.get_destination_id(),
+			m_receive_network_id.get_source_id(),
+			m_receive_network_id.get_type());
+
+		if (send_network_id.get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		// This notification to eapol_core_c object.
+		// WAPI authentication finished successfully.
+		eap_state_notification_c * notification = new eap_state_notification_c(
+			m_am_tools,
+			&send_network_id,
+			m_is_client,
+			eap_state_notification_generic,
+			eap_protocol_layer_wai,
+			eapol_key_handshake_type_wai_handshake,
+			eapol_key_state_wapi_authentication_running,
+			eapol_key_state_wapi_authentication_finished_successfull,
+			0ul,
+			false);
+		if (notification == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		state_notification(notification);
+
+		delete notification;
+	}
+
+	cancel_session_timeout();
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	set_wapi_state(wapi_core_state_authentication_ok);
+
+	//cancel_retransmission();
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::packet_process(
+	const eap_am_network_id_c * const receive_network_id,
+	eap_general_header_base_c * const packet_data,
+	const u32_t packet_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("WAI: %s: wapi_core_c::packet_process(): state = %s, negotiation state = %s.\n"),
+		(m_is_client == true) ? "client": "server",
+		wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+		wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	eap_status_e status(eap_status_process_general_error);
+
+
+	// This automatic variable stores the current packet sequence number.
+	// If the received packet is illegal the current packet sequence number is restored.
+	eap_automatic_simple_value_c<u16_t> automatic_packet_sequence_number(
+		m_am_tools,
+		&m_packet_sequence_number,
+		m_packet_sequence_number);
+
+	// This automatic variable stores the current WAPI-state.
+	// If the received packet is illegal the current WAPI-state is restored.
+	eap_automatic_simple_value_c<wapi_core_state_e> automatic_wapi_state(
+		m_am_tools,
+		&m_wapi_state,
+		m_wapi_state);
+
+
+	if (m_wapi_state == wapi_core_state_none)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: WAI: %s: wapi_core_c::packet_process(): Verify state %s == %s, negotiation state = %s, drop packet.\n"),
+			(m_is_client == true) ? "client": "server",
+			wapi_strings_c::get_wapi_core_state_string(m_wapi_state),
+			wapi_strings_c::get_wapi_core_state_string(wapi_core_state_none),
+			wapi_strings_c::get_wapi_negotiation_state_string(m_wapi_negotiation_state)));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
+	}
+
+	if (packet_data == 0
+		|| packet_data->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	if (receive_network_id == 0
+		|| receive_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (packet_length < eap_header_base_c::get_header_length())
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
+	}
+
+	wai_protocol_packet_header_c wai(
+		m_am_tools,
+		packet_data->get_header_buffer(packet_length),
+		packet_length);
+
+	if (wai.get_is_valid() == false)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("packet_process: %s, packet buffer corrupted.\n"),
+			 (m_is_client_role == true) ? "client": "server"
+			 ));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		EAP_TRACE_FLAGS_MESSAGE_DATA|TRACE_TEST_VECTORS, 
+		(EAPL("WAI-packet"),
+		 wai.get_header_buffer(packet_length),
+		 packet_length));
+
+	WAI_PROTOCOL_PACKET_TRACE_HEADER("wapi_core_c::packet_process(): ->", &wai, m_is_client_role);
+
+	status = wai.check_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (m_shutdown_was_called == true
+		&& m_is_client_role == true)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: WAPI_Core: %s, wapi_core_c::packet_process(): %s packet dropped quietly because shutdown was already called.\n"),
+			 (m_is_client_role == true) ? "client": "server",
+			 wapi_strings_c::get_wai_protocol_subtype_string(wai.get_subtype())));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
+	}
+
+	status = packet_reassemble(&wai);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	wai_protocol_packet_header_c reass_wai(
+		m_am_tools,
+		m_reassemble_packet.get_data(),
+		m_reassemble_packet.get_data_length());
+		
+	if (reass_wai.get_is_valid() == false)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_core_c::packet_process(): %s, packet buffer corrupted.\n"),
+			 (m_is_client_role == true) ? "client": "server"
+			 ));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+
+	if (m_is_client_role == true)
+	{
+		status = check_retransmission(&reass_wai);
+
+		if (status == eap_status_ok)
+		{
+			// OK, re-transmitted an old packet.
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+
+		switch(reass_wai.get_subtype())
+		{
+		case wai_protocol_subtype_authentication_activation:
+			status = handle_authentication_activation(receive_network_id, &reass_wai);
+			break;
+		case wai_protocol_subtype_access_authentication_response:
+			status = handle_access_authentication_response(receive_network_id, &reass_wai);
+			break;
+		case wai_protocol_subtype_unicast_key_negotiation_request:
+			status = handle_unicast_key_negotiation_request(receive_network_id, &reass_wai);
+			break;
+		case wai_protocol_subtype_unicast_key_negotiation_confirmation:
+			status = handle_unicast_key_negotiation_confirmation(receive_network_id, &reass_wai);
+			break;
+		case wai_protocol_subtype_multicast_key_announcement:
+			status = handle_multicast_key_announcement(receive_network_id, &reass_wai);
+			break;
+		default:
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: WAPI_Core: %s, wapi_core_c::packet_process(): Unknown %d=%s packet dropped quietly.\n"),
+				 (m_is_client_role == true) ? "client": "server",
+				 reass_wai.get_subtype(),
+				 wapi_strings_c::get_wai_protocol_subtype_string(reass_wai.get_subtype())));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
+		};
+	}
+#if defined(USE_WAPI_CORE_SERVER)
+	else
+	{
+		switch(reass_wai.get_subtype())
+		{
+		case wai_protocol_subtype_access_authentication_request:
+			status = handle_access_authentication_request(receive_network_id, &reass_wai);
+			break;
+		case wai_protocol_subtype_unicast_key_negotiation_response:
+			status = handle_unicast_key_negotiation_response(receive_network_id, &reass_wai);
+			break;
+		case wai_protocol_subtype_multicast_key_announcement_response:
+			status = handle_multicast_key_announcement_response(receive_network_id, &reass_wai);
+			break;
+		default:
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: WAPI_Core: %s, wapi_core_c::packet_process(): Unknown %d=%s packet dropped quietly.\n"),
+				 (m_is_client_role == true) ? "client": "server",
+				 reass_wai.get_subtype(),
+				 wapi_strings_c::get_wai_protocol_subtype_string(reass_wai.get_subtype())));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
+		};
+	}
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+	if (status == eap_status_ok
+		|| status == eap_status_pending_request)
+	{
+		automatic_packet_sequence_number.do_not_restore_variable();
+		automatic_wapi_state.do_not_restore_variable();
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::packet_send(
+	const eap_am_network_id_c * const send_network_id,
+	eap_buf_chain_wr_c * const sent_packet,
+	const u32_t header_offset,
+	const u32_t data_length,
+	const u32_t buffer_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	wai_protocol_packet_header_c wai(
+		m_am_tools,
+		sent_packet->get_data_offset(
+			header_offset, data_length),
+		data_length);
+
+	if (wai.get_is_valid() == false)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("packet_send(): %s, packet buffer corrupted.\n"),
+			 (m_is_client_role == true) ? "client": "server"
+			 ));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	EAP_ASSERT(header_offset < sent_packet->get_data_length());
+	EAP_ASSERT(data_length <= sent_packet->get_data_length());
+	EAP_ASSERT(sent_packet->get_data_length() <= buffer_length);
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		EAP_TRACE_FLAGS_MESSAGE_DATA|TRACE_TEST_VECTORS, 
+		(EAPL("WAI-packet"),
+		 wai.get_header_buffer(data_length),
+		 data_length));
+
+	WAI_PROTOCOL_PACKET_TRACE_HEADER("wapi_core_c::packet_send(): <-", &wai, m_is_client_role);
+
+	if (m_shutdown_was_called == true
+		&& m_is_client_role == true)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: WAPI_Core: %s, wapi_core_c::packet_send(): %s packet dropped quietly because shutdown was already called.\n"),
+			 (m_is_client_role == true) ? "client": "server",
+			 wapi_strings_c::get_wai_protocol_subtype_string(wai.get_subtype())));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly);
+	}
+
+	eap_status_e status = m_partner->packet_send(
+		send_network_id, sent_packet, header_offset, data_length, buffer_length);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::resend_packet(
+	const eap_am_network_id_c * const send_network_id,
+	const wai_message_c * const wai_message_data,
+	const u32_t retransmission_counter,
+	const u16_t packet_sequence_number)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_UNREFERENCED_PARAMETER(retransmission_counter); // Only trace uses this.
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("<- WAPI_Core: %s: wapi_core_c::resend_packet(), counter %d.\n"),
+		 (m_is_client_role == true) ? "client": "server",
+		 retransmission_counter
+		 ));
+
+	// We make a copy because random error test may corrupt the data.
+	wai_message_c * const copy_packet = wai_message_data->copy();
+
+	if (copy_packet == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	// NOTE: send packet directly to partner object.
+	// This will skip initialization of re-transmission for re-transmitted packet.
+	eap_status_e status = packet_fragment(
+		copy_packet,
+		packet_sequence_number);
+
+	delete copy_packet;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::cancel_retransmission()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("TIMER: %s: WAPI_CORE_TIMER_RETRANSMISSION_ID cancelled.\n"),
+			 (m_is_client_role == true ? "client": "server")
+			 ));
+
+		if (m_is_client_role == false)
+		{
+			// Only WAPI-server uses timer to re-transmits WAI-packets.
+			m_partner->cancel_timer(this, WAPI_CORE_TIMER_RETRANSMISSION_ID);
+		}
+
+		m_retransmission.reset();
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::init_retransmission(
+	const eap_am_network_id_c * const send_network_id,
+	const wai_message_c * const received_wai_message_data,
+	const wai_message_c * const new_wai_message_data,
+	const u16_t packet_sequence_number,
+	const wai_protocol_subtype_e wapi_subtype
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	if (m_is_client_role == false)
+	{
+		if (m_retransmission_time == 0u
+			|| m_retransmission_counter == 0u)
+		{
+			// No retransmission.
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+		}
+	}
+
+	EAP_ASSERT(send_network_id->get_source() != 0);
+	EAP_ASSERT(send_network_id->get_destination() != 0);
+
+	wapi_core_retransmission_c * retransmission = new wapi_core_retransmission_c(
+		m_am_tools,
+		send_network_id,
+		received_wai_message_data,
+		new_wai_message_data,
+		m_retransmission_time,
+		m_retransmission_counter,
+		packet_sequence_number,
+		wapi_subtype);
+	if (retransmission == 0
+		|| retransmission->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = m_retransmission.add_object_to_begin(
+		retransmission,
+		true);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (m_is_client_role == false)
+	{
+		// Only WAPI-server uses timer to re-transmits WAI-packets.
+		m_partner->cancel_timer(this, WAPI_CORE_TIMER_RETRANSMISSION_ID);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("TIMER: %s: WAPI_CORE_TIMER_RETRANSMISSION_ID cancelled.\n"),
+			 (m_is_client_role == true ? "client": "server")
+			 ));
+	}
+
+	retransmission = m_retransmission.get_object(0ul);
+
+	if (retransmission == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	if (retransmission->get_is_valid() == true)
+	{
+		if (m_is_client_role == false)
+		{
+			// Only WAPI-server uses timer to re-transmits WAI-packets.
+			u32_t next_retransmission_time = retransmission->get_next_retransmission_time();
+
+			eap_status_e status = m_partner->set_timer(this, WAPI_CORE_TIMER_RETRANSMISSION_ID, 0,
+				next_retransmission_time);
+
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TIMER: %s: WAPI_CORE_TIMER_RETRANSMISSION_ID set %d ms.\n"),
+				 (m_is_client_role == true ? "client": "server"),
+				 next_retransmission_time));
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+		else
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+		}
+	}
+	else
+	{
+		(void) m_retransmission.remove_object(0ul);
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_core_c::check_retransmission(const wai_protocol_packet_header_c * const received_wai)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::check_retransmission(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::check_retransmission()");
+
+	EAP_ASSERT(m_is_client == true);
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (received_wai == 0
+		|| received_wai->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	for (u32_t index = 0ul; index < m_retransmission.get_object_count(); ++index)
+	{
+		const wapi_core_retransmission_c * const retransmission = m_retransmission.get_object(index);
+		if (retransmission == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found);
+		}
+
+		const wai_message_c * const message = retransmission->get_wai_received_message_data();
+		if (message == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found);
+		}
+		else
+		{
+			wai_protocol_packet_header_c wai(
+				m_am_tools,
+				message->get_wai_message_data()->get_data(),
+				message->get_wai_message_data()->get_data_length());
+
+			if (wai.get_is_valid() == false)
+			{
+				EAP_TRACE_ERROR(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("wapi_core_c::packet_fragment(): %s, packet buffer corrupted.\n"),
+					 (m_is_client_role == true) ? "client": "server"
+					 ));
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+			}
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("%s: wapi_core_c::check_retransmission(): wai.get_version()=%d, received_wai->get_version()=%d\n"),
+				 (m_is_client == true ? "client": "server"),
+				 wai.get_version(),
+				 received_wai->get_version()));
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("%s: wapi_core_c::check_retransmission(): wai.get_type()=%d, received_wai->get_type()=%d\n"),
+				 (m_is_client == true ? "client": "server"),
+				 wai.get_type(),
+				 received_wai->get_type()));
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("%s: wapi_core_c::check_retransmission(): wai.get_subtype()=%d, received_wai->get_subtype()=%d\n"),
+				 (m_is_client == true ? "client": "server"),
+				 wai.get_subtype(),
+				 received_wai->get_subtype()));
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("%s: wapi_core_c::check_retransmission(): wai.get_packet_sequence_number()=%d, received_wai->get_packet_sequence_number()=%d\n"),
+				 (m_is_client == true ? "client": "server"),
+				 wai.get_packet_sequence_number(),
+				 received_wai->get_packet_sequence_number()));
+
+			if (wai.get_version() == received_wai->get_version()
+				&& wai.get_type() == received_wai->get_type()
+				&& wai.get_subtype() == received_wai->get_subtype()
+				&& wai.get_packet_sequence_number() == received_wai->get_packet_sequence_number())
+			{
+				status = resend_packet(
+					retransmission->get_send_network_id(),
+					retransmission->get_wai_message_data(),
+					retransmission->get_retransmission_counter(),
+					retransmission->get_packet_sequence_number());
+				if (status == eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+		} // for()
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::set_wapi_failure_timeout()
+{
+	eap_status_e status = m_partner->set_timer(
+		this,
+		WAPI_CORE_FAILURE_RECEIVED_ID,
+		0,
+		m_wapi_core_failure_received_timeout);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: TIMER: %s: WAPI_CORE_FAILURE_RECEIVED_ID failed.\n"),
+			 (m_is_client_role == true ? "client": "server")
+			 ));
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("TIMER: %s: WAPI_CORE_FAILURE_RECEIVED_ID set %d ms.\n"),
+			 (m_is_client_role == true ? "client": "server"),
+			 m_wapi_core_failure_received_timeout
+			 ));
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::cancel_wapi_failure_timeout()
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("TIMER: %s: WAPI_CORE_FAILURE_RECEIVED_ID cancelled.\n"),
+		 (m_is_client_role == true ? "client": "server")
+		 ));
+
+	return m_partner->cancel_timer(
+		this,
+		WAPI_CORE_FAILURE_RECEIVED_ID);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT u32_t wapi_core_c::get_header_offset(
+	u32_t * const MTU,
+	u32_t * const trailer_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const u32_t offset = m_partner->get_header_offset(MTU, trailer_length);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_core_c::get_header_offset(): offset=%d, MTU=%d, trailer_length=%d\n"),
+		offset,
+		*MTU,
+		*trailer_length));
+
+	return offset;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::configure()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+#if !defined(USE_EAP_DEBUG_TRACE)
+	EAP_TRACE_ALWAYS(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::configure(): %s\n"),
+		 ((m_is_client == true) ? "client": "server")));
+#else
+	EAP_TRACE_ALWAYS(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::configure(): %s: this = 0x%08x => 0x%08x.\n"),
+		 ((m_is_client == true) ? "client": "server"),
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+#endif
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::configure()");
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#if defined(USE_EAP_TEST_VECTORS)
+
+	{
+		eap_variable_data_c data(m_am_tools);
+
+		eap_status_e status = m_partner->read_configure(
+			cf_str_EAP_TRACE_only_trace_messages.get_field(),
+			&data);
+		if (status == eap_status_ok
+			&& data.get_data_length() == sizeof(u32_t)
+			&& data.get_data(data.get_data_length()) != 0)
+		{
+			if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u)
+			{
+				// Activate only WAPI message traces.
+				m_am_tools->set_trace_mask(
+					eap_am_tools_c::eap_trace_mask_always
+					| eap_am_tools_c::eap_trace_mask_eap_messages);
+			}
+			else
+			{
+				// Disable only WAPI message traces.
+				m_am_tools->set_trace_mask(
+					m_am_tools->get_trace_mask() & (~eap_am_tools_c::eap_trace_mask_eap_messages));
+			}
+		}
+		else
+		{
+			// Disable only WAPI message traces.
+			m_am_tools->set_trace_mask(
+				m_am_tools->get_trace_mask() & (~eap_am_tools_c::eap_trace_mask_eap_messages));
+		}
+	}
+
+
+	{
+		eap_variable_data_c data(m_am_tools);
+
+		eap_status_e status = m_partner->read_configure(
+			cf_str_EAP_TRACE_only_test_vectors.get_field(),
+			&data);
+		if (status == eap_status_ok
+			&& data.get_data_length() == sizeof(u32_t)
+			&& data.get_data(data.get_data_length()) != 0)
+		{
+			if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u)
+			{
+				// Activates only WAPI test vector traces.
+				m_am_tools->set_trace_mask(eap_am_tools_c::eap_trace_mask_test_vectors);
+			}
+		}
+	}
+
+
+	{
+		eap_variable_data_c data(m_am_tools);
+
+		eap_status_e status = m_partner->read_configure(
+			cf_str_EAP_TRACE_crypto_test_vectors_sha1.get_field(),
+			&data);
+		if (status == eap_status_ok
+			&& data.get_data_length() == sizeof(u32_t)
+			&& data.get_data(data.get_data_length()) != 0)
+		{
+			if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u)
+			{
+				// Activates SHA1 WAPI test vector traces.
+				m_am_tools->set_trace_mask(m_am_tools->get_trace_mask()
+					| eap_am_tools_c::eap_trace_mask_crypto_sha1);
+			}
+		}
+	}
+
+
+	{
+		eap_variable_data_c data(m_am_tools);
+
+		eap_status_e status = m_partner->read_configure(
+			cf_str_EAP_TRACE_crypto_test_vectors_rc4.get_field(),
+			&data);
+		if (status == eap_status_ok
+			&& data.get_data_length() == sizeof(u32_t)
+			&& data.get_data(data.get_data_length()) != 0)
+		{
+			if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u)
+			{
+				// Activates RC4 WAPI test vector traces.
+				m_am_tools->set_trace_mask(m_am_tools->get_trace_mask()
+					| eap_am_tools_c::eap_trace_mask_crypto_rc4);
+			}
+		}
+	}
+
+
+	{
+		eap_variable_data_c data(m_am_tools);
+
+		eap_status_e status = m_partner->read_configure(
+			cf_str_EAP_TRACE_crypto_test_vectors_md4.get_field(),
+			&data);
+		if (status == eap_status_ok
+			&& data.get_data_length() == sizeof(u32_t)
+			&& data.get_data(data.get_data_length()) != 0)
+		{
+			if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u)
+			{
+				// Activates MD4 WAPI test vector traces.
+				m_am_tools->set_trace_mask(m_am_tools->get_trace_mask()
+					| eap_am_tools_c::eap_trace_mask_crypto_md4);
+			}
+		}
+	}
+
+
+	{
+		eap_variable_data_c data(m_am_tools);
+
+		eap_status_e status = m_partner->read_configure(
+			cf_str_EAP_TRACE_crypto_test_vectors_test_random.get_field(),
+			&data);
+		if (status == eap_status_ok
+			&& data.get_data_length() == sizeof(u32_t)
+			&& data.get_data(data.get_data_length()) != 0)
+		{
+			if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u)
+			{
+				// Activates test random generator WAPI test vector traces.
+				m_am_tools->set_trace_mask(m_am_tools->get_trace_mask()
+					| eap_am_tools_c::eap_trace_mask_crypto_test_random
+					| eap_am_tools_c::eap_trace_mask_crypto_sha1);
+			}
+		}
+	}
+
+#endif //#if defined(USE_EAP_TEST_VECTORS)
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == false)
+	{
+		eap_variable_data_c retransmission_time(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_WAPI_CORE_retransmission_time.get_field(),
+			&retransmission_time);
+		if (status == eap_status_ok
+			&& retransmission_time.get_is_valid_data() == true)
+		{
+			u32_t *retransmission_time_value = reinterpret_cast<u32_t *>(
+				retransmission_time.get_data(sizeof(u32_t)));
+			if (retransmission_time_value != 0)
+			{
+				m_retransmission_time = *retransmission_time_value;
+			}
+			else
+			{
+				m_retransmission_time = WAPI_CORE_RETRANSMISSION_TIME;
+			}
+		}
+		else
+		{
+			m_retransmission_time = WAPI_CORE_RETRANSMISSION_TIME;
+		}
+	}
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+	{
+		eap_variable_data_c retransmission_counter(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_WAPI_CORE_retransmission_counter.get_field(),
+			&retransmission_counter);
+		if (status == eap_status_ok
+			&& retransmission_counter.get_is_valid_data() == true)
+		{
+			u32_t *retransmission_counter_value = reinterpret_cast<u32_t *>(
+				retransmission_counter.get_data(sizeof(u32_t)));
+			if (retransmission_counter_value != 0)
+			{
+				m_retransmission_counter = *retransmission_counter_value;
+			}
+			else
+			{
+				m_retransmission_counter = WAPI_CORE_RETRANSMISSION_COUNTER;
+			}
+		}
+		else
+		{
+			m_retransmission_counter = WAPI_CORE_RETRANSMISSION_COUNTER;
+		}
+	}
+
+	//----------------------------------------------------------
+
+	{
+		eap_variable_data_c session_timeout(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_WAPI_CORE_session_timeout.get_field(),
+			&session_timeout);
+		if (status == eap_status_ok
+			&& session_timeout.get_is_valid_data() == true)
+		{
+			u32_t *handler_timeout = reinterpret_cast<u32_t *>(
+				session_timeout.get_data(sizeof(u32_t)));
+			if (handler_timeout != 0)
+			{
+				m_session_timeout = *handler_timeout;
+			}
+			else
+			{
+				m_session_timeout = WAPI_CORE_SESSION_TIMEOUT;
+			}
+		}
+		else
+		{
+			m_session_timeout = WAPI_CORE_SESSION_TIMEOUT;
+		}
+	}
+
+
+#if defined(USE_WAPI_CORE_SERVER)
+
+	if (m_is_client == false)
+	{
+		eap_variable_data_c session_timeout(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_WAPI_CORE_server_session_timeout.get_field(),
+			&session_timeout);
+		if (status == eap_status_ok
+			&& session_timeout.get_is_valid_data() == true)
+		{
+			u32_t *handler_timeout = reinterpret_cast<u32_t *>(
+				session_timeout.get_data(sizeof(u32_t)));
+			if (handler_timeout != 0)
+			{
+				// This is optional.
+				m_session_timeout = *handler_timeout;
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	if (m_is_client == false)
+	{
+		eap_variable_data_c only_initial_authentication(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_WAPI_CORE_server_only_initial_authentication.get_field(),
+			&only_initial_authentication);
+		if (status == eap_status_ok
+			&& only_initial_authentication.get_is_valid_data() == true)
+		{
+			u32_t *flag = reinterpret_cast<u32_t *>(
+				only_initial_authentication.get_data(sizeof(u32_t)));
+			if (flag != 0)
+			{
+				if (*flag == 0)
+				{
+					m_only_initial_authentication = false;
+				}
+				else
+				{
+					m_only_initial_authentication = true;
+				}
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	if (m_is_client == false)
+	{
+		eap_status_e status = m_partner->read_configure(
+			cf_str_WAPI_CORE_server_test_other_asu_id.get_field(),
+			&m_test_other_asu_id);
+		if (status == eap_status_ok
+			&& m_test_other_asu_id.get_is_valid_data() == true)
+		{
+			// This is optional for testing purposes.
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::configure(): Other ASU ID\n"),
+				 this,
+				 (m_is_client == true ? "client": "server")));
+		}
+	}
+
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+	//----------------------------------------------------------
+
+	{
+		eap_variable_data_c failure_received_timeout(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_WAPI_CORE_failure_received_timeout.get_field(),
+			&failure_received_timeout);
+		if (status == eap_status_ok
+			&& failure_received_timeout.get_is_valid_data() == true)
+		{
+			u32_t *timeout = reinterpret_cast<u32_t *>(
+				failure_received_timeout.get_data(sizeof(u32_t)));
+			if (timeout != 0)
+			{
+				m_wapi_core_failure_received_timeout = *timeout;
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	{
+		eap_status_e status = read_configure(
+			cf_str_WAPI_CORE_PSK.get_field(),
+			&m_preshared_key_PSK);
+		if (status == eap_status_ok)
+		{
+			if (m_preshared_key_PSK.get_data_length() == WAPI_BK_LENGTH)
+			{
+				status = m_BK.set_copy_of_buffer(&m_preshared_key_PSK);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+			else
+			{
+				// Create BK from PSK and label.
+				crypto_kd_hmac_sha256_c kd_hmac(m_am_tools);
+				if (kd_hmac.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				const eap_variable_data_c label(
+					m_am_tools,
+					WAPI_PRESHARED_KEY_LABEL,
+					WAPI_PRESHARED_KEY_LABEL_LENGTH,
+					false,
+					false);
+				if (label.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				status = kd_hmac.expand_key(
+					&m_BK,
+					WAPI_BK_LENGTH,
+					&m_preshared_key_PSK,
+					&label);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	m_wapi_header_offset = m_partner->get_header_offset(&m_MTU, &m_trailer_length);
+
+
+	// Add session timeout.
+	initialize_session_timeout(m_session_timeout);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::shutdown()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	eap_status_e status(eap_status_ok);
+
+#if !defined(USE_EAP_DEBUG_TRACE)
+	EAP_TRACE_ALWAYS(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::shutdown(): %s: m_shutdown_was_called=%d.\n"),
+		 ((m_is_client == true) ? "client": "server"),
+		 m_shutdown_was_called));
+#else
+	EAP_TRACE_ALWAYS(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::shutdown(): %s: this = 0x%08x => 0x%08x, ")
+		 EAPL("m_shutdown_was_called=%d.\n"),
+		 ((m_is_client == true) ? "client": "server"),
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this),
+		 m_shutdown_was_called));
+#endif
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::shutdown()");
+
+	if (m_shutdown_was_called == true)
+	{
+		// Shutdown was already called once.
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	m_shutdown_was_called = true;
+
+	cancel_retransmission();
+	cancel_session_timeout();
+	cancel_wapi_failure_timeout();
+	cancel_asynchronous_init_remove_wapi_session();
+
+	if (m_partner != 0)
+	{
+		cancel_session_timeout();
+	}
+
+	if (m_ec_certificate_store != 0)
+	{
+		m_ec_certificate_store->shutdown();
+	}
+
+	if (m_am_wapi_core != 0)
+	{
+		m_am_wapi_core->shutdown();
+	}
+
+#if !defined(USE_EAP_DEBUG_TRACE)
+	EAP_TRACE_ALWAYS(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::shutdown(): %s: m_shutdown_was_called=%d, status=%d returns.\n"),
+		 ((m_is_client == true) ? "client": "server"),
+		 m_shutdown_was_called,
+		 status));
+#else
+	EAP_TRACE_ALWAYS(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::shutdown(): %s: this = 0x%08x => 0x%08x, ")
+		 EAPL("m_shutdown_was_called=%d, status=%d returns.\n"),
+		 ((m_is_client == true) ? "client": "server"),
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this),
+		 m_shutdown_was_called,
+		 status));
+#endif
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::restart_authentication(
+	const eap_am_network_id_c * const send_network_id,
+	const bool is_client_when_true)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	// Here we swap the addresses.
+	eap_am_network_id_c receive_network_id(m_am_tools,
+		send_network_id->get_destination_id(),
+		send_network_id->get_source_id(),
+		send_network_id->get_type());
+
+	eap_status_e status = eap_status_process_general_error;
+
+	initialize_session_timeout(m_session_timeout);
+
+	if (is_client_when_true == false)
+	{
+		status = start_authentication();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		m_client_restart_authentication_initiated = true;
+	}
+	else
+	{
+		if (m_client_restart_authentication_initiated == true)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+		}
+
+		status = allow_authentication();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		m_client_restart_authentication_initiated = true;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::read_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->read_configure(field, data);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::write_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->write_configure(field, data);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::timer_expired(
+	const u32_t id, void *data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_UNREFERENCED_PARAMETER(data); // Only trace uses this.
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("TIMER: [0x%08x]->wapi_core_c::timer_expired(id 0x%02x, data 0x%08x), %s.\n"),
+		 this,
+		 id,
+		 data,
+		 (m_is_client == true) ? "client": "server"));
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (id == WAPI_CORE_TIMER_RETRANSMISSION_ID)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("TIMER: %s: WAPI_CORE_TIMER_RETRANSMISSION_ID elapsed.\n"),
+			 (m_is_client == true ? "client": "server")
+			 ));
+
+		if (m_retransmission.get_object_count() > 0ul)
+		{
+			wapi_core_retransmission_c * const retransmission = m_retransmission.get_object(0ul);
+
+			if (retransmission != 0
+				&& retransmission->get_is_valid() == true
+				&& retransmission->get_retransmission_counter() > 0)
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("TIMER: %s, new retransmission, retransmission->get_is_valid()=%d, ")
+					 EAPL("retransmission->get_retransmission_counter()=%d.\n"),
+					 (m_is_client == true) ? "client": "server",
+					 retransmission->get_is_valid(),
+					 retransmission->get_retransmission_counter()));
+				
+				status = eap_status_ok;
+
+				if (retransmission->get_wapi_subtype() == wai_protocol_subtype_unicast_key_negotiation_request
+					|| retransmission->get_wapi_subtype() == wai_protocol_subtype_multicast_key_announcement)
+				{
+					// Also the previous message must be re-transmitted.
+					if (m_retransmission.get_object_count() > 1ul)
+					{
+						wapi_core_retransmission_c * const prev_retransmission = m_retransmission.get_object(1ul);
+						
+						if (prev_retransmission != 0
+							&& prev_retransmission->get_is_valid() == true
+							&& prev_retransmission->get_retransmission_counter() > 0)
+						{
+							status = resend_packet(
+								prev_retransmission->get_send_network_id(),
+								prev_retransmission->get_wai_message_data(),
+								prev_retransmission->get_retransmission_counter(),
+								prev_retransmission->get_packet_sequence_number());
+						}
+					}
+				}
+				
+				if (status == eap_status_ok)
+				{
+					status = resend_packet(
+						retransmission->get_send_network_id(),
+						retransmission->get_wai_message_data(),
+						retransmission->get_retransmission_counter(),
+						retransmission->get_packet_sequence_number());
+				}
+				
+				if (status == eap_status_ok)
+				{
+					if (retransmission->get_retransmission_counter() > 0u)
+					{
+						// OK, initialize the next time to retransmit.
+						u32_t next_retransmission_time
+							= retransmission->get_next_retransmission_time();
+
+						status = m_partner->set_timer(
+							this,
+							WAPI_CORE_TIMER_RETRANSMISSION_ID,
+							0,
+							next_retransmission_time);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_DEBUG(
+								m_am_tools, 
+								TRACE_FLAGS_DEFAULT, 
+								(EAPL("ERROR: TIMER: %s: WAPI_CORE_TIMER_RETRANSMISSION_ID ")
+								 EAPL("set %d ms, retransmission_counter %d, failed.\n"),
+								 (m_is_client == true ? "client": "server"),
+								 next_retransmission_time,
+								 retransmission->get_retransmission_counter()));
+						}
+						else
+						{
+							retransmission->get_next_retransmission_counter(); // This decrements the counter.
+							
+							EAP_TRACE_DEBUG(
+								m_am_tools, 
+								TRACE_FLAGS_DEFAULT, 
+								(EAPL("TIMER: %s: WAPI_CORE_TIMER_RETRANSMISSION_ID ")
+								 EAPL("set %d ms, retransmission_counter %d.\n"),
+								 (m_is_client == true ? "client": "server"),
+								 next_retransmission_time,
+								 retransmission->get_retransmission_counter()));
+						}
+					}
+
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+				else
+				{
+					status = eap_status_ok;
+
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+			else
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("TIMER: %s, no retransmission, m_retransmission=0x%08x.\n"),
+					 (m_is_client == true) ? "client": "server",
+					 retransmission));
+				if (retransmission != 0)
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools, 
+						TRACE_FLAGS_DEFAULT, 
+						(EAPL("TIMER: %s, no retransmission, retransmission->get_is_valid()=%d, ")
+						 EAPL("retransmission->get_retransmission_counter()=%d.\n"),
+						 (m_is_client == true) ? "client": "server",
+						 retransmission->get_is_valid(),
+						 retransmission->get_retransmission_counter()));
+				}
+				
+				// No good WAI-Response received to WAI-Requests.
+				// Terminate the session.
+
+				{
+					eap_am_network_id_c send_network_id(
+						m_am_tools,
+						m_receive_network_id.get_destination_id(),
+						m_receive_network_id.get_source_id(),
+						m_receive_network_id.get_type());
+
+					eap_state_notification_c notification(
+						m_am_tools,
+						&send_network_id,
+						m_is_client,
+						eap_state_notification_eap,
+						eap_protocol_layer_eap,
+						eap_type_none,
+						eap_state_none,
+						eap_state_authentication_terminated_unsuccessfully,
+						0ul,
+						false);
+
+					notification.set_authentication_error(eap_status_authentication_failure);
+					
+					state_notification(&notification);
+				}
+
+				status = eap_status_ok;
+			}
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TIMER: %s, no retransmission, count of m_retransmission=%d.\n"),
+				 (m_is_client == true) ? "client": "server",
+				 m_retransmission.get_object_count()));
+		}
+	}
+	else if (id == WAPI_CORE_SESSION_TIMEOUT_ID)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("TIMER: %s: WAPI_CORE_SESSION_TIMEOUT_ID elapsed.\n"),
+			 (m_is_client == true ? "client": "server")
+			 ));
+
+		// we will remove this session immediately.
+		status = initialize_asynchronous_init_remove_wapi_session(0ul);
+
+		{
+			// Here we swap the addresses.
+			eap_am_network_id_c send_network_id(m_am_tools,
+				m_receive_network_id.get_destination_id(),
+				m_receive_network_id.get_source_id(),
+				m_receive_network_id.get_type());
+
+			if (send_network_id.get_is_valid_data() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			// This notification to eapol_core_c object.
+			// WAI authentication terminated unsuccessfully.
+			eap_state_notification_c * notification = new eap_state_notification_c(
+				m_am_tools,
+				&send_network_id,
+				m_is_client,
+				eap_state_notification_generic,
+				eap_protocol_layer_wai,
+				eapol_key_handshake_type_wai_handshake,
+				eapol_key_state_wapi_authentication_running,
+				eapol_key_state_wapi_authentication_terminated_unsuccessfull,
+				0ul,
+				false);
+			if (notification == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			notification->set_authentication_error(eap_status_authentication_failure);
+
+			state_notification(notification);
+
+			delete notification;
+
+			set_wapi_state(wapi_core_state_authentication_failed);
+		}
+
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+	else if (id == WAPI_CORE_REMOVE_SESSION_TIMEOUT_ID)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("TIMER: %s: WAPI_CORE_REMOVE_SESSION_TIMEOUT_ID elapsed.\n"),
+			 (m_is_client == true ? "client": "server")
+			 ));
+
+		status = asynchronous_init_remove_wapi_session();
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::timer_delete_data(
+	const u32_t id, void *data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_UNREFERENCED_PARAMETER(data); // Only trace uses this.
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("TIMER: [0x%08x]->wapi_core_c::timer_delete_data(id 0x%02x, data 0x%08x): %s.\n"),
+		 this,
+		 id,
+		 data,
+		 (m_is_client == true) ? "client": "server"
+		 ));
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	if (id == WAPI_CORE_TIMER_RETRANSMISSION_ID)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("TIMER: %s: WAPI_CORE_TIMER_RETRANSMISSION_ID delete data.\n"),
+			 (m_is_client == true ? "client": "server")
+			 ));
+
+		if (m_retransmission.get_object_count() > 0ul)
+		{
+			wapi_core_retransmission_c * const retransmission = m_retransmission.get_object(0ul);
+
+			if (retransmission != 0
+				&& retransmission->get_is_valid() == true
+				&& retransmission->get_retransmission_counter() > 0)
+			{
+				// Do not delete yet.
+				// cancel_retransmission() will delete m_retransmission.
+			}
+			else if (retransmission != 0)
+			{
+				(void) m_retransmission.remove_object(0ul);
+			}
+		}
+	}
+	else if (id == WAPI_CORE_REMOVE_SESSION_TIMEOUT_ID)
+	{
+		// Nothing to do.
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::reset()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+#if !defined(USE_EAP_DEBUG_TRACE)
+	EAP_TRACE_ALWAYS(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::reset(): %s.\n"),
+		 ((m_is_client == true) ? "client": "server")));
+#else
+	EAP_TRACE_ALWAYS(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_core_c::reset(): %s: this = 0x%08x => 0x%08x.\n"),
+		 ((m_is_client == true) ? "client": "server"),
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+#endif
+
+	eap_status_e status = eap_status_ok;
+
+	cancel_retransmission();
+
+	cancel_session_timeout();
+
+	cancel_wapi_failure_timeout();
+
+	cancel_asynchronous_init_remove_wapi_session();
+
+    // restart message sequencing
+    m_packet_sequence_number = 0ul;
+
+	// Add session timeout.
+	initialize_session_timeout(m_session_timeout);
+
+	m_wapi_state = wapi_core_state_none;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::set_session_timeout(
+	const u32_t session_timeout_ms)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	eap_status_e status = initialize_session_timeout(session_timeout_ms);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::set_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id, 
+	void * const p_data,
+	const u32_t p_time_ms)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->set_timer(
+		p_initializer, 
+		p_id, 
+		p_data,
+		p_time_ms);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::cancel_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->cancel_timer(
+		p_initializer, 
+		p_id);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::cancel_all_timers()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->cancel_all_timers();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::set_authentication_role(const bool when_true_set_client)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	cancel_retransmission();
+
+	cancel_wapi_failure_timeout();
+
+	m_is_client_role = when_true_set_client;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::cancel_authentication_session()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::cancel_authentication_session(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::cancel_authentication_session()");
+
+	cancel_retransmission();
+	cancel_wapi_failure_timeout();
+	cancel_session_timeout();
+
+	m_fragment_sequence_number = 0ul;
+	m_packet_sequence_number = 0u;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::check_bksa_cache(
+	const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::check_bksa_cache(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::check_bksa_cache()");
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::complete_query_asu_id(
+	const eap_variable_data_c * const asn1_der_subject_name,
+	const eap_variable_data_c * const asn1_der_issuer_name,
+	const eap_variable_data_c * const asn1_der_sequence_number,
+	const eap_status_e id_status)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_query_asu_id(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::complete_query_asu_id()");
+
+	if (id_status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, id_status);
+	}
+
+	eap_status_e status = m_asu_id.set_copy_of_buffer(asn1_der_subject_name);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_asu_id.add_data(asn1_der_issuer_name);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_asu_id.add_data(asn1_der_sequence_number);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+
+	status = m_ec_certificate_store->get_own_certificate();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::complete_get_own_certificate(
+	const eap_variable_data_c * const own_certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_get_own_certificate(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::complete_get_own_certificate()");
+
+	eap_status_e status(eap_status_not_supported);
+
+#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == false
+		&& m_wapi_state == wapi_core_state_start_certificate_negotiation)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Saves own certificate.
+
+		status = m_own_certificate.set_copy_of_buffer(own_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Reads the ID of STA_AE
+
+		status = m_ec_certificate_store->read_id_of_certificate(&m_own_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+	}
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::complete_select_certificate(
+	const eap_variable_data_c * const issuer_ID,
+	const eap_variable_data_c * const certificate_ID,
+	const eap_variable_data_c * const certificate)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_select_certificate(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::complete_select_certificate()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	if (issuer_ID == 0
+		|| issuer_ID->get_is_valid() == false
+		|| certificate_ID == 0
+		|| certificate_ID->get_is_valid() == false
+		|| certificate == 0
+		|| certificate->get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (m_is_client == true
+		&& m_wapi_state == wapi_core_state_process_authentication_activation_message)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Saves own ID.
+
+		status = m_asue_id.set_copy_of_buffer(certificate_ID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("m_asue_id"),
+			 m_asue_id.get_data(),
+			 m_asue_id.get_data_length()));
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Saves own certificate.
+
+		status = m_own_certificate.set_copy_of_buffer(certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Reads the ID of STA_AE
+
+		status = m_ec_certificate_store->read_id_of_certificate(&m_peer_certificate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::complete_read_id_of_certificate(
+	const eap_variable_data_c * const ID)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_read_id_of_certificate(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::complete_read_id_of_certificate()");
+
+	eap_status_e status(eap_status_not_supported);
+
+#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == false
+		&& m_wapi_state == wapi_core_state_start_certificate_negotiation)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Save AE-ID.
+
+		status = m_ae_id.set_copy_of_buffer(ID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("m_ae_id"),
+			 m_ae_id.get_data(),
+			 m_ae_id.get_data_length()));
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create Authentication Identifier.
+
+		if (m_wapi_negotiation_state == wapi_negotiation_state_initial_negotiation)
+		{
+			crypto_random_c rand(m_am_tools);
+			if (rand.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = rand.get_rand_bytes(
+				&m_authentication_identifier,
+				WAPI_AUTHENTICATION_IDENTIFIER_LENGTH);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("new local m_authentication_identifier"),
+				 m_authentication_identifier.get_data(),
+				 m_authentication_identifier.get_data_length()));
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create the Authentication Activation Packet.
+
+		wai_message_payloads_c * const payloads = new wai_message_payloads_c(m_am_tools, m_is_client);
+		eap_automatic_variable_c<wai_message_payloads_c> automatic_payloads(m_am_tools, payloads);
+
+		if (payloads == 0
+			|| payloads->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = payloads->initialise_header();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->get_wai_protocol_packet_header_writable()->set_subtype(wai_protocol_subtype_authentication_activation);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds FLAG to data field.
+
+		{
+			wai_variable_data_c data_flag(m_am_tools);
+			if (data_flag.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			u8_t flag(wai_data_flag_mask_none);
+
+			if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+			{
+				flag = wai_data_flag_mask_BK_Rekeying;
+			}
+
+			status = data_flag.create(
+				wai_payload_type_flag,
+				&flag,
+				sizeof(flag));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = payloads->add_tlv(&data_flag);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds Authentication Identifier to data field.
+
+		{
+			wai_variable_data_c data_authentication_identifier(m_am_tools);
+			if (data_authentication_identifier.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = data_authentication_identifier.create(
+				wai_payload_type_authentication_identifier,
+				&m_authentication_identifier);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = payloads->add_tlv(&data_authentication_identifier);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds ID of local ASU to data field.
+
+		{
+			wai_variable_data_c data_id_of_local_asu(m_am_tools);
+			if (data_id_of_local_asu.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			if (m_test_other_asu_id.get_is_valid_data() == true)
+			{
+				status = data_id_of_local_asu.create(
+					wai_payload_type_identity,
+					&m_test_other_asu_id);
+			}
+			else
+			{
+				status = data_id_of_local_asu.create(
+					wai_payload_type_identity,
+					&m_asu_id);
+			}
+
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = payloads->add_tlv(&data_id_of_local_asu);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds STA_AE Certificate to data field.
+
+		{
+			wai_variable_data_c data_certificate(m_am_tools);
+			if (data_certificate.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = data_certificate.create(
+				wai_payload_type_certificate,
+				&m_own_certificate);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = payloads->add_tlv(&data_certificate);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds ECDH parameter to data field.
+
+		{
+			wai_variable_data_c data_ecdh_parameter(m_am_tools);
+			if (data_ecdh_parameter.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = data_ecdh_parameter.create(
+				wai_payload_type_echd_parameter,
+				WAPI_ECDH_OID_PARAMETER,
+				sizeof(WAPI_ECDH_OID_PARAMETER));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = payloads->add_tlv(&data_ecdh_parameter);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create and send message.
+
+		wai_message_c new_wai_message_data(m_am_tools, m_is_client);
+		if (new_wai_message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = payloads->create_wai_tlv_message(&new_wai_message_data, false);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		//cancel_retransmission();
+
+		status = packet_send(
+			&new_wai_message_data,
+			payloads->get_wai_protocol_packet_header_writable()->get_subtype());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		set_wapi_state(wapi_core_state_wait_access_authentication_request_message);
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	}
+	else
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == true
+		&& m_wapi_state == wapi_core_state_process_authentication_activation_message)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Saves ID of STA_AE.
+
+		status = m_ae_id.set_copy_of_buffer(ID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("m_ae_id"),
+			 m_ae_id.get_data(),
+			 m_ae_id.get_data_length()));
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Creates ECDH temporary keys.
+
+		status = m_ec_certificate_store->create_ecdh_temporary_keys();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::complete_create_signature_with_private_key(
+	const eap_variable_data_c * const signature,
+	const eap_status_e signature_status)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_create_signature_with_private_key(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::complete_create_signature_with_private_key()");
+
+	if (signature_status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, signature_status);
+	}
+
+	eap_status_e status(eap_status_not_supported);
+
+	
+#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == false
+		&& m_wapi_state == wapi_core_state_process_access_authentication_request_message_AE_signature_trusted_by_ASUE)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds signature of AE trusted by ASUE to data field.
+
+		{
+			wai_variable_data_c data_signature(m_am_tools);
+			if (data_signature.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_ae_id"),
+				 m_ae_id.get_data(),
+				 m_ae_id.get_data_length()));
+
+			status = create_signature_attributes(
+				&data_signature,
+				&m_ae_id,
+				signature);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_signature);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create and send message.
+
+		wai_message_c new_wai_message_data(m_am_tools, m_is_client);
+		if (new_wai_message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_new_payloads.create_wai_tlv_message(&new_wai_message_data, false);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		//cancel_retransmission();
+
+		status = packet_send(
+			&new_wai_message_data,
+			m_new_payloads.get_wai_protocol_packet_header_writable()->get_subtype());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		m_new_payloads.reset();
+
+		set_wapi_state(wapi_core_state_start_unicast_key_negotiation);
+
+		status = start_unicast_key_negotiation();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	}
+	else if (m_is_client == false
+		&& m_wapi_state == wapi_core_state_process_access_authentication_request_message_ASU_signature_trusted_by_AE)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds signature of server trusted by AE to data field.
+
+		status = create_signature_attributes(
+			&m_server_signature_trusted_by_ae,
+			&m_asu_id,
+			signature);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Creates ECDH temporary keys.
+
+		status = m_ec_certificate_store->create_ecdh_temporary_keys();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else if (m_is_client == false
+		&& m_wapi_state == wapi_core_state_process_access_authentication_request_message)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds signature of server trusted by ASUE to data field.
+
+		status = create_signature_attributes(
+			&m_server_signature_trusted_by_asue,
+			&m_asu_id,
+			signature);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		{
+			eap_variable_data_c HASH(m_am_tools);
+			if (HASH.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			wai_message_payloads_c * const payloads = new wai_message_payloads_c(m_am_tools, m_is_client);
+			eap_automatic_variable_c<wai_message_payloads_c> automatic_payloads(m_am_tools, payloads);
+
+			if (payloads == 0
+				|| payloads->get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = payloads->insert_payload(&m_result_of_certificate_verification);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = payloads->insert_payload(&m_server_signature_trusted_by_asue);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = create_HASH(payloads, true, &HASH);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_asu_id"),
+				 m_asu_id.get_data(),
+				 m_asu_id.get_data_length()));
+
+			set_wapi_state(wapi_core_state_process_access_authentication_request_message_ASU_signature_trusted_by_AE);
+
+			status = m_ec_certificate_store->create_signature_with_private_key(
+				&HASH,
+				&m_asu_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+	else
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == true
+		&& m_wapi_state == wapi_core_state_process_authentication_activation_message)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds Signature of ASUE to data field.
+
+		{
+			wai_variable_data_c data_signature(m_am_tools);
+			if (data_signature.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_asue_id"),
+				 m_asue_id.get_data(),
+				 m_asue_id.get_data_length()));
+
+			status = create_signature_attributes(
+				&data_signature,
+				&m_asue_id,
+				signature);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_signature);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create and send message.
+
+		wai_message_c new_wai_message_data(m_am_tools, m_is_client);
+		if (new_wai_message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_new_payloads.create_wai_tlv_message(&new_wai_message_data, false);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = packet_send(
+			&new_wai_message_data,
+			m_new_payloads.get_wai_protocol_packet_header_writable()->get_subtype());
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		m_new_payloads.reset();
+
+		set_wapi_state(wapi_core_state_wait_access_authentication_response_message);
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::complete_verify_signature_with_public_key(
+	const eap_status_e verification_status)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_verify_signature_with_public_key(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::complete_verify_signature_with_public_key()");
+
+	eap_status_e status(eap_status_not_supported);
+
+#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == false
+		&& m_wapi_state == wapi_core_state_process_access_authentication_request_message)
+	{
+		if (verification_status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, verification_status);
+		}
+
+		// Create the AE challenge.
+		if (m_ae_certificate_challenge.get_is_valid_data() == false)
+		{
+			crypto_random_c rand(m_am_tools);
+			if (rand.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = rand.get_rand_bytes(
+				&m_ae_certificate_challenge,
+				WAPI_CHALLENGE_LENGTH);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		if (m_do_certificate_validation == true)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_verify_signature_with_public_key(): does certificate validation\n"),
+				this,
+				(m_is_client == true ? "client": "server")));
+
+			// First we need to create verification results by server (ASU) of both certificates, ASUE certificate and AE certificate.
+			// Second thing to create are server (ASU) signatures trusted by ASUE and AE.
+			//     Signature trusted by ASUE signs field Authentication Result for certificate in the Certificate Authentication Response packet.
+			//     Signature trusted by AE signs both fields Authentication Result for certificate and Signature trusted by ASUE in the Certificate Authentication Response packet.
+			// All operations are simulated here without external server (ASU) and without Certificate Authentication Request and Certificate Authentication Response packets.
+
+			// Create the result of certificate verification.
+			status = create_result_of_certificate_verification(
+				&m_result_of_certificate_verification,
+				&m_ae_certificate_challenge,
+				&m_asue_certificate_challenge,
+				wapi_certificate_result_valid,
+				&m_peer_certificate, // ASUE certificate
+				wapi_certificate_result_valid,
+				&m_own_certificate); // AE certificate
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+			// Create Signature of ASU.
+
+			{
+				eap_variable_data_c HASH(m_am_tools);
+				if (HASH.get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				wai_message_payloads_c * const payloads = new wai_message_payloads_c(m_am_tools, m_is_client);
+				eap_automatic_variable_c<wai_message_payloads_c> automatic_payloads(m_am_tools, payloads);
+
+				if (payloads == 0
+					|| payloads->get_is_valid() == false)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+				}
+
+				status = payloads->initialise_header();
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = payloads->get_wai_protocol_packet_header_writable()->set_subtype(wai_protocol_subtype_certificate_authentication_response);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = payloads->add_tlv(&m_result_of_certificate_verification);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = create_HASH(payloads, true, &HASH);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				EAP_TRACE_DATA_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("m_asu_id"),
+					 m_asu_id.get_data(),
+					 m_asu_id.get_data_length()));
+
+				status = m_ec_certificate_store->create_signature_with_private_key(
+					&HASH,
+					&m_asu_id);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_verify_signature_with_public_key(): no certificate validation\n"),
+				this,
+				(m_is_client == true ? "client": "server")));
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+			// Creates ECDH temporary keys.
+
+			set_wapi_state(wapi_core_state_process_access_authentication_request_message_ASU_signature_trusted_by_AE);
+
+			status = m_ec_certificate_store->create_ecdh_temporary_keys();
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		}
+	}
+	else
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == true
+		&& m_wapi_state == wapi_core_state_process_access_authentication_response_message)
+	{
+		if (verification_status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, verification_status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Verify Signature of ASU.
+
+		if (m_do_certificate_validation == true)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_verify_signature_with_public_key(): does certificate validation\n"),
+				this,
+				(m_is_client == true ? "client": "server")));
+
+			if (m_server_signature_trusted_by_ae.get_is_valid_data() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload);
+			}
+
+			eap_variable_data_c signature_data(m_am_tools);
+			if (signature_data.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_variable_data_c received_asu_id(m_am_tools);
+			if (received_asu_id.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = parse_signature_attributes(
+				&m_server_signature_trusted_by_ae,
+				&received_asu_id,
+				&signature_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("received_asu_id"),
+				 received_asu_id.get_data(),
+				 received_asu_id.get_data_length()));
+
+			eap_variable_data_c HASH(m_am_tools);
+			if (HASH.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+			// Adds Multiple Certificate Verification Result to data field.
+
+			{
+				status = m_new_payloads.reset();
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = m_new_payloads.add_tlv(&m_result_of_certificate_verification);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+
+			status = create_HASH(&m_new_payloads, false, &HASH);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			set_wapi_state(wapi_core_state_process_access_authentication_response_message_ASU_signature);
+
+			status = m_ec_certificate_store->verify_signature_with_public_key(
+				&m_asu_id,
+				&HASH,
+				&signature_data,
+				false);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_verify_signature_with_public_key(): no certificate validation\n"),
+				this,
+				(m_is_client == true ? "client": "server")));
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+			// Create temporary ECDH keys.
+
+			set_wapi_state(wapi_core_state_process_access_authentication_response_message_ASU_signature);
+
+			status = m_ec_certificate_store->create_ecdh(
+				&m_own_private_key_d,
+				&m_peer_public_key_x,
+				&m_peer_public_key_y);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		}
+	}
+	else if (m_is_client == true
+		&& m_wapi_state == wapi_core_state_process_access_authentication_response_message_ASU_signature)
+	{
+		if (verification_status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, verification_status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create temporary ECDH keys.
+
+		status = m_ec_certificate_store->create_ecdh(
+			&m_own_private_key_d,
+			&m_peer_public_key_x,
+			&m_peer_public_key_y);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::complete_create_ecdh_temporary_keys(
+	const eap_variable_data_c * const private_key_d,
+	const eap_variable_data_c * const public_key_x,
+	const eap_variable_data_c * const public_key_y)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_create_ecdh_temporary_keys(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::complete_create_ecdh_temporary_keys()");
+
+	eap_status_e status(eap_status_not_supported);
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("private_key_d"),
+		 private_key_d->get_data(),
+		 private_key_d->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("public_key_x"),
+		 public_key_x->get_data(),
+		 public_key_x->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("public_key_y"),
+		 public_key_y->get_data(),
+		 public_key_y->get_data_length()));
+
+	
+#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == false
+		&& m_wapi_state == wapi_core_state_process_access_authentication_request_message_ASU_signature_trusted_by_AE)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Save ECDH keys.
+
+		// We do not use the new keys. Only the first generated keys.
+		if (m_own_private_key_d.get_is_valid_data() == false
+			|| m_own_public_key_x.get_is_valid_data() == false
+			|| m_own_public_key_y.get_is_valid_data() == false)
+		{
+			status = m_own_private_key_d.set_copy_of_buffer(private_key_d);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_own_public_key_x.set_copy_of_buffer(public_key_x);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_own_public_key_y.set_copy_of_buffer(public_key_y);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create temporary ECDH keys.
+
+		status = m_ec_certificate_store->create_ecdh(
+			&m_own_private_key_d,
+			&m_peer_public_key_x,
+			&m_peer_public_key_y);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+	}
+	else
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == true
+		&& m_wapi_state == wapi_core_state_process_authentication_activation_message)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Save ECDH keys.
+
+		// We do not use the new keys. Only the first generated keys.
+		if (m_own_private_key_d.get_is_valid_data() == false
+			|| m_own_public_key_x.get_is_valid_data() == false
+			|| m_own_public_key_y.get_is_valid_data() == false)
+		{
+			status = m_own_private_key_d.set_copy_of_buffer(private_key_d);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_own_public_key_x.set_copy_of_buffer(public_key_x);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_own_public_key_y.set_copy_of_buffer(public_key_y);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create the Access Authentication Request Packet.
+
+		m_new_payloads.reset();
+
+		if (m_new_payloads.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = m_new_payloads.initialise_header();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_new_payloads.get_wai_protocol_packet_header_writable()->set_subtype(wai_protocol_subtype_access_authentication_request);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds FLAG to data field.
+
+		{
+			wai_variable_data_c data_flag(m_am_tools);
+			if (data_flag.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			u8_t flag(wai_data_flag_mask_none | wai_data_flag_mask_Certificate_Validation_Request);
+
+			if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+			{
+				flag = wai_data_flag_mask_BK_Rekeying;
+			}
+
+			status = data_flag.create(
+				wai_payload_type_flag,
+				&flag,
+				sizeof(flag));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_flag);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds Authentication Identifier to data field.
+
+		{
+			wai_variable_data_c data_authentication_identifier(m_am_tools);
+			if (data_authentication_identifier.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = data_authentication_identifier.create(
+				wai_payload_type_authentication_identifier,
+				&m_authentication_identifier);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_authentication_identifier);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds ASUE Challenge to data field.
+
+		{
+			wai_variable_data_c data_ASUE_challenge(m_am_tools);
+			if (data_ASUE_challenge.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = data_ASUE_challenge.create(
+				wai_payload_type_nonce,
+				&m_asue_certificate_challenge);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_ASUE_challenge);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds ASUE key data to data field.
+
+		{
+			wai_variable_data_c ASUE_key_data(m_am_tools);
+			if (ASUE_key_data.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			u8_t ec_point_type(WAI_EC_POINT_TYPE_NO_COMPRESSION_ID);
+
+			status = ASUE_key_data.create(
+				wai_payload_type_key_data,
+				&ec_point_type,
+				sizeof(ec_point_type));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = ASUE_key_data.add_data(
+				wai_payload_type_key_data,
+				&m_own_public_key_x);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = ASUE_key_data.add_data(
+				wai_payload_type_key_data,
+				&m_own_public_key_y);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&ASUE_key_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds ID of STA_AE to data field.
+
+		{
+			wai_variable_data_c data_id_of_ae(m_am_tools);
+			if (data_id_of_ae.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_ae_id"),
+				 m_ae_id.get_data(),
+				 m_ae_id.get_data_length()));
+
+			status = data_id_of_ae.create(
+				wai_payload_type_identity,
+				&m_ae_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_id_of_ae);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds STA_ASUE Certificate to data field.
+
+		{
+			wai_variable_data_c data_certificate(m_am_tools);
+			if (data_certificate.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = data_certificate.create(
+				wai_payload_type_certificate,
+				&m_own_certificate);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_certificate);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds ECDH parameter to data field.
+
+		{
+			wai_variable_data_c data_ecdh_parameter(m_am_tools);
+			if (data_ecdh_parameter.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = data_ecdh_parameter.create(
+				wai_payload_type_echd_parameter,
+				WAPI_ECDH_OID_PARAMETER,
+				sizeof(WAPI_ECDH_OID_PARAMETER));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_ecdh_parameter);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds optional ASU list trusted by ASUE. We do not add.
+
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create Signature of ASUE.
+
+		{
+			eap_variable_data_c HASH(m_am_tools);
+			if (HASH.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = create_HASH(&m_new_payloads, false, &HASH);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_asue_id"),
+				 m_asue_id.get_data(),
+				 m_asue_id.get_data_length()));
+
+			status = m_ec_certificate_store->create_signature_with_private_key(
+				&HASH,
+				&m_asue_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+bool wapi_core_c::compare_issuer_name(const eap_variable_data_c * const asue_id, const eap_variable_data_c * const ae_id)
+{
+	eap_variable_data_c asue_subject_name(m_am_tools);
+	eap_variable_data_c asue_issuer_name(m_am_tools);
+	eap_variable_data_c asue_sequence_number(m_am_tools);
+
+	if (asue_subject_name.get_is_valid() == false
+		|| asue_issuer_name.get_is_valid() == false
+		|| asue_sequence_number.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return false;
+	}
+
+	{
+		wapi_asn1_der_parser_c asue(m_am_tools);
+
+		if (asue.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			return false;
+		}
+
+		eap_status_e status = asue.decode(asue_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void) EAP_STATUS_RETURN(m_am_tools, status);
+			return false;
+		}
+
+		status = asue.get_wapi_identity(
+			&asue_subject_name,
+			&asue_issuer_name,
+			&asue_sequence_number);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void) EAP_STATUS_RETURN(m_am_tools, status);
+			return false;
+		}
+	}
+
+
+	eap_variable_data_c ae_subject_name(m_am_tools);
+	eap_variable_data_c ae_issuer_name(m_am_tools);
+	eap_variable_data_c ae_sequence_number(m_am_tools);
+
+	if (ae_subject_name.get_is_valid() == false
+		|| ae_issuer_name.get_is_valid() == false
+		|| ae_sequence_number.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return false;
+	}
+
+	{
+		wapi_asn1_der_parser_c ae(m_am_tools);
+
+		if (ae.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void) EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			return false;
+		}
+
+		eap_status_e status = ae.decode(ae_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void) EAP_STATUS_RETURN(m_am_tools, status);
+			return false;
+		}
+
+		status = ae.get_wapi_identity(
+			&ae_subject_name,
+			&ae_issuer_name,
+			&ae_sequence_number);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void) EAP_STATUS_RETURN(m_am_tools, status);
+			return false;
+		}
+	}
+
+	return asue_issuer_name.compare(&ae_issuer_name) == 0;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_core_c::complete_create_ecdh(
+	const eap_variable_data_c * const K_AB_x4,
+	const eap_variable_data_c * const K_AB_y4)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: this = 0x%08x, %s: wapi_core_c::complete_create_ecdh(): state=%s\n"),
+		 this,
+		 (m_is_client == true ? "client": "server"),
+		 wapi_strings_c::get_wapi_core_state_string(m_wapi_state)));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_core_c::complete_create_ecdh()");
+
+	eap_variable_data_c key(m_am_tools);
+	if (key.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("K_AB_x4"),
+		 K_AB_x4->get_data(),
+		 K_AB_x4->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("K_AB_y4"),
+		 K_AB_y4->get_data(),
+		 K_AB_y4->get_data_length()));
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// Only the x-coordinate is used in key generation.
+	status = key.set_copy_of_buffer(K_AB_x4);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// BK || Challenge seed = KD_HMAC_SHA256((yxP) abscissa, NONCE_AE || NONCE_ASUE || string label)
+
+	crypto_kd_hmac_sha256_c kd_hmac(m_am_tools);
+	if (kd_hmac.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_variable_data_c label(m_am_tools);
+	if (label.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = label.set_copy_of_buffer(&m_ae_certificate_challenge);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = label.add_data(&m_asue_certificate_challenge);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = label.add_data(WAPI_CERTIFICATE_KEY_LABEL, WAPI_CERTIFICATE_KEY_LABEL_LENGTH);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	eap_variable_data_c bk_challenge_seed(m_am_tools);
+	if (bk_challenge_seed.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = kd_hmac.expand_key(
+		&bk_challenge_seed,
+		WAPI_BK_LENGTH + WAPI_CHALLENGE_SEED_LENGTH,
+		&key,
+		&label);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	status = m_BK.set_copy_of_buffer(
+		bk_challenge_seed.get_data(WAPI_BK_LENGTH),
+		WAPI_BK_LENGTH);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	{
+		eap_variable_data_c next_challenge(m_am_tools);
+		if (next_challenge.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		crypto_sha_256_c sha_256(m_am_tools);
+		if (sha_256.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = sha_256.hash_init();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = sha_256.hash_update(
+			bk_challenge_seed.get_data_offset(WAPI_BK_LENGTH, WAPI_CHALLENGE_SEED_LENGTH),
+			WAPI_CHALLENGE_SEED_LENGTH);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		u32_t md_length(sha_256.get_digest_length());
+
+		status = m_authentication_identifier.set_buffer_length(md_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_authentication_identifier.set_data_length(md_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = sha_256.hash_final(
+			m_authentication_identifier.get_data(),
+			&md_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("next local m_authentication_identifier"),
+			 m_authentication_identifier.get_data(),
+			 m_authentication_identifier.get_data_length()));
+	}
+
+#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == false
+		&& m_wapi_state == wapi_core_state_process_access_authentication_request_message_ASU_signature_trusted_by_AE)
+	{
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create the Access Authentication Request Packet.
+
+		m_new_payloads.reset();
+
+		if (m_new_payloads.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = m_new_payloads.initialise_header();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_new_payloads.get_wai_protocol_packet_header_writable()->set_subtype(wai_protocol_subtype_access_authentication_response);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds FLAG to data field.
+
+		{
+			wai_variable_data_c data_flag(m_am_tools);
+			if (data_flag.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			u8_t flag(wai_data_flag_mask_none | wai_data_flag_mask_Optional_Field | wai_data_flag_mask_Certificate_Validation_Request);
+
+			if (m_wapi_negotiation_state == wapi_negotiation_state_rekeying)
+			{
+				flag = wai_data_flag_mask_BK_Rekeying;
+			}
+
+			status = data_flag.create(
+				wai_payload_type_flag,
+				&flag,
+				sizeof(flag));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_flag);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds ASUE Challenge to data field.
+
+		{
+			wai_variable_data_c data_ASUE_challenge(m_am_tools);
+			if (data_ASUE_challenge.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = data_ASUE_challenge.create(
+				wai_payload_type_nonce,
+				&m_asue_certificate_challenge);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_ASUE_challenge);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds AE Challenge to data field.
+
+		{
+			wai_variable_data_c data_AE_challenge(m_am_tools);
+			if (data_AE_challenge.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = data_AE_challenge.create(
+				wai_payload_type_nonce,
+				&m_ae_certificate_challenge);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_AE_challenge);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds Access Result to data field.
+
+		{
+			wai_variable_data_c data_AE_challenge(m_am_tools);
+			if (data_AE_challenge.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			wapi_access_result_e result(wapi_access_result_successfull_access);
+
+			status = data_AE_challenge.create(
+				wai_payload_type_access_result,
+				&result,
+				sizeof(result));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_AE_challenge);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds ASUE key data to data field.
+
+		{
+			wai_variable_data_c ASUE_key_data(m_am_tools);
+			if (ASUE_key_data.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			u8_t ec_point_type(WAI_EC_POINT_TYPE_NO_COMPRESSION_ID);
+
+			status = ASUE_key_data.create(
+				wai_payload_type_key_data,
+				&ec_point_type,
+				sizeof(ec_point_type));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = ASUE_key_data.add_data(
+				wai_payload_type_key_data,
+				&m_peer_public_key_x);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = ASUE_key_data.add_data(
+				wai_payload_type_key_data,
+				&m_peer_public_key_y);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&ASUE_key_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds AE key data to data field.
+
+		{
+			wai_variable_data_c ASUE_key_data(m_am_tools);
+			if (ASUE_key_data.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			u8_t ec_point_type(WAI_EC_POINT_TYPE_NO_COMPRESSION_ID);
+
+			status = ASUE_key_data.create(
+				wai_payload_type_key_data,
+				&ec_point_type,
+				sizeof(ec_point_type));
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = ASUE_key_data.add_data(
+				wai_payload_type_key_data,
+				&m_own_public_key_x);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = ASUE_key_data.add_data(
+				wai_payload_type_key_data,
+				&m_own_public_key_y);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&ASUE_key_data);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds ID of STA_AE to data field.
+
+		{
+			wai_variable_data_c data_id_of_ae(m_am_tools);
+			if (data_id_of_ae.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_ae_id"),
+				 m_ae_id.get_data(),
+				 m_ae_id.get_data_length()));
+
+			status = data_id_of_ae.create(
+				wai_payload_type_identity,
+				&m_ae_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_id_of_ae);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds ID of STA_ASUE to data field.
+
+		{
+			wai_variable_data_c data_id_of_asue(m_am_tools);
+			if (data_id_of_asue.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_asue_id"),
+				 m_asue_id.get_data(),
+				 m_asue_id.get_data_length()));
+
+			status = data_id_of_asue.create(
+				wai_payload_type_identity,
+				&m_asue_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&data_id_of_asue);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Adds Multiple Certificate Verification Result to data field.
+
+		if (m_do_certificate_validation == true)
+		{
+			status = m_new_payloads.add_tlv(&m_result_of_certificate_verification);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			status = m_new_payloads.add_tlv(&m_server_signature_trusted_by_asue);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			if (compare_issuer_name(&m_asu_id, &m_ae_id) == false)
+			{
+				status = m_new_payloads.add_tlv(&m_server_signature_trusted_by_ae);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+		}
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// Create Signature of AE.
+
+		{
+			eap_variable_data_c HASH(m_am_tools);
+			if (HASH.get_is_valid() == false)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			status = create_HASH(&m_new_payloads, true, &HASH);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("m_asue_id"),
+				 m_asue_id.get_data(),
+				 m_asue_id.get_data_length()));
+
+			set_wapi_state(wapi_core_state_process_access_authentication_request_message_AE_signature_trusted_by_ASUE);
+
+			status = m_ec_certificate_store->create_signature_with_private_key(
+				&HASH,
+				&m_ae_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+	else
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == true
+		&& m_wapi_state == wapi_core_state_process_access_authentication_response_message_ASU_signature)
+	{
+		set_wapi_state(wapi_core_state_wait_unicast_key_negotiation_request_message);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_core_retransmission.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,206 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_core_retransmission.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 10 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 47 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+
+#include "eap_am_memory.h"
+#include "eap_tools.h"
+#include "eap_am_export.h"
+#include "abs_eap_base_timer.h"
+#include "wapi_core_retransmission.h"
+#include "eap_am_network_id.h"
+#include "wai_message.h"
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_core_retransmission_c::~wapi_core_retransmission_c()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	delete m_send_network_id;
+	m_send_network_id = 0;
+
+	delete m_wai_message_data;
+	m_wai_message_data = 0;
+
+	delete m_wai_received_message_data;
+	m_wai_received_message_data = 0;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_core_retransmission_c::wapi_core_retransmission_c(
+	abs_eap_am_tools_c * const tools,
+	const eap_am_network_id_c * const send_network_id,
+	const wai_message_c * const received_wai_message_data_or_null,
+	const wai_message_c * const wai_message_data,
+	const u32_t retransmission_time,
+	const u32_t retransmission_counter,
+	const u16_t packet_sequence_number,
+	const wai_protocol_subtype_e wapi_subtype)
+	: m_am_tools(tools)
+	, m_send_network_id(send_network_id->copy())
+	, m_wai_message_data(wai_message_data->copy())
+	, m_wai_received_message_data(0)
+	, m_is_valid(false)
+	, m_retransmission_time(retransmission_time)
+	, m_retransmission_counter(retransmission_counter)
+	, m_packet_sequence_number(packet_sequence_number)
+	, m_wapi_subtype(wapi_subtype)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	//EAP_ASSERT(m_send_network_id->get_source() != 0);
+	//EAP_ASSERT(m_send_network_id->get_destination() != 0);
+
+	if (received_wai_message_data_or_null != 0)
+	{
+		m_wai_received_message_data = received_wai_message_data_or_null->copy();
+	}
+
+	if (m_send_network_id != 0
+		&& m_wai_message_data != 0
+		&& m_wai_message_data->get_is_valid() == true)
+	{
+		m_is_valid = true;
+	}
+	else
+	{
+		delete m_send_network_id;
+		m_send_network_id = 0;
+
+		delete m_wai_message_data;
+		m_wai_message_data = 0;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool wapi_core_retransmission_c::get_is_valid() const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wapi_core_retransmission_c::get_next_retransmission_counter()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return --m_retransmission_counter;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wapi_core_retransmission_c::get_retransmission_counter() const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_retransmission_counter;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wapi_core_retransmission_c::get_next_retransmission_time()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	u32_t time = m_retransmission_time;
+
+	u32_t jitter_data = 0ul;
+	i32_t jitter = 0;
+	eap_status_e status = m_am_tools->get_crypto()->get_rand_bytes(
+		reinterpret_cast<u8_t *>(&jitter_data),
+		sizeof(jitter_data));
+	if (status != eap_status_ok)
+	{
+		jitter = 0;
+	}
+	else
+	{
+		// Jitter should be -m_retransmission_time/2 ... m_retransmission_time/2.
+		jitter_data = (jitter_data % (m_retransmission_time));
+		jitter = jitter_data - m_retransmission_time/2;
+	}
+	m_retransmission_time += (m_retransmission_time + jitter);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return time;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_am_network_id_c *wapi_core_retransmission_c::get_send_network_id() const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_send_network_id;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const wai_message_c * wapi_core_retransmission_c::get_wai_message_data() const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_wai_message_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u16_t wapi_core_retransmission_c::get_packet_sequence_number() const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_packet_sequence_number;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT const wai_message_c * wapi_core_retransmission_c::get_wai_received_message_data() const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_wai_received_message_data;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wai_protocol_subtype_e wapi_core_retransmission_c::get_wapi_subtype() const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_wapi_subtype;
+}
+
+//--------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_ethernet_core.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,840 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_ethernet_core.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 15.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 20003
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+
+#include "eap_am_memory.h"
+#include "eap_variable_data.h"
+#include "eap_tools.h"
+#include "wapi_ethernet_core.h"
+#include "eapol_ethernet_header.h"
+#include "eap_buffer.h"
+#include "eapol_session_key.h"
+#include "eap_automatic_variable.h"
+
+#include "abs_eap_am_mutex.h"
+
+
+//--------------------------------------------------
+
+// 
+EAP_FUNC_EXPORT wapi_ethernet_core_c::~wapi_ethernet_core_c()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_ethernet_core_c::~wapi_ethernet_core_c(): this = 0x%08x\n"),
+		this));
+
+	EAP_ASSERT(m_shutdown_was_called == true);
+
+	delete m_wapi_core;
+	m_wapi_core=0;
+
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+#if defined(_WIN32) && !defined(__GNUC__)
+	#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
+#endif
+
+// 
+EAP_FUNC_EXPORT wapi_ethernet_core_c::wapi_ethernet_core_c(
+	abs_eap_am_tools_c * const tools,
+	abs_wapi_ethernet_core_c * const partner,
+	const bool is_client_when_true)
+: m_partner(partner)
+, m_wapi_core(new wapi_session_core_c(tools, this, is_client_when_true))
+, m_am_tools(tools)
+, m_is_client(is_client_when_true)
+, m_is_valid(false)
+, m_shutdown_was_called(false)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_ethernet_core_c::wapi_ethernet_core_c(): %s, this = 0x%08x, compiled %s %s.\n"),
+		(m_is_client == true) ? "client": "server",
+		this,
+		__DATE__,
+		__TIME__));
+
+	if (m_wapi_core != 0
+		&& m_wapi_core->get_is_valid() == true)
+	{
+		set_is_valid();
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::packet_process(
+	const eap_am_network_id_c * const /* receive_network_id */,
+	eap_general_header_base_c * const packet_data,
+	const u32_t packet_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	eap_status_e status = eap_status_process_general_error;
+
+	EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("####################################################################\n")));
+
+	if (m_wapi_core == 0)
+	{
+		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("####################################################################\n")));
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	if (packet_length < eapol_ethernet_header_rd_c::get_header_length())
+	{
+		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("####################################################################\n")));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	eapol_ethernet_header_wr_c eth_header(
+		m_am_tools,
+		packet_data->get_header_buffer(packet_data->get_header_buffer_length()),
+		packet_data->get_header_buffer_length());
+
+	if (eth_header.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	if (packet_length < eth_header.get_data_length())
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	EAP_TRACE_ALWAYS(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("-> ETHERNET: %s: type=0x%04x, packet_length 0x%04x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 eth_header.get_type(),
+		 packet_length));
+
+	if (m_is_client == true)
+	{
+		EAP_TRACE_DATA_ALWAYS(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+			(EAPL("-> ETHERNET packet client"),
+			 eth_header.get_header_buffer(eth_header.get_header_buffer_length()),
+			 packet_length));
+	}
+	else
+	{
+		EAP_TRACE_DATA_ALWAYS(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+			(EAPL("-> ETHERNET packet server"),
+			 eth_header.get_header_buffer(eth_header.get_header_buffer_length()),
+			 packet_length));
+	}
+
+	if (eth_header.get_type() == eapol_ethernet_type_wapi)
+	{
+		eap_am_network_id_c receive_network_id(
+			m_am_tools,
+			eth_header.get_source(),
+			eth_header.get_source_length(),
+			eth_header.get_destination(),
+			eth_header.get_destination_length(),
+			eth_header.get_type(),
+			false,
+			false);
+
+		eapol_header_wr_c eapol(
+			m_am_tools,
+			eth_header.get_eapol_header(),
+			eth_header.get_data_length());
+		if (eapol.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+		}
+
+		status = m_wapi_core->packet_process(
+			&receive_network_id,
+			&eapol,
+			packet_length-eapol_ethernet_header_rd_c::get_header_length());
+
+		EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eapol);
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Not WAPI supported ethernet type 0x%04x\n"), eth_header.get_type()));
+		status = eap_status_ethernet_type_not_supported;
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("####################################################################\n")));
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::packet_send(
+	const eap_am_network_id_c * const send_network_id,
+	eap_buf_chain_wr_c * const sent_packet,
+	const u32_t header_offset,
+	const u32_t data_length,
+	const u32_t buffer_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(header_offset < sent_packet->get_data_length());
+	EAP_ASSERT(data_length <= sent_packet->get_data_length());
+	EAP_ASSERT(sent_packet->get_data_length() <= buffer_length);
+
+	if (send_network_id->get_is_valid_data() == false)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	if (header_offset < eapol_ethernet_header_wr_c::get_header_length())
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("packet_send: packet buffer corrupted.\n")));
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+	}
+
+	// ****
+	// TODO: Check these header types for WAPI
+	eapol_ethernet_header_wr_c eth(
+		m_am_tools,
+		sent_packet->get_data_offset(
+			header_offset-eapol_ethernet_header_wr_c::get_header_length(),
+			eapol_ethernet_header_wr_c::get_header_length()),
+		eapol_ethernet_header_wr_c::get_header_length());
+
+	if (eth.get_is_valid() == false)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("packet_send: packet buffer corrupted.\n")));
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+	}
+
+
+	eth.set_type(static_cast<eapol_ethernet_type_e>(send_network_id->get_type()));
+
+	m_am_tools->memmove(
+		eth.get_destination(),
+		send_network_id->get_destination(),
+		send_network_id->get_destination_length());
+
+	m_am_tools->memmove(
+		eth.get_source(),
+		send_network_id->get_source(),
+		send_network_id->get_source_length());
+
+
+	EAP_TRACE_ALWAYS(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("<- ETHERNET: %s: type=0x%04x, packet_length 0x%04x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 eth.get_type(),
+		 data_length));
+
+	if (m_is_client == true)
+	{
+		EAP_TRACE_DATA_ALWAYS(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+			(EAPL("<- ETHERNET packet client"),
+			 eth.get_header_buffer(eth.get_header_buffer_length()),
+			 data_length+eapol_ethernet_header_wr_c::get_header_length()));
+	}
+	else
+	{
+		EAP_TRACE_DATA_ALWAYS(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+			(EAPL("<- ETHERNET packet server"),
+			 eth.get_header_buffer(eth.get_header_buffer_length()),
+			 data_length+eapol_ethernet_header_wr_c::get_header_length()));
+	}
+
+	sent_packet->set_is_client(m_is_client);
+
+	eap_status_e status = m_partner->packet_send(
+		send_network_id,
+		sent_packet,
+		header_offset-eapol_ethernet_header_wr_c::get_header_length(),
+		data_length+eapol_ethernet_header_wr_c::get_header_length(),
+		buffer_length);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT u32_t wapi_ethernet_core_c::get_header_offset(
+	u32_t * const MTU,
+	u32_t * const trailer_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// ****
+	// TODO: Check these for WAPI
+	const u32_t offset = m_partner->get_header_offset(MTU, trailer_length);
+	(*MTU) -= eapol_ethernet_header_wr_c::get_header_length();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return offset+eapol_ethernet_header_wr_c::get_header_length();
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::start_authentication(
+	const eap_am_network_id_c * const receive_network_id,
+	const bool is_client_when_true)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	if (m_wapi_core == 0)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = m_wapi_core->restart_authentication(receive_network_id, is_client_when_true, true);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::start_reassociation(
+	const eap_am_network_id_c * const receive_network_id,
+	const eapol_key_authentication_type_e authentication_type,
+	const eap_variable_data_c * const BKID)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status(eap_status_not_supported);
+
+// ****
+// TODO: Is this needed in WAPI?
+#if 0
+	status = m_eapol_core->start_reassociation(
+		receive_network_id,
+		authentication_type,
+		BKID);
+#endif
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::read_reassociation_parameters(
+	const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address.
+	const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address.
+	const eapol_key_authentication_type_e authentication_type,
+	eap_variable_data_c * const BKID,
+	const eap_variable_data_c * const received_WAPI_ie,
+	const eap_variable_data_c * const sent_WAPI_ie)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_ethernet_core_c::read_reassociation_parameters()\n")));
+
+	if (m_wapi_core == 0)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_status_e status = m_wapi_core->read_reassociation_parameters(
+		old_receive_network_id,
+		new_receive_network_id,
+		authentication_type,
+		BKID,
+		received_WAPI_ie,
+		sent_WAPI_ie);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::complete_reassociation(
+	const eapol_wlan_authentication_state_e reassociation_result,
+	const eap_am_network_id_c * const receive_network_id,
+	const eapol_key_authentication_type_e authentication_type,
+	const eap_variable_data_c * const received_WAPI_IE,
+	const eap_variable_data_c * const sent_WAPI_IE,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status(eap_status_not_supported);
+
+	//***
+	// TODO: Support for this needs to be added to wapi_core_c
+	/*
+	status = m_wapi_core->complete_reassociation(
+		reassociation_result,
+		receive_network_id,
+		authentication_type,
+		received_WAPI_IE,
+		sent_WAPI_IE,
+		pairwise_key_cipher_suite,
+		group_key_cipher_suite);
+	*/
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void wapi_ethernet_core_c::set_is_valid()
+{
+	m_is_valid = true;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT bool wapi_ethernet_core_c::get_is_valid()
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::configure()
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_ethernet_core_c::configure()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_ethernet_core_c::configure()");
+
+	eap_status_e status = m_wapi_core->configure();
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::shutdown()
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("%s: wapi_ethernet_core_c::shutdown(), m_shutdown_was_called=%d\n"),
+		(m_is_client == true) ? "client": "server",
+		m_shutdown_was_called));
+
+	if (m_shutdown_was_called == true)
+	{
+		// Shutdown function was called already.
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	m_shutdown_was_called = true;
+
+	eap_status_e status(eap_status_ok);
+
+	if (m_wapi_core != 0)
+	{
+		status = m_wapi_core->shutdown();
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::packet_data_session_key(
+	const eap_am_network_id_c * const send_network_id,
+	const eapol_session_key_c * const key)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	if (key == 0
+		|| key->get_is_valid() == false)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ERROR: wapi_ethernet_core_c::packet_data_session_key(), invalid key.\n")));
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_ethernet_core_c::packet_data_session_key(): key_type 0x%02x, key_index %d\n"),
+		key->get_key_type(),
+		key->get_key_index()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_ethernet_core_c::packet_data_session_key():"),
+		key->get_key()->get_data(key->get_key()->get_data_length()),
+		key->get_key()->get_data_length()));
+
+	const eap_status_e status = m_partner->packet_data_session_key(
+		send_network_id,
+		key);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::read_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	const eap_status_e status = m_partner->read_configure(field, data);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::write_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	const eap_status_e status = m_partner->write_configure(field, data);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void wapi_ethernet_core_c::state_notification(
+	const abs_eap_state_notification_c * const state)
+{
+	m_partner->state_notification(state);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::set_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id, 
+	void * const p_data,
+	const u32_t p_time_ms)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->set_timer(
+		p_initializer, 
+		p_id, 
+		p_data,
+		p_time_ms);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::cancel_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->cancel_timer(
+		p_initializer, 
+		p_id);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::cancel_all_timers()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->cancel_all_timers();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::cancel_all_authentication_sessions()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_ethernet_core_c::cancel_all_authentication_sessions()\n")));
+
+	eap_status_e status = m_wapi_core->cancel_all_authentication_sessions();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::check_bksa_cache(
+	eap_array_c<eap_am_network_id_c> * const bssid_sta_receive_network_ids,
+	const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_ethernet_core_c::check_bksa_cache()\n")));
+
+	eap_status_e status = m_wapi_core->check_bksa_cache(
+		bssid_sta_receive_network_ids,
+		selected_eapol_key_authentication_type,
+		pairwise_key_cipher_suite,
+		group_key_cipher_suite);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+/**
+ * This function removes BKSA from cache.
+ * @param receive_network_id carries the MAC addresses.
+ * MAC address of Authenticator should be in source address.
+ * MAC address of Supplicant should be in destination address.
+ */
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::remove_bksa_from_cache(
+	const eap_am_network_id_c * const receive_network_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_ethernet_core_c::remove_bksa_from_cache()\n")));
+
+	eap_status_e status = m_wapi_core->remove_bksa_from_cache(
+		receive_network_id);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+/**
+ * Function creates a state for later use. This is for optimazing 4-Way Handshake.
+ * @param receive_network_id carries the MAC addresses.
+ * MAC address of Authenticator should be in source address. MAC address of 
+ * Supplicant should be in destination address.
+ * @param authentication_type is the selected authentication type.
+ */
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::create_state(
+	const eap_am_network_id_c * const receive_network_id,
+	const eapol_key_authentication_type_e authentication_type
+	)
+{
+	eap_status_e status = eap_status_process_general_error;
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	status = m_wapi_core->create_state(
+		receive_network_id,
+		authentication_type);
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+
+//--------------------------------------------------
+
+/**
+ * @param receive_network_id carries the MAC addresses.
+ * MAC address of Authenticator should be in source address. MAC address of Supplicant should be in destination address.
+ * @param authenticator_RSNA_IE is RSN IE of authenticator. Authenticator sends this in Beacon or Probe message.
+ * @param supplicant_RSNA_IE is RSN IE of supplicant. Supplicant sends this in (re)association request message.
+ * @param eapol_pairwise_cipher is the selected pairwise cipher.
+ * @param eapol_group_cipher is the selected group cipher.
+ */
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::association(
+	const eap_am_network_id_c * const receive_network_id,
+	const eapol_key_authentication_type_e authentication_type,
+	const eap_variable_data_c * const wapi_ie_ae,
+	const eap_variable_data_c * const wapi_ie_asue,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher,
+	const eap_variable_data_c * const pre_shared_key
+	)
+{
+	eap_status_e status = eap_status_process_general_error;
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	status = m_wapi_core->association(
+		receive_network_id,
+		authentication_type,
+		wapi_ie_ae,
+		wapi_ie_asue,
+		eapol_pairwise_cipher,
+		eapol_group_cipher,
+		pre_shared_key);
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+
+//--------------------------------------------------
+
+/**
+ * @param receive_network_id carries the MAC addresses.
+ * MAC address of Authenticator should be in source address. MAC address of Supplicant should be in destination address.
+ */
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::disassociation(
+	const eap_am_network_id_c * const receive_network_id
+	)
+{
+	eap_status_e status = eap_status_process_general_error;
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	status = m_wapi_core->disassociation(
+		receive_network_id);
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::restart_authentication(
+	const eap_am_network_id_c * const receive_network_id,
+	const bool is_client_when_true,
+	const bool force_clean_restart,
+	const bool from_timer
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	eap_status_e status = m_wapi_core->restart_authentication(
+		receive_network_id,
+		is_client_when_true,
+		force_clean_restart,
+		from_timer);
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::asynchronous_init_remove_wapi_session(
+	const eap_am_network_id_c * const send_network_id
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+}
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_ethernet_core_c::set_session_timeout(
+	const u32_t session_timeout_ms
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+}
+
+//--------------------------------------------------
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_message_wlan_authentication.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,2354 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_message_wlan_authentication.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 8.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 20000 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#include "wapi_message_wlan_authentication.h"
+#include "eapol_wlan_database_reference.h"
+#include "eap_am_memory.h"
+#include "abs_eap_state_notification.h"
+#include "eap_crypto_api.h"
+// #include "eap_header_string.h"
+#include "eap_buffer.h"
+#include "eapol_session_key.h"
+#include "eapol_handle_tlv_message_data.h"
+#include "eap_automatic_variable.h"
+#include "eap_array_algorithms.h"
+#include "eap_config.h"
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE wapi_message_wlan_authentication_c::~wapi_message_wlan_authentication_c()
+{
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE wapi_message_wlan_authentication_c::wapi_message_wlan_authentication_c(
+	abs_eap_am_tools_c * const tools,
+	abs_wapi_message_wlan_authentication_c * const partner)
+	: m_am_tools(tools)
+	, m_wauth(0)
+	, m_partner(partner)
+	, m_wlan_database_reference(tools)
+	, m_header_offset(0ul)
+	, m_MTU(0ul)
+	, m_trailer_length(0ul)
+	, m_error_code(wlan_eap_if_send_status_ok)
+	, m_error_function(eapol_tlv_message_type_function_none)
+	, m_is_valid(true)
+{
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE eap_status_e wapi_message_wlan_authentication_c::configure(
+	const u32_t header_offset,
+	const u32_t MTU,
+	const u32_t trailer_length)
+{
+	eap_status_e status(eap_status_ok);
+
+	//----------------------------------------------------------
+
+	m_header_offset = header_offset;
+	m_MTU = MTU;
+	m_trailer_length = trailer_length;
+
+	//----------------------------------------------------------
+
+	// wapi_wlan_authentication_c object uses the tools object.
+	m_wauth = wapi_wlan_authentication_c::new_wapi_wlan_authentication(
+		m_am_tools,
+		this,
+		true,
+		this);
+	if (m_wauth != 0
+		&& m_wauth->get_is_valid() == true)
+	{
+		status = m_wauth->configure();
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE eap_status_e wapi_message_wlan_authentication_c::shutdown()
+{
+	// After use the wapi_wlan_authentication_c object must be deleted first.
+	if (m_wauth != 0)
+	{
+		m_wauth->shutdown();
+		delete m_wauth;
+		m_wauth = 0;
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE bool wapi_message_wlan_authentication_c::get_is_valid()
+{
+	return m_is_valid;
+}
+
+// ----------------------------------------------------------------
+
+// 
+EAP_FUNC_EXPORT_INTERFACE eap_status_e wapi_message_wlan_authentication_c::timer_expired(
+	const u32_t id, void *data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("TIMER: [0x%08x]->wapi_message_wlan_authentication_c::timer_expired")
+		 EAPL("(id 0x%02x, data 0x%08x).\n"),
+		 this, id, data));
+		 
+	EAP_UNREFERENCED_PARAMETER(id);
+	EAP_UNREFERENCED_PARAMETER(data);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return eap_status_ok;
+}
+
+// ----------------------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE eap_status_e wapi_message_wlan_authentication_c::timer_delete_data(
+	const u32_t id, void * data)
+{
+
+	EAP_UNREFERENCED_PARAMETER(id);
+	EAP_UNREFERENCED_PARAMETER(data);
+
+	return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE eap_status_e wapi_message_wlan_authentication_c::packet_send(
+	const eap_am_network_id_c * const send_network_id,
+	eap_buf_chain_wr_c * const sent_packet,
+	const u32_t header_offset,
+	const u32_t data_length,
+	const u32_t buffer_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status(eap_status_ok);
+
+	if (sent_packet->get_do_length_checks() == true)
+	{
+		if (header_offset != m_header_offset)
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: wapi_message_wlan_authentication_c::packet_send: packet buffer corrupted (header_offset != %d).\n"),
+				m_header_offset));
+			EAP_ASSERT_ALWAYS(header_offset == m_header_offset);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+		else if (header_offset+data_length != sent_packet->get_data_length())
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: wapi_message_wlan_authentication_c::packet_send: packet buffer corrupted ")
+				 EAPL("(data_length %d != sent_packet->get_data_length() %d).\n"),
+				 header_offset+data_length,
+				 sent_packet->get_data_length()));
+			EAP_ASSERT_ALWAYS(data_length == sent_packet->get_buffer_length());
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+		else if (header_offset+data_length > buffer_length)
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: wapi_message_wlan_authentication_c::packet_send: packet buffer corrupted ")
+				 EAPL("(header_offset+data_length %d > buffer_length %d).\n"),
+				 header_offset+data_length,
+				 buffer_length));
+			EAP_ASSERT_ALWAYS(header_offset+data_length <= buffer_length);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+		else if (header_offset+data_length > m_MTU)
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: wapi_message_wlan_authentication_c::packet_send: packet buffer corrupted ")
+				 EAPL("(header_offset+data_length %d > m_MTU %d).\n"),
+				 header_offset+data_length,
+				 m_MTU));
+			EAP_ASSERT_ALWAYS(header_offset+data_length <= m_MTU);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}
+	}
+	else
+	{
+		// Always we need at least the Ethernet header.
+		if (sent_packet->get_data_length()
+			< eapol_ethernet_header_wr_c::get_header_length())
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: wapi_message_wlan_authentication_c::packet_send: packet buffer corrupted ")
+				 EAPL("(sent_packet->get_data_length() %d < ")
+				 EAPL("eapol_ethernet_header_wr_c::get_header_length() %d).\n"),
+				 sent_packet->get_data_length(),
+				 eapol_ethernet_header_wr_c::get_header_length()));
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+		}		
+	}
+	
+	eapol_ethernet_header_wr_c eth(
+		m_am_tools,
+		sent_packet->get_data_offset(header_offset, data_length),
+		data_length);
+		
+	if (eth.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+	}
+	
+	{
+		// Creates message data composed of Attribute-Value Pairs.
+		eapol_handle_tlv_message_data_c message(m_am_tools);
+
+		if (message.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message.add_parameter_data(eapol_tlv_message_type_function_packet_send);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = message.add_parameter_data(send_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = message.add_parameter_data(sent_packet);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = send_message(&message);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE u32_t wapi_message_wlan_authentication_c::get_header_offset(
+	u32_t * const MTU,
+	u32_t * const trailer_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// Header of this module is in the beginning of the buffer
+	// no additional header are used.
+	*MTU = m_MTU;
+	*trailer_length = m_trailer_length;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_header_offset;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE eap_status_e wapi_message_wlan_authentication_c::associate(
+	eapol_key_802_11_authentication_mode_e authentication_mode )
+{
+	eap_status_e status(eap_status_ok);
+
+	{
+		// Creates message data composed of Attribute-Value Pairs.
+		eapol_handle_tlv_message_data_c message(m_am_tools);
+
+		if (message.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message.add_parameter_data(eapol_tlv_message_type_function_associate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = message.add_parameter_data(
+			eapol_tlv_message_type_eapol_key_802_11_authentication_mode, 
+			static_cast<u32_t>(authentication_mode));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = send_message(&message);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE eap_status_e wapi_message_wlan_authentication_c::disassociate(
+	const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+	const bool self_disassociation)
+{
+	eap_status_e status(eap_status_ok);
+
+	{
+		// Creates message data composed of Attribute-Value Pairs.
+		eapol_handle_tlv_message_data_c message(m_am_tools);
+
+		if (message.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message.add_parameter_data(eapol_tlv_message_type_function_disassociate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = message.add_parameter_data(receive_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = message.add_parameter_data(self_disassociation);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = send_message(&message);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE eap_status_e wapi_message_wlan_authentication_c::packet_data_session_key(
+	const eap_am_network_id_c * const send_network_id,
+	const eapol_session_key_c * const key)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	
+	eap_status_e status(eap_status_ok);
+
+	if (key == 0
+		|| key->get_is_valid() == false)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ERROR: wapi_message_wlan_authentication_c::packet_data_session_key(), invalid key.\n")));
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+	}
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_message_wlan_authentication_c::packet_data_session_key(): key_type 0x%02x, key_index %d\n"),
+		 key->get_key_type(),
+		 key->get_key_index()));
+	
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_message_wlan_authentication_c::packet_data_session_key"), 
+		 key->get_key()->get_data(key->get_key()->get_data_length()),
+		 key->get_key()->get_data_length()));
+	
+	{
+		// Creates message data composed of Attribute-Value Pairs.
+		eapol_handle_tlv_message_data_c message(m_am_tools);
+
+		if (message.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message.add_parameter_data(eapol_tlv_message_type_function_packet_data_session_key);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = message.add_parameter_data(send_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// ****
+		// TODO: This needs to be checked for WAPI keys,
+		// may need modifications
+		status = message.add_parameter_data(key);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = send_message(&message);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE void wapi_message_wlan_authentication_c::state_notification(
+	const abs_eap_state_notification_c * const state)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status(eap_status_ok);
+
+	{
+		// Creates message data composed of Attribute-Value Pairs.
+		eapol_handle_tlv_message_data_c message(m_am_tools);
+
+		if (message.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			return;
+		}
+
+		status = message.add_parameter_data(eapol_tlv_message_type_function_state_notification);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void)EAP_STATUS_RETURN(m_am_tools, status);
+			return;
+		}
+
+		status = message.add_parameter_data(state);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void)EAP_STATUS_RETURN(m_am_tools, status);
+			return;
+		}
+
+		status = send_message(&message);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			(void)EAP_STATUS_RETURN(m_am_tools, status);
+			return;
+		}
+	}
+	
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE eap_status_e wapi_message_wlan_authentication_c::reassociate(
+	const eap_am_network_id_c * const send_network_id,
+	const eapol_key_authentication_type_e authentication_type,
+	const eap_variable_data_c * const BKID)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status(eap_status_ok);
+
+	if (BKID == 0
+		|| BKID->get_is_valid() == false)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ERROR: wapi_message_wlan_authentication_c::reassociate(), invalid BKID.\n")));
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+	}
+	
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_message_wlan_authentication_c::reassociate"), 
+		 BKID->get_data(BKID->get_data_length()),
+		 BKID->get_data_length()));
+	
+	{
+		// Creates message data composed of Attribute-Value Pairs.
+		eapol_handle_tlv_message_data_c message(m_am_tools);
+
+		if (message.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message.add_parameter_data(eapol_tlv_message_type_function_reassociate);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = message.add_parameter_data(send_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = message.add_parameter_data(
+			eapol_tlv_message_type_eapol_key_authentication_type,
+			static_cast<u32_t>(authentication_type));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = message.add_parameter_data(BKID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = send_message(&message);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE eap_status_e wapi_message_wlan_authentication_c::get_wlan_database_reference_values(
+	eap_variable_data_c * const reference) const
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	if (m_wlan_database_reference.get_is_valid_data() == true
+		&& m_wlan_database_reference.get_data_length() > 0ul)
+	{
+
+		return reference->set_copy_of_buffer(&m_wlan_database_reference);
+	}
+	else
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ERROR: wapi_message_wlan_authentication_c::get_wlan_database_reference_values(): no complete parameters.\n")));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT)
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::send_error_message(
+	const eap_status_e function_status,
+	const eapol_tlv_message_type_function_e function)
+{
+	wlan_eap_if_send_status_e error_code = wlan_eap_if_send_status_conversion_c::convert(function_status);
+
+	eap_status_e status(eap_status_ok);
+
+	{
+		// Creates message data composed of Attribute-Value Pairs.
+		eapol_handle_tlv_message_data_c message(m_am_tools);
+
+		if (message.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message.add_parameter_data(
+			eapol_tlv_message_type_error,
+			static_cast<u32_t>(error_code));
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = message.add_parameter_data(function);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = send_message(&message);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::process_message_type_error(
+	EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters)
+{
+	eap_status_e status(eap_status_ok);
+
+	{
+		// Error payload is the first in this case.
+		const eap_tlv_header_c * const error_header = parameters->get_object(eapol_message_payload_index_function);
+
+		if (error_header == 0
+			|| error_header->get_type() != eapol_tlv_message_type_error)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(error_header, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		m_error_code = static_cast<wlan_eap_if_send_status_e>(value);
+	}
+
+	{
+		// Fuction payload is the second in this case.
+		const eap_tlv_header_c * const function_header = parameters->get_object(eapol_message_payload_index_first_parameter);
+
+		if (function_header == 0
+			|| function_header->get_type() != eapol_tlv_message_type_function)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(function_header, &m_error_function);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::send_message(eapol_handle_tlv_message_data_c * const message)
+{
+	// Sends message data composed of Attribute-Value Pairs.
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		EAP_TRACE_FLAGS_MESSAGE_DATA,
+		(EAPL("wapi_message_wlan_authentication_c::send_message()"),
+		message->get_message_data(),
+		message->get_message_data_length()));
+
+	{
+		wlan_eap_if_send_status_e send_status = m_partner->send_data(
+			message->get_message_data(),
+			message->get_message_data_length());
+		if (send_status != wlan_eap_if_send_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools,
+				wlan_eap_if_send_status_conversion_c::convert(send_status));
+		}
+
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools,
+			wlan_eap_if_send_status_conversion_c::convert(send_status));
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT_INTERFACE wlan_eap_if_send_status_e wapi_message_wlan_authentication_c::process_data(const void * const data, const u32_t length)
+{
+	// Parses message data composed of Attribute-Value Pairs.
+
+	eap_status_e status(eap_status_ok);
+
+	eapol_handle_tlv_message_data_c message(m_am_tools);
+
+	if (message.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+		status = eap_status_allocation_error;
+
+		(void) send_error_message(
+			status,
+			eapol_tlv_message_type_function_none);
+
+		return wlan_eap_if_send_status_conversion_c::convert(
+			EAP_STATUS_RETURN(m_am_tools, status));
+	}
+
+	status = message.set_message_data(length, data);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+		(void) send_error_message(
+			status,
+			eapol_tlv_message_type_function_none);
+
+		return wlan_eap_if_send_status_conversion_c::convert(
+			EAP_STATUS_RETURN(m_am_tools, status));
+	}
+
+	status = process_message(&message);
+
+	return wlan_eap_if_send_status_conversion_c::convert(
+		EAP_STATUS_RETURN(m_am_tools, status));
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::process_message(eapol_handle_tlv_message_data_c * const message)
+{
+	// Parses message data composed of Attribute-Value Pairs.
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		EAP_TRACE_FLAGS_MESSAGE_DATA,
+		(EAPL("wapi_message_wlan_authentication_c::process_message()"),
+		message->get_message_data(),
+		message->get_message_data_length()));
+
+	eap_array_c<eap_tlv_header_c> parameters(m_am_tools);
+
+	eap_status_e status = message->parse_message_data(&parameters);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+		(void) send_error_message(
+			status,
+			eapol_tlv_message_type_function_none);
+
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (parameters.get_object_count() == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+		status = eap_status_illegal_parameter;
+
+		(void) send_error_message(
+			status,
+			eapol_tlv_message_type_function_none);
+
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	const eap_tlv_header_c * const function_header = parameters.get_object(eapol_message_payload_index_function);
+	if (function_header == 0
+		|| (function_header->get_type() != eapol_tlv_message_type_error
+			&& function_header->get_type() != eapol_tlv_message_type_function))
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+		status = eap_status_illegal_parameter;
+
+		(void) send_error_message(
+			status,
+			eapol_tlv_message_type_function_none);
+
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	if (function_header->get_type() == eapol_tlv_message_type_error)
+	{
+		status = process_message_type_error(&parameters);
+	}
+	else // function_header->get_type() == eapol_tlv_message_type_function
+	{
+		eapol_tlv_message_type_function_e function(eapol_tlv_message_type_function_none);
+
+		status = message->get_parameter_data(function_header, &function);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+			(void) send_error_message(
+				status,
+				eapol_tlv_message_type_function_none);
+
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		switch(function)
+		{
+		// The interface uses the old EAPOL function name
+		// but in WAPI we are checking BKID here
+		case eapol_tlv_message_type_function_check_pmksa_cache:
+			status = check_bksa_cache(&parameters);
+			break;
+		case eapol_tlv_message_type_function_start_authentication:
+			status = start_authentication(&parameters);
+			break;
+		case eapol_tlv_message_type_function_complete_association:
+			status = complete_association(&parameters);
+			break;
+		case eapol_tlv_message_type_function_disassociation:
+			status = disassociation(&parameters);
+			break;
+		case eapol_tlv_message_type_function_start_reassociation:
+			status = start_reassociation(&parameters);
+			break;
+		case eapol_tlv_message_type_function_complete_reassociation:
+			status = complete_reassociation(&parameters);
+			break;
+		case eapol_tlv_message_type_function_packet_process:
+			status = packet_process(&parameters);
+			break;
+		case eapol_tlv_message_type_function_update_header_offset:
+			status = update_header_offset(&parameters);
+			break;
+		case eapol_tlv_message_type_function_update_wlan_database_reference_values:
+			status = update_wlan_database_reference_values(&parameters);
+			break;
+		default:
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("ERROR: wapi_message_wlan_authentication_c::process_data(): unknown function %d.\n"),
+				 function));
+
+			status = eap_status_illegal_parameter;
+		};
+
+		if (status != eap_status_ok
+			&& status != eap_status_success
+			&& status != eap_status_pending_request
+			&& status != eap_status_completed_request
+			&& status != eap_status_drop_packet_quietly)
+		{
+			(void) send_error_message(
+				status,
+				function);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::check_bksa_cache(
+	EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters)
+{
+
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status(eap_status_ok);
+
+	u32_t parameter_index(eapol_message_payload_index_first_parameter);
+
+	eap_array_c<eap_am_network_id_c> bssid_sta_receive_network_ids(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const array_of_network_ids
+			= parameters->get_object(parameter_index);
+
+		if (array_of_network_ids == 0
+			|| array_of_network_ids->get_type() != eapol_tlv_message_type_array)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c array_data(m_am_tools);
+
+		if (array_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = array_data.set_message_data(
+			array_of_network_ids->get_value_length(),
+			array_of_network_ids->get_value(array_of_network_ids->get_value_length()));
+
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		eap_array_c<eap_tlv_header_c> network_ids(m_am_tools);
+
+		status = array_data.parse_message_data(
+			&network_ids);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		for (u32_t ind = 0ul; ind < network_ids.get_object_count(); ++ind)
+		{
+			const eap_tlv_header_c * const header = network_ids.get_object(ind);
+
+			if (header == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+			}
+
+			eap_am_network_id_c * const new_network_id = new eap_am_network_id_c(m_am_tools);
+			if (new_network_id == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+			}
+
+			eap_automatic_variable_c<eap_am_network_id_c> automatic_new_network_id(m_am_tools, new_network_id);
+
+			status = array_data.get_parameter_data(header, new_network_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			automatic_new_network_id.do_not_free_variable();
+
+			status = bssid_sta_receive_network_ids.add_object(
+				new_network_id,
+				true);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+		} // for()
+	}
+
+
+	++parameter_index;
+
+	eapol_key_authentication_type_e selected_eapol_key_authentication_type(eapol_key_authentication_type_none);
+
+	{
+		const eap_tlv_header_c * const authentication_type
+			= parameters->get_object(parameter_index);
+
+		if (authentication_type == 0
+			|| authentication_type->get_type() != eapol_tlv_message_type_eapol_key_authentication_type)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(authentication_type, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		selected_eapol_key_authentication_type = static_cast<eapol_key_authentication_type_e>(value);
+		
+	}
+	
+	
+	++parameter_index;
+	
+	eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none);
+
+	{
+		const eap_tlv_header_c * const authentication_type
+			= parameters->get_object(parameter_index);
+
+		if (authentication_type == 0
+			|| authentication_type->get_type() != eapol_tlv_message_type_RSNA_cipher)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(authentication_type, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		pairwise_key_cipher_suite = static_cast<eapol_RSNA_key_header_c::eapol_RSNA_cipher_e>(value);
+	}
+
+
+	++parameter_index;
+
+	eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none);
+
+	{
+		const eap_tlv_header_c * const authentication_type
+			= parameters->get_object(parameter_index);
+
+		if (authentication_type == 0
+			|| authentication_type->get_type() != eapol_tlv_message_type_RSNA_cipher)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(authentication_type, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		group_key_cipher_suite = static_cast<eapol_RSNA_key_header_c::eapol_RSNA_cipher_e>(value);
+	}
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	
+	status = m_wauth->check_bksa_cache(
+		&bssid_sta_receive_network_ids,
+		selected_eapol_key_authentication_type,
+		pairwise_key_cipher_suite,
+		group_key_cipher_suite);
+	
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	if (status == eap_status_ok
+		|| status == eap_status_not_found)
+	{
+		// Creates message data composed of Attribute-Value Pairs.
+		eapol_handle_tlv_message_data_c message(m_am_tools);
+
+		if (message.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		// Old function name is used in the interface
+		status = message.add_parameter_data(
+			eapol_tlv_message_type_function_complete_check_pmksa_cache);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		u32_t network_id_parameters_size(0ul);
+		u32_t ind = 0ul;
+
+		// Calculates the message size.
+		for (ind = 0ul; ind < bssid_sta_receive_network_ids.get_object_count(); ++ind)
+		{
+			const eap_am_network_id_c * const network_id = bssid_sta_receive_network_ids.get_object(ind);
+			if (network_id == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+			}
+
+			network_id_parameters_size += 
+				eap_tlv_header_c::get_header_length()
+				+ message.get_payload_size(network_id);
+		}
+
+		status = message.add_structured_parameter_header(
+			eapol_tlv_message_type_array,
+			network_id_parameters_size);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+		
+		// Adds network ID array objects to message.
+		for (ind = 0ul; ind < bssid_sta_receive_network_ids.get_object_count(); ++ind)
+		{
+			const eap_am_network_id_c * const network_id = bssid_sta_receive_network_ids.get_object(ind);
+			if (network_id == 0)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+			}
+
+			status = message.add_parameter_data(
+				network_id);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+
+		status = send_message(&message);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::start_authentication(
+	EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status(eap_status_ok);
+
+	u32_t parameter_index(eapol_message_payload_index_first_parameter);
+
+	eap_variable_data_c SSID(m_am_tools);
+
+	if (SSID.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	{
+		const eap_tlv_header_c * const ssid_parameter
+			= parameters->get_object(parameter_index);
+
+		if (ssid_parameter == 0
+			|| ssid_parameter->get_type() != eapol_tlv_message_type_variable_data)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(ssid_parameter, &SSID);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	
+	
+	++parameter_index;
+
+	eapol_key_authentication_type_e selected_eapol_key_authentication_type(eapol_key_authentication_type_none);
+
+	{
+		const eap_tlv_header_c * const authentication_type_parameter
+			= parameters->get_object(parameter_index);
+
+		if (authentication_type_parameter == 0
+			|| authentication_type_parameter->get_type() != eapol_tlv_message_type_eapol_key_authentication_type)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(authentication_type_parameter, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		selected_eapol_key_authentication_type = static_cast<eapol_key_authentication_type_e>(value);
+	}
+
+
+	++parameter_index;
+
+	eap_variable_data_c preshared_key(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const preshared_key_parameter
+			= parameters->get_object(parameter_index);
+
+		if (preshared_key_parameter == 0
+			|| preshared_key_parameter->get_type() != eapol_tlv_message_type_variable_data)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(preshared_key_parameter, &preshared_key);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+	bool WAPI_override_enabled(false);
+
+	{
+		const eap_tlv_header_c * const WAPI_override_enabled_parameter
+			= parameters->get_object(parameter_index);
+
+		if (WAPI_override_enabled_parameter == 0
+			|| WAPI_override_enabled_parameter->get_type() != eapol_tlv_message_type_boolean)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(WAPI_override_enabled_parameter, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		WAPI_override_enabled = (value == 0) ? false: true;
+	}
+
+
+	++parameter_index;
+
+	eap_am_network_id_c receive_network_id(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const receive_network_id_parameter
+			= parameters->get_object(parameter_index);
+
+		if (receive_network_id_parameter == 0
+			|| receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = m_wauth->start_authentication(
+		&SSID,
+		selected_eapol_key_authentication_type,
+		&preshared_key,
+		WAPI_override_enabled, 
+		&receive_network_id
+		);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::complete_association(
+	EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status(eap_status_ok);
+
+	u32_t parameter_index(eapol_message_payload_index_first_parameter);
+
+	eapol_wlan_authentication_state_e association_result(eapol_wlan_authentication_state_none);
+
+	{
+		const eap_tlv_header_c * const association_result_parameter
+			= parameters->get_object(parameter_index);
+
+		if (association_result_parameter == 0
+			|| association_result_parameter->get_type() != eapol_tlv_message_type_eapol_wlan_authentication_state)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(association_result_parameter, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		association_result = static_cast<eapol_wlan_authentication_state_e>(value);
+	}
+
+
+	++parameter_index;
+
+	eap_am_network_id_c receive_network_id(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const receive_network_id_parameter
+			= parameters->get_object(parameter_index);
+
+		if (receive_network_id_parameter == 0
+			|| receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+	eap_variable_data_c received_WAPI_IE(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const received_WAPI_IE_parameter
+			= parameters->get_object(parameter_index);
+
+		if (received_WAPI_IE_parameter == 0
+			|| received_WAPI_IE_parameter->get_type() != eapol_tlv_message_type_variable_data)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(received_WAPI_IE_parameter, &received_WAPI_IE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+	eap_variable_data_c sent_WAPI_IE(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const sent_WAPI_IE_parameter
+			= parameters->get_object(parameter_index);
+
+		if (sent_WAPI_IE_parameter == 0
+			|| sent_WAPI_IE_parameter->get_type() != eapol_tlv_message_type_variable_data)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(sent_WAPI_IE_parameter, &sent_WAPI_IE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+
+	eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none);
+
+	{
+		const eap_tlv_header_c * const pairwise_key_cipher_suite_parameter
+			= parameters->get_object(parameter_index);
+
+		if (pairwise_key_cipher_suite_parameter == 0
+			|| pairwise_key_cipher_suite_parameter->get_type() != eapol_tlv_message_type_RSNA_cipher)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(pairwise_key_cipher_suite_parameter, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		pairwise_key_cipher_suite = static_cast<eapol_RSNA_key_header_c::eapol_RSNA_cipher_e>(value);
+	}
+
+	++parameter_index;
+	
+
+	eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none);
+
+	{
+		const eap_tlv_header_c * const group_key_cipher_suite_parameter
+			= parameters->get_object(parameter_index);
+
+		if (group_key_cipher_suite_parameter == 0
+			|| group_key_cipher_suite_parameter->get_type() != eapol_tlv_message_type_RSNA_cipher)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+		
+		status = message_data.get_parameter_data(group_key_cipher_suite_parameter, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		group_key_cipher_suite = static_cast<eapol_RSNA_key_header_c::eapol_RSNA_cipher_e>(value);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = m_wauth->complete_association(
+		association_result,
+		&receive_network_id, ///< source includes remote address, destination includes local address.
+		&received_WAPI_IE,
+		&sent_WAPI_IE,
+		pairwise_key_cipher_suite,
+		group_key_cipher_suite
+		);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::disassociation(
+	EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status(eap_status_ok);
+
+	u32_t parameter_index(eapol_message_payload_index_first_parameter);
+
+	eap_am_network_id_c receive_network_id(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const receive_network_id_parameter
+			= parameters->get_object(parameter_index);
+
+		if (receive_network_id_parameter == 0
+			|| receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = m_wauth->disassociation(
+		&receive_network_id ///< source includes remote address, destination includes local address.
+		);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::start_reassociation(
+	EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status(eap_status_ok);
+
+	u32_t parameter_index(eapol_message_payload_index_first_parameter);
+
+	eap_am_network_id_c old_receive_network_id(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const old_receive_network_id_parameter
+			= parameters->get_object(parameter_index);
+
+		if (old_receive_network_id_parameter == 0
+			|| old_receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(old_receive_network_id_parameter, &old_receive_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	++parameter_index;
+
+	eap_am_network_id_c new_receive_network_id(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const new_receive_network_id_parameter
+			= parameters->get_object(parameter_index);
+
+		if (new_receive_network_id_parameter == 0
+			|| new_receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(new_receive_network_id_parameter, &new_receive_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+	eapol_key_authentication_type_e selected_eapol_key_authentication_type(eapol_key_authentication_type_none);
+
+	{
+		const eap_tlv_header_c * const authentication_type
+			= parameters->get_object(parameter_index);
+
+		if (authentication_type == 0
+			|| authentication_type->get_type() != eapol_tlv_message_type_eapol_key_authentication_type)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(authentication_type, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		selected_eapol_key_authentication_type = static_cast<eapol_key_authentication_type_e>(value);
+	}
+
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = m_wauth->start_reassociation(
+		&old_receive_network_id,
+		&new_receive_network_id,
+		selected_eapol_key_authentication_type);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::complete_reassociation(
+	EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status(eap_status_ok);
+
+	u32_t parameter_index(eapol_message_payload_index_first_parameter);
+
+	eapol_wlan_authentication_state_e association_result(eapol_wlan_authentication_state_none);
+
+	{
+		const eap_tlv_header_c * const association_result_parameter
+			= parameters->get_object(parameter_index);
+
+		if (association_result_parameter == 0
+			|| association_result_parameter->get_type() != eapol_tlv_message_type_eapol_wlan_authentication_state)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(association_result_parameter, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		association_result = static_cast<eapol_wlan_authentication_state_e>(value);
+	}
+
+
+	++parameter_index;
+
+	eap_am_network_id_c receive_network_id(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const receive_network_id_parameter
+			= parameters->get_object(parameter_index);
+
+		if (receive_network_id_parameter == 0
+			|| receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+	eap_variable_data_c received_WAPI_IE(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const received_WAPI_IE_parameter
+			= parameters->get_object(parameter_index);
+
+		if (received_WAPI_IE_parameter == 0
+			|| received_WAPI_IE_parameter->get_type() != eapol_tlv_message_type_variable_data)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(received_WAPI_IE_parameter, &received_WAPI_IE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+	eap_variable_data_c sent_WAPI_IE(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const sent_WAPI_IE_parameter
+			= parameters->get_object(parameter_index);
+
+		if (sent_WAPI_IE_parameter == 0
+			|| sent_WAPI_IE_parameter->get_type() != eapol_tlv_message_type_variable_data)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(sent_WAPI_IE_parameter, &sent_WAPI_IE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+
+	eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none);
+
+	{
+		const eap_tlv_header_c * const pairwise_key_cipher_suite_parameter
+			= parameters->get_object(parameter_index);
+
+		if (pairwise_key_cipher_suite_parameter == 0
+			|| pairwise_key_cipher_suite_parameter->get_type() != eapol_tlv_message_type_RSNA_cipher)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(pairwise_key_cipher_suite_parameter, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		pairwise_key_cipher_suite = static_cast<eapol_RSNA_key_header_c::eapol_RSNA_cipher_e>(value);
+	}
+
+	++parameter_index;
+
+
+	eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none);
+
+	{
+		const eap_tlv_header_c * const group_key_cipher_suite_parameter
+			= parameters->get_object(parameter_index);
+
+		if (group_key_cipher_suite_parameter == 0
+			|| group_key_cipher_suite_parameter->get_type() != eapol_tlv_message_type_RSNA_cipher)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		u32_t value(0ul);
+
+		status = message_data.get_parameter_data(group_key_cipher_suite_parameter, &value);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		group_key_cipher_suite = static_cast<eapol_RSNA_key_header_c::eapol_RSNA_cipher_e>(value);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	status = m_wauth->complete_reassociation(
+		association_result,
+		&receive_network_id, ///< source includes remote address, destination includes local address.
+		&received_WAPI_IE,
+		&sent_WAPI_IE,
+		pairwise_key_cipher_suite,
+		group_key_cipher_suite
+		);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::packet_process(
+	EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status(eap_status_ok);
+
+	u32_t parameter_index(eapol_message_payload_index_first_parameter);
+
+	eap_am_network_id_c receive_network_id(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const receive_network_id_parameter
+			= parameters->get_object(parameter_index);
+
+		if (receive_network_id_parameter == 0
+			|| receive_network_id_parameter->get_type() != eapol_tlv_message_type_network_id)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(receive_network_id_parameter, &receive_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+	eap_variable_data_c packet_data_payload(m_am_tools);
+
+	{
+		const eap_tlv_header_c * const packet_data_parameter
+			= parameters->get_object(parameter_index);
+
+		if (packet_data_parameter == 0
+			|| packet_data_parameter->get_type() != eapol_tlv_message_type_variable_data)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(packet_data_parameter, &packet_data_payload);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eapol_ethernet_header_wr_c eth(
+		m_am_tools,
+		packet_data_payload.get_data(),
+		packet_data_payload.get_data_length());
+	if (eth.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = m_wauth->packet_process(
+		&receive_network_id,
+		&eth,
+		packet_data_payload.get_data_length()
+		);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::update_header_offset(
+	EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status(eap_status_ok);
+
+	u32_t parameter_index(eapol_message_payload_index_first_parameter);
+
+	{
+		const eap_tlv_header_c * const header_offset_value_parameter
+			= parameters->get_object(parameter_index);
+
+		if (header_offset_value_parameter == 0
+			|| header_offset_value_parameter->get_type() != eapol_tlv_message_type_u32_t)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(header_offset_value_parameter, &m_header_offset);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+	{
+		const eap_tlv_header_c * const MTU_value_parameter
+			= parameters->get_object(parameter_index);
+
+		if (MTU_value_parameter == 0
+			|| MTU_value_parameter->get_type() != eapol_tlv_message_type_u32_t)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(MTU_value_parameter, &m_MTU);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+	++parameter_index;
+
+	{
+		const eap_tlv_header_c * const trailer_length_parameter
+			= parameters->get_object(parameter_index);
+
+		if (trailer_length_parameter == 0
+			|| trailer_length_parameter->get_type() != eapol_tlv_message_type_u32_t)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(trailer_length_parameter, &m_trailer_length);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_message_wlan_authentication_c::update_wlan_database_reference_values(
+	EAP_TEMPLATE_CONST eap_array_c<eap_tlv_header_c> * const parameters)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status(eap_status_ok);
+
+	u32_t parameter_index(eapol_message_payload_index_first_parameter);
+
+	{
+		const eap_tlv_header_c * const reference_parameter
+			= parameters->get_object(parameter_index);
+
+		if (reference_parameter == 0
+			|| reference_parameter->get_type() != eapol_tlv_message_type_variable_data)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		}
+
+		eapol_handle_tlv_message_data_c message_data(m_am_tools);
+
+		if (message_data.get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = message_data.get_parameter_data(reference_parameter, &m_wlan_database_reference);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+// End of file.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_session_core.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,2105 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_session_core.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 16.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 20004
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+
+#include "eap_am_memory.h"
+#include "eap_tools.h"
+#include "wapi_session_core.h"
+#include "eap_state_notification.h"
+#include "eap_network_id_selector.h"
+#include "abs_eap_am_mutex.h"
+#include "eap_config.h"
+#include "wapi_core.h"
+#include "eap_buffer.h"
+#include "eap_automatic_variable.h"
+#include "wai_protocol_packet_header.h"
+#include "wapi_strings.h"
+#include "eapol_session_key.h"
+
+
+//--------------------------------------------------
+
+// 
+EAP_FUNC_EXPORT wapi_session_core_c::~wapi_session_core_c()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_session_core_c::~wapi_session_core_c(): this = 0x%08x => 0x%08x.\n"),
+		this,
+		dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	EAP_ASSERT(m_shutdown_was_called == true);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+#if defined(_WIN32) && !defined(__GNUC__)
+	#pragma warning( disable : 4355 ) // 'this' : used in base member initializer list
+#endif
+
+// 
+EAP_FUNC_EXPORT wapi_session_core_c::wapi_session_core_c(
+	abs_eap_am_tools_c * const tools,
+	abs_wapi_core_c * const partner,
+	const bool is_client_when_true)
+: m_partner(partner)
+, m_am_tools(tools)
+, m_session_map(tools, this)
+, m_remove_session_timeout(WAPI_SESSION_CORE_REMOVE_SESSION_TIMEOUT)
+, m_is_client(is_client_when_true)
+, m_is_valid(false)
+, m_use_wapi_session_core_reset_session(true)
+, m_shutdown_was_called(false)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_session_core_c::wapi_session_core_c(): this = 0x%08x => 0x%08x.\n"),
+		this,
+		dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	set_is_valid();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT abs_wapi_core_c * wapi_session_core_c::get_partner()
+{
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	return m_partner;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void wapi_session_core_c::set_is_valid()
+{
+	m_is_valid = true;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT bool wapi_session_core_c::get_is_valid()
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::reset()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_session_core_c::reset(): this = 0x%08x => 0x%08x.\n"),
+		this,
+		dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	eap_status_e status = m_session_map.for_each(shutdown_operation, true);
+	(void)EAP_STATUS_RETURN(m_am_tools, status);
+
+	status = m_session_map.reset();
+	(void)EAP_STATUS_RETURN(m_am_tools, status);
+
+	m_partner->cancel_timer(this, WAPI_SESSION_CORE_REMOVE_SESSION_ID);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("TIMER: WAPI_SESSION_CORE_REMOVE_SESSION_ID cancelled, %s.\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT wapi_core_c * wapi_session_core_c::create_new_session(
+	const eap_am_network_id_c * const receive_network_id)
+{
+	eap_status_e status = eap_status_process_general_error;
+
+	// Create a new session.
+	wapi_core_c * const session = new wapi_core_c(
+		m_am_tools,
+		this,
+		m_is_client,
+		receive_network_id);
+
+	if (session == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return 0;
+	}
+
+	if (session->get_is_valid() == false)
+	{
+		session->shutdown();
+		delete session;
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return 0;
+	}
+
+	status = session->configure();
+	if (status != eap_status_ok)
+	{
+		session->shutdown();
+		delete session;
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void)EAP_STATUS_RETURN(m_am_tools, status);
+		return 0;
+	}
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(m_am_tools,
+		receive_network_id->get_destination_id(),
+		receive_network_id->get_source_id(),
+		receive_network_id->get_type());
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		session->shutdown();
+		delete session;
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return 0;
+	}
+
+	eap_network_id_selector_c selector(
+		m_am_tools,
+		&send_network_id);
+	if (selector.get_is_valid() == false)
+	{
+		session->shutdown();
+		delete session;
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		return 0;
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("create_new_session() WAPI session"),
+		 selector.get_data(selector.get_data_length()),
+		 selector.get_data_length()));
+
+	status = m_session_map.add_handler(&selector, session);
+	if (status != eap_status_ok)
+	{
+		session->shutdown();
+		delete session;
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		(void)EAP_STATUS_RETURN(m_am_tools, status);
+		return 0;
+	}
+
+	return session;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::reset_or_remove_session(
+	wapi_core_c ** const session,
+	const eap_network_id_selector_c * const selector,
+	const bool reset_immediately)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (session == 0
+		|| *session == 0
+		|| selector == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+
+	if (m_use_wapi_session_core_reset_session == true)
+	{
+		// This will reuse session.
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_session_core_c::reset_or_remove_session(): resets session, session 0x%08x.\n"),
+			(*session)));
+
+		// NOTE, this delayed reset of session is used bacause the device is so slow in some cases
+		// (e.g. it cannot respond to WPA 4-Way Handshake message fast enough)
+
+		if (reset_immediately == true)
+		{
+			(*session)->unset_marked_removed();
+
+			status = (*session)->reset();
+		}
+		else
+		{
+			// This will delay reset to wapi_core_c::packet_process().
+			status = eap_status_ok;
+		}
+	}
+	else
+	{
+		//  This will cause shutdown of the session.
+		status = eap_status_process_general_error;
+	}
+
+	if (status != eap_status_ok)
+	{
+		// We cannot reuse the session.
+
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_session_core_c::reset_or_remove_session(): shutdown session, session 0x%08x.\n"),
+			(*session)));
+
+		(*session)->shutdown();
+		(*session) = 0;
+
+		status = m_session_map.remove_handler(selector, true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: wapi_session_core_c::reset_or_remove_session(): m_session_map.remove_type(), eap_status_e %d\n"),
+				status));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_session_core_c::reset_or_remove_session(): session NOT reused.\n")));
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_session_core_c::reset_or_remove_session(): session reused, session 0x%08x.\n"),
+			(*session)));
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::packet_process(
+	const eap_am_network_id_c * const receive_network_id,
+	eap_general_header_base_c * const packet_data,
+	const u32_t packet_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	eap_status_e status = eap_status_process_general_error;
+
+	// Each WAPI authentication session includes its own wapi_core_c object.
+	// WAPI authentication sessions are separated by eap_am_network_id_c object.
+
+	if (packet_data == 0
+		|| packet_length < eap_header_base_c::get_header_length())
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error);
+	}
+
+	if (receive_network_id == 0
+		|| receive_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	wai_protocol_packet_header_c wai(
+		m_am_tools,
+		packet_data->get_header_buffer(packet_length),
+		packet_length);
+
+	if (wai.get_is_valid() == false)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_session_core_c::packet_process(): %s, packet buffer corrupted.\n"),
+			 (m_is_client == true) ? "client": "server"
+			 ));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		EAP_TRACE_FLAGS_MESSAGE_DATA|TRACE_TEST_VECTORS, 
+		(EAPL("WAI-packet"),
+		 wai.get_header_buffer(packet_length),
+		 packet_length));
+
+	WAI_PROTOCOL_PACKET_TRACE_HEADER("->", &wai, m_is_client);
+
+	status = wai.check_header();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(m_am_tools,
+		receive_network_id->get_destination_id(),
+		receive_network_id->get_source_id(),
+		receive_network_id->get_type());
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_network_id_selector_c selector(
+		m_am_tools,
+		&send_network_id);
+	if (selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("packet_process() WAPI-session"),
+		 selector.get_data(selector.get_data_length()),
+		 selector.get_data_length()));
+
+	wapi_core_c *session = m_session_map.get_handler(&selector);
+
+	if (session == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error);
+	}
+
+	if (session != 0)
+	{
+		status = session->packet_process(
+			receive_network_id,
+			&wai,
+			packet_length);
+	}
+	else
+	{
+		status = eap_status_illegal_eap_type;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::packet_send(
+	const eap_am_network_id_c * const send_network_id,
+	eap_buf_chain_wr_c * const sent_packet,
+	const u32_t header_offset,
+	const u32_t data_length,
+	const u32_t buffer_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	EAP_ASSERT(header_offset < sent_packet->get_data_length());
+	EAP_ASSERT(data_length <= sent_packet->get_data_length());
+	EAP_ASSERT(sent_packet->get_data_length() <= buffer_length);
+
+	wai_protocol_packet_header_c wai(
+		m_am_tools,
+		sent_packet->get_data_offset(header_offset, data_length),
+		data_length);
+
+	if (wai.get_is_valid() == false)
+	{
+		EAP_TRACE_ERROR(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_session_core_c::packet_process(): %s, packet buffer corrupted.\n"),
+			 (m_is_client == true) ? "client": "server"
+			 ));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools, 
+		EAP_TRACE_FLAGS_MESSAGE_DATA|TRACE_TEST_VECTORS, 
+		(EAPL("WAI-packet"),
+		 wai.get_header_buffer(data_length),
+		 data_length));
+
+	WAI_PROTOCOL_PACKET_TRACE_HEADER("<-", &wai, m_is_client);
+
+	eap_status_e status = m_partner->packet_send(
+		send_network_id, sent_packet, header_offset, data_length, buffer_length);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT u32_t wapi_session_core_c::get_header_offset(
+	u32_t * const MTU,
+	u32_t * const trailer_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const u32_t offset = m_partner->get_header_offset(MTU, trailer_length);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return offset;
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::configure()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+
+	{
+		// This is optional.
+		eap_variable_data_c data(m_am_tools);
+
+		eap_status_e status = m_partner->read_configure(
+			cf_str_EAP_SESSION_use_reset_session.get_field(),
+			&data);
+		if (status == eap_status_ok
+			&& data.get_data_length() == sizeof(u32_t)
+			&& data.get_data(data.get_data_length()) != 0)
+		{
+			u32_t *flag = reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()));
+
+			if (flag != 0)
+			{
+				if ((*flag) != 0ul)
+				{
+					m_use_wapi_session_core_reset_session = true;
+				}
+				else
+				{
+					m_use_wapi_session_core_reset_session = false;
+				}
+			}
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::shutdown_operation(
+	wapi_core_c * const core,
+	abs_eap_am_tools_c * const m_am_tools)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_UNREFERENCED_PARAMETER(m_am_tools);
+
+	eap_status_e status = core->shutdown();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::shutdown()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_session_core_c::shutdown(): this = 0x%08x => 0x%08x.\n"),
+		this,
+		dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	if (m_shutdown_was_called == true)
+	{
+		// Shutdown function was called already.
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	m_shutdown_was_called = true;
+
+	eap_status_e status = reset();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::restart_authentication(
+	const eap_am_network_id_c * const send_network_id,
+	const bool is_client_when_true)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+	EAP_ASSERT(is_client_when_true == m_is_client);
+
+	eap_status_e status = eap_status_process_general_error;
+
+	eap_network_id_selector_c selector(
+		m_am_tools,
+		send_network_id);
+	if (selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("restart_authentication() WAPI session"),
+		 selector.get_data(selector.get_data_length()),
+		 selector.get_data_length()));
+
+	wapi_core_c *session = m_session_map.get_handler(&selector);
+
+	if (session != 0)
+	{
+		status = session->restart_authentication(
+			send_network_id,
+			is_client_when_true);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::restart_authentication(
+	const eap_am_network_id_c * const receive_network_id,
+	const bool is_client_when_true,
+	const bool force_clean_restart,
+	const bool from_timer)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+	EAP_ASSERT(is_client_when_true == m_is_client);
+
+	eap_status_e status = eap_status_process_general_error;
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(m_am_tools,
+		receive_network_id->get_destination_id(),
+		receive_network_id->get_source_id(),
+		receive_network_id->get_type());
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_network_id_selector_c selector(
+		m_am_tools,
+		&send_network_id);
+	if (selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("restart_authentication() WAPI session"),
+		 selector.get_data(selector.get_data_length()),
+		 selector.get_data_length()));
+
+	wapi_core_c *session = m_session_map.get_handler(&selector);
+
+	if (session == 0)
+	{
+		// Create a new session.
+		session = create_new_session(receive_network_id);
+	}
+
+	if (session != 0)
+	{
+		status = session->restart_authentication(
+			receive_network_id,
+			is_client_when_true);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::packet_data_session_key(
+	const eap_am_network_id_c * const send_network_id,
+	const eapol_session_key_c * const key)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("%s: wapi_session_core_c::packet_data_session_key()\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_session_core_c::packet_data_session_key()");
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	eap_status_e status = eap_status_process_general_error;
+
+	if (key->get_is_valid() == true)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("eapol session key: type 0x%02x, index 0x%02x, tx %d\n"),
+			 key->get_key_type(),
+			 key->get_key_index(),
+			 key->get_key_tx_bit()));
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("eapol session key"),
+			 key->get_key()->get_data(key->get_key()->get_data_length()),
+			 key->get_key()->get_data_length()));
+	}
+
+	// Forward the keys to lower layers
+	status = m_partner->packet_data_session_key(
+			send_network_id,
+			key);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::read_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->read_configure(field, data);
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::write_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->write_configure(field, data);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::timer_expired(
+	const u32_t id, void *data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("TIMER: [0x%08x]->wapi_session_core_c::")
+		 EAPL("timer_expired(id 0x%02x, data 0x%08x), %s.\n"),
+		 this,
+		 id,
+		 data,
+		 (m_is_client == true) ? "client": "server"));
+
+	if (id == WAPI_SESSION_CORE_REMOVE_SESSION_ID)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("TIMER: WAPI_SESSION_CORE_REMOVE_SESSION_ID elapsed, %s.\n"),
+			 (m_is_client == true) ? "client": "server"));
+
+		const eap_network_id_selector_c * const selector 
+			= reinterpret_cast<const eap_network_id_selector_c *>(data);
+		if (selector == 0
+			|| selector->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("timer_expired() WAPI-session"),
+			 selector->get_data(selector->get_data_length()),
+			 selector->get_data_length()));
+
+		wapi_core_c *session = m_session_map.get_handler(selector);
+
+		if (session != 0
+			&& session->get_marked_removed() == true)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TIMER: unused session found, it is deleted, session 0x%08x.\n"),
+				session));
+
+			// Session must be deleted here.
+			session->shutdown();
+			session = 0;
+
+			// This will delete session.
+			eap_status_e status = m_session_map.remove_handler(selector, true);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("ERROR: m_session_map.remove_type(), eap_status_e %d\n"),
+					 status));
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		else if (session != 0
+			&& session->get_marked_removed() == false)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TIMER: session found, it is in use, session 0x%08x.\n"),
+				session));
+		}
+		else
+		{
+			// Not found, no need to remove.
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TIMER: session not found.\n")));
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::timer_delete_data(
+	const u32_t id, void *data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("TIMER: [0x%08x]->wapi_session_core_c::")
+		 EAPL("timer_delete_data(id 0x%02x, data 0x%08x).\n"),
+		this, id, data));
+
+	if (id == WAPI_SESSION_CORE_REMOVE_SESSION_ID)
+
+	{
+		const eap_network_id_selector_c * const selector 
+			= reinterpret_cast<const eap_network_id_selector_c *>(data);
+		delete selector;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::synchronous_cancel_all_wapi_sessions()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_session_core_c::synchronous_cancel_all_wapi_sessions(): this = 0x%08x => 0x%08x.\n"),
+		this,
+		dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	eap_status_e status = reset();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::synchronous_create_wapi_session(
+	const eap_am_network_id_c * const receive_network_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_session_core_c::synchronous_create_wapi_session(): this = 0x%08x => 0x%08x.\n"),
+		this,
+		dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	eap_status_e status = eap_status_process_general_error;
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(
+		m_am_tools,
+		receive_network_id->get_destination_id(),
+		receive_network_id->get_source_id(),
+		receive_network_id->get_type());
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_network_id_selector_c selector(
+		m_am_tools,
+		&send_network_id);
+	if (selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("synchronous_create_eap_session() WAPI-session"),
+		 selector.get_data(selector.get_data_length()),
+		 selector.get_data_length()));
+
+	wapi_core_c *session = m_session_map.get_handler(&selector);
+
+	if (session == 0)
+	{
+		session = create_new_session(receive_network_id);
+
+		if (session == 0)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+		else
+		{
+			status = eap_status_ok;
+		}
+	}
+	else
+	{
+		status = eap_status_ok;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::synchronous_remove_wapi_session(
+	const eap_am_network_id_c * const receive_network_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_session_core_c::synchronous_remove_eap_session(): this = 0x%08x => 0x%08x.\n"),
+		this,
+		dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	eap_status_e status = eap_status_process_general_error;
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(
+		m_am_tools,
+		receive_network_id->get_destination_id(),
+		receive_network_id->get_source_id(),
+		receive_network_id->get_type());
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_network_id_selector_c selector(
+		m_am_tools,
+		&send_network_id);
+	if (selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("synchronous_remove_eap_session() WAPI-session"),
+		 selector.get_data(selector.get_data_length()),
+		 selector.get_data_length()));
+
+	wapi_core_c *session = m_session_map.get_handler(&selector);
+
+	if (session != 0)
+	{
+		// This reset is immediaete.
+		status = reset_or_remove_session(
+			&session,
+			&selector,
+			true);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		// Not found, no need to remove.
+		status = eap_status_ok;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_session_core_c::asynchronous_init_remove_wapi_session(
+	const eap_am_network_id_c * const send_network_id)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_session_core_c::asynchronous_init_remove_wapi_session(): %s.\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	eap_network_id_selector_c state_selector(
+		m_am_tools,
+		send_network_id);
+	if (state_selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("asynchronous_init_remove_wapi_session() WAPI session"),
+		 state_selector.get_data(state_selector.get_data_length()),
+		 state_selector.get_data_length()));
+
+	eap_status_e status = asynchronous_init_remove_wapi_session(
+		&state_selector);
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_session_core_c::asynchronous_init_remove_wapi_session(
+	const eap_network_id_selector_c * const state_selector)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_session_core_c::asynchronous_init_remove_wapi_session(): %s.\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	// NOTE: we cannot call directly synchronous_remove_wapi_session(), because we will
+	// return from here to removed object.
+
+	eap_status_e status = eap_status_process_general_error;
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("asynchronous_init_remove_wapi_session() WAPI session"),
+		 state_selector->get_data(state_selector->get_data_length()),
+		 state_selector->get_data_length()));
+
+	wapi_core_c *session = m_session_map.get_handler(state_selector);
+
+	if (session != 0)
+	{
+		session->set_marked_removed();
+
+		// So we initiate a timer to remove session identified by state_selector.
+		eap_network_id_selector_c * const copy_selector = state_selector->copy();
+		if (copy_selector == 0
+			|| copy_selector->get_is_valid() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = m_partner->set_timer(
+			this,
+			WAPI_SESSION_CORE_REMOVE_SESSION_ID, 
+			copy_selector,
+			m_remove_session_timeout);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_session_core_c::asynchronous_init_remove_wapi_session()")
+			 EAPL(": %s: WAPI_SESSION_CORE_REMOVE_SESSION_ID timer set %d ms.\n"),
+			 (m_is_client == true) ? "client": "server",
+			 m_remove_session_timeout));
+	}
+	else
+	{
+		// Not found, cannot remove.
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("ERROR: wapi_session_core_c::asynchronous_init_remove_wapi_session()")
+			 EAPL(": %s: failed session not found.\n"),
+			 (m_is_client == true) ? "client": "server"));
+
+		status = eap_status_ok;
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void wapi_session_core_c::state_notification(
+	const abs_eap_state_notification_c * const state)
+{
+	m_partner->state_notification(state);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::set_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id, 
+	void * const p_data,
+	const u32_t p_time_ms)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->set_timer(
+		p_initializer, 
+		p_id, 
+		p_data,
+		p_time_ms);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::cancel_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->cancel_timer(
+		p_initializer, 
+		p_id);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::cancel_all_timers()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	const eap_status_e status = m_partner->cancel_all_timers();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::set_session_timeout(
+	const u32_t /* session_timeout_ms */)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::cancel_authentication_session(
+	wapi_core_c * const handler,
+	abs_eap_am_tools_c * const m_am_tools)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_session_core_c::cancel_authentication_session(): this = 0x%08x => 0x%08x.\n"),
+		handler,
+		dynamic_cast<abs_eap_base_timer_c *>(handler)));
+
+	EAP_UNREFERENCED_PARAMETER(m_am_tools);
+
+	eap_status_e status = handler->cancel_authentication_session();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::cancel_all_authentication_sessions()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_ethernet_core_c::cancel_all_authentication_sessions()\n")));
+
+	eap_status_e status = m_session_map.for_each(cancel_authentication_session, true);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::check_bksa_cache(
+	eap_array_c<eap_am_network_id_c> * const bssid_sta_receive_network_ids,
+	// ****
+	// TODO: This needs to be updated for WAPI
+	const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	eap_status_e status = eap_status_ok;
+
+	for (u32_t ind = 0ul; ind < bssid_sta_receive_network_ids->get_object_count();)
+	{
+		eap_am_network_id_c * const receive_network_id = bssid_sta_receive_network_ids->get_object(ind);
+		if (receive_network_id == 0)
+		{
+			bssid_sta_receive_network_ids->reset();
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		// Here we swap the addresses.
+		eap_am_network_id_c send_network_id(
+			m_am_tools,
+			receive_network_id->get_destination_id(),
+			receive_network_id->get_source_id(),
+			receive_network_id->get_type());
+		if (send_network_id.get_is_valid_data() == false)
+		{
+			bssid_sta_receive_network_ids->reset();
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		eap_network_id_selector_c state_selector(
+			m_am_tools,
+			&send_network_id);
+		if (state_selector.get_is_valid() == false)
+		{
+			bssid_sta_receive_network_ids->reset();
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("check_pmksa_cache(): checks WAPI-session"),
+			 state_selector.get_data(state_selector.get_data_length()),
+			 state_selector.get_data_length()));
+		
+		wapi_core_c *session = m_session_map.get_handler(&state_selector);
+		
+		if (session == 0
+			|| selected_eapol_key_authentication_type == eapol_key_authentication_type_RSNA_PSK
+			|| selected_eapol_key_authentication_type == eapol_key_authentication_type_WPA_PSK
+			|| session->check_bksa_cache(
+				selected_eapol_key_authentication_type,
+				pairwise_key_cipher_suite,
+				group_key_cipher_suite) != eap_status_ok)
+		{
+			// No cached PMKID for this address and security suite.
+			EAP_TRACE_DATA_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("No cached PMKID for this address"),
+				 state_selector.get_data(state_selector.get_data_length()),
+				 state_selector.get_data_length()));
+
+			status = bssid_sta_receive_network_ids->remove_object(ind);
+			if (status != eap_status_ok)
+			{
+				bssid_sta_receive_network_ids->reset();
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			// Note here we do not increase index because we removed the current object.
+		}
+		else
+		{
+			// Check the next index.
+			++ind;
+		}
+	} // for()
+
+	if (bssid_sta_receive_network_ids->get_object_count() > 0ul)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+	else
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found);
+	}
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::association(
+	const eap_am_network_id_c * const receive_network_id,
+	// ****
+	// TODO: This needs to be updated for WAPI
+	const eapol_key_authentication_type_e authentication_type,
+	const eap_variable_data_c * const wapi_ie_ae,
+	const eap_variable_data_c * const wapi_ie_asue,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher,
+	const eap_variable_data_c * const /* pre_shared_key_PSK */
+	)
+{
+	eap_status_e status = eap_status_process_general_error;
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("%s: wapi_session_core_c::association().\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_session_core_c::association()");
+
+	if (receive_network_id->get_type() != eapol_ethernet_type_wapi)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: wapi_session_core_c::association(): Illegal Ethernet type %d\n"),
+			receive_network_id->get_type()));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ethernet_type_not_supported);
+	}
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(
+		m_am_tools,
+		receive_network_id->get_destination_id(),
+		receive_network_id->get_source_id(),
+		receive_network_id->get_type());
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_network_id_selector_c state_selector(
+		m_am_tools,
+		&send_network_id);
+
+	if (state_selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("association(): WAPI-session"),
+		state_selector.get_data(state_selector.get_data_length()),
+		state_selector.get_data_length()));
+
+
+	wapi_core_c *session = m_session_map.get_handler(&state_selector);
+
+	if (session != 0)
+	{
+		// Reuse the session.
+		session->unset_marked_removed();
+
+		if (m_is_client == false)
+		{
+			// In test version do not reset server.
+		}
+		else
+		{
+			status = session->reset();
+			if (status != eap_status_ok)
+			{
+				// We cannot reuse the session.
+				EAP_TRACE_ERROR(
+					m_am_tools,
+					TRACE_FLAGS_ERROR,
+					(EAPL("wapi_session_core_c::association(): session NOT reused.\n")));
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+	if (session == 0)
+	{
+		session = new wapi_core_c(
+			m_am_tools,
+			this,
+			m_is_client,
+			receive_network_id);
+		if (session == 0
+			|| session->get_is_valid() == false)
+		{
+			if (session != 0)
+			{
+				session->shutdown();
+			}
+			else
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("WARNING: wapi_session_core_c::association(): Cannot run session->shutdown() 0x%08x\n"),
+					session));
+			}
+			delete session;
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = session->configure();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = session->initialize(
+			receive_network_id,
+			authentication_type,
+			wapi_ie_ae,
+			wapi_ie_asue,
+			eapol_pairwise_cipher,
+			eapol_group_cipher);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_session_map.add_handler(&state_selector, session);
+		if (status != eap_status_ok)
+		{
+			if (session != 0)
+			{
+				session->shutdown();
+			}
+			else
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("WARNING: wapi_session_core_c::association(): Cannot run session->shutdown() 0x%08x\n"),
+					session));
+			}
+			delete session;
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+	}
+	else
+	{
+		status = session->initialize(
+			receive_network_id,
+			authentication_type,
+			wapi_ie_ae,
+			wapi_ie_asue,
+			eapol_pairwise_cipher,
+			eapol_group_cipher);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+
+#if 0
+#if defined(USE_WAPI_CORE_SERVER)
+	if (m_is_client == false)
+	{
+		status = session->start_authentication();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+#endif //#if defined(USE_WAPI_CORE_SERVER)
+#endif
+	if (m_is_client == true)
+	{
+		status = session->allow_authentication();
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_session_core_c::init_eapol_key_bksa_caching_timeout(
+	const eap_am_network_id_c * const send_network_id)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("%s: wapi_session_core_c::init_eapol_key_pmksa_caching_timeout().\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_session_core_c::init_eapol_key_bksa_caching_timeout()");
+
+	// Initialize BKSA caching timeout of WAPI-session.
+	eap_network_id_selector_c state_selector(
+		m_am_tools,
+		send_network_id);
+
+	if (state_selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("init_eapol_key_bksa_caching_timeout(): WAPI session"),
+		state_selector.get_data(state_selector.get_data_length()),
+		state_selector.get_data_length()));
+
+	wapi_core_c *session = m_session_map.get_handler(&state_selector);
+
+	if (session == 0)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("session not found.\n"),
+			 (m_is_client == true) ? "client": "server"));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+
+	eap_status_e status = session->init_bksa_caching_timeout();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: wapi_session_core_c::init_eapol_key_bksa_caching_timeout(): ")
+			 EAPL("session->init_pmksa_caching_timeout(), eap_status_e %d\n"),
+			 status));
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::disassociation(
+	const eap_am_network_id_c * const receive_network_id
+	)
+{
+	eap_status_e status = eap_status_process_general_error;
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("%s: wapi_session_core_c::disassociation().\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_session_core_c::disassociation()");
+
+	if (receive_network_id == 0)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(
+		m_am_tools,
+		receive_network_id->get_destination_id(),
+		receive_network_id->get_source_id(),
+		receive_network_id->get_type());
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = init_eapol_key_bksa_caching_timeout(
+		&send_network_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: wapi_session_core_c::disassociation(): ")
+			 EAPL("init_eapol_key_pmksa_caching_timeout(), eap_status_e %d\n"),
+			status));
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::create_state(
+	const eap_am_network_id_c * const receive_network_id,
+	// ****
+	// TODO: This needs to be updated for WAPI
+	const eapol_key_authentication_type_e authentication_type
+	)
+{
+	eap_status_e status = eap_status_process_general_error;
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("%s: eapol_core_c::create_state().\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_session_core_c::create_state()");
+
+	if (receive_network_id->get_type() != eapol_ethernet_type_wapi)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: eapol_core_c::create_state(): Illegal Ethernet type %d\n"),
+			receive_network_id->get_type()));
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ethernet_type_not_supported);
+	}
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(
+		m_am_tools,
+		receive_network_id->get_destination_id(),
+		receive_network_id->get_source_id(),
+		receive_network_id->get_type());
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_network_id_selector_c state_selector(
+		m_am_tools,
+		&send_network_id);
+
+	if (state_selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_session_core_c::create_state(): WAPI-session"),
+		state_selector.get_data(state_selector.get_data_length()),
+		state_selector.get_data_length()));
+
+
+	wapi_core_c *session = m_session_map.get_handler(&state_selector);
+
+	if (session != 0)
+	{
+		// Reuse the session.
+		session->unset_marked_removed();
+
+		if (m_is_client == false)
+		{
+			// In test version do not reset server.
+		}
+		else
+		{
+			status = session->reset();
+			if (status != eap_status_ok)
+			{
+				// We cannot reuse the session.
+				EAP_TRACE_ERROR(
+					m_am_tools,
+					TRACE_FLAGS_ERROR,
+					(EAPL("wapi_session_core_c::create_state(): session NOT reused.\n")));
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+	}
+
+
+	if (session == 0)
+	{
+		session = new wapi_core_c(
+			m_am_tools,
+			this,
+			m_is_client,
+			receive_network_id);
+		if (session == 0
+			|| session->get_is_valid() == false)
+		{
+			if (session != 0)
+			{
+				session->shutdown();
+			}
+			else
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("WARNING: wapi_session_core_c::create_state(): Cannot run session->shutdown() 0x%08x\n"),
+					session));
+			}
+			delete session;
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		status = session->initialize(
+			receive_network_id,
+			authentication_type);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_session_map.add_handler(&state_selector, session);
+		if (status != eap_status_ok)
+		{
+			if (session != 0)
+			{
+				session->shutdown();
+			}
+			else
+			{
+				EAP_TRACE_DEBUG(
+					m_am_tools, 
+					TRACE_FLAGS_DEFAULT, 
+					(EAPL("WARNING: wapi_session_core_c::create_state(): Cannot run session->shutdown() 0x%08x\n"),
+					session));
+			}
+			delete session;
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		status = session->initialize(
+			receive_network_id,
+			authentication_type);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	status = session->configure();
+	if (status != eap_status_ok)
+	{
+		status = remove_wapi_state(
+			&send_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("WARNING: wapi_session_core_c::create_state(): ")
+				 EAPL("remove_eapol_key_state(), eap_status_e %d\n"),
+				status));
+		}
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_session_core_c::remove_wapi_state(
+	const eap_am_network_id_c * const send_network_id)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("%s: wapi_session_core_c::remove_wapi_state().\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_session_core_c::remove_wapi_state()");
+
+	// Remove possible WAPI state.
+	eap_network_id_selector_c state_selector(
+		m_am_tools,
+		send_network_id);
+
+	if (state_selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("remove_eapol_key_state(): WAPI-session"),
+		state_selector.get_data(state_selector.get_data_length()),
+		state_selector.get_data_length()));
+
+	wapi_core_c * const session = m_session_map.get_handler(&state_selector);
+
+	if (session != 0)
+	{
+		if (session->get_marked_removed() == false)
+		{
+			// Do not remove object in use.
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("WARNING: wapi_session_core_c::remove_eapol_key_state(): Cannot removed used object 0x%08x\n"),
+				session));
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+		}
+
+		session->shutdown();
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: wapi_session_core_c::remove_eapol_key_state(): Cannot run session->shutdown() 0x%08x\n"),
+			session));
+	}
+
+	eap_status_e status = m_session_map.remove_handler(&state_selector, true);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: wapi_session_core_c::remove_eapol_key_state(): ")
+			 EAPL("session->remove_handler(), eap_status_e %d\n"),
+			 status));
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::remove_bksa_from_cache(
+	const eap_am_network_id_c * const receive_network_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = eap_status_process_general_error;
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("%s: wapi_session_core_c::remove_bksa_from_cache().\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_session_core_c::remove_bksa_from_cache()");
+
+	if (receive_network_id == 0)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// Here we swap the addresses.
+	eap_am_network_id_c send_network_id(
+		m_am_tools,
+		receive_network_id->get_destination_id(),
+		receive_network_id->get_source_id(),
+		receive_network_id->get_type());
+	if (send_network_id.get_is_valid_data() == false)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	status = remove_wapi_state(
+		&send_network_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: ewapi_session_core_c::remove_bksa_from_cache(): ")
+			 EAPL("remove_eapol_key_state(), eap_status_e %d\n"),
+			status));
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_session_core_c::read_reassociation_parameters(
+	const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address.
+	const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address.
+	const eapol_key_authentication_type_e authentication_type,
+	eap_variable_data_c * const BKID,
+	const eap_variable_data_c * const received_WAPI_ie,
+	const eap_variable_data_c * const sent_WAPI_ie)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("%s: wapi_session_core_c::read_reassociation_parameters()\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_session_core_c::read_reassociation_parameters()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	// No need to check authentication type anymore. It can be changed in reassociation.
+
+	// Here we swap the addresses.
+	eap_am_network_id_c new_send_network_id(
+		m_am_tools,
+		new_receive_network_id->get_destination_id(),
+		new_receive_network_id->get_source_id(),
+		new_receive_network_id->get_type());
+	if (new_send_network_id.get_is_valid_data() == false)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	eap_network_id_selector_c state_selector(
+		m_am_tools,
+		&new_send_network_id);
+
+	if (state_selector.get_is_valid() == false)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("read_reassociation_parameters(): WAPI-session"),
+		state_selector.get_data(state_selector.get_data_length()),
+		state_selector.get_data_length()));
+
+	wapi_core_c * const session = m_session_map.get_handler(&state_selector);
+
+	if (session != 0)
+	{
+		status = session->reset_cached_bksa();
+		if (status != eap_status_ok)
+		{
+			// We cannot reuse the session.
+			EAP_TRACE_ERROR(
+				m_am_tools, 
+				TRACE_FLAGS_ERROR, 
+				(EAPL("wapi_session_core_c::read_reassociation_parameters(): session NOT reused.\n")));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// We have state for this connection.
+		status = session->read_reassociation_parameters(
+			new_receive_network_id, ///< source includes remote address, destination includes local address.
+			authentication_type,
+			BKID,
+			received_WAPI_ie,
+			sent_WAPI_ie);
+		if (status != eap_status_ok)
+		{
+			// ERROR, Cannot reassociate.
+
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: wapi_session_core_c::read_reassociation_parameters(): Cannot reassociate.\n")));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+	else
+	{
+		status = eap_status_not_found;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_strings.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,214 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_strings.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 23 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 707 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+#if defined(USE_WAPI_CORE)
+
+#include "eap_automatic_variable.h"
+#include "ec_cs_types.h"
+#include "ec_cs_data.h"
+#include "wapi_strings.h"
+
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_strings_c::~wapi_strings_c()
+{
+}
+
+EAP_FUNC_EXPORT wapi_strings_c::wapi_strings_c()
+{
+}
+
+EAP_FUNC_EXPORT eap_const_string wapi_strings_c::get_wapi_completion_operation_string(const wapi_completion_operation_e type)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(type, wapi_completion_operation_none)
+	else EAP_IF_RETURN_STRING(type, wapi_completion_operation_continue_certificate_authentication)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(type);
+		return EAPL("Unknown WAPI completion operation");
+	}
+}
+
+EAP_FUNC_EXPORT eap_const_string wapi_strings_c::get_wai_protocol_version_string(const wai_protocol_version_e type)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(type, wai_protocol_version_none)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_version_1)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(type);
+		return EAPL("Unknown WAI protocol version");
+	}
+}
+
+EAP_FUNC_EXPORT eap_const_string wapi_strings_c::get_wai_protocol_type_string(const wai_protocol_type_e type)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(type, wai_protocol_type_none)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_type_wai)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(type);
+		return EAPL("Unknown WAI protocol type");
+	}
+}
+
+EAP_FUNC_EXPORT eap_const_string wapi_strings_c::get_wai_protocol_subtype_string(const wai_protocol_subtype_e type)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(type, wai_protocol_subtype_none)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_pre_authentication_start)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_stakey_request)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_authentication_activation)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_access_authentication_request)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_access_authentication_response)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_certificate_authentication_request)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_certificate_authentication_response)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_unicast_key_negotiation_request)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_unicast_key_negotiation_response)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_unicast_key_negotiation_confirmation)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_multicast_key_announcement)
+	else EAP_IF_RETURN_STRING(type, wai_protocol_subtype_multicast_key_announcement_response)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(type);
+		return EAPL("Unknown WAI protocol subtype");
+	}
+}
+
+EAP_FUNC_EXPORT eap_const_string wapi_strings_c::get_wai_tlv_header_string(const wai_tlv_type_e type)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(type, wai_tlv_type_none)
+	else EAP_IF_RETURN_STRING(type, wai_tlv_type_signature_attribute)
+	else EAP_IF_RETURN_STRING(type, wai_tlv_type_echd_parameter)
+	else EAP_IF_RETURN_STRING(type, wai_tlv_type_result_of_certificate_validation)
+	else EAP_IF_RETURN_STRING(type, wai_tlv_type_identity_list)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(type);
+		return EAPL("Unknown WAI TLV header type");
+	}
+}
+
+EAP_FUNC_EXPORT eap_const_string wapi_strings_c::get_wai_payload_type_string(const wai_payload_type_e type)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(type, wai_payload_type_none)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_flag)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_access_result)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_uskid)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_mskid_stakeyid)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_result)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_addid)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_bkid)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_key_announcement_identifier)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_data_sequence_number)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_message_authentication_code)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_authentication_identifier)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_nonce)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_key_data)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_wie)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_echd_parameter)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_signature_attributes)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_result_of_certificate_verification)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_identity_list)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_optional)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_certificate)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_identity)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_first_known)
+	else EAP_IF_RETURN_STRING(type, wai_payload_type_last_known)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(type);
+		return EAPL("Unknown WAI payload type");
+	}
+}
+
+EAP_FUNC_EXPORT eap_const_string wapi_strings_c::get_wapi_core_state_string(const wapi_core_state_e state)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(state, wapi_core_state_none)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_start_unicast_key_negotiation)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_start_certificate_negotiation)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_start_multicast_key_announcement)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_wait_authentication_activation_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_process_authentication_activation_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_wait_access_authentication_request_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_process_access_authentication_request_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_process_access_authentication_request_message_ASU_signature_trusted_by_AE)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_process_access_authentication_request_message_AE_signature_trusted_by_ASUE)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_wait_certificate_authentication_request_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_wait_certificate_authentication_response_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_wait_access_authentication_response_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_process_access_authentication_response_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_process_access_authentication_response_message_ASU_signature)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_wait_unicast_key_negotiation_request_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_wait_unicast_key_negotiation_response_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_wait_unicast_key_negotiation_confirmation_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_wait_multicast_announcement_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_wait_multicast_announcement_response_message)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_authentication_ok)
+	else EAP_IF_RETURN_STRING(state, wapi_core_state_authentication_failed)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(state);
+		return EAPL("Unknown WAPI core state");
+	}
+};
+
+
+EAP_FUNC_EXPORT eap_const_string wapi_strings_c::get_wapi_negotiation_state_string(const wapi_negotiation_state_e state)
+{
+#if defined(USE_EAP_TRACE_STRINGS)
+	EAP_IF_RETURN_STRING(state, wapi_negotiation_state_none)
+	else EAP_IF_RETURN_STRING(state, wapi_negotiation_state_initial_negotiation)
+	else EAP_IF_RETURN_STRING(state, wapi_negotiation_state_rekeying)
+	else
+#endif // #if defined(USE_EAP_TRACE_STRINGS)
+	{
+		EAP_UNREFERENCED_PARAMETER(state);
+		return EAPL("Unknown WAPI negotiation state");
+	}
+};
+
+//----------------------------------------------------------------------------------
+
+#endif //#if defined(USE_WAPI_CORE)
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_common/src/wapi_wlan_authentication.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,3088 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_common/src/wapi_wlan_authentication.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 18.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of WAPI source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 20001 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+
+// INCLUDE FILES
+
+#include "eap_am_memory.h"
+
+#include "eap_am_tools.h"
+#include "eap_variable_data.h"
+#include "eap_tools.h"
+#include "abs_eap_am_mutex.h"
+
+#include "wapi_wlan_authentication.h"
+#include "eapol_ethernet_header.h"
+#include "wapi_ethernet_core.h"
+#include "eap_crypto_api.h"
+#include "eap_header_string.h"
+#include "abs_eap_state_notification.h"
+#include "eapol_session_key.h"
+#include "eap_buffer.h"
+#include "eap_config.h"
+#include "eap_array_algorithms.h"
+#include "eap_state_notification.h"
+#include "eap_automatic_variable.h"
+
+
+
+// LOCAL CONSTANTS
+
+enum wapi_am_core_timer_id_e
+{
+	WAPI_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID,
+	WAPI_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID,
+	WAPI_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID,
+	WAPI_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID
+};
+
+#if defined(USE_WAPI_WLAN_AUTHENTICATION_MUTEX)
+
+	#define WAUTH_ENTER_MUTEX(tools) { tools->enter_global_mutex(); }
+
+	#define WAUTH_LEAVE_MUTEX(tools) { tools->leave_global_mutex(); }
+
+#else
+
+	#define WAUTH_ENTER_MUTEX(tools)
+
+	#define WAUTH_LEAVE_MUTEX(tools)
+
+#endif //#if defined(USE_WAPI_WLAN_AUTHENTICATION_MUTEX)
+
+// ================= MEMBER FUNCTIONS =======================
+
+EAP_FUNC_EXPORT wapi_wlan_authentication_c * wapi_wlan_authentication_c::new_wapi_wlan_authentication(
+	abs_eap_am_tools_c * const tools,
+	abs_wapi_wlan_authentication_c * const partner,
+	const bool is_client_when_true,
+	const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference
+	)
+{
+	EAP_TRACE_DEBUG(
+		tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("partner calls: wapi_wlan_authentication_c::new_wapi_wlan_authentication()\n")));
+
+	EAP_TRACE_RETURN_STRING(tools, "returns to partner: wapi_wlan_authentication_c::new_wapi_wlan_authentication()");
+
+	wapi_am_wlan_authentication_c * m_am_wauth = wapi_am_wlan_authentication_c::new_wapi_am_wlan_authentication(
+		tools,
+		is_client_when_true,
+		wlan_database_reference);
+	if (m_am_wauth == 0
+		|| m_am_wauth->get_is_valid() == false)
+	{
+		// ERROR.
+		if (m_am_wauth != 0)
+		{
+			EAP_TRACE_DEBUG(
+				tools,
+				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+				(EAPL("calls: wapi_wlan_authentication_c::new_eapol_wlan_authentication(): m_am_wauth->shutdown(): %s.\n"),
+				(is_client_when_true == true) ? "client": "server"));
+
+			m_am_wauth->shutdown();
+			delete m_am_wauth;
+			m_am_wauth = 0;
+		}
+		return 0;
+	}
+
+	wapi_wlan_authentication_c * wauth = new wapi_wlan_authentication_c(tools, partner, m_am_wauth, is_client_when_true);
+	if (wauth == 0
+		|| wauth->get_is_valid() == false)
+	{
+		// ERROR.
+		if (wauth != 0)
+		{
+			wauth->shutdown();
+			delete wauth;
+		}
+		return 0;
+	}
+
+	EAP_TRACE_DEBUG(
+		tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::new_wapi_wlan_authentication(): m_am_wauth->set_am_partner(): %s.\n"),
+		(is_client_when_true == true) ? "client": "server"));
+
+	m_am_wauth->set_am_partner(
+		wauth );
+
+	return wauth;
+}	
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_wlan_authentication_c::wapi_wlan_authentication_c(
+	abs_eap_am_tools_c * const tools,
+	abs_wapi_wlan_authentication_c * const partner,
+	wapi_am_wlan_authentication_c * const am_wauth, ///< wapi_wlan_authentication_c must always delete the am_wauth object.
+	const bool is_client_when_true)
+: m_partner(partner)
+, m_am_wauth(am_wauth)
+, m_ethernet_core(0)
+, m_am_tools(tools)
+, m_preshared_key(tools)
+, m_authentication_type(eapol_key_authentication_type_none)
+, m_802_11_authentication_mode(eapol_key_802_11_authentication_mode_none)
+, m_received_WAPI_IE(tools)
+, m_sent_WAPI_IE(tools)
+, m_group_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)
+, m_pairwise_key_cipher_suite(eapol_RSNA_key_header_c::eapol_RSNA_cipher_none)
+, m_authentication_counter(0u)
+, m_successful_authentications(0u)
+, m_failed_authentications(0u)
+, m_is_valid(false)
+, m_is_client(is_client_when_true)
+, m_shutdown_was_called(false)
+#if defined(USE_EAP_ERROR_TESTS)
+, m_error_probability(0u)
+, m_randomly_drop_packets_probability(0u)
+, m_generate_multiple_error_packets(0u)
+, m_enable_random_errors(false)
+, m_randomly_drop_packets(false)
+, m_manipulate_ethernet_header(false)
+, m_send_original_packet_first(false)
+#endif //#if defined(USE_EAP_ERROR_TESTS)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("starts: wapi_wlan_authentication_c::wapi_wlan_authentication_c(): %s, this = 0x%08x => 0x%08x, compiled %s %s.\n"),
+		(m_is_client == true) ? "client": "server",
+		this,
+		dynamic_cast<abs_eap_base_timer_c *>(this),
+		__DATE__,
+		__TIME__));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns: wapi_wlan_authentication_c::wapi_wlan_authentication_c()");
+
+	if (m_am_wauth == 0
+		|| m_am_wauth->get_is_valid() == false)
+	{
+		// ERROR.
+		if (m_am_wauth != 0)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+				(EAPL("calls: wapi_wlan_authentication_c::wapi_wlan_authentication_c(): m_am_wauth->shutdown(): %s.\n"),
+				(is_client_when_true == true) ? "client": "server"));
+
+			m_am_wauth->shutdown();
+			delete am_wauth;
+		}
+		return;
+	}
+
+	if (m_am_tools == 0
+		|| m_am_tools->get_is_valid() == false)
+	{
+		// ERROR.
+		if (m_am_wauth != 0)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+				(EAPL("calls: wapi_wlan_authentication_c::wapi_wlan_authentication_c(): m_am_wauth->shutdown(): %s.\n"),
+				(is_client_when_true == true) ? "client": "server"));
+
+			m_am_wauth->shutdown();
+			delete am_wauth;
+		}
+		return;
+	}
+
+	m_is_valid = true;
+}	
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_wlan_authentication_c::~wapi_wlan_authentication_c()
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("partner calls: wapi_wlan_authentication_c::~wapi_wlan_authentication_c(): this = 0x%08x\n"),
+		this));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: wapi_wlan_authentication_c::~wapi_wlan_authentication_c()");
+
+	EAP_ASSERT(m_shutdown_was_called == true);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::shutdown()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("partner calls: wapi_wlan_authentication_c::shutdown(); %s, m_shutdown_was_called=%d\n"),
+		(m_is_client == true) ? "client": "server",
+		m_shutdown_was_called));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: wapi_wlan_authentication_c::shutdown()");
+
+	if (m_shutdown_was_called == true)
+	{
+		// Shutdown was already called once.
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+	}
+	m_shutdown_was_called = true;
+	
+	// Cancel timer	
+	cancel_all_timers();
+
+	// Delete upper stack if it still exists
+	if (m_ethernet_core != 0)
+	{
+		WAUTH_ENTER_MUTEX(m_am_tools);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls eapol: wapi_wlan_authentication_c::shutdown(): m_ethernet_core->shutdown(): %s.\n"),
+			(m_is_client == true) ? "client": "server"));
+
+		eap_status_e status = m_ethernet_core->shutdown();
+		EAP_UNREFERENCED_PARAMETER(status);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("returns from eapol: wapi_wlan_authentication_c::shutdown(): m_ethernet_core->shutdown(): %s, status = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			eap_status_string_c::get_status_string(status)));
+
+		WAUTH_LEAVE_MUTEX(m_am_tools);
+
+		delete m_ethernet_core;
+		m_ethernet_core = 0;
+	}
+	
+	// Print some statistics
+	if (m_is_client)
+	{
+		EAP_TRACE_ALWAYS(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_TEST_VECTORS,
+			(EAPL("wapi_wlan_authentication_c::shutdown(): client authentication SUCCESS %d, FAILED %d, count %d\n"),
+			m_successful_authentications,
+			m_failed_authentications,
+			m_authentication_counter));	
+	}
+	else
+	{
+		EAP_TRACE_ALWAYS(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_TEST_VECTORS,
+			(EAPL("wapi_wlan_authentication_c::shutdown(): server authentication SUCCESS %d, FAILED %d, count %d\n"),
+			m_successful_authentications,
+			m_failed_authentications,
+			m_authentication_counter));
+	}
+
+
+	if (m_am_wauth != 0)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls: wapi_wlan_authentication_c::shutdown(): m_am_wauth->shutdown(): %s.\n"),
+			(m_is_client == true) ? "client": "server"));
+
+		m_am_wauth->shutdown();
+		delete m_am_wauth;
+		m_am_wauth = 0;
+	}
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAUTH EXITING.\n")));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return eap_status_ok;
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_wlan_authentication_c::cancel_all_authentication_sessions()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_wlan_authentication_c::cancel_all_authentication_sessions(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (m_ethernet_core != 0)
+	{
+		WAUTH_ENTER_MUTEX(m_am_tools);
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls eapol: wapi_wlan_authentication_c::cancel_all_authentication_sessions(): m_ethernet_core->cancel_all_authentication_sessions(): %s.\n"),
+			(m_is_client == true) ? "client": "server"));
+		status = m_ethernet_core->cancel_all_authentication_sessions();
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("returns from eapol: wapi_wlan_authentication_c::cancel_all_authentication_sessions(): m_ethernet_core->cancel_all_authentication_sessions(): %s, status = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			eap_status_string_c::get_status_string(status)));
+		WAUTH_LEAVE_MUTEX(m_am_tools);
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("wapi_wlan_authentication_c::cancel_all_authentication_sessions(): Stack did not exists.\n")));
+		status = eap_status_process_general_error;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::start_authentication(
+	const eap_variable_data_c * const SSID,
+	const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+	const eap_variable_data_c * const preshared_key,
+	const bool WAPI_override_enabled,
+	const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address.
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("partner calls: wapi_wlan_authentication_c::start_authentication(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("Starting authentication, selected_eapol_key_authentication_type = %d.\n"),
+		selected_eapol_key_authentication_type));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: wapi_wlan_authentication_c::start_authentication()");
+
+	eap_status_e status(eap_status_ok);
+
+	status = cancel_all_authentication_sessions();
+	if (status != eap_status_ok)
+	{
+		(void) EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	m_authentication_type = selected_eapol_key_authentication_type;
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::start_authentication(): m_am_wauth->set_wlan_parameters(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	status = m_am_wauth->set_wlan_parameters(
+		SSID,
+		WAPI_override_enabled,
+		preshared_key,
+		m_authentication_type);
+	if (status != eap_status_ok)
+	{
+		(void) disassociation(0); // Note we have no addresses yet.
+
+		(void) wapi_indication(
+			0, // Note we have no addresses yet.
+			eapol_wlan_authentication_state_failed_completely);
+
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::start_authentication(): m_am_wauth->reset_wapi_configuration(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	status = m_am_wauth->reset_wapi_configuration();
+	if (status != eap_status_ok)
+	{
+		(void) disassociation(0); // Note we have no addresses yet.
+
+		(void) wapi_indication(
+			0, // Note we have no addresses yet.
+			eapol_wlan_authentication_state_failed_completely);
+
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::start_authentication(): m_am_wauth->get_wlan_configuration(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+
+	status = m_am_wauth->get_wlan_configuration(
+		&m_preshared_key);
+	if (status != eap_status_ok)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// Start new authentication from scratch.
+	// WAPI uses always open 802.11 mode.
+	m_802_11_authentication_mode = eapol_key_802_11_authentication_mode_open;
+	
+	// USE_WAPI_CORE needs to be defined in the common code the
+	// get this if compiled
+	if( m_authentication_type == eapol_key_authentication_type_WAI_PSK )
+	{
+		EAP_TRACE_ALWAYS(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("start_authentication(): Trying auth mode OPEN and WAI-PSK.\n")));
+	}
+	else
+	{
+		EAP_TRACE_ALWAYS(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("start_authentication(): Trying auth mode OPEN and WAI certificates.\n")));
+	}
+
+	WAUTH_ENTER_MUTEX(m_am_tools);
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls eapol: wapi_wlan_authentication_c::start_authentication(): m_ethernet_core->create_state(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+	status = m_ethernet_core->create_state(
+		receive_network_id,
+		m_authentication_type
+		);
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("returns from eapol: wapi_wlan_authentication_c::start_authentication(): m_ethernet_core->create_state(): %s, status = %s.\n"),
+		(m_is_client == true) ? "client": "server",
+		eap_status_string_c::get_status_string(status)));
+	WAUTH_LEAVE_MUTEX(m_am_tools);
+	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls partner: wapi_wlan_authentication_c::start_authentication(): m_partner->associate(%d).\n"),
+		m_802_11_authentication_mode));
+
+	status = m_partner->associate(m_802_11_authentication_mode);
+	(void)EAP_STATUS_RETURN(m_am_tools, status);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("returns from partner: wapi_wlan_authentication_c::start_authentication(): %s: m_partner->associate(): status = %s\n"),
+		 (m_is_client == true) ? "client": "server",
+		 eap_status_string_c::get_status_string(status)));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status); 
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::complete_association(
+	const eapol_wlan_authentication_state_e association_result,
+	const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+	const eap_variable_data_c * const received_WAPI_IE,
+	const eap_variable_data_c * const sent_WAPI_IE,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+		(EAPL("partner calls: wapi_wlan_authentication_c::complete_association(): %s: association_result=%d\n"),
+		(m_is_client == true) ? "client": "server",
+		association_result));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: wapi_wlan_authentication_c::complete_association()");
+
+	eap_status_e status(eap_status_ok);
+
+	// ASSOCIATION UNSUCCESSFUL
+	if (association_result != eapol_wlan_authentication_state_association_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("complete_association: Unsuccessful.\n")));
+
+		EAP_TRACE_DATA_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("Got AP MAC address"),
+			receive_network_id->get_source(),
+			receive_network_id->get_source_length()));
+
+			EAP_TRACE_ALWAYS(
+				m_am_tools,
+				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+				(EAPL("Could not associate to the AP.\n")));
+
+			EAP_TRACE_ALWAYS(
+				m_am_tools,
+				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+				(EAPL("Indication sent to WLM: eap_status_this_ap_failed.\n")));
+
+			(void) disassociation(receive_network_id);
+
+			status = wapi_indication(
+				receive_network_id,
+				eapol_wlan_authentication_state_this_ap_failed);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+
+	}
+	
+	// ASSOCIATION SUCCESSFUL
+	EAP_TRACE_ALWAYS(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+		(EAPL("complete_association: Successful.\n")));
+
+	// Store parameters
+
+	if (m_authentication_type == eapol_key_authentication_type_WAI_certificate
+	   || m_authentication_type == eapol_key_authentication_type_WAI_PSK)
+	{
+		status = m_received_WAPI_IE.set_copy_of_buffer(received_WAPI_IE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		status = m_sent_WAPI_IE.set_copy_of_buffer(sent_WAPI_IE);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	m_group_key_cipher_suite = group_key_cipher_suite;
+
+	m_pairwise_key_cipher_suite = pairwise_key_cipher_suite;
+
+	eap_variable_data_c * preshared_key = 0;
+
+	if (m_authentication_type == eapol_key_authentication_type_WAI_PSK)
+	{
+		preshared_key = &m_preshared_key;
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::complete_association(): m_am_wauth->association(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	status = m_am_wauth->association(receive_network_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	WAUTH_ENTER_MUTEX(m_am_tools);
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls eapol: wapi_wlan_authentication_c::complete_association(): m_ethernet_core->association(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+	status = m_ethernet_core->association(
+		receive_network_id,
+		m_authentication_type,
+		&m_received_WAPI_IE,
+		&m_sent_WAPI_IE,
+		pairwise_key_cipher_suite,
+		group_key_cipher_suite,
+		preshared_key);
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("returns from eapol: wapi_wlan_authentication_c::complete_association(): m_ethernet_core->association(): %s, status = %s.\n"),
+		(m_is_client == true) ? "client": "server",
+		eap_status_string_c::get_status_string(status)));
+	WAUTH_LEAVE_MUTEX(m_am_tools);
+
+	if (status != eap_status_ok)
+	{
+
+		EAP_TRACE_ALWAYS(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+			(EAPL("m_ethernet_core->association call failed.\n")));
+
+		EAP_TRACE_ALWAYS(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+			(EAPL("Indication sent to WLM: eap_status_failed_completely.\n")));
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls: wapi_wlan_authentication_c::complete_association(): this->disassociation(): %s.\n"),
+			(m_is_client == true) ? "client": "server"));
+
+		(void) disassociation(receive_network_id);
+
+		status = wapi_indication(
+			receive_network_id,
+			eapol_wlan_authentication_state_failed_completely);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+	}
+	
+	// Start waiting for authentication messages
+	
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::check_bksa_cache(
+	eap_array_c<eap_am_network_id_c> * const bssid_sta_receive_network_ids,
+	const eapol_key_authentication_type_e selected_eapol_key_authentication_type,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("partner calls: wapi_wlan_authentication_c::check_bksa_cache(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: wapi_wlan_authentication_c::check_bksa_cache()");
+
+	WAUTH_ENTER_MUTEX(m_am_tools);
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls eapol: wapi_wlan_authentication_c::check_bksa_cache(): m_ethernet_core->check_bksa_cache(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+	eap_status_e status = m_ethernet_core->check_bksa_cache(
+		bssid_sta_receive_network_ids,
+		selected_eapol_key_authentication_type,
+		pairwise_key_cipher_suite,
+		group_key_cipher_suite);
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("returns from eapol: wapi_wlan_authentication_c::check_bksa_cache(): m_ethernet_core->check_bksa_cache(): %s, status = %s.\n"),
+		(m_is_client == true) ? "client": "server",
+		eap_status_string_c::get_status_string(status)));
+	WAUTH_LEAVE_MUTEX(m_am_tools);
+
+	if (bssid_sta_receive_network_ids->get_object_count() == 0)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("WARNING: wapi_wlan_authentication_c::check_bksa_cache(): %s: No BKSA:s found in cache.\n"),
+			(m_is_client == true) ? "client": "server"));
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::start_reassociation(
+	const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address.
+	const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address.
+	const eapol_key_authentication_type_e selected_eapol_key_authentication_type 
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("partner calls: wapi_wlan_authentication_c::start_reassociation(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: wapi_wlan_authentication_c::start_reassociation()");
+
+	{
+		EAP_TRACE_DATA_DEBUG(m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("old_receive_network_id source:"),
+			old_receive_network_id->get_source_id()->get_data(),
+			old_receive_network_id->get_source_id()->get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("old_receive_network_id destination:"),
+			old_receive_network_id->get_destination_id()->get_data(),
+			old_receive_network_id->get_destination_id()->get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("new_receive_network_id source:"),
+			new_receive_network_id->get_source_id()->get_data(),
+			new_receive_network_id->get_source_id()->get_data_length()));
+
+		EAP_TRACE_DATA_DEBUG(m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("new_receive_network_id destination:"),
+			new_receive_network_id->get_destination_id()->get_data(),
+			new_receive_network_id->get_destination_id()->get_data_length()));
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_status_e status = cancel_all_authentication_sessions();
+	if (status != eap_status_ok)
+	{
+		(void) EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::start_reassociation(): m_am_wauth->reset_wapi_configuration(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	status = m_am_wauth->reset_wapi_configuration();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	eap_variable_data_c reassociation_BKID(m_am_tools);
+
+	WAUTH_ENTER_MUTEX(m_am_tools);
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls eapol: wapi_wlan_authentication_c::start_reassociation(): m_ethernet_core->read_reassociation_parameters(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	status = m_ethernet_core->read_reassociation_parameters(
+		old_receive_network_id,
+		new_receive_network_id,
+		selected_eapol_key_authentication_type,
+		&reassociation_BKID,
+		0,
+		0);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("returns from eapol: wapi_wlan_authentication_c::start_reassociation(): m_ethernet_core->read_reassociation_parameters(): %s, status = %s.\n"),
+		(m_is_client == true) ? "client": "server",
+		eap_status_string_c::get_status_string(status)));
+	WAUTH_LEAVE_MUTEX(m_am_tools);
+
+	if (status == eap_status_ok)
+	{
+		// Here we swap the addresses.
+		eap_am_network_id_c send_network_id(
+			m_am_tools,
+			new_receive_network_id->get_destination_id(),
+			new_receive_network_id->get_source_id(),
+			new_receive_network_id->get_type());
+		if (send_network_id.get_is_valid_data() == false)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+		}
+
+		m_authentication_type = selected_eapol_key_authentication_type;
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls partner: wapi_wlan_authentication_c::start_reassociation(): %s: m_partner->reassociate(): m_authentication_type=%d.\n"),
+			 (m_is_client == true) ? "client": "server",
+			 m_authentication_type));
+
+		status = m_partner->reassociate(
+			&send_network_id,
+			m_authentication_type,
+			&reassociation_BKID);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("returns from partner: wapi_wlan_authentication_c::start_reassociation(): %s: m_partner->reassociate(): status = %s\n"),
+			 (m_is_client == true) ? "client": "server",
+			 eap_status_string_c::get_status_string(status)));
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::complete_reassociation(
+	const eapol_wlan_authentication_state_e reassociation_result,
+	const eap_am_network_id_c * const receive_network_id,
+	const eap_variable_data_c * const received_WAPI_IE,
+	const eap_variable_data_c * const sent_WAPI_IE,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite,
+	const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("partner calls: wapi_wlan_authentication_c::complete_reassociation(): %s, reassociation_result=%d\n"),
+		(m_is_client == true) ? "client": "server",
+		reassociation_result));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: wapi_wlan_authentication_c::complete_reassociation()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (reassociation_result != eapol_wlan_authentication_state_association_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("complete_reassociation: Unsuccessful.\n")));
+
+		WAUTH_ENTER_MUTEX(m_am_tools);
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls eapol: wapi_wlan_authentication_c::complete_reassociation(): m_ethernet_core->remove_bksa_from_cache(): %s.\n"),
+			(m_is_client == true) ? "client": "server"));
+		status = m_ethernet_core->remove_bksa_from_cache(
+			receive_network_id);
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("returns from eapol: wapi_wlan_authentication_c::complete_reassociation(): m_ethernet_core->remove_bksa_from_cache(): %s, status = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			eap_status_string_c::get_status_string(status)));
+		WAUTH_LEAVE_MUTEX(m_am_tools);
+
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure);
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("complete_reassociation: Successful.\n")));
+
+		WAUTH_ENTER_MUTEX(m_am_tools);
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls eapol: wapi_wlan_authentication_c::complete_reassociation(): m_ethernet_core->complete_reassociation(): %s.\n"),
+			(m_is_client == true) ? "client": "server"));
+		status = m_ethernet_core->complete_reassociation(
+			reassociation_result,
+			receive_network_id,
+			m_authentication_type,
+			received_WAPI_IE,
+			sent_WAPI_IE,
+			pairwise_key_cipher_suite,
+			group_key_cipher_suite);
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("returns from eapol: wapi_wlan_authentication_c::complete_reassociation(): m_ethernet_core->complete_reassociation(): %s, status = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			eap_status_string_c::get_status_string(status)));
+		WAUTH_LEAVE_MUTEX(m_am_tools);
+
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::packet_process(
+	const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+	eap_general_header_base_c * const packet_data,
+	const u32_t packet_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("partner calls: wapi_wlan_authentication_c::packet_process(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: wapi_wlan_authentication_c::packet_process()");
+
+	if (packet_length < eapol_ethernet_header_wr_c::get_header_length())
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message);
+	}
+
+	eapol_ethernet_header_wr_c eth_header(
+		m_am_tools,
+		packet_data->get_header_buffer(packet_length),
+		packet_length);
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (eth_header.get_type() == eapol_ethernet_type_wapi)
+	{
+		// Forward the packet to the Ethernet layer of the WAPI stack.
+		// Ignore return value. Failure is signalled using state_notification.
+		WAUTH_ENTER_MUTEX(m_am_tools);
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls eapol: wapi_wlan_authentication_c::packet_process(): m_ethernet_core->packet_process(): %s.\n"),
+			(m_is_client == true) ? "client": "server"));
+		status = m_ethernet_core->packet_process(
+			receive_network_id,
+			&eth_header,
+			packet_length);
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("returns from eapol: wapi_wlan_authentication_c::packet_process(): m_ethernet_core->packet_process(): %s, status = %s.\n"),
+			(m_is_client == true) ? "client": "server",
+			eap_status_string_c::get_status_string(status)));
+		WAUTH_LEAVE_MUTEX(m_am_tools);
+
+		EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eth_header);
+	} 
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("WAPI: Not supported ethernet type 0x%04x\n"), eth_header.get_type()));
+		status = eap_status_ethernet_type_not_supported;
+	}
+	
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void wapi_wlan_authentication_c::set_is_valid()
+{
+	m_is_valid = true;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool wapi_wlan_authentication_c::get_is_valid()
+{
+	return m_is_valid;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT void wapi_wlan_authentication_c::increment_authentication_counter()
+{
+	++m_authentication_counter;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT u32_t wapi_wlan_authentication_c::get_authentication_counter()
+{
+	return m_authentication_counter;
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool wapi_wlan_authentication_c::get_is_client()
+{
+	return m_is_client;
+}
+	
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::packet_data_session_key(
+	const eap_am_network_id_c * const send_network_id,
+	const eapol_session_key_c * const key)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	eap_status_e status(eap_status_ok);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::packet_data_session_key(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::packet_data_session_key()");
+
+	const eap_variable_data_c * const key_data = key->get_key();
+	if (key_data == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error);
+	}
+
+	EAP_TRACE_DEBUG(m_am_tools,
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_wlan_authentication_c::packet_data_session_key(): %s: key_type 0x%02x, key_index %d\n"),
+		(m_is_client == true) ? "client": "server",
+		key->get_key_type(),
+		key->get_key_index()));
+
+	EAP_TRACE_DATA_DEBUG(m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("packet_data_session_key:"),
+		key_data->get_data(key_data->get_data_length()),
+		key_data->get_data_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("packet_data_session_key      send source"), 
+		 send_network_id->get_source(),
+		 send_network_id->get_source_length()));
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("packet_data_session_key send destination"), 
+		 send_network_id->get_destination(),
+		 send_network_id->get_destination_length()));
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls partner: wapi_wlan_authentication_c::packet_data_session_key(): %s: m_partner->packet_data_session_key()\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	status = m_partner->packet_data_session_key(send_network_id, key);
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("returns from partner: wapi_wlan_authentication_c::packet_data_session_key(): %s: m_partner->packet_data_session_key(): status = %s\n"),
+		 (m_is_client == true) ? "client": "server",
+		 eap_status_string_c::get_status_string(status)));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+#if defined(USE_EAP_ERROR_TESTS)
+
+//
+eap_status_e wapi_wlan_authentication_c::random_error(
+	eap_buf_chain_wr_c * const sent_packet,
+	const bool forse_error,
+	const u32_t packet_index)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = eap_status_ok;
+
+	crypto_random_c rand(m_am_tools);
+	u32_t minimum_index = 0;
+
+	sent_packet->set_is_client(false);
+
+	if (m_manipulate_ethernet_header == false)
+	{
+		minimum_index = eapol_ethernet_header_wr_c::get_header_length();
+	}
+
+	status = m_am_tools->generate_random_error(
+		sent_packet,
+		forse_error,
+		packet_index,
+		minimum_index,
+		m_error_probability,
+		eapol_ethernet_header_wr_c::get_header_length());
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return status;
+}
+
+#endif //#if defined(USE_EAP_ERROR_TESTS)
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::packet_send(
+	const eap_am_network_id_c * const send_network_id,
+	eap_buf_chain_wr_c * const sent_packet,
+	const u32_t header_offset,
+	const u32_t data_length,
+	const u32_t buffer_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::packet_send(data_length=%d): %s.\n"),
+		data_length,
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::packet_send()");
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	if (header_offset != 0u)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("packet_send: packet buffer corrupted.\n")));
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+	}
+	else if (header_offset+data_length != sent_packet->get_data_length())
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ERROR: packet_send: packet buffer corrupted (data_length != sent_packet->get_data_length()).\n")));
+		EAP_ASSERT(data_length == sent_packet->get_buffer_length());
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);
+	}	
+
+	eap_status_e status(eap_status_ok);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls partner: wapi_wlan_authentication_c::packet_send(): %s: m_partner->packet_send()\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+
+#if defined(USE_EAP_ERROR_TESTS)
+
+	if (m_randomly_drop_packets == true)
+	{
+		u32_t random_guard;
+		crypto_random_c rand(m_am_tools);
+		status = rand.get_rand_bytes(
+			reinterpret_cast<u8_t *>(&random_guard),
+			sizeof(random_guard));
+		if (status != eap_status_ok)
+		{
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+
+		// This is simple limiter to the probability of a packet drop.
+		// probability = m_randomly_drop_packets_probability / (2^32)
+		if (random_guard < m_randomly_drop_packets_probability)
+		{
+			// Drops this packet.
+
+			if (sent_packet->get_stack_address() == 0)
+			{
+				// Initialize error testing data.
+				sent_packet->set_stack_address(this);
+				m_am_tools->increase_packet_index();
+				sent_packet->set_send_packet_index(m_am_tools->get_packet_index());
+			}
+
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send packet dropped\n"),
+				sent_packet->get_stack_address(),
+				sent_packet->get_send_packet_index()));
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return eap_status_ok;
+		}
+	}
+
+
+	if (m_send_original_packet_first == true
+		&& m_generate_multiple_error_packets > 0ul)
+	{
+		if (sent_packet->get_stack_address() == 0)
+		{
+			// Initialize error testing data.
+			sent_packet->set_stack_address(this);
+			m_am_tools->increase_packet_index();
+			sent_packet->set_send_packet_index(m_am_tools->get_packet_index());
+		}
+
+		if (sent_packet->get_is_manipulated() == false)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send original packet\n"),
+				sent_packet->get_stack_address(),
+				sent_packet->get_send_packet_index()));
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send original already manipulated packet\n"),
+				sent_packet->get_stack_address(),
+				sent_packet->get_send_packet_index()));
+		}
+
+#endif //#if defined(USE_EAP_ERROR_TESTS)
+
+
+		// Here we send the original packet.
+		status = m_partner->packet_send(
+			send_network_id,
+			sent_packet,
+			header_offset,
+			data_length,
+			buffer_length);
+
+
+#if defined(USE_EAP_ERROR_TESTS)
+	}
+#endif //#if defined(USE_EAP_ERROR_TESTS)
+
+
+#if defined(USE_EAP_ERROR_TESTS)
+
+	if (m_enable_random_errors == true)
+	{
+		if (m_generate_multiple_error_packets > 0ul)
+		{
+			// First create a copy of sent packet. Original correct packet will be sent last.
+			for (u32_t ind = 0ul; ind < m_generate_multiple_error_packets; ind++)
+			{
+				eap_buf_chain_wr_c *copy_packet = sent_packet->copy();
+
+				if (copy_packet != 0
+					&& copy_packet->get_is_valid_data() == true)
+				{
+					m_am_tools->increase_packet_index();
+					copy_packet->set_send_packet_index(m_am_tools->get_packet_index());
+
+					// Make a random error to the copy message.
+					random_error(copy_packet, true, copy_packet->get_send_packet_index());
+
+					EAP_TRACE_DEBUG(
+						m_am_tools, 
+						TRACE_FLAGS_DEFAULT, 
+						(EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send error packet\n"),
+						copy_packet->get_stack_address(),
+						copy_packet->get_send_packet_index()));
+
+					// Here we send the copied and manipulated packet.
+					status = m_partner->packet_send(
+						send_network_id,
+						copy_packet,
+						header_offset,
+						data_length,
+						buffer_length
+						);
+				}
+
+				delete copy_packet;
+			}
+		}
+		else
+		{
+			if (sent_packet->get_stack_address() == 0)
+			{
+				// Initialize error testing data.
+				sent_packet->set_stack_address(this);
+				m_am_tools->increase_packet_index();
+				sent_packet->set_send_packet_index(m_am_tools->get_packet_index());
+			}
+
+			eap_buf_chain_wr_c *copy_packet = sent_packet->copy();
+
+			if (copy_packet != 0
+				&& copy_packet->get_is_valid_data() == true)
+			{
+				m_am_tools->increase_packet_index();
+				copy_packet->set_send_packet_index(m_am_tools->get_packet_index());
+
+				// Make a random error to the original message.
+				random_error(copy_packet, false, copy_packet->get_send_packet_index());
+
+				if (copy_packet->get_is_manipulated() == true)
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools, 
+						TRACE_FLAGS_DEFAULT, 
+						(EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send error packet\n"),
+						copy_packet->get_stack_address(),
+						copy_packet->get_send_packet_index()));
+
+					// Here we send the copied and manipulated packet.
+					status = m_partner->packet_send(
+						send_network_id,
+						copy_packet,
+						header_offset,
+						data_length,
+						buffer_length);
+				}
+			}
+
+			delete copy_packet;
+		}
+	}
+
+
+	if (m_send_original_packet_first == false)
+	{
+		if (sent_packet->get_stack_address() == 0)
+		{
+			// Initialize error testing data.
+			sent_packet->set_stack_address(this);
+			m_am_tools->increase_packet_index();
+			sent_packet->set_send_packet_index(m_am_tools->get_packet_index());
+		}
+
+		if (sent_packet->get_is_manipulated() == false)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send original packet\n"),
+				sent_packet->get_stack_address(),
+				sent_packet->get_send_packet_index()));
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send original already manipulated packet\n"),
+				sent_packet->get_stack_address(),
+				sent_packet->get_send_packet_index()));
+		}
+
+		// Here we send the original packet.
+		status = m_partner->packet_send(
+			send_network_id,
+			sent_packet,
+			header_offset,
+			data_length,
+			buffer_length
+			);
+
+		//m_am_tools->increase_packet_index();
+	}
+	else if (m_generate_multiple_error_packets == 0ul
+		|| m_enable_random_errors == false)
+	{
+		if (sent_packet->get_stack_address() == 0)
+		{
+			// Initialize error testing data.
+			sent_packet->set_stack_address(this);
+			m_am_tools->increase_packet_index();
+			sent_packet->set_send_packet_index(m_am_tools->get_packet_index());
+		}
+
+		if (sent_packet->get_is_manipulated() == true)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send error packet\n"),
+				sent_packet->get_stack_address(),
+				sent_packet->get_send_packet_index()));
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("TEST: random_error(): packet_index 0x%08x:%lu, Send original packet\n"),
+				sent_packet->get_stack_address(),
+				sent_packet->get_send_packet_index()));
+		}
+
+		// Here we send the original possibly manipulated packet.
+		status = m_partner->packet_send(
+			send_network_id,
+			sent_packet,
+			header_offset,
+			data_length,
+			buffer_length
+			);
+
+		//m_am_tools->increase_packet_index();
+	}
+
+#endif //#if defined(USE_EAP_ERROR_TESTS)
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("returns from partner: wapi_wlan_authentication_c::packet_send(): %s: m_partner->packet_send(): status = %s\n"),
+		 (m_is_client == true) ? "client": "server",
+		 eap_status_string_c::get_status_string(status)));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_wlan_authentication_c::cancel_timer_this_ap_failed()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = cancel_timer(
+		this,
+		WAPI_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_wlan_authentication_c::cancel_timer_this_ap_failed(): Cancels timer WAPI_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID.\n")));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_wlan_authentication_c::cancel_timer_failed_completely()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = cancel_timer(
+		this,
+		WAPI_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_wlan_authentication_c::cancel_timer_failed_completely(): Cancels timer WAPI_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID.\n")));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_wlan_authentication_c::cancel_timer_no_response()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = cancel_timer(
+		this,
+		WAPI_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_wlan_authentication_c::cancel_timer_no_response(): Cancels timer WAPI_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID.\n")));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_wlan_authentication_c::cancel_timer_authentication_cancelled()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = cancel_timer(
+		this,
+		WAPI_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_wlan_authentication_c::cancel_timer_authentication_cancelled(): Cancels timer WAPI_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID.\n")));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT void wapi_wlan_authentication_c::state_notification(
+	const abs_eap_state_notification_c * const state)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::state_notification()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::state_notification()");
+
+	if (state == 0 
+		|| state->get_send_network_id() == 0
+		|| state->get_send_network_id()->get_is_valid_data() == false)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ERROR: Illegal state notification state=0x%08x, state->get_send_network_id()=0x%08x.\n"),
+			state,
+			((state != 0) ? state->get_send_network_id() : 0)));
+		(void)EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+		return;
+	}
+
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("    send source"),
+		 state->get_send_network_id()->get_source(),
+		 state->get_send_network_id()->get_source_length()));
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("send destination"),
+		 state->get_send_network_id()->get_destination(),
+		 state->get_send_network_id()->get_destination_length()));
+
+	// Here we swap the addresses.
+	eap_am_network_id_c receive_network_id(m_am_tools,
+		state->get_send_network_id()->get_destination_id(),
+		state->get_send_network_id()->get_source_id(),
+		state->get_send_network_id()->get_type());
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	eap_am_network_id_c* send_network_id = new eap_am_network_id_c(
+		m_am_tools,
+		state->get_send_network_id());
+
+	eap_automatic_variable_c<eap_am_network_id_c>
+		automatic_send_network_id(m_am_tools, send_network_id);
+
+	if (send_network_id == 0 
+		|| send_network_id->get_is_valid_data() == false)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("ERROR: No network identity: Indication sent to WLM: eap_status_failed_completely.\n")));
+
+		(void) cancel_timer_failed_completely();
+
+		set_timer(
+			this,
+			WAPI_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID,
+			send_network_id,
+			0);
+		
+		automatic_send_network_id.do_not_free_variable();
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("Sets timer ")
+			 EAPL("WAPI_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID.\n")));
+	}
+
+
+	{
+		eap_status_string_c status_string;
+		eap_header_string_c eap_string;
+
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_wlan_authentication_c::state_notification() %s: protocol layer %d=%s, protocol %d=%s, 0x%08x=%s\n"),
+			(state->get_is_client() == true ? "client": "server"),
+			state->get_protocol_layer(),
+			state->get_protocol_layer_string(),
+			state->get_protocol(),
+			state->get_protocol_string(),
+			convert_eap_type_to_u32_t(state->get_eap_type()),
+			eap_string.get_eap_type_string(state->get_eap_type())));
+
+		EAP_TRACE_DEBUG(
+			m_am_tools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("wapi_wlan_authentication_c::state_notification() %s: current state %d=%s, error %d=%s\n"),
+			(state->get_is_client() == true ? "client": "server"),
+			state->get_current_state(),
+			state->get_current_state_string(),
+			state->get_authentication_error(),
+			status_string.get_status_string(state->get_authentication_error())));
+	}
+
+#if 0
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls partner: wapi_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"),
+		 (m_is_client == true) ? "client": "server"));
+
+	// Calls lower layer.
+	// Note the optimization prevents most of the state notifications to lower layer.
+	m_partner->state_notification(state);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("returns from partner: wapi_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"),
+		 (m_is_client == true) ? "client": "server"));
+#endif
+
+	// ****
+	// TODO: Check if these functionalities are ok for WAPI
+	// as a treatment for general layer failures;
+	// WAPI failure has its own protocol layer: eap_protocol_layer_wapi
+	
+	if(state->get_protocol_layer() == eap_protocol_layer_general)
+	{
+		if (state->get_current_state() == eap_general_state_authentication_cancelled)
+		{
+			// Authentication was cancelled. Cannot continue.
+			cancel_timer_authentication_cancelled();
+
+			set_timer(this, WAPI_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID, send_network_id, 0);
+			automatic_send_network_id.do_not_free_variable();
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("Authentication was cancelled. Sets timer ")
+				 EAPL("WAPI_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID.\n")));
+
+			// This indication is sent synchronously to WLAN engine. That prevent other indications to bypass this indication.
+			eap_status_e status = wapi_indication(
+				&receive_network_id,
+				eapol_wlan_authentication_state_authentication_cancelled);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				(void)EAP_STATUS_RETURN(m_am_tools, status);
+				return;
+			}
+		}
+		else if (state->get_current_state() == eap_general_state_configuration_error)
+		{
+			// Configuration error. Cannot continue.
+			(void) cancel_timer_failed_completely();
+
+			set_timer(this, WAPI_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID, send_network_id, 0);
+			automatic_send_network_id.do_not_free_variable();
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("Configuration error. Sets timer ")
+				 EAPL("WAPI_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID.\n")));
+		}
+		else if (state->get_current_state() == eap_general_state_authentication_error)
+		{
+			// An authentication error from WAPI stack.
+
+			eap_status_string_c status_string;
+			eap_header_string_c eap_string;
+
+			EAP_TRACE_ERROR(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: wapi_wlan_authentication_c::state_notification() %s: protocol layer %d=%s, protocol %d=%s, 0x%08x=%s\n"),
+				(state->get_is_client() == true ? "client": "server"),
+				state->get_protocol_layer(),
+				state->get_protocol_layer_string(),
+				state->get_protocol(),
+				state->get_protocol_string(),
+				convert_eap_type_to_u32_t(state->get_eap_type()),
+				eap_string.get_eap_type_string(state->get_eap_type())));
+
+			EAP_TRACE_ERROR(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("ERROR: wapi_wlan_authentication_c::state_notification() %s: current state %d=%s, error %d=%s\n"),
+				(state->get_is_client() == true ? "client": "server"),
+				state->get_current_state(),
+				state->get_current_state_string(),
+				state->get_authentication_error(),
+				status_string.get_status_string(state->get_authentication_error())));
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+				(EAPL("calls partner: wapi_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"),
+				 (m_is_client == true) ? "client": "server"));
+
+			// Calls lower layer.
+			// Note the optimization prevents most of the state notifications to lower layer.
+			m_partner->state_notification(state);
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+				(EAPL("returns from partner: wapi_wlan_authentication_c::state_notification(): %s: m_partner->state_notification()\n"),
+				 (m_is_client == true) ? "client": "server"));
+
+			(void) cancel_timer_this_ap_failed();
+
+			set_timer(
+				this,
+				WAPI_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID,
+				send_network_id,
+				0);
+			automatic_send_network_id.do_not_free_variable();
+
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("Sets timer WAPI_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID.\n")));
+		}
+		else if (state->get_current_state() == eap_general_state_immediate_reconnect)
+		{
+			// An provision protocol ready. Do immediate reconnect to use the new credentials.
+
+			eap_status_string_c status_string;
+			eap_header_string_c eap_string;
+
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("wapi_wlan_authentication_c::state_notification() %s: protocol layer %d=%s, protocol %d=%s, 0x%08x=%s\n"),
+				(state->get_is_client() == true ? "client": "server"),
+				state->get_protocol_layer(),
+				state->get_protocol_layer_string(),
+				state->get_protocol(),
+				state->get_protocol_string(),
+				convert_eap_type_to_u32_t(state->get_eap_type()),
+				eap_string.get_eap_type_string(state->get_eap_type())));
+
+			EAP_TRACE_DEBUG(
+				m_am_tools, 
+				TRACE_FLAGS_DEFAULT, 
+				(EAPL("wapi_wlan_authentication_c::state_notification() %s: current state %d=%s, error %d=%s\n"),
+				(state->get_is_client() == true ? "client": "server"),
+				state->get_current_state(),
+				state->get_current_state_string(),
+				state->get_authentication_error(),
+				status_string.get_status_string(state->get_authentication_error())));
+
+				eap_status_e status = wapi_indication(
+					&receive_network_id,
+					eapol_wlan_authentication_state_immediate_reconnect);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return;
+				}
+		}
+	}
+	else if(state->get_protocol_layer() == eap_protocol_layer_wai)
+	{
+		switch (state->get_current_state())
+		{
+		case eapol_key_state_wapi_authentication_terminated_unsuccessfull:
+			{					
+				increment_authentication_counter();
+				m_failed_authentications++;
+
+				// Consider WAPI layer failures fatal.
+				EAP_TRACE_ERROR(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("ERROR: Unsuccessful authentication on WAI level.\n")));
+
+				(void) cancel_timer_this_ap_failed();
+
+				set_timer(
+					this,
+					WAPI_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID,
+					send_network_id,
+					0);
+				automatic_send_network_id.do_not_free_variable();
+
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("Sets timer WAPI_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID.\n")));
+			}
+			break;
+
+		case eapol_key_state_wapi_authentication_finished_successfull:
+			{
+				// This is used in WAI authentications.
+				increment_authentication_counter();
+				m_successful_authentications++;
+
+				EAP_TRACE_ALWAYS(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI: %s: Authentication SUCCESS\n"),
+					(m_is_client == true ? "client": "server")));
+
+				eap_status_e status = wapi_indication(
+					&receive_network_id,
+					eapol_wlan_authentication_state_authentication_successfull);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return;
+				}
+			}
+			break;
+
+		case eapol_key_state_wapi_authentication_running:
+			{
+				// This is used in dynamic WAI authentications.
+				EAP_TRACE_ALWAYS(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+					(EAPL("WAPI: %s: Authentication RUNNING\n"),
+					(m_is_client == true ? "client": "server")));
+
+				eap_status_e status = wapi_indication(
+					&receive_network_id,
+					eapol_wlan_authentication_state_wapi_authentication_running);
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return;
+				}
+			}
+			break;
+
+		default:
+			break;
+		}
+	}
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::state_notification(): m_am_wauth->state_notification(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	// AM could have to show some notification to user.
+	m_am_wauth->state_notification(state);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::timer_expired(
+	const u32_t id,
+	void * data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::timer_expired(): id = %d, data = 0x%08x.\n"),
+		id,
+		data));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::timer_expired()");
+
+
+	eap_am_network_id_c * const send_network_id = static_cast<eap_am_network_id_c *>(data);
+	if (send_network_id == 0 
+		|| send_network_id->get_is_valid_data() == false)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	// Here we swap the addresses.
+	eap_am_network_id_c receive_network_id(m_am_tools,
+		send_network_id->get_destination_id(),
+		send_network_id->get_source_id(),
+		send_network_id->get_type());
+
+
+	switch (id)
+	{
+	case WAPI_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID:
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID elapsed: ")
+				 EAPL("Indication sent to WLM: eap_status_failed_completely.\n")));
+
+			(void) disassociation_mutex_must_be_reserved(&receive_network_id);
+
+			eap_status_e status = wapi_indication(
+				&receive_network_id,
+				eapol_wlan_authentication_state_failed_completely);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		break;
+	
+	case WAPI_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID:
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID elapsed: ")
+				 EAPL("Indication sent to WLM: eap_status_this_ap_failed.\n")));
+
+			(void) disassociation_mutex_must_be_reserved(&receive_network_id);
+
+			eap_status_e status = wapi_indication(
+				&receive_network_id,
+				eapol_wlan_authentication_state_this_ap_failed);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		break;
+
+	case WAPI_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID:
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID elapsed: ")
+				 EAPL("Indication sent to WLM: eap_status_no_response.\n")));
+
+			(void) disassociation_mutex_must_be_reserved(&receive_network_id);
+
+			eap_status_e status = wapi_indication(
+				&receive_network_id,
+				eapol_wlan_authentication_state_no_response);
+			if (status != eap_status_ok)
+			{
+				EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+				return EAP_STATUS_RETURN(m_am_tools, status);
+			}
+		}
+		break;
+		
+	case WAPI_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID:
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("WAPI_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID elapsed: ")
+				 EAPL("Indication sent to WLM: eapol_wlan_authentication_state_authentication_cancelled.\n")));
+
+			(void) disassociation_mutex_must_be_reserved(&receive_network_id);
+		}
+		break;
+
+	default:
+		break;
+	}
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::timer_delete_data(
+	const u32_t id,
+	void *data)
+{
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::timer_delete_data(): id = %d, data = 0x%08x.\n"),
+		id,
+		data));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::timer_delete_data()");
+
+	eap_am_network_id_c * const send_network_id = static_cast<eap_am_network_id_c *>(data);
+	if (send_network_id == 0 
+		|| send_network_id->get_is_valid_data() == false)
+	{
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter);
+	}
+
+	switch (id)
+	{
+	case WAPI_WLAN_AUTHENTICATION_TIMER_FAILED_COMPLETELY_ID:
+	case WAPI_WLAN_AUTHENTICATION_TIMER_THIS_AP_FAILED_ID:
+	case WAPI_WLAN_AUTHENTICATION_TIMER_NO_RESPONSE_ID:
+	case WAPI_WLAN_AUTHENTICATION_TIMER_AUTHENTICATION_CANCELLED_ID:
+		delete send_network_id;
+		break;
+	default:
+		{
+			EAP_TRACE_ERROR(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("wapi_wlan_authentication_c::timer_delete_data: deleted unknown timer.\n")));
+			(void)EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported);
+		}
+	}
+
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT u32_t wapi_wlan_authentication_c::get_header_offset(
+	u32_t * const MTU,
+	u32_t * const trailer_length)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::get_header_offset()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::get_header_offset()");
+
+	EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls partner: wapi_wlan_authentication_c::get_header_offset(): %s: m_partner->get_header_offset()\n"),
+		 (m_is_client == true) ? "client": "server"));
+	
+	const u32_t offset = m_partner->get_header_offset(MTU, trailer_length);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("returns from partner: wapi_wlan_authentication_c::get_header_offset(): %s: m_partner->get_header_offset(): offset = %d\n"),
+		 (m_is_client == true) ? "client": "server",
+		 offset));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return offset;
+
+}
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_wlan_authentication_c::disassociation_mutex_must_be_reserved(
+	const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address.
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::disassociation_mutex_must_be_reserved(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::disassociation_mutex_must_be_reserved()");
+
+	eap_status_e status(eap_status_process_general_error);
+
+	if (m_ethernet_core != 0)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls eapol: wapi_wlan_authentication_c::disassociation_mutex_must_be_reserved(): m_ethernet_core->disassociation(): %s.\n"),
+			(m_is_client == true) ? "client": "server"));
+
+		status = m_ethernet_core->disassociation(receive_network_id);
+
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("returns from eapol: wapi_wlan_authentication_c::disassociation_mutex_must_be_reserved(): m_ethernet_core->disassociation(): %s, status = %s.\n"),
+			 (m_is_client == true) ? "client": "server",
+			 eap_status_string_c::get_status_string(status)));
+
+		if (status == eap_status_handler_does_not_exists_error)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("wapi_wlan_authentication_c::disassociation_mutex_must_be_reserved(): Association did not exists.\n")));
+			status = eap_status_ok;
+		}
+	}
+	else
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("wapi_wlan_authentication_c::disassociation_mutex_must_be_reserved(): Stack did not exists.\n")));
+	}
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::disassociation_mutex_must_be_reserved(): m_am_wauth->disassociation(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	// This call indicates the disassociation to adaptation.
+	status = m_am_wauth->disassociation(receive_network_id);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("wapi_wlan_authentication_c::disassociation_mutex_must_be_reserved(): m_am_wauth->disassociation() failed.\n")));
+		(void) EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::disassociation(
+	const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address.
+	)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("partner calls: wapi_wlan_authentication_c::disassociation(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: wapi_wlan_authentication_c::disassociation()");
+
+	eap_status_e status(eap_status_ok);
+
+	WAUTH_ENTER_MUTEX(m_am_tools);
+	status = disassociation_mutex_must_be_reserved(receive_network_id);
+	WAUTH_LEAVE_MUTEX(m_am_tools);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::configure()
+{	
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("partner calls: wapi_wlan_authentication_c::configure(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to partner: wapi_wlan_authentication_c::configure()");
+
+	//----------------------------------------------------------
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::configure(): m_am_wauth->configure(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	eap_status_e status = m_am_wauth->configure();
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	//----------------------------------------------------------
+	
+	// Read configuration parameters
+
+	//----------------------------------------------------------
+
+	{		
+		eap_variable_data_c EAP_TRACE_disable_traces(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAP_TRACE_disable_traces.get_field(),
+			&EAP_TRACE_disable_traces);
+		if (status == eap_status_ok
+			&& EAP_TRACE_disable_traces.get_is_valid_data() == true)
+		{
+			u32_t *disable_traces = reinterpret_cast<u32_t *>(
+				EAP_TRACE_disable_traces.get_data(sizeof(u32_t)));
+			if (disable_traces != 0
+				&& *disable_traces != 0)
+			{
+				m_am_tools->set_trace_mask(eap_am_tools_c::eap_trace_mask_none);
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	{		
+		eap_variable_data_c EAP_TRACE_activate_only_trace_masks_always_and_error(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAP_TRACE_activate_only_trace_masks_always_and_error.get_field(),
+			&EAP_TRACE_activate_only_trace_masks_always_and_error);
+		if (status == eap_status_ok
+			&& EAP_TRACE_activate_only_trace_masks_always_and_error.get_is_valid_data() == true)
+		{
+			u32_t *activate_trace_mask_always = reinterpret_cast<u32_t *>(
+				EAP_TRACE_activate_only_trace_masks_always_and_error.get_data(sizeof(u32_t)));
+			if (activate_trace_mask_always != 0
+				&& *activate_trace_mask_always != 0)
+			{
+				m_am_tools->set_trace_mask(
+					eap_am_tools_c::eap_trace_mask_always
+					| eap_am_tools_c::eap_trace_mask_error
+					);
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	{		
+		eap_variable_data_c EAP_TRACE_activate_trace_on_error(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAP_TRACE_activate_trace_on_error.get_field(),
+			&EAP_TRACE_activate_trace_on_error);
+		if (status == eap_status_ok
+			&& EAP_TRACE_activate_trace_on_error.get_is_valid_data() == true)
+		{
+			u32_t *activate_trace_on_error = reinterpret_cast<u32_t *>(
+				EAP_TRACE_activate_trace_on_error.get_data(sizeof(u32_t)));
+			if (activate_trace_on_error != 0
+				&& *activate_trace_on_error != 0)
+			{
+				m_am_tools->set_activate_trace_on_error();
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	{
+		eap_variable_data_c EAP_TRACE_enable_timer_traces(m_am_tools);
+
+		status = read_configure(
+			cf_str_EAP_TRACE_enable_timer_traces.get_field(),
+			&EAP_TRACE_enable_timer_traces);
+		if (status == eap_status_ok
+			&& EAP_TRACE_enable_timer_traces.get_is_valid_data() == true)
+		{
+			u32_t *enable_timer_traces = reinterpret_cast<u32_t *>(
+				EAP_TRACE_enable_timer_traces.get_data(sizeof(u32_t)));
+			if (enable_timer_traces != 0
+				&& *enable_timer_traces != 0)
+			{
+				m_am_tools->set_trace_mask(
+					m_am_tools->get_trace_mask()
+					| TRACE_FLAGS_TIMER
+					);
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	{
+		eap_variable_data_c EAP_TRACE_enable_timer_queue_traces(m_am_tools);
+
+		status = read_configure(
+			cf_str_EAP_TRACE_enable_timer_queue_traces.get_field(),
+			&EAP_TRACE_enable_timer_queue_traces);
+		if (status == eap_status_ok
+			&& EAP_TRACE_enable_timer_queue_traces.get_is_valid_data() == true)
+		{
+			u32_t *enable_timer_queue_traces = reinterpret_cast<u32_t *>(
+				EAP_TRACE_enable_timer_queue_traces.get_data(sizeof(u32_t)));
+			if (enable_timer_queue_traces != 0
+				&& *enable_timer_queue_traces != 0)
+			{
+				m_am_tools->set_trace_mask(
+					m_am_tools->get_trace_mask()
+					| TRACE_FLAGS_TIMER_QUEUE
+					);
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	{
+		eap_variable_data_c EAP_TRACE_enable_ok_return_traces(m_am_tools);
+
+		status = read_configure(
+			cf_str_EAP_TRACE_enable_ok_return_traces.get_field(),
+			&EAP_TRACE_enable_ok_return_traces);
+		if (status == eap_status_ok
+			&& EAP_TRACE_enable_ok_return_traces.get_is_valid_data() == true)
+		{
+			u32_t *enable_ok_return_traces = reinterpret_cast<u32_t *>(
+				EAP_TRACE_enable_ok_return_traces.get_data(sizeof(u32_t)));
+			if (enable_ok_return_traces != 0
+				&& *enable_ok_return_traces != 0)
+			{
+				m_am_tools->set_trace_mask(
+					m_am_tools->get_trace_mask()
+					| TRACE_FLAGS_OK_RETURNS
+					);
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	{
+		eap_variable_data_c EAP_TRACE_enable_message_data_traces(m_am_tools);
+
+		status = read_configure(
+			cf_str_EAP_TRACE_enable_message_data_traces.get_field(),
+			&EAP_TRACE_enable_message_data_traces);
+		if (status == eap_status_ok
+			&& EAP_TRACE_enable_message_data_traces.get_is_valid_data() == true)
+		{
+			u32_t *enable_message_data_traces = reinterpret_cast<u32_t *>(
+				EAP_TRACE_enable_message_data_traces.get_data(sizeof(u32_t)));
+			if (enable_message_data_traces != 0
+				&& *enable_message_data_traces != 0)
+			{
+				m_am_tools->set_trace_mask(
+					m_am_tools->get_trace_mask()
+					| EAP_TRACE_FLAGS_MESSAGE_DATA
+					);
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+	// JPH: temporarily reads setting from configuration file.
+	{
+		eap_variable_data_c eapol_key_authentication_type(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAPOL_key_authentication_type.get_field(),
+			&eapol_key_authentication_type);
+		if (status == eap_status_ok
+			&& eapol_key_authentication_type.get_is_valid() == true
+			&& eapol_key_authentication_type.get_data_length() > 0ul
+			&& eapol_key_authentication_type.get_data(
+				eapol_key_authentication_type.get_data_length()) != 0)
+		{
+			if (cf_str_EAPOL_key_authentication_type_config_value_RSNA_EAP.get_field()
+				->compare(
+					m_am_tools,
+					&eapol_key_authentication_type) == true)
+			{
+				m_authentication_type
+					= eapol_key_authentication_type_RSNA_EAP;
+			}
+			else if (cf_str_EAPOL_key_authentication_type_config_value_RSNA_PSK.get_field()
+					 ->compare(
+						 m_am_tools,
+						 &eapol_key_authentication_type) == true)
+			{
+				m_authentication_type
+					= eapol_key_authentication_type_RSNA_PSK;
+			}
+			else if (cf_str_EAPOL_key_authentication_type_config_value_WPA_EAP.get_field()
+					 ->compare(
+						 m_am_tools,
+						 &eapol_key_authentication_type) == true)
+			{
+				m_authentication_type
+					= eapol_key_authentication_type_WPA_EAP;
+			}
+			else if (cf_str_EAPOL_key_authentication_type_config_value_WPA_PSK.get_field()
+					 ->compare(
+						 m_am_tools,
+						 &eapol_key_authentication_type) == true)
+			{
+				m_authentication_type
+					= eapol_key_authentication_type_WPA_PSK;
+			}
+			else if (cf_str_EAPOL_key_authentication_type_config_value_dynamic_WEP.get_field()
+					 ->compare(
+						 m_am_tools,
+						 &eapol_key_authentication_type) == true)
+			{
+				m_authentication_type
+					= eapol_key_authentication_type_802_1X;
+			}
+#if defined(EAP_USE_WPXM)
+			else if (cf_str_EAPOL_key_authentication_type_config_value_WPXM.get_field()
+					 ->compare(
+						 m_am_tools,
+						 &eapol_key_authentication_type) == true)
+			{
+				m_authentication_type
+					= eapol_key_authentication_type_WPXM;
+			}
+#endif //#if defined(EAP_USE_WPXM)
+			else if (cf_str_EAPOL_key_authentication_type_config_value_WFA_SC.get_field()
+					 ->compare(
+						 m_am_tools,
+						 &eapol_key_authentication_type) == true)
+			{
+				m_authentication_type
+					= eapol_key_authentication_type_WFA_SC;
+			}
+			else if (cf_str_EAPOL_key_authentication_type_config_value_WAI_PSK.get_field()
+					 ->compare(
+						 m_am_tools,
+						 &eapol_key_authentication_type) == true)
+			{
+				m_authentication_type
+					= eapol_key_authentication_type_WAI_PSK;
+			}
+			else if (cf_str_EAPOL_key_authentication_type_config_value_WAI_certificate.get_field()
+					 ->compare(
+						 m_am_tools,
+						 &eapol_key_authentication_type) == true)
+			{
+				m_authentication_type
+					= eapol_key_authentication_type_WAI_certificate;
+			}
+		}
+	}
+
+	//----------------------------------------------------------
+
+#if defined(USE_EAP_ERROR_TESTS)
+
+	{
+		{
+			eap_variable_data_c EAP_ERROR_TEST_randomly_drop_packets(m_am_tools);
+			
+			status = read_configure(
+				cf_str_EAP_ERROR_TEST_randomly_drop_packets.get_field(),
+				&EAP_ERROR_TEST_randomly_drop_packets);
+			if (status == eap_status_ok
+				&& EAP_ERROR_TEST_randomly_drop_packets.get_is_valid_data() == true)
+			{
+				u32_t *randomly_drop_packets = reinterpret_cast<u32_t *>(
+					EAP_ERROR_TEST_randomly_drop_packets.get_data(sizeof(u32_t)));
+				if (randomly_drop_packets != 0
+					&& *randomly_drop_packets != 0)
+				{
+					m_randomly_drop_packets = true;
+				}
+			}
+		}
+		
+		{
+			eap_variable_data_c EAP_ERROR_TEST_randomly_drop_packets_probability(m_am_tools);
+
+			status = read_configure(
+				cf_str_EAP_ERROR_TEST_randomly_drop_packets_probability.get_field(),
+				&EAP_ERROR_TEST_randomly_drop_packets_probability);
+			if (status == eap_status_ok
+				&& EAP_ERROR_TEST_randomly_drop_packets_probability.get_is_valid_data() == true)
+			{
+				u32_t *randomly_drop_packets_probability = reinterpret_cast<u32_t *>(
+					EAP_ERROR_TEST_randomly_drop_packets_probability.get_data(sizeof(u32_t)));
+				if (randomly_drop_packets_probability != 0)
+				{
+					m_randomly_drop_packets_probability = *randomly_drop_packets_probability;
+				}
+			}
+		}
+
+		
+		{
+			eap_variable_data_c EAP_ERROR_TEST_enable_random_errors(m_am_tools);
+			
+			status = read_configure(
+				cf_str_EAP_ERROR_TEST_enable_random_errors.get_field(),
+				&EAP_ERROR_TEST_enable_random_errors);
+			if (status == eap_status_ok
+				&& EAP_ERROR_TEST_enable_random_errors.get_is_valid_data() == true)
+			{
+				u32_t *enable_random_errors = reinterpret_cast<u32_t *>(
+					EAP_ERROR_TEST_enable_random_errors.get_data(sizeof(u32_t)));
+				if (enable_random_errors != 0
+					&& *enable_random_errors != 0)
+				{
+					m_enable_random_errors = true;
+				}
+			}
+		}
+		
+		{
+			eap_variable_data_c EAP_ERROR_TEST_send_original_packet_first(m_am_tools);
+			
+			status = read_configure(
+				cf_str_EAP_ERROR_TEST_send_original_packet_first.get_field(),
+				&EAP_ERROR_TEST_send_original_packet_first);
+			if (status == eap_status_ok
+				&& EAP_ERROR_TEST_send_original_packet_first.get_is_valid_data() == true)
+			{
+				u32_t *send_original_packet_first = reinterpret_cast<u32_t *>(
+					EAP_ERROR_TEST_send_original_packet_first.get_data(sizeof(u32_t)));
+				if (send_original_packet_first != 0
+					&& *send_original_packet_first != 0)
+				{
+					m_send_original_packet_first = true;
+				}
+			}
+		}
+		
+		{
+			eap_variable_data_c EAP_ERROR_TEST_generate_multiple_error_packets(m_am_tools);
+			
+			status = read_configure(
+				cf_str_EAP_ERROR_TEST_generate_multiple_error_packets.get_field(),
+				&EAP_ERROR_TEST_generate_multiple_error_packets);
+			if (status == eap_status_ok
+				&& EAP_ERROR_TEST_generate_multiple_error_packets.get_is_valid_data() == true)
+			{
+				u32_t *generate_multiple_error_packets = reinterpret_cast<u32_t *>(
+					EAP_ERROR_TEST_generate_multiple_error_packets.get_data(sizeof(u32_t)));
+				if (generate_multiple_error_packets != 0
+					&& *generate_multiple_error_packets != 0)
+				{
+					m_generate_multiple_error_packets = *generate_multiple_error_packets;
+				}
+			}
+		}
+		
+		
+		{
+			eap_variable_data_c EAP_ERROR_TEST_manipulate_ethernet_header(m_am_tools);
+			
+			status = read_configure(
+				cf_str_EAP_ERROR_TEST_manipulate_ethernet_header.get_field(),
+				&EAP_ERROR_TEST_manipulate_ethernet_header);
+			if (status == eap_status_ok
+				&& EAP_ERROR_TEST_manipulate_ethernet_header.get_is_valid_data() == true)
+			{
+				u32_t *manipulate_ethernet_header = reinterpret_cast<u32_t *>(
+					EAP_ERROR_TEST_manipulate_ethernet_header.get_data(sizeof(u32_t)));
+				if (manipulate_ethernet_header != 0
+					&& *manipulate_ethernet_header != 0)
+				{
+					m_manipulate_ethernet_header = true;
+				}
+			}
+		}
+		
+		{
+			eap_variable_data_c EAP_ERROR_TEST_error_probability(m_am_tools);
+			
+			status = read_configure(
+				cf_str_EAP_ERROR_TEST_error_probability.get_field(),
+				&EAP_ERROR_TEST_error_probability);
+			if (status == eap_status_ok
+				&& EAP_ERROR_TEST_error_probability.get_is_valid_data() == true)
+			{
+				u32_t *error_probability = reinterpret_cast<u32_t *>(
+					EAP_ERROR_TEST_error_probability.get_data(sizeof(u32_t)));
+				if (error_probability != 0)
+				{
+					m_error_probability = *error_probability;
+				}
+			}
+		}
+	} // if (m_manipulate_only_tunneled_messages == false)
+
+#endif //#if defined(USE_EAP_ERROR_TESTS)
+
+	//----------------------------------------------------------
+
+	// Create stack if it does not already exist. 
+	status = create_upper_stack();
+
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	// All of the configuration options are optional.
+	// So we return OK.
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::read_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::read_configure(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::read_configure()");
+
+	EAP_ASSERT_ALWAYS(data != 0);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::read_configure(): m_am_wauth->read_configure(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	eap_status_e status = m_am_wauth->read_configure(field, data);
+
+	m_am_tools->trace_configuration(
+		status,
+		field,
+		data);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::write_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::write_configure(): %s\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::write_configure()");
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls: wapi_wlan_authentication_c::write_configure(): m_am_wauth->write_configure(): %s.\n"),
+		(m_is_client == true) ? "client": "server"));
+
+	eap_status_e status = m_am_wauth->write_configure(field, data);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::set_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id, 
+	void * const p_data,
+	const u32_t p_time_ms)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::set_timer(): id = %d, data = 0x%08x, time = %d\n"),
+		p_id,
+		p_data,
+		p_time_ms));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::set_timer()");
+
+	const eap_status_e status = m_am_tools->am_set_timer(
+		p_initializer, 
+		p_id, 
+		p_data,
+		p_time_ms);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::cancel_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::cancel_timer(): initializer = 0x%08x, id = %d\n"),
+		p_initializer,
+		p_id));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::cancel_timer()");
+
+	const eap_status_e status = m_am_tools->am_cancel_timer(
+		p_initializer, 
+		p_id);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::cancel_all_timers()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::cancel_all_timers()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::cancel_all_timers()");
+
+	eap_status_e status = eap_status_ok;
+	
+	if (m_am_tools != 0)
+	{
+		WAUTH_ENTER_MUTEX(m_am_tools);
+		status = m_am_tools->am_cancel_all_timers();
+		WAUTH_LEAVE_MUTEX(m_am_tools);
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::wapi_indication(
+	const eap_am_network_id_c * const receive_network_id, ///< source includes remote address, destination includes local address.
+	const eapol_wlan_authentication_state_e wlan_authentication_state)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::wapi_indication()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::wapi_indication()");
+
+	eap_status_e status(eap_status_ok);
+
+	eap_am_network_id_c send_network_id(m_am_tools);
+
+	if (receive_network_id != 0)
+	{
+		// Here we swap the addresses.
+		eap_am_network_id_c tmp_network_id(m_am_tools,
+			receive_network_id->get_destination_id(),
+			receive_network_id->get_source_id(),
+			receive_network_id->get_type());
+
+		status = send_network_id.set_copy_of_network_id(&tmp_network_id);
+		if (status != eap_status_ok)
+		{
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(m_am_tools, status);
+		}
+	}
+
+	eap_state_notification_c notification(
+		m_am_tools,
+		&send_network_id,
+		m_is_client,
+		eap_state_notification_generic,
+		eap_protocol_layer_wapi,  // this layer is WAPI notification to WLAN engine.
+		eap_type_none,
+		eapol_wlan_authentication_state_none, // Previous state is unknown.
+		wlan_authentication_state, // The current indicated state.
+		0UL,
+		false // This is not applicable here.
+		);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_wlan_authentication_c::wapi_indication(): Sending state notification to Engine. state=%s=%d\n"),
+		 notification.get_state_string( notification.get_protocol_layer() ,wlan_authentication_state ),
+		 wlan_authentication_state));	
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("    send source"),
+		 send_network_id.get_source(),
+		 send_network_id.get_source_length()));
+	EAP_TRACE_DATA_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("send destination"),
+		 send_network_id.get_destination(),
+		 send_network_id.get_destination_length()));
+		
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("calls partner: wapi_wlan_authentication_c::wapi_indication(): %s: m_partner->state_notification()\n"),
+		 (m_is_client == true) ? "client": "server"));
+	
+	m_partner->state_notification(&notification);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+		(EAPL("returns from partner: wapi_wlan_authentication_c::wapi_indication(): %s: m_partner->state_notification(): status = %s\n"),
+		 (m_is_client == true) ? "client": "server",
+		 eap_status_string_c::get_status_string(status)));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_wlan_authentication_c::create_upper_stack()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("eapol calls: wapi_wlan_authentication_c::create_upper_stack()\n")));
+
+	EAP_TRACE_RETURN_STRING(m_am_tools, "returns to eapol: wapi_wlan_authentication_c::create_upper_stack()");
+
+	eap_status_e status(eap_status_ok);
+
+	if (m_ethernet_core == 0)
+	{        
+		m_ethernet_core = new wapi_ethernet_core_c(m_am_tools, this, m_is_client);
+		if (m_ethernet_core == 0
+			|| m_ethernet_core->get_is_valid() != true)
+		{
+			if (m_ethernet_core != 0)
+			{
+				WAUTH_ENTER_MUTEX(m_am_tools);
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("calls eapol: wapi_wlan_authentication_c::create_upper_stack(): m_ethernet_core->shutdown(): %s.\n"),
+					(m_is_client == true) ? "client": "server"));
+				status = m_ethernet_core->shutdown();
+				EAP_TRACE_DEBUG(
+					m_am_tools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+					(EAPL("returns from eapol: wapi_wlan_authentication_c::create_upper_stack(): m_ethernet_core->shutdown(): %s, status = %s.\n"),
+					 (m_is_client == true) ? "client": "server",
+					 eap_status_string_c::get_status_string(status)));
+				WAUTH_LEAVE_MUTEX(m_am_tools);
+
+				delete m_ethernet_core;
+				m_ethernet_core = 0;							
+			}			
+			EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack creation failed.\n")));			
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);	
+		}
+
+		// Initialise upper stack
+		WAUTH_ENTER_MUTEX(m_am_tools);
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("calls eapol: wapi_wlan_authentication_c::create_upper_stack(): m_ethernet_core->configure(): %s.\n"),
+			(m_is_client == true) ? "client": "server"));
+		status = m_ethernet_core->configure();
+		EAP_TRACE_DEBUG(
+			m_am_tools,
+			TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+			(EAPL("returns from eapol: wapi_wlan_authentication_c::create_upper_stack(): m_ethernet_core->configure(): %s, status = %s.\n"),
+			 (m_is_client == true) ? "client": "server",
+			 eap_status_string_c::get_status_string(status)));
+		WAUTH_LEAVE_MUTEX(m_am_tools);
+		
+		if (status != eap_status_ok)
+		{
+			WAUTH_ENTER_MUTEX(m_am_tools);
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+				(EAPL("calls eapol: wapi_wlan_authentication_c::create_upper_stack(): m_ethernet_core->shutdown(): %s.\n"),
+				(m_is_client == true) ? "client": "server"));
+			status = m_ethernet_core->shutdown();
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT, 
+				(EAPL("returns from eapol: wapi_wlan_authentication_c::create_upper_stack(): m_ethernet_core->shutdown(): %s, status = %s.\n"),
+				 (m_is_client == true) ? "client": "server",
+				 eap_status_string_c::get_status_string(status)));
+			WAUTH_LEAVE_MUTEX(m_am_tools);
+
+			delete m_ethernet_core;
+			m_ethernet_core = 0;							
+
+			EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Stack creation failed.\n")));			
+			EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+			return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error);	
+		}
+	}
+	else
+	{			
+		status = eap_status_already_exists;
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+EAP_FUNC_EXPORT u32_t wapi_wlan_authentication_c::get_wrong_send_packet_index()
+{
+	return 0ul;
+}
+
+#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+//--------------------------------------------------
+
+#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+EAP_FUNC_EXPORT void wapi_wlan_authentication_c::reset_authentication_can_succeed()
+{
+}
+
+#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+//--------------------------------------------------
+
+#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+EAP_FUNC_EXPORT void wapi_wlan_authentication_c::set_authentication_can_succeed()
+{
+}
+
+#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+//--------------------------------------------------
+
+#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+EAP_FUNC_EXPORT void wapi_wlan_authentication_c::restore_authentication_can_succeed()
+{
+}
+
+#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+//--------------------------------------------------
+
+#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+EAP_FUNC_EXPORT void wapi_wlan_authentication_c::set_authentication_must_not_succeed(
+	const u32_t /* wrong_packet_index */,
+	const u32_t /* packet_index */,
+	const void * const /* wrong_packet_stack */)
+{
+}
+
+#endif //#if defined(USE_TEST_EAPOL_WLAN_AUTHENTICATION)
+
+//--------------------------------------------------
+
+// End of file.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/bwins/wapiu.def	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,577 @@
+EXPORTS
+	?type_configure_read@wapi_am_core_symbian_c@@MAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 1 NONAME ; enum eap_status_e wapi_am_core_symbian_c::type_configure_read(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?set_session_timeout@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@K@Z @ 2 NONAME ; enum eap_status_e wapi_ethernet_core_c::set_session_timeout(unsigned long)
+	?cancel_timer@wapi_wlan_authentication_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 3 NONAME ; enum eap_status_e wapi_wlan_authentication_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long)
+	??0wapi_wlan_authentication_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_wapi_wlan_authentication_c@@PAVwapi_am_wlan_authentication_c@@_N@Z @ 4 NONAME ; wapi_wlan_authentication_c::wapi_wlan_authentication_c(class abs_eap_am_tools_c *, class abs_wapi_wlan_authentication_c *, class wapi_am_wlan_authentication_c *, bool)
+	?set_payload_type@wai_variable_data_c@@QAE?AW4eap_status_e@@W4wai_payload_type_e@@@Z @ 5 NONAME ; enum eap_status_e wai_variable_data_c::set_payload_type(enum wai_payload_type_e)
+	?packet_send@wapi_session_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 6 NONAME ; enum eap_status_e wapi_session_core_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long)
+	??1wai_message_payloads_c@@UAE@XZ @ 7 NONAME ; wai_message_payloads_c::~wai_message_payloads_c(void)
+	?compare@ec_cs_compare_certificate_reference_c@@UBEJPBVec_cs_data_c@@0@Z @ 8 NONAME ; long ec_cs_compare_certificate_reference_c::compare(class ec_cs_data_c const *, class ec_cs_data_c const *) const
+	?write_configure@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 9 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?send_message@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PAVeapol_handle_tlv_message_data_c@@@Z @ 10 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::send_message(class eapol_handle_tlv_message_data_c *)
+	?get_tlv@wai_message_payloads_c@@QBEPAVwai_variable_data_c@@K@Z @ 11 NONAME ; class wai_variable_data_c * wai_message_payloads_c::get_tlv(unsigned long) const
+	?get_data_length@eap_core_retransmission_c@@QBEKXZ @ 12 NONAME ; unsigned long eap_core_retransmission_c::get_data_length(void) const
+	?copy_tlv@wai_message_payloads_c@@QAE?AW4eap_status_e@@PBV1@W4wai_payload_type_e@@@Z @ 13 NONAME ; enum eap_status_e wai_message_payloads_c::copy_tlv(class wai_message_payloads_c const *, enum wai_payload_type_e)
+	?complete_association@wapi_wlan_authentication_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@PBVeap_variable_data_c@@2W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@3@Z @ 14 NONAME ; enum eap_status_e wapi_wlan_authentication_c::complete_association(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e)
+	??1wapi_asn1_der_parser_c@@UAE@XZ @ 15 NONAME ; wapi_asn1_der_parser_c::~wapi_asn1_der_parser_c(void)
+	?update_wlan_database_reference_values@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 16 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::update_wlan_database_reference_values(class eap_array_c<class eap_tlv_header_c> const *)
+	?set_am_partner@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PAVabs_wapi_am_wlan_authentication_c@@@Z @ 17 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::set_am_partner(class abs_wapi_am_wlan_authentication_c *)
+	?set_pending_operation@ec_certificate_store_c@@AAEXW4ec_cs_pending_operation_e@@@Z @ 18 NONAME ; void ec_certificate_store_c::set_pending_operation(enum ec_cs_pending_operation_e)
+	?get_key_size@wapi_am_crypto_sms4_c@@QAEKXZ @ 19 NONAME ; unsigned long wapi_am_crypto_sms4_c::get_key_size(void)
+	?cancel_retransmission@wapi_core_c@@AAE?AW4eap_status_e@@XZ @ 20 NONAME ; enum eap_status_e wapi_core_c::cancel_retransmission(void)
+	?set_timer@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 21 NONAME ; enum eap_status_e wapi_ethernet_core_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long)
+	?create_encrypted_certificate@ec_cs_tlv_c@@QAE?AW4eap_status_e@@W4ec_cs_data_type_e@@PBVeap_variable_data_c@@111W4ec_cs_tlv_type_e@@1PAV4@@Z @ 22 NONAME ; enum eap_status_e ec_cs_tlv_c::create_encrypted_certificate(enum ec_cs_data_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, enum ec_cs_tlv_type_e, class eap_variable_data_c const *, class eap_variable_data_c *)
+	?complete_verify_signature_with_public_key@ec_certificate_store_c@@UAE?AW4eap_status_e@@W42@@Z @ 23 NONAME ; enum eap_status_e ec_certificate_store_c::complete_verify_signature_with_public_key(enum eap_status_e)
+	?query_certificate_list@ec_certificate_store_c@@UAE?AW4eap_status_e@@XZ @ 24 NONAME ; enum eap_status_e ec_certificate_store_c::query_certificate_list(void)
+	?get_reference@ec_cs_data_c@@QBEPBVeap_variable_data_c@@XZ @ 25 NONAME ; class eap_variable_data_c const * ec_cs_data_c::get_reference(void) const
+	?get_ec_cs_store_data_string@ec_cs_strings_c@@SAPBDW4ec_cs_pending_operation_e@@@Z @ 26 NONAME ; char const * ec_cs_strings_c::get_ec_cs_store_data_string(enum ec_cs_pending_operation_e)
+	?add_data@wai_variable_data_c@@QAE?AW4eap_status_e@@W4wai_payload_type_e@@PBXK@Z @ 27 NONAME ; enum eap_status_e wai_variable_data_c::add_data(enum wai_payload_type_e, void const *, unsigned long)
+	?timer_delete_data@ec_certificate_store_c@@UAE?AW4eap_status_e@@KPAX@Z @ 28 NONAME ; enum eap_status_e ec_certificate_store_c::timer_delete_data(unsigned long, void *)
+	?parse_encrypted_tlv@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@PBVec_cs_variable_data_c@@PAV4@@Z @ 29 NONAME ; enum eap_status_e ec_cs_tlv_c::parse_encrypted_tlv(class eap_variable_data_c const *, class ec_cs_variable_data_c const *, class ec_cs_variable_data_c *)
+	?association@wapi_ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@2W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@32@Z @ 30 NONAME ; enum eap_status_e wapi_ethernet_core_c::association(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, class eap_variable_data_c const *)
+	?complete_reassociation@wapi_ethernet_core_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@3W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@4@Z @ 31 NONAME ; enum eap_status_e wapi_ethernet_core_c::complete_reassociation(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e)
+	?new_ec_base_algorithms_c@ec_am_base_algorithms_c@@SAPAV1@PAVabs_eap_am_tools_c@@PAVabs_ec_am_algorithms_c@@_N@Z @ 32 NONAME ; class ec_am_base_algorithms_c * ec_am_base_algorithms_c::new_ec_base_algorithms_c(class abs_eap_am_tools_c *, class abs_ec_am_algorithms_c *, bool)
+	?write_configure@wapi_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 33 NONAME ; enum eap_status_e wapi_core_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?decode@asn1_der_type_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 34 NONAME ; enum eap_status_e asn1_der_type_c::decode(class eap_variable_data_c const *)
+	?create_tlv@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PAVec_cs_variable_data_c@@W4ec_cs_tlv_type_e@@PBVeap_variable_data_c@@@Z @ 35 NONAME ; enum eap_status_e ec_cs_tlv_c::create_tlv(class ec_cs_variable_data_c *, enum ec_cs_tlv_type_e, class eap_variable_data_c const *)
+	?completion_action_add@ec_certificate_store_c@@AAE?AW4eap_status_e@@W4ec_cs_completion_e@@@Z @ 36 NONAME ; enum eap_status_e ec_certificate_store_c::completion_action_add(enum ec_cs_completion_e)
+	?get_wlan_configuration@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 37 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::get_wlan_configuration(class eap_variable_data_c *)
+	?state_notification@wapi_session_core_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 38 NONAME ; void wapi_session_core_c::state_notification(class abs_eap_state_notification_c const *)
+	?initialise_header@wai_message_payloads_c@@QAE?AW4eap_status_e@@XZ @ 39 NONAME ; enum eap_status_e wai_message_payloads_c::initialise_header(void)
+	?parse_encrypted_certificate@ec_cs_tlv_c@@QAE?AW4eap_status_e@@W4ec_cs_data_type_e@@PBVeap_variable_data_c@@111PAV4@@Z @ 40 NONAME ; enum eap_status_e ec_cs_tlv_c::parse_encrypted_certificate(enum ec_cs_data_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *)
+	?set_is_valid@wapi_core_c@@UAEXXZ @ 41 NONAME ; void wapi_core_c::set_is_valid(void)
+	?set_timer@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 42 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long)
+	??1ec_cs_completion_c@@UAE@XZ @ 43 NONAME ; ec_cs_completion_c::~ec_cs_completion_c(void)
+	?set_timer@wapi_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 44 NONAME ; enum eap_status_e wapi_core_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long)
+	?create_state@wapi_ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@@Z @ 45 NONAME ; enum eap_status_e wapi_ethernet_core_c::create_state(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e)
+	?get_extented_tag@asn1_der_type_c@@QBE?AW4eap_status_e@@PAPBEPAK@Z @ 46 NONAME ; enum eap_status_e asn1_der_type_c::get_extented_tag(unsigned char const * *, unsigned long *) const
+	?get_own_certificate@ec_certificate_store_c@@UAE?AW4eap_status_e@@XZ @ 47 NONAME ; enum eap_status_e ec_certificate_store_c::get_own_certificate(void)
+	?get_is_valid@wapi_certificate_asn1_der_parser_c@@QBE_NXZ @ 48 NONAME ; bool wapi_certificate_asn1_der_parser_c::get_is_valid(void) const
+	?object_increase_reference_count@wai_variable_data_c@@QAEXXZ @ 49 NONAME ; void wai_variable_data_c::object_increase_reference_count(void)
+	?cancel_session_timeout@wapi_core_c@@AAE?AW4eap_status_e@@XZ @ 50 NONAME ; enum eap_status_e wapi_core_c::cancel_session_timeout(void)
+	??0ec_cs_data_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 51 NONAME ; ec_cs_data_c::ec_cs_data_c(class abs_eap_am_tools_c *)
+	??1ec_cs_tlv_payloads_c@@UAE@XZ @ 52 NONAME ; ec_cs_tlv_payloads_c::~ec_cs_tlv_payloads_c(void)
+	?completion_action_push@ec_certificate_store_c@@AAE?AW4eap_status_e@@W4ec_cs_completion_e@@@Z @ 53 NONAME ; enum eap_status_e ec_certificate_store_c::completion_action_push(enum ec_cs_completion_e)
+	?compare@wai_variable_data_c@@QBEJPBV1@@Z @ 54 NONAME ; long wai_variable_data_c::compare(class wai_variable_data_c const *) const
+	?get_type_header_length@wai_variable_data_c@@QBEKXZ @ 55 NONAME ; unsigned long wai_variable_data_c::get_type_header_length(void) const
+	?initialize_certificate_store@wapi_am_core_symbian_c@@MAE?AW4eap_status_e@@W4wapi_completion_operation_e@@@Z @ 56 NONAME ; enum eap_status_e wapi_am_core_symbian_c::initialize_certificate_store(enum wapi_completion_operation_e)
+	?add_tlv@ec_cs_tlv_payloads_c@@QAE?AW4eap_status_e@@PAVec_cs_variable_data_c@@@Z @ 57 NONAME ; enum eap_status_e ec_cs_tlv_payloads_c::add_tlv(class ec_cs_variable_data_c *)
+	?set_wlan_parameters@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@_N0W4eapol_key_authentication_type_e@@@Z @ 58 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::set_wlan_parameters(class eap_variable_data_c const *, bool, class eap_variable_data_c const *, enum eapol_key_authentication_type_e)
+	??0wai_message_payloads_c@@QAE@PAVabs_eap_am_tools_c@@_N@Z @ 59 NONAME ; wai_message_payloads_c::wai_message_payloads_c(class abs_eap_am_tools_c *, bool)
+	??0wapi_session_core_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_wapi_core_c@@_N@Z @ 60 NONAME ; wapi_session_core_c::wapi_session_core_c(class abs_eap_am_tools_c *, class abs_wapi_core_c *, bool)
+	?disassociation@wapi_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 61 NONAME ; enum eap_status_e wapi_wlan_authentication_c::disassociation(class eap_am_network_id_c const *)
+	??1ec_cs_strings_c@@UAE@XZ @ 62 NONAME ; ec_cs_strings_c::~ec_cs_strings_c(void)
+	?timer_delete_data@wapi_core_c@@UAE?AW4eap_status_e@@KPAX@Z @ 63 NONAME ; enum eap_status_e wapi_core_c::timer_delete_data(unsigned long, void *)
+	?cancel_timer@wapi_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 64 NONAME ; enum eap_status_e wapi_core_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long)
+	??0wapi_message_wlan_authentication_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_wapi_message_wlan_authentication_c@@@Z @ 65 NONAME ; wapi_message_wlan_authentication_c::wapi_message_wlan_authentication_c(class abs_eap_am_tools_c *, class abs_wapi_message_wlan_authentication_c *)
+	?reset@wai_message_payloads_c@@QAE?AW4eap_status_e@@XZ @ 66 NONAME ; enum eap_status_e wai_message_payloads_c::reset(void)
+	?cancel_all_timers@wapi_session_core_c@@UAE?AW4eap_status_e@@XZ @ 67 NONAME ; enum eap_status_e wapi_session_core_c::cancel_all_timers(void)
+	??0ec_certificate_store_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_ec_certificate_store_c@@PAVec_am_base_certificate_store_c@@_N@Z @ 68 NONAME ; ec_certificate_store_c::ec_certificate_store_c(class abs_eap_am_tools_c *, class abs_ec_certificate_store_c *, class ec_am_base_certificate_store_c *, bool)
+	?create@wai_variable_data_c@@QAE?AW4eap_status_e@@W4wai_payload_type_e@@PBVeap_variable_data_c@@@Z @ 69 NONAME ; enum eap_status_e wai_variable_data_c::create(enum wai_payload_type_e, class eap_variable_data_c const *)
+	??1ec_cs_data_c@@UAE@XZ @ 70 NONAME ; ec_cs_data_c::~ec_cs_data_c(void)
+	?reset@wapi_session_core_c@@QAE?AW4eap_status_e@@XZ @ 71 NONAME ; enum eap_status_e wapi_session_core_c::reset(void)
+	?initialize@wapi_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@2W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@3@Z @ 72 NONAME ; enum eap_status_e wapi_core_c::initialize(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e)
+	?NewL@CWapiCertificates@@SAPAV1@XZ @ 73 NONAME ; class CWapiCertificates * CWapiCertificates::NewL(void)
+	?get_header_offset@wapi_core_c@@QAEKPAK0@Z @ 74 NONAME ; unsigned long wapi_core_c::get_header_offset(unsigned long *, unsigned long *)
+	?get_ec_cs_store_data_change_status_string@ec_cs_strings_c@@SAPBDW4ec_cs_data_change_status_e@@@Z @ 75 NONAME ; char const * ec_cs_strings_c::get_ec_cs_store_data_change_status_string(enum ec_cs_data_change_status_e)
+	?get_wai_payload_type_string@wapi_strings_c@@SAPBDW4wai_payload_type_e@@@Z @ 76 NONAME ; char const * wapi_strings_c::get_wai_payload_type_string(enum wai_payload_type_e)
+	?cancel_timer@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 77 NONAME ; enum eap_status_e wapi_ethernet_core_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long)
+	?get_wapi_completion_operation_string@wapi_strings_c@@SAPBDW4wapi_completion_operation_e@@@Z @ 78 NONAME ; char const * wapi_strings_c::get_wapi_completion_operation_string(enum wapi_completion_operation_e)
+	?get_data_length@ec_cs_variable_data_c@@QBEKXZ @ 79 NONAME ; unsigned long ec_cs_variable_data_c::get_data_length(void) const
+	?get_writable_data@ec_cs_data_c@@QAEPAVeap_variable_data_c@@XZ @ 80 NONAME ; class eap_variable_data_c * ec_cs_data_c::get_writable_data(void)
+	?get_data@ec_cs_variable_data_c@@QBEPAEK@Z @ 81 NONAME ; unsigned char * ec_cs_variable_data_c::get_data(unsigned long) const
+	??1ec_cs_compare_reference_issuer_name_c@@UAE@XZ @ 82 NONAME ; ec_cs_compare_reference_issuer_name_c::~ec_cs_compare_reference_issuer_name_c(void)
+	?get_pc_string@asn1_der_type_c@@QBEPBDXZ @ 83 NONAME ; char const * asn1_der_type_c::get_pc_string(void) const
+	?initialize_session_timeout@wapi_core_c@@AAE?AW4eap_status_e@@K@Z @ 84 NONAME ; enum eap_status_e wapi_core_c::initialize_session_timeout(unsigned long)
+	?get_full_data@asn1_der_type_c@@QBEPBEXZ @ 85 NONAME ; unsigned char const * asn1_der_type_c::get_full_data(void) const
+	?process_message@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PAVeapol_handle_tlv_message_data_c@@@Z @ 86 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::process_message(class eapol_handle_tlv_message_data_c *)
+	?new_wapi_wlan_authentication@wapi_wlan_authentication_c@@SAPAV1@PAVabs_eap_am_tools_c@@PAVabs_wapi_wlan_authentication_c@@_NPBVabs_eapol_wlan_database_reference_if_c@@@Z @ 87 NONAME ; class wapi_wlan_authentication_c * wapi_wlan_authentication_c::new_wapi_wlan_authentication(class abs_eap_am_tools_c *, class abs_wapi_wlan_authentication_c *, bool, class abs_eapol_wlan_database_reference_if_c const *)
+	?parse_ec_cs_payloads@ec_cs_tlv_payloads_c@@QAE?AW4eap_status_e@@PAXPAK1@Z @ 88 NONAME ; enum eap_status_e ec_cs_tlv_payloads_c::parse_ec_cs_payloads(void *, unsigned long *, unsigned long *)
+	?get_data@ec_cs_data_c@@QBEPBVeap_variable_data_c@@XZ @ 89 NONAME ; class eap_variable_data_c const * ec_cs_data_c::get_data(void) const
+	?get_is_valid@wai_variable_data_c@@QBE_NXZ @ 90 NONAME ; bool wai_variable_data_c::get_is_valid(void) const
+	?get_sent_packet@eap_core_retransmission_c@@QBEPAVeap_buf_chain_wr_c@@XZ @ 91 NONAME ; class eap_buf_chain_wr_c * eap_core_retransmission_c::get_sent_packet(void) const
+	?get_header_offset@wapi_session_core_c@@UAEKPAK0@Z @ 92 NONAME ; unsigned long wapi_session_core_c::get_header_offset(unsigned long *, unsigned long *)
+	?add_data@wai_variable_data_c@@QAE?AW4eap_status_e@@PBV1@@Z @ 93 NONAME ; enum eap_status_e wai_variable_data_c::add_data(class wai_variable_data_c const *)
+	?init_header@wai_variable_data_c@@QAE?AW4eap_status_e@@W4wai_payload_type_e@@K@Z @ 94 NONAME ; enum eap_status_e wai_variable_data_c::init_header(enum wai_payload_type_e, unsigned long)
+	?compare@ec_cs_data_c@@QBEJPBV1@@Z @ 95 NONAME ; long ec_cs_data_c::compare(class ec_cs_data_c const *) const
+	?get_index@asn1_der_type_c@@QBEKXZ @ 96 NONAME ; unsigned long asn1_der_type_c::get_index(void) const
+	?get_partner@wapi_session_core_c@@QAEPAVabs_wapi_core_c@@XZ @ 97 NONAME ; class abs_wapi_core_c * wapi_session_core_c::get_partner(void)
+	?set_session_timeout@wapi_am_core_symbian_c@@IAE?AW4eap_status_e@@K@Z @ 98 NONAME ; enum eap_status_e wapi_am_core_symbian_c::set_session_timeout(unsigned long)
+	?get_writable_full_tlv_buffer@ec_cs_variable_data_c@@QAEPAVeap_variable_data_c@@XZ @ 99 NONAME ; class eap_variable_data_c * ec_cs_variable_data_c::get_writable_full_tlv_buffer(void)
+	?DeleteAPSpecificDataL@CWapiCertificates@@QAEXH@Z @ 100 NONAME ; void CWapiCertificates::DeleteAPSpecificDataL(int)
+	?get_pc@asn1_der_type_c@@QBE?AW4asn1_pc_e@1@XZ @ 101 NONAME ; enum asn1_der_type_c::asn1_pc_e asn1_der_type_c::get_pc(void) const
+	?cancel_all_authentication_sessions@wapi_ethernet_core_c@@QAE?AW4eap_status_e@@XZ @ 102 NONAME ; enum eap_status_e wapi_ethernet_core_c::cancel_all_authentication_sessions(void)
+	?set_change_status@ec_cs_data_c@@QAEXW4ec_cs_data_change_status_e@@@Z @ 103 NONAME ; void ec_cs_data_c::set_change_status(enum ec_cs_data_change_status_e)
+	??1ec_cs_compare_certificate_reference_c@@UAE@XZ @ 104 NONAME ; ec_cs_compare_certificate_reference_c::~ec_cs_compare_certificate_reference_c(void)
+	?get_change_status@ec_cs_data_c@@QBE?AW4ec_cs_data_change_status_e@@XZ @ 105 NONAME ; enum ec_cs_data_change_status_e ec_cs_data_c::get_change_status(void) const
+	?set_completion_action@ec_cs_completion_c@@QAEXW4ec_cs_completion_e@@@Z @ 106 NONAME ; void ec_cs_completion_c::set_completion_action(enum ec_cs_completion_e)
+	?reset@ec_cs_tlv_message_c@@QAE?AW4eap_status_e@@XZ @ 107 NONAME ; enum eap_status_e ec_cs_tlv_message_c::reset(void)
+	?cancel_all_authentication_sessions@wapi_session_core_c@@QAE?AW4eap_status_e@@XZ @ 108 NONAME ; enum eap_status_e wapi_session_core_c::cancel_all_authentication_sessions(void)
+	?packet_data_session_key@wapi_session_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeapol_session_key_c@@@Z @ 109 NONAME ; enum eap_status_e wapi_session_core_c::packet_data_session_key(class eap_am_network_id_c const *, class eapol_session_key_c const *)
+	?process_message_type_error@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 110 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::process_message_type_error(class eap_array_c<class eap_tlv_header_c> const *)
+	?add_next_payload_with_same_tlv_type@wai_variable_data_c@@QAEXPAV1@@Z @ 111 NONAME ; void wai_variable_data_c::add_next_payload_with_same_tlv_type(class wai_variable_data_c *)
+	?packet_process@wapi_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 112 NONAME ; enum eap_status_e wapi_core_c::packet_process(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long)
+	?check_payloads_existense@ec_cs_tlv_payloads_c@@QBE?AW4eap_status_e@@PBV?$eap_array_c@W4ec_cs_tlv_type_e@@@@@Z @ 113 NONAME ; enum eap_status_e ec_cs_tlv_payloads_c::check_payloads_existense(class eap_array_c<enum ec_cs_tlv_type_e> const *) const
+	?timer_delete_data@wapi_message_wlan_authentication_c@@UAE?AW4eap_status_e@@KPAX@Z @ 114 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::timer_delete_data(unsigned long, void *)
+	?compare_id_and_certificate@ec_certificate_store_c@@AAE?AW4eap_status_e@@PBVeap_variable_data_c@@0@Z @ 115 NONAME ; enum eap_status_e ec_certificate_store_c::compare_id_and_certificate(class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?shutdown@wapi_wlan_authentication_c@@QAE?AW4eap_status_e@@XZ @ 116 NONAME ; enum eap_status_e wapi_wlan_authentication_c::shutdown(void)
+	?init_header@ec_cs_variable_data_c@@QAE?AW4eap_status_e@@W4ec_cs_tlv_type_e@@K@Z @ 117 NONAME ; enum eap_status_e ec_cs_variable_data_c::init_header(enum ec_cs_tlv_type_e, unsigned long)
+	??0ec_cs_compare_certificate_id_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_variable_data_c@@1@Z @ 118 NONAME ; ec_cs_compare_certificate_id_c::ec_cs_compare_certificate_id_c(class abs_eap_am_tools_c *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?timer_expired@wapi_wlan_authentication_c@@UAE?AW4eap_status_e@@KPAX@Z @ 119 NONAME ; enum eap_status_e wapi_wlan_authentication_c::timer_expired(unsigned long, void *)
+	?reset@wapi_am_core_symbian_c@@UAE?AW4eap_status_e@@XZ @ 120 NONAME ; enum eap_status_e wapi_am_core_symbian_c::reset(void)
+	?select_certificate@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 121 NONAME ; enum eap_status_e ec_certificate_store_c::select_certificate(class eap_variable_data_c const *)
+	?check_bksa_cache@wapi_wlan_authentication_c@@QAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_am_network_id_c@@@@W4eapol_key_authentication_type_e@@W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@2@Z @ 122 NONAME ; enum eap_status_e wapi_wlan_authentication_c::check_bksa_cache(class eap_array_c<class eap_am_network_id_c> *, enum eapol_key_authentication_type_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e)
+	??0ec_cs_tlv_c@@QAE@PAVabs_eap_am_tools_c@@_N@Z @ 123 NONAME ; ec_cs_tlv_c::ec_cs_tlv_c(class abs_eap_am_tools_c *, bool)
+	?cancel_all_timers@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@XZ @ 124 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::cancel_all_timers(void)
+	??0ec_am_algorithms_direct_nrc_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_ec_am_algorithms_c@@_N@Z @ 125 NONAME ; ec_am_algorithms_direct_nrc_c::ec_am_algorithms_direct_nrc_c(class abs_eap_am_tools_c *, class abs_ec_am_algorithms_c *, bool)
+	??1eap_am_file_input_symbian_c@@UAE@XZ @ 126 NONAME ; eap_am_file_input_symbian_c::~eap_am_file_input_symbian_c(void)
+	?get_type_data@wai_variable_data_c@@QBEPAEK@Z @ 127 NONAME ; unsigned char * wai_variable_data_c::get_type_data(unsigned long) const
+	?reset_wapi_configuration@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@XZ @ 128 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::reset_wapi_configuration(void)
+	??1wapi_ethernet_core_c@@UAE@XZ @ 129 NONAME ; wapi_ethernet_core_c::~wapi_ethernet_core_c(void)
+	?read_certificate_id@wapi_certificate_asn1_der_parser_c@@QAE?AW4eap_status_e@@PAVeap_variable_data_c@@00@Z @ 130 NONAME ; enum eap_status_e wapi_certificate_asn1_der_parser_c::read_certificate_id(class eap_variable_data_c *, class eap_variable_data_c *, class eap_variable_data_c *)
+	?object_decrease_reference_count@wapi_core_c@@QAEKXZ @ 131 NONAME ; unsigned long wapi_core_c::object_decrease_reference_count(void)
+	?set_is_valid@wapi_wlan_authentication_c@@QAEXXZ @ 132 NONAME ; void wapi_wlan_authentication_c::set_is_valid(void)
+	?get_full_data_length@asn1_der_type_c@@QBEKXZ @ 133 NONAME ; unsigned long asn1_der_type_c::get_full_data_length(void) const
+	??0wai_variable_data_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 134 NONAME ; wai_variable_data_c::wai_variable_data_c(class abs_eap_am_tools_c *)
+	?compare_object_identifier@asn1_der_type_c@@QBE?AW4eap_status_e@@PBDK@Z @ 135 NONAME ; enum eap_status_e asn1_der_type_c::compare_object_identifier(char const *, unsigned long) const
+	??1wapi_strings_c@@UAE@XZ @ 136 NONAME ; wapi_strings_c::~wapi_strings_c(void)
+	?file_read@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 137 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_read(class eap_variable_data_c *)
+	??1ec_base_certificate_store_c@@UAE@XZ @ 138 NONAME ; ec_base_certificate_store_c::~ec_base_certificate_store_c(void)
+	?reset@wai_message_c@@QAE?AW4eap_status_e@@XZ @ 139 NONAME ; enum eap_status_e wai_message_c::reset(void)
+	?create_master_key_data@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@000PAV3@@Z @ 140 NONAME ; enum eap_status_e ec_cs_tlv_c::create_master_key_data(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *)
+	?parse_data_with_MAC@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0@Z @ 141 NONAME ; enum eap_status_e ec_cs_tlv_c::parse_data_with_MAC(class eap_variable_data_c const *, class eap_variable_data_c const *)
+	??1ec_cs_compare_certificate_id_c@@UAE@XZ @ 142 NONAME ; ec_cs_compare_certificate_id_c::~ec_cs_compare_certificate_id_c(void)
+	?get_is_valid@wapi_am_core_symbian_c@@MAE_NXZ @ 143 NONAME ; bool wapi_am_core_symbian_c::get_is_valid(void)
+	?convert_to_wai_tlv_type@wai_variable_data_c@@SA?AW4wai_tlv_type_e@@W4wai_payload_type_e@@@Z @ 144 NONAME ; enum wai_tlv_type_e wai_variable_data_c::convert_to_wai_tlv_type(enum wai_payload_type_e)
+	?verify_signature_with_public_key@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@00_N@Z @ 145 NONAME ; enum eap_status_e ec_certificate_store_c::verify_signature_with_public_key(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, bool)
+	?set_authentication_role@wapi_core_c@@QAE?AW4eap_status_e@@_N@Z @ 146 NONAME ; enum eap_status_e wapi_core_c::set_authentication_role(bool)
+	?check_bksa_cache@wapi_ethernet_core_c@@QAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_am_network_id_c@@@@W4eapol_key_authentication_type_e@@W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@2@Z @ 147 NONAME ; enum eap_status_e wapi_ethernet_core_c::check_bksa_cache(class eap_array_c<class eap_am_network_id_c> *, enum eapol_key_authentication_type_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e)
+	?get_class_string@asn1_der_type_c@@QBEPBDXZ @ 148 NONAME ; char const * asn1_der_type_c::get_class_string(void) const
+	?packet_send@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 149 NONAME ; enum eap_status_e wapi_ethernet_core_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long)
+	?completion_action_check@ec_certificate_store_c@@AAE?AW4eap_status_e@@XZ @ 150 NONAME ; enum eap_status_e ec_certificate_store_c::completion_action_check(void)
+	?get_previous_type@asn1_der_type_c@@QBEPBV1@XZ @ 151 NONAME ; class asn1_der_type_c const * asn1_der_type_c::get_previous_type(void) const
+	?complete_select_certificate@wapi_core_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 152 NONAME ; enum eap_status_e wapi_core_c::complete_select_certificate(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?parse_wai_payloads@wai_message_payloads_c@@QAE?AW4eap_status_e@@PAXKPAK@Z @ 153 NONAME ; enum eap_status_e wai_message_payloads_c::parse_wai_payloads(void *, unsigned long, unsigned long *)
+	?get_is_client@wapi_wlan_authentication_c@@UAE_NXZ @ 154 NONAME ; bool wapi_wlan_authentication_c::get_is_client(void)
+	?complete_create_ecdh_temporary_keys@wapi_core_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 155 NONAME ; enum eap_status_e wapi_core_c::complete_create_ecdh_temporary_keys(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?create_signature_with_private_key@ec_am_algorithms_direct_nrc_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@0@Z @ 156 NONAME ; enum eap_status_e ec_am_algorithms_direct_nrc_c::create_signature_with_private_key(class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?SetCACertL@CWapiCertificates@@QAEXHV?$TBuf8@$0BDG@@@@Z @ 157 NONAME ; void CWapiCertificates::SetCACertL(int, class TBuf8<310>)
+	?get_header@ec_cs_variable_data_c@@QBEPBVec_cs_tlv_header_c@@XZ @ 158 NONAME ; class ec_cs_tlv_header_c const * ec_cs_variable_data_c::get_header(void) const
+	?convert_to_wai_certificate_identifier@wai_variable_data_c@@SA?AW4wai_certificate_identifier_e@@W4wai_payload_type_e@@@Z @ 159 NONAME ; enum wai_certificate_identifier_e wai_variable_data_c::convert_to_wai_certificate_identifier(enum wai_payload_type_e)
+	?packet_process@wapi_wlan_authentication_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 160 NONAME ; enum eap_status_e wapi_wlan_authentication_c::packet_process(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long)
+	??0wapi_ethernet_core_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_wapi_ethernet_core_c@@_N@Z @ 161 NONAME ; wapi_ethernet_core_c::wapi_ethernet_core_c(class abs_eap_am_tools_c *, class abs_wapi_ethernet_core_c *, bool)
+	?parse_encrypted_tlv_with_MAC@ec_cs_tlv_c@@QAE?AW4eap_status_e@@W4ec_cs_data_type_e@@PBVeap_variable_data_c@@111PAVec_cs_variable_data_c@@@Z @ 162 NONAME ; enum eap_status_e ec_cs_tlv_c::parse_encrypted_tlv_with_MAC(enum ec_cs_data_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, class ec_cs_variable_data_c *)
+	?get_ec_cs_store_data_string@ec_cs_strings_c@@SAPBDW4ec_cs_data_type_e@@@Z @ 163 NONAME ; char const * ec_cs_strings_c::get_ec_cs_store_data_string(enum ec_cs_data_type_e)
+	?timer_delete_data@wapi_session_core_c@@UAE?AW4eap_status_e@@KPAX@Z @ 164 NONAME ; enum eap_status_e wapi_session_core_c::timer_delete_data(unsigned long, void *)
+	?read_configure@wapi_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 165 NONAME ; enum eap_status_e wapi_core_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?read_configure@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 166 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?packet_process@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 167 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::packet_process(class eap_array_c<class eap_tlv_header_c> const *)
+	?asynchronous_init_remove_wapi_session@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 168 NONAME ; enum eap_status_e wapi_ethernet_core_c::asynchronous_init_remove_wapi_session(class eap_am_network_id_c const *)
+	?complete_initialize_certificate_store@ec_certificate_store_c@@UAE?AW4eap_status_e@@W4wapi_completion_operation_e@@@Z @ 169 NONAME ; enum eap_status_e ec_certificate_store_c::complete_initialize_certificate_store(enum wapi_completion_operation_e)
+	?create_encrypted_tlv@ec_cs_tlv_c@@QAE?AW4eap_status_e@@W4ec_cs_tlv_type_e@@PBVeap_variable_data_c@@PBVec_cs_variable_data_c@@PAV5@@Z @ 170 NONAME ; enum eap_status_e ec_cs_tlv_c::create_encrypted_tlv(enum ec_cs_tlv_type_e, class eap_variable_data_c const *, class ec_cs_variable_data_c const *, class ec_cs_variable_data_c *)
+	?timer_expired@ec_certificate_store_c@@UAE?AW4eap_status_e@@KPAX@Z @ 171 NONAME ; enum eap_status_e ec_certificate_store_c::timer_expired(unsigned long, void *)
+	?timer_expired@wapi_message_wlan_authentication_c@@UAE?AW4eap_status_e@@KPAX@Z @ 172 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::timer_expired(unsigned long, void *)
+	?add_imported_certificate_file@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@0@Z @ 173 NONAME ; enum eap_status_e ec_certificate_store_c::add_imported_certificate_file(class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?generate_data_key@ec_cs_tlv_c@@QAE?AW4eap_status_e@@_NW4ec_cs_data_type_e@@PAVeap_variable_data_c@@PBV4@33@Z @ 174 NONAME ; enum eap_status_e ec_cs_tlv_c::generate_data_key(bool, enum ec_cs_data_type_e, class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?set_timer@wapi_session_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 175 NONAME ; enum eap_status_e wapi_session_core_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long)
+	?set_copy_of_buffer@wai_variable_data_c@@QAE?AW4eap_status_e@@W4wai_payload_type_e@@PBXK@Z @ 176 NONAME ; enum eap_status_e wai_variable_data_c::set_copy_of_buffer(enum wai_payload_type_e, void const *, unsigned long)
+	?create_ec_cs_tlv_message@ec_cs_tlv_payloads_c@@QBE?AW4eap_status_e@@PAVec_cs_tlv_message_c@@_N@Z @ 177 NONAME ; enum eap_status_e ec_cs_tlv_payloads_c::create_ec_cs_tlv_message(class ec_cs_tlv_message_c *, bool) const
+	?get_authentication_counter@wapi_wlan_authentication_c@@QAEKXZ @ 178 NONAME ; unsigned long wapi_wlan_authentication_c::get_authentication_counter(void)
+	?reset@ec_cs_data_c@@QAE?AW4eap_status_e@@XZ @ 179 NONAME ; enum eap_status_e ec_cs_data_c::reset(void)
+	?internal_complete_add_imported_certificate_file@ec_certificate_store_c@@AAE?AW4eap_status_e@@XZ @ 180 NONAME ; enum eap_status_e ec_certificate_store_c::internal_complete_add_imported_certificate_file(void)
+	?cancel_authentication_session@wapi_core_c@@QAE?AW4eap_status_e@@XZ @ 181 NONAME ; enum eap_status_e wapi_core_c::cancel_authentication_session(void)
+	?reset@ec_cs_variable_data_c@@QAE?AW4eap_status_e@@XZ @ 182 NONAME ; enum eap_status_e ec_cs_variable_data_c::reset(void)
+	?get_ec_cs_message_data@ec_cs_tlv_message_c@@QAEPAVeap_variable_data_c@@XZ @ 183 NONAME ; class eap_variable_data_c * ec_cs_tlv_message_c::get_ec_cs_message_data(void)
+	?completion_action_pop@ec_certificate_store_c@@AAE?AW4eap_status_e@@XZ @ 184 NONAME ; enum eap_status_e ec_certificate_store_c::completion_action_pop(void)
+	?parse_generic_payload@wai_message_payloads_c@@AAE?AW4eap_status_e@@W4wai_payload_type_e@@PBVwai_variable_data_c@@PAK@Z @ 185 NONAME ; enum eap_status_e wai_message_payloads_c::parse_generic_payload(enum wai_payload_type_e, class wai_variable_data_c const *, unsigned long *)
+	?get_wai_tlv_header_string@wapi_strings_c@@SAPBDW4wai_tlv_type_e@@@Z @ 186 NONAME ; char const * wapi_strings_c::get_wai_tlv_header_string(enum wai_tlv_type_e)
+	??0CWapiCertificates@@QAE@XZ @ 187 NONAME ; CWapiCertificates::CWapiCertificates(void)
+	?get_ec_cs_tlv_header_string@ec_cs_strings_c@@SAPBDW4ec_cs_tlv_type_e@@@Z @ 188 NONAME ; char const * ec_cs_strings_c::get_ec_cs_tlv_header_string(enum ec_cs_tlv_type_e)
+	?set_data_references_read@ec_cs_data_c@@QAEXXZ @ 189 NONAME ; void ec_cs_data_c::set_data_references_read(void)
+	?shutdown@wapi_am_core_symbian_c@@UAE?AW4eap_status_e@@XZ @ 190 NONAME ; enum eap_status_e wapi_am_core_symbian_c::shutdown(void)
+	?get_packet_sequence_number@wapi_core_retransmission_c@@QBEGXZ @ 191 NONAME ; unsigned short wapi_core_retransmission_c::get_packet_sequence_number(void) const
+	??0ec_cs_compare_reference_issuer_name_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 192 NONAME ; ec_cs_compare_reference_issuer_name_c::ec_cs_compare_reference_issuer_name_c(class abs_eap_am_tools_c *)
+	?read_reassociation_parameters@wapi_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PAVeap_variable_data_c@@PBV5@3@Z @ 193 NONAME ; enum eap_status_e wapi_core_c::read_reassociation_parameters(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?complete_reassociation@wapi_wlan_authentication_c@@QAE?AW4eap_status_e@@W4eapol_wlan_authentication_state_e@@PBVeap_am_network_id_c@@PBVeap_variable_data_c@@2W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@3@Z @ 194 NONAME ; enum eap_status_e wapi_wlan_authentication_c::complete_reassociation(enum eapol_wlan_authentication_state_e, class eap_am_network_id_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e)
+	?get_type_data_length@wai_variable_data_c@@QBEKXZ @ 195 NONAME ; unsigned long wai_variable_data_c::get_type_data_length(void) const
+	??1ec_cs_variable_data_c@@UAE@XZ @ 196 NONAME ; ec_cs_variable_data_c::~ec_cs_variable_data_c(void)
+	?get_class@asn1_der_type_c@@QBE?AW4asn1_class_e@1@XZ @ 197 NONAME ; enum asn1_der_type_c::asn1_class_e asn1_der_type_c::get_class(void) const
+	?get_wai_protocol_packet_header@wai_message_payloads_c@@QBEPBVwai_protocol_packet_header_c@@XZ @ 198 NONAME ; class wai_protocol_packet_header_c const * wai_message_payloads_c::get_wai_protocol_packet_header(void) const
+	?set_wapi_failure_timeout@wapi_core_c@@AAE?AW4eap_status_e@@XZ @ 199 NONAME ; enum eap_status_e wapi_core_c::set_wapi_failure_timeout(void)
+	?get_tlv_count@wai_message_payloads_c@@QBEKXZ @ 200 NONAME ; unsigned long wai_message_payloads_c::get_tlv_count(void) const
+	?read_generic_tlv@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PBVec_cs_variable_data_c@@W4ec_cs_tlv_type_e@@PAVeap_variable_data_c@@@Z @ 201 NONAME ; enum eap_status_e ec_cs_tlv_c::read_generic_tlv(class ec_cs_variable_data_c const *, enum ec_cs_tlv_type_e, class eap_variable_data_c *)
+	?compare@ec_cs_compare_reference_issuer_name_c@@UBEJPBVec_cs_data_c@@0@Z @ 202 NONAME ; long ec_cs_compare_reference_issuer_name_c::compare(class ec_cs_data_c const *, class ec_cs_data_c const *) const
+	?are_pending_queries_completed@ec_certificate_store_c@@AAE?AW4eap_status_e@@XZ @ 203 NONAME ; enum eap_status_e ec_certificate_store_c::are_pending_queries_completed(void)
+	?file_read_line@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 204 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_read_line(class eap_variable_data_c *)
+	?set_copy_of_buffer@wai_variable_data_c@@QAE?AW4eap_status_e@@PBV1@@Z @ 205 NONAME ; enum eap_status_e wai_variable_data_c::set_copy_of_buffer(class wai_variable_data_c const *)
+	?create_wai_tlv_message@wai_message_payloads_c@@QBE?AW4eap_status_e@@PAVwai_message_c@@_N@Z @ 206 NONAME ; enum eap_status_e wai_message_payloads_c::create_wai_tlv_message(class wai_message_c *, bool) const
+	?get_is_valid@eap_core_retransmission_c@@QBE_NXZ @ 207 NONAME ; bool eap_core_retransmission_c::get_is_valid(void) const
+	?packet_send@wapi_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 208 NONAME ; enum eap_status_e wapi_core_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long)
+	?complete_reassociation@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 209 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::complete_reassociation(class eap_array_c<class eap_tlv_header_c> const *)
+	?set_key@wapi_am_crypto_sms4_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 210 NONAME ; enum eap_status_e wapi_am_crypto_sms4_c::set_key(class eap_variable_data_c const *)
+	?get_is_valid@ec_cs_tlv_c@@QAE_NXZ @ 211 NONAME ; bool ec_cs_tlv_c::get_is_valid(void)
+	?get_full_tlv_buffer@ec_cs_variable_data_c@@QBEPBVeap_variable_data_c@@XZ @ 212 NONAME ; class eap_variable_data_c const * ec_cs_variable_data_c::get_full_tlv_buffer(void) const
+	?read_u16_t_tlv@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PBVec_cs_variable_data_c@@W4ec_cs_tlv_type_e@@PAG@Z @ 213 NONAME ; enum eap_status_e ec_cs_tlv_c::read_u16_t_tlv(class ec_cs_variable_data_c const *, enum ec_cs_tlv_type_e, unsigned short *)
+	?remove_cached_certificate_store_data@ec_certificate_store_c@@UAE?AW4eap_status_e@@XZ @ 214 NONAME ; enum eap_status_e ec_certificate_store_c::remove_cached_certificate_store_data(void)
+	?file_delete@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 215 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_delete(class eap_variable_data_c const *)
+	?shutdown@ec_certificate_store_c@@UAE?AW4eap_status_e@@XZ @ 216 NONAME ; enum eap_status_e ec_certificate_store_c::shutdown(void)
+	?get_payloads@ec_cs_tlv_c@@QBEPBVec_cs_tlv_payloads_c@@XZ @ 217 NONAME ; class ec_cs_tlv_payloads_c const * ec_cs_tlv_c::get_payloads(void) const
+	?get_data_length@wai_variable_data_c@@QBEKXZ @ 218 NONAME ; unsigned long wai_variable_data_c::get_data_length(void) const
+	?get_wai_message_data@wai_message_c@@QBEPBVeap_variable_data_c@@XZ @ 219 NONAME ; class eap_variable_data_c const * wai_message_c::get_wai_message_data(void) const
+	?configure@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@XZ @ 220 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::configure(void)
+	?object_increase_reference_count@ec_cs_variable_data_c@@QAEXXZ @ 221 NONAME ; void ec_cs_variable_data_c::object_increase_reference_count(void)
+	?cancel_all_timers@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@XZ @ 222 NONAME ; enum eap_status_e wapi_ethernet_core_c::cancel_all_timers(void)
+	?set_is_invalid@wapi_am_crypto_sms4_c@@AAEXXZ @ 223 NONAME ; void wapi_am_crypto_sms4_c::set_is_invalid(void)
+	??1CWapiCertificates@@UAE@XZ @ 224 NONAME ; CWapiCertificates::~CWapiCertificates(void)
+	?add_data@ec_cs_variable_data_c@@QAE?AW4eap_status_e@@PBV1@@Z @ 225 NONAME ; enum eap_status_e ec_cs_variable_data_c::add_data(class ec_cs_variable_data_c const *)
+	??1ec_cs_compare_certificate_issuer_name_c@@UAE@XZ @ 226 NONAME ; ec_cs_compare_certificate_issuer_name_c::~ec_cs_compare_certificate_issuer_name_c(void)
+	??0ec_cs_compare_certificate_issuer_name_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_variable_data_c@@1@Z @ 227 NONAME ; ec_cs_compare_certificate_issuer_name_c::ec_cs_compare_certificate_issuer_name_c(class abs_eap_am_tools_c *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?reset@ec_cs_tlv_c@@QAE?AW4eap_status_e@@XZ @ 228 NONAME ; enum eap_status_e ec_cs_tlv_c::reset(void)
+	?complete_verify_signature_with_public_key@wapi_core_c@@UAE?AW4eap_status_e@@W42@@Z @ 229 NONAME ; enum eap_status_e wapi_core_c::complete_verify_signature_with_public_key(enum eap_status_e)
+	?packet_data_session_key@wapi_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeapol_session_key_c@@@Z @ 230 NONAME ; enum eap_status_e wapi_wlan_authentication_c::packet_data_session_key(class eap_am_network_id_c const *, class eapol_session_key_c const *)
+	?get_tlv_pointer@wai_message_payloads_c@@QBEPAVwai_variable_data_c@@W4wai_payload_type_e@@@Z @ 231 NONAME ; class wai_variable_data_c * wai_message_payloads_c::get_tlv_pointer(enum wai_payload_type_e) const
+	?synchronous_cancel_all_wapi_sessions@wapi_session_core_c@@QAE?AW4eap_status_e@@XZ @ 232 NONAME ; enum eap_status_e wapi_session_core_c::synchronous_cancel_all_wapi_sessions(void)
+	?get_next_retransmission_counter@wapi_core_retransmission_c@@QAEKXZ @ 233 NONAME ; unsigned long wapi_core_retransmission_c::get_next_retransmission_counter(void)
+	?init_retransmission@wapi_core_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVwai_message_c@@1GW4wai_protocol_subtype_e@@@Z @ 234 NONAME ; enum eap_status_e wapi_core_c::init_retransmission(class eap_am_network_id_c const *, class wai_message_c const *, class wai_message_c const *, unsigned short, enum wai_protocol_subtype_e)
+	?get_wapi_subtype@wapi_core_retransmission_c@@QBE?AW4wai_protocol_subtype_e@@XZ @ 235 NONAME ; enum wai_protocol_subtype_e wapi_core_retransmission_c::get_wapi_subtype(void) const
+	?get_is_valid@asn1_der_type_c@@QBE_NXZ @ 236 NONAME ; bool asn1_der_type_c::get_is_valid(void) const
+	?GetConfigurationL@CWapiCertificates@@QAEXHAAVTDes16@@0@Z @ 237 NONAME ; void CWapiCertificates::GetConfigurationL(int, class TDes16 &, class TDes16 &)
+	??0wapi_strings_c@@QAE@XZ @ 238 NONAME ; wapi_strings_c::wapi_strings_c(void)
+	?association@wapi_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@2W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@32@Z @ 239 NONAME ; enum eap_status_e wapi_session_core_c::association(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, class eap_variable_data_c const *)
+	??1ec_cs_compare_reference_id_c@@UAE@XZ @ 240 NONAME ; ec_cs_compare_reference_id_c::~ec_cs_compare_reference_id_c(void)
+	?packet_data_session_key@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeapol_session_key_c@@@Z @ 241 NONAME ; enum eap_status_e wapi_ethernet_core_c::packet_data_session_key(class eap_am_network_id_c const *, class eapol_session_key_c const *)
+	?get_content@asn1_der_type_c@@QBEPBEXZ @ 242 NONAME ; unsigned char const * asn1_der_type_c::get_content(void) const
+	?set_wai_message_data@wai_message_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 243 NONAME ; enum eap_status_e wai_message_c::set_wai_message_data(class eap_variable_data_c const *)
+	?compare@ec_cs_compare_certificate_id_c@@UBEJPBVec_cs_data_c@@0@Z @ 244 NONAME ; long ec_cs_compare_certificate_id_c::compare(class ec_cs_data_c const *, class ec_cs_data_c const *) const
+	?ecb_encrypt@wapi_am_crypto_sms4_c@@QAE?AW4eap_status_e@@PBXPAXK@Z @ 245 NONAME ; enum eap_status_e wapi_am_crypto_sms4_c::ecb_encrypt(void const *, void *, unsigned long)
+	?set_copy_of_buffer@ec_cs_variable_data_c@@QAE?AW4eap_status_e@@PBV1@@Z @ 246 NONAME ; enum eap_status_e ec_cs_variable_data_c::set_copy_of_buffer(class ec_cs_variable_data_c const *)
+	?complete_association@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 247 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::complete_association(class eap_array_c<class eap_tlv_header_c> const *)
+	??0ec_cs_tlv_payloads_c@@QAE@PAVabs_eap_am_tools_c@@_N@Z @ 248 NONAME ; ec_cs_tlv_payloads_c::ec_cs_tlv_payloads_c(class abs_eap_am_tools_c *, bool)
+	?read_configure@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 249 NONAME ; enum eap_status_e wapi_ethernet_core_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?compare_object_identifier@asn1_der_type_c@@QBE?AW4eap_status_e@@PBEK@Z @ 250 NONAME ; enum eap_status_e asn1_der_type_c::compare_object_identifier(unsigned char const *, unsigned long) const
+	?state_notification@wapi_message_wlan_authentication_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 251 NONAME ; void wapi_message_wlan_authentication_c::state_notification(class abs_eap_state_notification_c const *)
+	??0eap_core_retransmission_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKKKW4eap_code_value_e@@EVeap_expanded_type_c@@@Z @ 252 NONAME ; eap_core_retransmission_c::eap_core_retransmission_c(class abs_eap_am_tools_c *, class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long, unsigned long, enum eap_code_value_e, unsigned char, class eap_expanded_type_c)
+	?set_is_valid@wapi_am_crypto_sms4_c@@AAEXXZ @ 253 NONAME ; void wapi_am_crypto_sms4_c::set_is_valid(void)
+	?disassociation@wapi_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 254 NONAME ; enum eap_status_e wapi_session_core_c::disassociation(class eap_am_network_id_c const *)
+	?set_next_payload_with_same_tlv_type@wai_variable_data_c@@QAEXPAV1@@Z @ 255 NONAME ; void wai_variable_data_c::set_next_payload_with_same_tlv_type(class wai_variable_data_c *)
+	?ResetCertificateStoreL@CWapiCertificates@@QAEXXZ @ 256 NONAME ; void CWapiCertificates::ResetCertificateStoreL(void)
+	?update_header_offset@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 257 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::update_header_offset(class eap_array_c<class eap_tlv_header_c> const *)
+	?L_data@wapi_am_crypto_sms4_c@@AAEXPAK@Z @ 258 NONAME ; void wapi_am_crypto_sms4_c::L_data(unsigned long *)
+	??1wai_message_c@@UAE@XZ @ 259 NONAME ; wai_message_c::~wai_message_c(void)
+	?get_send_network_id@wapi_core_retransmission_c@@QBEPAVeap_am_network_id_c@@XZ @ 260 NONAME ; class eap_am_network_id_c * wapi_core_retransmission_c::get_send_network_id(void) const
+	?create_upper_stack@wapi_wlan_authentication_c@@AAE?AW4eap_status_e@@XZ @ 261 NONAME ; enum eap_status_e wapi_wlan_authentication_c::create_upper_stack(void)
+	?restart_authentication@wapi_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N@Z @ 262 NONAME ; enum eap_status_e wapi_core_c::restart_authentication(class eap_am_network_id_c const *, bool)
+	?get_is_valid@wapi_am_wlan_authentication_symbian_c@@UAE_NXZ @ 263 NONAME ; bool wapi_am_wlan_authentication_symbian_c::get_is_valid(void)
+	?disassociation@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 264 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::disassociation(class eap_am_network_id_c const *)
+	?directory_read@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PAV?$eap_array_c@Vabs_eap_file_stat_c@@@@@Z @ 265 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::directory_read(class eap_array_c<class abs_eap_file_stat_c> *)
+	??0ec_cs_compare_reference_id_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 266 NONAME ; ec_cs_compare_reference_id_c::ec_cs_compare_reference_id_c(class abs_eap_am_tools_c *)
+	?file_read_word@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 267 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_read_word(class eap_variable_data_c *)
+	?read_configure@wapi_session_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 268 NONAME ; enum eap_status_e wapi_session_core_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?cancel_timer@wapi_session_core_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 269 NONAME ; enum eap_status_e wapi_session_core_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long)
+	?start_authentication@wapi_wlan_authentication_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@W4eapol_key_authentication_type_e@@0_NPBVeap_am_network_id_c@@@Z @ 270 NONAME ; enum eap_status_e wapi_wlan_authentication_c::start_authentication(class eap_variable_data_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *, bool, class eap_am_network_id_c const *)
+	?reset@wapi_core_c@@QAE?AW4eap_status_e@@XZ @ 271 NONAME ; enum eap_status_e wapi_core_c::reset(void)
+	?complete_query_asu_id@wapi_core_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@00W42@@Z @ 272 NONAME ; enum eap_status_e wapi_core_c::complete_query_asu_id(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *, enum eap_status_e)
+	?get_wapi_identity@wapi_asn1_der_parser_c@@QAE?AW4eap_status_e@@PAVeap_variable_data_c@@00@Z @ 273 NONAME ; enum eap_status_e wapi_asn1_der_parser_c::get_wapi_identity(class eap_variable_data_c *, class eap_variable_data_c *, class eap_variable_data_c *)
+	?add_next_payload_with_same_tlv_type@ec_cs_variable_data_c@@QAEXPAV1@@Z @ 274 NONAME ; void ec_cs_variable_data_c::add_next_payload_with_same_tlv_type(class ec_cs_variable_data_c *)
+	?create_MAC@ec_cs_tlv_c@@AAE?AW4eap_status_e@@PAVeap_variable_data_c@@PBV3@1@Z @ 275 NONAME ; enum eap_status_e ec_cs_tlv_c::create_MAC(class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?complete_remove_certificate_store@wapi_am_core_symbian_c@@MAE?AW4eap_status_e@@W42@@Z @ 276 NONAME ; enum eap_status_e wapi_am_core_symbian_c::complete_remove_certificate_store(enum eap_status_e)
+	?create_ecdh_temporary_keys@ec_am_algorithms_direct_nrc_c@@UAE?AW4eap_status_e@@XZ @ 277 NONAME ; enum eap_status_e ec_am_algorithms_direct_nrc_c::create_ecdh_temporary_keys(void)
+	?write_configure@wapi_session_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 278 NONAME ; enum eap_status_e wapi_session_core_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	??0wapi_am_crypto_sms4_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 279 NONAME ; wapi_am_crypto_sms4_c::wapi_am_crypto_sms4_c(class abs_eap_am_tools_c *)
+	?get_full_tlv_buffer@wai_variable_data_c@@QBEPBVeap_variable_data_c@@XZ @ 280 NONAME ; class eap_variable_data_c const * wai_variable_data_c::get_full_tlv_buffer(void) const
+	?reset@wai_variable_data_c@@QAE?AW4eap_status_e@@XZ @ 281 NONAME ; enum eap_status_e wai_variable_data_c::reset(void)
+	?start_reassociation@wapi_wlan_authentication_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@0W4eapol_key_authentication_type_e@@@Z @ 282 NONAME ; enum eap_status_e wapi_wlan_authentication_c::start_reassociation(class eap_am_network_id_c const *, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e)
+	?completion_action_clenup@ec_certificate_store_c@@AAE?AW4eap_status_e@@XZ @ 283 NONAME ; enum eap_status_e ec_certificate_store_c::completion_action_clenup(void)
+	?reset_or_remove_session@wapi_session_core_c@@AAE?AW4eap_status_e@@PAPAVwapi_core_c@@PBVeap_network_id_selector_c@@_N@Z @ 284 NONAME ; enum eap_status_e wapi_session_core_c::reset_or_remove_session(class wapi_core_c * *, class eap_network_id_selector_c const *, bool)
+	?get_is_valid@ec_cs_tlv_payloads_c@@QBE_NXZ @ 285 NONAME ; bool ec_cs_tlv_payloads_c::get_is_valid(void) const
+	?get_sub_types@asn1_der_type_c@@QBEPBV?$eap_array_c@Vasn1_der_type_c@@@@XZ @ 286 NONAME ; class eap_array_c<class asn1_der_type_c> const * asn1_der_type_c::get_sub_types(void) const
+	?get_header_offset@wapi_ethernet_core_c@@UAEKPAK0@Z @ 287 NONAME ; unsigned long wapi_ethernet_core_c::get_header_offset(unsigned long *, unsigned long *)
+	?wapi_indication@wapi_wlan_authentication_c@@EAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_wlan_authentication_state_e@@@Z @ 288 NONAME ; enum eap_status_e wapi_wlan_authentication_c::wapi_indication(class eap_am_network_id_c const *, enum eapol_wlan_authentication_state_e)
+	?packet_process@wapi_session_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 289 NONAME ; enum eap_status_e wapi_session_core_c::packet_process(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long)
+	??0eap_am_file_input_symbian_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 290 NONAME ; eap_am_file_input_symbian_c::eap_am_file_input_symbian_c(class abs_eap_am_tools_c *)
+	?start_reassociation@wapi_ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@@Z @ 291 NONAME ; enum eap_status_e wapi_ethernet_core_c::start_reassociation(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *)
+	?get_tag_string@asn1_der_type_c@@QBEPBDXZ @ 292 NONAME ; char const * asn1_der_type_c::get_tag_string(void) const
+	?copy@wai_message_c@@QBEPAV1@XZ @ 293 NONAME ; class wai_message_c * wai_message_c::copy(void) const
+	?set_marked_removed@wapi_core_c@@QAEXXZ @ 294 NONAME ; void wapi_core_c::set_marked_removed(void)
+	?cancel_all_timers@wapi_wlan_authentication_c@@UAE?AW4eap_status_e@@XZ @ 295 NONAME ; enum eap_status_e wapi_wlan_authentication_c::cancel_all_timers(void)
+	?timer_delete_data@wapi_wlan_authentication_c@@UAE?AW4eap_status_e@@KPAX@Z @ 296 NONAME ; enum eap_status_e wapi_wlan_authentication_c::timer_delete_data(unsigned long, void *)
+	?set_is_valid@wapi_ethernet_core_c@@UAEXXZ @ 297 NONAME ; void wapi_ethernet_core_c::set_is_valid(void)
+	?get_is_valid@ec_cs_data_c@@QBE_NXZ @ 298 NONAME ; bool ec_cs_data_c::get_is_valid(void) const
+	?get_next_retransmission_time@wapi_core_retransmission_c@@QAEKXZ @ 299 NONAME ; unsigned long wapi_core_retransmission_c::get_next_retransmission_time(void)
+	?init_bksa_caching_timeout@wapi_core_c@@QAE?AW4eap_status_e@@XZ @ 300 NONAME ; enum eap_status_e wapi_core_c::init_bksa_caching_timeout(void)
+	??0wapi_core_retransmission_c@@QAE@PAVabs_eap_am_tools_c@@PBVeap_am_network_id_c@@PBVwai_message_c@@2KKGW4wai_protocol_subtype_e@@@Z @ 301 NONAME ; wapi_core_retransmission_c::wapi_core_retransmission_c(class abs_eap_am_tools_c *, class eap_am_network_id_c const *, class wai_message_c const *, class wai_message_c const *, unsigned long, unsigned long, unsigned short, enum wai_protocol_subtype_e)
+	?get_tag@asn1_der_type_c@@QBE?AW4asn1_tag_e@1@XZ @ 302 NONAME ; enum asn1_der_type_c::asn1_tag_e asn1_der_type_c::get_tag(void) const
+	?get_send_network_id@eap_core_retransmission_c@@QAEPAVeap_am_network_id_c@@XZ @ 303 NONAME ; class eap_am_network_id_c * eap_core_retransmission_c::get_send_network_id(void)
+	??1ec_cs_tlv_c@@UAE@XZ @ 304 NONAME ; ec_cs_tlv_c::~ec_cs_tlv_c(void)
+	?configure@wapi_am_core_symbian_c@@MAE?AW4eap_status_e@@XZ @ 305 NONAME ; enum eap_status_e wapi_am_core_symbian_c::configure(void)
+	?complete_read_id_of_certificate@wapi_core_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 306 NONAME ; enum eap_status_e wapi_core_c::complete_read_id_of_certificate(class eap_variable_data_c const *)
+	?compare@ec_cs_compare_reference_id_c@@UBEJPBVec_cs_data_c@@0@Z @ 307 NONAME ; long ec_cs_compare_reference_id_c::compare(class ec_cs_data_c const *, class ec_cs_data_c const *) const
+	?copy_tlv_data@wai_message_payloads_c@@QAE?AW4eap_status_e@@W4wai_payload_type_e@@PBXK@Z @ 308 NONAME ; enum eap_status_e wai_message_payloads_c::copy_tlv_data(enum wai_payload_type_e, void const *, unsigned long)
+	?directory_open@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 309 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::directory_open(class eap_variable_data_c const *)
+	?set_ec_cs_message_data@ec_cs_tlv_message_c@@QAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 310 NONAME ; enum eap_status_e ec_cs_tlv_message_c::set_ec_cs_message_data(class eap_variable_data_c *)
+	?state_notification@wapi_ethernet_core_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 311 NONAME ; void wapi_ethernet_core_c::state_notification(class abs_eap_state_notification_c const *)
+	?get_retransmission_counter@wapi_core_retransmission_c@@QBEKXZ @ 312 NONAME ; unsigned long wapi_core_retransmission_c::get_retransmission_counter(void) const
+	?increment_authentication_counter@wapi_wlan_authentication_c@@QAEXXZ @ 313 NONAME ; void wapi_wlan_authentication_c::increment_authentication_counter(void)
+	?restart_authentication@wapi_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N@Z @ 314 NONAME ; enum eap_status_e wapi_session_core_c::restart_authentication(class eap_am_network_id_c const *, bool)
+	?check_bksa_cache@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 315 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::check_bksa_cache(class eap_array_c<class eap_tlv_header_c> const *)
+	?file_copy@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@0@Z @ 316 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_copy(class eap_variable_data_c const *, class eap_variable_data_c const *)
+	??1wai_variable_data_c@@UAE@XZ @ 317 NONAME ; wai_variable_data_c::~wai_variable_data_c(void)
+	?set_is_valid@wapi_session_core_c@@UAEXXZ @ 318 NONAME ; void wapi_session_core_c::set_is_valid(void)
+	?set_type@ec_cs_variable_data_c@@QAEXW4ec_cs_tlv_type_e@@@Z @ 319 NONAME ; void ec_cs_variable_data_c::set_type(enum ec_cs_tlv_type_e)
+	?get_header_offset@wapi_wlan_authentication_c@@UAEKPAK0@Z @ 320 NONAME ; unsigned long wapi_wlan_authentication_c::get_header_offset(unsigned long *, unsigned long *)
+	?get_header_offset@wapi_message_wlan_authentication_c@@UAEKPAK0@Z @ 321 NONAME ; unsigned long wapi_message_wlan_authentication_c::get_header_offset(unsigned long *, unsigned long *)
+	?create_ecdh@ec_am_algorithms_direct_nrc_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 322 NONAME ; enum eap_status_e ec_am_algorithms_direct_nrc_c::create_ecdh(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?directory_close@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@XZ @ 323 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::directory_close(void)
+	?write_certificate_store_data@wapi_am_core_symbian_c@@MAE?AW4eap_status_e@@_NW4ec_cs_pending_operation_e@@PBV?$eap_array_c@Vec_cs_data_c@@@@@Z @ 324 NONAME ; enum eap_status_e wapi_am_core_symbian_c::write_certificate_store_data(bool, enum ec_cs_pending_operation_e, class eap_array_c<class ec_cs_data_c> const *)
+	??1abs_ec_certificate_store_c@@UAE@XZ @ 325 NONAME ; abs_ec_certificate_store_c::~abs_ec_certificate_store_c(void)
+	??0ec_cs_strings_c@@QAE@XZ @ 326 NONAME ; ec_cs_strings_c::ec_cs_strings_c(void)
+	?configure@wapi_core_c@@UAE?AW4eap_status_e@@XZ @ 327 NONAME ; enum eap_status_e wapi_core_c::configure(void)
+	?get_ec_cs_tlv_header@wai_variable_data_c@@QBEPBVec_cs_tlv_header_c@@XZ @ 328 NONAME ; class ec_cs_tlv_header_c const * wai_variable_data_c::get_ec_cs_tlv_header(void) const
+	?get_wai_message_data_writable@wai_message_c@@QAEPAVeap_variable_data_c@@XZ @ 329 NONAME ; class eap_variable_data_c * wai_message_c::get_wai_message_data_writable(void)
+	?complete_create_signature_with_private_key@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@W42@@Z @ 330 NONAME ; enum eap_status_e ec_certificate_store_c::complete_create_signature_with_private_key(class eap_variable_data_c const *, enum eap_status_e)
+	?create_u32_t_tlv@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PAVec_cs_variable_data_c@@W4ec_cs_tlv_type_e@@K@Z @ 331 NONAME ; enum eap_status_e ec_cs_tlv_c::create_u32_t_tlv(class ec_cs_variable_data_c *, enum ec_cs_tlv_type_e, unsigned long)
+	?get_wlan_database_reference_values@wapi_message_wlan_authentication_c@@UBE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 332 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::get_wlan_database_reference_values(class eap_variable_data_c *) const
+	?new_wapi_am_core@wapi_am_base_core_c@@SAPAV1@PAVabs_eap_am_tools_c@@PAVabs_wapi_am_core_c@@_NPBVeap_am_network_id_c@@@Z @ 333 NONAME ; class wapi_am_base_core_c * wapi_am_base_core_c::new_wapi_am_core(class abs_eap_am_tools_c *, class abs_wapi_am_core_c *, bool, class eap_am_network_id_c const *)
+	?get_is_valid@ec_cs_completion_c@@QAE_NXZ @ 334 NONAME ; bool ec_cs_completion_c::get_is_valid(void)
+	?timer_expired@wapi_session_core_c@@UAE?AW4eap_status_e@@KPAX@Z @ 335 NONAME ; enum eap_status_e wapi_session_core_c::timer_expired(unsigned long, void *)
+	??1eap_core_retransmission_c@@UAE@XZ @ 336 NONAME ; eap_core_retransmission_c::~eap_core_retransmission_c(void)
+	??1ec_cs_tlv_message_c@@UAE@XZ @ 337 NONAME ; ec_cs_tlv_message_c::~ec_cs_tlv_message_c(void)
+	?set_next_payload_with_same_tlv_type@ec_cs_variable_data_c@@QAEXPAV1@@Z @ 338 NONAME ; void ec_cs_variable_data_c::set_next_payload_with_same_tlv_type(class ec_cs_variable_data_c *)
+	?copy_tlv_data@ec_cs_tlv_payloads_c@@QAE?AW4eap_status_e@@W4ec_cs_tlv_type_e@@PBXK@Z @ 339 NONAME ; enum eap_status_e ec_cs_tlv_payloads_c::copy_tlv_data(enum ec_cs_tlv_type_e, void const *, unsigned long)
+	?configure@wapi_session_core_c@@UAE?AW4eap_status_e@@XZ @ 340 NONAME ; enum eap_status_e wapi_session_core_c::configure(void)
+	?set_copy_of_buffer@ec_cs_variable_data_c@@QAE?AW4eap_status_e@@PBXK@Z @ 341 NONAME ; enum eap_status_e ec_cs_variable_data_c::set_copy_of_buffer(void const *, unsigned long)
+	?write_configure@wapi_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 342 NONAME ; enum eap_status_e wapi_wlan_authentication_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?get_completion_action_string@ec_cs_completion_c@@SAPBDW4ec_cs_completion_e@@@Z @ 343 NONAME ; char const * ec_cs_completion_c::get_completion_action_string(enum ec_cs_completion_e)
+	?complete_create_ecdh@wapi_core_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@0@Z @ 344 NONAME ; enum eap_status_e wapi_core_c::complete_create_ecdh(class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?copy@wai_message_payloads_c@@QBEPAV1@XZ @ 345 NONAME ; class wai_message_payloads_c * wai_message_payloads_c::copy(void) const
+	?get_object_count@wapi_asn1_der_parser_c@@QBEKXZ @ 346 NONAME ; unsigned long wapi_asn1_der_parser_c::get_object_count(void) const
+	?get_data_offset@wai_variable_data_c@@QBEPAEKK@Z @ 347 NONAME ; unsigned char * wai_variable_data_c::get_data_offset(unsigned long, unsigned long) const
+	??0ec_cs_tlv_message_c@@QAE@PAVabs_eap_am_tools_c@@_N@Z @ 348 NONAME ; ec_cs_tlv_message_c::ec_cs_tlv_message_c(class abs_eap_am_tools_c *, bool)
+	?create_u16_t_tlv@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PAVec_cs_variable_data_c@@W4ec_cs_tlv_type_e@@G@Z @ 349 NONAME ; enum eap_status_e ec_cs_tlv_c::create_u16_t_tlv(class ec_cs_variable_data_c *, enum ec_cs_tlv_type_e, unsigned short)
+	?get_is_valid@wapi_am_crypto_sms4_c@@QAE_NXZ @ 350 NONAME ; bool wapi_am_crypto_sms4_c::get_is_valid(void)
+	?get_next_retransmission_counter@eap_core_retransmission_c@@QAEKXZ @ 351 NONAME ; unsigned long eap_core_retransmission_c::get_next_retransmission_counter(void)
+	?read_configure@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 352 NONAME ; enum eap_status_e ec_certificate_store_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?verify_padding@ec_cs_tlv_payloads_c@@AAE?AW4eap_status_e@@PBEK@Z @ 353 NONAME ; enum eap_status_e ec_cs_tlv_payloads_c::verify_padding(unsigned char const *, unsigned long)
+	?get_payload_type@wai_variable_data_c@@QBE?AW4wai_payload_type_e@@XZ @ 354 NONAME ; enum wai_payload_type_e wai_variable_data_c::get_payload_type(void) const
+	?get_tlv_pointer@ec_cs_tlv_payloads_c@@QBEPAVec_cs_variable_data_c@@W4ec_cs_tlv_type_e@@@Z @ 355 NONAME ; class ec_cs_variable_data_c * ec_cs_tlv_payloads_c::get_tlv_pointer(enum ec_cs_tlv_type_e) const
+	?send_error_message@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@W42@W4eapol_tlv_message_type_function_e@@@Z @ 356 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::send_error_message(enum eap_status_e, enum eapol_tlv_message_type_function_e)
+	?ecb_process_data@wapi_am_crypto_sms4_c@@AAE?AW4eap_status_e@@PBXPAXK_N@Z @ 357 NONAME ; enum eap_status_e wapi_am_crypto_sms4_c::ecb_process_data(void const *, void *, unsigned long, bool)
+	?get_is_valid@ec_certificate_store_c@@UBE_NXZ @ 358 NONAME ; bool ec_certificate_store_c::get_is_valid(void) const
+	?cancel_timer@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@K@Z @ 359 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::cancel_timer(class abs_eap_base_timer_c *, unsigned long)
+	?get_is_valid@wai_message_payloads_c@@QBE_NXZ @ 360 NONAME ; bool wai_message_payloads_c::get_is_valid(void) const
+	?decode@wapi_certificate_asn1_der_parser_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 361 NONAME ; enum eap_status_e wapi_certificate_asn1_der_parser_c::decode(class eap_variable_data_c const *)
+	?get_type_data_offset@wai_variable_data_c@@QBEPAEKK@Z @ 362 NONAME ; unsigned char * wai_variable_data_c::get_type_data_offset(unsigned long, unsigned long) const
+	?get_writable_full_tlv_buffer@wai_variable_data_c@@QAEPAVeap_variable_data_c@@XZ @ 363 NONAME ; class eap_variable_data_c * wai_variable_data_c::get_writable_full_tlv_buffer(void)
+	?shutdown@wapi_core_c@@UAE?AW4eap_status_e@@XZ @ 364 NONAME ; enum eap_status_e wapi_core_c::shutdown(void)
+	?packet_data_session_key@wapi_message_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVeapol_session_key_c@@@Z @ 365 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::packet_data_session_key(class eap_am_network_id_c const *, class eapol_session_key_c const *)
+	?cancel_wapi_failure_timeout@wapi_core_c@@AAE?AW4eap_status_e@@XZ @ 366 NONAME ; enum eap_status_e wapi_core_c::cancel_wapi_failure_timeout(void)
+	?reassociate@wapi_message_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@PBVeap_variable_data_c@@@Z @ 367 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::reassociate(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c const *)
+	?configure@ec_am_algorithms_direct_nrc_c@@UAE?AW4eap_status_e@@XZ @ 368 NONAME ; enum eap_status_e ec_am_algorithms_direct_nrc_c::configure(void)
+	?complete_read_certificate_store_data@ec_certificate_store_c@@UAE?AW4eap_status_e@@W42@W4ec_cs_pending_operation_e@@PBV?$eap_array_c@Vec_cs_data_c@@@@@Z @ 369 NONAME ; enum eap_status_e ec_certificate_store_c::complete_read_certificate_store_data(enum eap_status_e, enum ec_cs_pending_operation_e, class eap_array_c<class ec_cs_data_c> const *)
+	?set_am_partner@wapi_am_core_symbian_c@@IAEXPAVabs_wapi_am_core_c@@@Z @ 370 NONAME ; void wapi_am_core_symbian_c::set_am_partner(class abs_wapi_am_core_c *)
+	?verify_signature_with_public_key@ec_am_algorithms_direct_nrc_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 371 NONAME ; enum eap_status_e ec_am_algorithms_direct_nrc_c::verify_signature_with_public_key(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?get_wapi_negotiation_state_string@wapi_strings_c@@SAPBDW4wapi_negotiation_state_e@@@Z @ 372 NONAME ; char const * wapi_strings_c::get_wapi_negotiation_state_string(enum wapi_negotiation_state_e)
+	?complete_write_certificate_store_data@ec_certificate_store_c@@UAE?AW4eap_status_e@@W42@W4ec_cs_pending_operation_e@@@Z @ 373 NONAME ; enum eap_status_e ec_certificate_store_c::complete_write_certificate_store_data(enum eap_status_e, enum ec_cs_pending_operation_e)
+	?set_receive_network_id@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 374 NONAME ; enum eap_status_e ec_certificate_store_c::set_receive_network_id(class eap_am_network_id_c const *)
+	?file_exists@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 375 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_exists(class eap_variable_data_c const *)
+	?get_decoded_subject_name@wapi_asn1_der_parser_c@@QAE?AW4eap_status_e@@PAVeap_variable_data_c@@0@Z @ 376 NONAME ; enum eap_status_e wapi_asn1_der_parser_c::get_decoded_subject_name(class eap_variable_data_c *, class eap_variable_data_c *)
+	?get_is_valid_data@wai_variable_data_c@@QBE_NXZ @ 377 NONAME ; bool wai_variable_data_c::get_is_valid_data(void) const
+	?set_ae_certificate@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 378 NONAME ; enum eap_status_e ec_certificate_store_c::set_ae_certificate(class eap_variable_data_c const *)
+	?get_wai_protocol_subtype_string@wapi_strings_c@@SAPBDW4wai_protocol_subtype_e@@@Z @ 379 NONAME ; char const * wapi_strings_c::get_wai_protocol_subtype_string(enum wai_protocol_subtype_e)
+	?convert_to_ec_cs_tlv_type@wai_variable_data_c@@SA?AW4ec_cs_tlv_type_e@@W4wai_payload_type_e@@@Z @ 380 NONAME ; enum ec_cs_tlv_type_e wai_variable_data_c::convert_to_ec_cs_tlv_type(enum wai_payload_type_e)
+	?start_certificate_import@ec_certificate_store_c@@UAE?AW4eap_status_e@@XZ @ 381 NONAME ; enum eap_status_e ec_certificate_store_c::start_certificate_import(void)
+	??0ec_cs_compare_certificate_reference_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 382 NONAME ; ec_cs_compare_certificate_reference_c::ec_cs_compare_certificate_reference_c(class abs_eap_am_tools_c *)
+	?get_next_retransmission_time@eap_core_retransmission_c@@QAEKXZ @ 383 NONAME ; unsigned long eap_core_retransmission_c::get_next_retransmission_time(void)
+	?get_eap_type@eap_core_retransmission_c@@QBE?AVeap_expanded_type_c@@XZ @ 384 NONAME ; class eap_expanded_type_c eap_core_retransmission_c::get_eap_type(void) const
+	??1wapi_core_retransmission_c@@UAE@XZ @ 385 NONAME ; wapi_core_retransmission_c::~wapi_core_retransmission_c(void)
+	?GetAllCertificateLabelsL@CWapiCertificates@@QAEXPAPAV?$RArray@V?$TBuf@$0PP@@@@@PAPAV?$RArray@V?$TBuf8@$0BDG@@@@@01@Z @ 386 NONAME ; void CWapiCertificates::GetAllCertificateLabelsL(class RArray<class TBuf<255> > * *, class RArray<class TBuf8<310> > * *, class RArray<class TBuf<255> > * *, class RArray<class TBuf8<310> > * *)
+	?association@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 387 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::association(class eap_am_network_id_c const *)
+	?create_ecdh@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 388 NONAME ; enum eap_status_e ec_certificate_store_c::create_ecdh(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?verify_data_with_MAC@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PBVec_cs_data_c@@@Z @ 389 NONAME ; enum eap_status_e ec_cs_tlv_c::verify_data_with_MAC(class eap_variable_data_c const *, class eap_variable_data_c const *, class ec_cs_data_c const *)
+	?start_reassociation@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 390 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::start_reassociation(class eap_array_c<class eap_tlv_header_c> const *)
+	?get_wai_tlv_header@wai_variable_data_c@@QBEPBVwai_tlv_header_c@@XZ @ 391 NONAME ; class wai_tlv_header_c const * wai_variable_data_c::get_wai_tlv_header(void) const
+	??1wapi_wlan_authentication_c@@UAE@XZ @ 392 NONAME ; wapi_wlan_authentication_c::~wapi_wlan_authentication_c(void)
+	?shutdown_operation@wapi_session_core_c@@CA?AW4eap_status_e@@PAVwapi_core_c@@PAVabs_eap_am_tools_c@@@Z @ 393 NONAME ; enum eap_status_e wapi_session_core_c::shutdown_operation(class wapi_core_c *, class abs_eap_am_tools_c *)
+	?get_writable_reference@ec_cs_data_c@@QAEPAVeap_variable_data_c@@XZ @ 394 NONAME ; class eap_variable_data_c * ec_cs_data_c::get_writable_reference(void)
+	??1wapi_message_wlan_authentication_c@@UAE@XZ @ 395 NONAME ; wapi_message_wlan_authentication_c::~wapi_message_wlan_authentication_c(void)
+	?get_data_offset@ec_cs_variable_data_c@@QBEPAEKK@Z @ 396 NONAME ; unsigned char * ec_cs_variable_data_c::get_data_offset(unsigned long, unsigned long) const
+	?get_type_class@wai_variable_data_c@@QBE?AW4wai_payload_type_size_e@@XZ @ 397 NONAME ; enum wai_payload_type_size_e wai_variable_data_c::get_type_class(void) const
+	?start_authentication@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 398 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::start_authentication(class eap_array_c<class eap_tlv_header_c> const *)
+	?packet_send@wapi_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 399 NONAME ; enum eap_status_e wapi_wlan_authentication_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long)
+	?complete_create_ecdh@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@0@Z @ 400 NONAME ; enum eap_status_e ec_certificate_store_c::complete_create_ecdh(class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?get_header_offset@eap_core_retransmission_c@@QBEKXZ @ 401 NONAME ; unsigned long eap_core_retransmission_c::get_header_offset(void) const
+	?create_data_with_MAC@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@0PAV3@@Z @ 402 NONAME ; enum eap_status_e ec_cs_tlv_c::create_data_with_MAC(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c *)
+	?get_is_valid@ec_am_algorithms_direct_nrc_c@@UBE_NXZ @ 403 NONAME ; bool ec_am_algorithms_direct_nrc_c::get_is_valid(void) const
+	?convert_to_wai_payload_type@wai_variable_data_c@@SA?AW4wai_payload_type_e@@W4wai_tlv_type_e@@@Z @ 404 NONAME ; enum wai_payload_type_e wai_variable_data_c::convert_to_wai_payload_type(enum wai_tlv_type_e)
+	?parse_generic_payload@ec_cs_tlv_payloads_c@@AAE?AW4eap_status_e@@W4ec_cs_tlv_type_e@@PBVec_cs_tlv_header_c@@@Z @ 405 NONAME ; enum eap_status_e ec_cs_tlv_payloads_c::parse_generic_payload(enum ec_cs_tlv_type_e, class ec_cs_tlv_header_c const *)
+	?asynchronous_init_remove_wapi_session@wapi_session_core_c@@QAE?AW4eap_status_e@@PBVeap_network_id_selector_c@@@Z @ 406 NONAME ; enum eap_status_e wapi_session_core_c::asynchronous_init_remove_wapi_session(class eap_network_id_selector_c const *)
+	?synchronous_create_wapi_session@wapi_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 407 NONAME ; enum eap_status_e wapi_session_core_c::synchronous_create_wapi_session(class eap_am_network_id_c const *)
+	??1ec_am_algorithms_direct_nrc_c@@UAE@XZ @ 408 NONAME ; ec_am_algorithms_direct_nrc_c::~ec_am_algorithms_direct_nrc_c(void)
+	?get_is_valid@wapi_core_c@@UAE_NXZ @ 409 NONAME ; bool wapi_core_c::get_is_valid(void)
+	?new_ec_base_certificate_store_c@ec_base_certificate_store_c@@SAPAV1@PAVabs_eap_am_tools_c@@PAVabs_ec_certificate_store_c@@PAVec_am_base_certificate_store_c@@_N@Z @ 410 NONAME ; class ec_base_certificate_store_c * ec_base_certificate_store_c::new_ec_base_certificate_store_c(class abs_eap_am_tools_c *, class abs_ec_certificate_store_c *, class ec_am_base_certificate_store_c *, bool)
+	?reset@ec_cs_tlv_payloads_c@@QAE?AW4eap_status_e@@XZ @ 411 NONAME ; enum eap_status_e ec_cs_tlv_payloads_c::reset(void)
+	?compare@ec_cs_compare_reference_c@@UBEJPBVec_cs_data_c@@0@Z @ 412 NONAME ; long ec_cs_compare_reference_c::compare(class ec_cs_data_c const *, class ec_cs_data_c const *) const
+	?create@wai_variable_data_c@@QAE?AW4eap_status_e@@W4wai_payload_type_e@@PBXK@Z @ 413 NONAME ; enum eap_status_e wai_variable_data_c::create(enum wai_payload_type_e, void const *, unsigned long)
+	?reset_cached_bksa@wapi_core_c@@QAE?AW4eap_status_e@@XZ @ 414 NONAME ; enum eap_status_e wapi_core_c::reset_cached_bksa(void)
+	?shutdown@wapi_message_wlan_authentication_c@@QAE?AW4eap_status_e@@XZ @ 415 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::shutdown(void)
+	?get_sub_type@asn1_der_type_c@@QBEPBV1@PBVasn1_type_const_c@@@Z @ 416 NONAME ; class asn1_der_type_c const * asn1_der_type_c::get_sub_type(class asn1_type_const_c const *) const
+	?timer_expired@wapi_core_c@@UAE?AW4eap_status_e@@KPAX@Z @ 417 NONAME ; enum eap_status_e wapi_core_c::timer_expired(unsigned long, void *)
+	?get_is_valid_data@ec_cs_variable_data_c@@QBE_NXZ @ 418 NONAME ; bool ec_cs_variable_data_c::get_is_valid_data(void) const
+	?get_data_references_read@ec_cs_data_c@@QAE_NXZ @ 419 NONAME ; bool ec_cs_data_c::get_data_references_read(void)
+	?get_retransmission_counter@eap_core_retransmission_c@@QBEKXZ @ 420 NONAME ; unsigned long eap_core_retransmission_c::get_retransmission_counter(void) const
+	?complete_get_own_certificate@wapi_core_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 421 NONAME ; enum eap_status_e wapi_core_c::complete_get_own_certificate(class eap_variable_data_c const *)
+	?disassociate@wapi_message_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N@Z @ 422 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::disassociate(class eap_am_network_id_c const *, bool)
+	?query_asu_id@ec_certificate_store_c@@UAE?AW4eap_status_e@@XZ @ 423 NONAME ; enum eap_status_e ec_certificate_store_c::query_asu_id(void)
+	?add_data@ec_cs_variable_data_c@@QAE?AW4eap_status_e@@PBXK@Z @ 424 NONAME ; enum eap_status_e ec_cs_variable_data_c::add_data(void const *, unsigned long)
+	?read_reassociation_parameters@wapi_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@0W4eapol_key_authentication_type_e@@PAVeap_variable_data_c@@PBV5@3@Z @ 425 NONAME ; enum eap_status_e wapi_session_core_c::read_reassociation_parameters(class eap_am_network_id_c const *, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?get_block_size@wapi_am_crypto_sms4_c@@QAEKXZ @ 426 NONAME ; unsigned long wapi_am_crypto_sms4_c::get_block_size(void)
+	?get_buffer_size@eap_core_retransmission_c@@QBEKXZ @ 427 NONAME ; unsigned long eap_core_retransmission_c::get_buffer_size(void) const
+	?set_copy_of_buffer@ec_cs_variable_data_c@@QAE?AW4eap_status_e@@W4ec_cs_tlv_type_e@@PBXK@Z @ 428 NONAME ; enum eap_status_e ec_cs_variable_data_c::set_copy_of_buffer(enum ec_cs_tlv_type_e, void const *, unsigned long)
+	??0wapi_core_c@@QAE@PAVabs_eap_am_tools_c@@PAVabs_wapi_core_c@@_NPBVeap_am_network_id_c@@@Z @ 429 NONAME ; wapi_core_c::wapi_core_c(class abs_eap_am_tools_c *, class abs_wapi_core_c *, bool, class eap_am_network_id_c const *)
+	?get_is_valid@ec_cs_tlv_message_c@@QAE_NXZ @ 430 NONAME ; bool ec_cs_tlv_message_c::get_is_valid(void)
+	?get_wapi_core_state_string@wapi_strings_c@@SAPBDW4wapi_core_state_e@@@Z @ 431 NONAME ; char const * wapi_strings_c::get_wapi_core_state_string(enum wapi_core_state_e)
+	?set_timer@wapi_wlan_authentication_c@@UAE?AW4eap_status_e@@PAVabs_eap_base_timer_c@@KPAXK@Z @ 432 NONAME ; enum eap_status_e wapi_wlan_authentication_c::set_timer(class abs_eap_base_timer_c *, unsigned long, void *, unsigned long)
+	?authentication_finished@wapi_am_core_symbian_c@@MAE?AW4eap_status_e@@_N@Z @ 433 NONAME ; enum eap_status_e wapi_am_core_symbian_c::authentication_finished(bool)
+	?get_am_partner@wapi_am_core_symbian_c@@IAEPAVabs_wapi_am_core_c@@XZ @ 434 NONAME ; class abs_wapi_am_core_c * wapi_am_core_symbian_c::get_am_partner(void)
+	?parse_cs_tlv@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PBVec_cs_variable_data_c@@@Z @ 435 NONAME ; enum eap_status_e ec_cs_tlv_c::parse_cs_tlv(class ec_cs_variable_data_c const *)
+	?shutdown@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@XZ @ 436 NONAME ; enum eap_status_e wapi_ethernet_core_c::shutdown(void)
+	?get_is_valid@wapi_session_core_c@@UAE_NXZ @ 437 NONAME ; bool wapi_session_core_c::get_is_valid(void)
+	?check_payloads_existense@ec_cs_tlv_payloads_c@@QBE?AW4eap_status_e@@PBW4ec_cs_tlv_type_e@@K@Z @ 438 NONAME ; enum eap_status_e ec_cs_tlv_payloads_c::check_payloads_existense(enum ec_cs_tlv_type_e const *, unsigned long) const
+	?check_bksa_cache@wapi_session_core_c@@QAE?AW4eap_status_e@@PAV?$eap_array_c@Veap_am_network_id_c@@@@W4eapol_key_authentication_type_e@@W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@2@Z @ 439 NONAME ; enum eap_status_e wapi_session_core_c::check_bksa_cache(class eap_array_c<class eap_am_network_id_c> *, enum eapol_key_authentication_type_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e)
+	?get_is_valid@wapi_asn1_der_parser_c@@QBE_NXZ @ 440 NONAME ; bool wapi_asn1_der_parser_c::get_is_valid(void) const
+	?set_session_timeout@wapi_core_c@@UAE?AW4eap_status_e@@K@Z @ 441 NONAME ; enum eap_status_e wapi_core_c::set_session_timeout(unsigned long)
+	?get_is_valid@wapi_core_retransmission_c@@QBE_NXZ @ 442 NONAME ; bool wapi_core_retransmission_c::get_is_valid(void) const
+	?create_new_session@wapi_session_core_c@@AAEPAVwapi_core_c@@PBVeap_am_network_id_c@@@Z @ 443 NONAME ; class wapi_core_c * wapi_session_core_c::create_new_session(class eap_am_network_id_c const *)
+	?completion_action_trace@ec_certificate_store_c@@AAEXXZ @ 444 NONAME ; void ec_certificate_store_c::completion_action_trace(void)
+	?state_notification@wapi_am_wlan_authentication_symbian_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 445 NONAME ; void wapi_am_wlan_authentication_symbian_c::state_notification(class abs_eap_state_notification_c const *)
+	?authentication_finished@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@_NW4eapol_key_authentication_type_e@@@Z @ 446 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::authentication_finished(bool, enum eapol_key_authentication_type_e)
+	?increase_count_of_sub_types@asn1_der_type_c@@QAEXXZ @ 447 NONAME ; void asn1_der_type_c::increase_count_of_sub_types(void)
+	?get_tlv_count@ec_cs_tlv_payloads_c@@QBEKXZ @ 448 NONAME ; unsigned long ec_cs_tlv_payloads_c::get_tlv_count(void) const
+	?get_eap_code@eap_core_retransmission_c@@QBE?AW4eap_code_value_e@@XZ @ 449 NONAME ; enum eap_code_value_e eap_core_retransmission_c::get_eap_code(void) const
+	?compare_issuer_name_of_id_and_certificate@ec_certificate_store_c@@AAE?AW4eap_status_e@@PBVeap_variable_data_c@@0@Z @ 450 NONAME ; enum eap_status_e ec_certificate_store_c::compare_issuer_name_of_id_and_certificate(class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?file_close@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@XZ @ 451 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_close(void)
+	??1wapi_session_core_c@@UAE@XZ @ 452 NONAME ; wapi_session_core_c::~wapi_session_core_c(void)
+	?create_state@wapi_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@@Z @ 453 NONAME ; enum eap_status_e wapi_session_core_c::create_state(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e)
+	?get_tlv_pointer@ec_cs_tlv_payloads_c@@QBEPAVec_cs_variable_data_c@@W4ec_cs_tlv_type_e@@K@Z @ 454 NONAME ; class ec_cs_variable_data_c * ec_cs_tlv_payloads_c::get_tlv_pointer(enum ec_cs_tlv_type_e, unsigned long) const
+	?associate@wapi_message_wlan_authentication_c@@UAE?AW4eap_status_e@@W4eapol_key_802_11_authentication_mode_e@@@Z @ 455 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::associate(enum eapol_key_802_11_authentication_mode_e)
+	?create_generic_tlv@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PAVec_cs_variable_data_c@@W4ec_cs_tlv_type_e@@PBVeap_variable_data_c@@@Z @ 456 NONAME ; enum eap_status_e ec_cs_tlv_c::create_generic_tlv(class ec_cs_variable_data_c *, enum ec_cs_tlv_type_e, class eap_variable_data_c const *)
+	?initialize@wapi_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@W4eapol_key_authentication_type_e@@@Z @ 457 NONAME ; enum eap_status_e wapi_core_c::initialize(class eap_am_network_id_c const *, enum eapol_key_authentication_type_e)
+	?packet_process@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_general_header_base_c@@K@Z @ 458 NONAME ; enum eap_status_e wapi_ethernet_core_c::packet_process(class eap_am_network_id_c const *, class eap_general_header_base_c *, unsigned long)
+	?copy@ec_cs_data_c@@QBEPAV1@XZ @ 459 NONAME ; class ec_cs_data_c * ec_cs_data_c::copy(void) const
+	?read_configure@wapi_am_core_symbian_c@@IAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 460 NONAME ; enum eap_status_e wapi_am_core_symbian_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?complete_create_ecdh_temporary_keys@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@00@Z @ 461 NONAME ; enum eap_status_e ec_certificate_store_c::complete_create_ecdh_temporary_keys(class eap_variable_data_c const *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?write_configure@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 462 NONAME ; enum eap_status_e wapi_ethernet_core_c::write_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?state_notification@wapi_am_core_symbian_c@@IAEXPBVabs_eap_state_notification_c@@@Z @ 463 NONAME ; void wapi_am_core_symbian_c::state_notification(class abs_eap_state_notification_c const *)
+	?process_data@wapi_message_wlan_authentication_c@@QAE?AW4wlan_eap_if_send_status_e@@PBXK@Z @ 464 NONAME ; enum wlan_eap_if_send_status_e wapi_message_wlan_authentication_c::process_data(void const *, unsigned long)
+	?state_notification@wapi_core_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 465 NONAME ; void wapi_core_c::state_notification(class abs_eap_state_notification_c const *)
+	?ecb_decrypt@wapi_am_crypto_sms4_c@@QAE?AW4eap_status_e@@PBXPAXK@Z @ 466 NONAME ; enum eap_status_e wapi_am_crypto_sms4_c::ecb_decrypt(void const *, void *, unsigned long)
+	?L_key@wapi_am_crypto_sms4_c@@AAEXPAK@Z @ 467 NONAME ; void wapi_am_crypto_sms4_c::L_key(unsigned long *)
+	??1asn1_der_type_c@@UAE@XZ @ 468 NONAME ; asn1_der_type_c::~asn1_der_type_c(void)
+	??0asn1_der_type_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 469 NONAME ; asn1_der_type_c::asn1_der_type_c(class abs_eap_am_tools_c *)
+	?get_data@wai_variable_data_c@@QBEPAEK@Z @ 470 NONAME ; unsigned char * wai_variable_data_c::get_data(unsigned long) const
+	?get_wai_protocol_packet_header_writable@wai_message_payloads_c@@QAEPAVwai_protocol_packet_header_c@@XZ @ 471 NONAME ; class wai_protocol_packet_header_c * wai_message_payloads_c::get_wai_protocol_packet_header_writable(void)
+	?type_configure_write@wapi_am_core_symbian_c@@MAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 472 NONAME ; enum eap_status_e wapi_am_core_symbian_c::type_configure_write(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?add_data@wai_variable_data_c@@QAE?AW4eap_status_e@@W4wai_payload_type_e@@PBVeap_variable_data_c@@@Z @ 473 NONAME ; enum eap_status_e wai_variable_data_c::add_data(enum wai_payload_type_e, class eap_variable_data_c const *)
+	??0wapi_am_wlan_authentication_symbian_c@@QAE@PAVabs_eap_am_tools_c@@_NPBVabs_eapol_wlan_database_reference_if_c@@@Z @ 474 NONAME ; wapi_am_wlan_authentication_symbian_c::wapi_am_wlan_authentication_symbian_c(class abs_eap_am_tools_c *, bool, class abs_eapol_wlan_database_reference_if_c const *)
+	??1wapi_am_wlan_authentication_symbian_c@@UAE@XZ @ 475 NONAME ; wapi_am_wlan_authentication_symbian_c::~wapi_am_wlan_authentication_symbian_c(void)
+	?set_session_timeout@wapi_session_core_c@@UAE?AW4eap_status_e@@K@Z @ 476 NONAME ; enum eap_status_e wapi_session_core_c::set_session_timeout(unsigned long)
+	??0wapi_certificate_asn1_der_parser_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 477 NONAME ; wapi_certificate_asn1_der_parser_c::wapi_certificate_asn1_der_parser_c(class abs_eap_am_tools_c *)
+	??1ec_am_base_algorithms_c@@UAE@XZ @ 478 NONAME ; ec_am_base_algorithms_c::~ec_am_base_algorithms_c(void)
+	?get_next_type@asn1_der_type_c@@QBEPBV1@XZ @ 479 NONAME ; class asn1_der_type_c const * asn1_der_type_c::get_next_type(void) const
+	??0wai_message_c@@QAE@PAVabs_eap_am_tools_c@@_N@Z @ 480 NONAME ; wai_message_c::wai_message_c(class abs_eap_am_tools_c *, bool)
+	?shutdown@wapi_session_core_c@@UAE?AW4eap_status_e@@XZ @ 481 NONAME ; enum eap_status_e wapi_session_core_c::shutdown(void)
+	?compare@ec_cs_compare_certificate_issuer_name_c@@UBEJPBVec_cs_data_c@@0@Z @ 482 NONAME ; long ec_cs_compare_certificate_issuer_name_c::compare(class ec_cs_data_c const *, class ec_cs_data_c const *) const
+	?get_content_length@asn1_der_type_c@@QBEKXZ @ 483 NONAME ; unsigned long asn1_der_type_c::get_content_length(void) const
+	?remove_bksa_from_cache@wapi_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 484 NONAME ; enum eap_status_e wapi_session_core_c::remove_bksa_from_cache(class eap_am_network_id_c const *)
+	?allow_authentication@wapi_core_c@@QAE?AW4eap_status_e@@XZ @ 485 NONAME ; enum eap_status_e wapi_core_c::allow_authentication(void)
+	?object_increase_reference_count@wapi_core_c@@QAEXXZ @ 486 NONAME ; void wapi_core_c::object_increase_reference_count(void)
+	?state_notification@wapi_wlan_authentication_c@@UAEXPBVabs_eap_state_notification_c@@@Z @ 487 NONAME ; void wapi_wlan_authentication_c::state_notification(class abs_eap_state_notification_c const *)
+	?get_wai_protocol_type_string@wapi_strings_c@@SAPBDW4wai_protocol_type_e@@@Z @ 488 NONAME ; char const * wapi_strings_c::get_wai_protocol_type_string(enum wai_protocol_type_e)
+	??1wapi_core_c@@UAE@XZ @ 489 NONAME ; wapi_core_c::~wapi_core_c(void)
+	??0ec_cs_variable_data_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 490 NONAME ; ec_cs_variable_data_c::ec_cs_variable_data_c(class abs_eap_am_tools_c *)
+	?read_id_of_certificate@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 491 NONAME ; enum eap_status_e ec_certificate_store_c::read_id_of_certificate(class eap_variable_data_c const *)
+	?get_wai_payload_type_string@wai_variable_data_c@@QBEPBDXZ @ 492 NONAME ; char const * wai_variable_data_c::get_wai_payload_type_string(void) const
+	?add_tlv@wai_message_payloads_c@@QAE?AW4eap_status_e@@PAVwai_variable_data_c@@@Z @ 493 NONAME ; enum eap_status_e wai_message_payloads_c::add_tlv(class wai_variable_data_c *)
+	?configure@wapi_message_wlan_authentication_c@@QAE?AW4eap_status_e@@KKK@Z @ 494 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::configure(unsigned long, unsigned long, unsigned long)
+	??0ec_cs_completion_c@@QAE@PAVabs_eap_am_tools_c@@W4ec_cs_completion_e@@@Z @ 495 NONAME ; ec_cs_completion_c::ec_cs_completion_c(class abs_eap_am_tools_c *, enum ec_cs_completion_e)
+	?cancel_all_timers@wapi_core_c@@QAE?AW4eap_status_e@@XZ @ 496 NONAME ; enum eap_status_e wapi_core_c::cancel_all_timers(void)
+	?check_bksa_cache@wapi_core_c@@QAE?AW4eap_status_e@@W4eapol_key_authentication_type_e@@W4eapol_RSNA_cipher_e@eapol_RSNA_key_header_c@@1@Z @ 497 NONAME ; enum eap_status_e wapi_core_c::check_bksa_cache(enum eapol_key_authentication_type_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e, enum eapol_RSNA_key_header_c::eapol_RSNA_cipher_e)
+	?complete_create_signature_with_private_key@wapi_core_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@W42@@Z @ 498 NONAME ; enum eap_status_e wapi_core_c::complete_create_signature_with_private_key(class eap_variable_data_c const *, enum eap_status_e)
+	?read_certificate_store_data@wapi_am_core_symbian_c@@MAE?AW4eap_status_e@@W4ec_cs_pending_operation_e@@PBV?$eap_array_c@Vec_cs_data_c@@@@@Z @ 499 NONAME ; enum eap_status_e wapi_am_core_symbian_c::read_certificate_store_data(enum ec_cs_pending_operation_e, class eap_array_c<class ec_cs_data_c> const *)
+	?get_next_payload_with_same_tlv_type@ec_cs_variable_data_c@@QBEPAV1@XZ @ 500 NONAME ; class ec_cs_variable_data_c * ec_cs_variable_data_c::get_next_payload_with_same_tlv_type(void) const
+	??0ec_cs_compare_reference_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 501 NONAME ; ec_cs_compare_reference_c::ec_cs_compare_reference_c(class abs_eap_am_tools_c *)
+	??1wapi_certificate_asn1_der_parser_c@@UAE@XZ @ 502 NONAME ; wapi_certificate_asn1_der_parser_c::~wapi_certificate_asn1_der_parser_c(void)
+	?get_is_valid@ec_cs_variable_data_c@@QBE_NXZ @ 503 NONAME ; bool ec_cs_variable_data_c::get_is_valid(void) const
+	?copy_tlv@ec_cs_tlv_payloads_c@@QAE?AW4eap_status_e@@PBV1@W4ec_cs_tlv_type_e@@@Z @ 504 NONAME ; enum eap_status_e ec_cs_tlv_payloads_c::copy_tlv(class ec_cs_tlv_payloads_c const *, enum ec_cs_tlv_type_e)
+	?get_wai_protocol_version_string@wapi_strings_c@@SAPBDW4wai_protocol_version_e@@@Z @ 505 NONAME ; char const * wapi_strings_c::get_wai_protocol_version_string(enum wai_protocol_version_e)
+	?set_type@ec_cs_data_c@@QAEXW4ec_cs_data_type_e@@@Z @ 506 NONAME ; void ec_cs_data_c::set_type(enum ec_cs_data_type_e)
+	?get_is_valid@wapi_wlan_authentication_c@@QAE_NXZ @ 507 NONAME ; bool wapi_wlan_authentication_c::get_is_valid(void)
+	?cancel_certificate_store_store_operations@wapi_am_core_symbian_c@@MAE?AW4eap_status_e@@XZ @ 508 NONAME ; enum eap_status_e wapi_am_core_symbian_c::cancel_certificate_store_store_operations(void)
+	?get_completion_action@ec_cs_completion_c@@QBE?AW4ec_cs_completion_e@@XZ @ 509 NONAME ; enum ec_cs_completion_e ec_cs_completion_c::get_completion_action(void) const
+	?complete_add_imported_certificate_file@wapi_am_core_symbian_c@@MAE?AW4eap_status_e@@W42@PBVeap_variable_data_c@@@Z @ 510 NONAME ; enum eap_status_e wapi_am_core_symbian_c::complete_add_imported_certificate_file(enum eap_status_e, class eap_variable_data_c const *)
+	?get_wai_message_data@wapi_core_retransmission_c@@QBEPBVwai_message_c@@XZ @ 511 NONAME ; class wai_message_c const * wapi_core_retransmission_c::get_wai_message_data(void) const
+	?get_wai_received_message_data@wapi_core_retransmission_c@@QBEPBVwai_message_c@@XZ @ 512 NONAME ; class wai_message_c const * wapi_core_retransmission_c::get_wai_received_message_data(void) const
+	?copy@wai_variable_data_c@@QBEPAV1@XZ @ 513 NONAME ; class wai_variable_data_c * wai_variable_data_c::copy(void) const
+	?compare@ec_cs_variable_data_c@@QBEJPBV1@@Z @ 514 NONAME ; long ec_cs_variable_data_c::compare(class ec_cs_variable_data_c const *) const
+	?get_eap_identifier@eap_core_retransmission_c@@QBEEXZ @ 515 NONAME ; unsigned char eap_core_retransmission_c::get_eap_identifier(void) const
+	?restart_authentication@wapi_session_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N11@Z @ 516 NONAME ; enum eap_status_e wapi_session_core_c::restart_authentication(class eap_am_network_id_c const *, bool, bool, bool)
+	?get_type@ec_cs_variable_data_c@@QBE?AW4ec_cs_tlv_type_e@@XZ @ 517 NONAME ; enum ec_cs_tlv_type_e ec_cs_variable_data_c::get_type(void) const
+	?get_tlv_pointer@wai_message_payloads_c@@QBEPAVwai_variable_data_c@@W4wai_payload_type_e@@K@Z @ 518 NONAME ; class wai_variable_data_c * wai_message_payloads_c::get_tlv_pointer(enum wai_payload_type_e, unsigned long) const
+	??1wapi_am_crypto_sms4_c@@UAE@XZ @ 519 NONAME ; wapi_am_crypto_sms4_c::~wapi_am_crypto_sms4_c(void)
+	?get_header_length@asn1_der_type_c@@QBEKXZ @ 520 NONAME ; unsigned long asn1_der_type_c::get_header_length(void) const
+	??1ec_cs_compare_reference_c@@UAE@XZ @ 521 NONAME ; ec_cs_compare_reference_c::~ec_cs_compare_reference_c(void)
+	?disassociation@wapi_message_wlan_authentication_c@@AAE?AW4eap_status_e@@PBV?$eap_array_c@Veap_tlv_header_c@@@@@Z @ 522 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::disassociation(class eap_array_c<class eap_tlv_header_c> const *)
+	?get_next_payload_with_same_tlv_type@wai_variable_data_c@@QBEPAV1@XZ @ 523 NONAME ; class wai_variable_data_c * wai_variable_data_c::get_next_payload_with_same_tlv_type(void) const
+	?create_signature_with_private_key@ec_certificate_store_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@0@Z @ 524 NONAME ; enum eap_status_e ec_certificate_store_c::create_signature_with_private_key(class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?set_buffer@wai_variable_data_c@@QAE?AW4eap_status_e@@W4wai_payload_type_e@@PBXK@Z @ 525 NONAME ; enum eap_status_e wai_variable_data_c::set_buffer(enum wai_payload_type_e, void const *, unsigned long)
+	?sms4_substitute@wapi_am_crypto_sms4_c@@AAEXPAK@Z @ 526 NONAME ; void wapi_am_crypto_sms4_c::sms4_substitute(unsigned long *)
+	?copy@ec_cs_variable_data_c@@QBEPAV1@XZ @ 527 NONAME ; class ec_cs_variable_data_c * ec_cs_variable_data_c::copy(void) const
+	?get_type@ec_cs_data_c@@QBE?AW4ec_cs_data_type_e@@XZ @ 528 NONAME ; enum ec_cs_data_type_e ec_cs_data_c::get_type(void) const
+	?configure@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@XZ @ 529 NONAME ; enum eap_status_e wapi_ethernet_core_c::configure(void)
+	?file_size@eap_am_file_input_symbian_c@@UAEKXZ @ 530 NONAME ; unsigned long eap_am_file_input_symbian_c::file_size(void)
+	?decode@wapi_asn1_der_parser_c@@QAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 531 NONAME ; enum eap_status_e wapi_asn1_der_parser_c::decode(class eap_variable_data_c const *)
+	??0wapi_asn1_der_parser_c@@QAE@PAVabs_eap_am_tools_c@@@Z @ 532 NONAME ; wapi_asn1_der_parser_c::wapi_asn1_der_parser_c(class abs_eap_am_tools_c *)
+	??1ec_certificate_store_c@@UAE@XZ @ 533 NONAME ; ec_certificate_store_c::~ec_certificate_store_c(void)
+	?disassociation@wapi_ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 534 NONAME ; enum eap_status_e wapi_ethernet_core_c::disassociation(class eap_am_network_id_c const *)
+	?get_marked_removed@wapi_core_c@@QAE_NXZ @ 535 NONAME ; bool wapi_core_c::get_marked_removed(void)
+	?get_is_valid@eap_am_file_input_symbian_c@@UAE_NXZ @ 536 NONAME ; bool eap_am_file_input_symbian_c::get_is_valid(void)
+	?initialize_certificate_store@ec_certificate_store_c@@UAE?AW4eap_status_e@@XZ @ 537 NONAME ; enum eap_status_e ec_certificate_store_c::initialize_certificate_store(void)
+	?cancel_authentication_session@wapi_session_core_c@@CA?AW4eap_status_e@@PAVwapi_core_c@@PAVabs_eap_am_tools_c@@@Z @ 538 NONAME ; enum eap_status_e wapi_session_core_c::cancel_authentication_session(class wapi_core_c *, class abs_eap_am_tools_c *)
+	?remove_bksa_from_cache@wapi_ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 539 NONAME ; enum eap_status_e wapi_ethernet_core_c::remove_bksa_from_cache(class eap_am_network_id_c const *)
+	?insert_payload@wai_message_payloads_c@@QAE?AW4eap_status_e@@PBVwai_variable_data_c@@@Z @ 540 NONAME ; enum eap_status_e wai_message_payloads_c::insert_payload(class wai_variable_data_c const *)
+	?get_partner@wapi_core_c@@QAEPAVabs_wapi_core_c@@XZ @ 541 NONAME ; class abs_wapi_core_c * wapi_core_c::get_partner(void)
+	?start_authentication@wapi_core_c@@QAE?AW4eap_status_e@@XZ @ 542 NONAME ; enum eap_status_e wapi_core_c::start_authentication(void)
+	?file_write@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@@Z @ 543 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_write(class eap_variable_data_c const *)
+	?copy@ec_cs_tlv_payloads_c@@QBEPAV1@XZ @ 544 NONAME ; class ec_cs_tlv_payloads_c * ec_cs_tlv_payloads_c::copy(void) const
+	?configure@wapi_wlan_authentication_c@@QAE?AW4eap_status_e@@XZ @ 545 NONAME ; enum eap_status_e wapi_wlan_authentication_c::configure(void)
+	?get_is_valid_data@ec_cs_data_c@@QBE_NXZ @ 546 NONAME ; bool ec_cs_data_c::get_is_valid_data(void) const
+	?start_authentication@wapi_ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N@Z @ 547 NONAME ; enum eap_status_e wapi_ethernet_core_c::start_authentication(class eap_am_network_id_c const *, bool)
+	?get_count_of_sub_types@asn1_der_type_c@@QBEGXZ @ 548 NONAME ; unsigned short asn1_der_type_c::get_count_of_sub_types(void) const
+	?read_reassociation_parameters@wapi_ethernet_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@0W4eapol_key_authentication_type_e@@PAVeap_variable_data_c@@PBV5@3@Z @ 549 NONAME ; enum eap_status_e wapi_ethernet_core_c::read_reassociation_parameters(class eap_am_network_id_c const *, class eap_am_network_id_c const *, enum eapol_key_authentication_type_e, class eap_variable_data_c *, class eap_variable_data_c const *, class eap_variable_data_c const *)
+	?set_copy_of_buffer@ec_cs_data_c@@QAE?AW4eap_status_e@@PBV1@@Z @ 550 NONAME ; enum eap_status_e ec_cs_data_c::set_copy_of_buffer(class ec_cs_data_c const *)
+	?set_is_valid@ec_cs_completion_c@@AAEXXZ @ 551 NONAME ; void ec_cs_completion_c::set_is_valid(void)
+	?set_copy_of_buffer@wai_variable_data_c@@QAE?AW4eap_status_e@@W4wai_payload_type_e@@PBVeap_variable_data_c@@@Z @ 552 NONAME ; enum eap_status_e wai_variable_data_c::set_copy_of_buffer(enum wai_payload_type_e, class eap_variable_data_c const *)
+	?create_ecdh_temporary_keys@ec_certificate_store_c@@UAE?AW4eap_status_e@@XZ @ 553 NONAME ; enum eap_status_e ec_certificate_store_c::create_ecdh_temporary_keys(void)
+	?packet_send@wapi_message_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PAVeap_buf_chain_wr_c@@KKK@Z @ 554 NONAME ; enum eap_status_e wapi_message_wlan_authentication_c::packet_send(class eap_am_network_id_c const *, class eap_buf_chain_wr_c *, unsigned long, unsigned long, unsigned long)
+	?restart_authentication@wapi_ethernet_core_c@@UAE?AW4eap_status_e@@PBVeap_am_network_id_c@@_N11@Z @ 555 NONAME ; enum eap_status_e wapi_ethernet_core_c::restart_authentication(class eap_am_network_id_c const *, bool, bool, bool)
+	?get_wapi_identity@wapi_asn1_der_parser_c@@QAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 556 NONAME ; enum eap_status_e wapi_asn1_der_parser_c::get_wapi_identity(class eap_variable_data_c *)
+	?shutdown@wapi_am_wlan_authentication_symbian_c@@UAE?AW4eap_status_e@@XZ @ 557 NONAME ; enum eap_status_e wapi_am_wlan_authentication_symbian_c::shutdown(void)
+	?unset_marked_removed@wapi_core_c@@QAEXXZ @ 558 NONAME ; void wapi_core_c::unset_marked_removed(void)
+	?get_tlv@ec_cs_tlv_payloads_c@@QBEPAVec_cs_variable_data_c@@K@Z @ 559 NONAME ; class ec_cs_variable_data_c * ec_cs_tlv_payloads_c::get_tlv(unsigned long) const
+	?read_certificate_id@wapi_certificate_asn1_der_parser_c@@QAE?AW4eap_status_e@@PAVeap_variable_data_c@@@Z @ 560 NONAME ; enum eap_status_e wapi_certificate_asn1_der_parser_c::read_certificate_id(class eap_variable_data_c *)
+	?get_is_valid@wapi_ethernet_core_c@@UAE_NXZ @ 561 NONAME ; bool wapi_ethernet_core_c::get_is_valid(void)
+	?file_open@eap_am_file_input_symbian_c@@UAE?AW4eap_status_e@@PBVeap_variable_data_c@@W4eap_file_io_direction_e@@@Z @ 562 NONAME ; enum eap_status_e eap_am_file_input_symbian_c::file_open(class eap_variable_data_c const *, enum eap_file_io_direction_e)
+	?get_is_valid@wapi_message_wlan_authentication_c@@QAE_NXZ @ 563 NONAME ; bool wapi_message_wlan_authentication_c::get_is_valid(void)
+	?get_object@wapi_asn1_der_parser_c@@QBEPBVasn1_der_type_c@@K@Z @ 564 NONAME ; class asn1_der_type_c const * wapi_asn1_der_parser_c::get_object(unsigned long) const
+	?get_is_valid@wai_message_c@@QBE_NXZ @ 565 NONAME ; bool wai_message_c::get_is_valid(void) const
+	?synchronous_remove_wapi_session@wapi_session_core_c@@QAE?AW4eap_status_e@@PBVeap_am_network_id_c@@@Z @ 566 NONAME ; enum eap_status_e wapi_session_core_c::synchronous_remove_wapi_session(class eap_am_network_id_c const *)
+	?configure@ec_certificate_store_c@@UAE?AW4eap_status_e@@XZ @ 567 NONAME ; enum eap_status_e ec_certificate_store_c::configure(void)
+	??1abs_ec_am_algorithms_c@@UAE@XZ @ 568 NONAME ; abs_ec_am_algorithms_c::~abs_ec_am_algorithms_c(void)
+	?new_wapi_am_wlan_authentication@wapi_am_wlan_authentication_c@@SAPAV1@PAVabs_eap_am_tools_c@@_NPBVabs_eapol_wlan_database_reference_if_c@@@Z @ 569 NONAME ; class wapi_am_wlan_authentication_c * wapi_am_wlan_authentication_c::new_wapi_am_wlan_authentication(class abs_eap_am_tools_c *, bool, class abs_eapol_wlan_database_reference_if_c const *)
+	?read_configure@wapi_wlan_authentication_c@@UAE?AW4eap_status_e@@PBVeap_configuration_field_c@@PAVeap_variable_data_c@@@Z @ 570 NONAME ; enum eap_status_e wapi_wlan_authentication_c::read_configure(class eap_configuration_field_c const *, class eap_variable_data_c *)
+	?resend_packet@wapi_core_c@@AAE?AW4eap_status_e@@PBVeap_am_network_id_c@@PBVwai_message_c@@KG@Z @ 571 NONAME ; enum eap_status_e wapi_core_c::resend_packet(class eap_am_network_id_c const *, class wai_message_c const *, unsigned long, unsigned short)
+	?set_partner@wapi_core_c@@QAEXPAVabs_wapi_core_c@@@Z @ 572 NONAME ; void wapi_core_c::set_partner(class abs_wapi_core_c *)
+	?SetUserCertL@CWapiCertificates@@QAEXHV?$TBuf8@$0BDG@@@@Z @ 573 NONAME ; void CWapiCertificates::SetUserCertL(int, class TBuf8<310>)
+	?read_u32_t_tlv@ec_cs_tlv_c@@QAE?AW4eap_status_e@@PBVec_cs_variable_data_c@@W4ec_cs_tlv_type_e@@PAK@Z @ 574 NONAME ; enum eap_status_e ec_cs_tlv_c::read_u32_t_tlv(class ec_cs_variable_data_c const *, enum ec_cs_tlv_type_e, unsigned long *)
+	?add_padding@ec_cs_tlv_message_c@@QAE?AW4eap_status_e@@K@Z @ 575 NONAME ; enum eap_status_e ec_cs_tlv_message_c::add_padding(unsigned long)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/eabi/wapiu.def	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,867 @@
+EXPORTS
+	_ZN11ec_cs_tlv_c10create_MACEP19eap_variable_data_cPKS0_S3_ @ 1 NONAME
+	_ZN11ec_cs_tlv_c10create_tlvEP21ec_cs_variable_data_c16ec_cs_tlv_type_ePK19eap_variable_data_c @ 2 NONAME
+	_ZN11ec_cs_tlv_c12get_is_validEv @ 3 NONAME
+	_ZN11ec_cs_tlv_c12parse_cs_tlvEPK21ec_cs_variable_data_c @ 4 NONAME
+	_ZN11ec_cs_tlv_c14read_u16_t_tlvEPK21ec_cs_variable_data_c16ec_cs_tlv_type_ePt @ 5 NONAME
+	_ZN11ec_cs_tlv_c14read_u32_t_tlvEPK21ec_cs_variable_data_c16ec_cs_tlv_type_ePm @ 6 NONAME
+	_ZN11ec_cs_tlv_c16create_u16_t_tlvEP21ec_cs_variable_data_c16ec_cs_tlv_type_et @ 7 NONAME
+	_ZN11ec_cs_tlv_c16create_u32_t_tlvEP21ec_cs_variable_data_c16ec_cs_tlv_type_em @ 8 NONAME
+	_ZN11ec_cs_tlv_c16read_generic_tlvEPK21ec_cs_variable_data_c16ec_cs_tlv_type_eP19eap_variable_data_c @ 9 NONAME
+	_ZN11ec_cs_tlv_c17generate_data_keyEb17ec_cs_data_type_eP19eap_variable_data_cPKS1_S4_S4_ @ 10 NONAME
+	_ZN11ec_cs_tlv_c18create_generic_tlvEP21ec_cs_variable_data_c16ec_cs_tlv_type_ePK19eap_variable_data_c @ 11 NONAME
+	_ZN11ec_cs_tlv_c19parse_data_with_MACEPK19eap_variable_data_cS2_ @ 12 NONAME
+	_ZN11ec_cs_tlv_c19parse_encrypted_tlvEPK19eap_variable_data_cPK21ec_cs_variable_data_cPS3_ @ 13 NONAME
+	_ZN11ec_cs_tlv_c20create_data_with_MACEPK19eap_variable_data_cS2_PS0_ @ 14 NONAME
+	_ZN11ec_cs_tlv_c20create_encrypted_tlvE16ec_cs_tlv_type_ePK19eap_variable_data_cPK21ec_cs_variable_data_cPS4_ @ 15 NONAME
+	_ZN11ec_cs_tlv_c20verify_data_with_MACEPK19eap_variable_data_cS2_PK12ec_cs_data_c @ 16 NONAME
+	_ZN11ec_cs_tlv_c22create_master_key_dataEPK19eap_variable_data_cS2_S2_S2_PS0_ @ 17 NONAME
+	_ZN11ec_cs_tlv_c27parse_encrypted_certificateE17ec_cs_data_type_ePK19eap_variable_data_cS3_S3_S3_PS1_ @ 18 NONAME
+	_ZN11ec_cs_tlv_c28create_encrypted_certificateE17ec_cs_data_type_ePK19eap_variable_data_cS3_S3_S3_16ec_cs_tlv_type_eS3_PS1_ @ 19 NONAME
+	_ZN11ec_cs_tlv_c28parse_encrypted_tlv_with_MACE17ec_cs_data_type_ePK19eap_variable_data_cS3_S3_S3_P21ec_cs_variable_data_c @ 20 NONAME
+	_ZN11ec_cs_tlv_c5resetEv @ 21 NONAME
+	_ZN11wapi_core_c10initializeEPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 22 NONAME
+	_ZN11wapi_core_c10initializeEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_cS6_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES8_ @ 23 NONAME
+	_ZN11wapi_core_c11get_partnerEv @ 24 NONAME
+	_ZN11wapi_core_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 25 NONAME
+	_ZN11wapi_core_c11set_partnerEP15abs_wapi_core_c @ 26 NONAME
+	_ZN11wapi_core_c12cancel_timerEP20abs_eap_base_timer_cm @ 27 NONAME
+	_ZN11wapi_core_c12get_is_validEv @ 28 NONAME
+	_ZN11wapi_core_c12set_is_validEv @ 29 NONAME
+	_ZN11wapi_core_c13resend_packetEPK19eap_am_network_id_cPK13wai_message_cmt @ 30 NONAME
+	_ZN11wapi_core_c13timer_expiredEmPv @ 31 NONAME
+	_ZN11wapi_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 32 NONAME
+	_ZN11wapi_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 33 NONAME
+	_ZN11wapi_core_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 34 NONAME
+	_ZN11wapi_core_c16check_bksa_cacheE31eapol_key_authentication_type_eN23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES2_ @ 35 NONAME
+	_ZN11wapi_core_c17cancel_all_timersEv @ 36 NONAME
+	_ZN11wapi_core_c17get_header_offsetEPmS0_ @ 37 NONAME
+	_ZN11wapi_core_c17reset_cached_bksaEv @ 38 NONAME
+	_ZN11wapi_core_c17timer_delete_dataEmPv @ 39 NONAME
+	_ZN11wapi_core_c18get_marked_removedEv @ 40 NONAME
+	_ZN11wapi_core_c18set_marked_removedEv @ 41 NONAME
+	_ZN11wapi_core_c18state_notificationEPK28abs_eap_state_notification_c @ 42 NONAME
+	_ZN11wapi_core_c19init_retransmissionEPK19eap_am_network_id_cPK13wai_message_cS5_t22wai_protocol_subtype_e @ 43 NONAME
+	_ZN11wapi_core_c19set_session_timeoutEm @ 44 NONAME
+	_ZN11wapi_core_c20allow_authenticationEv @ 45 NONAME
+	_ZN11wapi_core_c20complete_create_ecdhEPK19eap_variable_data_cS2_ @ 46 NONAME
+	_ZN11wapi_core_c20start_authenticationEv @ 47 NONAME
+	_ZN11wapi_core_c20unset_marked_removedEv @ 48 NONAME
+	_ZN11wapi_core_c21cancel_retransmissionEv @ 49 NONAME
+	_ZN11wapi_core_c21complete_query_asu_idEPK19eap_variable_data_cS2_S2_12eap_status_e @ 50 NONAME
+	_ZN11wapi_core_c22cancel_session_timeoutEv @ 51 NONAME
+	_ZN11wapi_core_c22restart_authenticationEPK19eap_am_network_id_cb @ 52 NONAME
+	_ZN11wapi_core_c23set_authentication_roleEb @ 53 NONAME
+	_ZN11wapi_core_c24set_wapi_failure_timeoutEv @ 54 NONAME
+	_ZN11wapi_core_c25init_bksa_caching_timeoutEv @ 55 NONAME
+	_ZN11wapi_core_c26initialize_session_timeoutEm @ 56 NONAME
+	_ZN11wapi_core_c27cancel_wapi_failure_timeoutEv @ 57 NONAME
+	_ZN11wapi_core_c27complete_select_certificateEPK19eap_variable_data_cS2_S2_ @ 58 NONAME
+	_ZN11wapi_core_c28complete_get_own_certificateEPK19eap_variable_data_c @ 59 NONAME
+	_ZN11wapi_core_c29cancel_authentication_sessionEv @ 60 NONAME
+	_ZN11wapi_core_c29read_reassociation_parametersEPK19eap_am_network_id_c31eapol_key_authentication_type_eP19eap_variable_data_cPKS4_S7_ @ 61 NONAME
+	_ZN11wapi_core_c31complete_read_id_of_certificateEPK19eap_variable_data_c @ 62 NONAME
+	_ZN11wapi_core_c31object_decrease_reference_countEv @ 63 NONAME
+	_ZN11wapi_core_c31object_increase_reference_countEv @ 64 NONAME
+	_ZN11wapi_core_c35complete_create_ecdh_temporary_keysEPK19eap_variable_data_cS2_S2_ @ 65 NONAME
+	_ZN11wapi_core_c41complete_verify_signature_with_public_keyE12eap_status_e @ 66 NONAME
+	_ZN11wapi_core_c42complete_create_signature_with_private_keyEPK19eap_variable_data_c12eap_status_e @ 67 NONAME
+	_ZN11wapi_core_c5resetEv @ 68 NONAME
+	_ZN11wapi_core_c8shutdownEv @ 69 NONAME
+	_ZN11wapi_core_c9configureEv @ 70 NONAME
+	_ZN11wapi_core_c9set_timerEP20abs_eap_base_timer_cmPvm @ 71 NONAME
+	_ZN11wapi_core_cC1EP18abs_eap_am_tools_cP15abs_wapi_core_cbPK19eap_am_network_id_c @ 72 NONAME
+	_ZN11wapi_core_cC2EP18abs_eap_am_tools_cP15abs_wapi_core_cbPK19eap_am_network_id_c @ 73 NONAME
+	_ZN11wapi_core_cD0Ev @ 74 NONAME
+	_ZN11wapi_core_cD1Ev @ 75 NONAME
+	_ZN11wapi_core_cD2Ev @ 76 NONAME
+	_ZN12ec_cs_data_c17get_writable_dataEv @ 77 NONAME
+	_ZN12ec_cs_data_c17set_change_statusE26ec_cs_data_change_status_e @ 78 NONAME
+	_ZN12ec_cs_data_c18set_copy_of_bufferEPKS_ @ 79 NONAME
+	_ZN12ec_cs_data_c22get_writable_referenceEv @ 80 NONAME
+	_ZN12ec_cs_data_c24get_data_references_readEv @ 81 NONAME
+	_ZN12ec_cs_data_c24set_data_references_readEv @ 82 NONAME
+	_ZN12ec_cs_data_c5resetEv @ 83 NONAME
+	_ZN12ec_cs_data_c8set_typeE17ec_cs_data_type_e @ 84 NONAME
+	_ZN12ec_cs_data_cC1EP18abs_eap_am_tools_c @ 85 NONAME
+	_ZN12ec_cs_data_cC2EP18abs_eap_am_tools_c @ 86 NONAME
+	_ZN12ec_cs_data_cD0Ev @ 87 NONAME
+	_ZN12ec_cs_data_cD1Ev @ 88 NONAME
+	_ZN12ec_cs_data_cD2Ev @ 89 NONAME
+	_ZN13wai_message_c20set_wai_message_dataEPK19eap_variable_data_c @ 90 NONAME
+	_ZN13wai_message_c29get_wai_message_data_writableEv @ 91 NONAME
+	_ZN13wai_message_c5resetEv @ 92 NONAME
+	_ZN13wai_message_cC1EP18abs_eap_am_tools_cb @ 93 NONAME
+	_ZN13wai_message_cC2EP18abs_eap_am_tools_cb @ 94 NONAME
+	_ZN13wai_message_cD0Ev @ 95 NONAME
+	_ZN13wai_message_cD1Ev @ 96 NONAME
+	_ZN13wai_message_cD2Ev @ 97 NONAME
+	_ZN14wapi_strings_c25get_wai_tlv_header_stringE14wai_tlv_type_e @ 98 NONAME
+	_ZN14wapi_strings_c26get_wapi_core_state_stringE17wapi_core_state_e @ 99 NONAME
+	_ZN14wapi_strings_c27get_wai_payload_type_stringE18wai_payload_type_e @ 100 NONAME
+	_ZN14wapi_strings_c28get_wai_protocol_type_stringE19wai_protocol_type_e @ 101 NONAME
+	_ZN14wapi_strings_c31get_wai_protocol_subtype_stringE22wai_protocol_subtype_e @ 102 NONAME
+	_ZN14wapi_strings_c31get_wai_protocol_version_stringE22wai_protocol_version_e @ 103 NONAME
+	_ZN14wapi_strings_c33get_wapi_negotiation_state_stringE24wapi_negotiation_state_e @ 104 NONAME
+	_ZN14wapi_strings_c36get_wapi_completion_operation_stringE27wapi_completion_operation_e @ 105 NONAME
+	_ZN14wapi_strings_cC1Ev @ 106 NONAME
+	_ZN14wapi_strings_cC2Ev @ 107 NONAME
+	_ZN14wapi_strings_cD0Ev @ 108 NONAME
+	_ZN14wapi_strings_cD1Ev @ 109 NONAME
+	_ZN14wapi_strings_cD2Ev @ 110 NONAME
+	_ZN15asn1_der_type_c27increase_count_of_sub_typesEv @ 111 NONAME
+	_ZN15asn1_der_type_c6decodeEPK19eap_variable_data_c @ 112 NONAME
+	_ZN15asn1_der_type_cC1EP18abs_eap_am_tools_c @ 113 NONAME
+	_ZN15asn1_der_type_cC2EP18abs_eap_am_tools_c @ 114 NONAME
+	_ZN15asn1_der_type_cD0Ev @ 115 NONAME
+	_ZN15asn1_der_type_cD1Ev @ 116 NONAME
+	_ZN15asn1_der_type_cD2Ev @ 117 NONAME
+	_ZN15ec_cs_strings_c27get_ec_cs_store_data_stringE17ec_cs_data_type_e @ 118 NONAME
+	_ZN15ec_cs_strings_c27get_ec_cs_store_data_stringE25ec_cs_pending_operation_e @ 119 NONAME
+	_ZN15ec_cs_strings_c27get_ec_cs_tlv_header_stringE16ec_cs_tlv_type_e @ 120 NONAME
+	_ZN15ec_cs_strings_c41get_ec_cs_store_data_change_status_stringE26ec_cs_data_change_status_e @ 121 NONAME
+	_ZN15ec_cs_strings_cC1Ev @ 122 NONAME
+	_ZN15ec_cs_strings_cC2Ev @ 123 NONAME
+	_ZN15ec_cs_strings_cD0Ev @ 124 NONAME
+	_ZN15ec_cs_strings_cD1Ev @ 125 NONAME
+	_ZN15ec_cs_strings_cD2Ev @ 126 NONAME
+	_ZN17CWapiCertificates10SetCACertLEi5TBuf8ILi310EE @ 127 NONAME
+	_ZN17CWapiCertificates12SetUserCertLEi5TBuf8ILi310EE @ 128 NONAME
+	_ZN17CWapiCertificates17GetConfigurationLEiR6TDes16S1_ @ 129 NONAME
+	_ZN17CWapiCertificates21DeleteAPSpecificDataLEi @ 130 NONAME
+	_ZN17CWapiCertificates22ResetCertificateStoreLEv @ 131 NONAME
+	_ZN17CWapiCertificates24GetAllCertificateLabelsLEPP6RArrayI4TBufILi255EEEPPS0_I5TBuf8ILi310EEES5_SA_ @ 132 NONAME
+	_ZN17CWapiCertificates4NewLEv @ 133 NONAME
+	_ZN17CWapiCertificatesC1Ev @ 134 NONAME
+	_ZN17CWapiCertificatesC2Ev @ 135 NONAME
+	_ZN17CWapiCertificatesD0Ev @ 136 NONAME
+	_ZN17CWapiCertificatesD1Ev @ 137 NONAME
+	_ZN17CWapiCertificatesD2Ev @ 138 NONAME
+	_ZN18ec_cs_completion_c12get_is_validEv @ 139 NONAME
+	_ZN18ec_cs_completion_c12set_is_validEv @ 140 NONAME
+	_ZN18ec_cs_completion_c21set_completion_actionE18ec_cs_completion_e @ 141 NONAME
+	_ZN18ec_cs_completion_c28get_completion_action_stringE18ec_cs_completion_e @ 142 NONAME
+	_ZN18ec_cs_completion_cC1EP18abs_eap_am_tools_c18ec_cs_completion_e @ 143 NONAME
+	_ZN18ec_cs_completion_cC2EP18abs_eap_am_tools_c18ec_cs_completion_e @ 144 NONAME
+	_ZN18ec_cs_completion_cD0Ev @ 145 NONAME
+	_ZN18ec_cs_completion_cD1Ev @ 146 NONAME
+	_ZN18ec_cs_completion_cD2Ev @ 147 NONAME
+	_ZN19ec_cs_tlv_message_c11add_paddingEm @ 148 NONAME
+	_ZN19ec_cs_tlv_message_c12get_is_validEv @ 149 NONAME
+	_ZN19ec_cs_tlv_message_c22get_ec_cs_message_dataEv @ 150 NONAME
+	_ZN19ec_cs_tlv_message_c22set_ec_cs_message_dataEP19eap_variable_data_c @ 151 NONAME
+	_ZN19ec_cs_tlv_message_c5resetEv @ 152 NONAME
+	_ZN19ec_cs_tlv_message_cC1EP18abs_eap_am_tools_cb @ 153 NONAME
+	_ZN19ec_cs_tlv_message_cC2EP18abs_eap_am_tools_cb @ 154 NONAME
+	_ZN19ec_cs_tlv_message_cD0Ev @ 155 NONAME
+	_ZN19ec_cs_tlv_message_cD1Ev @ 156 NONAME
+	_ZN19ec_cs_tlv_message_cD2Ev @ 157 NONAME
+	_ZN19wai_variable_data_c10set_bufferE18wai_payload_type_ePKvm @ 158 NONAME
+	_ZN19wai_variable_data_c11init_headerE18wai_payload_type_em @ 159 NONAME
+	_ZN19wai_variable_data_c16set_payload_typeE18wai_payload_type_e @ 160 NONAME
+	_ZN19wai_variable_data_c18set_copy_of_bufferE18wai_payload_type_ePK19eap_variable_data_c @ 161 NONAME
+	_ZN19wai_variable_data_c18set_copy_of_bufferE18wai_payload_type_ePKvm @ 162 NONAME
+	_ZN19wai_variable_data_c18set_copy_of_bufferEPKS_ @ 163 NONAME
+	_ZN19wai_variable_data_c23convert_to_wai_tlv_typeE18wai_payload_type_e @ 164 NONAME
+	_ZN19wai_variable_data_c25convert_to_ec_cs_tlv_typeE18wai_payload_type_e @ 165 NONAME
+	_ZN19wai_variable_data_c27convert_to_wai_payload_typeE14wai_tlv_type_e @ 166 NONAME
+	_ZN19wai_variable_data_c28get_writable_full_tlv_bufferEv @ 167 NONAME
+	_ZN19wai_variable_data_c31object_increase_reference_countEv @ 168 NONAME
+	_ZN19wai_variable_data_c35add_next_payload_with_same_tlv_typeEPS_ @ 169 NONAME
+	_ZN19wai_variable_data_c35set_next_payload_with_same_tlv_typeEPS_ @ 170 NONAME
+	_ZN19wai_variable_data_c37convert_to_wai_certificate_identifierE18wai_payload_type_e @ 171 NONAME
+	_ZN19wai_variable_data_c5resetEv @ 172 NONAME
+	_ZN19wai_variable_data_c6createE18wai_payload_type_ePK19eap_variable_data_c @ 173 NONAME
+	_ZN19wai_variable_data_c6createE18wai_payload_type_ePKvm @ 174 NONAME
+	_ZN19wai_variable_data_c8add_dataE18wai_payload_type_ePK19eap_variable_data_c @ 175 NONAME
+	_ZN19wai_variable_data_c8add_dataE18wai_payload_type_ePKvm @ 176 NONAME
+	_ZN19wai_variable_data_c8add_dataEPKS_ @ 177 NONAME
+	_ZN19wai_variable_data_cC1EP18abs_eap_am_tools_c @ 178 NONAME
+	_ZN19wai_variable_data_cC2EP18abs_eap_am_tools_c @ 179 NONAME
+	_ZN19wai_variable_data_cD0Ev @ 180 NONAME
+	_ZN19wai_variable_data_cD1Ev @ 181 NONAME
+	_ZN19wai_variable_data_cD2Ev @ 182 NONAME
+	_ZN19wapi_am_base_core_c16new_wapi_am_coreEP18abs_eap_am_tools_cP18abs_wapi_am_core_cbPK19eap_am_network_id_c @ 183 NONAME
+	_ZN19wapi_session_core_c11associationEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_cS6_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES8_S6_ @ 184 NONAME
+	_ZN19wapi_session_core_c11get_partnerEv @ 185 NONAME
+	_ZN19wapi_session_core_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 186 NONAME
+	_ZN19wapi_session_core_c12cancel_timerEP20abs_eap_base_timer_cm @ 187 NONAME
+	_ZN19wapi_session_core_c12create_stateEPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 188 NONAME
+	_ZN19wapi_session_core_c12get_is_validEv @ 189 NONAME
+	_ZN19wapi_session_core_c12set_is_validEv @ 190 NONAME
+	_ZN19wapi_session_core_c13timer_expiredEmPv @ 191 NONAME
+	_ZN19wapi_session_core_c14disassociationEPK19eap_am_network_id_c @ 192 NONAME
+	_ZN19wapi_session_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 193 NONAME
+	_ZN19wapi_session_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 194 NONAME
+	_ZN19wapi_session_core_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 195 NONAME
+	_ZN19wapi_session_core_c16check_bksa_cacheEP11eap_array_cI19eap_am_network_id_cE31eapol_key_authentication_type_eN23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES6_ @ 196 NONAME
+	_ZN19wapi_session_core_c17cancel_all_timersEv @ 197 NONAME
+	_ZN19wapi_session_core_c17get_header_offsetEPmS0_ @ 198 NONAME
+	_ZN19wapi_session_core_c17timer_delete_dataEmPv @ 199 NONAME
+	_ZN19wapi_session_core_c18create_new_sessionEPK19eap_am_network_id_c @ 200 NONAME
+	_ZN19wapi_session_core_c18shutdown_operationEP11wapi_core_cP18abs_eap_am_tools_c @ 201 NONAME
+	_ZN19wapi_session_core_c18state_notificationEPK28abs_eap_state_notification_c @ 202 NONAME
+	_ZN19wapi_session_core_c19set_session_timeoutEm @ 203 NONAME
+	_ZN19wapi_session_core_c22remove_bksa_from_cacheEPK19eap_am_network_id_c @ 204 NONAME
+	_ZN19wapi_session_core_c22restart_authenticationEPK19eap_am_network_id_cb @ 205 NONAME
+	_ZN19wapi_session_core_c22restart_authenticationEPK19eap_am_network_id_cbbb @ 206 NONAME
+	_ZN19wapi_session_core_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 207 NONAME
+	_ZN19wapi_session_core_c23reset_or_remove_sessionEPP11wapi_core_cPK25eap_network_id_selector_cb @ 208 NONAME
+	_ZN19wapi_session_core_c29cancel_authentication_sessionEP11wapi_core_cP18abs_eap_am_tools_c @ 209 NONAME
+	_ZN19wapi_session_core_c29read_reassociation_parametersEPK19eap_am_network_id_cS2_31eapol_key_authentication_type_eP19eap_variable_data_cPKS4_S7_ @ 210 NONAME
+	_ZN19wapi_session_core_c31synchronous_create_wapi_sessionEPK19eap_am_network_id_c @ 211 NONAME
+	_ZN19wapi_session_core_c31synchronous_remove_wapi_sessionEPK19eap_am_network_id_c @ 212 NONAME
+	_ZN19wapi_session_core_c34cancel_all_authentication_sessionsEv @ 213 NONAME
+	_ZN19wapi_session_core_c36synchronous_cancel_all_wapi_sessionsEv @ 214 NONAME
+	_ZN19wapi_session_core_c5resetEv @ 215 NONAME
+	_ZN19wapi_session_core_c8shutdownEv @ 216 NONAME
+	_ZN19wapi_session_core_c9configureEv @ 217 NONAME
+	_ZN19wapi_session_core_c9set_timerEP20abs_eap_base_timer_cmPvm @ 218 NONAME
+	_ZN19wapi_session_core_cC1EP18abs_eap_am_tools_cP15abs_wapi_core_cb @ 219 NONAME
+	_ZN19wapi_session_core_cC2EP18abs_eap_am_tools_cP15abs_wapi_core_cb @ 220 NONAME
+	_ZN19wapi_session_core_cD0Ev @ 221 NONAME
+	_ZN19wapi_session_core_cD1Ev @ 222 NONAME
+	_ZN19wapi_session_core_cD2Ev @ 223 NONAME
+	_ZN20ec_cs_tlv_payloads_c13copy_tlv_dataE16ec_cs_tlv_type_ePKvm @ 224 NONAME
+	_ZN20ec_cs_tlv_payloads_c14verify_paddingEPKhm @ 225 NONAME
+	_ZN20ec_cs_tlv_payloads_c20parse_ec_cs_payloadsEPvPmS1_ @ 226 NONAME
+	_ZN20ec_cs_tlv_payloads_c21parse_generic_payloadE16ec_cs_tlv_type_ePK18ec_cs_tlv_header_c @ 227 NONAME
+	_ZN20ec_cs_tlv_payloads_c5resetEv @ 228 NONAME
+	_ZN20ec_cs_tlv_payloads_c7add_tlvEP21ec_cs_variable_data_c @ 229 NONAME
+	_ZN20ec_cs_tlv_payloads_c8copy_tlvEPKS_16ec_cs_tlv_type_e @ 230 NONAME
+	_ZN20ec_cs_tlv_payloads_cC1EP18abs_eap_am_tools_cb @ 231 NONAME
+	_ZN20ec_cs_tlv_payloads_cC2EP18abs_eap_am_tools_cb @ 232 NONAME
+	_ZN20ec_cs_tlv_payloads_cD0Ev @ 233 NONAME
+	_ZN20ec_cs_tlv_payloads_cD1Ev @ 234 NONAME
+	_ZN20ec_cs_tlv_payloads_cD2Ev @ 235 NONAME
+	_ZN20wapi_ethernet_core_c11associationEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_cS6_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES8_S6_ @ 236 NONAME
+	_ZN20wapi_ethernet_core_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 237 NONAME
+	_ZN20wapi_ethernet_core_c12cancel_timerEP20abs_eap_base_timer_cm @ 238 NONAME
+	_ZN20wapi_ethernet_core_c12create_stateEPK19eap_am_network_id_c31eapol_key_authentication_type_e @ 239 NONAME
+	_ZN20wapi_ethernet_core_c12get_is_validEv @ 240 NONAME
+	_ZN20wapi_ethernet_core_c12set_is_validEv @ 241 NONAME
+	_ZN20wapi_ethernet_core_c14disassociationEPK19eap_am_network_id_c @ 242 NONAME
+	_ZN20wapi_ethernet_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 243 NONAME
+	_ZN20wapi_ethernet_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 244 NONAME
+	_ZN20wapi_ethernet_core_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 245 NONAME
+	_ZN20wapi_ethernet_core_c16check_bksa_cacheEP11eap_array_cI19eap_am_network_id_cE31eapol_key_authentication_type_eN23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES6_ @ 246 NONAME
+	_ZN20wapi_ethernet_core_c17cancel_all_timersEv @ 247 NONAME
+	_ZN20wapi_ethernet_core_c17get_header_offsetEPmS0_ @ 248 NONAME
+	_ZN20wapi_ethernet_core_c18state_notificationEPK28abs_eap_state_notification_c @ 249 NONAME
+	_ZN20wapi_ethernet_core_c19set_session_timeoutEm @ 250 NONAME
+	_ZN20wapi_ethernet_core_c19start_reassociationEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_c @ 251 NONAME
+	_ZN20wapi_ethernet_core_c20start_authenticationEPK19eap_am_network_id_cb @ 252 NONAME
+	_ZN20wapi_ethernet_core_c22complete_reassociationE33eapol_wlan_authentication_state_ePK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_cS7_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES9_ @ 253 NONAME
+	_ZN20wapi_ethernet_core_c22remove_bksa_from_cacheEPK19eap_am_network_id_c @ 254 NONAME
+	_ZN20wapi_ethernet_core_c22restart_authenticationEPK19eap_am_network_id_cbbb @ 255 NONAME
+	_ZN20wapi_ethernet_core_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 256 NONAME
+	_ZN20wapi_ethernet_core_c29read_reassociation_parametersEPK19eap_am_network_id_cS2_31eapol_key_authentication_type_eP19eap_variable_data_cPKS4_S7_ @ 257 NONAME
+	_ZN20wapi_ethernet_core_c34cancel_all_authentication_sessionsEv @ 258 NONAME
+	_ZN20wapi_ethernet_core_c37asynchronous_init_remove_wapi_sessionEPK19eap_am_network_id_c @ 259 NONAME
+	_ZN20wapi_ethernet_core_c8shutdownEv @ 260 NONAME
+	_ZN20wapi_ethernet_core_c9configureEv @ 261 NONAME
+	_ZN20wapi_ethernet_core_c9set_timerEP20abs_eap_base_timer_cmPvm @ 262 NONAME
+	_ZN20wapi_ethernet_core_cC1EP18abs_eap_am_tools_cP24abs_wapi_ethernet_core_cb @ 263 NONAME
+	_ZN20wapi_ethernet_core_cC2EP18abs_eap_am_tools_cP24abs_wapi_ethernet_core_cb @ 264 NONAME
+	_ZN20wapi_ethernet_core_cD0Ev @ 265 NONAME
+	_ZN20wapi_ethernet_core_cD1Ev @ 266 NONAME
+	_ZN20wapi_ethernet_core_cD2Ev @ 267 NONAME
+	_ZN21ec_cs_variable_data_c11init_headerE16ec_cs_tlv_type_em @ 268 NONAME
+	_ZN21ec_cs_variable_data_c18set_copy_of_bufferE16ec_cs_tlv_type_ePKvm @ 269 NONAME
+	_ZN21ec_cs_variable_data_c18set_copy_of_bufferEPKS_ @ 270 NONAME
+	_ZN21ec_cs_variable_data_c18set_copy_of_bufferEPKvm @ 271 NONAME
+	_ZN21ec_cs_variable_data_c28get_writable_full_tlv_bufferEv @ 272 NONAME
+	_ZN21ec_cs_variable_data_c31object_increase_reference_countEv @ 273 NONAME
+	_ZN21ec_cs_variable_data_c35add_next_payload_with_same_tlv_typeEPS_ @ 274 NONAME
+	_ZN21ec_cs_variable_data_c35set_next_payload_with_same_tlv_typeEPS_ @ 275 NONAME
+	_ZN21ec_cs_variable_data_c5resetEv @ 276 NONAME
+	_ZN21ec_cs_variable_data_c8add_dataEPKS_ @ 277 NONAME
+	_ZN21ec_cs_variable_data_c8add_dataEPKvm @ 278 NONAME
+	_ZN21ec_cs_variable_data_c8set_typeE16ec_cs_tlv_type_e @ 279 NONAME
+	_ZN21ec_cs_variable_data_cC1EP18abs_eap_am_tools_c @ 280 NONAME
+	_ZN21ec_cs_variable_data_cC2EP18abs_eap_am_tools_c @ 281 NONAME
+	_ZN21ec_cs_variable_data_cD0Ev @ 282 NONAME
+	_ZN21ec_cs_variable_data_cD1Ev @ 283 NONAME
+	_ZN21ec_cs_variable_data_cD2Ev @ 284 NONAME
+	_ZN21wapi_am_crypto_sms4_c11ecb_decryptEPKvPvm @ 285 NONAME
+	_ZN21wapi_am_crypto_sms4_c11ecb_encryptEPKvPvm @ 286 NONAME
+	_ZN21wapi_am_crypto_sms4_c12get_is_validEv @ 287 NONAME
+	_ZN21wapi_am_crypto_sms4_c12get_key_sizeEv @ 288 NONAME
+	_ZN21wapi_am_crypto_sms4_c12set_is_validEv @ 289 NONAME
+	_ZN21wapi_am_crypto_sms4_c14get_block_sizeEv @ 290 NONAME
+	_ZN21wapi_am_crypto_sms4_c14set_is_invalidEv @ 291 NONAME
+	_ZN21wapi_am_crypto_sms4_c15sms4_substituteEPm @ 292 NONAME
+	_ZN21wapi_am_crypto_sms4_c16ecb_process_dataEPKvPvmb @ 293 NONAME
+	_ZN21wapi_am_crypto_sms4_c5L_keyEPm @ 294 NONAME
+	_ZN21wapi_am_crypto_sms4_c6L_dataEPm @ 295 NONAME
+	_ZN21wapi_am_crypto_sms4_c7set_keyEPK19eap_variable_data_c @ 296 NONAME
+	_ZN21wapi_am_crypto_sms4_cC1EP18abs_eap_am_tools_c @ 297 NONAME
+	_ZN21wapi_am_crypto_sms4_cC2EP18abs_eap_am_tools_c @ 298 NONAME
+	_ZN21wapi_am_crypto_sms4_cD0Ev @ 299 NONAME
+	_ZN21wapi_am_crypto_sms4_cD1Ev @ 300 NONAME
+	_ZN21wapi_am_crypto_sms4_cD2Ev @ 301 NONAME
+	_ZN22abs_ec_am_algorithms_cD0Ev @ 302 NONAME
+	_ZN22abs_ec_am_algorithms_cD1Ev @ 303 NONAME
+	_ZN22abs_ec_am_algorithms_cD2Ev @ 304 NONAME
+	_ZN22ec_certificate_store_c11create_ecdhEPK19eap_variable_data_cS2_S2_ @ 305 NONAME
+	_ZN22ec_certificate_store_c12query_asu_idEv @ 306 NONAME
+	_ZN22ec_certificate_store_c13timer_expiredEmPv @ 307 NONAME
+	_ZN22ec_certificate_store_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 308 NONAME
+	_ZN22ec_certificate_store_c17timer_delete_dataEmPv @ 309 NONAME
+	_ZN22ec_certificate_store_c18select_certificateEPK19eap_variable_data_c @ 310 NONAME
+	_ZN22ec_certificate_store_c18set_ae_certificateEPK19eap_variable_data_c @ 311 NONAME
+	_ZN22ec_certificate_store_c19get_own_certificateEv @ 312 NONAME
+	_ZN22ec_certificate_store_c20complete_create_ecdhEPK19eap_variable_data_cS2_ @ 313 NONAME
+	_ZN22ec_certificate_store_c21completion_action_addE18ec_cs_completion_e @ 314 NONAME
+	_ZN22ec_certificate_store_c21completion_action_popEv @ 315 NONAME
+	_ZN22ec_certificate_store_c21set_pending_operationE25ec_cs_pending_operation_e @ 316 NONAME
+	_ZN22ec_certificate_store_c22completion_action_pushE18ec_cs_completion_e @ 317 NONAME
+	_ZN22ec_certificate_store_c22query_certificate_listEv @ 318 NONAME
+	_ZN22ec_certificate_store_c22read_id_of_certificateEPK19eap_variable_data_c @ 319 NONAME
+	_ZN22ec_certificate_store_c22set_receive_network_idEPK19eap_am_network_id_c @ 320 NONAME
+	_ZN22ec_certificate_store_c23completion_action_checkEv @ 321 NONAME
+	_ZN22ec_certificate_store_c23completion_action_traceEv @ 322 NONAME
+	_ZN22ec_certificate_store_c24completion_action_clenupEv @ 323 NONAME
+	_ZN22ec_certificate_store_c24start_certificate_importEv @ 324 NONAME
+	_ZN22ec_certificate_store_c26compare_id_and_certificateEPK19eap_variable_data_cS2_ @ 325 NONAME
+	_ZN22ec_certificate_store_c26create_ecdh_temporary_keysEv @ 326 NONAME
+	_ZN22ec_certificate_store_c28initialize_certificate_storeEv @ 327 NONAME
+	_ZN22ec_certificate_store_c29add_imported_certificate_fileEPK19eap_variable_data_cS2_ @ 328 NONAME
+	_ZN22ec_certificate_store_c29are_pending_queries_completedEv @ 329 NONAME
+	_ZN22ec_certificate_store_c32verify_signature_with_public_keyEPK19eap_variable_data_cS2_S2_b @ 330 NONAME
+	_ZN22ec_certificate_store_c33create_signature_with_private_keyEPK19eap_variable_data_cS2_ @ 331 NONAME
+	_ZN22ec_certificate_store_c35complete_create_ecdh_temporary_keysEPK19eap_variable_data_cS2_S2_ @ 332 NONAME
+	_ZN22ec_certificate_store_c36complete_read_certificate_store_dataE12eap_status_e25ec_cs_pending_operation_ePK11eap_array_cI12ec_cs_data_cE @ 333 NONAME
+	_ZN22ec_certificate_store_c36remove_cached_certificate_store_dataEv @ 334 NONAME
+	_ZN22ec_certificate_store_c37complete_initialize_certificate_storeE27wapi_completion_operation_e @ 335 NONAME
+	_ZN22ec_certificate_store_c37complete_write_certificate_store_dataE12eap_status_e25ec_cs_pending_operation_e @ 336 NONAME
+	_ZN22ec_certificate_store_c41compare_issuer_name_of_id_and_certificateEPK19eap_variable_data_cS2_ @ 337 NONAME
+	_ZN22ec_certificate_store_c41complete_verify_signature_with_public_keyE12eap_status_e @ 338 NONAME
+	_ZN22ec_certificate_store_c42complete_create_signature_with_private_keyEPK19eap_variable_data_c12eap_status_e @ 339 NONAME
+	_ZN22ec_certificate_store_c47internal_complete_add_imported_certificate_fileEv @ 340 NONAME
+	_ZN22ec_certificate_store_c8shutdownEv @ 341 NONAME
+	_ZN22ec_certificate_store_c9configureEv @ 342 NONAME
+	_ZN22ec_certificate_store_cC1EP18abs_eap_am_tools_cP26abs_ec_certificate_store_cP30ec_am_base_certificate_store_cb @ 343 NONAME
+	_ZN22ec_certificate_store_cC2EP18abs_eap_am_tools_cP26abs_ec_certificate_store_cP30ec_am_base_certificate_store_cb @ 344 NONAME
+	_ZN22ec_certificate_store_cD0Ev @ 345 NONAME
+	_ZN22ec_certificate_store_cD1Ev @ 346 NONAME
+	_ZN22ec_certificate_store_cD2Ev @ 347 NONAME
+	_ZN22wai_message_payloads_c13copy_tlv_dataE18wai_payload_type_ePKvm @ 348 NONAME
+	_ZN22wai_message_payloads_c14insert_payloadEPK19wai_variable_data_c @ 349 NONAME
+	_ZN22wai_message_payloads_c17initialise_headerEv @ 350 NONAME
+	_ZN22wai_message_payloads_c18parse_wai_payloadsEPvmPm @ 351 NONAME
+	_ZN22wai_message_payloads_c21parse_generic_payloadE18wai_payload_type_ePK19wai_variable_data_cPm @ 352 NONAME
+	_ZN22wai_message_payloads_c39get_wai_protocol_packet_header_writableEv @ 353 NONAME
+	_ZN22wai_message_payloads_c5resetEv @ 354 NONAME
+	_ZN22wai_message_payloads_c7add_tlvEP19wai_variable_data_c @ 355 NONAME
+	_ZN22wai_message_payloads_c8copy_tlvEPKS_18wai_payload_type_e @ 356 NONAME
+	_ZN22wai_message_payloads_cC1EP18abs_eap_am_tools_cb @ 357 NONAME
+	_ZN22wai_message_payloads_cC2EP18abs_eap_am_tools_cb @ 358 NONAME
+	_ZN22wai_message_payloads_cD0Ev @ 359 NONAME
+	_ZN22wai_message_payloads_cD1Ev @ 360 NONAME
+	_ZN22wai_message_payloads_cD2Ev @ 361 NONAME
+	_ZN22wapi_am_core_symbian_c8shutdownEv @ 362 NONAME
+	_ZN22wapi_am_core_symbian_c9configureEv @ 363 NONAME
+	_ZN22wapi_asn1_der_parser_c17get_wapi_identityEP19eap_variable_data_c @ 364 NONAME
+	_ZN22wapi_asn1_der_parser_c17get_wapi_identityEP19eap_variable_data_cS1_S1_ @ 365 NONAME
+	_ZN22wapi_asn1_der_parser_c24get_decoded_subject_nameEP19eap_variable_data_cS1_ @ 366 NONAME
+	_ZN22wapi_asn1_der_parser_c6decodeEPK19eap_variable_data_c @ 367 NONAME
+	_ZN22wapi_asn1_der_parser_cC1EP18abs_eap_am_tools_c @ 368 NONAME
+	_ZN22wapi_asn1_der_parser_cC2EP18abs_eap_am_tools_c @ 369 NONAME
+	_ZN22wapi_asn1_der_parser_cD0Ev @ 370 NONAME
+	_ZN22wapi_asn1_der_parser_cD1Ev @ 371 NONAME
+	_ZN22wapi_asn1_der_parser_cD2Ev @ 372 NONAME
+	_ZN23ec_am_base_algorithms_c24new_ec_base_algorithms_cEP18abs_eap_am_tools_cP22abs_ec_am_algorithms_cb @ 373 NONAME
+	_ZN23ec_am_base_algorithms_cD0Ev @ 374 NONAME
+	_ZN23ec_am_base_algorithms_cD1Ev @ 375 NONAME
+	_ZN23ec_am_base_algorithms_cD2Ev @ 376 NONAME
+	_ZN25eap_core_retransmission_c19get_send_network_idEv @ 377 NONAME
+	_ZN25eap_core_retransmission_c28get_next_retransmission_timeEv @ 378 NONAME
+	_ZN25eap_core_retransmission_c31get_next_retransmission_counterEv @ 379 NONAME
+	_ZN25eap_core_retransmission_cC1EP18abs_eap_am_tools_cPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmmm16eap_code_value_eh19eap_expanded_type_c @ 380 NONAME
+	_ZN25eap_core_retransmission_cC2EP18abs_eap_am_tools_cPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmmm16eap_code_value_eh19eap_expanded_type_c @ 381 NONAME
+	_ZN25eap_core_retransmission_cD0Ev @ 382 NONAME
+	_ZN25eap_core_retransmission_cD1Ev @ 383 NONAME
+	_ZN25eap_core_retransmission_cD2Ev @ 384 NONAME
+	_ZN25ec_cs_compare_reference_cC1EP18abs_eap_am_tools_c @ 385 NONAME
+	_ZN25ec_cs_compare_reference_cC2EP18abs_eap_am_tools_c @ 386 NONAME
+	_ZN25ec_cs_compare_reference_cD0Ev @ 387 NONAME
+	_ZN25ec_cs_compare_reference_cD1Ev @ 388 NONAME
+	_ZN25ec_cs_compare_reference_cD2Ev @ 389 NONAME
+	_ZN26abs_ec_certificate_store_cD0Ev @ 390 NONAME
+	_ZN26abs_ec_certificate_store_cD1Ev @ 391 NONAME
+	_ZN26abs_ec_certificate_store_cD2Ev @ 392 NONAME
+	_ZN26wapi_core_retransmission_c28get_next_retransmission_timeEv @ 393 NONAME
+	_ZN26wapi_core_retransmission_c31get_next_retransmission_counterEv @ 394 NONAME
+	_ZN26wapi_core_retransmission_cC1EP18abs_eap_am_tools_cPK19eap_am_network_id_cPK13wai_message_cS7_mmt22wai_protocol_subtype_e @ 395 NONAME
+	_ZN26wapi_core_retransmission_cC2EP18abs_eap_am_tools_cPK19eap_am_network_id_cPK13wai_message_cS7_mmt22wai_protocol_subtype_e @ 396 NONAME
+	_ZN26wapi_core_retransmission_cD0Ev @ 397 NONAME
+	_ZN26wapi_core_retransmission_cD1Ev @ 398 NONAME
+	_ZN26wapi_core_retransmission_cD2Ev @ 399 NONAME
+	_ZN26wapi_wlan_authentication_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 400 NONAME
+	_ZN26wapi_wlan_authentication_c12cancel_timerEP20abs_eap_base_timer_cm @ 401 NONAME
+	_ZN26wapi_wlan_authentication_c12get_is_validEv @ 402 NONAME
+	_ZN26wapi_wlan_authentication_c12set_is_validEv @ 403 NONAME
+	_ZN26wapi_wlan_authentication_c13get_is_clientEv @ 404 NONAME
+	_ZN26wapi_wlan_authentication_c13timer_expiredEmPv @ 405 NONAME
+	_ZN26wapi_wlan_authentication_c14disassociationEPK19eap_am_network_id_c @ 406 NONAME
+	_ZN26wapi_wlan_authentication_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 407 NONAME
+	_ZN26wapi_wlan_authentication_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 408 NONAME
+	_ZN26wapi_wlan_authentication_c15wapi_indicationEPK19eap_am_network_id_c33eapol_wlan_authentication_state_e @ 409 NONAME
+	_ZN26wapi_wlan_authentication_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 410 NONAME
+	_ZN26wapi_wlan_authentication_c16check_bksa_cacheEP11eap_array_cI19eap_am_network_id_cE31eapol_key_authentication_type_eN23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES6_ @ 411 NONAME
+	_ZN26wapi_wlan_authentication_c17cancel_all_timersEv @ 412 NONAME
+	_ZN26wapi_wlan_authentication_c17get_header_offsetEPmS0_ @ 413 NONAME
+	_ZN26wapi_wlan_authentication_c17timer_delete_dataEmPv @ 414 NONAME
+	_ZN26wapi_wlan_authentication_c18create_upper_stackEv @ 415 NONAME
+	_ZN26wapi_wlan_authentication_c18state_notificationEPK28abs_eap_state_notification_c @ 416 NONAME
+	_ZN26wapi_wlan_authentication_c19start_reassociationEPK19eap_am_network_id_cS2_31eapol_key_authentication_type_e @ 417 NONAME
+	_ZN26wapi_wlan_authentication_c20complete_associationE33eapol_wlan_authentication_state_ePK19eap_am_network_id_cPK19eap_variable_data_cS6_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES8_ @ 418 NONAME
+	_ZN26wapi_wlan_authentication_c20start_authenticationEPK19eap_variable_data_c31eapol_key_authentication_type_eS2_bPK19eap_am_network_id_c @ 419 NONAME
+	_ZN26wapi_wlan_authentication_c22complete_reassociationE33eapol_wlan_authentication_state_ePK19eap_am_network_id_cPK19eap_variable_data_cS6_N23eapol_RSNA_key_header_c19eapol_RSNA_cipher_eES8_ @ 420 NONAME
+	_ZN26wapi_wlan_authentication_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 421 NONAME
+	_ZN26wapi_wlan_authentication_c26get_authentication_counterEv @ 422 NONAME
+	_ZN26wapi_wlan_authentication_c28new_wapi_wlan_authenticationEP18abs_eap_am_tools_cP30abs_wapi_wlan_authentication_cbPK38abs_eapol_wlan_database_reference_if_c @ 423 NONAME
+	_ZN26wapi_wlan_authentication_c32increment_authentication_counterEv @ 424 NONAME
+	_ZN26wapi_wlan_authentication_c8shutdownEv @ 425 NONAME
+	_ZN26wapi_wlan_authentication_c9configureEv @ 426 NONAME
+	_ZN26wapi_wlan_authentication_c9set_timerEP20abs_eap_base_timer_cmPvm @ 427 NONAME
+	_ZN26wapi_wlan_authentication_cC1EP18abs_eap_am_tools_cP30abs_wapi_wlan_authentication_cP29wapi_am_wlan_authentication_cb @ 428 NONAME
+	_ZN26wapi_wlan_authentication_cC2EP18abs_eap_am_tools_cP30abs_wapi_wlan_authentication_cP29wapi_am_wlan_authentication_cb @ 429 NONAME
+	_ZN26wapi_wlan_authentication_cD0Ev @ 430 NONAME
+	_ZN26wapi_wlan_authentication_cD1Ev @ 431 NONAME
+	_ZN26wapi_wlan_authentication_cD2Ev @ 432 NONAME
+	_ZN27eap_am_file_input_symbian_c10file_closeEv @ 433 NONAME
+	_ZN27eap_am_file_input_symbian_c10file_writeEPK19eap_variable_data_c @ 434 NONAME
+	_ZN27eap_am_file_input_symbian_c11file_deleteEPK19eap_variable_data_c @ 435 NONAME
+	_ZN27eap_am_file_input_symbian_c11file_existsEPK19eap_variable_data_c @ 436 NONAME
+	_ZN27eap_am_file_input_symbian_c14file_read_lineEP19eap_variable_data_c @ 437 NONAME
+	_ZN27eap_am_file_input_symbian_c9file_copyEPK19eap_variable_data_cS2_ @ 438 NONAME
+	_ZN27eap_am_file_input_symbian_c9file_openEPK19eap_variable_data_c23eap_file_io_direction_e @ 439 NONAME
+	_ZN27eap_am_file_input_symbian_c9file_readEP19eap_variable_data_c @ 440 NONAME
+	_ZN27eap_am_file_input_symbian_c9file_sizeEv @ 441 NONAME
+	_ZN27eap_am_file_input_symbian_cC1EP18abs_eap_am_tools_c @ 442 NONAME
+	_ZN27eap_am_file_input_symbian_cC2EP18abs_eap_am_tools_c @ 443 NONAME
+	_ZN27eap_am_file_input_symbian_cD0Ev @ 444 NONAME
+	_ZN27eap_am_file_input_symbian_cD1Ev @ 445 NONAME
+	_ZN27eap_am_file_input_symbian_cD2Ev @ 446 NONAME
+	_ZN27ec_base_certificate_store_c31new_ec_base_certificate_store_cEP18abs_eap_am_tools_cP26abs_ec_certificate_store_cP30ec_am_base_certificate_store_cb @ 447 NONAME
+	_ZN27ec_base_certificate_store_cD0Ev @ 448 NONAME
+	_ZN27ec_base_certificate_store_cD1Ev @ 449 NONAME
+	_ZN27ec_base_certificate_store_cD2Ev @ 450 NONAME
+	_ZN28ec_cs_compare_reference_id_cC1EP18abs_eap_am_tools_c @ 451 NONAME
+	_ZN28ec_cs_compare_reference_id_cC2EP18abs_eap_am_tools_c @ 452 NONAME
+	_ZN28ec_cs_compare_reference_id_cD0Ev @ 453 NONAME
+	_ZN28ec_cs_compare_reference_id_cD1Ev @ 454 NONAME
+	_ZN28ec_cs_compare_reference_id_cD2Ev @ 455 NONAME
+	_ZN29ec_am_algorithms_direct_nrc_c11create_ecdhEPK19eap_variable_data_cS2_S2_ @ 456 NONAME
+	_ZN29ec_am_algorithms_direct_nrc_c26create_ecdh_temporary_keysEv @ 457 NONAME
+	_ZN29ec_am_algorithms_direct_nrc_c32verify_signature_with_public_keyEPK19eap_variable_data_cS2_S2_ @ 458 NONAME
+	_ZN29ec_am_algorithms_direct_nrc_c33create_signature_with_private_keyEPK19eap_variable_data_cS2_ @ 459 NONAME
+	_ZN29ec_am_algorithms_direct_nrc_c9configureEv @ 460 NONAME
+	_ZN29ec_am_algorithms_direct_nrc_cC1EP18abs_eap_am_tools_cP22abs_ec_am_algorithms_cb @ 461 NONAME
+	_ZN29ec_am_algorithms_direct_nrc_cC2EP18abs_eap_am_tools_cP22abs_ec_am_algorithms_cb @ 462 NONAME
+	_ZN29ec_am_algorithms_direct_nrc_cD0Ev @ 463 NONAME
+	_ZN29ec_am_algorithms_direct_nrc_cD1Ev @ 464 NONAME
+	_ZN29ec_am_algorithms_direct_nrc_cD2Ev @ 465 NONAME
+	_ZN29wapi_am_wlan_authentication_c31new_wapi_am_wlan_authenticationEP18abs_eap_am_tools_cbPK38abs_eapol_wlan_database_reference_if_c @ 466 NONAME
+	_ZN30ec_cs_compare_certificate_id_cC1EP18abs_eap_am_tools_cPK19eap_variable_data_cS4_ @ 467 NONAME
+	_ZN30ec_cs_compare_certificate_id_cC2EP18abs_eap_am_tools_cPK19eap_variable_data_cS4_ @ 468 NONAME
+	_ZN30ec_cs_compare_certificate_id_cD0Ev @ 469 NONAME
+	_ZN30ec_cs_compare_certificate_id_cD1Ev @ 470 NONAME
+	_ZN30ec_cs_compare_certificate_id_cD2Ev @ 471 NONAME
+	_ZN34wapi_certificate_asn1_der_parser_c19read_certificate_idEP19eap_variable_data_c @ 472 NONAME
+	_ZN34wapi_certificate_asn1_der_parser_c19read_certificate_idEP19eap_variable_data_cS1_S1_ @ 473 NONAME
+	_ZN34wapi_certificate_asn1_der_parser_c6decodeEPK19eap_variable_data_c @ 474 NONAME
+	_ZN34wapi_certificate_asn1_der_parser_cC1EP18abs_eap_am_tools_c @ 475 NONAME
+	_ZN34wapi_certificate_asn1_der_parser_cC2EP18abs_eap_am_tools_c @ 476 NONAME
+	_ZN34wapi_certificate_asn1_der_parser_cD0Ev @ 477 NONAME
+	_ZN34wapi_certificate_asn1_der_parser_cD1Ev @ 478 NONAME
+	_ZN34wapi_certificate_asn1_der_parser_cD2Ev @ 479 NONAME
+	_ZN34wapi_message_wlan_authentication_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 480 NONAME
+	_ZN34wapi_message_wlan_authentication_c11reassociateEPK19eap_am_network_id_c31eapol_key_authentication_type_ePK19eap_variable_data_c @ 481 NONAME
+	_ZN34wapi_message_wlan_authentication_c12disassociateEPK19eap_am_network_id_cb @ 482 NONAME
+	_ZN34wapi_message_wlan_authentication_c12get_is_validEv @ 483 NONAME
+	_ZN34wapi_message_wlan_authentication_c12process_dataEPKvm @ 484 NONAME
+	_ZN34wapi_message_wlan_authentication_c12send_messageEP31eapol_handle_tlv_message_data_c @ 485 NONAME
+	_ZN34wapi_message_wlan_authentication_c13timer_expiredEmPv @ 486 NONAME
+	_ZN34wapi_message_wlan_authentication_c14disassociationEPK11eap_array_cI16eap_tlv_header_cE @ 487 NONAME
+	_ZN34wapi_message_wlan_authentication_c14packet_processEPK11eap_array_cI16eap_tlv_header_cE @ 488 NONAME
+	_ZN34wapi_message_wlan_authentication_c15process_messageEP31eapol_handle_tlv_message_data_c @ 489 NONAME
+	_ZN34wapi_message_wlan_authentication_c16check_bksa_cacheEPK11eap_array_cI16eap_tlv_header_cE @ 490 NONAME
+	_ZN34wapi_message_wlan_authentication_c17get_header_offsetEPmS0_ @ 491 NONAME
+	_ZN34wapi_message_wlan_authentication_c17timer_delete_dataEmPv @ 492 NONAME
+	_ZN34wapi_message_wlan_authentication_c18send_error_messageE12eap_status_e33eapol_tlv_message_type_function_e @ 493 NONAME
+	_ZN34wapi_message_wlan_authentication_c18state_notificationEPK28abs_eap_state_notification_c @ 494 NONAME
+	_ZN34wapi_message_wlan_authentication_c19start_reassociationEPK11eap_array_cI16eap_tlv_header_cE @ 495 NONAME
+	_ZN34wapi_message_wlan_authentication_c20complete_associationEPK11eap_array_cI16eap_tlv_header_cE @ 496 NONAME
+	_ZN34wapi_message_wlan_authentication_c20start_authenticationEPK11eap_array_cI16eap_tlv_header_cE @ 497 NONAME
+	_ZN34wapi_message_wlan_authentication_c20update_header_offsetEPK11eap_array_cI16eap_tlv_header_cE @ 498 NONAME
+	_ZN34wapi_message_wlan_authentication_c22complete_reassociationEPK11eap_array_cI16eap_tlv_header_cE @ 499 NONAME
+	_ZN34wapi_message_wlan_authentication_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 500 NONAME
+	_ZN34wapi_message_wlan_authentication_c26process_message_type_errorEPK11eap_array_cI16eap_tlv_header_cE @ 501 NONAME
+	_ZN34wapi_message_wlan_authentication_c37update_wlan_database_reference_valuesEPK11eap_array_cI16eap_tlv_header_cE @ 502 NONAME
+	_ZN34wapi_message_wlan_authentication_c8shutdownEv @ 503 NONAME
+	_ZN34wapi_message_wlan_authentication_c9associateE38eapol_key_802_11_authentication_mode_e @ 504 NONAME
+	_ZN34wapi_message_wlan_authentication_c9configureEmmm @ 505 NONAME
+	_ZN34wapi_message_wlan_authentication_cC1EP18abs_eap_am_tools_cP38abs_wapi_message_wlan_authentication_c @ 506 NONAME
+	_ZN34wapi_message_wlan_authentication_cC2EP18abs_eap_am_tools_cP38abs_wapi_message_wlan_authentication_c @ 507 NONAME
+	_ZN34wapi_message_wlan_authentication_cD0Ev @ 508 NONAME
+	_ZN34wapi_message_wlan_authentication_cD1Ev @ 509 NONAME
+	_ZN34wapi_message_wlan_authentication_cD2Ev @ 510 NONAME
+	_ZN37ec_cs_compare_certificate_reference_cC1EP18abs_eap_am_tools_c @ 511 NONAME
+	_ZN37ec_cs_compare_certificate_reference_cC2EP18abs_eap_am_tools_c @ 512 NONAME
+	_ZN37ec_cs_compare_certificate_reference_cD0Ev @ 513 NONAME
+	_ZN37ec_cs_compare_certificate_reference_cD1Ev @ 514 NONAME
+	_ZN37ec_cs_compare_certificate_reference_cD2Ev @ 515 NONAME
+	_ZN37ec_cs_compare_reference_issuer_name_cC1EP18abs_eap_am_tools_c @ 516 NONAME
+	_ZN37ec_cs_compare_reference_issuer_name_cC2EP18abs_eap_am_tools_c @ 517 NONAME
+	_ZN37ec_cs_compare_reference_issuer_name_cD0Ev @ 518 NONAME
+	_ZN37ec_cs_compare_reference_issuer_name_cD1Ev @ 519 NONAME
+	_ZN37ec_cs_compare_reference_issuer_name_cD2Ev @ 520 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c11associationEPK19eap_am_network_id_c @ 521 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c12cancel_timerEP20abs_eap_base_timer_cm @ 522 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c12get_is_validEv @ 523 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c14disassociationEPK19eap_am_network_id_c @ 524 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 525 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c14set_am_partnerEP33abs_wapi_am_wlan_authentication_c @ 526 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 527 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c17cancel_all_timersEv @ 528 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c19set_wlan_parametersEPK19eap_variable_data_cbS2_31eapol_key_authentication_type_e @ 529 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c22get_wlan_configurationEP19eap_variable_data_c @ 530 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c23authentication_finishedEb31eapol_key_authentication_type_e @ 531 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c24reset_wapi_configurationEv @ 532 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c8shutdownEv @ 533 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c9configureEv @ 534 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_c9set_timerEP20abs_eap_base_timer_cmPvm @ 535 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_cC1EP18abs_eap_am_tools_cbPK38abs_eapol_wlan_database_reference_if_c @ 536 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_cC2EP18abs_eap_am_tools_cbPK38abs_eapol_wlan_database_reference_if_c @ 537 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_cD0Ev @ 538 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_cD1Ev @ 539 NONAME
+	_ZN37wapi_am_wlan_authentication_symbian_cD2Ev @ 540 NONAME
+	_ZN39ec_cs_compare_certificate_issuer_name_cC1EP18abs_eap_am_tools_cPK19eap_variable_data_cS4_ @ 541 NONAME
+	_ZN39ec_cs_compare_certificate_issuer_name_cC2EP18abs_eap_am_tools_cPK19eap_variable_data_cS4_ @ 542 NONAME
+	_ZN39ec_cs_compare_certificate_issuer_name_cD0Ev @ 543 NONAME
+	_ZN39ec_cs_compare_certificate_issuer_name_cD1Ev @ 544 NONAME
+	_ZN39ec_cs_compare_certificate_issuer_name_cD2Ev @ 545 NONAME
+	_ZNK11ec_cs_tlv_c12get_payloadsEv @ 546 NONAME
+	_ZNK12ec_cs_data_c12get_is_validEv @ 547 NONAME
+	_ZNK12ec_cs_data_c13get_referenceEv @ 548 NONAME
+	_ZNK12ec_cs_data_c17get_change_statusEv @ 549 NONAME
+	_ZNK12ec_cs_data_c17get_is_valid_dataEv @ 550 NONAME
+	_ZNK12ec_cs_data_c7compareEPKS_ @ 551 NONAME
+	_ZNK12ec_cs_data_c8get_dataEv @ 552 NONAME
+	_ZNK12ec_cs_data_c8get_typeEv @ 553 NONAME
+	_ZNK13wai_message_c12get_is_validEv @ 554 NONAME
+	_ZNK13wai_message_c20get_wai_message_dataEv @ 555 NONAME
+	_ZNK13wai_message_c4copyEv @ 556 NONAME
+	_ZNK15asn1_der_type_c11get_contentEv @ 557 NONAME
+	_ZNK15asn1_der_type_c12get_is_validEv @ 558 NONAME
+	_ZNK15asn1_der_type_c12get_sub_typeEPK17asn1_type_const_c @ 559 NONAME
+	_ZNK15asn1_der_type_c13get_full_dataEv @ 560 NONAME
+	_ZNK15asn1_der_type_c13get_next_typeEv @ 561 NONAME
+	_ZNK15asn1_der_type_c13get_pc_stringEv @ 562 NONAME
+	_ZNK15asn1_der_type_c13get_sub_typesEv @ 563 NONAME
+	_ZNK15asn1_der_type_c14get_tag_stringEv @ 564 NONAME
+	_ZNK15asn1_der_type_c16get_class_stringEv @ 565 NONAME
+	_ZNK15asn1_der_type_c16get_extented_tagEPPKhPm @ 566 NONAME
+	_ZNK15asn1_der_type_c17get_header_lengthEv @ 567 NONAME
+	_ZNK15asn1_der_type_c17get_previous_typeEv @ 568 NONAME
+	_ZNK15asn1_der_type_c18get_content_lengthEv @ 569 NONAME
+	_ZNK15asn1_der_type_c20get_full_data_lengthEv @ 570 NONAME
+	_ZNK15asn1_der_type_c22get_count_of_sub_typesEv @ 571 NONAME
+	_ZNK15asn1_der_type_c25compare_object_identifierEPKcm @ 572 NONAME
+	_ZNK15asn1_der_type_c25compare_object_identifierEPKhm @ 573 NONAME
+	_ZNK15asn1_der_type_c6get_pcEv @ 574 NONAME
+	_ZNK15asn1_der_type_c7get_tagEv @ 575 NONAME
+	_ZNK15asn1_der_type_c9get_classEv @ 576 NONAME
+	_ZNK15asn1_der_type_c9get_indexEv @ 577 NONAME
+	_ZNK18ec_cs_completion_c21get_completion_actionEv @ 578 NONAME
+	_ZNK19wai_variable_data_c12get_is_validEv @ 579 NONAME
+	_ZNK19wai_variable_data_c13get_type_dataEm @ 580 NONAME
+	_ZNK19wai_variable_data_c14get_type_classEv @ 581 NONAME
+	_ZNK19wai_variable_data_c15get_data_lengthEv @ 582 NONAME
+	_ZNK19wai_variable_data_c15get_data_offsetEmm @ 583 NONAME
+	_ZNK19wai_variable_data_c16get_payload_typeEv @ 584 NONAME
+	_ZNK19wai_variable_data_c17get_is_valid_dataEv @ 585 NONAME
+	_ZNK19wai_variable_data_c18get_wai_tlv_headerEv @ 586 NONAME
+	_ZNK19wai_variable_data_c19get_full_tlv_bufferEv @ 587 NONAME
+	_ZNK19wai_variable_data_c20get_ec_cs_tlv_headerEv @ 588 NONAME
+	_ZNK19wai_variable_data_c20get_type_data_lengthEv @ 589 NONAME
+	_ZNK19wai_variable_data_c20get_type_data_offsetEmm @ 590 NONAME
+	_ZNK19wai_variable_data_c22get_type_header_lengthEv @ 591 NONAME
+	_ZNK19wai_variable_data_c27get_wai_payload_type_stringEv @ 592 NONAME
+	_ZNK19wai_variable_data_c35get_next_payload_with_same_tlv_typeEv @ 593 NONAME
+	_ZNK19wai_variable_data_c4copyEv @ 594 NONAME
+	_ZNK19wai_variable_data_c7compareEPKS_ @ 595 NONAME
+	_ZNK19wai_variable_data_c8get_dataEm @ 596 NONAME
+	_ZNK20ec_cs_tlv_payloads_c12get_is_validEv @ 597 NONAME
+	_ZNK20ec_cs_tlv_payloads_c13get_tlv_countEv @ 598 NONAME
+	_ZNK20ec_cs_tlv_payloads_c15get_tlv_pointerE16ec_cs_tlv_type_e @ 599 NONAME
+	_ZNK20ec_cs_tlv_payloads_c15get_tlv_pointerE16ec_cs_tlv_type_em @ 600 NONAME
+	_ZNK20ec_cs_tlv_payloads_c24check_payloads_existenseEPK11eap_array_cI16ec_cs_tlv_type_eE @ 601 NONAME
+	_ZNK20ec_cs_tlv_payloads_c24check_payloads_existenseEPK16ec_cs_tlv_type_em @ 602 NONAME
+	_ZNK20ec_cs_tlv_payloads_c24create_ec_cs_tlv_messageEP19ec_cs_tlv_message_cb @ 603 NONAME
+	_ZNK20ec_cs_tlv_payloads_c4copyEv @ 604 NONAME
+	_ZNK20ec_cs_tlv_payloads_c7get_tlvEm @ 605 NONAME
+	_ZNK21ec_cs_variable_data_c10get_headerEv @ 606 NONAME
+	_ZNK21ec_cs_variable_data_c12get_is_validEv @ 607 NONAME
+	_ZNK21ec_cs_variable_data_c15get_data_lengthEv @ 608 NONAME
+	_ZNK21ec_cs_variable_data_c15get_data_offsetEmm @ 609 NONAME
+	_ZNK21ec_cs_variable_data_c17get_is_valid_dataEv @ 610 NONAME
+	_ZNK21ec_cs_variable_data_c19get_full_tlv_bufferEv @ 611 NONAME
+	_ZNK21ec_cs_variable_data_c35get_next_payload_with_same_tlv_typeEv @ 612 NONAME
+	_ZNK21ec_cs_variable_data_c4copyEv @ 613 NONAME
+	_ZNK21ec_cs_variable_data_c7compareEPKS_ @ 614 NONAME
+	_ZNK21ec_cs_variable_data_c8get_dataEm @ 615 NONAME
+	_ZNK21ec_cs_variable_data_c8get_typeEv @ 616 NONAME
+	_ZNK22ec_certificate_store_c12get_is_validEv @ 617 NONAME
+	_ZNK22wai_message_payloads_c12get_is_validEv @ 618 NONAME
+	_ZNK22wai_message_payloads_c13get_tlv_countEv @ 619 NONAME
+	_ZNK22wai_message_payloads_c15get_tlv_pointerE18wai_payload_type_e @ 620 NONAME
+	_ZNK22wai_message_payloads_c15get_tlv_pointerE18wai_payload_type_em @ 621 NONAME
+	_ZNK22wai_message_payloads_c22create_wai_tlv_messageEP13wai_message_cb @ 622 NONAME
+	_ZNK22wai_message_payloads_c30get_wai_protocol_packet_headerEv @ 623 NONAME
+	_ZNK22wai_message_payloads_c4copyEv @ 624 NONAME
+	_ZNK22wai_message_payloads_c7get_tlvEm @ 625 NONAME
+	_ZNK22wapi_asn1_der_parser_c10get_objectEm @ 626 NONAME
+	_ZNK22wapi_asn1_der_parser_c12get_is_validEv @ 627 NONAME
+	_ZNK22wapi_asn1_der_parser_c16get_object_countEv @ 628 NONAME
+	_ZNK25eap_core_retransmission_c12get_eap_codeEv @ 629 NONAME
+	_ZNK25eap_core_retransmission_c12get_eap_typeEv @ 630 NONAME
+	_ZNK25eap_core_retransmission_c12get_is_validEv @ 631 NONAME
+	_ZNK25eap_core_retransmission_c15get_buffer_sizeEv @ 632 NONAME
+	_ZNK25eap_core_retransmission_c15get_data_lengthEv @ 633 NONAME
+	_ZNK25eap_core_retransmission_c15get_sent_packetEv @ 634 NONAME
+	_ZNK25eap_core_retransmission_c17get_header_offsetEv @ 635 NONAME
+	_ZNK25eap_core_retransmission_c18get_eap_identifierEv @ 636 NONAME
+	_ZNK25eap_core_retransmission_c26get_retransmission_counterEv @ 637 NONAME
+	_ZNK25ec_cs_compare_reference_c7compareEPK12ec_cs_data_cS2_ @ 638 NONAME
+	_ZNK26wapi_core_retransmission_c12get_is_validEv @ 639 NONAME
+	_ZNK26wapi_core_retransmission_c16get_wapi_subtypeEv @ 640 NONAME
+	_ZNK26wapi_core_retransmission_c19get_send_network_idEv @ 641 NONAME
+	_ZNK26wapi_core_retransmission_c20get_wai_message_dataEv @ 642 NONAME
+	_ZNK26wapi_core_retransmission_c26get_packet_sequence_numberEv @ 643 NONAME
+	_ZNK26wapi_core_retransmission_c26get_retransmission_counterEv @ 644 NONAME
+	_ZNK26wapi_core_retransmission_c29get_wai_received_message_dataEv @ 645 NONAME
+	_ZNK28ec_cs_compare_reference_id_c7compareEPK12ec_cs_data_cS2_ @ 646 NONAME
+	_ZNK29ec_am_algorithms_direct_nrc_c12get_is_validEv @ 647 NONAME
+	_ZNK30ec_cs_compare_certificate_id_c7compareEPK12ec_cs_data_cS2_ @ 648 NONAME
+	_ZNK34wapi_certificate_asn1_der_parser_c12get_is_validEv @ 649 NONAME
+	_ZNK34wapi_message_wlan_authentication_c34get_wlan_database_reference_valuesEP19eap_variable_data_c @ 650 NONAME
+	_ZNK37ec_cs_compare_certificate_reference_c7compareEPK12ec_cs_data_cS2_ @ 651 NONAME
+	_ZNK37ec_cs_compare_reference_issuer_name_c7compareEPK12ec_cs_data_cS2_ @ 652 NONAME
+	_ZNK39ec_cs_compare_certificate_issuer_name_c7compareEPK12ec_cs_data_cS2_ @ 653 NONAME
+	_ZTI11ec_cs_tlv_c @ 654 NONAME
+	_ZTI11wai_usksa_c @ 655 NONAME
+	_ZTI11wapi_core_c @ 656 NONAME
+	_ZTI12ec_cs_data_c @ 657 NONAME
+	_ZTI13wai_message_c @ 658 NONAME
+	_ZTI14wapi_strings_c @ 659 NONAME
+	_ZTI15asn1_der_type_c @ 660 NONAME
+	_ZTI15ec_cs_strings_c @ 661 NONAME
+	_ZTI16wai_tlv_header_c @ 662 NONAME
+	_ZTI17CWapiCertificates @ 663 NONAME
+	_ZTI17dummy_wapi_core_c @ 664 NONAME
+	_ZTI18ec_cs_completion_c @ 665 NONAME
+	_ZTI18ec_cs_tlv_header_c @ 666 NONAME
+	_ZTI19ec_cs_tlv_message_c @ 667 NONAME
+	_ZTI19wai_variable_data_c @ 668 NONAME
+	_ZTI19wapi_session_core_c @ 669 NONAME
+	_ZTI20ec_cs_tlv_payloads_c @ 670 NONAME
+	_ZTI20wapi_ethernet_core_c @ 671 NONAME
+	_ZTI21ec_cs_variable_data_c @ 672 NONAME
+	_ZTI21tls_peap_tlv_header_c @ 673 NONAME
+	_ZTI21wapi_am_crypto_sms4_c @ 674 NONAME
+	_ZTI22abs_ec_am_algorithms_c @ 675 NONAME
+	_ZTI22ec_certificate_store_c @ 676 NONAME
+	_ZTI22wai_message_payloads_c @ 677 NONAME
+	_ZTI22wapi_am_core_symbian_c @ 678 NONAME
+	_ZTI22wapi_asn1_der_parser_c @ 679 NONAME
+	_ZTI23ec_am_base_algorithms_c @ 680 NONAME
+	_ZTI25eap_core_retransmission_c @ 681 NONAME
+	_ZTI25ec_cs_compare_reference_c @ 682 NONAME
+	_ZTI26abs_ec_certificate_store_c @ 683 NONAME
+	_ZTI26wapi_core_retransmission_c @ 684 NONAME
+	_ZTI26wapi_wlan_authentication_c @ 685 NONAME
+	_ZTI27eap_am_file_input_symbian_c @ 686 NONAME
+	_ZTI27ec_base_certificate_store_c @ 687 NONAME
+	_ZTI28ec_cs_compare_reference_id_c @ 688 NONAME
+	_ZTI28wai_protocol_packet_header_c @ 689 NONAME
+	_ZTI29ec_am_algorithms_direct_nrc_c @ 690 NONAME
+	_ZTI29wapi_am_wlan_authentication_c @ 691 NONAME
+	_ZTI30ec_cs_compare_certificate_id_c @ 692 NONAME
+	_ZTI34wapi_certificate_asn1_der_parser_c @ 693 NONAME
+	_ZTI34wapi_message_wlan_authentication_c @ 694 NONAME
+	_ZTI37ec_cs_compare_certificate_reference_c @ 695 NONAME
+	_ZTI37ec_cs_compare_reference_issuer_name_c @ 696 NONAME
+	_ZTI37wapi_am_wlan_authentication_symbian_c @ 697 NONAME
+	_ZTI39ec_cs_compare_certificate_issuer_name_c @ 698 NONAME
+	_ZTV11ec_cs_tlv_c @ 699 NONAME
+	_ZTV11wai_usksa_c @ 700 NONAME
+	_ZTV11wapi_core_c @ 701 NONAME
+	_ZTV12ec_cs_data_c @ 702 NONAME
+	_ZTV13wai_message_c @ 703 NONAME
+	_ZTV14wapi_strings_c @ 704 NONAME
+	_ZTV15asn1_der_type_c @ 705 NONAME
+	_ZTV15ec_cs_strings_c @ 706 NONAME
+	_ZTV16wai_tlv_header_c @ 707 NONAME
+	_ZTV17CWapiCertificates @ 708 NONAME
+	_ZTV17dummy_wapi_core_c @ 709 NONAME
+	_ZTV18ec_cs_completion_c @ 710 NONAME
+	_ZTV18ec_cs_tlv_header_c @ 711 NONAME
+	_ZTV19ec_cs_tlv_message_c @ 712 NONAME
+	_ZTV19wai_variable_data_c @ 713 NONAME
+	_ZTV19wapi_session_core_c @ 714 NONAME
+	_ZTV20ec_cs_tlv_payloads_c @ 715 NONAME
+	_ZTV20wapi_ethernet_core_c @ 716 NONAME
+	_ZTV21ec_cs_variable_data_c @ 717 NONAME
+	_ZTV21tls_peap_tlv_header_c @ 718 NONAME
+	_ZTV21wapi_am_crypto_sms4_c @ 719 NONAME
+	_ZTV22abs_ec_am_algorithms_c @ 720 NONAME
+	_ZTV22ec_certificate_store_c @ 721 NONAME
+	_ZTV22wai_message_payloads_c @ 722 NONAME
+	_ZTV22wapi_am_core_symbian_c @ 723 NONAME
+	_ZTV22wapi_asn1_der_parser_c @ 724 NONAME
+	_ZTV23ec_am_base_algorithms_c @ 725 NONAME
+	_ZTV25eap_core_retransmission_c @ 726 NONAME
+	_ZTV25ec_cs_compare_reference_c @ 727 NONAME
+	_ZTV26abs_ec_certificate_store_c @ 728 NONAME
+	_ZTV26wapi_core_retransmission_c @ 729 NONAME
+	_ZTV26wapi_wlan_authentication_c @ 730 NONAME
+	_ZTV27eap_am_file_input_symbian_c @ 731 NONAME
+	_ZTV27ec_base_certificate_store_c @ 732 NONAME
+	_ZTV28ec_cs_compare_reference_id_c @ 733 NONAME
+	_ZTV28wai_protocol_packet_header_c @ 734 NONAME
+	_ZTV29ec_am_algorithms_direct_nrc_c @ 735 NONAME
+	_ZTV29wapi_am_wlan_authentication_c @ 736 NONAME
+	_ZTV30ec_cs_compare_certificate_id_c @ 737 NONAME
+	_ZTV34wapi_certificate_asn1_der_parser_c @ 738 NONAME
+	_ZTV34wapi_message_wlan_authentication_c @ 739 NONAME
+	_ZTV37ec_cs_compare_certificate_reference_c @ 740 NONAME
+	_ZTV37ec_cs_compare_reference_issuer_name_c @ 741 NONAME
+	_ZTV37wapi_am_wlan_authentication_symbian_c @ 742 NONAME
+	_ZTV39ec_cs_compare_certificate_issuer_name_c @ 743 NONAME
+	_ZThn12_N11wapi_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 744 NONAME
+	_ZThn12_N11wapi_core_c18state_notificationEPK28abs_eap_state_notification_c @ 745 NONAME
+	_ZThn12_N11wapi_core_c19set_session_timeoutEm @ 746 NONAME
+	_ZThn12_N11wapi_core_c20complete_create_ecdhEPK19eap_variable_data_cS2_ @ 747 NONAME
+	_ZThn12_N11wapi_core_c21complete_query_asu_idEPK19eap_variable_data_cS2_S2_12eap_status_e @ 748 NONAME
+	_ZThn12_N11wapi_core_c27complete_select_certificateEPK19eap_variable_data_cS2_S2_ @ 749 NONAME
+	_ZThn12_N11wapi_core_c28complete_get_own_certificateEPK19eap_variable_data_c @ 750 NONAME
+	_ZThn12_N11wapi_core_c31complete_read_id_of_certificateEPK19eap_variable_data_c @ 751 NONAME
+	_ZThn12_N11wapi_core_c35complete_create_ecdh_temporary_keysEPK19eap_variable_data_cS2_S2_ @ 752 NONAME
+	_ZThn12_N11wapi_core_c41complete_verify_signature_with_public_keyE12eap_status_e @ 753 NONAME
+	_ZThn12_N11wapi_core_c42complete_create_signature_with_private_keyEPK19eap_variable_data_c12eap_status_e @ 754 NONAME
+	_ZThn12_N11wapi_core_cD0Ev @ 755 NONAME
+	_ZThn12_N11wapi_core_cD1Ev @ 756 NONAME
+	_ZThn12_N19wapi_session_core_c12get_is_validEv @ 757 NONAME
+	_ZThn12_N19wapi_session_core_c12set_is_validEv @ 758 NONAME
+	_ZThn12_N19wapi_session_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 759 NONAME
+	_ZThn12_N19wapi_session_core_c8shutdownEv @ 760 NONAME
+	_ZThn12_N19wapi_session_core_c9configureEv @ 761 NONAME
+	_ZThn12_N19wapi_session_core_cD0Ev @ 762 NONAME
+	_ZThn12_N19wapi_session_core_cD1Ev @ 763 NONAME
+	_ZThn12_N22ec_certificate_store_c22query_certificate_listEv @ 764 NONAME
+	_ZThn12_N22ec_certificate_store_c24start_certificate_importEv @ 765 NONAME
+	_ZThn12_N22ec_certificate_store_c29add_imported_certificate_fileEPK19eap_variable_data_cS2_ @ 766 NONAME
+	_ZThn12_N22ec_certificate_store_c36complete_read_certificate_store_dataE12eap_status_e25ec_cs_pending_operation_ePK11eap_array_cI12ec_cs_data_cE @ 767 NONAME
+	_ZThn12_N22ec_certificate_store_c36remove_cached_certificate_store_dataEv @ 768 NONAME
+	_ZThn12_N22ec_certificate_store_c37complete_initialize_certificate_storeE27wapi_completion_operation_e @ 769 NONAME
+	_ZThn12_N22ec_certificate_store_c37complete_write_certificate_store_dataE12eap_status_e25ec_cs_pending_operation_e @ 770 NONAME
+	_ZThn12_N22ec_certificate_store_cD0Ev @ 771 NONAME
+	_ZThn12_N22ec_certificate_store_cD1Ev @ 772 NONAME
+	_ZThn16_N11wapi_core_c12cancel_timerEP20abs_eap_base_timer_cm @ 773 NONAME
+	_ZThn16_N11wapi_core_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 774 NONAME
+	_ZThn16_N11wapi_core_c19set_session_timeoutEm @ 775 NONAME
+	_ZThn16_N11wapi_core_c9set_timerEP20abs_eap_base_timer_cmPvm @ 776 NONAME
+	_ZThn16_N11wapi_core_cD0Ev @ 777 NONAME
+	_ZThn16_N11wapi_core_cD1Ev @ 778 NONAME
+	_ZThn28_N22wapi_am_core_symbian_c8shutdownEv @ 779 NONAME
+	_ZThn28_N22wapi_am_core_symbian_c9configureEv @ 780 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c11associationEPK19eap_am_network_id_c @ 781 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c12cancel_timerEP20abs_eap_base_timer_cm @ 782 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c12get_is_validEv @ 783 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c14disassociationEPK19eap_am_network_id_c @ 784 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 785 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c14set_am_partnerEP33abs_wapi_am_wlan_authentication_c @ 786 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 787 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c17cancel_all_timersEv @ 788 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c19set_wlan_parametersEPK19eap_variable_data_cbS2_31eapol_key_authentication_type_e @ 789 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c22get_wlan_configurationEP19eap_variable_data_c @ 790 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c23authentication_finishedEb31eapol_key_authentication_type_e @ 791 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c24reset_wapi_configurationEv @ 792 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c8shutdownEv @ 793 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c9configureEv @ 794 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_c9set_timerEP20abs_eap_base_timer_cmPvm @ 795 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_cD0Ev @ 796 NONAME
+	_ZThn28_N37wapi_am_wlan_authentication_symbian_cD1Ev @ 797 NONAME
+	_ZThn4_N11wapi_core_c13timer_expiredEmPv @ 798 NONAME
+	_ZThn4_N11wapi_core_c17timer_delete_dataEmPv @ 799 NONAME
+	_ZThn4_N11wapi_core_cD0Ev @ 800 NONAME
+	_ZThn4_N11wapi_core_cD1Ev @ 801 NONAME
+	_ZThn4_N19wapi_session_core_cD0Ev @ 802 NONAME
+	_ZThn4_N19wapi_session_core_cD1Ev @ 803 NONAME
+	_ZThn4_N20wapi_ethernet_core_c12get_is_validEv @ 804 NONAME
+	_ZThn4_N20wapi_ethernet_core_c12set_is_validEv @ 805 NONAME
+	_ZThn4_N20wapi_ethernet_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 806 NONAME
+	_ZThn4_N20wapi_ethernet_core_c8shutdownEv @ 807 NONAME
+	_ZThn4_N20wapi_ethernet_core_c9configureEv @ 808 NONAME
+	_ZThn4_N20wapi_ethernet_core_cD0Ev @ 809 NONAME
+	_ZThn4_N20wapi_ethernet_core_cD1Ev @ 810 NONAME
+	_ZThn4_N22ec_certificate_store_c11create_ecdhEPK19eap_variable_data_cS2_S2_ @ 811 NONAME
+	_ZThn4_N22ec_certificate_store_c12query_asu_idEv @ 812 NONAME
+	_ZThn4_N22ec_certificate_store_c18select_certificateEPK19eap_variable_data_c @ 813 NONAME
+	_ZThn4_N22ec_certificate_store_c18set_ae_certificateEPK19eap_variable_data_c @ 814 NONAME
+	_ZThn4_N22ec_certificate_store_c19get_own_certificateEv @ 815 NONAME
+	_ZThn4_N22ec_certificate_store_c22read_id_of_certificateEPK19eap_variable_data_c @ 816 NONAME
+	_ZThn4_N22ec_certificate_store_c22set_receive_network_idEPK19eap_am_network_id_c @ 817 NONAME
+	_ZThn4_N22ec_certificate_store_c26create_ecdh_temporary_keysEv @ 818 NONAME
+	_ZThn4_N22ec_certificate_store_c28initialize_certificate_storeEv @ 819 NONAME
+	_ZThn4_N22ec_certificate_store_c32verify_signature_with_public_keyEPK19eap_variable_data_cS2_S2_b @ 820 NONAME
+	_ZThn4_N22ec_certificate_store_c33create_signature_with_private_keyEPK19eap_variable_data_cS2_ @ 821 NONAME
+	_ZThn4_N22ec_certificate_store_c8shutdownEv @ 822 NONAME
+	_ZThn4_N22ec_certificate_store_c9configureEv @ 823 NONAME
+	_ZThn4_N22ec_certificate_store_cD0Ev @ 824 NONAME
+	_ZThn4_N22ec_certificate_store_cD1Ev @ 825 NONAME
+	_ZThn4_N26wapi_wlan_authentication_c11packet_sendEPK19eap_am_network_id_cP18eap_buf_chain_wr_cmmm @ 826 NONAME
+	_ZThn4_N26wapi_wlan_authentication_c12cancel_timerEP20abs_eap_base_timer_cm @ 827 NONAME
+	_ZThn4_N26wapi_wlan_authentication_c13get_is_clientEv @ 828 NONAME
+	_ZThn4_N26wapi_wlan_authentication_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 829 NONAME
+	_ZThn4_N26wapi_wlan_authentication_c15write_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 830 NONAME
+	_ZThn4_N26wapi_wlan_authentication_c17cancel_all_timersEv @ 831 NONAME
+	_ZThn4_N26wapi_wlan_authentication_c17get_header_offsetEPmS0_ @ 832 NONAME
+	_ZThn4_N26wapi_wlan_authentication_c18state_notificationEPK28abs_eap_state_notification_c @ 833 NONAME
+	_ZThn4_N26wapi_wlan_authentication_c23packet_data_session_keyEPK19eap_am_network_id_cPK19eapol_session_key_c @ 834 NONAME
+	_ZThn4_N26wapi_wlan_authentication_c9set_timerEP20abs_eap_base_timer_cmPvm @ 835 NONAME
+	_ZThn4_N26wapi_wlan_authentication_cD1Ev @ 836 NONAME
+	_ZThn4_N34wapi_message_wlan_authentication_c13timer_expiredEmPv @ 837 NONAME
+	_ZThn4_N34wapi_message_wlan_authentication_c17timer_delete_dataEmPv @ 838 NONAME
+	_ZThn4_N34wapi_message_wlan_authentication_cD0Ev @ 839 NONAME
+	_ZThn4_N34wapi_message_wlan_authentication_cD1Ev @ 840 NONAME
+	_ZThn4_NK22ec_certificate_store_c12get_is_validEv @ 841 NONAME
+	_ZThn8_N11wapi_core_c12get_is_validEv @ 842 NONAME
+	_ZThn8_N11wapi_core_c12set_is_validEv @ 843 NONAME
+	_ZThn8_N11wapi_core_c14packet_processEPK19eap_am_network_id_cP25eap_general_header_base_cm @ 844 NONAME
+	_ZThn8_N11wapi_core_c8shutdownEv @ 845 NONAME
+	_ZThn8_N11wapi_core_c9configureEv @ 846 NONAME
+	_ZThn8_N11wapi_core_cD0Ev @ 847 NONAME
+	_ZThn8_N11wapi_core_cD1Ev @ 848 NONAME
+	_ZThn8_N19wapi_session_core_c13timer_expiredEmPv @ 849 NONAME
+	_ZThn8_N19wapi_session_core_c17timer_delete_dataEmPv @ 850 NONAME
+	_ZThn8_N19wapi_session_core_cD0Ev @ 851 NONAME
+	_ZThn8_N19wapi_session_core_cD1Ev @ 852 NONAME
+	_ZThn8_N22ec_certificate_store_c14read_configureEPK25eap_configuration_field_cP19eap_variable_data_c @ 853 NONAME
+	_ZThn8_N22ec_certificate_store_c20complete_create_ecdhEPK19eap_variable_data_cS2_ @ 854 NONAME
+	_ZThn8_N22ec_certificate_store_c35complete_create_ecdh_temporary_keysEPK19eap_variable_data_cS2_S2_ @ 855 NONAME
+	_ZThn8_N22ec_certificate_store_c41complete_verify_signature_with_public_keyE12eap_status_e @ 856 NONAME
+	_ZThn8_N22ec_certificate_store_c42complete_create_signature_with_private_keyEPK19eap_variable_data_c12eap_status_e @ 857 NONAME
+	_ZThn8_N22ec_certificate_store_cD0Ev @ 858 NONAME
+	_ZThn8_N22ec_certificate_store_cD1Ev @ 859 NONAME
+	_ZThn8_N26wapi_wlan_authentication_c13timer_expiredEmPv @ 860 NONAME
+	_ZThn8_N26wapi_wlan_authentication_c17timer_delete_dataEmPv @ 861 NONAME
+	_ZThn8_N26wapi_wlan_authentication_cD1Ev @ 862 NONAME
+	_ZThn8_N34wapi_message_wlan_authentication_cD0Ev @ 863 NONAME
+	_ZThn8_N34wapi_message_wlan_authentication_cD1Ev @ 864 NONAME
+	_ZThn8_NK34wapi_message_wlan_authentication_c34get_wlan_database_reference_valuesEP19eap_variable_data_c @ 865 NONAME
+
Binary file eapol/eapol_framework/wapi_symbian/group/20021357.SPD has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/group/20021357.txt	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,14 @@
+;
+; Policy file to allow wapi database to be shared
+; Database backup not allowed
+;
+; \EPOC32\RELEASE\WINSCW\UDEB\EDBSPCONV.EXE /f=c:\20021357.txt /b=c:\20021357.spd
+; c: is Symbian specfic c drive (it is /epoc32\winscw\c for winscw paltform)
+;
+[database]
+read
+capability = ReadUserData WriteUserData
+write
+capability = ReadUserData WriteUserData
+schema
+capability = ReadUserData WriteUserData
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/group/bld.inf	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,45 @@
+/*
+* ============================================================================
+*  Name        : bld.inf
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : Build information file for project WAPI
+*  Version     : %version: 3 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+PRJ_EXPORTS
+
+// DBMS security policy file for storing WAPI database
+// WAPI database is not backed up for security reasons (contains plaintext private keys)
+20021357.SPD  /epoc32/data/z/private/100012a5/policy/20021357.SPD
+20021357.SPD  /epoc32/release/winscw/udeb/z/private/100012a5/policy/20021357.SPD
+20021357.SPD  /epoc32/release/winscw/urel/z/private/100012a5/policy/20021357.SPD
+
+// Exporting IBY file
+../rom/wapi.iby	CORE_MW_LAYER_IBY_EXPORT_PATH(wapi.iby) 
+
+// Copies WAPI configuration file to WLAN server private folder
+../wapi_core/symbian/file_config/wapi_symbian.conf  /epoc32/data/z/private/101F8EC5/wapi.conf
+
+PRJ_MMPFILES
+
+// This compiles WAPI implementation. You need special release to compile this.
+wapi.mmp
+wlanwapiif.mmp
+
+// End of file.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/group/wapi.mmh	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,69 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/group/wapi.mmh
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : Project definition file for project WAPI
+*  Version     : %version: 11 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1
+*/
+
+//-------------------------------------------------------------------
+
+// Set up the preprocessor macros for source files
+
+// This flag tells the 64-bit multiplication of platform can be used.
+MACRO USE_EAP_64_BIT_MULTIPLICATION
+
+// This is very important definition.
+MACRO EAP_LITTLE_ENDIAN=1
+
+//-------------------------------------------------------------------
+// This is used to enable configuring from file.
+MACRO USE_WAPI_FILECONFIG=1
+MACRO USE_EAP_FILECONFIG=1
+
+MACRO USE_EAP_EXPANDED_TYPES=1
+
+// Add this when database compatibility is not needed anymore.
+// This fixes some names of database fields.
+MACRO USE_WAPI_FIXED_DATABASE_FIELDS=1
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// This flag activates message based WLAN engine EAPOL interface.
+MACRO USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_IF
+#define USE_EAPOL_WLAN_AUTHENTICATION_MESSAGE_IF
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+MACRO USE_CERTIFICATE_STORE=1
+#define USE_CERTIFICATE_STORE
+
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+// This flag activates server codes of EAPOL
+MACRO USE_EAP_CORE_SERVER=1
+
+// These following macros should be adjusted depending on the test environment.
+// For WLM compatibility only NO_EAP_MUTEX should be defined.
+MACRO NO_EAP_MUTEX=1
+// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+MACRO USE_WAPI_CORE=1
+#define USE_WAPI_CORE
+MACRO USE_EC_CERTIFICATE_STORE=1
+#define USE_EC_CERTIFICATE_STORE
+
+MACRO USE_NRC_ECC_ALGORITHMS
+#define USE_NRC_ECC_ALGORITHMS
+
+MACRO WAPI_USE_CERTIFICATE_STORE=1
+#define WAPI_USE_CERTIFICATE_STORE
+
+//-------------------------------------------------------------------
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/group/wapi.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,152 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/group/wapi.mmp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : Project definition file for project WAPI
+*  Version     : %version: 34.1.4.1.4 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1
+*/
+
+
+//-------------------------------------------------------------------
+
+#include <platform_paths.hrh>
+#include "wapi.mmh"
+
+//-------------------------------------------------------------------
+CAPABILITY ALL -TCB
+VENDORID VID_DEFAULT
+
+TARGET			  wapi.dll
+TARGETTYPE		dll
+UID			      0x1000008d  0x2001B269
+
+///////////////////////////////////////////////////////////////////
+
+LANG	SC
+
+
+USERINCLUDE ../../eapol_symbian/am/type/symbian/plugin/include
+USERINCLUDE ../../eapol_symbian/am/common
+USERINCLUDE ../../eapol_common/am/common
+USERINCLUDE ../../eapol_symbian/am/include
+USERINCLUDE ../../eapol_common/am/include
+USERINCLUDE ../../eapol_common/include
+USERINCLUDE ../../eapol_common/type
+USERINCLUDE ../../eapol_common/am/common/DSS_random
+USERINCLUDE ../../eapol_common/type/tls_peap/tls/include
+
+#if defined(USE_NRC_ECC_ALGORITHMS)
+USERINCLUDE ../../wapi_common/ecc_library
+#endif //#if defined(USE_NRC_ECC_ALGORITHMS)
+
+USERINCLUDE ../../wapi_common/include/
+USERINCLUDE ../wlanwapiif/inc
+USERINCLUDE ../include
+USERINCLUDE ../../../../accesssec_plat/wapi_db_api/inc
+
+SYSTEMINCLUDE /epoc32/include/ecom
+SYSTEMINCLUDE /epoc32/include/kernel 
+SYSTEMINCLUDE /epoc32/include/libc
+SYSTEMINCLUDE /epoc32/include/libc/netinet
+
+SOURCEPATH ../../eapol_common/common/
+SOURCE  asn1_der_type.cpp
+
+SOURCEPATH	../../eapol_symbian/am/common/file_io/symbian
+SOURCE eap_am_file_input_symbian.cpp
+
+SOURCEPATH ../../eapol_common/core
+SOURCE eap_core_retransmission.cpp
+
+SOURCEPATH	../../eapol_symbian/am/common/symbian
+SOURCE eap_am_trace_symbian.cpp
+
+SOURCEPATH ../../wapi_common/src/
+SOURCE abs_ec_am_algorithms.cpp
+SOURCE abs_ec_certificate_store.cpp
+SOURCE ec_am_algorithms_direct_nrc.cpp
+SOURCE ec_am_base_algorithms.cpp
+SOURCE ec_base_certificate_store.cpp
+SOURCE ec_certificate_store.cpp
+SOURCE ec_cs_compare_certificate_id.cpp
+SOURCE ec_cs_compare_certificate_issuer_name.cpp
+SOURCE ec_cs_compare_certificate_reference.cpp
+SOURCE ec_cs_compare_reference_id.cpp
+SOURCE ec_cs_compare_reference.cpp
+SOURCE ec_cs_compare_reference_issuer_name.cpp
+SOURCE ec_cs_completion.cpp
+SOURCE ec_cs_data.cpp
+SOURCE ec_cs_strings.cpp
+SOURCE ec_cs_tlv.cpp
+SOURCE ec_cs_tlv_header.cpp
+SOURCE ec_cs_tlv_message.cpp
+SOURCE ec_cs_tlv_payloads.cpp
+SOURCE wai_message.cpp
+SOURCE wai_message_payloads.cpp
+SOURCE wai_protocol_packet_header.cpp
+SOURCE wai_tlv_header.cpp
+SOURCE wai_usksa.cpp
+SOURCE wai_variable_data.cpp
+SOURCE wapi_am_crypto_sms4.cpp
+SOURCE wapi_am_wlan_authentication.cpp
+SOURCE wapi_asn1_der_parser.cpp
+SOURCE wapi_certificate_asn1_der_parser.cpp
+SOURCE wapi_core.cpp
+SOURCE wapi_core_retransmission.cpp
+SOURCE wapi_ethernet_core.cpp
+SOURCE wapi_message_wlan_authentication.cpp
+SOURCE wapi_session_core.cpp
+SOURCE wapi_strings.cpp
+SOURCE wapi_wlan_authentication.cpp
+SOURCE dummy_wapi_core.cpp
+
+SOURCEPATH ../wapi_core/symbian
+SOURCE  wapi_am_core_symbian.cpp
+SOURCE  wapi_am_wlan_authentication_symbian.cpp
+SOURCE  certificate_store_db_symbian.cpp
+SOURCE 	WapiCertificates.cpp
+
+SOURCEPATH ../../eapol_common/type/tls_peap/tls/src
+SOURCE tls_peap_tlv_header.cpp
+
+#if defined(USE_NRC_ECC_ALGORITHMS)
+SOURCEPATH ../../wapi_common/ecc_library
+SOURCE nc_big.c
+SOURCE nc_drmeccp256.c
+SOURCE nc_gfp_ecc.c
+SOURCE nc_hash.c
+SOURCE nc_pkcs1_5.c
+SOURCE nc_prime.c
+SOURCE nc_rand.c
+SOURCE nc_sha1.c
+SOURCE nc_sha256.c
+SOURCE nc_sha512.c
+#endif //#if defined(USE_NRC_ECC_ALGORITHMS)
+
+MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers.
+
+LIBRARY		euser.lib ecom.lib eapol.lib efsrv.lib cone.lib
+LIBRARY		etelmm.lib etel.lib	// For ETel connection
+LIBRARY		hash.lib random.lib cryptography.lib asn1.lib
+LIBRARY   estor.lib edbms.lib // for RReadStream and RDbColReadStream
+LIBRARY   charconv.lib 
+LIBRARY   bafl.lib
+LIBRARY   estlib.lib // For memcmp, used in NRC ECC library.
+
+LIBRARY   wlandbif.lib
+
+
+MACRO USE_EAP_INTERFACE_EXPORTS
+//-------------------------------------------------------------------
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/group/wlanwapiif.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,73 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/group/wlanwapiif.mmp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : Project definition file for project WAPI
+*  Version     : %version: 9.1.3.1.2 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1
+*/
+
+
+//-------------------------------------------------------------------
+
+#include <platform_paths.hrh>
+#include "wapi.mmh"
+
+//-------------------------------------------------------------------
+CAPABILITY CAP_ECOM_PLUGIN
+TARGET wlanwapiif.dll
+TARGETTYPE    PLUGIN
+
+VENDORID VID_DEFAULT
+
+// ECom Dll recognition UID followed by the unique UID for this dll
+UID 0x10009D8D 0x2001959f
+
+///////////////////////////////////////////////////////////////////
+
+LANG	SC
+
+
+USERINCLUDE ../../eapol_symbian/am/type/symbian/plugin/include
+USERINCLUDE ../../eapol_symbian/am/common
+USERINCLUDE ../../eapol_common/am/common
+USERINCLUDE ../../eapol_symbian/am/include
+USERINCLUDE ../../eapol_common/am/include
+USERINCLUDE ../../eapol_common/include
+USERINCLUDE ../../eapol_common/type
+USERINCLUDE ../../eapol_common/am/common/DSS_random
+USERINCLUDE ../../wapi_common/include/
+USERINCLUDE ../wlanwapiif/inc
+USERINCLUDE ../include
+
+SYSTEMINCLUDE /epoc32/include/ecom
+SYSTEMINCLUDE /epoc32/include/kernel 
+SYSTEMINCLUDE /epoc32/include/libc
+SYSTEMINCLUDE /epoc32/include/libc/netinet
+
+SOURCEPATH ../wlanwapiif/src
+
+SOURCE  wlan_wapi_if_implementation.cpp
+
+SOURCEPATH ../wlanwapiif/data
+START RESOURCE 2001959f.rss
+TARGET wlanwapiif.rsc
+END
+
+MW_LAYER_SYSTEMINCLUDE // For the MiddleWare domain headers.
+
+MACRO USE_EAP_INTERFACE_EXPORTS
+
+LIBRARY euser.lib ECom.lib eapol.lib edbms.lib efsrv.lib wapi.lib
+//-------------------------------------------------------------------
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/include/WapiDbDefaults.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,50 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/include/WapiDbDefaults.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 6 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPIDBDEFAULTS_H_)
+#define _WAPIDBDEFAULTS_H_
+
+// LOCAL CONSTANTS
+
+#if !defined(USE_WAPI_FILECONFIG)
+	const TInt default_WAPI_TRACE_disable_traces = 0;
+	const TInt default_WAPI_TRACE_enable_function_traces = 0;
+	const TInt default_WAPI_TRACE_only_trace_messages = 0;
+	const TInt default_WAPI_TRACE_only_test_vectors = 0;
+#endif //#if !defined(USE_WAPI_FILECONFIG)
+
+_LIT(default_WAPI_TRACE_output_file_name, "c:\\logs\\wapi\\wapi_core.txt");
+
+#if !defined(USE_WAPI_FILECONFIG)
+	const TInt default_WAPI_CORE_session_timeout = 120000; // ms = 120 seconds = 2 minutes.
+	const TInt default_WAPI_CORE_starts_max_count = 3;		
+	const TInt default_WAPI_CORE_send_start_interval = 2000; // ms
+	const TInt default_WAPI_ERROR_TEST_enable_random_errors = 0;
+	const TInt default_WAPI_ERROR_TEST_send_original_packet_first = 0;
+	const TInt default_WAPI_ERROR_TEST_generate_multiple_error_packets = 2;
+	const TInt default_WAPI_ERROR_TEST_manipulate_ethernet_header = 0;
+	const TInt default_WAPI_ERROR_TEST_error_probability = 8000000;
+	const TInt default_WAPI_CORE_retransmission_counter = 0;
+#endif //#if !defined(USE_WAPI_FILECONFIG)
+		
+#endif // _WAPIDBDEFAULTS_H_
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/include/certificate_store_db_parameters.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,124 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/include/certificate_store_db_parameters.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 15 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+#if !defined(_CERTIFICATESTOREDBPARAMETERNAMES_H_)
+#define _CERTIFICATESTOREDBPARAMETERNAMES_H_
+
+
+// For the certificate store database.
+// Full path is not needed. The database certificatestore.dat will be saved in the 
+// data cage path for DBMS. So it will be in "\private\100012a5\certificatestore.dat" in C: drive.
+// The maximum length of database name is 0x40 (KDbMaxName) , which is defined in d32dbms.h.
+_LIT( KCsDatabaseName, "c:certificatestore.dat" );
+
+// For the security policy.
+_LIT( KSecureUidFormatCertificate, "SECURE[20021357]" ); 
+
+
+// Table names in certificate store
+_LIT( KCsGeneralSettingsTableName,  "cs_general_settings" );
+_LIT( KCsClientAsuIdListTableName,  "cs_client_asu_id_list" );
+_LIT( KCsCaAsuIdListTableName,      "cs_ca_asu_id_list" );
+_LIT( KCsClientCertificateTable,    "cs_client_certificate" );
+_LIT( KCsCaCertificateTable,        "cs_ca_certificate" );
+_LIT( KCsPrivateKeyTable,           "cs_private_key" );
+_LIT( KCsWapiCertLabelTable,        "wapi_cs_cert_labels" );
+_LIT( KCsWapiCertFileTable,         "wapi_cs_cert_files" );
+
+/**
+* Column names in general settings table.
+*/
+_LIT( KCsPassword, "CS_password" );
+_LIT( KCsReferenceCounter, "CS_reference_counter" );
+_LIT( KCsMasterKey, "CS_master_key" );
+_LIT( KCsInitialized, "CS_initialized" );
+_LIT( KCsPasswordMaxValidityTime, "CS_password_max_validity_time" );
+_LIT( KCsLastPasswordIdentityTime, "CS_password_last_identity_time" );
+
+/**
+* Column names in client ASU ID list table.
+*/ 
+_LIT( KCsClientAsuIdReference, "CS_client_ASU_ID_reference" );
+_LIT( KCsClientAsuIdData, "CS_client_ASU_ID_data" );
+
+/**
+* Column names in CA ASU ID list table.
+*/ 
+_LIT( KCsCaAsuIdReference, "CS_CA_ASU_ID_reference" );
+_LIT( KCsCaAsuIdData, "CS_CA_ASU_ID_data" );
+
+/**
+* Column names in client certificate table
+*/ 
+_LIT( KCsClientCertAsuIdReference, "CS_client_cert_ASU_ID_reference" );
+_LIT( KCsClientCertData, "CS_client_cert_data" );
+
+/**
+* Column names in CA certificate table
+*/ 
+_LIT( KCsCaCertAsuIdReference, "CS_CA_cert_ASU_ID_reference" );
+_LIT( KCsCaCertData, "CS_CA_cert_data" );
+
+/**
+* Column names in private key table
+*/ 
+_LIT( KCsPrivateKeyAsuIdReference, "CS_private_key_ASU_ID_reference" );
+_LIT( KCsPrivateKeyData, "CS_private_key_data" );
+
+/**
+* Column names in certificate label table for WAPI
+*/ 
+_LIT( KCsCertLabelAsuIdReference, "wapi_cs_cert_ASU_ID_reference" );
+_LIT( KCsCACertLabel, "CS_CA_cert_label" );
+_LIT( KCsUserCertLabel, "CS_user_cert_label" );
+
+/**
+* Column names in certificate file table for WAPI
+*/ 
+_LIT( KCsFileName, "CS_file_name" );
+
+/* Constants that define maximum column
+* lengths in CS DB.
+*/ 
+const TUint KCsMaxPasswordLengthInDb = 255;
+const TUint KCsMaxRefCounterLengthInDb = 255;
+const TUint KCsMaxMasterKeyLengthInDb = 255;
+const TUint KCsMaxAsuIdRefLengthInDb = 10;  // 5 digits -> unicode
+// maximum subject label length
+const TUint KCsMaxWapiCertLabelLength = 255; 
+// maximum lenght for the decoded identity in the db
+const TUint KCsMaxWapiCertLabelTableLength = 800;
+
+/**
+* Maximum length of SQL query in CS DB.
+*/ 
+const TUint KMaxSqlQueryLength = 512;
+
+/**
+* Constant defines default column number.
+*/ 
+const TInt KDefaultColumnNumberOne = 1; // For DB view.
+
+// The directory from where the certificates are imported
+_LIT8(KCertificateStoreImportDir, "c:\\data\\WAPI\\");
+// Max filesize for importable file
+const TUint KMaxCertificateFileSize = 4096;
+
+#endif // _CERTIFICATESTOREDBPARAMETERNAMES_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/include/certificate_store_db_symbian.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,621 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/include/certificate_store_db_symbian.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 38 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+#ifndef CERTIFICATESTOREDBSYMBIAN_H
+#define CERTIFICATESTOREDBSYMBIAN_H
+
+// INCLUDES
+#include <d32dbms.h>
+#include <e32cmn.h>
+#include <etelmm.h>
+#include <EapType.h>
+#include "eap_status.h"
+#include "certificate_store_db_parameters.h"
+#include "eap_expanded_type.h"
+#include "ec_cs_types.h"
+#include "eap_array.h"
+#include "WapiCertificates.h"
+
+// CONSTANTS
+const TInt KNumBytesForLimiters = 2;
+
+struct SWapiCertEntry
+{
+	HBufC8* iReference;	
+	HBufC8* iData;
+};
+
+// FORWARD DECLARATIONS
+class abs_eap_am_tools_c;
+class eap_variable_data_c;
+class wapi_am_core_symbian_c;
+
+// CLASS DECLARATION
+/**
+* Class implements certificate store functionality.
+*/
+NONSHARABLE_CLASS ( CCertificateStoreDatabase )
+    {
+    
+    private: // CS states
+    
+        /**
+        * State defines the type of service called.
+        */ 
+        enum TCertificateStoreState
+            {
+            ECertificateStoreNotInitialized,     /* 0 */
+            ECertificateStoreInitialized,        /* 1 */
+            // ...
+            ECertificateStoreStatesNumber        /* 2 */   // keep always as last element
+            };
+
+                
+    public:  // Constructors and destructor
+
+        /**
+        * Two-phased constructor.
+        * 
+        * @param aAmTools Pointer to adaptation module tools.
+        */
+        static CCertificateStoreDatabase* NewL(
+                abs_eap_am_tools_c* aAmTools );
+	
+        /**
+        * Destructor.
+        */
+        virtual ~CCertificateStoreDatabase();
+
+        
+    public:	// New, open/close/destroy functionality	
+		
+        /**
+        * Open certificate store database.
+        * 
+        * Database and tables are created.
+        * Method leaves if an error occurs.
+        */ 
+        void OpenCertificateStoreL();
+	
+        /**
+        * Close certificate DB and session.
+        */ 
+        void Close();	
+
+        /**
+        * Destroy certificate store.
+        * 
+        * @return General symbian error.
+        */ 
+	    TInt DestroyCertificateStore();
+	    
+        /**
+        * Set core partner.
+        * 
+        * This method is used to deliver pointer of core class.
+        */ 
+
+	    void SetCorePartner(wapi_am_core_symbian_c *partner);
+	    
+    public: // New 
+       
+	    /**
+	    * Function initializes the certificate store.
+	    * 
+	    * This function is completed by function call
+	    * complete_initialize_certificate_store() .
+	    */
+        void InitializeCertificateStoreL();
+
+	    /**
+	    * Function cancels all certificate_store store operations.
+	    */
+	    void CancelCertificateStoreStoreOperations();
+
+	
+    public: // New, get/set/remove data in database    
+        
+        /**
+        * Get data from CS by reference.
+        * 
+        * Memory is allocated inside the method.
+        * The caller is responsible for memory cleaning.
+        * Note that method can leave.
+        * @param aDataType Type of data (CA cert., client cert., or private key).
+        * @param aDataReference Reference used to search data.
+        * @param aOutColumnValue Returned column value. The caller is responsible
+        *                        for memory cleaning.
+        */ 
+        void GetCsDataByReferenceL( ec_cs_data_type_e aDataType,
+           	                        const TDesC8& aDataReference,
+       	                            HBufC8** aOutColumnValue );
+        
+        /**
+        * Get data from CS by int reference.
+        * 
+        * Memory is allocated inside the method.
+        * The caller is responsible for memory cleaning.
+        * Note that method can leave.
+        * @param aDataType Type of data (CA cert., client cert., or private key).
+        * @param aDataReference Reference used to search data.
+        * @param aOutColumnValue Returned column value. The caller is responsible
+        *                        for memory cleaning.
+        */ 
+        void GetCsDataByReferenceL( ec_cs_data_type_e aDataType,
+           	                        const TUint aDataReference,
+       	                            HBufC8** aOutColumnValue );
+        
+        /**
+        * Get data from CS by reference.
+        * 
+        * Memory is allocated inside the method.
+        * The caller is responsible for memory cleaning.
+        * Note that method can leave.
+        * @param aDataType Type of data to be searched in CS.
+        * @param aOutColumnValue Returned column value. The caller is responsible
+        *                        for memory cleaning.
+        */ 
+        void GetCsDataL( ec_cs_data_type_e aDataType,
+          	            HBufC8** aOutColumnValue,
+						RArray<SWapiCertEntry>& aArray,
+						TBool aGetAll);
+ 
+   
+        /**
+        * Set CS data by reference.
+        * 
+        * @param aDataType Type of data to be saved in CS.
+        * @param aColumnValue Reference to column value descriptor.
+        * @param aDataReference Reference used to search data.
+        * @param aIsNewEntry ETrue - insert new item,
+        *                    EFalse - update existing one.
+        */ 
+        void SetCsDataByReferenceL( ec_cs_data_type_e aDataType,
+        		                    const TDesC8& aColumnValue,
+        		                    const TDesC8& aDataReference,
+        		                    const TBool aIsNewEntry );
+
+        /**
+        * Set CS data by int reference.
+        * 
+        * @param aDataType Type of data to be saved in CS.
+        * @param aColumnValue Reference to column value descriptor.
+        * @param aDataReference Reference used to search data.
+        * @param aIsNewEntry ETrue - insert new item,
+        *                    EFalse - update existing one.
+        */ 
+        void SetCsDataByReferenceL( ec_cs_data_type_e aDataType,
+        		                    const TDesC8& aColumnValue,
+        		                    const TUint aDataReference,
+        		                    const TBool aIsNewEntry );
+
+
+        /**
+        * Set CS data.
+        * 
+        * @param aDataType Type of data to be saved in CS.
+        * @param aColumnValue Reference to column value descriptor.
+        * @param aIsNewEntry  ETrue - insert new item,
+        *                     EFalse - update existing one.
+        */ 
+        void SetCsDataL( ec_cs_data_type_e aDataType,
+        		         const TDesC8& aColumnValue,
+        		         const TBool aIsNewEntry );
+        
+        
+        /**
+        * Remove CS data by reference.
+        * 
+        * Method leaves if an error occurs.
+        * @param aDataType Type of data to be saved in CS.
+        * @param aColumnValue Reference to column value descriptor.
+        * @param aDataReference Reference used to search data.
+        */ 
+        void RemoveCsDataByReferenceL( ec_cs_data_type_e aDataType,
+                                       const TDesC8& aColumnValue,
+                                       const TDesC8& aDataReference );
+
+        /**
+        * Remove CS data by int reference.
+        * 
+        * Method leaves if an error occurs.
+        * @param aDataType Type of data to be saved in CS.
+        * @param aColumnValue Reference to column value descriptor.
+        * @param aDataReference Reference used to search data.
+        */ 
+        void RemoveCsDataByReferenceL( ec_cs_data_type_e aDataType,
+                                       const TDesC8& aColumnValue,
+                                       const TUint aDataReference );
+
+        /**
+        * Remove CS data by data type.
+        * 
+        * @param aDataType Type of data to be saved in CS.
+        * @param aColumnValue Reference to column value descriptor. 
+        */ 
+        void RemoveCsDataL( ec_cs_data_type_e aDataType,
+        	                const TDesC8& aColumnValue );
+        
+        /**
+        * Remove CS data by from table matching the id.
+        * 
+        * @param aTableName The table to be modified
+        * @param aReferenceName The reference column 
+        * @param aRefId The reference id 
+        */ 
+        void RemoveDataFromTableL( const TDesC& aTableName, const TDesC& aReferenceName, TUint aRefId  );
+        
+        /**
+        * Remove specific rows from all the AP specific tables.
+        * 
+        * @param aId The reference id (service table id )
+        */
+        void DeleteAPSpecificDataL( const TInt aId );
+        
+    public: // New, boolean conditions
+    
+	    /**
+        * Check if certificate store was initialized by common side.
+        * 
+        * @return ETrue - initilized, EFalse - not initialized.
+        */ 
+	    TBool IsInitializedL();
+	    		
+
+    public: // Access
+
+        /**
+        * Return reference to certificate store DB.
+        */ 
+        RDbNamedDatabase& GetCertificateStoreDb();
+    
+    public: // WAPI certificate label get/set functionality
+    		
+        /**
+        *  Set WAPI CA certificate identity KCsWapiCertLabelTable table, matching the id
+        */ 
+        void SetCACertL( const TInt aId, const TBuf8 <KMaxIdentityLength> aSelectedCert );
+        
+        /**
+        * Set WAPI user certificate identity to the KCsWapiCertLabelTable table, matching the id
+        */ 
+        void SetUserCertL( const TInt aId, const TBuf8 <KMaxIdentityLength> aSelectedCert);
+        
+        /**
+        * Set WAPI certificate identity to the KCsWapiCertLabelTable table for the
+        * given parameter, matching the id 
+        */ 
+        void SetCertL ( const TInt aId, const TBuf8<KMaxIdentityLength> aSelectedCert, 
+                 const TDesC& aParameterName );
+        
+        /**
+        * Get certificate labels set to the KCsWapiCertLabelTable table matching the id
+        */ 
+        void GetConfigurationL( const TInt aId, TDes& aCACert, TDes& aUserCert );
+        
+        /**
+        * Reads and decodes the label data from the given view
+        */ 
+        void ReadLabelTableL( RDbView& aView, TDes& aCert );
+        
+       
+        
+                                          
+    private: // New, database, tables
+	
+        /**
+        * Create CS database and all necessary tables.
+        * 
+        * Note that method can leave.
+        */
+	    void CreateCertificateStoreL();
+	    
+	    /**
+	    * Create CS database.
+	    * 
+	    * Note that method can leave.
+	    */ 
+	    void CreateDatabaseL();
+	    
+	    /**
+	    * Create table for general settings.
+	    * 
+	    * Create table for general settings, such as
+	    * CS password, reference counter, master key,
+	    * initialization flag, CS password max. validity time,
+	    * CS password last identity time, CS WAPI session max
+	    * validity time, CS WAPI session last full auth. time.
+	    * Note that method can leave.
+	    */ 
+	    void CreateGeneralSettingsTableL();	    	    
+	    
+	    /**
+	    * Create table that stores list of client ASU IDs.
+	    * 
+	    * Note that method can leave.
+	    */ 	    
+	    void CreateClientAsuIdListTableL();
+	    
+	    /**
+	    * Create table that stores list of CA ASU IDs.
+	    * 
+	    * Note that method can leave.
+	    */ 
+	    void CreateCaAsuIdListTableL();
+	    
+	    /*
+	    * Create table that stores list of client certificate data.
+	    * 
+	    * Note that method can leave.
+	    */ 
+	    void CreateClientCertificateTableL();
+	    
+	    /**
+	    * Create table that stores list of CA certificate data.
+	    * 
+	    * Note that method can leave.
+	    */ 
+	    void CreateCaCertificateTableL();
+	    
+	    /**
+	    * Create table that stores list of private key data.
+	    * 
+	    * Note that method can leave.
+	    */ 
+	    void CreatePrivateKeyTableL();
+	    
+	    /**
+	    * Create table that stores the WAPI certificate labels
+	    */ 
+	    void CreateWapiCertLabeltableL();
+	    
+	    /**
+	     * Create table that stores the WAPI certificate files
+	    */ 
+        void CreateWapiCertFiletableL();
+
+    private: // Operations with RDbView rowset  
+
+        /**
+	    * Get long binary data.
+	    * 
+	    * Read long binary data using stream from DB view.
+	    * Note that the caller is responsible for memory cleaning.
+	    * Note that method can leave.
+	    * @param aView Reference to rowsets from an SQL query
+	    * @param aOutColumnValue Returned column value. Memory is allocated
+	    *                        inside the method.
+	    */ 
+	    void GetLongBinaryDataL( RDbView& aView, HBufC8** aOutColumnValue );
+	
+        /**
+	    * Get binary data.
+	    * 
+	    * Read binary data from DB view.
+	    * Note that the caller is responsible for memory cleaning.
+	    * Note that method can leave.
+	    * @param aView Reference to rowsets from an SQL query.
+	    * @param aOutColumnValue Returned column value. Memory is allocated
+	    *                        inside the method.
+	    */ 
+	    void GetBinaryDataL( RDbView& aView, HBufC8** aOutColumnValue );
+	
+        /**
+	    * Get binary data.
+	    * 
+	    * Read binary data from DB view.
+	    * Note that the caller is responsible for memory cleaning.
+	    * Note that method can leave.
+	    * @param aView Reference to rowsets from an SQL query.
+	    * @param aArray Returned column values. Memory is allocated
+	    *                        inside the method.
+	    */ 
+		void GetTableDataL( RDbView& aView, RArray<SWapiCertEntry>& aArray );
+								
+        /**
+        * Insert data and reference to view.
+        * 
+        * Note that method can leave.
+        * @param aView Reference to rowset from SQL query.
+        * @param aReferenceColumnName Column name for reference.
+        * @param aDataColumnName Column name for data.
+        * @param aDataReference16 Reference to descriptor containing
+        *                         data reference value in unicode.
+        * @param aColumnValue Reference to descriptor containing column value.
+        */ 
+        void InsertDataAndReferenceL( RDbView& aView,
+                                      const TDesC& aReferenceColumnName,
+                                      const TDesC& aDataColumnName,
+                                      const TDesC16& aDataReference16,
+                                      const TDesC8& aColumnValue );
+        
+        /**
+        * Insert data and reference to view.
+        * 
+        * Note that method can leave.
+        * @param aView Reference to rowset from SQL query.
+        * @param aReferenceColumnName Column name for reference.
+        * @param aDataColumnName Column name for data.
+        * @param aDataRef Reference to the row to be modified
+        * @param aColumnValue Reference to descriptor containing column value.
+        */
+        void InsertDataAndReferenceL( RDbView& aView,
+                                      const TDesC& aReferenceColumnName,
+                                      const TDesC& aDataColumnName,
+                                      const TUint aDataRef,
+                                      const TDesC8& aColumnValue );
+        
+        /**
+        * Insert data and reference to view.
+        * 
+        * Note that method can leave.
+        * @param aView Reference to rowset from SQL query.
+        * @param aReferenceColumnName Column name for reference.
+        * @param aDataColumnName Column name for data.
+        * @param aDataRef Reference to the row to be modified
+        * @param aColumnValue Reference to descriptor containing column value.
+        */
+        void InsertDataAndReferenceL( RDbView& aView,
+                                      const TDesC& aReferenceColumnName,
+                                      const TDesC& aDataColumnName,
+                                      const TUint aDataRef,
+                                      const TDesC& aColumnValue );
+
+        /**
+        * Insert data value to view.
+        * 
+        * Note that method can leave.
+        * @param aView Reference to rowset from SQL query.
+        * @param aDataColumnName Column name for data.
+        * @param aColumnValue Reference to descriptor containing column value.
+        */ 
+		void InsertDataL( RDbView& aView,
+				          const TDesC& aDataColumnName,
+				          const TDesC8& aColumnValue );		
+
+        /**
+        * Update view with specified column value.
+        * 
+        * There should be only one-row-one-column in view.
+        * Note that method can leave.
+        * @param aView Reference to rowset from SQL query.
+        * @param aColumnValue Reference to descriptor containg column value.
+        */ 
+        void UpdateColOneRowOneL( RDbView& aView,
+        		                  const TDesC8& aColumnValue );
+        
+
+    private: // Other
+
+        /**
+        * Convert from utf8 to unicode.
+        * 
+        * Note that the caller is responsible for memory cleaning.
+        * Note that method can leave.
+        * @param aInBuf Const reference to the input buffer.
+        * @param aOutBuf Returned converted buffer, memory is allocated inside
+        *                the method. 
+        */
+        void ConvertFromBuf8ToBuf16LC( const TDesC8& aInBuf8, HBufC16** aOutBuf16 );
+
+        /**
+        * Convert from unicode to utf8.
+        * 
+        * Note that the caller is responsible for memory cleaning.
+        * Note that method can leave.
+        * @param aInBuf Const reference to the input buffer.
+        * @param aOutBuf Returned converted buffer, memory is allocated inside
+        *                the method. 
+        */
+        void ConvertFromBuf16ToBuf8LC( const TDesC16& aInBuf16, HBufC8** aOutBuf8 );
+
+	    /**
+        * Writes certificate store state in CS database.
+        * 
+	    * If CS object is deleted, the state can be recovered
+	    * from database.
+	    * Note that method can leave.
+	    * @param aState Parameter defines CS state.
+	    */ 
+        void WriteCertificateStoreStateL( TCertificateStoreState aState );	    
+    
+	    /**
+	    * Get database names.
+	    *  
+	    * According to data type, return table, reference and data
+	    * column names.
+	    * Note that method can leave.
+	    * @param aDataType Certificate store data types.
+	    * @param aTableName Table name.
+	    * @param aReferenceColumnName Column name of reference.
+	    * @param aDataColumnName Column name of data.
+	    */ 
+	    void GetDbNamesFromDataTypeL( ec_cs_data_type_e aDataType,
+	     		                      TDes& aTableName,
+	     		                      TDes& aReferenceColumnName,
+	     		                      TDes& aDataColumnName );
+	     
+	     /**
+	     * Get database names.
+	     *  
+	     * According to data type, return table and data
+	     * column names.
+	     * Note that method can leave.
+	     * @param aDataType Certificate store data types.
+	     * @param aTableName Table name.
+	     * @param aDataColumnName Column name of data.
+	     */ 
+	     void GetDbNamesFromDataTypeL( ec_cs_data_type_e aDataType,
+	      		                       TDes& aTableName,
+	                                   TDes& aDataColumnName );
+
+	      
+    private: // Private constructors
+
+        /**
+        * C++ default constructor.
+        */
+        CCertificateStoreDatabase( abs_eap_am_tools_c* aAmTools );
+        
+        /**
+        * By default Symbian 2nd phase constructor is private.
+        */
+        void ConstructL();
+	
+        
+    private: // Data
+	
+        /**
+        * State defines the type of the requested service.
+        */ 
+	    TCertificateStoreState iState;	
+	
+        /**
+        * Generic database implementation.
+        */ 
+	    RDbNamedDatabase iCsDb;
+
+        /**
+        * Represents a session with the DBMS server.
+        */ 
+	    RDbs iCsDbSession;	
+	
+        /**
+        * ETrue - CS created, EFalse - not.
+        */ 
+	    TBool iCsDbCreated;
+	    
+        /**
+        * ETrue - CS session opened, EFalse - not.
+        */ 
+	    TBool iCsSessionOpened;
+	
+        /**
+        * Adaptation module tools.
+        */ 
+	    abs_eap_am_tools_c* iAmTools;
+	    
+		// pointer to core class, to provide method interface	   
+        wapi_am_core_symbian_c *iPartner;
+		
+    }; // NONSHARABLE_CLASS ( CCertificateStoreDatabase )
+
+#endif // CERTIFICATESTOREDBSYMBIAN_H
+
+// End of file.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/include/wapi_am_core_symbian.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,775 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/include/wapi_am_core_symbian.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 41.2.1.1.2 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+
+#if !defined(_WAPI_AM_CORE_SYMBIAN_H_)
+#define _WAPI_AM_CORE_SYMBIAN_H_
+
+// INCLUDES
+#include <d32dbms.h>
+#include <e32cmn.h>
+#include <etelmm.h>
+#include <wdbifwlansettings.h>
+#include "eapol_key_types.h"
+#include "wapi_am_base_core.h"
+#include "ec_am_base_certificate_store.h"
+#include "wapi_types.h"
+#include "eap_am_trace_symbian.h"
+#include "abs_wapi_am_core.h"
+#include "abs_ec_am_certificate_store.h"
+#include "certificate_store_db_symbian.h"
+
+// FORWARD DECLARATIONS
+class eap_am_tools_symbian_c;
+class eap_file_config_c;
+class abs_ec_am_base_certificate_store_c;
+class abs_wapi_am_base_core_c;
+class CCertificateStoreDatabase;
+
+const TInt KMaxWPAPSKPasswordLength = 64;
+const TInt KWPAPSKLength = 32;
+const TInt KCsMaxWapiCertLabelLen = 255;
+
+
+// CLASS DECLARATION
+class wapi_am_core_symbian_c
+    :  public CActive,
+    public wapi_am_base_core_c,
+	public abs_eap_base_timer_c
+
+{
+private: // AO states
+    /**
+    * Possible states of active object, which are
+    * used in asynch. requests.
+    */ 
+    enum TWapiState 
+	    {
+	    EWapiHandlingDeviceSeedQueryState,  /* 0 */
+#if defined( WAPI_USE_UI_NOTIFIER )   		    
+	    EWapiQueryCertFilePasswordState,
+	    EWapiQueryImportFilePasswordState,
+#endif   		    
+	    EWapiStatesNumber                   /*  */ // keep always as last element
+	    };
+
+public:
+
+    virtual ~wapi_am_core_symbian_c();	
+	
+	///////////////////////////////////////////////////////////////
+	/* These are called from WLM via CEapol */
+
+	static wapi_am_core_symbian_c * NewL(
+		abs_eap_am_tools_c *const,
+		abs_wapi_am_core_c* const aPartner,
+		const bool aIsClient);
+	
+	
+   static wapi_am_core_symbian_c * NewL(
+		abs_eap_am_tools_c *const,
+        abs_wapi_am_core_c* const aPartner,
+        CCertificateStoreDatabase* aCertificateStoreDb,
+        const bool aIsClient);
+
+   /**
+   * The shutdown() function is called before the destructor of the 
+   * object is executed. During the function call the object 
+   * could shutdown the operations, for example cancel timers.
+   * Each derived class must define this function.
+   */
+   EAP_FUNC_EXPORT eap_status_e shutdown();
+
+   /** Function sets partner object of adaptation module of certificate store.
+	 *  Partner object is the certificate store object.
+	 */
+	void set_am_certificate_store_partner(abs_ec_am_certificate_store_c * const partner);
+
+	eap_status_e set_timer(
+		abs_eap_base_timer_c * const p_initializer, 
+		const u32_t p_id, 
+		void * const p_data,
+		const u32_t p_time_ms);
+
+	eap_status_e cancel_timer(
+		abs_eap_base_timer_c * const p_initializer, 
+		const u32_t p_id);
+
+	eap_status_e cancel_all_timers();
+
+	eap_status_e timer_expired(const u32_t id, void *data);
+
+	eap_status_e timer_delete_data(const u32_t id, void *data);
+	
+  /**
+	* Import is completed and list of available certs can be read
+	*/ 
+	eap_status_e complete_start_certificate_import();
+	    
+	/**
+	* Interface function for calling the function to store the lists of available certificates
+	*/ 
+	eap_status_e complete_query_certificate_list(
+		EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const ca_certificates,
+		EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const user_certificates);
+	
+	/**
+	 * Store received lists of available certificates
+	 */ 
+	eap_status_e complete_query_certificate_listL(
+	    EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const ca_certificates,
+	    EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const user_certificates);
+  
+	/**
+	 * This is called by WapiCertificates module used by the UI.
+	 * It gets the available certificate labels
+	 */ 
+  void GetAllCertificateLabelsL( RArray<TBuf<KCsMaxWapiCertLabelLen> > **aUserCerts,
+                                      RArray<TBuf<KCsMaxWapiCertLabelLen> > **aCACerts,
+                                      RArray<TBuf8<KMaxIdentityLength> > **aUserCertsData,
+                                      RArray<TBuf8<KMaxIdentityLength> > **aCACertsData,
+                                      TRequestStatus& aStatus);
+
+  /** Client calls this function.
+    *  WAPI AM erases imported certificates list & other vital things.
+    */
+    EAP_FUNC_IMPORT eap_status_e reset();
+
+protected:
+	
+	wapi_am_core_symbian_c(
+			abs_eap_am_tools_c *const,
+			abs_wapi_am_core_c * const aPartner,
+		const bool is_client_when_true);
+	
+	   wapi_am_core_symbian_c(
+			abs_eap_am_tools_c *const,
+			abs_wapi_am_core_c * const aPartner,
+	        CCertificateStoreDatabase* aCertificateStoreDb,
+	        const bool is_client_when_true);
+	   
+	
+	void ConstructL();
+
+	
+    protected: // from CActive
+    
+        /**
+        * RunL from CActive
+        */    
+	    void RunL();
+
+	    /**
+        * DoCancel from CActive
+        */    
+	    void DoCancel();
+
+
+    protected: // from wapi_am_base_core_c
+    
+
+	    /***************************************/
+	    /* from wapi_am_base_core_c */
+	    /***************************************/
+	
+	    EAP_FUNC_IMPORT abs_wapi_am_core_c * get_am_partner();
+	
+        /** Function sets partner object of adaptation module of WAPI.
+	    *  Partner object is the WAPI core object.
+	    */
+	    EAP_FUNC_IMPORT void set_am_partner(abs_wapi_am_core_c * const partner);
+
+	    EAP_FUNC_IMPORT eap_status_e configure();
+
+	    EAP_FUNC_IMPORT bool get_is_valid();
+
+	    /** Client calls this function.
+	    *  WAPI AM could make some fast operations here, heavy operations should be done in the reset() function.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e authentication_finished(
+		    const bool true_when_successfull);
+
+	    /**
+	    * The type_configure_read() function reads the configuration data identified
+	    * by the field string of field_length bytes length. Adaptation module must direct
+	    * the query to some persistent store.
+	    * @param field is generic configure string idenfying the required configure data.
+	    * @param field_length is length of the field string.
+	    * @param data is pointer to existing eap_variable_data object.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e type_configure_read(
+		    const eap_configuration_field_c * const field,
+		    eap_variable_data_c * const data);
+
+        /**
+	    * The type_configure_write() function writes the configuration data identified
+	    * by the field string of field_length bytes length. Adaptation module must direct
+	    * the action to some persistent store.
+	    * @param field is generic configure string idenfying the required configure data.
+	    * @param field_length is length of the field string.
+	    * @param data is pointer to existing eap_variable_data object.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e type_configure_write(
+		    const eap_configuration_field_c * const field,
+		    eap_variable_data_c * const data);
+
+	    
+    protected: // from ec_am_base_certificate_store_c
+
+    
+	    /***************************************/
+	    /* from ec_am_base_certificate_store_c */
+	    /***************************************/
+	
+	    /**
+        * Function initializes the certificate store.
+	    * This function is completed by complete_initialize_certificate_store() function call.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e initialize_certificate_store(
+		    const wapi_completion_operation_e completion_operation);
+
+	    /**
+	    * Function reads the certificate store data referenced by parameter in_references.
+	    * This function is completed by complete_read_certificate_store_data() function call.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e read_certificate_store_data(
+		    const ec_cs_pending_operation_e in_pending_operation,
+		    EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references);
+
+	    /**
+	    * Function writes the certificate store data referenced by parameter in_references_and_data_blocks.
+	    * This function is completed by complete_write_certificate_store_data() function call.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e write_certificate_store_data(
+		    const bool when_true_must_be_synchronous_operation,
+		    const ec_cs_pending_operation_e in_pending_operation,
+		    EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references_and_data_blocks);
+
+	    /**
+	    * Function completes the add_imported_certificate_file() function call.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e complete_add_imported_certificate_file(
+		    const eap_status_e in_completion_status,
+		    const eap_variable_data_c * const in_imported_certificate_filename);
+
+	    /**
+	    * Function completes the remove_certificate_store() function call.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e complete_remove_certificate_store(
+		    const eap_status_e in_completion_status);
+
+	    /**
+	    * Function cancels all certificate_store store operations.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e cancel_certificate_store_store_operations();
+
+	    /**
+	    * The set_session_timeout() function changes the session timeout timer to be elapsed after session_timeout_ms milliseconds.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e set_session_timeout(
+		    const u32_t session_timeout_ms);
+
+	    /**
+	    * This is notification of internal state transition.
+	    * This is used for notifications, debugging and protocol testing.
+	    * The primal notifications are eap_state_variable_e::eap_state_authentication_finished_successfully
+	    * and eap_state_variable_e::eap_state_authentication_terminated_unsuccessfully. EAP-type MUST send these
+	    * two notifications to lower layer.
+	    * These two notifications are sent using EAP-protocol layer (eap_protocol_layer_e::eap_protocol_layer_eap).
+	    * See also eap_state_notification_c.
+	    */
+	    EAP_FUNC_IMPORT void state_notification(
+		    const abs_eap_state_notification_c * const state);
+
+	    /**
+	    * The read_configure() function reads the configuration data identified
+	    * by the field string of field_length bytes length. Adaptation module must direct
+	    * the query to some persistent store.
+	    * @param field is generic configure string idenfying the required configure data.
+	    * @param field_length is length of the field string.
+	    * @param data is pointer to existing eap_variable_data object.
+	    * 
+	    * EAP-type should store it's parameters to an own database. The own database should be accessed
+	    * through adaptation module of EAP-type. See eap_am_type_tls_peap_simulator_c::type_configure_read.
+	    */
+	    EAP_FUNC_IMPORT eap_status_e read_configure(
+		    const eap_configuration_field_c * const field,
+		    eap_variable_data_c * const data);
+	
+	    
+    private: // New, timer expired process methods
+    
+        /**
+        * Process initialize-certificate-store request.
+        * 
+        * @return EAP status.
+        */ 
+        eap_status_e ProcessInitCertificateStore();
+
+        /**
+        * Process add-certificate-file request.
+        * 
+        * @return EAP status.
+        */ 
+        eap_status_e ProcessAddCertificateFile();
+
+        /**
+        * Process read-certificate-store-data request.
+        * 
+        * @return EAP status.
+        */ 
+        eap_status_e ProcessReadCertificateStoreData();
+        
+        /**
+        * Process write-certificate-store-data request.
+        * 
+        * @return EAP status.
+        */ 
+        eap_status_e ProcessWriteCertificateStoreData();
+     	
+
+    private: // New, writing to CS
+
+        /**
+        * Write data to certificate store.
+        * Method leaves if an error occurs.
+        */ 
+        void WriteCertificateStoreDataL();
+        
+        /**
+        * Write certificate store data with reference.
+        * 
+        * Method re-delivers writing request to certificate store.
+        * Method leaves if an error occurs.
+        * 
+        * @param aDataReference Certificate store data item.
+        * @param aIsNewEntry ETrue - new entry, EFalse - otherwise.
+        */ 
+	    void WriteCsDataWithReferenceL(
+	    	const ec_cs_data_c* const aDataReference,
+            TBool aIsNewEntry );				    
+
+	    /**
+	    * Write certificate store data.
+        *
+        * Method re-delivers writing request to certificate store.
+        * Method leaves if an error occurs.
+        * 
+        * @param aData Certificate store data item.
+        * @param aIsNewEntry ETrue - new entry, EFalse - otherwise.
+	    */ 
+        void WriteCsDataL(
+        	const ec_cs_data_c* const aData,
+        	TBool aIsNewEntry );
+        
+        /**
+        * Delete certificate store data item found by reference.
+        * 
+        * Method leaves if an error occurs.
+        * 
+        * @param aDataReference Data reference used to search data in the table.
+        */ 
+        void DeleteCsDataWithReferenceL(
+        	const ec_cs_data_c* const aDataReference );
+        
+
+    private: // New, reading from CS
+    
+        /**
+        * Read data from certificate store.
+        * Method leaves if an error occurs.
+        */ 
+        void ReadCertificateStoreDataL();
+        
+        /**
+        * Read data using reference from certificate store.
+        * 
+        * Method takes care about elegant cleaning of memory 
+        * allocated by CS and adding new data item to EAP array.
+        * Method leaves if an error occurs.
+        * 
+        * @param aDataReference Data reference used to search data in the table.
+        */ 
+        void ReadCsDataByReferenceL(
+        	const ec_cs_data_c* const aDataReference );
+          
+        /**
+        * Read specified data type from certificate store.
+        * 
+        * Method takes care about elegant cleaning of memory 
+        * allocated by CS and adding new data item to EAP array.
+        * Method leaves if an error occurs.
+        * 
+        * @param aDataReference Data reference used to search data in the table.
+        */ 
+        void ReadCsDataL( const ec_cs_data_c* const aDataReference );
+
+        /**
+        * Get certificate store data by reference.
+        * 
+        * Method re-delivers reading request to certificate store.
+        * Memory for returned buffer is allocated by CS.
+        * Memory ownership is transfered to the caller.
+        * Note that the method can leave.
+        * 
+        * @param aDataReference Reference used to search data.
+        * @param aOutColumnValue Returned data buffer.
+        */ 
+        void GetCsDataByReferenceL(
+        	const ec_cs_data_c* const aDataReference,
+        	HBufC8** aOutColumnValue ); 
+        
+        /**
+        * Get certificate store data by data type.
+        *
+        * Method re-delivers reading request to certificate store.
+        * Memory for returned buffer is allocated by CS.
+        * Memory ownership is transfered to the caller.
+        * Method leaves if an error occurs.
+        * 
+        * @param aDataType Type of data used to search data in table.
+        * @param aOutColumnValue Returned data buffer.
+        */ 
+        void GetCsDataL( ec_cs_data_type_e aDataType,
+          	             HBufC8** aOutColumnValue );
+
+        /**
+        * Get certificate store table by data type.
+        *
+        * Method re-delivers reading request to certificate store.
+        * Memory for returned buffer is allocated by CS.
+        * Memory ownership is transfered to the caller.
+        * Method leaves if an error occurs.
+        * 
+        * @param aDataType Type of data used to search data in table.
+        * @param aArray Returned data buffer.
+        */ 
+  		void GetCsTableL(ec_cs_data_type_e aDataType,
+  			HBufC8** aOutColumnValue,
+  			RArray<SWapiCertEntry>& aArray);
+
+        /**
+        * Read password.
+        * 
+        * Read password from certificate store.
+        * Method leaves if an error occurs.
+        * @param aDataReference Password reference.
+        */ 
+        void ReadPasswordL( const ec_cs_data_c* const aDataReference );
+
+        /**
+        * Read device seed.
+        * 
+        * Read device seed from certificate store.
+        * Method leaves if an error occurs.
+        * 
+        * @param aDataReference Device seed reference.
+        */ 
+        void ReadDeviceSeedL( const ec_cs_data_c* const aDataReference );
+        				
+        /**
+        * Read certificate file password.
+        * 
+        * Read certificate file password from certificate store.
+        * Method leaves if an error occurs.
+        * 
+        * @param aDataReference Reference of certificate file password.
+        */ 
+		void ReadCertificateFilePasswordL(
+			const ec_cs_data_c* const aDataReference );		
+
+        /**
+         * Add new CS data object to the list.
+         *
+         * Method leaves if an error occurs.
+         * @param aDataReference Certificate store data reference.
+         * @param aData Certificate store data.
+         */ 
+         void AddObjectL( const ec_cs_data_c* const aDataReference,
+         		          const eap_variable_data_c* const aData );
+         
+
+         
+   private: // New, start/complete asynch. requests
+    
+        /*
+        * Start asynchronous request.
+        * 
+        * @param aState State of active object that defines the type
+        *               of request to be served.
+        * @return ETrue - if request started succefully, EFalse - otherwise.
+        */ 
+        TBool StartAsynchRequest( TWapiState aState );
+
+#if defined( WAPI_USE_UI_NOTIFIER )   		    
+        
+        /**
+        * Ask from user certificate files password.
+        */ 
+        StartQueryCertFilePassword();
+
+        /**
+        * Complete start-query-cert-file-password request.
+        */ 
+        CompleteQueryCertFilePassword();
+
+        /**
+        * Ask from user import file password.
+        */ 
+        StartQueryImportFilePassword();
+        
+        /**
+        * Complete start-query-import-file-password request.
+        */ 
+        CompleteQueryImportFilePassword();
+        
+#endif // WAPI_USE_UI_NOTIFIER 
+        
+    private: // New, complete asynch. query methods in active object    
+    
+        void CompleteHandlingDeviceSeedQueryState();	    
+
+        
+    private: // New methods, misc
+    
+        void CopyBufToEapVarL( const TDesC8& aInBuf,
+            eap_variable_data_c& aOutEapVar );
+
+   
+    	void set_is_valid();
+    	
+    	eap_status_e CreateDeviceSeedAsync();
+
+    	void CompleteCreateDeviceSeed( TInt aStatus );
+
+    	TInt CreateMMETelConnectionL();
+
+    	void DisconnectMMETEL();	
+
+    	eap_status_e ImportFilesL();
+    	
+    	void UpdatePasswordTimeL();
+    	
+    	void CheckPasswordTimeValidityL();
+    	
+    	TInt64 ReadIntDbValueL(
+    			RDbNamedDatabase& aDb,
+    			const TDesC& aColumnName,
+    			const TDesC& aSqlStatement );
+    	
+        /**
+        * Convert from utf8 to unicode.
+        * 
+        * Note that the caller is responsible for memory cleaning.
+        * Note that method can leave.
+        * @param aInBuf Const reference to the input buffer.
+        * @param aOutBuf Returned converted buffer, memory is allocated inside
+        *                the method. 
+        */
+        void ConvertFromBuf8ToBuf16LC( const TDesC8& aInBuf8, HBufC16** aOutBuf16 );
+
+        /**
+        * Check if filename is in db.
+        * 
+        * Method leaves if an error occurs.
+        * @param aFileName contains filename to be checked.
+        * Return value ETrue indicates found, and EFalse indicates not found
+        */ 
+        TBool CheckFilenameL(TPtr8 aFileNamePtr );
+        
+        /**
+        * This is internal functionality of complete_add_imported_certificate_file.
+        * 
+        * Method can be used also, if complete_add_imported_certificate_file is not called.
+        * Method leaves if an error occurs.
+        */ 
+        void CompleteAddImportedCertificateFileL(const eap_variable_data_c * const in_imported_certificate_filename);
+
+    private: // Data
+
+    
+        /**
+        * Timer IDs which are usually used in asynch. calls
+        * from common side.
+        */ 
+        enum TWapiAmCoreTimerId
+            {
+            EWapiInitCertificateStoreTimerId,       /* 0 */
+            EWapiAddCertificateFileTimerId,         /* 1 */
+            EWapiReadCertificateStoreDataTimerId,   /* 2 */
+            EWapiWriteCertificateStoreDataTimerId,  /* 3 */
+            // ...
+            EWapiTimerIdsNumber                     /* 4 */ // keep always as last element
+            };
+
+    	
+        /**
+        * The current state of active object.
+        */ 
+        TWapiState iState;	
+
+	    /**
+	    * Pointer to the AM tools class.
+	    */
+        abs_eap_am_tools_c* iAmTools;
+	    
+        /*
+        * Array of References:
+        */
+	    eap_array_c<ec_cs_data_c> iInReferences;
+
+	    /**
+	    * Array of reference & datablocks:
+	    */ 
+	    eap_array_c<ec_cs_data_c> iReferencesAndDataBlocks;
+
+	    /**
+	    * EAPOL status that is returned to common side.
+	    */ 
+	    eap_status_e iWapiCompletionStatus;
+
+	    /*
+	    * Variable describes the pending operation of
+	    * certificate store.
+	    */ 
+	    ec_cs_pending_operation_e iCsPendingOperation;
+
+
+	    /**
+	    * Pointer to the lower layer in the stack.
+	    */
+        abs_wapi_am_core_c* iPartner;
+
+
+        /**
+        *
+        */ 
+        abs_ec_am_certificate_store_c* iCertStorePartner;
+        
+        /*
+        * Certificate store implements database store for certificate data.
+        */ 
+        CCertificateStoreDatabase* iCertificateStoreDb;
+        
+        /**
+        * Password of certificate store.
+        */ 
+    	eap_variable_data_c iCsPassword;
+
+	    /*
+        * Boolean flag to make sure that if objects are deleted in cancel,
+	    * we don't use them anymore.
+	    */
+	    TBool iCancelCalled;
+
+
+#if defined( WAPI_USE_UI_NOTIFIER )
+    	
+        /**
+        * Notifier. It acts as a service provider.
+        */
+        RNotifier iNotifier; 
+              
+         /**
+         * Data sent from AO to notifier plugin.
+         */
+         TWapiUiNotifierInfo* iNotifierDataToUser;
+
+         /**
+         * Packaged data sent from AO to notifier plugin.
+         */
+         TPckg<TWapiUiNotifierInfo>* iNotifierDataPckgToUser;	
+
+         /**
+         * Data from notifier plugin to AO.
+         */
+         TWapiUiNotifierInfo* iNotifierDataFromUser;
+
+ 	    /**
+         * Packaged data from notifier plugin to AO.
+         */
+ 	    TPckg<TWapiUiNotifierInfo>* iNotifierDataPckgFromUser;	
+   	
+#endif // WAPI_USE_CERT_FILE_PASSWORD
+ 	    
+	    //--------- TODO: DELETE NOT USED MEMBERS ------
+	    
+	    u32_t m_authentication_counter;
+
+	    u32_t m_successful_authentications;
+
+	    u32_t m_failed_authentications;
+
+	    bool m_is_valid;
+
+	    bool m_is_client;	
+
+	    bool m_first_authentication;
+
+	    bool m_self_disassociated;
+
+	    eap_variable_data_c * m_ssid;
+
+	    eap_am_network_id_c* m_receive_network_id;
+
+	    eap_file_config_c* m_fileconfig;
+	    wapi_completion_operation_e iCompletionOperation;
+	
+	    // For MMETEL connection.
+        RTelServer iServer;
+        RMobilePhone iPhone;
+    
+        // Stores the last queried Phone identities like manufacturer, model, 
+        // revision and serial number
+        RMobilePhone::TMobilePhoneIdentityV1 iDeviceId; 
+    	
+        // Tells if MMETEL is connected already or not.
+        TBool iMMETELConnectionStatus;  
+    
+        eap_variable_data_c* iWapiDeviceSeed;
+        
+        /* Status for the WAPICertificates class Active object */
+        TRequestStatus* iWapiCertsStatus;
+        
+        // The pointers to store the pointer to the certificate store array 
+        // for the wapicertificates label reading functionality
+        RArray<TBuf<KCsMaxWapiCertLabelLen> > **iUserCerts;
+        RArray<TBuf<KCsMaxWapiCertLabelLen> > **iCACerts;
+        RArray<TBuf8<KMaxIdentityLength> > **iUserCertsData;
+        RArray<TBuf8<KMaxIdentityLength> > **iCACertsData;
+    
+        RArray<SWapiCertEntry> iCertArray;
+        
+        TBool iGetAll;
+        
+        eap_variable_data_c iEapVarData;
+
+        RArray<TBuf8<KMaxFileName> > iImportedFilenames; 
+	//--------------------------------------------------
+    }; // class wapi_am_core_symbian_c
+
+#endif //#if !defined(_WAPI_AM_CORE_SYMBIAN_H_)
+
+//--------------------------------------------------
+
+
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/include/wapi_am_wlan_authentication_symbian.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,210 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/include/wapi_am_wlan_authentication_symbian.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 13.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+
+
+#if !defined(_WAPI_AM_WLAN_AUTHENTICATION_SYMBIAN_H_)
+#define _WAPI_AM_WLAN_AUTHENTICATION_SYMBIAN_H_
+
+#include "eap_am_export.h"
+#include "wapi_am_wlan_authentication.h"
+#include "eapol_wlan_database_reference.h"
+#include "eap_am_network_id.h"
+#include "eap_array_algorithms.h"
+
+#include <e32base.h>
+#include <e32std.h>
+#include <d32dbms.h>
+
+#include <wdbifwlansettings.h>
+
+#include <EapType.h>
+
+
+// Full path is not needed. The database wapi.dat will be saved in the 
+// data cage path for DBMS. So it will be in "\private\100012a5\wapi.dat" in C: drive.
+// The maximum length of database name is 0x40 (KDbMaxName) , which is defined in d32dbms.h.
+
+_LIT(KWapiDatabaseName, "c:wapi.dat");
+
+
+class CEapType;
+class abs_wapi_am_wlan_authentication_c;
+class abs_eap_am_tools_c;
+class eap_file_config_c;
+
+/// This class declares the adaptation module of wapi_am_wlan_authentication_c.
+/// See comments of the functions from wapi_am_wlan_authentication_c.
+class EAP_EXPORT wapi_am_wlan_authentication_symbian_c
+: public CActive
+, public wapi_am_wlan_authentication_c
+{
+private:
+	//--------------------------------------------------
+
+	abs_wapi_am_wlan_authentication_c * m_am_partner;
+
+	abs_eap_am_tools_c * m_am_tools;
+
+	/// This is object to handle file configuration.
+	eap_file_config_c * m_fileconfig;
+
+	/// SSID of current network.
+	eap_variable_data_c m_SSID;
+
+	/// This pointer is abstract interface to reference of WLAN database of the current connection.
+	const abs_eapol_wlan_database_reference_if_c * m_wlan_database_reference;
+
+
+	/// Network identity of current connection.
+	eap_am_network_id_c m_receive_network_id;
+
+	/// WLAN security mode as defined in Symbian platform.
+	EWlanSecurityMode m_security_mode;
+
+	/// WLAN authentication type.
+	eapol_key_authentication_type_e m_selected_eapol_key_authentication_type;
+
+	/// This object is client (true).
+	bool m_is_client;
+
+	/// This object is valid (true).
+	bool m_is_valid;
+
+	/// WPA(2)-PSK
+	eap_variable_data_c m_wapi_preshared_key;
+
+	/// HAHS of WPA(2)-PSK 
+	eap_variable_data_c m_wapi_psk;
+	
+	// Iap Index, NULL if not initialized
+	TUint iIapIndex;
+	//--------------------------------------------------
+
+	/// Function reads one configuration value from database.
+	void ReadConfigureL(
+		eap_config_string fieldx,
+		const eap_configuration_field_c * const field,
+		const u32_t /*field_length*/,
+		eap_variable_data_c * const data);
+
+	/// Control function of this active-object.
+	void RunL();
+
+	/// Cancel function for active-object.
+	void DoCancel();
+
+	/// THis function reads the references to active Internet Access Point (IAP).
+	eap_status_e read_database_reference_values(
+		TIndexType * const type,
+		TUint * const index);
+
+
+    // This function Gets Psk from commdbif
+	eap_status_e GetWlanConfigurationL(eap_variable_data_c * const wapi_psk );
+	
+	/// This function sends error notification to partner object.
+	void send_error_notification(const eap_status_e error);
+
+	//--------------------------------------------------
+public:
+	//--------------------------------------------------
+
+	// 
+	EAP_FUNC_IMPORT virtual ~wapi_am_wlan_authentication_symbian_c();
+
+	// 
+	EAP_FUNC_IMPORT wapi_am_wlan_authentication_symbian_c(
+		abs_eap_am_tools_c * const tools,
+		const bool is_client_when_true,
+		const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference);
+
+
+	/// See comments of the functions from wapi_am_wlan_authentication_c.
+
+	EAP_FUNC_IMPORT bool get_is_valid();
+
+	EAP_FUNC_IMPORT eap_status_e configure();
+
+	EAP_FUNC_IMPORT eap_status_e shutdown();
+
+	EAP_FUNC_IMPORT eap_status_e set_am_partner(
+		abs_wapi_am_wlan_authentication_c * am_partner
+		);
+
+	EAP_FUNC_IMPORT eap_status_e reset_wapi_configuration();
+
+	EAP_FUNC_IMPORT eap_status_e set_wlan_parameters(
+		const eap_variable_data_c * const SSID,
+		const bool WPA_override_enabled,
+		const eap_variable_data_c * const wapi_preshared_key,
+		const eapol_key_authentication_type_e selected_eapol_key_authentication_type);
+
+	EAP_FUNC_IMPORT eap_status_e association(
+		const eap_am_network_id_c * const receive_network_id);
+
+	EAP_FUNC_IMPORT eap_status_e disassociation(
+		const eap_am_network_id_c * const receive_network_id ///< source includes remote address, destination includes local address.
+		);
+
+	EAP_FUNC_IMPORT eap_status_e get_wlan_configuration(
+		eap_variable_data_c * const wapi_psk);
+
+	/**
+	 * This function indicates finish of the authentication to adatation module.
+	 * @param when_true_successfull tells whether authentication was successfull (true) or not (false).
+	 * @param authentication_type tells the used WLAN authentication type.
+	 */
+	EAP_FUNC_EXPORT eap_status_e authentication_finished(
+		const bool when_true_successfull,
+		const eapol_key_authentication_type_e authentication_type);
+
+	EAP_FUNC_IMPORT eap_status_e read_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	EAP_FUNC_IMPORT eap_status_e write_configure(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data);
+
+	EAP_FUNC_IMPORT eap_status_e set_timer(
+		abs_eap_base_timer_c * const initializer, 
+		const u32_t id, 
+		void * const data,
+		const u32_t p_time_ms);
+
+	EAP_FUNC_IMPORT eap_status_e cancel_timer(
+		abs_eap_base_timer_c * const initializer, 
+		const u32_t id);
+
+	EAP_FUNC_IMPORT eap_status_e cancel_all_timers();
+
+	EAP_FUNC_IMPORT void state_notification(
+		const abs_eap_state_notification_c * const state);
+
+	//--------------------------------------------------
+}; // class wapi_am_wlan_authentication_symbian_c
+
+#endif //#if !defined(_WAPI_AM_WLAN_AUTHENTICATION_SYMBIAN_H_)
+
+//--------------------------------------------------
+
+
+
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/rom/wapi.iby	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/rom/wapi.iby
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : Image description file for project WAPI
+*  Version     : %version: 11.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.0
+*/
+
+
+#ifndef __WAPI_IBY__
+#define __WAPI_IBY__
+#include <bldvariant.hrh>
+
+#ifdef __PROTOCOL_WLAN
+#ifdef FF_WLAN_WAPI_INCLUDE_IN_ROM
+
+/* WAPI */
+
+// WAPI main DLL
+file=ABI_DIR\BUILD_DIR\wapi.dll			SHARED_LIB_DIR\wapi.dll
+
+// WLAN engine WAPI interface
+ECOM_PLUGIN(wlanwapiif.dll, 2001959f.rsc)
+
+// WAPI database DBMS policy file
+data=ZPRIVATE\100012A5\policy\20021357.spd			private\100012A5\policy\20021357.spd
+
+// WAPI configuration file
+data=ZPRIVATE\101F8EC5\wapi.conf	private\101F8EC5\wapi.conf
+
+#endif // FF_WLAN_WAPI_INCLUDE_IN_ROM
+#endif // __PROTOCOL_WLAN
+#endif // #ifndef __WAPI_IBY__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/wapi_core/symbian/WapiCertificates.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,267 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/wapi_core/symbian/WapiCertificates.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 25.1.3 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+#include "WapiCertificates.h"
+#include "certificate_store_db_symbian.h"
+#include "abs_eap_am_tools.h"
+#include "eap_am_tools_symbian.h"
+#include "dummy_wapi_core.h"
+#include "wapi_am_core_symbian.h"
+#include "ec_certificate_store.h"
+#include <e32std.h>
+
+// -----------------------------------------------------------------------------
+// CWapiCertificates::CWapiCertificates()
+// The constructor does not do anything
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CWapiCertificates::CWapiCertificates(): CActive(CActive::EPriorityStandard)
+    {
+    }
+    
+// -----------------------------------------------------------------------------
+// CWapiCertificates::~CWapiCertificates()
+// The destructor
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CWapiCertificates::~CWapiCertificates()
+    {    
+    if ( iEcCertStore != NULL )
+        {
+        iEcCertStore->shutdown();
+        delete iEcCertStore;
+        }
+    if ( iWapiCore != NULL )
+        {
+        iWapiCore->shutdown();
+        delete iWapiCore;
+        }
+    delete iCertDB;
+
+    delete iDummyCore;
+    
+    if ( iAmTools != NULL )
+        {
+        iAmTools->am_cancel_all_timers();
+				abs_eap_am_tools_c::delete_abs_eap_am_tools_c(iAmTools);
+        }
+    
+    if(IsActive())
+	    {
+	    Cancel();		
+	    }
+    }
+    
+// -----------------------------------------------------------------------------
+// CWapiCertificates::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CWapiCertificates::ConstructL()
+    {
+	  // Create the needed certificate store object
+    iAmTools = abs_eap_am_tools_c::new_abs_eap_am_tools_c();
+    if ( iAmTools == NULL || iAmTools->get_is_valid() != true )
+        {
+        User::Leave(KErrGeneral);
+        }
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CWapiCertificates::ConstructL\n" ) ) );
+
+    iCertDB = CCertificateStoreDatabase::NewL( iAmTools );
+    // Open the certificate store connection
+    iCertDB->OpenCertificateStoreL();
+  
+    // create the dummy core and ec cert store in order to create the 
+    // wapi_am_core_symbian object
+    iDummyCore = new(ELeave) dummy_wapi_core_c();
+    // check if dummyCore is ok
+    if ( iDummyCore->get_is_valid() == false )
+        {
+        User::Leave( KErrGeneral );
+        }
+    
+    iWapiCore = wapi_am_core_symbian_c::NewL( iAmTools, iDummyCore, iCertDB, false);
+    
+    iCertDB->SetCorePartner(iWapiCore);
+    
+    iEcCertStore = new(ELeave) ec_certificate_store_c(iAmTools, iDummyCore, iWapiCore , true);
+    
+    eap_status_e status = iEcCertStore->configure();
+    if(status != eap_status_ok)
+        {
+        User::Leave( KErrGeneral );
+        }
+        
+    iWapiCore->set_am_certificate_store_partner(iEcCertStore);
+    
+    CActiveScheduler::Add(this); // add this object to the active scheduler
+  	}
+
+// -----------------------------------------------------------------------------
+// CWapiCertificates::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//   
+EXPORT_C CWapiCertificates* CWapiCertificates::NewL()
+    {
+    CWapiCertificates* self = new(ELeave) CWapiCertificates(); 
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+		
+
+    
+//------------------------------------------------------------------------------
+// CWapiCertificates::GetAllCertificateLabelsL( )
+//------------------------------------------------------------------------------
+EXPORT_C void CWapiCertificates::GetAllCertificateLabelsL( RArray<TBuf<KMaxLabelLength> > **aUserCerts, RArray<TBuf8<KMaxIdentityLength> >**aUserCertData,
+        RArray<TBuf<KMaxLabelLength> > **aCACerts, RArray<TBuf8<KMaxIdentityLength> >**aCACertData )
+    {
+    // Use the provided service for reading the list.
+
+    iWapiCore->GetAllCertificateLabelsL( aUserCerts, aCACerts, aUserCertData, aCACertData, iStatus );
+    // Let's wait until certificate db get's the job done and return after that
+    SetActive();
+    iWait.Start();
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CWapiCertificates::GetAllCertificateLabelsL, status = %d.\n" ),
+        iStatus.Int() ) );
+
+    if (*aCACerts)
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "CWapiCertificates::GetAllCertificateLabelsL, CA Count = %d.\n" ),
+                (*aCACerts)->Count() ) );
+        }
+    if (*aUserCerts)
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "CWapiCertificates::GetAllCertificateLabelsL, Client count = %d.\n" ),
+                (*aUserCerts)->Count() ) );
+        }
+    
+    if (*aCACerts)
+        {
+        for (TInt aCa = 0; aCa <(*aCACerts)->Count(); aCa++)
+            {
+            TPtrC certPtr;
+            certPtr.Set ((**aCACerts)[aCa]);
+            EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "CaCert:"), certPtr.Ptr(),
+                certPtr.Size() ));
+            }
+        }
+    
+    if (*aUserCerts)
+        {
+        for (TInt aCa = 0; aCa <(*aUserCerts)->Count(); aCa++)
+            {
+            TPtrC certPtr;
+            certPtr.Set ((**aUserCerts)[aCa]);
+            EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "ClientCert:"), certPtr.Ptr(),
+                certPtr.Size() ));
+            }
+        }
+    // Check the status
+    User::LeaveIfError( iStatus.Int() );
+    return;
+    }
+    
+//------------------------------------------------------------------------------
+// CWapiCertificates::ResetCertificateStore( )
+//------------------------------------------------------------------------------
+EXPORT_C void CWapiCertificates::ResetCertificateStoreL( )
+    {
+    // Use the provided service for destroying the certificate store
+    TInt error = iCertDB->DestroyCertificateStore( );
+    // Leave if error returned
+    User::LeaveIfError( error );
+    }
+    
+//------------------------------------------------------------------------------
+// CWapiCertificates::GetConfiguration(TInt aId, TDes& aCACert, TDes& aUserCert)
+//------------------------------------------------------------------------------
+EXPORT_C void CWapiCertificates::GetConfigurationL( const TInt aId, TDes& aCACert, TDes& aUserCert )
+    {
+    // Use the provided service for getting the selected CA and user certificates
+    iCertDB->GetConfigurationL( aId, aCACert, aUserCert );
+    }
+
+//------------------------------------------------------------------------------
+// CWapiCertificates::SetCACert( TInt aId, const TBuf8<KMaxIdentityLength> aSelectedCert )
+//------------------------------------------------------------------------------
+EXPORT_C void CWapiCertificates::SetCACertL( const TInt aId, const TBuf8<KMaxIdentityLength> aSelectedCert )
+    {
+    // Use the provided service for setting the selected CA certificate
+    iCertDB->SetCACertL( aId, aSelectedCert );
+    }
+
+//------------------------------------------------------------------------------
+// CWapiCertificates::SetUserCert( TInt aId, const TBuf8<KMaxIdentityLength> aSelectedCert )
+//------------------------------------------------------------------------------
+EXPORT_C void CWapiCertificates::SetUserCertL( const TInt aId, const TBuf8<KMaxIdentityLength> aSelectedCert)
+    {
+    // Use the provided service for setting the selected user certificate
+    iCertDB->SetUserCertL( aId, aSelectedCert );
+    }
+
+//------------------------------------------------------------------------------
+// CWapiCertificates::DeleteAPSpecificDataL( TInt aId )
+//------------------------------------------------------------------------------
+EXPORT_C void CWapiCertificates::DeleteAPSpecificDataL( const TInt aId )
+    {
+    // Use the provided service for deleting the rows mathing the id
+    iCertDB->DeleteAPSpecificDataL( aId );
+    }
+    
+// ================= protected: from CActive =======================
+    
+// ---------------------------------------------------------
+// CWapiCertificates::RunL()
+// ---------------------------------------------------------
+//
+void CWapiCertificates::RunL()
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CWapiCertificates::RunL() IN, iStatus=%d.\n"), iStatus.Int() ) );
+        
+    // This is needed to continue the execution after Wait.Start(); 
+    iWait.AsyncStop(); 
+    return; 
+    } // CWapiCertificates::RunL()
+
+    
+// ---------------------------------------------------------
+// CWapiCertificates::RunL()
+// ---------------------------------------------------------
+//
+void CWapiCertificates::DoCancel()
+    {
+    if( iStatus == KRequestPending )
+        {
+        TRequestStatus * reqStat = &iStatus;
+        User::RequestComplete(reqStat, KErrCancel);
+        }
+    }
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/wapi_core/symbian/certificate_store_db_symbian.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,2818 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/wapi_core/symbian/certificate_store_db_symbian.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 61 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+
+// INCLUDE FILES
+#include <mmtsy_names.h>
+#include <utf.h>                           // for CnvUtfConverter
+#include <s32strm.h> 	                   // For RReadStream
+#include <d32dbms.h>                       // for RDbColReadStream
+#include "certificate_store_db_symbian.h"
+#include "eap_am_trace_symbian.h"
+#include "eap_variable_data.h"
+#include "abs_eap_am_tools.h"
+#include "eap_am_tools_symbian.h"
+#include "eap_am_types.h"
+#include "wapi_asn1_der_parser.h"
+#include "wapi_am_core_symbian.h"
+// ================= public:  Constructors and destructor =======================
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::NewL()
+// ---------------------------------------------------------
+//
+CCertificateStoreDatabase* CCertificateStoreDatabase::NewL(
+    abs_eap_am_tools_c* aAmTools )
+    {    
+	CCertificateStoreDatabase* self = new(ELeave)
+	    CCertificateStoreDatabase( aAmTools );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+
+    } // CCertificateStoreDatabase::NewL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::~CCertificateStoreDatabase()
+// ---------------------------------------------------------
+//
+CCertificateStoreDatabase::~CCertificateStoreDatabase()
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::~CCertificateStoreDatabase() IN\n" ) ) );
+
+    Close();
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::~CCertificateStoreDatabase() OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::~CCertificateStoreDatabase()
+
+
+// ================= public: New, open/close/destroy functionality =======================
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::OpenCertificateStoreL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::OpenCertificateStoreL()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::OpenCertificateStoreL() IN\n" ) ) );
+	
+    if ( iCsDbCreated == EFalse || iCsSessionOpened == EFalse )
+		{
+		// Certificate store DB and tables are not created.
+		CreateCertificateStoreL();
+		}
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::OpenCertificateStoreL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::OpenCertificateStoreL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::Close()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::Close()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::Close() IN\n" ) ) );
+
+	if ( iCsDbCreated )
+		{
+		iCsDb.Close();
+		iCsDbCreated = EFalse;
+		}
+	if ( iCsSessionOpened )
+	    {
+		iCsDbSession.Close();
+		iCsSessionOpened = EFalse;
+	    }	
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::Close() OUT\n" ) ) );
+	
+	} // CCertificateStoreDatabase::Close()
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::SetCorePartner()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::SetCorePartner(wapi_am_core_symbian_c *partner)
+    {
+    iPartner = partner; 
+    }
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::DestroyCertificateStore()
+// ---------------------------------------------------------
+//
+TInt CCertificateStoreDatabase::DestroyCertificateStore()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::DestroyCertificateStore() IN, \
+        iCsSessionOpened=%d, iCsDbCreated=%d\n" ),
+        iCsSessionOpened, iCsDbCreated ) );
+		
+    // There could be a case where certificate store DB is destroyed and UI
+    // calls this function. We return KErrNone in that case.        
+    if ( iCsDbCreated == EFalse )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "WARNING: CCertificateStoreDatabase::DestroyCertificateStore() \
+            Certificate store DB doesn't exist. Returning KErrNone.\n" ) ) );
+        return KErrNone;
+        }
+
+    if ( iCsSessionOpened == EFalse )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::DestroyCertificateStore() \
+			Certificate store not opened!\n" ) ) );
+		return KErrSessionClosed;
+		}	
+		
+    if (iPartner != NULL)
+        {
+        iPartner->reset();
+        }
+    
+	TInt error = iCsDb.Destroy();
+		
+	if ( error != KErrNone )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::DestroyCertificateStore() \
+			iCsDb.Destroy() failed, error=%d.\n" ), error ) );
+		}
+		else
+		{
+		iCsDbCreated = EFalse;
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "CCertificateStoreDatabase::DestroyCertificateStore() \
+			CS DB destroyed successfully.\n" ) ) );	
+		}
+	
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::DestroyCertificateStore() OUT,\
+        error=%d.\n" ), error ) );
+	
+    return error;
+	} // CCertificateStoreDatabase::DestroyCertificateStore()
+
+
+// ================= public:  New =======================
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::InitializeCertificateStoreL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::InitializeCertificateStoreL()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::InitializeCertificateStoreL() IN\n" ) ) );
+
+    WriteCertificateStoreStateL( ECertificateStoreInitialized );
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::InitializeCertificateStoreL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::InitializeCertificateStoreL()
+
+
+// ================= public: New, get/set/remove data in database =======================
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::GetCsDataByReferenceL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::GetCsDataByReferenceL(
+    ec_cs_data_type_e aDataType,
+    const TDesC8& aDataReference,
+   	HBufC8** aOutColumnValue )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCsDataByReferenceL1() IN\n" ) ) );
+    
+        // Convert the received reference id into integer.. 
+    TUint intRef;
+    if (aDataType != ec_cs_data_type_selected_ca_id && aDataType != ec_cs_data_type_selected_client_id)
+        {
+        // Convert the received reference id into integer.. 
+        intRef = eap_read_u32_t_network_order(
+            aDataReference.Ptr(),
+            aDataReference.Size());
+        }
+    else
+        {
+        intRef = static_cast<TUint>(*aDataReference.Ptr());
+        }
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ( "CCertificateStoreDatabase::GetCsDataByReference1L() \
+            New entry: reference set to DB(TEXT)=%d\n" ), intRef ) );
+    GetCsDataByReferenceL ( aDataType, intRef, aOutColumnValue );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCsDataByReferenceL1() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::GetCsDataByReferenceL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::GetCsDataByReferenceL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::GetCsDataByReferenceL(
+    ec_cs_data_type_e aDataType,
+    const TUint aDataReference,
+   	HBufC8** aOutColumnValue )
+    
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCsDataByReferenceL() IN\n" ) ) );
+    	
+    // There could be a case where CS DB is destroyed and UI
+    // calls this function. We just return in that case.
+    if ( !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "ERROR: CCertificateStoreDatabase::GetCsDataByReferenceL() \
+                CS DB doesn't exist. Don't do anything.\n" ) ) );
+        return;
+        }
+
+    if ( !iCsSessionOpened )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "ERROR: CCertificateStoreDatabase::GetCsDataByReferenceL() - CS not opened.\n" ) ) );
+        User::Leave( KErrSessionClosed );
+        }			
+		    
+    // DB names
+    TBuf<KDbMaxName> tableName;               // const from d32dbms.h
+    TBuf<KDbMaxColName> referenceColumnName;  // const from d32dbms.h
+    TBuf<KDbMaxColName> dataColumnName;       // const from d32dbms.h
+
+    GetDbNamesFromDataTypeL( aDataType, tableName, referenceColumnName,
+		                        dataColumnName );
+
+    // create SQL query statement
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+
+    _LIT( KSqlQuery, "SELECT %S FROM %S WHERE %S=%d" );
+    sqlStatement.Format( KSqlQuery, &dataColumnName, &tableName, &referenceColumnName, aDataReference );
+
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+            "wapi_am_core_symbian_c::GetCsDataByReferenceL() sqlStatement",
+            sqlStatement.Ptr(), sqlStatement.Size() ) );	
+
+    RDbView view;
+    User::LeaveIfError( view.Prepare( iCsDb, TDbQuery( sqlStatement ),
+            TDbWindow::EUnlimited, RDbView::EReadOnly ) );
+    
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCsDataByReferenceL() View prepared OK.\n" ) ) );
+	CleanupClosePushL( view );
+	User::LeaveIfError( view.EvaluateAll() );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCsDataByReferenceL() View evaluated OK.\n" ) ) );    
+    
+	if ( view.FirstL() )
+	    {
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "CCertificateStoreDatabase::GetCsDataByReferenceL() view.FirstL() OK.\n" ) ) );    
+		
+		view.GetL();		
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "CCertificateStoreDatabase::GetCsDataByReferenceL() view.GetL() OK.\n" ) ) );    
+
+		switch ( view.ColType( KDefaultColumnNumberOne ) )
+		    {
+		    case EDbColText:				
+			    {
+                // Buffer for unicode parameter
+                HBufC* unicodebuf = HBufC::NewLC(view.ColLength( KDefaultColumnNumberOne ));
+                TPtr unicodeString = unicodebuf->Des();
+                unicodeString = view.ColDes(KDefaultColumnNumberOne);
+                // Convert to 8-bit
+                if (unicodeString.Size() > 0)
+                    {
+                    *aOutColumnValue = HBufC8::NewLC(
+                        view.ColLength( KDefaultColumnNumberOne ) ); // Buffer for the data.
+                    TPtr8 outColumnValuePtr8 = ( *aOutColumnValue )->Des();
+                    outColumnValuePtr8.Copy(unicodeString);
+                    if (outColumnValuePtr8.Size() == 0)
+	                    {
+	                        User::Leave(KErrNoMemory);
+	                    }
+                    CleanupStack::Pop( *aOutColumnValue );
+                    } 
+                else 
+                    {
+                        // Empty field. Do nothing...data remains invalid
+                    }
+                CleanupStack::PopAndDestroy(unicodebuf);
+			    break;
+			    }
+			    
+		    case EDbColUint32:
+	            {
+	                TUint value;
+	                value = view.ColUint32(KDefaultColumnNumberOne);
+                    *aOutColumnValue = HBufC8::NewLC(
+                        view.ColLength( KDefaultColumnNumberOne ) ); // Buffer for the data.
+                    TPtr8 outColumnValuePtr8 = ( *aOutColumnValue )->Des();
+                    outColumnValuePtr8.Copy((const unsigned char *)&value, sizeof(TUint));
+                    if (outColumnValuePtr8.Size() == 0)
+                    {
+                        User::Leave(KErrNoMemory);
+                    }
+                    CleanupStack::Pop( *aOutColumnValue );
+	            }
+	            break;
+		        
+		    case EDbColBinary:
+			    {
+		        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	                "ERROR: CCertificateStoreDatabase::GetCsDataByReferenceL() \
+	                Unsupported DB field EDbColBinary.\n" ) ) );
+				User::Leave( KErrNotSupported );
+                break;
+			    }
+		    case EDbColLongBinary:				
+			    {
+		        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+					"CCertificateStoreDatabase::GetCsDataByReferenceL() \
+					Long binary column.\n" ) ) );			
+				GetLongBinaryDataL( view, aOutColumnValue );
+				break;
+			    }			
+		    default:
+		    	{
+		        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		            "ERROR: CCertificateStoreDatabase::GetCsDataByReferenceL() \
+		            Unsupported DB field:%d\n" ), 
+		            view.ColType( KDefaultColumnNumberOne ) ) );
+			    User::Leave( KErrNotSupported );
+			    break;
+		    	}
+		    } // switch ( view.ColType( KDefaultColumnNumberOne ) )
+	    } // if ( view.FirstL() )
+	
+	// clean
+	CleanupStack::PopAndDestroy( &view ); // Close view.	
+    CleanupStack::PopAndDestroy( buf );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCsDataByReferenceL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::GetCsDataByReferenceL()
+	
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::GetCsDataL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::GetCsDataL(
+	ec_cs_data_type_e aDataType,
+    HBufC8** aOutColumnValue,
+	RArray<SWapiCertEntry>& aArray,
+	TBool aGetAll)
+
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCsDataL() IN\n" ) ) );
+
+    aArray.Reset();
+    
+    // There could be a case where CS DB is destroyed and UI
+    // calls this function. We just return in that case.
+    if ( !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::GetCsDataL() \
+            CS DB doesn't exist. Don't do anything.\n" ) ) );
+        return;
+        }
+
+    if ( !iCsSessionOpened )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::GetCsDataL() CS not opened.\n" ) ) );
+		User::Leave( KErrSessionClosed );
+		}			
+
+    // DB names
+	TBuf<KDbMaxName> tableName;               // const from d32dbms.h
+	TBuf<KDbMaxColName> dataColumnName;       // const from d32dbms.h
+
+	GetDbNamesFromDataTypeL( aDataType, tableName, dataColumnName );
+
+  	// create SQL query statement
+	HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+	TPtr sqlStatement = buf->Des();
+
+	_LIT( KSqlQuery, "SELECT %S FROM %S" );
+    _LIT( KSqlQueryAll, "SELECT * FROM %S" );
+	if (aGetAll)
+	    sqlStatement.Format( KSqlQueryAll, &tableName );
+	else
+	    sqlStatement.Format( KSqlQuery, &dataColumnName, &tableName );
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::GetCsDataL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );	
+
+		
+ 	RDbView view;
+	User::LeaveIfError( view.Prepare( iCsDb, TDbQuery( sqlStatement ),
+		TDbWindow::EUnlimited, RDbView::EReadOnly ) );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCsDataL() View prepared OK.\n" ) ) );
+	CleanupClosePushL( view );
+	User::LeaveIfError( view.EvaluateAll() );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCsDataL() View evaluated OK.\n" ) ) );    
+    
+ 	if ( view.FirstL() && aGetAll == EFalse)
+	    {
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			"CCertificateStoreDatabase::GetCsDataL() view.FirstL() OK.\n" ) ) );
+		
+		view.GetL();		
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			"CCertificateStoreDatabase::GetCsDataL() view.GetL() OK.\n" ) ) );
+
+		switch ( view.ColType( KDefaultColumnNumberOne ) )
+		    {
+		    case EDbColText:				
+			    {
+                EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                    "CCertificateStoreDatabase::GetCsDataL() \
+                    EDbColText.\n" ) ) );            
+			    // Buffer for unicode parameter
+                HBufC* unicodebuf = HBufC::NewLC(view.ColLength( KDefaultColumnNumberOne ));
+			    TPtr unicodeString = unicodebuf->Des();
+                unicodeString = view.ColDes(KDefaultColumnNumberOne);
+                // Convert to 8-bit
+                if (unicodeString.Size() > 0)
+                    {
+                    *aOutColumnValue = HBufC8::NewLC(
+                        view.ColLength( KDefaultColumnNumberOne ) ); // Buffer for the data.
+                    TPtr8 outColumnValuePtr8 = ( *aOutColumnValue )->Des();
+                    outColumnValuePtr8.Copy(unicodeString);
+                     if (outColumnValuePtr8.Size() == 0)
+                    {
+                        User::Leave(KErrNoMemory);
+                    }
+                     CleanupStack::Pop( *aOutColumnValue );
+
+                } 
+                else 
+                    {
+                        // Empty field. Do nothing...data remains invalid
+                     }
+                CleanupStack::PopAndDestroy(unicodebuf);
+
+                break;
+			    }
+	         case EDbColUint32:
+	                {
+	                EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	                    "CCertificateStoreDatabase::GetCsDataL() \
+	                    EDbColUint32.\n" ) ) );            
+	                    TUint value;
+	                    value = view.ColUint32(KDefaultColumnNumberOne);
+	                    *aOutColumnValue = HBufC8::NewLC(
+	                        view.ColLength( KDefaultColumnNumberOne ) ); // Buffer for the data.
+	                    TPtr8 outColumnValuePtr8 = ( *aOutColumnValue )->Des();
+	                    outColumnValuePtr8.Copy((const unsigned char *)&value, sizeof(TUint));
+	                    if (outColumnValuePtr8.Size() == 0)
+	                    {
+	                        User::Leave(KErrNoMemory);
+	                    }
+	                    CleanupStack::Pop( *aOutColumnValue );
+	                    if (outColumnValuePtr8.Size() == 0)
+	                    {
+	                        User::Leave(KErrNoMemory);
+	                    }
+	                }
+	                break;
+
+		    case EDbColBinary:
+			    {
+		        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+					"CCertificateStoreDatabase::GetCsDataL() \
+					Binary column.\n" ) ) );			
+				GetBinaryDataL( view, aOutColumnValue );
+                break;
+			    }
+		    case EDbColLongBinary:				
+			    {
+                EAP_TRACE_DEBUG_SYMBIAN(
+                    (_L("CCertificateStoreDatabase::GetCsDataL - Long Binary column\n")));
+            
+                GetLongBinaryDataL( view, aOutColumnValue );
+                break;
+			    }			
+		    default:
+		    	{
+		        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			    	"ERROR: CCertificateStoreDatabase::GetCsDataL() \
+			    	Unsupported DB field:%d\n" ),
+				    view.ColType( KDefaultColumnNumberOne ) ) );	
+			    User::Leave( KErrNotSupported );
+			    break;
+		    	}
+		    } // switch ( view.ColType( KDefaultColumnNumberOne ) )
+	    } // if ( view.FirstL() )
+ 	else
+        {
+        if (view.FirstL())
+            {
+            GetTableDataL(view, aArray);       
+            }
+        }
+	// clean memory
+	CleanupStack::PopAndDestroy( &view );
+    CleanupStack::PopAndDestroy( buf );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCsDataL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::GetCsDataL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::SetCsDataByReferenceL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::SetCsDataByReferenceL(
+    ec_cs_data_type_e aDataType,
+	const TDesC8& aColumnValue,
+	const TDesC8& aDataReference,
+	const TBool aIsNewEntry )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::SetCsDataByReferenceL1() IN\n" ) ) );
+	
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+        "wapi_am_core_symbian_c::SetCsDataByReferenceL1() Reference",
+        aDataReference.Ptr(), 
+        aDataReference.Size() ) );
+    
+	  // Convert the received reference id into integer.. 
+    TUint intRef = eap_read_u32_t_network_order(
+            aDataReference.Ptr(),
+            aDataReference.Size());
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ( "CCertificateStoreDatabase::SetCsDataByReferenceL1() \
+            New entry: reference set to DB(TEXT)=%d\n" ), intRef ) );
+    SetCsDataByReferenceL ( aDataType, aColumnValue, intRef, aIsNewEntry );
+		
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::SetCsDataByReferenceL1() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::SetCsDataByReferenceL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::SetCsDataByReferenceL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::SetCsDataByReferenceL(
+    ec_cs_data_type_e aDataType,
+    const TDesC8& aColumnValue,
+    const TUint aDataReference,
+    const TBool aIsNewEntry )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::SetCsDataByReferenceL() IN\n" ) ) );
+    
+    // There could be a case where CS DB is destroyed and UI
+    // calls this function. We just return in that case.
+    if ( !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::SetCsDataByReferenceL() \
+            CS DB doesn't exist. Don't do anything.\n" ) ) );
+        return;
+        }
+    
+    if ( !iCsSessionOpened )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::SetCsDataByReferenceL() \
+            CS not opened.\n" ) ) );
+        User::Leave( KErrSessionClosed );
+        }           
+    
+    if ( aColumnValue.Size() <= 0 )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::SetCsDataByReferenceL() \
+            Column value is negative!\n" ) ) );
+        User::Leave( KErrArgument );
+        }
+    
+    // DB names
+    TBuf<KDbMaxName> tableName;               // const from d32dbms.h
+    TBuf<KDbMaxColName> referenceColumnName;  // const from d32dbms.h
+    TBuf<KDbMaxColName> dataColumnName;       // const from d32dbms.h
+    RDbView::TAccess dbMode = RDbView::EUpdatable;       
+    
+    GetDbNamesFromDataTypeL( aDataType, tableName, referenceColumnName, 
+                            dataColumnName );
+
+    // create SQL query statement
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+    
+    _LIT( KSqlQueryInsert, "SELECT * FROM %S" );
+    _LIT( KSqlQueryWithRef, "SELECT %S FROM %S WHERE %S=%d" );
+
+    if( aIsNewEntry )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "CCertificateStoreDatabase::SetCsDataByReferenceL() \
+             New Entry.\n" ) ) );
+       dbMode = RDbView::EInsertOnly;         
+        sqlStatement.Format( KSqlQueryInsert, &tableName );         
+        }
+    else
+        {
+        sqlStatement.Format( KSqlQueryWithRef,
+                             &dataColumnName,
+                             &tableName,
+                             &referenceColumnName,
+                             &aDataReference );
+        }
+
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+        "wapi_am_core_symbian_c::SetCsDataByReferenceL() sqlStatement",
+        sqlStatement.Ptr(), 
+        sqlStatement.Size() ) );        
+    
+     RDbView view;   
+    User::LeaveIfError( view.Prepare( iCsDb, TDbQuery( sqlStatement ),
+        TDbWindow::EUnlimited, dbMode ) );   
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::SetCsDataByReferenceL() \
+        View prepared OK.\n" ) ) );
+    
+    CleanupClosePushL( view );
+    User::LeaveIfError( view.EvaluateAll() );
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::SetCsDataByReferenceL() \
+        View evaluated OK.\n" ) ) );
+
+    if ( aIsNewEntry && ( aDataReference > 0 ) )
+        {       
+        InsertDataAndReferenceL( view, referenceColumnName,
+            dataColumnName, aDataReference, aColumnValue );     
+        } // if ( aIsNewEntry && ...
+    else
+        {
+        UpdateColOneRowOneL( view, aColumnValue );      
+        }
+
+    view.PutL();    
+    
+    // clean
+    CleanupStack::PopAndDestroy( &view );   
+    CleanupStack::PopAndDestroy( buf );
+        
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::SetCsDataByReferenceL() OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::SetCsDataByReferenceL()
+    
+    
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::SetCsDataL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::SetCsDataL(
+    ec_cs_data_type_e aDataType,
+	const TDesC8& aColumnValue,
+	const TBool aIsNewEntry )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::SetCsDataL() IN\n" ) ) );
+    
+    // There could be a case where CS DB is destroyed and UI
+    // calls this function. We just return in that case.
+    if ( !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::SetCsDataL() \
+            CS DB doesn't exist. Don't do anything.\n" ) ) );
+        return;
+        }
+
+    if ( !iCsSessionOpened )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::SetCsDataL() \
+            CS not opened.\n" ) ) );
+		User::Leave( KErrSessionClosed );
+		}			
+
+	if ( aColumnValue.Size() <= 0 )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			"ERROR: CCertificateStoreDatabase::SetCsDataL() \
+			Column value is empty!\n" ) ) );
+		User::Leave( KErrArgument );
+		}
+
+    // DB names
+	TBuf<KDbMaxName> tableName;               // const from d32dbms.h
+	TBuf<KDbMaxColName> dataColumnName;       // const from d32dbms.h
+	RDbView::TAccess dbMode = RDbView::EUpdatable;		
+	
+	GetDbNamesFromDataTypeL( aDataType, tableName, dataColumnName );
+
+	// create SQL query statement
+	HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+	TPtr sqlStatement = buf->Des();
+	
+	_LIT( KSqlQuery, "SELECT %S FROM %S" );
+	_LIT( KSqlQueryInsert, "SELECT * FROM %S" );
+
+	if( aIsNewEntry )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	        "CCertificateStoreDatabase::SetCsDataByReferenceL() \
+	        New Entry.\n" ) ) );
+		dbMode = RDbView::EInsertOnly;			
+		sqlStatement.Format( KSqlQueryInsert, &tableName );			
+		}
+	else
+		{
+		sqlStatement.Format( KSqlQuery,
+			                 &dataColumnName,
+			                 &tableName );
+		}
+
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::SetCsDataL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );	
+	
+	RDbView view;	
+	User::LeaveIfError( view.Prepare( iCsDb, TDbQuery( sqlStatement ),
+		TDbWindow::EUnlimited, dbMode ) );   
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::SetCsDataByReferenceL() \
+        View prepared OK.\n" ) ) );
+	CleanupClosePushL( view );
+	User::LeaveIfError( view.EvaluateAll() );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::SetCsDataByReferenceL() \
+        View evaluated OK.\n" ) ) );
+	
+	if ( aIsNewEntry )
+		{
+		InsertDataL( view, dataColumnName, aColumnValue );		
+	    }
+	else
+	    {
+	    UpdateColOneRowOneL( view, aColumnValue );		
+	    }
+	
+	view.PutL();	
+	
+	// clean
+	CleanupStack::PopAndDestroy( &view );	
+	CleanupStack::PopAndDestroy( buf );
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::SetCsDataL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::SetCsDataL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::RemoveCsDataByReferenceL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::RemoveCsDataByReferenceL(
+	ec_cs_data_type_e aDataType,
+    const TDesC8& aColumnValue,
+    const TDesC8& aDataReference )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::RemoveCsDataByReferenceL1() IN\n" ) ) );
+
+    // Convert the received reference id into integer.. 
+    TUint intRef = eap_read_u32_t_network_order(
+            aDataReference.Ptr(),
+            aDataReference.Size());
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ( "CCertificateStoreDatabase::RemoveCsDataByReferenceL1() \
+            New entry: reference set to DB(TEXT)=%d\n" ), intRef ) );
+
+    RemoveCsDataByReferenceL ( aDataType, aColumnValue, intRef );
+		
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "CCertificateStoreDatabase::RemoveCsDataByReferenceL1() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::RemoveCsDataByReferenceL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::RemoveCsDataByReferenceL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::RemoveCsDataByReferenceL(
+    ec_cs_data_type_e aDataType,
+    const TDesC8& aColumnValue,
+    const TUint aDataReference )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::RemoveCsDataByReferenceL() IN\n" ) ) );
+    
+    // There could be a case where CS DB is destroyed and UI
+    // calls this function. We just return in that case.
+    if ( !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::RemoveCsDataByReferenceL() \
+            CS DB doesn't exist. Don't do anything.\n" ) ) );
+        return;
+        }
+
+    if ( !iCsSessionOpened )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::RemoveCsDataByReferenceL() \
+            CS not opened.\n" ) ) );
+        User::Leave( KErrSessionClosed );
+        }           
+
+    if ( aColumnValue.Size() <= 0 )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::RemoveCsDataByReferenceL() \
+            Column value is empty!\n" ) ) );
+        User::Leave( KErrArgument );
+        }
+        
+    // DB names
+    TBuf<KDbMaxName> tableName;               // const from d32dbms.h
+    TBuf<KDbMaxColName> referenceColumnName;  // const from d32dbms.h
+    TBuf<KDbMaxColName> dataColumnName;       // const from d32dbms.h
+    RDbView::TAccess dbMode = RDbView::EUpdatable;      
+    
+    GetDbNamesFromDataTypeL( aDataType, tableName, referenceColumnName,
+        dataColumnName );
+    
+    // create SQL query statement
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+    
+    _LIT( KSqlQueryWithRef, "SELECT %S FROM %S WHERE %S=%d" );  
+    sqlStatement.Format( KSqlQueryWithRef,
+                         &dataColumnName,
+                         &tableName,
+                         &referenceColumnName,
+                         &aDataReference );
+    
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+        "wapi_am_core_symbian_c::RemoveCsDataByReferenceL() sqlStatement",
+        sqlStatement.Ptr(), 
+        sqlStatement.Size() ) );        
+    
+    RDbView view;   
+    User::LeaveIfError( view.Prepare( iCsDb, TDbQuery( sqlStatement ),
+        TDbWindow::EUnlimited, dbMode ) );   
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::RemoveCsDataByReferenceL() \
+        View prepared OK.\n" ) ) );
+    CleanupClosePushL( view );
+    User::LeaveIfError( view.EvaluateAll() );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::RemoveCsDataByReferenceL() \
+        View evaluated OK.\n" ) ) );
+        
+    if ( view.FirstL() )
+        {
+        view.DeleteL();
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "CCertificateStoreDatabase::RemoveCsDataByReferenceL() \
+            View deleted OK.\n" ) ) );
+        }
+    else
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "CCertificateStoreDatabase::RemoveCsDataByReferenceL() \
+            No data found.\n" ) ) );
+        }
+    
+    // clean
+    CleanupStack::PopAndDestroy( &view );
+    CleanupStack::PopAndDestroy( buf );
+        
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::RemoveCsDataByReferenceL() OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::RemoveCsDataByReferenceL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::RemoveCsDataL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::RemoveCsDataL(
+	ec_cs_data_type_e aDataType,
+    const TDesC8& aColumnValue )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::RemoveCsDataL() IN\n" ) ) );
+
+    // There could be a case where CS DB is destroyed and UI
+    // calls this function. We just return in that case.
+    if ( !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::RemoveCsDataL() \
+            CS DB doesn't exist. Don't do anything.\n" ) ) );
+        return;
+        }
+
+    if ( !iCsSessionOpened )
+	    {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::RemoveCsDataL() \
+            CS not opened.\n" ) ) );
+	    User::Leave( KErrSessionClosed );
+	    }			
+
+    if ( aColumnValue.Size() <= 0 )
+	    {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		    "ERROR: CCertificateStoreDatabase::RemoveCsDataL() \
+		    Column value is empty!\n" ) ) );
+	    User::Leave( KErrArgument );
+	    }
+	    
+	// DB names
+	TBuf<KDbMaxName> tableName;               // const from d32dbms.h
+	TBuf<KDbMaxColName> referenceColumnName;  // const from d32dbms.h
+	TBuf<KDbMaxColName> dataColumnName;       // const from d32dbms.h
+	RDbView::TAccess dbMode = RDbView::EUpdatable;	
+	
+	GetDbNamesFromDataTypeL( aDataType, tableName, referenceColumnName,
+		dataColumnName );
+	
+	// create SQL query statement
+	HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+	TPtr sqlStatement = buf->Des();
+	
+	_LIT( KSqlQuery, "SELECT %S FROM %S" );
+	sqlStatement.Format( KSqlQuery,
+		                 &dataColumnName,
+		                 &tableName );
+	
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::RemoveCsDataL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );		
+	
+	RDbView view;	
+	User::LeaveIfError( view.Prepare( iCsDb, TDbQuery( sqlStatement ),
+		TDbWindow::EUnlimited, dbMode ) );   
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "CCertificateStoreDatabase::RemoveCsDataL() \
+	    View prepared OK.\n" ) ) );
+	CleanupClosePushL( view );
+	User::LeaveIfError( view.EvaluateAll() );
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "CCertificateStoreDatabase::RemoveCsDataL() \
+	    View evaluated OK.\n" ) ) );
+		
+	if ( view.FirstL() )
+		{
+		view.DeleteL();
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	        "CCertificateStoreDatabase::RemoveCsDataL() \
+			View deleted OK.\n" ) ) );
+		}
+	else
+		{
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	        "CCertificateStoreDatabase::RemoveCsDataL() \
+            No data found.\n" ) ) );
+		}
+	
+	// clean
+	CleanupStack::PopAndDestroy( &view );	
+	CleanupStack::PopAndDestroy( buf );
+		
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "CCertificateStoreDatabase::RemoveCsDataL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::RemoveCsDataL()
+
+
+// ================= public: New, boolean conditions =======================
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::IsInitializedL()
+// ---------------------------------------------------------
+//
+TBool CCertificateStoreDatabase::IsInitializedL()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::IsInitializedL() IN\n" ) ) );
+		
+    // There could be a case where CS DB is destroyed and UI
+    // calls this function. We return EFalse in that case.      
+    if ( !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "CCertificateStoreDatabase::IsInitializedL() \
+            Certificate store DB doesn't exist. Returning EFalse." ) ) );   
+        return EFalse;
+        }
+
+    if ( !iCsSessionOpened )
+	    {
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			"CCertificateStoreDatabase::IsInitializedL() \
+			ERROR: certificate store not opened!" ) ) );
+		return EFalse;
+		}	
+		
+	TBool IsInitializedL( EFalse );		
+				
+	HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+	TPtr sqlStatement = buf->Des();
+
+	// Query only initialization flag field from general settings table.
+	_LIT( KSqlQuery, "SELECT %S FROM %S" );
+	sqlStatement.Format( KSqlQuery,
+						 &KCsInitialized,
+						 &KCsGeneralSettingsTableName );
+
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::IsInitializedL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );	
+
+	RDbView view;		
+	User::LeaveIfError( view.Prepare( iCsDb, TDbQuery( sqlStatement ),
+		TDbWindow::EUnlimited, RDbView::EReadOnly ) );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::IsInitializedL() View prepared OK.\n" ) ) );
+	
+	CleanupStack::PopAndDestroy( buf );
+	
+	CleanupClosePushL( view );
+		
+	User::LeaveIfError( view.EvaluateAll() );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::IsInitializedL() View evaluated OK.\n" ) ) );    
+	
+	if ( view.FirstL() )
+	    {
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		    "CCertificateStoreDatabase::IsInitializedL() view.FirstL() OK.\n" ) ) );
+		view.GetL();
+		
+		if ( view.IsColNull( KDefaultColumnNumberOne ) )
+			{
+			IsInitializedL = EFalse;
+			}
+		else
+			{
+			// Store the line
+			TUint initValue = view.ColUint( KDefaultColumnNumberOne );
+			
+			if ( initValue == ECertificateStoreInitialized )
+				{
+				IsInitializedL = ETrue;
+				}
+			else
+				{
+				IsInitializedL = EFalse;
+				}
+			
+			}		
+		}
+	else
+	    {
+		// Nothing in the view means there is no entry at all.
+		IsInitializedL = EFalse;
+		}
+	
+	CleanupStack::PopAndDestroy( &view ); // Close view.		
+
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"CCertificateStoreDatabase::IsInitializedL() \
+		OUT, IsInitializedL=%d.\n" ), IsInitializedL ) );
+	
+	return IsInitializedL;	
+	} // CCertificateStoreDatabase::IsInitializedL()
+
+
+// ================= private: Access =======================
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::GetCertificateStoreDb()
+// ---------------------------------------------------------
+//
+RDbNamedDatabase& CCertificateStoreDatabase::GetCertificateStoreDb()
+    {
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCertificateStoreDb() IN\n" ) ) );
+
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetCertificateStoreDb() OUT\n" ) ) );
+	return iCsDb; 
+    }
+
+
+// ================= private: New, database, tables =======================
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CreateCertificateStoreL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::CreateCertificateStoreL()
+    {
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateCertificateStoreL() IN\n" ) ) );
+
+    // 1. Open/create a database	
+    CreateDatabaseL();
+
+    // 2. Create CS tables to database (ignore error if tables exist)	
+
+    // Table 1: Create table for general settings. 
+    CreateGeneralSettingsTableL();
+
+    // Table 2: Create table for client ASU-ID list
+    CreateClientAsuIdListTableL();
+
+    // Table 3: Create table for CA ASU-ID list
+    CreateCaAsuIdListTableL();
+
+    // Table 4: Create table for client certificates
+    CreateClientCertificateTableL();
+
+    // Table 5: Create table for CA certificates
+    CreateCaCertificateTableL();
+
+    // Table 6: Create table for private keys
+    CreatePrivateKeyTableL();
+
+    // Table 7: Create table for WAPI certificate labels
+    CreateWapiCertLabeltableL();
+
+    // Table 8: Create table for WAPI certificate files
+    CreateWapiCertFiletableL();
+
+    
+    iCsDbCreated = ETrue;
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateCertificateStoreL() OUT\n" ) ) );    
+    
+    } // CCertificateStoreDatabase::CreateCertificateStoreL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CreateDatabaseL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::CreateDatabaseL()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateDatabaseL() IN\n" ) ) );    
+
+	// Connect to the DBMS server, if not connected already.
+	if ( !iCsSessionOpened )
+	    {
+		User::LeaveIfError( iCsDbSession.Connect() );
+		iCsSessionOpened = ETrue;
+	    }		
+	
+	// Create the secure shared database with the specified secure policy.
+	// Database will be created in the data caging path for DBMS (C:\private\100012a5).
+	TInt err = iCsDb.Create( iCsDbSession, KCsDatabaseName,
+		KSecureUidFormatCertificate );
+	DEBUG1( "CCertificateStoreDatabase::CreateDatabaseL() Created secure DB for \
+		certificatestore.dat, err=%d (-11=DB already exist).", err );	
+	if ( err == KErrNone )
+	    {
+		iCsDb.Close();
+	    }
+	else if ( err != KErrAlreadyExists ) 
+	    {
+		User::LeaveIfError( err );
+	    }
+	User::LeaveIfError( iCsDb.Open( iCsDbSession, KCsDatabaseName,
+		KSecureUidFormatCertificate ) );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateDatabaseL() OUT\n" ) ) );    
+	
+	} // CCertificateStoreDatabase::CreateDatabaseL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CreateGeneralSettingsTableL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::CreateGeneralSettingsTableL()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateGeneralSettingsTableL() IN\n" ) ) );
+
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+
+    // Table columns:
+    ////// NAME //////////////////////////// TYPE ////////////// Constant ////////////////////////
+    //| CS_password						     | VARBINARY(255)	| KCsPassword                  |//
+    //| CS_reference_counter			     | VARBINARY(255)	| KCsReferenceCounter	   	   |//
+    //| CS_master_key					     | VARBINARY(255)	| KCsMasterKey	   	           |//
+    //| CS_initialized					     | UNSIGNED INTEGER | KCsInitialized	   	       |//
+    //| CS_password_max_validity_time        | BIGINT	   	    | KCsPasswordMaxValidityTime   |//
+    //| CS_password_last_identity_time	     | BIGINT	   		| KCsLastPasswordIdentityTime  |//	    
+    //////////////////////////////////////////////////////////////////////////////////////////////
+
+    _LIT( KSqlCreateTable, "CREATE TABLE %S (\
+	    %S VARBINARY(%d),     \
+	    %S VARBINARY(%d),	  \
+        %S VARBINARY(%d),	  \
+	    %S UNSIGNED INTEGER,  \
+	    %S BIGINT,            \
+	    %S BIGINT)" );
+									 
+    sqlStatement.Format(
+        KSqlCreateTable, &KCsGeneralSettingsTableName,
+        &KCsPassword, KCsMaxPasswordLengthInDb,
+        &KCsReferenceCounter, KCsMaxRefCounterLengthInDb,
+        &KCsMasterKey, KCsMaxMasterKeyLengthInDb,
+        &KCsInitialized,
+        &KCsPasswordMaxValidityTime,
+        &KCsLastPasswordIdentityTime,
+        &KCsPrivateKeyAsuIdReference);
+    
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::CreateGeneralSettingsTableL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );
+
+    TInt err = iCsDb.Execute( sqlStatement );
+    if ( err != KErrNone && err != KErrAlreadyExists )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::CreateGeneralSettingsTableL() \
+            iCsDb.Execute(), err=%d.\n" ), err ) );
+        CleanupStack::PopAndDestroy( buf );
+        User::Leave( err );
+        }
+    CleanupStack::PopAndDestroy( buf );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateGeneralSettingsTableL() OUT\n" ) ) );
+    
+	} // CCertificateStoreDatabase::CreateGeneralSettingsTableL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CreateClientAsuIdListTableL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::CreateClientAsuIdListTableL()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateClientAsuIdListTableL() IN\n" ) ) );
+
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+
+    // Table columns:
+    ////// NAME /////////////////////// TYPE ///////////// Constant ////////////////////
+    //| CS_client_ASU_ID_reference    | UNSIGNED INTEGER   | KCsClientAsuIdReference |//		
+    //| CS_client_ASU_ID_data         | LONG VARBINARY	   | KCsClientAsuIdData      |//	
+    ////////////////////////////////////////////////////////////////////////////////////
+    _LIT( KSqlCreateTable, "CREATE TABLE %S (\
+    	%S UNSIGNED INTEGER, \
+        %S LONG VARBINARY)" );
+
+    sqlStatement.Format( KSqlCreateTable, &KCsClientAsuIdListTableName, 
+    	&KCsClientAsuIdReference, &KCsClientAsuIdData );
+    
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::CreateClientAsuIdListTableL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );
+    
+    TInt err = iCsDb.Execute( sqlStatement );
+    if ( err != KErrNone && err != KErrAlreadyExists )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::CreateClientAsuIdListTableL() \
+            iCsDb.Execute(), err=%d" ), err ) );
+        CleanupStack::PopAndDestroy( buf );
+	    User::Leave( err );
+        }
+    CleanupStack::PopAndDestroy( buf );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateClientAsuIdListTableL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::CreateClientAsuIdListTableL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CreateCaAsuIdListTableL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::CreateCaAsuIdListTableL()
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateCaAsuIdListTableL() IN\n" ) ) );
+    
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+
+    // Table columns:
+    ////// NAME //////////// TYPE ///////////// Constant ///////////////////
+    //| CS_CA_ASU_ID_reference  | UNSIGNED INTEGER)| KCsCaAsuIdReference |//	
+    //| CS_CA_ASU_ID_data       | LONG VARBINARY   | KCsCaAsuIdData      |//		
+    ////////////////////////////////////////////////////////////////////////
+    _LIT( KSqlCreateTable, "CREATE TABLE %S (\
+    	%S UNSIGNED INTEGER, \
+    	%S LONG VARBINARY)" );
+
+    sqlStatement.Format(
+    	KSqlCreateTable, &KCsCaAsuIdListTableName, 
+    	&KCsCaAsuIdReference,&KCsCaAsuIdData );
+
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::CreateCaAsuIdListTableL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );	
+
+    TInt err = iCsDb.Execute( sqlStatement );
+    if ( err != KErrNone && err != KErrAlreadyExists )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::CreateCaAsuIdListTableL() \
+        	iCsDb.Execute(), err=%d" ), err ) );
+        CleanupStack::PopAndDestroy( buf );
+	    User::Leave( err );
+        }
+    CleanupStack::PopAndDestroy( buf );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateCaAsuIdListTableL() OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::CreateCaAsuIdListTableL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CreateClientCertificateTableL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::CreateClientCertificateTableL()
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateClientCertificateTableL() IN\n" ) ) );    
+    
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+
+    // Table columns:
+    ////// NAME //////////// TYPE ///////////// Constant ////////////////////////////////////
+    //| CS_client_cert_ASU_ID_reference   | UNSIGNED INTEGER| KCsClientCertAsuIdReference |//	
+    //| CS_client_cert_data               | LONG VARBINARY  | KCsClientCertData           |//		
+    /////////////////////////////////////////////////////////////////////////////////////////
+    _LIT( KSqlCreateTable, "CREATE TABLE %S (\
+    	%S UNSIGNED INTEGER, \
+    	%S LONG VARBINARY)" );
+
+    sqlStatement.Format(
+    	KSqlCreateTable, &KCsClientCertificateTable, 
+    	&KCsClientCertAsuIdReference, &KCsClientCertData );
+    
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::CreateClientCertificateTableL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );	
+
+    TInt err = iCsDb.Execute( sqlStatement );
+    if ( err != KErrNone && err != KErrAlreadyExists )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::CreateClientCertificateTableL() \
+        	iCsDb.Execute(), err=%d" ), err ) );
+        CleanupStack::PopAndDestroy( buf );
+	    User::Leave(err);
+        }
+    CleanupStack::PopAndDestroy( buf );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateClientCertificateTableL() OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::CreateClientCertificateTableL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CreateCaCertificateTableL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::CreateCaCertificateTableL()
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateCaCertificateTableL() IN\n" ) ) );    
+    
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+
+    // Table columns:
+    ////// NAME //////////// TYPE ///////////// Constant ////////////////////////////
+    //| CS_client_cert_ASU_ID_reference   | UNSIGNED INTEGER| KCsClientCertAsuIdReference |//   
+    //| CS_CA_cert_data               | LONG VARBINARY  | KCsCaCertData           |//		
+    /////////////////////////////////////////////////////////////////////////////////
+    _LIT( KSqlCreateTable, "CREATE TABLE %S (\
+        %S UNSIGNED INTEGER, \
+    	%S LONG VARBINARY)" );
+
+    sqlStatement.Format(
+    	KSqlCreateTable, &KCsCaCertificateTable, 
+        &KCsCaCertAsuIdReference, &KCsCaCertData );
+    
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::CreateCaCertificateTableL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );	
+
+    TInt err = iCsDb.Execute( sqlStatement );
+    if ( err != KErrNone && err != KErrAlreadyExists )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::CreateCaCertificateTableL() \
+        	iCsDb.Execute(), err=%d" ), err ) );
+        CleanupStack::PopAndDestroy( buf );
+	    User::Leave( err );
+        }
+    CleanupStack::PopAndDestroy( buf );
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateCaCertificateTableL() OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::CreateCaCertificateTableL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CreatePrivateKeyTableL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::CreatePrivateKeyTableL()
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreatePrivateKeyTableL() IN\n" ) ) );
+    
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+
+    // Table columns:
+    ////// NAME ///////////////////////// TYPE ///////////// Constant /////////////////////
+    //| CS_private_key_ASU_ID_reference | UNSIGNED INTEGER| KCsPrivateKeyAsuIdReference |//	
+    //| CS_private_key_data             | LONG VARBINARY  | KCsPrivateKeyData           |//		
+    ///////////////////////////////////////////////////////////////////////////////////////
+    _LIT( KSqlCreateTable, "CREATE TABLE %S (\
+    	%S UNSIGNED INTEGER, \
+    	%S LONG VARBINARY)" );
+
+    sqlStatement.Format(
+    	KSqlCreateTable, &KCsPrivateKeyTable, 
+    	&KCsPrivateKeyAsuIdReference, &KCsPrivateKeyData );
+    
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::CreatePrivateKeyTableL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );	
+
+    TInt err = iCsDb.Execute( sqlStatement );
+    if ( err != KErrNone && err != KErrAlreadyExists )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::CreatePrivateKeyTableL() \
+        	iCsDb.Execute(), err=%d" ), err ) );
+        CleanupStack::PopAndDestroy( buf );
+	    User::Leave( err );
+        }
+    CleanupStack::PopAndDestroy( buf );
+        
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreatePrivateKeyTableL() OUT\n" ) ) );
+    }
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CreateWapiCertLabeltableL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::CreateWapiCertLabeltableL()
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateWapiCertLabeltableL() IN\n" ) ) );
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+
+    // Table columns:
+    ////// NAME ///////////////////////// TYPE ///////////// Constant //////////////////
+    //| wapi_cs_cert_ASU_ID_reference | UNSIGNED INTEGER  |KCsCertLabelAsuIdReference|//	
+    //| CS_CA_cert_label              | LONG VARBINARY    | KCsCACertLabel           |//		
+    //| CS_user_cert_label            | LONG VARBINARY 	  | KCsUserCertLabel         |//
+    ////////////////////////////////////////////////////////////////////////////////////
+
+    _LIT( KSqlCreateTable, "CREATE TABLE %S (\
+        %S UNSIGNED INTEGER, \
+    	%S LONG VARBINARY,	\
+		%S LONG VARBINARY)");
+
+    sqlStatement.Format( KSqlCreateTable, &KCsWapiCertLabelTable, 
+                        &KCsCertLabelAsuIdReference, 
+    					&KCsCACertLabel,
+    					&KCsUserCertLabel );
+	 
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+        "CCertificateStoreDatabase::CreateWapiCertLabeltableL() sqlStatement",
+        sqlStatement.Ptr(), 
+        sqlStatement.Size() ) );    
+ 
+    TInt err = iCsDb.Execute( sqlStatement );
+    if ( err != KErrNone && err != KErrAlreadyExists )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::CreateWapiCertLabeltableL() \
+        	iCsDb.Execute(), err=%d" ), err ) );
+            CleanupStack::PopAndDestroy( buf );
+	    	User::Leave( err );
+        }
+    CleanupStack::PopAndDestroy( buf );
+        
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateWapiCertLabeltableL() OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::CreateWapiCertLabeltableL()
+
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CreateWapiCertFiletableL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::CreateWapiCertFiletableL()
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateWapiCertFiletableL() IN\n" ) ) );
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+
+    // Table columns:
+    ////// NAME ///////////////////////// TYPE ///////////// Constant /////////////////
+    //| CS_filename                   | VARBINARY    | KCsFileName                  |//    
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    _LIT( KSqlCreateTable, "CREATE TABLE %S (%S VARBINARY)");
+
+    sqlStatement.Format( KSqlCreateTable, &KCsWapiCertFileTable, 
+                        &KCsFileName );
+     
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+        "CCertificateStoreDatabase::CreateWapiCertFiletableL() sqlStatement",
+        sqlStatement.Ptr(), 
+        sqlStatement.Size() ) );    
+
+    TInt err = iCsDb.Execute( sqlStatement );
+    if ( err != KErrNone && err != KErrAlreadyExists )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: CCertificateStoreDatabase::CreateWapiCertFiletableL() \
+            iCsDb.Execute(), err=%d" ), err ) );
+            CleanupStack::PopAndDestroy( buf );
+            User::Leave( err );
+        }
+    CleanupStack::PopAndDestroy( buf );
+        
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::CreateWapiCertFiletableL() OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::CreateWapiCertFiletableL()
+
+// ================= private:  Operations with view =======================
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::GetLongBinaryDataL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::GetLongBinaryDataL(
+	RDbView& aView,	HBufC8** aOutColumnValue )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetLongBinaryDataL() IN\n" ) ) );
+
+	// Get the value from DB.
+	*aOutColumnValue = HBufC8::NewLC(
+		aView.ColLength( KDefaultColumnNumberOne ) ); // Buffer for the data.
+	TPtr8 outColumnValuePtr8 = ( *aOutColumnValue )->Des();
+	
+    RDbColReadStream readStream;
+	readStream.OpenLC( aView, KDefaultColumnNumberOne );
+	readStream.ReadL( outColumnValuePtr8, aView.ColLength( KDefaultColumnNumberOne ) );
+	readStream.Close();
+	CleanupStack::Pop( &readStream );
+	
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"CCertificateStoreDatabase::GetLongBinaryDataL() LONG BINARY value from DB",
+		outColumnValuePtr8.Ptr(), outColumnValuePtr8.Size() ) );
+		
+	CleanupStack::Pop( *aOutColumnValue );
+ 
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetLongBinaryDataL() OUT\n" ) ) );
+    
+	} // CCertificateStoreDatabase::GetLongBinaryDataL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::GetBinaryDataL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::GetBinaryDataL(
+	RDbView& aView,	HBufC8** aOutColumnValue )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetBinaryDataL() IN\n" ) ) );
+
+	TPtrC8 dbValuePtrC8 = aView.ColDes8( KDefaultColumnNumberOne );
+
+	*aOutColumnValue = HBufC8::NewLC( dbValuePtrC8.Size() ); // Buffer for the data.
+	TPtr8 outColumnValuePtr8 = ( *aOutColumnValue )->Des();
+		
+	outColumnValuePtr8.Copy( dbValuePtrC8 );
+
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"CCertificateStoreDatabase::GetBinaryDataL() BINARY value from DB",
+		outColumnValuePtr8.Ptr(), outColumnValuePtr8.Size() ) );
+		
+	CleanupStack::Pop( *aOutColumnValue );
+				
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetBinaryDataL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::GetBinaryDataL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::GetTableDataL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::GetTableDataL( RDbView& aView, RArray<SWapiCertEntry>& aArray )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetTableDataL() IN\n" ) ) );
+
+	HBufC8* aOutColumnValue = NULL;
+	
+	if ( aView.FirstL())
+	        {
+	        do
+	            {
+	        
+	            SWapiCertEntry aEntry;
+	        
+                aView.GetL();        
+                EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                    "CCertificateStoreDatabase::GetTableDataL() aView.GetL() OK.\n" ) ) );
+            
+                for (TInt aColNumber = 1; aColNumber<3 ; aColNumber++ )
+                    {
+                    switch ( aView.ColType( aColNumber ) )
+                        {
+                        case EDbColText:                
+                            {
+                            // Buffer for unicode parameter
+                            HBufC* unicodebuf = HBufC::NewLC(aView.ColLength( aColNumber ));
+                            TPtr unicodeString = unicodebuf->Des();
+                            unicodeString = aView.ColDes(aColNumber);
+                            // Convert to 8-bit
+                            if (unicodeString.Size() > 0)
+                                {
+                                aOutColumnValue = HBufC8::NewLC(
+                                    aView.ColLength( aColNumber ) ); // Buffer for the data.
+                                TPtr8 outColumnValuePtr8 = ( aOutColumnValue )->Des();
+                                outColumnValuePtr8.Copy(unicodeString);
+                                 if (outColumnValuePtr8.Size() == 0)
+                                {
+                                    User::Leave(KErrNoMemory);
+                                }
+                                 CleanupStack::Pop( aOutColumnValue );
+                
+                            } 
+                            else 
+                                {
+                                    // Empty field. Do nothing...data remains invalid
+                                }
+                            CleanupStack::PopAndDestroy(unicodebuf);
+                            if(aColNumber == 1)
+                                aEntry.iReference = aOutColumnValue;
+                            else
+                                aEntry.iData = aOutColumnValue;
+               
+                            break;
+                            }
+                         case EDbColUint32:
+                                {
+                                    TUint value;
+                                    value = eap_htonl(aView.ColUint32(aColNumber));
+                                    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                                        "CCertificateStoreDatabase::GetTableDataL() \
+                                        uint32 value=%d" ), value ) );
+
+                                    aOutColumnValue = HBufC8::NewLC(
+                                        aView.ColLength( aColNumber ) ); // Buffer for the data.
+                                    TPtr8 outColumnValuePtr8 = ( aOutColumnValue )->Des();
+                                    outColumnValuePtr8.Copy((const unsigned char *)&value, sizeof(TUint));
+                                    if (outColumnValuePtr8.Size() == 0)
+                                    {
+                                        User::Leave(KErrNoMemory);
+                                    }
+                                    CleanupStack::Pop( aOutColumnValue );
+                                    if (outColumnValuePtr8.Size() == 0)
+                                    {
+                                        User::Leave(KErrNoMemory);
+                                    }
+                                    if(aColNumber == 1)
+                                        aEntry.iReference = aOutColumnValue;
+                                    else
+                                        aEntry.iData = aOutColumnValue;
+                               }
+                                
+                                break;
+                
+                        case EDbColBinary:
+                            {
+                            EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                                "CCertificateStoreDatabase::GetTableDataL() \
+                                Binary column.\n" ) ) );            
+                            GetBinaryDataL( aView, &aOutColumnValue );
+                            break;
+                            }
+                        case EDbColLongBinary:              
+                            {
+                            EAP_TRACE_DEBUG_SYMBIAN(
+                                (_L("CCertificateStoreDatabase::GetTableDataL - Long Binary column\n")));
+                        
+                            RDbColReadStream readStream;
+                        
+                            // Get the value from DB.
+                            HBufC8* valueBuf = HBufC8::NewLC(aView.ColLength(aColNumber)); // Buffer for the data.
+                            TPtr8 value8 = valueBuf->Des();
+                            
+                            readStream.OpenLC(aView, aColNumber);
+                            readStream.ReadL(value8, aView.ColLength(aColNumber));
+                            readStream.Close();
+                            CleanupStack::Pop(&readStream);
+                            
+                            EAP_TRACE_DATA_DEBUG_SYMBIAN(
+                                ("CCertificateStoreDatabase::GetTableDataL: LONG BINARY value from DB",
+                                value8.Ptr(), 
+                                value8.Size()));
+                            
+                            HBufC8 *aDbBinaryColumnValue = HBufC8::NewLC(value8.Size());
+                            TPtr8 aDbBinaryColumnValuePtr = (aDbBinaryColumnValue)->Des();         
+        
+                            aDbBinaryColumnValuePtr.Copy(value8);
+                            EAP_TRACE_DATA_DEBUG_SYMBIAN(
+                                ("CCertificateStoreDatabase::GetTableDataL: LONG BINARY value to caller",
+                                    aDbBinaryColumnValuePtr.Ptr(), 
+                                    aDbBinaryColumnValuePtr.Size()));
+                            
+                            CleanupStack::Pop(aDbBinaryColumnValue);
+                            CleanupStack::PopAndDestroy(valueBuf);
+                            
+                            if(aColNumber == 1)
+                                aEntry.iReference = aDbBinaryColumnValue;
+                            else
+                                aEntry.iData = aDbBinaryColumnValue;
+                           break;
+                            }       
+                        default:
+                            {
+                            EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                                "ERROR: CCertificateStoreDatabase::GetTableDataL() \
+                                Unsupported DB field:%d\n" ),
+                                aView.ColType( aColNumber ) ) );    
+                            User::Leave( KErrNotSupported );
+                            break;
+                            }
+                        } // switch ( aView.ColType( KDefaultColumnNumberOne ) )
+               
+                    } // for
+                aArray.Append(aEntry);
+	            }while (aView.NextL() != EFalse);
+	        } // if ( aView.FirstL() )
+			
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetTableDataL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::GetBinaryDataL()
+
+		
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::InsertDataAndReferenceL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::InsertDataAndReferenceL(
+	RDbView& aView,
+	const TDesC& aReferenceColumnName,
+	const TDesC& aDataColumnName,
+	const TDesC16& aDataReference16,
+	const TDesC8& aColumnValue )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::InsertCsDataByReferenceL IN1\n" ) ) );
+	
+    // Convert the received reference id into integer.. 
+    TUint intRef = eap_read_u32_t_network_order(
+            aDataReference16.Ptr(),
+            aDataReference16.Size());
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ( "CCertificateStoreDatabase::InsertCsDataByReferenceL1() \
+            New entry: reference set to DB(TEXT)=%d\n" ), intRef ) );
+    
+   InsertDataAndReferenceL ( aView, aReferenceColumnName, aDataColumnName, intRef, aColumnValue );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::InsertDataAndReferenceL OUT1\n" ) ) );
+
+	} // CCertificateStoreDatabase::InsertDataAndReferenceL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::InsertDataAndReferenceL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::InsertDataAndReferenceL(
+    RDbView& aView,
+    const TDesC& aReferenceColumnName,
+    const TDesC& aDataColumnName,
+    const TUint aDataRef,
+    const TDesC8& aColumnValue )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::InsertDataAndReferenceL IN1\n" ) ) );
+     
+    aView.InsertL();
+
+    // There are two columns here to set. Value and reference.  
+    // Get column set so we get the correct column numbers
+    CDbColSet* colSet = aView.ColSetL();
+    CleanupStack::PushL( colSet );
+
+    TDbColNo colNoReference = colSet->ColNo( aReferenceColumnName );
+    TDbColNo colNoValue = colSet->ColNo( aDataColumnName );
+            
+    aView.SetColL( colNoReference, aDataRef );
+            
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ( "CCertificateStoreDatabase::InsertDataAndReferenceL1() \
+            New entry: reference set to DB(TEXT)=%d\n" ), aDataRef ) );
+    
+    // Set the value.
+    HBufC8* valueBuf = HBufC8::NewLC( aColumnValue.Size() );
+    TPtr8 valuePtr8 = valueBuf->Des();      
+    valuePtr8.Copy( aColumnValue);      
+    aView.SetColL( colNoValue, valuePtr8 );
+            
+     EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+        "CCertificateStoreDatabase::InsertDataAndReferenceL1() \
+        New entry:Value set to DB",
+        valuePtr8.Ptr(), valuePtr8.Size() ) );
+    
+    CleanupStack::PopAndDestroy( valueBuf );        
+    CleanupStack::PopAndDestroy( colSet );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::InsertDataAndReferenceL1 OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::InsertDataAndReferenceL()
+    
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::InsertDataAndReferenceL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::InsertDataAndReferenceL(
+    RDbView& aView,
+    const TDesC& aReferenceColumnName,
+    const TDesC& aDataColumnName,
+    const TUint aDataRef,
+    const TDesC& aColumnValue )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::InsertDataAndReferenceL IN\n" ) ) );
+    
+    aView.InsertL();
+
+    // There are two columns here to set. Value and reference.  
+    // Get column set so we get the correct column numbers
+    CDbColSet* colSet = aView.ColSetL();
+    CleanupStack::PushL( colSet );
+
+    TDbColNo colNoReference = colSet->ColNo( aReferenceColumnName );
+    TDbColNo colNoValue = colSet->ColNo( aDataColumnName );
+            
+    aView.SetColL( colNoReference, aDataRef );
+            
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ( "CCertificateStoreDatabase::InsertDataAndReferenceL() \
+            New entry: reference set to DB(TEXT)=%d\n" ), &aDataRef ) );
+    
+    // Set the value.
+    aView.SetColL( colNoValue, aColumnValue );
+            
+    CleanupStack::PopAndDestroy( colSet );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::InsertDataAndReferenceL OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::InsertDataAndReferenceL()
+    
+
+// CCertificateStoreDatabase::InsertDataL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::InsertDataL(
+	RDbView& aView,
+	const TDesC& aDataColumnName,
+	const TDesC8& aColumnValue )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::InsertDataL() IN\n" ) ) );
+	
+	aView.InsertL();
+
+	// There is only one column here to set: data value.	
+	// Get column set so we get the correct column number.
+	CDbColSet* colSet = aView.ColSetL();
+	CleanupStack::PushL( colSet );
+	TDbColNo colNoValue = colSet->ColNo( aDataColumnName );
+				
+	// Set the value.
+	HBufC8* valueBuf = HBufC8::NewLC( aColumnValue.Size() );
+	TPtr8 valuePtr8 = valueBuf->Des();		
+	valuePtr8.Copy( aColumnValue);		
+	aView.SetColL( colNoValue, valuePtr8 );
+			
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"CCertificateStoreDatabase::InsertDataL() \
+		New entry: value set to DB",
+	    valuePtr8.Ptr(), valuePtr8.Size() ) );
+	
+	// clean
+	CleanupStack::PopAndDestroy( valueBuf );		
+	CleanupStack::PopAndDestroy( colSet );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::InsertDataL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::InsertDataAndReferenceL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::UpdateColOneRowOneL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::UpdateColOneRowOneL(
+	RDbView& aView, const TDesC8& aColumnValue )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::UpdateColOneRowOneL() IN\n" ) ) );
+	
+	if ( aView.IsEmptyL() ||
+		 aView.CountL() > KDefaultColumnNumberOne  ||
+		 aView.ColCount() == 0 ||
+		 aView.ColCount() > KDefaultColumnNumberOne  )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			"ERROR: CCertificateStoreDatabase::UpdateColOneRowOneL() \
+			Problem with rows or columns in DB view, row count=%d, col count=%d \n" ),
+			aView.CountL(), aView.ColCount() ) );
+			User::Leave( KErrNotFound );				
+		}	
+	if ( aView.FirstL() )
+		{			
+		aView.UpdateL(); // Here it is update.							
+		switch ( aView.ColType( KDefaultColumnNumberOne ) )
+			{
+			case EDbColText:				
+				{
+				// This value can be set as it is. The column is default 1 here.
+				aView.SetColL( KDefaultColumnNumberOne, aColumnValue );
+				break;
+				}
+            case EDbColUint32:
+                {
+                TUint aIntVal = eap_read_u32_t_network_order(
+                        aColumnValue.Ptr(),
+                        aColumnValue.Size());
+                aView.SetColL( KDefaultColumnNumberOne, aIntVal );
+                }
+                break;
+
+			case EDbColBinary:
+				{
+				aView.SetColL( KDefaultColumnNumberOne, aColumnValue );					
+				break;
+				}
+			case EDbColLongBinary:				
+				{
+			    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+					"CCertificateStoreDatabase::UpdateColOneRowOneL() \
+					Long binary column.\n" ) ) );
+				// A stream is needed for LONG columns in DB.
+				RDbColWriteStream writeStream;					
+				writeStream.OpenLC( aView, KDefaultColumnNumberOne );
+				writeStream.WriteL( aColumnValue );
+				writeStream.Close();
+				CleanupStack::Pop( &writeStream );
+				break;
+				}
+			default:
+				{
+			    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+					"ERROR: CCertificateStoreDatabase::UpdateColOneRowOneL() \
+					Unsupported DB field! \n" ) ) );	
+				User::Leave( KErrNotSupported );
+				}
+			} // switch ( aView.ColType( KDefaultColumnNumberOne ) )
+		} // if ( aView.FirstL() )
+	else
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			"ERROR: CCertificateStoreDatabase::UpdateColOneRowOneL() \
+			There are no rows in view.\n" ) ) );
+		User::Leave( KErrNotFound );
+		}
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::UpdateColOneRowOneL() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::UpdateColOneRowOneL()
+
+
+// ================= private:  Other =======================
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::ConvertFromBuf8ToBuf16LC()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::ConvertFromBuf8ToBuf16LC(
+	const TDesC8& aInBuf8, HBufC16** aOutBuf16 )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::ConvertFromBuf8ToBuf16LC() IN\n" ) ) );
+    
+	// convert utf8->unicode,
+	// aInBuf8 is UTF8 string, unicode max length is
+	// then the length of UTF8 string.
+	// NOTE, HBufC16 length means count of 16-bit objects.
+	*aOutBuf16 = HBufC16::NewLC( aInBuf8.Size() );
+	TPtr16 outBufPtr16 = ( *aOutBuf16 )->Des();
+
+	const TPtrC8 inBufPtrC8( aInBuf8 );
+
+	CnvUtfConverter::ConvertToUnicodeFromUtf8( outBufPtr16, inBufPtrC8 );
+
+	// print data
+	EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::ConvertFromBuf8ToBuf16LC() aInBuf8" ),
+        inBufPtrC8.Ptr(), inBufPtrC8.Size() ) );
+	
+    EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "CCertificateStoreDatabase::ConvertFromBuf8ToBuf16LC() aOutBuf16" ),
+	    outBufPtr16.Ptr(), outBufPtr16.Size() ) );
+	
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::ConvertFromBuf8ToBuf16LC() OUT\n" ) ) );
+
+	} // CCertificateStoreDatabase::ConvertFromBuf8ToBuf16LC()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::ConvertFromBuf16ToBuf8LC()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::ConvertFromBuf16ToBuf8LC(
+	const TDesC16& aInBuf16, HBufC8** aOutBuf8 )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::ConvertFromBuf16ToBuf8LC() IN\n" ) ) );
+
+    // "In UTF-8, characters are encoded using sequences of 1 to 6 octets."
+    // RFC2279 - UTF-8
+    const TUint KMaxNumberOfOctetsPerUtf8Char = 6;
+	// Convert unicode->utf8.
+	// Note, HBufC16 length means the number of 16-bit values or
+    // data items represented by the descriptor.
+    // Multiply number of charachters by max number of octets for char.
+	*aOutBuf8 = HBufC8::NewLC( aInBuf16.Length() * KMaxNumberOfOctetsPerUtf8Char );
+	TPtr8 outBufPtr8 = ( *aOutBuf8 )->Des();
+
+	const TPtrC16 inBufPtrC16( aInBuf16 );
+	
+	CnvUtfConverter::ConvertFromUnicodeToUtf8( outBufPtr8, inBufPtrC16 );
+  
+	// print data
+	EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "CCertificateStoreDatabase::ConvertFromBuf16ToBuf8LC() aInBuf16" ),
+	    inBufPtrC16.Ptr(), inBufPtrC16.Size() ) );
+   	
+	EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"CCertificateStoreDatabase::ConvertFromBuf16ToBuf8LC() aOutBuf8" ),
+		outBufPtr8.Ptr(), outBufPtr8.Size() ) );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::ConvertFromBuf16ToBuf8LC() OUT\n" ) ) );	
+	
+	} // CCertificateStoreDatabase::ConvertFromBuf16ToBuf8LC()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::WriteCertificateStoreStateL()
+// ---------------------------------------------------------
+void CCertificateStoreDatabase::WriteCertificateStoreStateL(
+	TCertificateStoreState aState )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::WriteCertificateStoreStateL() IN, \
+        aState=%d.\n" ), aState ) );
+	    
+    // There could be a case where CS DB is destroyed.
+    // We just return in that case. 
+    if ( !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "CCertificateStoreDatabase::SetUserCertL() CS not created.\n" ) ) );
+        OpenCertificateStoreL();
+        }  
+
+    if ( !iCsSessionOpened )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			"ERROR: CCertificateStoreDatabase::WriteCertificateStoreStateL() \
+			CS store not opened!\n" ) ) );		
+		User::Leave( KErrSessionClosed );
+		}		
+				
+	HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+	TPtr sqlStatement = buf->Des();
+				
+	_LIT( KSqlQuery, "SELECT %S FROM %S" );
+	sqlStatement.Format(
+		KSqlQuery,
+		&KCsInitialized,
+		&KCsGeneralSettingsTableName );
+
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::WriteCertificateStoreStateL() sqlStatement",
+		sqlStatement.Ptr(), 
+		sqlStatement.Size() ) );	
+
+ 	RDbView view;
+		
+	User::LeaveIfError( view.Prepare(
+		iCsDb, 
+	    TDbQuery( sqlStatement ), 
+		TDbWindow::EUnlimited ) );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::WriteCertificateStoreStateL() \
+        View prepared OK.\n" ) ) );	   
+	CleanupClosePushL( view );
+		
+	User::LeaveIfError( view.EvaluateAll() );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"CCertificateStoreDatabase::WriteCertificateStoreStateL() \
+		View evaluated OK.\n" ) ) );
+		
+	if ( !view.FirstL() )
+		{		
+		view.InsertL();
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+    		"CCertificateStoreDatabase::WriteCertificateStoreStateL() \
+    		View inserted OK.\n" ) ) );
+		}
+	else
+		{
+	    view.UpdateL();
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    	"CCertificateStoreDatabase::WriteCertificateStoreStateL() \
+	    	View updated OK.\n" ) ) );
+		}
+	
+	// Get column set so we get the correct column numbers
+	CDbColSet* colSet = view.ColSetL();
+	CleanupStack::PushL( colSet );
+						
+	view.SetColL( colSet->ColNo( KCsInitialized ), aState );
+						
+	CleanupStack::PopAndDestroy( colSet ); // Delete colSet
+					
+	// Now it should go to the DB.
+	view.PutL();	
+
+	CleanupStack::PopAndDestroy( &view ); // Close view.	
+	CleanupStack::PopAndDestroy( buf ); // Delete buf or sqlStatement.		
+		
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::WriteCertificateStoreStateL() OUT\n" ) ) );
+    
+	} // CCertificateStoreDatabase::WriteCertificateStoreStateL()
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::GetDbNamesFromDataTypeL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::GetDbNamesFromDataTypeL(
+	ec_cs_data_type_e aDataType, TDes& aTableName,
+	TDes& aReferenceColumnName, TDes& aDataColumnName )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetDbNamesFromDataTypeL() IN\n" ) ) );
+
+    switch ( aDataType )
+        {
+	    case ec_cs_data_type_ca_certificate_data:
+		    {
+		    aTableName = KCsCaCertificateTable;
+		    aReferenceColumnName = KCsCaCertAsuIdReference;
+		    aDataColumnName = KCsCaCertData;
+		    break;
+		    }
+	    case ec_cs_data_type_client_certificate_data:
+		    {
+		    aTableName = KCsClientCertificateTable;
+		    aReferenceColumnName = KCsClientCertAsuIdReference;
+		    aDataColumnName = KCsClientCertData;
+		    break;
+		    }
+	    case ec_cs_data_type_private_key_data:
+		    {
+		    aTableName = KCsPrivateKeyTable;
+		    aReferenceColumnName = KCsPrivateKeyAsuIdReference;
+		    aDataColumnName = KCsPrivateKeyData;
+		    break;
+		    }
+        case ec_cs_data_type_ca_asu_id:
+        case ec_cs_data_type_ca_asu_id_list:
+           {
+            aTableName = KCsCaAsuIdListTableName;
+            aReferenceColumnName = KCsCaAsuIdReference;
+            aDataColumnName = KCsCaAsuIdData;
+            break;
+            }
+        case ec_cs_data_type_client_asu_id:
+        case ec_cs_data_type_client_asu_id_list:
+            {
+            aTableName = KCsClientAsuIdListTableName;
+            aReferenceColumnName = KCsClientAsuIdReference;
+            aDataColumnName = KCsClientAsuIdData;
+            break;
+            }
+        case ec_cs_data_type_master_key:
+            {
+            aTableName = KCsGeneralSettingsTableName;
+            aReferenceColumnName = NULL;
+            aDataColumnName = KCsMasterKey;
+            break;
+            }
+        case ec_cs_data_type_reference_counter:
+            {
+            aTableName = KCsGeneralSettingsTableName;
+            aReferenceColumnName = NULL;
+            aDataColumnName = KCsReferenceCounter;          
+            break;
+            }
+        case ec_cs_data_type_selected_ca_id:
+            {
+            aTableName = KCsWapiCertLabelTable;
+            aReferenceColumnName = KCsCertLabelAsuIdReference;
+            aDataColumnName = KCsCACertLabel;          
+            break;
+            }
+       case ec_cs_data_type_selected_client_id:
+           {
+           aTableName = KCsWapiCertLabelTable;
+           aReferenceColumnName = KCsCertLabelAsuIdReference;
+           aDataColumnName = KCsUserCertLabel;          
+           break;
+           }
+ 		// ... add other types when needed
+        default:
+        	{
+		    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	            "ERROR: wapi_am_core_symbian_c::GetDbNamesFromDataTypeL() \
+	            unknown dataType=%d.\n" ), aDataType ) );
+			User::Leave( KErrArgument );	    	
+    	    }
+        } // switch
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetDbNamesFromDataTypeL() OUT\n" ) ) );
+
+    } // CCertificateStoreDatabase::GetDbNamesFromDataTypeL
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::GetDbNamesFromDataTypeL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::GetDbNamesFromDataTypeL(
+	ec_cs_data_type_e aDataType,
+	TDes& aTableName,
+	TDes& aDataColumnName )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::GetDbNamesFromDataTypeL() IN\n" ) ) );
+
+    switch ( aDataType )
+	    {
+		case ec_cs_data_type_master_key:
+			{
+		    aTableName = KCsGeneralSettingsTableName;
+		    aDataColumnName = KCsMasterKey;
+			break;
+			}
+		case ec_cs_data_type_reference_counter:
+			{
+		    aTableName = KCsGeneralSettingsTableName;
+		    aDataColumnName = KCsReferenceCounter;			
+			break;
+			}
+        case ec_cs_data_type_ca_certificate_data:
+            {
+            aTableName = KCsCaCertificateTable;
+            aDataColumnName = KCsCaCertData;
+            break;
+            }
+        case ec_cs_data_type_client_certificate_data:
+            {
+            aTableName = KCsClientCertificateTable;
+            aDataColumnName = KCsClientCertData;
+            break;
+            }
+        case ec_cs_data_type_ca_asu_id:
+        case ec_cs_data_type_ca_asu_id_list:
+           {
+            aTableName = KCsCaAsuIdListTableName;
+            // only table needed
+            break;
+            }
+        case ec_cs_data_type_client_asu_id:
+        case ec_cs_data_type_client_asu_id_list:
+            {
+            aTableName = KCsClientAsuIdListTableName;
+            // only table needed
+            break;
+            }
+        case ec_cs_data_type_selected_ca_id:
+            {
+            aTableName = KCsWapiCertLabelTable;
+            aDataColumnName = KCsCACertLabel;          
+            break;
+            }
+       case ec_cs_data_type_selected_client_id:
+           {
+           aTableName = KCsWapiCertLabelTable;
+           aDataColumnName = KCsUserCertLabel;          
+           break;
+            }
+			// ... add other types when needed	
+	    default:
+	    	{
+		    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	            "ERROR: wapi_am_core_symbian_c::GetDbNamesFromDataTypeL() \
+	            unknown dataType=%d.\n" ), aDataType ) );
+			User::Leave( KErrArgument );	    	
+		    }
+	    } // switch
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "CCertificateStoreDatabase::GetDbNamesFromDataTypeL() OUT\n" ) ) );		
+	
+	} // CCertificateStoreDatabase::GetDbNamesFromDataTypeL()
+
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::SetCACertL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::SetCACertL( const TInt aId, const TBuf8<KMaxIdentityLength> aSelectedCert )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ("CCertificateStoreDatabase::SetCACertL -Start")) );
+
+    SetCertL( aId, aSelectedCert, KCsCACertLabel );
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+                ("CCertificateStoreDatabase::SetCACertL -End")) );
+    return;
+	}
+                                  
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::SetUserCertL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::SetUserCertL( const TInt aId, const TBuf8<KMaxIdentityLength> aSelectedCert )
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+	        ("CCertificateStoreDatabase::SetUserCertL -Start")) );
+
+	SetCertL( aId, aSelectedCert, KCsUserCertLabel );
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+	            ("CCertificateStoreDatabase::SetUserCertL -End")) );
+    return;
+    }
+
+
+void CCertificateStoreDatabase::SetCertL ( const TInt aId, 
+        const TBuf8<KMaxIdentityLength> aSelectedCert, 
+        const TDesC& aParameterName )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ("CCertificateStoreDatabase::SetCertL -Start")) );
+
+    if ( !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "CCertificateStoreDatabase::SetUserCertL() CS not created.\n" ) ) );
+        OpenCertificateStoreL();
+        }  
+    
+    if ( !iCsSessionOpened )
+        {
+        EAP_TRACE_ERROR(
+            iAmTools,
+            TRACE_FLAGS_DEFAULT,
+            (EAPL("ERROR: CCertificateStoreDatabase::SetCertL() \
+                    CS store not opened!\n")));        
+        User::Leave( KErrSessionClosed );
+        } 
+        
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+        "CCertificateStoreDatabase::SetCertL() aSelectedCert",
+        aSelectedCert.Ptr(), 
+        aSelectedCert.Size() ) );    
+   
+    // Two SQL statements, one for addition and one for modification
+    _LIT(KSQLQuery, "SELECT %S FROM %S WHERE %S=%d");
+    _LIT(KSQLInsert, "SELECT * FROM %S");
+            
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+    sqlStatement.Format( KSQLQuery, &aParameterName, &KCsWapiCertLabelTable, &KCsCertLabelAsuIdReference, aId );
+        
+    // Prepare the view, leave if it fails
+    RDbView view;   
+    User::LeaveIfError(view.Prepare( iCsDb, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EUpdatable));
+    User::LeaveIfError(view.EvaluateAll()); 
+    CleanupClosePushL(view);
+        
+    // Update the data if the record exists
+    if (view.FirstL())
+        {
+        view.UpdateL();
+        // Get column set so we get the correct column numbers
+        CDbColSet* colSet = view.ColSetL();
+        CleanupStack::PushL(colSet);
+        view.SetColL( colSet->ColNo( aParameterName ), aSelectedCert ); 
+        view.PutL(); 
+        CleanupStack::PopAndDestroy( colSet );
+        }
+    // New row. Modify the sql statement for insertion
+    else
+        {
+        sqlStatement.Format( KSQLInsert, &KCsWapiCertLabelTable );
+        // Leave if the view preparation still fails
+        User::LeaveIfError ( view.Prepare( iCsDb, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EInsertOnly ));
+        User::LeaveIfError(view.EvaluateAll());
+        // Use the data insertion function to update data and reference
+        InsertDataAndReferenceL ( view, KCsCertLabelAsuIdReference, aParameterName, aId, aSelectedCert );  
+        view.PutL(); 
+        }
+         
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ("CCertificateStoreDatabase::SetCertL - labels read")) );
+    CleanupStack::PopAndDestroy( &view );
+    CleanupStack::PopAndDestroy( buf );
+    return;
+    }
+        
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::GetConfigurationL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::GetConfigurationL( const TInt aId, TDes& aCACert, TDes& aUserCert )
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+	        ("CCertificateStoreDatabase::GetConfigurationL -Start")) );
+	
+	_LIT(KEmpty, "None");
+	// Initialize with not found
+    aCACert.Copy( KEmpty );
+    aUserCert.Copy( KEmpty );
+
+    // Check whether db exists and connection is open. 
+	// Zero values are returned if not 
+    if ( !iCsSessionOpened || !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "CCertificateStoreDatabase::GetConfigurationL() \
+                CS not opened.\n" ) ) );
+        }
+    else
+        {  
+        HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+        TPtr sqlStatement = buf->Des();
+        
+	    // Read ca certificate label value
+	    _LIT(KSQLQuery, "SELECT %S FROM %S WHERE %S=%d");
+	    sqlStatement.Format( KSQLQuery, &KCsCACertLabel, &KCsWapiCertLabelTable, 
+	                        &KCsCertLabelAsuIdReference, aId );
+	    
+	    RDbView view;   
+	    User::LeaveIfError(view.Prepare( iCsDb, TDbQuery(sqlStatement), 
+	                            TDbWindow::EUnlimited, RDbView::EReadOnly));
+	    CleanupClosePushL(view);
+	    User::LeaveIfError(view.EvaluateAll()); 
+	  
+	    // Read the CA cert label
+        ReadLabelTableL( view, aCACert );
+	        
+	    // Read the User cert label
+	    sqlStatement.Format( KSQLQuery, &KCsUserCertLabel, &KCsWapiCertLabelTable, 
+	                            &KCsCertLabelAsuIdReference, aId );         
+	    User::LeaveIfError(view.Prepare( iCsDb, TDbQuery(sqlStatement), 
+	                                    TDbWindow::EUnlimited, RDbView::EReadOnly));
+	    User::LeaveIfError(view.EvaluateAll()); 
+	    
+	    ReadLabelTableL( view, aUserCert );
+
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+	            ("CCertificateStoreDatabase::GetConfigurationL - labels read")) );
+
+	    // Close database
+	    CleanupStack::PopAndDestroy( &view );
+	    CleanupStack::PopAndDestroy( buf );
+	    } 
+	return;
+	}
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::ReadLabelTable()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::ReadLabelTableL( RDbView& aView, TDes& aCert )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ("CCertificateStoreDatabase::ReadLabelTableL -Start")) );
+    
+    HBufC8* value;
+    eap_variable_data_c subjectName(iAmTools);
+    eap_variable_data_c label(iAmTools); 
+    wapi_asn1_der_parser_c wapiAsn1(iAmTools);
+    // Check memory reservations and leave if failed
+    if (wapiAsn1.get_is_valid() == false || 
+        subjectName.get_is_valid() == false ||
+        label.get_is_valid() == false )
+        {
+        EAP_TRACE_ERROR(
+            iAmTools,
+            TRACE_FLAGS_DEFAULT,
+            (EAPL("ERROR: CCertificateStoreDatabase::ReadLabelTableL() \
+                    Memory allocation failed!\n")));  
+        User::Leave(KErrGeneral);
+        }
+    
+    // check if there are rows in the view
+    if (aView.FirstL())
+        {
+        aView.GetL();
+        // Store the data     
+        GetLongBinaryDataL( aView, &value );
+        CleanupStack::PushL(value);
+        
+        // If the label exists, it will be decoded
+        if ( value->Size() > 0 )
+            {
+            eap_status_e status = label.set_copy_of_buffer( value->Ptr(), value->Size() );
+            CleanupStack::PopAndDestroy( value );
+            if ( status != eap_status_ok )
+                {
+                User::Leave(KErrGeneral);
+                }
+            
+            status = wapiAsn1.get_decoded_subject_name( &label, &subjectName );
+            if ( status != eap_status_ok )
+                {
+                EAP_TRACE_ERROR(
+                        iAmTools,
+                        TRACE_FLAGS_DEFAULT,
+                            (EAPL("ERROR: CCertificateStoreDatabase::ReadLabelTable() \
+                            decoding failed!\n")));  
+                User::Leave(KErrGeneral);
+                }
+            
+            // Check the lenght of the subject name part of the label,
+            if ( subjectName.get_data_length() <= KCsMaxWapiCertLabelLength )
+                {
+                TBuf8<KCsMaxWapiCertLabelLength> tmpLabel;
+                tmpLabel.Append( subjectName.get_data(subjectName.get_data_length()),
+                        subjectName.get_data_length());
+                        
+                // Copy the data into the returned parameter
+                HBufC16* label16;
+                ConvertFromBuf8ToBuf16LC( tmpLabel, &label16 );
+                aCert.Copy( *label16 );
+                CleanupStack::PopAndDestroy(label16);
+                }
+            // Label is too long, write to log
+            else
+                {
+                EAP_TRACE_ERROR(
+                        iAmTools,
+                        TRACE_FLAGS_DEFAULT,
+                        (EAPL("ERROR: CCertificateStoreDatabase::ReadLabelTable() \
+                        label too long!!\n"))); 
+                }
+            }
+        else
+            {
+            CleanupStack::PopAndDestroy(value);
+            }
+        }
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ("CCertificateStoreDatabase::ReadLabelTableL -End")) );
+    }
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::RemoveDataFromViewL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::RemoveDataFromTableL( const TDesC& aTableName, 
+                                    const TDesC& aReferenceName, TUint aRefId  )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ("CCertificateStoreDatabase::RemoveDataFromTable -Start")) );       
+        
+    RDbView view;
+    HBufC* buf = HBufC::NewLC( KMaxSqlQueryLength );
+    TPtr sqlStatement = buf->Des();
+    _LIT(KSQLQuery, "SELECT * FROM %S WHERE %S=%d");
+    
+    sqlStatement.Format( KSQLQuery, &aTableName, &aReferenceName, aRefId );
+    User::LeaveIfError(view.Prepare( iCsDb, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EUpdatable));
+    CleanupClosePushL(view);
+    
+    User::LeaveIfError(view.EvaluateAll());
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+            ("CCertificateStoreDatabase::RemoveDataFromTable - view evaluated OK\n")));
+    
+    if (view.FirstL())
+        {
+        //Delete the row if it was found
+        view.DeleteL(); 
+        }
+    else
+        {
+        // the row was not found
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+                ("CCertificateStoreDatabase::RemoveDataFromTable - No data found\n")));
+        }
+    CleanupStack::PopAndDestroy( &view );
+    CleanupStack::PopAndDestroy( buf );
+    }
+	
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::DeleteAPSpecificDataL( TInt aId )
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::DeleteAPSpecificDataL( const TInt aId )
+	{
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL
+	        ("CCertificateStoreDatabase::DeleteAPSpecificDataL -Start")) );  
+	
+    // If DB is not created, there is nothing to delete
+    if ( !iCsDbCreated )
+        {
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "ERROR: CCertificateStoreDatabase::DeleteAPSpecificDataL() \
+                CS DB doesn't exist. Don't do anything.\n" ) ) );
+        return;
+        }     
+
+    // Check whether db connection is open and data exists
+	if ( !iCsSessionOpened )
+	    {
+        EAP_TRACE_ERROR(
+            iAmTools,
+            TRACE_FLAGS_DEFAULT,
+            (EAPL("ERROR: CCertificateStoreDatabase::DeleteAPSpecificDataL() \
+                CS not opened.\n")));
+	    User::Leave( KErrSessionClosed );
+	    }   
+  
+    // Delete the row from KCsWapiCertLabelTable 
+    TRAPD ( err, RemoveDataFromTableL ( KCsWapiCertLabelTable, KCsCertLabelAsuIdReference, aId ));
+    
+    // Leave if there were errors in one of the deletions
+    User::LeaveIfError ( err );
+	}
+
+// ================= private:  Private constructors =======================
+
+
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::CCertificateStoreDatabase()
+// ---------------------------------------------------------
+//
+CCertificateStoreDatabase::CCertificateStoreDatabase(
+    abs_eap_am_tools_c* aAmTools )
+    : iState( ECertificateStoreStatesNumber )
+    , iCsDbCreated( EFalse )
+    , iCsSessionOpened( EFalse )
+    , iAmTools( aAmTools )
+    , iPartner (NULL)
+    {
+    }
+
+	
+// ---------------------------------------------------------
+// CCertificateStoreDatabase::ConstructL()
+// ---------------------------------------------------------
+//
+void CCertificateStoreDatabase::ConstructL()
+    {
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::ConstructL() IN\n" ) ) );		
+
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "CCertificateStoreDatabase::ConstructL() OUT\n" ) ) );			
+    
+    } // CCertificateStoreDatabase::ConstructL()
+
+// End of file.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/wapi_core/symbian/file_config/wapi_symbian.conf	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,90 @@
+#
+#  Name        : ./wlan_symbian/wlaneapol_symbian/am/wapi_core/symbian/file_config/wapi_symbian.conf
+#  Part of     : WAPI / 
+#  Description : Configuration file for WAPI.
+#  Version     : %version: 13 %
+#  
+#  Copyright © 2001-2008 Nokia. All rights reserved.
+#  This material, including documentation and any related 
+#  computer programs, is protected by copyright controlled by 
+#  Nokia. All rights are reserved. Copying, including 
+#  reproducing, storing, adapting or translating, any 
+#  or all of this material requires the prior written consent of 
+#  Nokia. This material also contains confidential 
+#  information which may not be disclosed to others without the 
+#  prior written consent of Nokia.
+#
+
+WAPI_TRACE_disable_traces = bool:false
+
+WAPI_TRACE_enable_timer_traces = bool:false
+
+WAPI_TRACE_enable_timer_queue_traces = bool:false
+
+WAPI_TRACE_output_file_name = string:e:\logs\eapol\wapi_core.txt
+
+WAPI_TRACE_max_trace_file_size = u32_t:1000000
+
+WAPI_TRACE_activate_only_trace_masks_always_and_error = bool:false
+
+WAPI_TRACE_activate_trace_on_error = bool:false
+
+WAPI_CORE_session_timeout = u32_t:60000
+
+WAPI_CORE_failure_received_timeout = u32_t:2000
+
+WAPI_CORE_remove_session_timeout = u32_t:10000
+
+WAPI_SESSION_use_reset_session = bool:false
+
+WAPI_CORE_starts_max_count = u32_t:3
+
+WAPI_CORE_send_start_interval = u32_t:2000
+
+WAPI_key_state_retransmission_counter = u32_t:3
+
+WAPI_key_state_retransmission_time = u32_t:500
+
+WAPI_key_state_handshake_timeout=u32_t:15000
+
+WAPI_max_session_validity_time = u32_t:43200
+
+#EAPOL_key_authentication_type = string:WAI_PSK
+#EAPOL_key_authentication_type = string:WAI_certificate
+
+# This is Hex-data configuration option.
+# This is the PSK used in WAPI testing.
+# The default value is empty.
+#WAPI_CORE_PSK = hex:74,65,73,74,74,65,73,74
+
+
+#-------------------------------------------------------------------------------------
+
+# This one shortens the long pathnames.
+#WAPI_CERT_DIR = string:z:\private\101F8EC5
+
+
+# This is the ASUE's ECC certificate file. It must be in DER format.
+#WAPI_ASUE_certificate_file = string:$(WAPI_CERT_DIR)\user.cer-0.der
+
+# This is the ASUE's ECC private key file. It must be in DER format.
+#WAPI_ASUE_private_key_file = string:$(WAPI_CERT_DIR)\user.cer-1.der
+
+
+# This is the AE's ECC certificate file. It must be in DER format.
+#WAPI_AE_certificate_file = string:$(WAPI_CERT_DIR)\as.cer-0.der
+
+# This is the AE's ECC private key file. It must be in DER format.
+#WAPI_AE_private_key_file = string:$(WAPI_CERT_DIR)\
+
+
+# This is the ASU's ECC certificate file. It must be in DER format.
+#WAPI_ASU_certificate_file = string:$(WAPI_CERT_DIR)\as.cer-0.der
+
+# This is the ASU's ECC private key file. It must be in DER format.
+#WAPI_ASU_private_key_file = string:$(WAPI_CERT_DIR)\
+
+#-------------------------------------------------------------------------------------
+
+
+# end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/wapi_core/symbian/wapi_am_core_symbian.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,3926 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/wapi_core/symbian/wapi_am_core_symbian.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 78.1.7 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of EAPOL source code.
+#if defined(USE_WAPI_MINIMUM_RELEASE_TRACES)
+	#undef WAPI_FILE_NUMBER_ENUM
+	#define WAPI_FILE_NUMBER_ENUM 148 
+	#undef WAPI_FILE_NUMBER_DATE 
+	#define WAPI_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_WAPI_MINIMUM_RELEASE_TRACES)
+
+// INCLUDE FILES
+
+#include <f32file.h>
+#include <mmtsy_names.h>
+#include <utf.h>   
+#include "eap_am_memory.h"
+
+#include "eap_variable_data.h"
+#include "eap_automatic_variable.h"
+#include "eap_tools.h"
+#include "eap_type_all.h"
+
+#include "eapol_ethernet_header.h"
+#include "ethernet_core.h"
+#include "eap_am_tools_symbian.h"
+#include "abs_eap_am_tools.h"
+#include "WapiDbDefaults.h"
+#include "eap_crypto_api.h"
+#include "eap_header_string.h"
+#include "eap_am_file_input_symbian.h"
+#include "eap_rogue_ap_entry.h"
+#include "abs_eap_state_notification.h"
+#include "eapol_session_key.h"
+#include "eap_buffer.h"
+#include "eap_config.h"
+#include "wapi_am_core_symbian.h"
+#include "abs_wapi_am_core.h"
+#include "abs_ec_am_certificate_store.h"
+#include "certificate_store_db_symbian.h"
+#include "ec_cs_tlv_header.h"
+#include "eap_array_algorithms.h"
+#include "ec_certificate_store.h"
+#include "wapi_asn1_der_parser.h"
+#include "wapi_core.h"
+
+#if defined(USE_WAPI_FILECONFIG)
+	#include "eap_file_config.h"
+#endif //#if defined(USE_EAP_FILECONFIG)
+
+#if defined (USE_EAPOL_KEY_STATE) 
+	#include "eapol_key_state.h"	
+#endif
+
+#if defined( WAPI_USE_UI_NOTIFIER )   		        
+#include "wapnotifier_struct.h"
+#endif
+
+
+// LOCAL CONSTANTS
+const TUint KMaxConfigStringLength = 256;
+
+const TUint KMaxDeviceSeedLength = RMobilePhone::KPhoneManufacturerIdSize+
+RMobilePhone::KPhoneModelIdSize+
+//RMobilePhone::KPhoneRevisionIdSize+
+RMobilePhone::KPhoneSerialNumberSize;
+const TUint KMaxDeviceSeedSize = 2*KMaxDeviceSeedLength;
+
+// ================= MEMBER FUNCTIONS =======================
+
+wapi_am_core_symbian_c::wapi_am_core_symbian_c(
+	abs_eap_am_tools_c *const aTools,
+	abs_wapi_am_core_c * const aPartner,
+	const bool aIsClientWhenTrue ) 
+    : CActive( CActive::EPriorityStandard )
+    , iState( EWapiStatesNumber )
+    , iAmTools( aTools )
+    , iInReferences( iAmTools )
+    , iReferencesAndDataBlocks( iAmTools )    
+    , iPartner( aPartner )
+    , iCertStorePartner( NULL )
+    , iCertificateStoreDb( NULL )
+    , iCsPassword ( iAmTools )
+    , iCancelCalled( EFalse )
+    , m_authentication_counter(0u)
+    , m_successful_authentications(0u)
+    , m_failed_authentications(0u)
+    , m_is_valid(false)
+    , m_is_client(aIsClientWhenTrue)
+    , m_first_authentication(true)
+    , m_self_disassociated(false)
+    , m_fileconfig(0)
+    , iEapVarData(iAmTools)
+    {
+    }	
+
+//--------------------------------------------------
+
+wapi_am_core_symbian_c::wapi_am_core_symbian_c(
+	abs_eap_am_tools_c *const aTools,
+	abs_wapi_am_core_c *const aPartner,
+	CCertificateStoreDatabase *aCertificateStoreDb,
+    const bool aIsClientWhenTrue)
+    : CActive( CActive::EPriorityStandard )
+    , iState( EWapiStatesNumber )
+    , iAmTools( aTools )
+    , iInReferences( iAmTools )
+    , iReferencesAndDataBlocks( iAmTools )    
+    , iPartner( aPartner )
+    , iCertStorePartner( NULL )
+    , iCertificateStoreDb( aCertificateStoreDb )
+    , iCsPassword ( iAmTools )
+    , iCancelCalled( EFalse )
+    , m_authentication_counter(0u)
+    , m_successful_authentications(0u)
+    , m_failed_authentications(0u)
+    , m_is_valid(false)
+    , m_is_client(aIsClientWhenTrue)
+    , m_first_authentication(true)
+    , m_self_disassociated(false)
+    , m_fileconfig(0)
+    , iEapVarData(iAmTools)
+    {
+    }   
+	
+
+void wapi_am_core_symbian_c::ConstructL()
+{
+	if (iPartner == 0)
+	{
+		User::Leave(KErrGeneral);
+	}
+	// Activate Scheduler
+    CActiveScheduler::Add( this );
+
+    if (iAmTools->configure() != eap_status_ok)
+	{
+		User::Leave(KErrGeneral);
+	}
+
+	iWapiDeviceSeed  = new (ELeave) eap_variable_data_c(iAmTools);
+
+	iWapiDeviceSeed->reset();
+
+	iImportedFilenames.Reset();
+		
+	EAP_TRACE_DEBUG(
+		iAmTools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI INITIALISATION\n")));	
+	EAP_TRACE_DEBUG(
+		iAmTools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("====================\n")));	
+
+    EAP_TRACE_ALWAYS(
+        iAmTools,
+        TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+        (EAPL("wapi_am_core_symbian_c::ConstructL: %s: \n"),
+        (m_is_client == true ? "client": "server")));
+
+	// Create the cert store if it wasn't passed as a parameter
+	if ( iCertificateStoreDb == NULL )
+	    {
+	    iCertificateStoreDb = CCertificateStoreDatabase::NewL( iAmTools );
+	    }
+	
+	m_ssid = new (ELeave) eap_variable_data_c(iAmTools);
+
+	// reset sertificate array
+	iCertArray.Reset();
+	
+	if (m_is_client)
+	    {
+#if defined(USE_WAPI_FILECONFIG)
+	    {
+		EAP_TRACE_DEBUG(
+			iAmTools,
+			TRACE_FLAGS_DEFAULT,
+			(EAPL("Initialize file configuration.\n")));
+			eap_am_file_input_symbian_c fileio(iAmTools);
+
+		eap_variable_data_c file_name_c_data(iAmTools);
+
+		eap_status_e status(eap_status_process_general_error);
+
+		eap_const_string const FILECONFIG_FILENAME_C
+		= "c:\\system\\data\\wapi.conf";
+
+		status = file_name_c_data.set_copy_of_buffer(
+		        FILECONFIG_FILENAME_C,
+		        iAmTools->strlen(FILECONFIG_FILENAME_C));
+		if (status != eap_status_ok)
+		    {
+		    EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+		    User::Leave(iAmTools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(iAmTools, status)));
+		    }
+
+		status = file_name_c_data.add_end_null();
+		if (status != eap_status_ok)
+		    {
+		    EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+		    User::Leave(iAmTools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(iAmTools, status)));
+		    }
+    
+
+		eap_variable_data_c file_name_z_data(iAmTools);
+
+		eap_const_string const FILECONFIG_FILENAME_Z
+            = "z:\\private\\101F8EC5\\wapi.conf";
+
+		status = file_name_z_data.set_copy_of_buffer(
+		        FILECONFIG_FILENAME_Z,
+				iAmTools->strlen(FILECONFIG_FILENAME_Z));
+		if (status != eap_status_ok)
+			{
+			EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+			User::Leave(iAmTools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(iAmTools, status)));
+			}
+
+		status = file_name_z_data.add_end_null();
+		if (status != eap_status_ok)
+		    {
+		    EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+		    User::Leave(iAmTools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(iAmTools, status)));
+			}
+		
+
+		if (status == eap_status_ok)
+		    {
+			// First try open from C: disk.
+			status = fileio.file_open(
+				&file_name_c_data,
+				eap_file_io_direction_read);
+			if (status == eap_status_ok)
+			    {
+				EAP_TRACE_DEBUG(
+					iAmTools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("Opens configure file %s\n"),
+					file_name_c_data.get_data(file_name_c_data.get_data_length())));
+			    }
+			else if (status != eap_status_ok)
+			    {
+				// Second try open from Z: disk.
+				status = fileio.file_open(
+					&file_name_z_data,
+					eap_file_io_direction_read);
+				if (status == eap_status_ok)
+				    {
+					EAP_TRACE_DEBUG(
+						iAmTools,
+						TRACE_FLAGS_DEFAULT,
+						(EAPL("Opens configure file %s\n"),
+						 file_name_z_data.get_data(file_name_z_data.get_data_length())));
+				    }
+			    }
+
+			if (status == eap_status_ok)
+			    {
+				// Some of the files were opened.
+
+				m_fileconfig = new eap_file_config_c(iAmTools);
+				if (m_fileconfig != 0
+					&& m_fileconfig->get_is_valid() == true)
+				    {
+					status = m_fileconfig->configure(&fileio);
+					if (status != eap_status_ok)
+					    {
+						EAP_TRACE_DEBUG(
+							iAmTools,
+							TRACE_FLAGS_DEFAULT,
+							(EAPL("ERROR: Configure read from %s failed.\n"),
+							file_name_c_data.get_data(file_name_c_data.get_data_length())));
+					    }
+					else
+					    {
+						EAP_TRACE_DEBUG(
+							iAmTools,
+							TRACE_FLAGS_DEFAULT,
+							(EAPL("Configure read from %s\n"),
+							file_name_c_data.get_data(file_name_c_data.get_data_length())));
+					    }
+				    }
+				else
+				    {
+					// No file configuration.
+					delete m_fileconfig;
+					m_fileconfig = 0;
+
+					EAP_TRACE_DEBUG(
+						iAmTools,
+						TRACE_FLAGS_DEFAULT,
+						(EAPL("ERROR: Cannot create configure object for file %s\n"),
+						file_name_c_data.get_data(file_name_c_data.get_data_length())));
+				    }
+			    }
+			else
+			    {
+				EAP_TRACE_DEBUG(
+					iAmTools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("ERROR: Cannot open configure file neither %s nor %s\n"),
+					file_name_c_data.get_data(file_name_c_data.get_data_length()),
+					file_name_z_data.get_data(file_name_z_data.get_data_length())));
+			    }
+		    }
+	    }
+
+#endif //#if defined(USE_WAPI_FILECONFIG)
+
+#if defined(USE_WAPI_HARDWARE_TRACE)
+		// Disable traces.
+		iAmTools->set_trace_mask(eap_am_tools_c::eap_trace_mask_none);
+
+		eap_variable_data_c trace_output_file(iAmTools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAP_TRACE_output_file_name.get_field(),
+			&trace_output_file);
+		if (status == eap_status_ok
+			&& trace_output_file.get_is_valid_data() == true)
+		    {
+			status = iAmTools->set_trace_file_name(&trace_output_file);
+			if (status == eap_status_ok)
+			    {
+				// OK, set the default trace mask.
+				iAmTools->set_trace_mask(
+					eap_am_tools_c::eap_trace_mask_debug
+					| eap_am_tools_c::eap_trace_mask_always
+					| eap_am_tools_c::eap_trace_mask_error);
+			    }
+		    }
+#endif //#if defined(USE_WAPI_HARDWARE_TRACE)
+
+
+    EAP_TRACE_DEBUG(
+        iAmTools,
+        TRACE_FLAGS_DEFAULT,
+        (EAPL("To Configure wapi_am_core_symbian_c\n")));
+        
+		eap_status_e status = configure();
+		if (status != eap_status_ok)
+		    {
+			User::Leave(KErrGeneral);
+		    }
+        
+	    }	
+	EAP_TRACE_DEBUG(
+		iAmTools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("Configured WAPI AM...\n")));
+
+	EAP_TRACE_DEBUG(
+		iAmTools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("Created timer...\n")));
+
+	EAP_TRACE_DEBUG(
+		iAmTools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("========================\n")));
+
+	set_is_valid();
+
+#if defined( WAPI_USE_UI_NOTIFIER )	
+    TInt err = iNotifier.Connect();
+    if ( err != KErrNone )
+        {
+    	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+    		"ERROR: wapi_am_core_symbian_c::ConstructL() \
+    		Failed to connect to notifier server, err=%d.\n" ), err ) );	
+        return;
+        }
+    if ( !iNotifierDataToUser )
+    	{
+    	iNotifierDataToUser = new(ELeave) TWapiUiNotifierInfo;	
+    	}
+	if ( !iNotifierDataPckgToUser )
+		{
+		iNotifierDataPckgToUser = new(ELeave) TPckg<TWapiUiNotifierInfo> (*iNotifierDataToUser);	
+		}
+	if ( !iNotifierDataFromUser )
+		{
+		iNotifierDataFromUser = new(ELeave) TWapiUiNotifierInfo;
+		}
+	if ( !iNotifierDataPckgFromUser )
+		{
+		iNotifierDataPckgFromUser = new(ELeave) TPckg<TWapiUiNotifierInfo> (*iNotifierDataFromUser);			
+		}
+#endif
+
+    } // wapi_am_core_symbian_c::ConstructL()
+
+
+//--------------------------------------------------
+
+void wapi_am_core_symbian_c::set_am_certificate_store_partner(abs_ec_am_certificate_store_c * const partner)
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+          "wapi_am_core_symbian_c::set_am_certificate_store_partner" ) ) );
+	iCertStorePartner = partner;
+	 
+    }
+
+//--------------------------------------------------
+
+wapi_am_core_symbian_c* wapi_am_core_symbian_c::NewL(
+	abs_eap_am_tools_c* const aTools,
+	abs_wapi_am_core_c * const aPartner,
+	const bool aIsClient)
+    {
+	wapi_am_core_symbian_c* self = new(ELeave) wapi_am_core_symbian_c(
+		aTools, aPartner, aIsClient );
+	CleanupStack::PushL(self);
+	self->ConstructL();
+
+	if (self->get_is_valid() != true)
+	    {
+		User::Leave(KErrGeneral);
+	    }
+
+	CleanupStack::Pop();
+	return self;
+    }
+
+wapi_am_core_symbian_c* wapi_am_core_symbian_c::NewL(
+	abs_eap_am_tools_c* const aTools,
+    abs_wapi_am_core_c * const aPartner,
+    CCertificateStoreDatabase* aCertificateStoreDb,
+    const bool aIsClient)
+    {
+    wapi_am_core_symbian_c* self = new(ELeave) wapi_am_core_symbian_c(
+        aTools, aPartner, aCertificateStoreDb, aIsClient);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+
+    if (self->get_is_valid() != true)
+        {
+        User::Leave(KErrGeneral);
+        }
+
+    CleanupStack::Pop();
+    return self;
+    }
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::~wapi_am_core_symbian_c()
+// ---------------------------------------------------------
+//
+wapi_am_core_symbian_c::~wapi_am_core_symbian_c()
+    {
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::~wapi_am_core_symbian_c IN\n" ) ) );
+
+	if (m_is_client)
+	    {
+#if defined(USE_EAP_FILECONFIG)
+	    delete m_fileconfig;
+	    m_fileconfig = 0;
+#endif //#if defined(USE_EAP_FILECONFIG)
+	    }
+	delete iWapiDeviceSeed;
+	    	
+#if defined( WAPI_USE_UI_NOTIFIER )	        
+	iNotifier.Close();
+    delete iNotifierDataToUser;
+    delete iNotifierDataPckgToUser;	
+	delete iNotifierDataFromUser;
+	delete iNotifierDataPckgFromUser;
+#endif // WAPI_USE_UI_NOTIFIER
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::~wapi_am_core_symbian_c OUT\n" ) ) );
+
+    } // wapi_am_core_symbian_c::~wapi_am_core_symbian_c()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::shutdown()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::shutdown()
+    {
+	EAP_TRACE_BEGIN(iAmTools, TRACE_FLAGS_DEFAULT);
+	
+	EAP_TRACE_DEBUG(
+		iAmTools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_am_core_symbian_c::shutdown()\n")));
+
+	// cancel asynch. request of AO
+	iCancelCalled = ETrue;
+	if ( IsActive() )
+		{
+		Cancel();
+		}
+	// Cancel timer	
+	cancel_timer(this, EWapiInitCertificateStoreTimerId);
+    cancel_timer(this, EWapiAddCertificateFileTimerId);
+    cancel_timer(this, EWapiReadCertificateStoreDataTimerId);
+    cancel_timer(this, EWapiWriteCertificateStoreDataTimerId);
+
+   delete m_ssid;
+   m_ssid = NULL;
+   
+   EAP_TRACE_DEBUG(
+		iAmTools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_am_core_symbian_c::shutdown() delete Arrays\n")));
+
+   TInt count=0;
+   while (count < iCertArray.Count())
+       {
+       if (iCertArray[count].iData != NULL)
+           {
+           delete iCertArray[count].iData;
+           iCertArray[count].iData = NULL;
+           }
+       if (iCertArray[count].iReference != NULL)
+           {
+           delete iCertArray[count].iReference;
+           iCertArray[count].iReference= NULL;
+           }
+       count ++;
+       }
+		
+
+	iCertArray.Reset();
+
+	delete m_fileconfig;
+	m_fileconfig = 0;
+	
+	EAP_TRACE_DEBUG(
+		iAmTools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI EXITING.\n")));
+	EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);	
+
+	return eap_status_ok;
+	
+    } // wapi_am_core_symbian_c::shutdown()
+
+
+// ================= protected: from CActive =======================
+    
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::RunL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::RunL()
+    {
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"wapi_am_core_symbian_c::RunL() IN, iStatus=%d, iState=%d.\n"),
+		iStatus.Int(), iState ) );
+
+	if ( iStatus.Int() != KErrNone )
+	    {
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	        "ERROR: wapi_am_core_symbian_c::RunL() iStatus=%d" ),
+	        iStatus.Int() ) );
+		return;
+	    }
+	  
+    if ( iState == EWapiHandlingDeviceSeedQueryState )
+		{
+	    CompleteHandlingDeviceSeedQueryState();	    
+        iState = EWapiStatesNumber;
+		}
+#if defined( WAPI_USE_UI_NOTIFIER )   		        
+    else if ( iState == EWapiQueryCertFilePasswordState )
+    	{
+        CompleteQueryCertFilePassword();
+    	}
+    else if ( iState == EWapiQueryImportFilePasswordState )
+    	{
+        CompleteQueryImportFilePassword();
+    	}
+#endif // WAPI_USE_UI_NOTIFIER 
+    else
+    	{
+    	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		    "ERROR: wapi_am_core_symbian_c::RunL() State is not supported, \
+		    iState = %d." ), iState ) );
+    	}
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::RunL() OUT.\n" ) ) );
+    
+    } // wapi_am_core_symbian_c::RunL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::DoCancel()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::DoCancel()
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::DoCancel() IN\n" ) ) );
+
+	EAP_TRACE_BEGIN(iAmTools, TRACE_FLAGS_DEFAULT);
+
+#if defined( WAPI_USE_UI_NOTIFIER )   		        
+	iNotifier.CancelNotifier( KWapiNotifierUid );
+#endif
+	
+	EAP_TRACE_DEBUG(
+		iAmTools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_am_core_symbian_c::DoCancel()\n")));
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::DoCancel() OUT\n" ) ) );
+
+    }
+
+//--------------------------------------------------
+
+void wapi_am_core_symbian_c::set_is_valid()
+    {
+	m_is_valid = true;
+    }
+
+bool wapi_am_core_symbian_c::get_is_valid()
+    {
+	return m_is_valid;
+    }
+
+//--------------------------------------------------
+
+//
+void wapi_am_core_symbian_c::state_notification(const abs_eap_state_notification_c * const state)
+{
+	EAP_TRACE_BEGIN(iAmTools, TRACE_FLAGS_DEFAULT);
+
+	if(state->get_protocol_layer() == eap_protocol_layer_general)
+	    {
+		if (state->get_current_state() == eap_general_state_authentication_cancelled)
+		    {
+			// Authentication was cancelled. Cannot continue.
+			EAP_TRACE_DEBUG(
+				iAmTools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("Authentication was cancelled. WAPI_AM_CORE_TIMER_FAILED_COMPLETELY_ID.\n")));
+
+            }
+		else if (state->get_current_state() == eap_general_state_configuration_error)
+		    {
+			// Configuration error. Cannot continue.
+			EAP_TRACE_DEBUG(
+				iAmTools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("Configuration error. WAPI_AM_CORE_TIMER_FAILED_COMPLETELY_ID.\n")));
+
+		    }
+	    }
+
+	
+	if(state->get_protocol_layer() == eap_protocol_layer_eapol)
+	{
+		switch (state->get_current_state())
+		{
+		case eapol_state_no_start_response:
+			EAP_TRACE_DEBUG(
+				iAmTools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("Indication NOT sent to WLM: ENoResponse.\n")));
+			break;
+		default:
+			break;
+		}
+	}
+	else if(state->get_protocol_layer() == eap_protocol_layer_eapol_key)
+	{
+		switch (state->get_current_state())
+		{
+		case eapol_key_state_802_11i_authentication_terminated_unsuccessfull:
+			{					
+
+				// Consider WAPI layer failures fatal.
+				EAP_TRACE_ERROR(
+					iAmTools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("ERROR: Unsuccessful authentication on WAPI level.\n")));
+				EAP_TRACE_DEBUG(
+					iAmTools,
+					TRACE_FLAGS_DEFAULT,
+					(EAPL("Indication NOT sent to WLM: EThisAPFailed.\n")));
+			}
+			break;
+		case eapol_key_state_802_11i_authentication_finished_successfull:
+			{					
+				EAP_TRACE_ALWAYS(
+					iAmTools,
+					TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+					(EAPL("EAPOL_KEY: %s: Authentication SUCCESS\n"),
+					(m_is_client == true ? "client": "server")));
+			}
+			break;
+		default:
+			break;
+		}
+	}	
+	
+
+	EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+}
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::timer_expired()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::timer_expired(
+	const u32_t id, void * /* data */)
+    {
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"wapi_am_core_symbian_c::timer_expired() IN, id = %d.\n"),
+		id ) );
+	
+	iWapiCompletionStatus = eap_status_ok;
+	eap_status_e status = eap_status_ok;
+	switch ( id )
+	    {
+	    case EWapiInitCertificateStoreTimerId:
+	    	{
+	    	status = ProcessInitCertificateStore();
+	    	break;
+	    	}
+	    case EWapiAddCertificateFileTimerId:
+	    	{
+	        status = ProcessAddCertificateFile();
+	        break;
+	    	}
+	    case EWapiReadCertificateStoreDataTimerId:
+	    	{	        
+            status = ProcessReadCertificateStoreData();
+            break;
+	    	}
+	    case EWapiWriteCertificateStoreDataTimerId:
+	    	{
+            status = ProcessWriteCertificateStoreData();
+            break;	    	
+	    	}
+	    default:
+	    	{
+	    	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			    "ERROR: wapi_am_core_symbian_c::timer_expired() unknown \
+			    id = %d.\n"), id ) );
+	    	}
+	    } // switch
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::timer_expired() OUT, status = %d.\n" ),
+	    status ) );
+	return status;
+
+    } // wapi_am_core_symbian_c::timer_expired()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::timer_delete_data()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::timer_delete_data(
+	const u32_t id, void *data)
+    {
+    return eap_status_ok;
+    }
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_core_symbian_c::configure()
+    {	
+	EAP_TRACE_DEBUG(
+		iAmTools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_am_core_symbian_c::configure()\n")));
+
+
+	//----------------------------------------------------------
+	{		
+		eap_variable_data_c EAP_TRACE_disable_traces(iAmTools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAP_TRACE_disable_traces.get_field(),
+			&EAP_TRACE_disable_traces);
+		if (status == eap_status_ok
+			&& EAP_TRACE_disable_traces.get_is_valid_data() == true)
+		    {
+			u32_t *disable_traces = reinterpret_cast<u32_t *>(
+				EAP_TRACE_disable_traces.get_data(sizeof(u32_t)));
+			if (disable_traces != 0
+				&& *disable_traces != 0)
+			    {
+				iAmTools->set_trace_mask(eap_am_tools_c::eap_trace_mask_none);
+			    }
+			else
+			    {
+				// OK, set the default trace mask.
+				iAmTools->set_trace_mask(
+					eap_am_tools_c::eap_trace_mask_debug
+					| eap_am_tools_c::eap_trace_mask_always
+					| eap_am_tools_c::eap_trace_mask_error);
+			    }
+		    }
+	}
+
+	//----------------------------------------------------------
+
+	{		
+		eap_variable_data_c EAP_TRACE_activate_only_trace_masks_always_and_error(iAmTools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAP_TRACE_activate_only_trace_masks_always_and_error.get_field(),
+			&EAP_TRACE_activate_only_trace_masks_always_and_error);
+		if (status == eap_status_ok
+			&& EAP_TRACE_activate_only_trace_masks_always_and_error.get_is_valid_data() == true)
+		    {
+			u32_t *activate_trace_mask_always
+				= reinterpret_cast<u32_t *>(
+					EAP_TRACE_activate_only_trace_masks_always_and_error.get_data(
+						sizeof(u32_t)));
+			if (activate_trace_mask_always != 0
+				&& *activate_trace_mask_always != 0)
+			    {
+				iAmTools->set_trace_mask(
+					eap_am_tools_c::eap_trace_mask_always
+					| eap_am_tools_c::eap_trace_mask_error
+					);
+			    }
+		    }
+	}
+
+	//----------------------------------------------------------
+
+	{		
+		eap_variable_data_c EAP_TRACE_activate_trace_on_error(iAmTools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAP_TRACE_activate_trace_on_error.get_field(),
+			&EAP_TRACE_activate_trace_on_error);
+		if (status == eap_status_ok
+			&& EAP_TRACE_activate_trace_on_error.get_is_valid_data() == true)
+		    {
+			u32_t *activate_trace_on_error = reinterpret_cast<u32_t *>(
+				EAP_TRACE_activate_trace_on_error.get_data(sizeof(u32_t)));
+			if (activate_trace_on_error != 0
+				&& *activate_trace_on_error != 0)
+			    {
+				iAmTools->set_activate_trace_on_error();
+			    }
+		    }
+	}
+
+    //----------------------------------------------------------
+    {       
+        eap_variable_data_c EAP_TRACE_disable_traces(iAmTools);
+
+        eap_status_e status = read_configure(
+            cf_str_EAP_TRACE_disable_traces.get_field(),
+            &EAP_TRACE_disable_traces);
+        if (status == eap_status_ok
+            && EAP_TRACE_disable_traces.get_is_valid_data() == true)
+            {
+            u32_t *disable_traces = reinterpret_cast<u32_t *>(
+                EAP_TRACE_disable_traces.get_data(sizeof(u32_t)));
+            if (disable_traces != 0
+                && *disable_traces != 0)
+                {
+                iAmTools->set_trace_mask(eap_am_tools_c::eap_trace_mask_none);
+                }
+            else
+                {
+                // OK, set the default trace mask.
+                iAmTools->set_trace_mask(
+                    eap_am_tools_c::eap_trace_mask_debug
+                    | eap_am_tools_c::eap_trace_mask_always
+                    | eap_am_tools_c::eap_trace_mask_error);
+                }
+            }
+    }
+
+    //----------------------------------------------------------
+
+    //----------------------------------------------------------
+
+	// All of the configuration options are optional.
+	// So we return OK.
+	return eap_status_ok;
+    }
+
+//--------------------------------------------------
+
+eap_status_e wapi_am_core_symbian_c::read_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+    {
+	EAP_TRACE_BEGIN(iAmTools, TRACE_FLAGS_DEFAULT);
+
+	if(field->get_field_length() > KMaxConfigStringLength)
+	    {
+		return eap_status_process_general_error;
+	    }
+	
+	eap_status_e status(eap_status_ok);
+	
+	eap_variable_data_c type_field(iAmTools);
+	eap_variable_data_c type_field_server(iAmTools);
+	
+#if defined(USE_EAP_FILECONFIG)
+		if (m_fileconfig != 0
+			&& m_fileconfig->get_is_valid() == true)
+		    {
+			// Here we could try the final configuration option.
+			status = m_fileconfig->read_configure(
+				field,
+				data);
+		    }
+#endif //#if defined(USE_EAP_FILECONFIG)
+
+	iAmTools->trace_configuration(
+		status,
+		field,
+		data);
+
+	EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(iAmTools, status);
+    }
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_am_core_symbian_c::set_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id, 
+	void * const p_data,
+	const u32_t p_time_ms)
+    {
+	EAP_TRACE_BEGIN(iAmTools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = iAmTools->am_set_timer(
+		p_initializer, 
+		p_id, 
+		p_data,
+		p_time_ms);
+
+	EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+	return status;
+        }
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_am_core_symbian_c::cancel_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id)
+    {
+	EAP_TRACE_BEGIN(iAmTools, TRACE_FLAGS_DEFAULT);
+	
+	const eap_status_e status = iAmTools->am_cancel_timer(
+		p_initializer, 
+		p_id);
+
+	EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+	return status;
+    }
+
+//--------------------------------------------------
+
+//
+eap_status_e wapi_am_core_symbian_c::cancel_all_timers()
+    {
+	EAP_TRACE_BEGIN(iAmTools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = iAmTools->am_cancel_all_timers();
+
+	EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+	return status;
+    }
+
+//--------------------------------------------------
+
+abs_wapi_am_core_c * wapi_am_core_symbian_c::get_am_partner()
+	{
+	return iPartner;
+	}
+
+//--------------------------------------------------
+
+void wapi_am_core_symbian_c::set_am_partner(abs_wapi_am_core_c * const partner)
+	{
+	iPartner = partner;	
+	}
+//--------------------------------------------------
+
+eap_status_e wapi_am_core_symbian_c::reset()
+	{
+	iImportedFilenames.Reset();  
+	return eap_status_ok;
+	}
+//--------------------------------------------------				
+
+eap_status_e wapi_am_core_symbian_c::authentication_finished(
+		const bool true_when_successfull)
+	{
+	return eap_status_ok;
+	}
+
+//----------------------------------------------------
+// These two methods only because of interface support 
+//----------------------------------------------------
+
+eap_status_e wapi_am_core_symbian_c::type_configure_read(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data)
+	{
+    EAP_TRACE_DATA_DEBUG(
+        iAmTools,
+        TRACE_FLAGS_DEFAULT,
+        (EAPL("Wanted Field"),
+                field->get_field(),
+                field->get_field_length()));
+
+    return eap_status_ok;
+	
+	}
+
+//--------------------------------------------------				
+eap_status_e wapi_am_core_symbian_c::type_configure_write(
+		const eap_configuration_field_c * const field,
+		eap_variable_data_c * const data)
+	{
+	return eap_status_ok;
+	
+	}
+
+
+// ================= protected: from ec_am_base_certificate_store_c =======================
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::initialize_certificate_store()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::initialize_certificate_store(
+	const wapi_completion_operation_e completion_operation )
+	{
+	EAP_TRACE_BEGIN(iAmTools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_DEBUG(iAmTools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_core_symbian_c::initialize_certificate_store IN\n")));
+	
+	iCompletionOperation = completion_operation;
+	
+	iWapiCompletionStatus = set_timer(
+			this,
+			EWapiInitCertificateStoreTimerId, 
+			0,
+			0);
+	
+	if (iWapiCompletionStatus != eap_status_ok)
+		{
+			EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+			return EAP_STATUS_RETURN(iAmTools, iWapiCompletionStatus);
+		}
+
+	iWapiCompletionStatus = eap_status_pending_request;
+			
+	EAP_TRACE_DEBUG(iAmTools, 
+			TRACE_FLAGS_DEFAULT, 
+			(EAPL("eap_am_type_tls_peap_symbian_c::initialize_certificate_store() OUT\n")));
+	
+	EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(iAmTools, iWapiCompletionStatus);	
+	
+	} // wapi_am_core_symbian_c::initialize_certificate_store()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::read_certificate_store_data()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::read_certificate_store_data(
+	const ec_cs_pending_operation_e in_pending_operation,
+	EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references )
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::read_certificate_store_data() IN, \
+	    in_pending_operation=%d.\n" ), in_pending_operation ) );
+	eap_status_e status = eap_status_ok;
+	
+	// store args in member vars
+	iCsPendingOperation = in_pending_operation;
+	
+	// store references
+	status = copy( in_references,   // original array
+		           &iInReferences,  // copy array
+	               iAmTools,        // am tools
+		           false );         // reset copy array
+	if ( status != eap_status_ok )
+		{
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		    "ERROR: wapi_am_core_symbian_c::read_certificate_store_data() \
+		    Copying of in_references array failed, status=%d.\n" ), status ) );
+		    return status;
+		}
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::read_certificate_store_data() set timer for \
+        EWapiReadCertificateStoreDataTimerId\n" ) ) );
+	status = set_timer( this, EWapiReadCertificateStoreDataTimerId,
+		0, 0 );
+	if ( status != eap_status_ok )
+		{
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		    "wapi_am_core_symbian_c::read_certificate_store_data() \
+		    failed to set timer, status=%d.\n" ), status ) );		
+		    return status;
+		}
+	else
+		{
+		status = eap_status_pending_request;
+		}
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::read_certificate_store_data() OUT, \
+        status=%d.\n" ), status ) );
+	return status;
+	
+	} // wapi_am_core_symbian_c::read_certificate_store_data()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::write_certificate_store_data()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::write_certificate_store_data(
+	const bool when_true_must_be_synchronous_operation,
+	const ec_cs_pending_operation_e in_pending_operation,
+	EAP_TEMPLATE_CONST eap_array_c<ec_cs_data_c> * const in_references_and_data_blocks )
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::write_certificate_store_data() IN, \
+        when_true_must_be_synchronous_operation=%d.\n" ),
+        when_true_must_be_synchronous_operation ) );
+	eap_status_e status = eap_status_ok;
+	
+	// store args in member vars
+	iCsPendingOperation = in_pending_operation;
+	
+	eap_variable_data_c aFilename(iAmTools);
+	
+    TInt i = 0;
+    while (i< iImportedFilenames.Count())
+        {
+        aFilename.set_copy_of_buffer(iImportedFilenames[i].Ptr(), iImportedFilenames[i].Size());
+        
+        TRAPD(err, CompleteAddImportedCertificateFileL(&aFilename));
+        if (err)
+            {
+            // Continue to next operation
+            }
+        iImportedFilenames[i].Zero();
+        i++;
+        }
+    iImportedFilenames.Reset();  
+
+
+	// store references
+	status = copy( in_references_and_data_blocks, // original array
+		           &iReferencesAndDataBlocks,     // copy array
+	               iAmTools,                      // am tools
+		           false );                       // reset copy array
+	if ( status != eap_status_ok )
+		{
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		    "ERROR: wapi_am_core_symbian_c::write_certificate_store_data() \
+		    Copying of in_references array failed, status=%d.\n" ), status ) );
+		}
+	
+    if ( when_true_must_be_synchronous_operation )
+    	{ 
+    	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "wapi_am_core_symbian_c::write_certificate_store_data() \
+            Synchronous writing.\n" ) ) );
+    	// no timer is set, writing is done here
+    	ProcessWriteCertificateStoreData();
+    	}
+    else
+    	{ 
+    	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+    	    "wapi_am_core_symbian_c::write_certificate_store_data() \
+    	    Asynchronous writing. Set timer for EWapiWriteCertificateStoreDataTimerId\n" ) ) );
+    	status = set_timer( this, EWapiWriteCertificateStoreDataTimerId,
+    		0, 0 );
+    	if ( status != eap_status_ok )
+    		{
+    		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+    		    "wapi_am_core_symbian_c::write_certificate_store_data() \
+    		    failed to set timer, status=%d.\n" ), status ) );		
+    		}
+    	else
+    		{
+    		status = eap_status_pending_request;
+    		}
+    	}
+    
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::write_certificate_store_data() OUT\n" ) ) );
+
+	return status;	
+	} // wapi_am_core_symbian_c::write_certificate_store_data()
+
+//--------------------------------------------------	
+
+eap_status_e wapi_am_core_symbian_c::complete_add_imported_certificate_file(
+	const eap_status_e in_completion_status,
+	const eap_variable_data_c * const in_imported_certificate_filename)
+	{
+        iWapiCompletionStatus = eap_status_ok;
+	
+    EAP_TRACE_DEBUG_SYMBIAN(
+        (_L("wapi_am_core_symbian_c::complete_add_imported_certificate_file in_completion_status=%d"),
+                in_completion_status));       
+
+    TBuf8<256> aFile;
+    aFile.Copy(in_imported_certificate_filename->get_data(in_imported_certificate_filename->get_data_length()), in_imported_certificate_filename->get_data_length());
+    iImportedFilenames.Append(aFile);
+    
+    TInt i = 0;
+    while (i< iImportedFilenames.Count())
+        {
+        EAP_TRACE_DATA_DEBUG(
+                iAmTools,
+            TRACE_FLAGS_DEFAULT,
+            (EAPL("eap_am_type_tls_peap_symbian_c::complete_add_imported_certificate_file: Got Filenames "),
+                    iImportedFilenames[i].Ptr(),
+                    iImportedFilenames[i].Size()));
+        i++;
+        }
+
+    iWapiCompletionStatus = set_timer(
+             this,
+             EWapiAddCertificateFileTimerId, 
+             0,
+             0);
+
+    return iWapiCompletionStatus;
+	
+	}
+
+	//--------------------------------------------------	
+void wapi_am_core_symbian_c::CompleteAddImportedCertificateFileL(const eap_variable_data_c * const in_imported_certificate_filename)
+    {
+    RFs aFs;
+     aFs.Connect( KFileServerDefaultMessageSlots );
+
+     HBufC8* buf = HBufC8::NewLC(in_imported_certificate_filename->get_data_length());
+     TPtr8 bufPtr = buf->Des();
+
+     if (in_imported_certificate_filename->get_data_length() != 0)
+         {
+         bufPtr.Copy(in_imported_certificate_filename->get_data(), in_imported_certificate_filename->get_data_length());
+         }
+
+     HBufC* FilePath = HBufC::NewLC(KMaxFileName);
+     TPtr FilePathPtr = FilePath->Des();
+     HBufC8* FilePath8 = HBufC8::NewLC(KMaxFileName);
+     TPtr8 FilePathPtr8 = FilePath8->Des();
+     
+     FilePathPtr8.Zero();
+     FilePathPtr8.Append(KCertificateStoreImportDir);
+     FilePathPtr8.Append(bufPtr);
+
+     FilePathPtr.Copy(FilePathPtr8);
+
+
+     EAP_TRACE_DATA_DEBUG(
+             iAmTools,
+         TRACE_FLAGS_DEFAULT,
+         (EAPL("eap_am_type_tls_peap_symbian_c::CompleteAddImportedCertificateFileL: Filename "),
+         FilePathPtr.Ptr(),
+         FilePathPtr.Size()));
+  
+     if (m_is_client)
+         {
+         EAP_TRACE_DATA_DEBUG(
+                 iAmTools,
+             TRACE_FLAGS_DEFAULT,
+             (EAPL("eap_am_type_tls_peap_symbian_c::CompleteAddImportedCertificateFileL: Delete File"),
+             FilePathPtr.Ptr(),
+             FilePathPtr.Size()));
+     
+         aFs.SetAtt(FilePathPtr, NULL, KEntryAttReadOnly);
+         if(aFs.Delete(FilePathPtr)!= KErrNone)
+             {
+             EAP_TRACE_DATA_DEBUG(
+                     iAmTools,
+                     TRACE_FLAGS_DEFAULT,
+                     (EAPL("eap_am_type_tls_peap_symbian_c::CompleteAddImportedCertificateFileL: Couldn't delete file"),
+                             FilePathPtr.Ptr(),
+                             FilePathPtr.Size()));
+     
+     
+             iWapiCompletionStatus = eap_status_file_does_not_exist;
+             }
+         }
+     else
+         {
+         RDbNamedDatabase& db = iCertificateStoreDb->GetCertificateStoreDb();
+         RDbView view;   
+         // Leave if the view preparation still fails
+         HBufC* buf3 = HBufC::NewLC(KMaxSqlQueryLength);
+         TPtr sqlStatement2 = buf3->Des();
+         _LIT(KSQLQueryRow2, "SELECT * FROM %S");
+         sqlStatement2.Format(KSQLQueryRow2, &KCsWapiCertFileTable);
+
+         EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+             "wapi_am_core_symbian_c::CompleteAddImportedCertificateFileL() sqlStatement",
+             sqlStatement2.Ptr(), 
+             sqlStatement2.Size() ) );    
+
+         User::LeaveIfError ( view.Prepare( db, TDbQuery(sqlStatement2), TDbWindow::EUnlimited, RDbView::EInsertOnly ));
+         CleanupStack::PopAndDestroy( buf3 );
+         CleanupClosePushL(view);
+         User::LeaveIfError(view.EvaluateAll());
+
+         // Use the data insertion function to update data and reference
+         CDbColSet* colSet = view.ColSetL();
+         CleanupStack::PushL( colSet );
+
+         view.InsertL();
+
+         TDbColNo colNo = KDefaultColumnNumberOne;
+         view.SetColL( colNo, bufPtr );
+
+         view.PutL(); 
+
+         CleanupStack::PopAndDestroy( colSet );
+         CleanupStack::PopAndDestroy( &view );        
+
+         }
+     CleanupStack::PopAndDestroy(FilePath8); 
+     CleanupStack::PopAndDestroy(FilePath); 
+     CleanupStack::PopAndDestroy(buf);
+
+    }
+
+eap_status_e wapi_am_core_symbian_c::complete_remove_certificate_store(
+	const eap_status_e in_completion_status)
+	{
+	return eap_status_ok;
+	
+	}
+
+	//--------------------------------------------------		
+
+eap_status_e wapi_am_core_symbian_c::cancel_certificate_store_store_operations()
+	{
+	return eap_status_ok;
+	
+	}
+
+//--------------------------------------------------	
+
+eap_status_e wapi_am_core_symbian_c::set_session_timeout(
+	const u32_t session_timeout_ms)
+	{
+	return eap_status_ok;
+	
+	}
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::CreateDeviceSeedAsync()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::CreateDeviceSeedAsync()
+{	
+	EAP_TRACE_BEGIN(iAmTools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG_SYMBIAN(
+		(_L("wapi_am_core_symbian_c::CreateDeviceSeedAsynch-Start ActiveStatus=%d"),
+		IsActive()));		
+	
+	if ( IsActive() )
+	{
+		EAP_TRACE_DEBUG_SYMBIAN(
+			(_L("wapi_am_core_symbian_c: Already active when tried to create device seed")));		
+		
+		return eap_status_device_busy;
+	}
+
+	eap_status_e status(eap_status_ok);	
+	
+	iState = EWapiHandlingDeviceSeedQueryState;
+		
+	// Create MMETEL connection.
+	TRAPD(error, CreateMMETelConnectionL());
+	if(error !=KErrNone)
+	{
+		return iAmTools->convert_am_error_to_eapol_error(error);
+	}
+	
+   	iPhone.GetPhoneId( iStatus, iDeviceId ); 
+
+	SetActive();
+	return status;
+} // wapi_am_core_symbian_c::CreateDeviceSeedAsynch()
+
+//--------------------------------------------------
+
+TInt wapi_am_core_symbian_c::CreateMMETelConnectionL()
+{
+	EAP_TRACE_BEGIN(iAmTools, TRACE_FLAGS_DEFAULT);
+	EAP_TRACE_DEBUG(iAmTools, TRACE_FLAGS_DEFAULT, (EAPL("Creating MMETel connection.\n")));
+
+	TInt errorCode = KErrNone;
+	
+	// MMETel need to be connected only once.    
+    if( !iMMETELConnectionStatus )
+    {
+		RTelServer::TPhoneInfo phoneInfo;
+		TInt phoneCount = 0;
+
+		// Connect to ETel server
+		User::LeaveIfError( iServer.Connect() ); 	
+		
+	    EAP_TRACE_DEBUG(iAmTools, TRACE_FLAGS_DEFAULT, (EAPL("Connected to ETel server.\n")));	
+
+		// This function loads an ETel TSY module, mmtsy.
+		errorCode = iServer.LoadPhoneModule( KMmTsyModuleName );	
+		
+	    EAP_TRACE_DEBUG(iAmTools, TRACE_FLAGS_DEFAULT, (EAPL("Loaded phone module.\n")));	    
+		
+		if ( errorCode != KErrNone && errorCode != KErrAlreadyExists )
+		{
+			User::Leave( errorCode );
+		}
+
+		iServer.SetExtendedErrorGranularity( RTelServer::EErrorExtended );
+
+		// This function retrieves the total number of phones supported by all 
+		// the currently loaded ETel (TSY) modules.
+		User::LeaveIfError( iServer.EnumeratePhones( phoneCount ) );	
+		
+		EAP_TRACE_DEBUG(iAmTools, TRACE_FLAGS_DEFAULT, (EAPL("Number of phones supported by the loaded ETel = %d.\n"), phoneCount));
+		
+		// This function retrieves information associated with the specified phone
+		while ( ( phoneCount-- ) && ( phoneInfo.iName != KMmTsyPhoneName ) ) 
+		{ 
+			User::LeaveIfError( iServer.GetPhoneInfo( phoneCount, phoneInfo ) );		
+			
+		    EAP_TRACE_DEBUG(iAmTools, TRACE_FLAGS_DEFAULT, (EAPL("Got phone info.\n")));
+		} 
+
+		// This function opens a phone subsession by name. ("DefaultPhone").
+		User::LeaveIfError( iPhone.Open( iServer, phoneInfo.iName ) );	
+		
+	    EAP_TRACE_DEBUG(iAmTools, TRACE_FLAGS_DEFAULT, (EAPL("Opened phone subsession.\n")));
+		
+		// MMETel connected and the phone module loaded fine.	
+		iMMETELConnectionStatus = ETrue; 	
+    }
+    else
+    {
+    	// MMETel already connected.
+	    EAP_TRACE_DEBUG(iAmTools, TRACE_FLAGS_DEFAULT, (EAPL("MMETel connected once already.\n")));
+    }
+	    
+	EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+    
+    return errorCode;	
+}
+
+//--------------------------------------------------				
+
+void wapi_am_core_symbian_c::DisconnectMMETEL()
+	{
+	    if( iMMETELConnectionStatus )
+	    {
+			EAP_TRACE_DEBUG(iAmTools, TRACE_FLAGS_DEFAULT, (EAPL("Closing RMobilePhone and MMETEL.\n")));
+			
+			iPhone.Close();
+			iServer.Close(); // Phone module is unloaded automatically when RTelServer session is closed
+			
+			iMMETELConnectionStatus = EFalse;
+	    }
+	    else
+	    {
+			EAP_TRACE_DEBUG(iAmTools, TRACE_FLAGS_DEFAULT, (EAPL("RMobilePhone and MMETEL already closed.\n")));    	
+	    }	
+	}
+
+
+// ================= private: New, timer expired process methods =======================
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ProcessInitCertificateStore()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::ProcessInitCertificateStore()
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::ProcessInitCertificateStore() IN\n" ) ) );
+
+	eap_status_e status = eap_status_ok;
+	if ( iCertificateStoreDb )
+		{
+		iCertStorePartner->remove_cached_certificate_store_data();
+
+		TRAPD( err, iCertificateStoreDb->InitializeCertificateStoreL() );
+		if ( err != KErrNone )
+			{
+			EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL (
+				"ERROR: wapi_am_core_symbian_c::ProcessInitCertificateStore() Leave, InitializeCertificateStoreL(), err=%d.\n" ), err ) );
+			status = iAmTools->convert_am_error_to_eapol_error( err );
+			}
+		}
+	else
+		{
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL (
+			"ERROR: wapi_am_core_symbian_c::ProcessInitCertificateStore() \
+			iCertificateStoreDb is NULL.\n" ) ) );
+		status = eap_status_process_general_error;
+		}
+	
+	if ( status == eap_status_ok )
+		{
+	    status = CreateDeviceSeedAsync();
+		}
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::ProcessInitCertificateStore() OUT, \
+	    status=%d.\n" ), status ) );
+	return status;
+	
+	} // wapi_am_core_symbian_c::ProcessInitCertificateStore()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ProcessAddCertificateFile()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::ProcessAddCertificateFile()
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"wapi_am_core_symbian_c::ProcessAddCertificateFile() IN\n" ) ) );
+	eap_status_e status = eap_status_ok;
+
+    TRAPD(err, ImportFilesL());
+ 	if (err)
+		{
+		// Complete with ok, even if import fails
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL("ERROR: wapi_am_core_symbian_c::Leave from ImportFilesL () err=%d.\n" ), err ) );
+		}
+    
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::ProcessAddCertificateFile() OUT\n" ) ) );
+    return status;
+	
+	} // wapi_am_core_symbian_c::ProcessAddCertificateFile()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ProcessReadCertificateStoreData()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::ProcessReadCertificateStoreData()
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::ProcessReadCertificateStoreData() IN\n" ) ) );
+	
+	// read certificate store
+    TRAPD( err, ReadCertificateStoreDataL() );
+    if ( err != KErrNone )
+    	{
+    	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+    		"ERROR: wapi_am_core_symbian_c::ProcessReadCertificateStoreData() LEAVE from ReadCertificateStoreDataL(), err=%d" ), err ) );
+        iWapiCompletionStatus = iAmTools->convert_am_error_to_eapol_error( err );
+     	}
+
+    if ( iWapiCompletionStatus == eap_status_ok || iWapiCompletionStatus == eap_status_pending_request )
+    	{
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "wapi_am_core_symbian_c::ProcessReadCertificateStoreData() \
+                COMPLETE read_certificate_store_data() request, \
+                status=%d, operation=%d" ), iWapiCompletionStatus,
+                iCsPendingOperation ) );
+        iWapiCompletionStatus = iCertStorePartner->complete_read_certificate_store_data(
+                iWapiCompletionStatus,
+                iCsPendingOperation,
+                &iReferencesAndDataBlocks );
+    	}
+     else // error status
+        {
+         iReferencesAndDataBlocks.reset();
+        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "wapi_am_core_symbian_c::ProcessReadCertificateStoreData() \
+                COMPLETE read_certificate_store_data() request, \
+                status=%d, operation=%d" ), iWapiCompletionStatus,
+                iCsPendingOperation ) );
+        iWapiCompletionStatus = iCertStorePartner->complete_read_certificate_store_data(
+                iWapiCompletionStatus,
+                iCsPendingOperation,
+                &iReferencesAndDataBlocks );
+    }
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ProcessReadCertificateStoreData() OUT, \
+        iWapiCompletionStatus=%d.\n" ), iWapiCompletionStatus ) );
+    return iWapiCompletionStatus;
+    
+	} // wapi_am_core_symbian_c::ProcessReadCertificateStoreData()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ProcessWriteCertificateStoreData()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::ProcessWriteCertificateStoreData()
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ProcessWriteCertificateStoreData() IN\n" ) ) );
+		
+	// write to certificate store
+    TRAPD( err, WriteCertificateStoreDataL() );
+    if ( err != KErrNone )
+    	{
+    	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+    	        "ERROR: wapi_am_core_symbian_c::ProcessWriteCertificateStoreData() LEAVE from WriteCertificateStoreDataL(), err=%d" ), err ) );
+    	iWapiCompletionStatus = iAmTools->convert_am_error_to_eapol_error( err );
+    	}
+	
+    // process status
+    if ( iWapiCompletionStatus == eap_status_ok || iWapiCompletionStatus == eap_status_pending_request )
+    	{
+    	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+    		"wapi_am_core_symbian_c::ProcessWriteCertificateStoreData(), \
+    		iWapiCompletionStatus=%d\n" ), iWapiCompletionStatus ) );    	
+    	}
+    else // error
+         {
+         // complete request!
+         iReferencesAndDataBlocks.reset();
+         EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "wapi_am_core_symbian_c::ProcessWriteCertificateStoreData() \
+             COMPLETE write_certificate_store_data() request, \
+             iWapiCompletionStatus=%d, operation=%d" ),
+             iWapiCompletionStatus, iCsPendingOperation ) );
+         eap_status_e status = iCertStorePartner->complete_write_certificate_store_data(
+             iWapiCompletionStatus,
+             iCsPendingOperation );
+         if ( status != eap_status_ok )
+             {
+             // just print an error
+             EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                 "ERROR: wapi_am_core_symbian_c::ProcessWriteCertificateStoreData() \
+                 complete_write_certificate_store_data(), status=%d" ), status ) );
+             }
+         }
+ 
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ProcessWriteCertificateStoreData() OUT\n" ) ) );
+    return iWapiCompletionStatus;
+	
+	} // wapi_am_core_symbian_c::ProcessWriteCertificateStoreData()
+
+
+// ================= private: New, writing to CS =======================
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::WriteCertificateStoreDataL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::WriteCertificateStoreDataL()
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::WriteCertificateStoreDataL() IN\n" ) ) );
+	
+	iWapiCompletionStatus = eap_status_ok;
+
+	for ( u32_t ind = 0ul;
+	      ind < iReferencesAndDataBlocks.get_object_count();ind++ )
+	    {    
+		const ec_cs_data_c* const dataReference = iReferencesAndDataBlocks.
+		    get_object( ind );
+		if (dataReference->get_is_valid() == false)
+		    {
+	        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	            "wapi_am_core_symbian_c::WriteCertificateStoreDataL() ERROR: datablock to be written is unvalid!\n" )));
+		    return;
+		    }
+		const ec_cs_data_type_e csDataType = dataReference->get_type();
+		
+        if (csDataType == NULL)
+            {
+            EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "wapi_am_core_symbian_c::WriteCertificateStoreDataL() ERROR: data type to be written is unvalid!\n" )));
+            return;
+            }
+	
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			"wapi_am_core_symbian_c::WriteCertificateStoreDataL() csDataType=%d.\n" ),
+			csDataType ) );
+		
+		if ( dataReference != NULL )
+			{
+		    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+			    "wapi_am_core_symbian_c::WriteCertificateStoreDataL() dataReference data(value):",
+			    dataReference->get_data()->get_data(
+			    	dataReference->get_data()->get_data_length() ),
+			    dataReference->get_data()->get_data_length() ) );
+		
+		    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+			    "wapi_am_core_symbian_c::WriteCertificateStoreDataL() data_reference reference:",
+			    dataReference->get_reference()->get_data(
+			    	dataReference->get_reference()->get_data_length() ),
+			    dataReference->get_reference()->get_data_length() ) );
+		
+		    EAP_TRACE_DEBUG_SYMBIAN( ( _L(
+			    "wapi_am_core_symbian_c::WriteCertificateStoreDataL() \
+			    change status=%d.\n" ), dataReference->get_change_status() ) );
+			}
+
+		if ( dataReference != 0
+			&& dataReference->get_is_valid() == true
+			&& dataReference->get_type() != ec_cs_data_type_none
+			&& dataReference->get_change_status() != ec_cs_data_change_status_none )
+		    {			
+		    ec_cs_data_change_status_e changeStatus = dataReference->get_change_status();
+			switch( csDataType )
+			    {
+				case ec_cs_data_type_master_key:
+				case ec_cs_data_type_reference_counter:
+					{
+				    WriteCsDataL( dataReference, EFalse );
+				    break;
+				    }
+				case ec_cs_data_type_password: 
+				case ec_cs_data_type_device_seed: 
+				case ec_cs_data_type_certificate_file_password:
+				    {
+				    // not saved; nothing to do
+				    break;
+				    }
+				case ec_cs_data_type_ca_certificate_data:
+				case ec_cs_data_type_client_certificate_data:
+				case ec_cs_data_type_private_key_data:				
+                case ec_cs_data_type_client_asu_id:
+                case ec_cs_data_type_ca_asu_id:
+				    {
+				    if ( changeStatus == ec_cs_data_change_status_modified )
+				    	{
+					    WriteCsDataWithReferenceL( dataReference, EFalse );				    
+				    	}
+				    else if ( changeStatus == ec_cs_data_change_status_new )
+				    	{
+					    WriteCsDataWithReferenceL( dataReference, ETrue );				    
+				    	}
+				    else if ( changeStatus == ec_cs_data_change_status_delete )
+				    	{
+				    	DeleteCsDataWithReferenceL( dataReference );
+				    	}
+				    else
+				        {
+	                    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	                        "ERROR: wapi_am_core_symbian_c::WriteCertificateStoreDataL() \
+	                        unknown change_status=%d.\n" ), changeStatus ) );
+				        }
+				    break;
+				    }
+				default:
+					{
+					EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+				        "ERROR: wapi_am_core_symbian_c::WriteCertificateStoreDataL() \
+				        unknown csDataType=%d.\n" ), csDataType ) );
+					iWapiCompletionStatus = eap_status_not_found;
+					User::Leave( KErrArgument );
+					}
+			    } // switch( csDataType )
+			
+		    } // if ( dataReference != 0...
+	    else
+	        {
+	        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	                "Warning: wapi_am_core_symbian_c::WriteCertificateStoreDataL() \
+	                failed" ) ) );
+	        if ( dataReference != 0 )
+	            {
+	            EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	                    "Warning: wapi_am_core_symbian_c::WriteCertificateStoreDataL() \
+		                No changes needed, reference: 0x%08x: type %d\n" ),
+		                dataReference, dataReference->get_type() ) );
+
+	            if ( dataReference->get_reference() != 0 )
+	                 {
+	                 EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	                         "Warning: wapi_am_core_symbian_c::WriteCertificateStoreDataL() \
+	                         unknown reference, or no changes needed" ),
+	                         dataReference->get_reference()->get_data(),
+	                         dataReference->get_reference()->get_data_length() ) );
+	                 }
+	            if ( dataReference->get_data() != 0 )
+	                {
+	                EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	                        "Warning: wapi_am_core_symbian_c::WriteCertificateStoreDataL() \
+		    	            unknown data" ),
+		    	            dataReference->get_data()->get_data(),
+		    	            dataReference->get_data()->get_data_length() ) );
+	                }
+	            }
+	        } // else
+	    } // for(...)
+
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::WriteCertificateStoreDataL() OUT\n" ) ) );
+	
+	} // wapi_am_core_symbian_c::WriteCertificateStoreDataL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::WriteCsDataWithReferenceL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::WriteCsDataWithReferenceL(
+    const ec_cs_data_c* const aDataReference,
+    TBool aIsNewEntry )
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::WriteCsDataWithReferenceL() IN\n" ) ) );
+	
+	// Get the data (or value) from the input
+	HBufC8* csDbColVal8 = HBufC8::NewLC(
+		aDataReference->get_data()->get_data_length() );
+	TPtr8 csDbColValPtr8 = csDbColVal8->Des();
+	csDbColValPtr8.Copy( aDataReference->get_data()->get_data(),
+                         aDataReference->get_data()->get_data_length() );
+	
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::WriteCsDataWithReferenceL() \
+		8 bit VALUE from common:",
+		csDbColValPtr8.Ptr(), csDbColValPtr8.Size() ) );
+	
+	// Get the reference from the input
+	HBufC8* csDbColRef8 = HBufC8::NewLC(
+		aDataReference->get_reference()->get_data_length() );
+	TPtr8 csDbColRefPtr8 = csDbColRef8->Des();
+	csDbColRefPtr8.Copy( aDataReference->get_reference()->get_data(),
+                         aDataReference->get_reference()->get_data_length() );
+
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::WriteCsDataWithReferenceL() \
+		8 bit REFERENCE from common:",
+		csDbColRefPtr8.Ptr(), csDbColRefPtr8.Size() ) );
+	
+	iCertificateStoreDb->SetCsDataByReferenceL(
+			aDataReference->get_type(),
+			csDbColValPtr8,
+			csDbColRefPtr8,
+			aIsNewEntry );
+
+    CleanupStack::PopAndDestroy( csDbColRef8 );
+	CleanupStack::PopAndDestroy( csDbColVal8 );
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::WriteCsDataWithReferenceL() OUT\n" ) ) );
+
+	} // wapi_am_core_symbian_c::WriteCsDataWithReferenceL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::WriteCsDataL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::WriteCsDataL(
+    const ec_cs_data_c* const aDataReference,
+    TBool aIsNewEntry )
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::WriteCsDataL() IN\n" ) ) );
+
+	// Get the data (or value) from the input
+	HBufC8* csDbColVal8 = HBufC8::NewLC(
+		aDataReference->get_data()->get_data_length() );
+	TPtr8 csDbColValPtr8 = csDbColVal8->Des();
+	csDbColValPtr8.Copy( aDataReference->get_data()->get_data(),
+                         aDataReference->get_data()->get_data_length() );
+	
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::WriteCsDataL() \
+		8 bit VALUE from common:",
+		csDbColValPtr8.Ptr(), csDbColValPtr8.Size() ) );
+		
+	iCertificateStoreDb->SetCsDataL(
+		aDataReference->get_type(),
+		csDbColValPtr8,
+        aIsNewEntry );
+
+	CleanupStack::PopAndDestroy( csDbColVal8 );
+	
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::WriteCsDataL() OUT\n" ) ) );
+	
+	} /// wapi_am_core_symbian_c::WriteCsDataL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::DeleteCsDataWithReferenceL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::DeleteCsDataWithReferenceL(
+	const ec_cs_data_c* const aDataReference )
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::DeleteCsDataWithReferenceL() IN\n" ) ) );
+	
+    // Get the data (or value) from the input
+    HBufC8* csDbColVal8 = HBufC8::NewLC(
+	    aDataReference->get_data()->get_data_length() );
+    TPtr8 csDbColValPtr8 = csDbColVal8->Des();
+    csDbColValPtr8.Copy( aDataReference->get_data()->get_data(),
+                         aDataReference->get_data()->get_data_length() );
+
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+	    "wapi_am_core_symbian_c::DeleteCsDataWithReferenceL() \
+	    8 bit VALUE from common:",
+	    csDbColValPtr8.Ptr(), csDbColValPtr8.Size() ) );
+
+    // Get the reference from the input
+    HBufC8* csDbColRef8 = HBufC8::NewLC(
+	    aDataReference->get_reference()->get_data_length() );
+    TPtr8 csDbColRefPtr8 = csDbColRef8->Des();
+    csDbColRefPtr8.Copy( aDataReference->get_reference()->get_data(),
+                         aDataReference->get_reference()->get_data_length() );
+
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+	    "wapi_am_core_symbian_c::DeleteCsDataWithReferenceL() \
+	    8 bit REFERENCE from common:",
+	    csDbColRefPtr8.Ptr(), csDbColRefPtr8.Size() ) );
+
+    iCertificateStoreDb->RemoveCsDataByReferenceL(
+		aDataReference->get_type(),
+		csDbColValPtr8,
+		csDbColRefPtr8 );
+
+    CleanupStack::PopAndDestroy( csDbColVal8 );
+    CleanupStack::PopAndDestroy( csDbColRef8 );
+
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::DeleteCsDataWithReferenceL() OUT\n" ) ) );
+
+	} // wapi_am_core_symbian_c::DeleteCsDataWithReferenceL()
+
+
+// ================= private: New, reading from CS =======================
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ReadCertificateStoreDataL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::ReadCertificateStoreDataL()
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadCertificateStoreDataL() IN\n" ) ) );
+
+	iWapiCompletionStatus = eap_status_ok;
+	
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadCertificateStoreDataL() \
+        First dataRefType=%d.\n" ), iInReferences.get_object( 0 )->get_type() ) );
+    
+	iReferencesAndDataBlocks.reset();
+
+	for( u32_t ind = 0ul; ind < iInReferences.get_object_count(); ind++ )
+	    {
+
+	    const ec_cs_data_c* const dataReference =
+            iInReferences.get_object( ind );
+	    
+        if (dataReference->get_is_valid() == false)
+            {
+            EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "wapi_am_core_symbian_c::ReadCertificateStoreDataL() ERROR: datablock to be written is unvalid!\n" )));
+            return;
+            }
+
+        if (iInReferences.get_object( ind )->get_reference()->get_data_length() >0)
+	        {
+	        EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+                "wapi_am_core_symbian_c::ReadCertificateStoreDataL() dataReference:",
+                dataReference->get_reference()->get_data(
+                    dataReference->get_reference()->get_data_length() ), 
+                dataReference->get_reference()->get_data_length() ) );
+	        }
+		if ( dataReference != 0
+			&& dataReference->get_is_valid() == true )
+		    {
+		    ec_cs_data_type_e dataRefType = dataReference->get_type();
+	        if (dataRefType == NULL)
+	            {
+	            EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	                "wapi_am_core_symbian_c::ReadCertificateStoreDataL() ERROR: dataType to be written is unvalid!\n" )));
+	            return;
+	            }
+
+			EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+				"wapi_am_core_symbian_c::ReadCertificateStoreDataL() \
+				dataRefType=%d.\n" ), dataRefType ) );
+		    				
+			
+			iGetAll = EFalse;
+			
+			switch( dataRefType )
+			    {
+				case ec_cs_data_type_master_key:         
+				case ec_cs_data_type_reference_counter:  
+				case ec_cs_data_type_client_asu_id_list: 
+				case ec_cs_data_type_ca_asu_id_list:
+					{
+				    ReadCsDataL( dataReference );
+				    break;
+				    }
+				case ec_cs_data_type_password:
+					{
+					ReadPasswordL( dataReference );
+					break;
+					}
+				case ec_cs_data_type_device_seed:
+				    {
+				    ReadDeviceSeedL( dataReference );
+				    break;
+				    }
+				case ec_cs_data_type_certificate_file_password:
+				    {
+				    ReadCertificateFilePasswordL( dataReference );
+				    break;
+				    }
+				case ec_cs_data_type_ca_certificate_data:     
+				case ec_cs_data_type_client_certificate_data: 
+				case ec_cs_data_type_private_key_data:				
+                case ec_cs_data_type_client_asu_id: 
+                case ec_cs_data_type_ca_asu_id:
+                case ec_cs_data_type_selected_ca_id:
+                case ec_cs_data_type_selected_client_id:
+				    {
+				    ReadCsDataByReferenceL( dataReference );				    
+				    break;
+				    }
+				default:
+					{
+					EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+				        "ERROR: wapi_am_core_symbian_c::ReadCertificateStoreDataL() \
+				        unknown dataRefType=%d.\n" ), dataRefType ) );
+					iWapiCompletionStatus = eap_status_not_found;
+					User::Leave( KErrArgument );
+					}
+			    } // switch( dataRefType )
+		    } // if ( dataReference != 0...
+	    } // for(...)
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::ReadCertificateStoreDataL() OUT\n" ) ) );
+	
+	} // wapi_am_core_symbian_c::ReadCertificateStoreDataL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ReadCsDataByReferenceL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::ReadCsDataByReferenceL(
+	const ec_cs_data_c* const aDataReference )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadCsDataByReferenceL() IN\n" ) ) );
+
+	HBufC8* outColumnValue = NULL;
+        
+   	GetCsDataByReferenceL( aDataReference, &outColumnValue );   
+   	if ( outColumnValue == NULL )
+    	{
+    	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: wapi_am_core_symbian_c::ReadCsDataByReferenceL() \
+        	outColumnValue is NULL!\n" ) ) );
+    	}
+   	else
+   	    CopyBufToEapVarL( *outColumnValue, iEapVarData );
+   	
+    // ownership was transfered from CS here
+    // delete buffer
+    delete outColumnValue;
+    outColumnValue = NULL;
+    
+    AddObjectL( aDataReference, &iEapVarData );
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadCsDataByReferenceL() OUT\n" ) ) );
+    
+    } // wapi_am_core_symbian_c::ReadCsDataByReferenceL()
+
+   
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ReadCsDataL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::ReadCsDataL(
+	const ec_cs_data_c* const aDataReference )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadCsDataL() IN\n" ) ) );
+
+	HBufC8* outColumnValue = NULL;
+	
+	ec_cs_data_type_e dataType = aDataReference->get_type();
+	ec_cs_data_type_e dataTypeToCaller(dataType);
+    iGetAll = EFalse;    
+
+    if (dataType == ec_cs_data_type_ca_asu_id_list)
+		{
+		dataTypeToCaller = ec_cs_data_type_ca_asu_id;
+		iGetAll = ETrue;	
+		}
+	if (dataType == ec_cs_data_type_client_asu_id_list)
+		{
+        dataTypeToCaller = ec_cs_data_type_client_asu_id;
+		iGetAll = ETrue;	
+		}
+	
+	if (iGetAll == EFalse)
+		{
+		TRAPD(err, GetCsDataL( dataType, &outColumnValue ));
+		if (err)
+		    {
+		    delete outColumnValue;
+		    outColumnValue = NULL;
+		    }
+	   	if ( outColumnValue == NULL )
+	    	{
+	    	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	            "ERROR: wapi_am_core_symbian_c::ReadCsDataL() \
+	        	outColumnValue is NULL!\n" ) ) );
+	    	}
+	   	else
+	   	    {
+	   	    CopyBufToEapVarL( *outColumnValue, iEapVarData );
+	   	    }	   	
+	    // ownership was transfered from CS here
+	    // delete buffer
+      AddObjectL( aDataReference, &iEapVarData );
+	    delete outColumnValue;
+	    outColumnValue = NULL;
+	    
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	        "wapi_am_core_symbian_c::ReadCsDataL() OUT\n" ) ) );
+		}
+	else
+		{
+		iCertArray.Reset();
+		TRAPD(err, GetCsTableL( dataType, &outColumnValue, iCertArray ));
+        delete outColumnValue;
+        outColumnValue = NULL;
+		if (err)
+		    {
+	        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	            "wapi_am_core_symbian_c::GetCsTableL() Leave\n" ) ) );
+	        User::Leave(err);
+	        }
+		else
+		    {
+            EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "wapi_am_core_symbian_c::GetCsTableL() Ok\n" ) ) );
+		    TInt aCounter = 0; 
+		    
+             while (aCounter < iCertArray.Count() )
+                {
+                 ec_cs_data_c* const csData = new ec_cs_data_c( iAmTools );
+                   
+                   if ( csData == NULL )
+                       {
+                       iWapiCompletionStatus = eap_status_allocation_error;
+                       EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                           "ERROR: wapi_am_core_symbian_c::AddObjectL() csData is NULL.\n" ) ) );
+                       User::Leave( iAmTools->convert_eapol_error_to_am_error(
+                           eap_status_allocation_error ) );
+                       }
+               if (iCertArray[aCounter].iReference->Size()>0 && iCertArray[aCounter].iData->Size()>0)
+                    {
+                    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                           "wapi_am_core_symbian_c::ReadCsDataL() copy reference\n" ) ) );
+
+                    csData->set_type(dataTypeToCaller);
+                    TPtr8 aDbBinaryColumnRefPtr = iCertArray[aCounter].iReference->Des();
+
+                    iWapiCompletionStatus = csData->get_writable_reference()->
+                    set_copy_of_buffer( aDbBinaryColumnRefPtr.Ptr(), aDbBinaryColumnRefPtr.Size() );
+                    
+                    EAP_TRACE_DATA_DEBUG_SYMBIAN(
+                        ("wapi_am_core_symbian_c::ReadCsDataL: reference to caller",
+                                csData->get_reference()->get_data(csData->get_reference()->get_data_length()), 
+                                csData->get_reference()->get_data_length()));
+                    if ( iWapiCompletionStatus != eap_status_ok )
+                        {
+                        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                            "ERROR: wapi_am_core_symbian_c::ReadCsDataL() Failed to add \
+                            new object, iWapiCompletionStatus=%d.\n" ), iWapiCompletionStatus ) );
+                        delete csData;
+                        User::Leave( iAmTools->convert_eapol_error_to_am_error(
+                            iWapiCompletionStatus ) );
+                        }
+                    
+                    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                        "wapi_am_core_symbian_c::ReadCsDataL() copy data\n" ) ) );
+
+                    TPtr8 aDbBinaryColumnValuePtr = iCertArray[aCounter].iData->Des();
+                     
+                    iWapiCompletionStatus = csData->get_writable_data()->
+                        set_copy_of_buffer( aDbBinaryColumnValuePtr.Ptr(), aDbBinaryColumnValuePtr.Size() );
+                    
+                    EAP_TRACE_DATA_DEBUG_SYMBIAN(
+                        ("wapi_am_core_symbian_c::ReadCsDataL: data to caller",
+                                csData->get_data()->get_data(csData->get_data()->get_data_length()), 
+                                csData->get_data()->get_data_length()));
+
+                    iWapiCompletionStatus = iReferencesAndDataBlocks.add_object( csData, true );
+
+                    delete iCertArray[aCounter].iReference;
+                    iCertArray[aCounter].iReference = NULL;
+                    delete iCertArray[aCounter].iData;
+                    iCertArray[aCounter].iData=NULL;
+                    
+                    if ( iWapiCompletionStatus != eap_status_ok )
+                        {
+                        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                                "ERROR: wapi_am_core_symbian_c::ReadCsDataL() Failed to add \
+                                new object, iWapiCompletionStatus=%d.\n" ), iWapiCompletionStatus ) );
+                        delete csData;
+                        User::Leave( iAmTools->convert_eapol_error_to_am_error(
+                                iWapiCompletionStatus ) );
+                        }
+                    }
+                aCounter++;
+                }
+             iCertArray.Reset();
+             EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "wapi_am_core_symbian_c::ReadCsDataL() OUT\n" ) ) );
+
+		    }
+		}
+	
+    } // wapi_am_core_symbian_c::ReadCsDataL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::GetCsDataByReferenceL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::GetCsDataByReferenceL(
+    const ec_cs_data_c* const aDataReference,
+    HBufC8** aOutColumnValue )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::GetCsDataByReferenceL() IN\n" ) ) );
+    
+    const eap_variable_data_c * const reference = aDataReference->get_reference();
+	if ( reference == NULL )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: wapi_am_core_symbian_c::GetCsDataByReferenceL() \
+            reference is NULL.\n" ) ) );
+		// Can't proceed.
+		User::Leave( KErrArgument );		
+		}
+	if ( reference->get_data_length() <= 0 )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: wapi_am_core_symbian_c::GetCsDataByReferenceL() \
+            reference is empty.\n" ) ) );
+		// Can't proceed.
+		User::Leave( KErrArgument );		
+		}
+
+	HBufC8* reference8 = HBufC8::NewL( reference->get_data_length() );
+	TPtr8 referencePtr8 = reference8->Des();				
+	referencePtr8.Copy( reference->get_data(), reference->get_data_length() );
+	
+          
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::GetCsDataByReferenceL() reference to DB",
+		referencePtr8.Ptr(), referencePtr8.Size() ) );			
+
+    ec_cs_data_type_e dataType = aDataReference->get_type();
+    
+  EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+          "wapi_am_core_symbian_c::GetCsDataByReferenceL() dataType = %d, m_is_client=%d ec_cs_data_type_selected_ca_id=%d ec_cs_data_type_selected_client_id=%d\n" ),
+           dataType, m_is_client, ec_cs_data_type_selected_ca_id,ec_cs_data_type_selected_client_id ) );
+
+    if ((dataType == ec_cs_data_type_selected_ca_id || dataType == ec_cs_data_type_selected_client_id) && m_is_client)
+        {
+        TUint32 aIndex = 0;
+        eap_variable_data_c database_reference_index(iAmTools);
+
+        eap_status_e status = iPartner->read_configure(
+            cf_str_WAPI_database_reference_index.get_field(),
+            &database_reference_index);
+        if (status != eap_status_ok
+            || database_reference_index.get_is_valid_data() == false
+            || database_reference_index.get_data_length() != sizeof(u32_t)
+            || database_reference_index.get_data(sizeof(u32_t)) == 0)
+            {
+            EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+            User::Leave( KErrArgument );        
+            }
+
+        u32_t *index = reinterpret_cast<u32_t *>(
+            database_reference_index.get_data(sizeof(u32_t)));
+        if (index != 0)
+            {
+            EAP_TRACE_DEBUG(
+                iAmTools,
+                TRACE_FLAGS_DEFAULT,
+                (EAPL("WAPI_Core: this = 0x%08x, %s: wapi_am_core_symbian_c::GetCsDataByReferenceL(): database_reference_index = %d\n"),
+                 this,
+                 (m_is_client == true ? "client": "server"),
+                 *index));
+            aIndex = static_cast<TUint32>(*index);
+            }
+
+        EAP_TRACE_DEBUG(
+             iAmTools,
+             TRACE_FLAGS_DEFAULT,
+             (EAPL("WAPI_Core: this = 0x%08x, %s: wapi_am_core_symbian_c::GetCsDataByReferenceL(): aIndex = %d\n"),
+              this,
+              (m_is_client == true ? "client": "server"),
+              aIndex));
+        
+        referencePtr8.SetLength(sizeof(aIndex));
+        referencePtr8.Copy( reinterpret_cast<TUint8*>(&aIndex), sizeof(aIndex) );
+        
+        EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+            "wapi_am_core_symbian_c::GetCsDataByReferenceL() reference to DB 2",
+            referencePtr8.Ptr(), referencePtr8.Size() ) );          
+        }
+
+	// read certificate store
+	TRAPD( err, iCertificateStoreDb->GetCsDataByReferenceL( 
+			dataType,
+			referencePtr8,
+			aOutColumnValue
+		    ) );
+
+	if ( err != KErrNone )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	        "wapi_am_core_symbian_c::iCertificateStoreDb->GetCsDataByReferenceL() ERROR: %d\n" ),err ) );
+		
+        if ( *aOutColumnValue != NULL )
+        	{ // some data was allocated by CS
+		    delete *aOutColumnValue;
+		    *aOutColumnValue = NULL;
+		    delete reference8;
+		    reference8 = NULL;
+       		}
+		User::Leave( err );
+		}
+	
+	delete reference8;
+	reference8 = NULL;
+	
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::GetCsDataByReferenceL() OUT\n" ) ) );
+
+    } // wapi_am_core_symbian_c::GetCsDataByReferenceL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::GetCsDataL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::GetCsDataL(
+    ec_cs_data_type_e aDataType,
+    HBufC8** aOutColumnValue )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::GetCsDataL() IN\n" ) ) );
+    
+    // read certificate store
+	TRAPD( err, iCertificateStoreDb->GetCsDataL( 
+		aDataType,         // data type
+		aOutColumnValue,// returned column value, memory is allocated in CS
+		iCertArray,     // data array for certificate info
+		EFalse    		// get all or one row
+	    ) );
+	
+	if ( err != KErrNone )
+		{
+        if ( *aOutColumnValue != NULL )
+        	{
+		    delete *aOutColumnValue;
+		    *aOutColumnValue = NULL;
+        	}
+		User::Leave( err );
+		}
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::GetCsDataL() OUT\n" ) ) );
+
+    } // wapi_am_core_symbian_c::GetCsDataL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::GetCsTableL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::GetCsTableL( ec_cs_data_type_e aDataType,
+  			HBufC8** aOutColumnValue,
+  			RArray<SWapiCertEntry>& aArray)
+{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::GetCsTableL() IN\n" ) ) );
+
+    // read certificate store
+	TRAPD( err, iCertificateStoreDb->GetCsDataL( 
+		aDataType,         // data type
+		aOutColumnValue,    // returned column value, memory is allocated in CS
+		aArray,     // data array for certificate info
+		ETrue    		// get all or one row
+	    ) );
+	
+	if ( err != KErrNone )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	        "wapi_am_core_symbian_c::GetCsTableL() LEAVE FROM iCertificateStoreDb->GetCsDataL\n" ) ) );
+        TInt aCounter = 0;	
+        while (aCounter < aArray.Count())
+	        {
+	        delete (aArray[aCounter].iData);
+	        aArray[aCounter].iData = NULL;
+	        delete (aArray[aCounter].iReference);
+	        aArray[aCounter].iReference = NULL;
+	        aCounter++;
+	        }
+		User::Leave( err );
+		}
+
+	
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::GetCsTableL() OUT\n" ) ) );
+
+	
+}
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ReadPasswordL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::ReadPasswordL(
+	const ec_cs_data_c* const aDataReference )
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadPasswordL() IN\n" ) ) );
+	
+	/*
+	* NOTE:  The password usage is reserved for future,
+	* when there will be config UI support. Use some 
+	* temporary password now. When password is really used,
+	* delete this code and uncomment below one.
+    */
+	_LIT( KTempPassword, "12345" );
+
+	iWapiCompletionStatus = iCsPassword.set_copy_of_buffer(
+		KTempPassword().Ptr(), KTempPassword().Size() );
+	if ( iWapiCompletionStatus != eap_status_ok )
+		{
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		    "ERROR: wapi_am_core_symbian_c::ReadPasswordL() \
+		    buffer copy failed, status=%d.\n" ), iWapiCompletionStatus ) );
+		User::Leave( iAmTools->convert_eapol_error_to_am_error(
+			iWapiCompletionStatus ) );
+		}
+
+	AddObjectL( aDataReference, &iCsPassword );
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadPasswordL() OUT\n" ) ) );
+	
+	} // wapi_am_core_symbian_c::ReadPasswordL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ReadDeviceSeedL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::ReadDeviceSeedL(
+	const ec_cs_data_c* const aDataReference )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadDeviceSeedL() IN\n" ) ) );
+		
+    eap_variable_data_c csDeviceSeed( iAmTools );
+    
+    iWapiCompletionStatus = csDeviceSeed.set_copy_of_buffer(
+    	iWapiDeviceSeed->get_data( iWapiDeviceSeed->get_data_length() ),
+    	iWapiDeviceSeed->get_data_length() );
+ 	if ( iWapiCompletionStatus != eap_status_ok )
+	    {		
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		    "ERROR: wapi_am_core_symbian_c::ReadDeviceSeedL() \
+			buffer copy failed, status=%d.\n" ), iWapiCompletionStatus ) );
+		User::Leave( iAmTools->convert_eapol_error_to_am_error(
+			iWapiCompletionStatus ) );
+	    }
+
+	EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+		"wapi_am_core_symbian_c::ReadDeviceSeedL() Device seed",
+		csDeviceSeed.get_data( csDeviceSeed.get_data_length() ),
+		csDeviceSeed.get_data_length() ) );
+
+	AddObjectL( aDataReference, &csDeviceSeed );
+
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadDeviceSeedL() OUT\n" ) ) );
+    
+    } // wapi_am_core_symbian_c::ReadDeviceSeedL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ReadCertificateFilePasswordL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::ReadCertificateFilePasswordL(
+	const ec_cs_data_c* const aDataReference )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadCertificateFilePasswordL() IN\n" ) ) );
+	
+#if defined( WAPI_USE_UI_NOTIFIER )   		        
+    StartAsynchRequest( EWapiQueryImportFilePasswordState );
+#endif
+    
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ReadCertificateFilePasswordL() OUT\n" ) ) );
+	
+    } // wapi_am_core_symbian_c::ReadCertificateFilePasswordL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::AddObjectL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::AddObjectL(
+	const ec_cs_data_c* const aDataReference,
+	const eap_variable_data_c* const aData )
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::AddObjectL() IN\n" ) ) );
+
+	ec_cs_data_c* const csData = new ec_cs_data_c( iAmTools );
+    
+	if ( csData == NULL )
+		{
+		iWapiCompletionStatus = eap_status_allocation_error;
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: wapi_am_core_symbian_c::AddObjectL() csData is NULL.\n" ) ) );
+		User::Leave( iAmTools->convert_eapol_error_to_am_error(
+			eap_status_allocation_error ) );
+		}
+	
+	ec_cs_data_type_e type = aDataReference->get_type();
+	csData->set_type( type );					
+
+    // set the reference.
+	iWapiCompletionStatus = csData->get_writable_reference()->
+	    set_copy_of_buffer( aDataReference->get_reference() );
+	if ( iWapiCompletionStatus != eap_status_ok )
+		{
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: wapi_am_core_symbian_c::AddObjectL() Failed to copy \
+            reference, iWapiCompletionStatus=%d.\n" ), iWapiCompletionStatus ) );
+        delete csData;
+		User::Leave( iAmTools->convert_eapol_error_to_am_error(
+			iWapiCompletionStatus ) );
+		}
+
+	iWapiCompletionStatus = csData->get_writable_data()->set_copy_of_buffer(
+		aData );
+	
+     if ( iWapiCompletionStatus != eap_status_ok )
+		{
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: wapi_am_core_symbian_c::AddObjectL() Failed to copy \
+            master key, iWapiCompletionStatus=%d.\n" ), iWapiCompletionStatus ) );
+        delete csData;
+		User::Leave( iAmTools->convert_eapol_error_to_am_error(
+			iWapiCompletionStatus ) );
+		}
+	
+	iWapiCompletionStatus = iReferencesAndDataBlocks.add_object( csData, true );
+
+	if ( iWapiCompletionStatus != eap_status_ok )
+	    {
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: wapi_am_core_symbian_c::AddObjectL() Failed to add \
+            new object, iWapiCompletionStatus=%d.\n" ), iWapiCompletionStatus ) );
+		delete csData;
+		User::Leave( iAmTools->convert_eapol_error_to_am_error(
+			iWapiCompletionStatus ) );
+		}
+					
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+    	"wapi_am_core_symbian_c::AddObjectL() Added data",
+		( csData->get_data() )->get_data( ( csData->get_data() )
+			->get_data_length() ),
+		( csData->get_data() )->get_data_length() ) );						
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::AddObjectL() OUT\n" ) ) );
+
+	} // wapi_am_core_symbian_c::AddObjectL()
+
+
+// ================= private: New, start/complete asynch. requests =======================
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::StartAsynchRequest()
+// ---------------------------------------------------------
+//
+TBool wapi_am_core_symbian_c::StartAsynchRequest(
+	wapi_am_core_symbian_c::TWapiState aState )
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::StartAsynchRequest() IN, \
+        aState=%d.\n" ), aState ) );
+    TBool status = ETrue;
+
+    if( IsActive() )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: wapi_am_core_symbian_c::StartAsynchRequest() \
+	        AO is active, iState=%d, aState=%d.\n" ), aState, aState ) );
+		return EFalse;
+		}
+	if ( iCancelCalled )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "wapi_am_core_symbian_c::StartAsynchRequest() \
+		     Cancel was called.\n" ) ) );
+		return EFalse;
+		}
+    iState = aState;    
+    switch ( iState )
+        {
+#if defined( WAPI_USE_UI_NOTIFIER )   		    
+        
+        case EWapiQueryCertFilePasswordState:
+        	{
+        	StartQueryCertFilePassword();
+            SetActive();
+        	}
+        case EWapiQueryImportFilePasswordState:
+        	{
+        	StartQueryImportFilePassword();
+            SetActive();
+        	break;
+        	}
+#endif // WAPI_USE_UI_NOTIFIER
+
+        default:
+        	{
+    	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+   	            "ERROR: wapi_am_core_symbian_c::StartAsynchRequest() \
+   		        State is not supported, iState = %d.\n" ), iState ) );
+    		status = EFalse;
+            break;
+        	}
+        }
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::StartAsynchRequest() OUT, \
+        status=%d.\n" ), status ) );
+    return status;
+	
+	} // wapi_am_core_symbian_c::StartAsynchRequest()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::StartQueryCertFilePassword()
+// ---------------------------------------------------------
+//
+#if defined( WAPI_USE_UI_NOTIFIER )   		    
+void wapi_am_core_symbian_c::StartQueryCertFilePassword()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::StartQueryCertFilePassword() IN\n" ) ) );
+    
+    iNotifierDataToUser->iState = TWapiUiNotifierState::
+        EWapiUiNotifierCsPasswordDialog;
+    iNotifier.StartNotifierAndGetResponse( 
+        iStatus,
+        KWapiNotifierUid,
+        *iNotifierDataPckgToUser,
+        *iNotifierDataPckgFromUser );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::StartQueryCertFilePassword() OUT\n" ) ) );
+	
+	} // wapi_am_core_symbian_c::StartQueryCertFilePassword()
+#endif // WAPI_USE_UI_NOTIFIER
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::CompleteQueryCertFilePassword()
+// ---------------------------------------------------------
+//
+#if defined( WAPI_USE_UI_NOTIFIER )   		    
+void wapi_am_core_symbian_c::CompleteQueryCertFilePassword()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::CompleteQueryCertFilePassword() IN\n" ) ) );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::CompleteQueryCertFilePassword() OUT\n" ) ) );
+	
+	} // wapi_am_core_symbian_c::CompleteQueryCertFilePassword()
+#endif // WAPI_USE_UI_NOTIFIER
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::StartQueryImportFilePassword()
+// ---------------------------------------------------------
+//
+#if defined( WAPI_USE_UI_NOTIFIER )   		    
+void wapi_am_core_symbian_c::StartQueryImportFilePassword()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::StartQueryImportFilePassword() IN\n" ) ) );
+    
+    iNotifierDataToUser->iState = TWapiUiNotifierState::
+        EWapiUiNotifierImportFileDialog;
+    iNotifier.StartNotifierAndGetResponse( 
+        iStatus,
+        KWapiNotifierUid,
+        *iNotifierDataPckgToUser,
+        *iNotifierDataPckgFromUser );
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::StartQueryImportFilePassword() OUT\n" ) ) );
+	
+	} // wapi_am_core_symbian_c::StartQueryImportFilePassword()
+#endif // WAPI_USE_UI_NOTIFIER
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::CompleteQueryImportFilePassword()
+// ---------------------------------------------------------
+//
+#if defined( WAPI_USE_UI_NOTIFIER )   		    
+void wapi_am_core_symbian_c::CompleteQueryImportFilePassword()
+	{
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::CompleteQueryCertFilePassword() IN\n" ) ) );
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::CompleteQueryImportFilePassword() OUT\n" ) ) );
+	
+	} // wapi_am_core_symbian_c::CompleteQueryImportFilePassword()
+#endif // WAPI_USE_UI_NOTIFIER
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ImportFilesL()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::ImportFilesL()
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	"wapi_am_core_symbian_c::ImportFilesL() IN\n" ) ) );
+
+	eap_status_e status = eap_status_ok;
+
+    if ( iCertificateStoreDb == NULL )
+        {
+        iCertificateStoreDb = CCertificateStoreDatabase::NewL( iAmTools );
+        }
+
+    EAP_TRACE_ALWAYS(
+        iAmTools,
+        TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+        (EAPL("ImportFilesL: %s: \n"),
+        (m_is_client == true ? "client": "server")));
+
+    TBool aFileAlreadyInList = EFalse;
+    
+    RDbNamedDatabase& db = iCertificateStoreDb->GetCertificateStoreDb();
+
+   // Create a buffer for the ascii strings - initialised in query
+    HBufC8* asciibuf = HBufC8::NewLC(KMaxFileName);
+    TPtr8 asciiString = asciibuf->Des();
+    asciiString.Zero();
+    
+    // Buffer for unicode parameter
+    HBufC* unicodebuf = HBufC::NewLC(KMaxFileName);
+    TPtr unicodeString = unicodebuf->Des();
+    
+     HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
+    TPtr sqlStatement = buf->Des();
+    _LIT(KSQLQueryRow, "SELECT * FROM %S");
+    sqlStatement.Format(KSQLQueryRow, &KCsWapiCertFileTable);
+    
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+        "wapi_am_core_symbian_c::ImportFilesL() sqlStatement for delete",
+        sqlStatement.Ptr(), 
+        sqlStatement.Size() ) );    
+
+    RDbView view;
+    User::LeaveIfError(view.Prepare( db, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EUpdatable));
+
+    CleanupClosePushL(view);
+    User::LeaveIfError(view.EvaluateAll()); 
+    if (view.FirstL())
+        {
+        if (m_is_client)
+          {
+          do
+              {
+                view.GetL();        
+                switch (view.ColType(KDefaultColumnNumberOne))
+                    {
+                    case EDbColText:                
+                        {
+                            unicodeString = view.ColDes(KDefaultColumnNumberOne);
+                            // Convert to 8-bit
+                            if (unicodeString.Size() > 0)
+                                {
+                                asciiString.Copy(unicodeString);
+                                if (status != eap_status_ok)
+                                    {
+                                    User::Leave(KErrNoMemory);
+                                    }
+                                } 
+                            else 
+                                {
+                                // Empty field. Do nothing...data remains invalid
+                                break;
+                                }
+                        }     
+                     break;
+                    case EDbColBinary:
+                        {
+                        TPtrC8 dbValuePtrC8 = view.ColDes8( KDefaultColumnNumberOne );
+                          
+                        asciiString.Copy( dbValuePtrC8 );
+                        
+                        EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+                          "ImportFilesL BINARY value from DB",
+                          asciiString.Ptr(), asciiString.Size() ) );
+                        
+                        }
+                        break;
+                    } // switch
+                if (asciiString.Size() > 0)
+                    {
+                    HBufC* FilePathD = HBufC::NewLC(KMaxFileName);
+                    TPtr FilePathPtrD = FilePathD->Des();
+                    HBufC8* FilePathD8 = HBufC8::NewLC(KMaxFileName);
+                    TPtr8 FilePathPtrD8 = FilePathD8->Des();
+                    
+                    FilePathPtrD8.Zero();
+                    FilePathPtrD8.Append(KCertificateStoreImportDir);
+                    FilePathPtrD8.Append(asciiString);
+    
+                    FilePathPtrD.Copy(FilePathPtrD8);
+    
+                    EAP_TRACE_DATA_DEBUG(
+                            iAmTools,
+                        TRACE_FLAGS_DEFAULT,
+                        (EAPL("wapi_am_core_symbian_c::ImportFilesL: Delete File"),
+                        FilePathPtrD.Ptr(),
+                        FilePathPtrD.Size()));
+                    RFs aFs;
+                    aFs.Connect( KFileServerDefaultMessageSlots );
+                    aFs.SetAtt(FilePathPtrD, NULL, KEntryAttReadOnly);
+
+                    if(aFs.Delete(FilePathPtrD)!= KErrNone)
+                        {
+                        EAP_TRACE_DATA_DEBUG(
+                                iAmTools,
+                                TRACE_FLAGS_DEFAULT,
+                                (EAPL("wapi_am_core_symbian_c::ImportFilesL: Couldn't delete file"),
+                                        FilePathPtrD.Ptr(),
+                                        FilePathPtrD.Size()));
+                         }
+                    else
+                        {
+                        view.DeleteL(); // remove current record
+                        }
+                    CleanupStack::PopAndDestroy(FilePathD8); 
+                    CleanupStack::PopAndDestroy(FilePathD);
+                    
+                   }
+               
+              }  while (view.NextL() != EFalse);
+          }
+        }
+
+    CleanupStack::PopAndDestroy(4); // view, asciibuf, unicodebuf, buf
+
+	CDir* aFiles = NULL;
+	 
+	RFs aFs;
+	aFs.Connect( KFileServerDefaultMessageSlots );
+
+	iWapiCompletionStatus = eap_status_pending_request;
+
+	TInt aFileCounter=0;
+	TBool aDirectoryEmpty = false;
+	TBool aDirectoryExists = true;
+	HBufC* buf2 = HBufC::NewLC(KMaxPath);
+    TPtr aFileNamePtr = buf2->Des();
+	HBufC8* aFileName8 = HBufC8::NewLC(KMaxFileName);
+	TUint aFileSize =0;
+	TPtr8 aFileNamePtr8 = aFileName8->Des();
+	TBool aBadFile = false;
+	HBufC* aPath = HBufC::NewLC(KMaxFileName);
+	TPtr aPathPtr = aPath->Des();
+	HBufC8* aPath8 = HBufC8::NewLC(KMaxFileName);
+	TPtr8 aPathPtr8 = aPath8->Des();
+	HBufC8* aReadData = NULL;
+	TBool aFileFound(EFalse);
+	
+	aPathPtr8.Zero();
+	aPathPtr8.Append(KCertificateStoreImportDir);
+
+	aPathPtr.Zero();
+	aPathPtr.Copy(aPathPtr8);
+
+	if (aFs.GetDir(aPathPtr, KEntryAttNormal, ESortByName, aFiles) == KErrNone)
+		{
+		EAP_TRACE_DEBUG_SYMBIAN(
+				(_L("wapi_am_core_symbian_c::ImportFilesL: aFiles %d"),
+						aFiles->Count()));
+		
+		while (aFileFound  == EFalse && (aFileCounter < aFiles->Count()))
+			{
+			aDirectoryExists = true;
+			aFileAlreadyInList = EFalse;
+			if (!((*aFiles)[aFileCounter].IsDir()))
+                {
+                aDirectoryEmpty = false;
+                aFileSize = (*aFiles)[aFileCounter].iSize;
+
+                aFileNamePtr8.Copy((*aFiles)[aFileCounter].iName);
+
+                 EAP_TRACE_DATA_DEBUG(
+                         iAmTools,
+                         TRACE_FLAGS_DEFAULT,
+                         (EAPL("wapi_am_core_symbian_c::ImportFilesL: aFileName"),
+                         aFileNamePtr8.Ptr(),
+                         aFileNamePtr8.Size()));
+
+                 EAP_TRACE_DEBUG_SYMBIAN(
+                        (_L("wapi_am_core_symbian_c::ImportFilesL: aFile size %d"),
+                                aFileSize));
+                 TInt i = 0;
+                 while (i< iImportedFilenames.Count())
+                     {
+                     if (aFileNamePtr8.Compare(iImportedFilenames[i]) == 0)
+                         aFileAlreadyInList = ETrue;
+                     i++;
+                     }
+ 
+                if (CheckFilenameL(aFileNamePtr8) == EFalse && aFileAlreadyInList == EFalse)
+                    {
+                    EAP_TRACE_DEBUG_SYMBIAN(
+                            (_L("wapi_am_core_symbian_c::ImportFilesL: File not yet Imported -> import")));                  
+
+                    if (aFileSize > KMaxCertificateFileSize)
+                        {
+                        EAP_TRACE_DEBUG_SYMBIAN(
+                               (_L("wapi_am_core_symbian_c::ImportFilesL: aFile size %d bigger than limit %d, do not import"),
+                                       aFileSize, KMaxCertificateFileSize));
+                        TBuf8<KMaxFileName> aFile; 
+                        aFile.Copy(aFileNamePtr8.Ptr(),aFileNamePtr8.Size());
+                        iImportedFilenames.Append(aFile);
+                        iWapiCompletionStatus = set_timer(
+                                 this,
+                                 EWapiAddCertificateFileTimerId, 
+                                 0,
+                                 0);
+                        
+                        delete aFiles;
+
+                        CleanupStack::PopAndDestroy(aPath8);
+                        CleanupStack::PopAndDestroy(aPath);
+                        CleanupStack::PopAndDestroy(aFileName8);
+                        CleanupStack::PopAndDestroy(buf2);
+                        EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+                        return EAP_STATUS_RETURN(iAmTools, iWapiCompletionStatus);
+                        }
+                    else
+                        aFileFound = ETrue;
+                    }
+                else
+                    {
+                    EAP_TRACE_DEBUG_SYMBIAN(
+                            (_L("wapi_am_core_symbian_c::ImportFilesL: File already imported")));                  
+                    }
+                }
+            aFileCounter++;
+			}
+			
+			if (!aFileFound)
+				{
+				EAP_TRACE_DEBUG_SYMBIAN(
+					(_L("wapi_am_core_symbian_c::ImportFilesL: aDirectoryEmpty or files already imported")));					
+				aDirectoryEmpty = true;
+				}
+			if (aDirectoryEmpty == true ||  aDirectoryExists == false || aFileFound == EFalse)
+				{
+				if (aDirectoryExists)
+					{
+                    delete aFiles;
+                    iWapiCompletionStatus = iCertStorePartner->complete_initialize_certificate_store( iCompletionOperation );
+                    CleanupStack::PopAndDestroy(aPath8);
+                    CleanupStack::PopAndDestroy(aPath);
+                    CleanupStack::PopAndDestroy(aFileName8);
+                    CleanupStack::PopAndDestroy(buf2);
+                    EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+                    return EAP_STATUS_RETURN(iAmTools, iWapiCompletionStatus);
+					}
+				}
+			else if(aFileFound != EFalse)
+				{
+				aPathPtr8.Zero();
+				aPathPtr8.Append(KCertificateStoreImportDir);
+				aPathPtr8.Append(aFileNamePtr8);
+				aPathPtr.Zero();
+				aPathPtr.Copy(aPathPtr8);
+				
+				EAP_TRACE_DEBUG_SYMBIAN(
+						(_L("wapi_am_core_symbian_c::ImportFilesL: Read aFile")));	
+				
+				RFile aFile;
+				if(aFile.Open(aFs, aPathPtr, EFileRead)==KErrNone)
+					{
+					aReadData= HBufC8::NewLC(aFileSize); 
+					TPtr8 aReadDataPtr = aReadData->Des();
+					aFile.Read(aReadDataPtr);
+					aFile.Close();
+					
+					EAP_TRACE_DEBUG_SYMBIAN(
+							(_L("wapi_am_core_symbian_c::ImportFilesL: Copy data")));	
+					
+					eap_variable_data_c * const in_imported_certificate_data = new eap_variable_data_c(iAmTools);
+                    if (in_imported_certificate_data == NULL)
+                        {
+                        CleanupStack::PopAndDestroy(aReadData);
+
+                        delete aFiles;
+
+                        CleanupStack::PopAndDestroy(aPath8);
+                        CleanupStack::PopAndDestroy(aPath);
+                        CleanupStack::PopAndDestroy(aFileName8);
+                        CleanupStack::PopAndDestroy(buf2);
+
+                        iWapiCompletionStatus = eap_status_allocation_error;
+                        EAP_TRACE_DEBUG_SYMBIAN(
+                                (_L("wapi_am_core_symbian_c::ImportFilesL: iWapiCompletionStatus != eap_status_ok")));  
+                        if (in_imported_certificate_data != NULL)
+                            delete in_imported_certificate_data;
+                         return EAP_STATUS_RETURN(iAmTools, iWapiCompletionStatus);
+                        
+                        }
+
+					iWapiCompletionStatus = in_imported_certificate_data->set_copy_of_buffer(aReadDataPtr.Ptr(), aReadDataPtr.Size());
+
+					eap_variable_data_c * const in_imported_certificate_file_name = new eap_variable_data_c(iAmTools);
+					if (in_imported_certificate_file_name == NULL)
+					    {
+	                    CleanupStack::PopAndDestroy(aReadData);
+
+	                    delete aFiles;
+
+	                    CleanupStack::PopAndDestroy(aPath8);
+	                    CleanupStack::PopAndDestroy(aPath);
+	                    CleanupStack::PopAndDestroy(aFileName8);
+	                    CleanupStack::PopAndDestroy(buf2);
+
+	                    iWapiCompletionStatus = eap_status_allocation_error;
+                        EAP_TRACE_DEBUG_SYMBIAN(
+                                (_L("wapi_am_core_symbian_c::ImportFilesL: iWapiCompletionStatus != eap_status_ok")));  
+                        if (in_imported_certificate_data != NULL)
+                            delete in_imported_certificate_data;
+                        if (in_imported_certificate_file_name != NULL)
+                            delete in_imported_certificate_file_name;
+                        return EAP_STATUS_RETURN(iAmTools, iWapiCompletionStatus);
+					    
+					    }
+
+					iWapiCompletionStatus = in_imported_certificate_file_name->set_copy_of_buffer(aFileNamePtr8.Ptr(), aFileNamePtr8.Size());
+					
+                    CleanupStack::PopAndDestroy(aReadData);
+
+					EAP_TRACE_DEBUG_SYMBIAN(
+							(_L("wapi_am_core_symbian_c::ImportFilesL: Complete operation")));	
+					
+                    delete aFiles;
+                    aFiles = NULL;
+
+                    CleanupStack::PopAndDestroy(aPath8);
+                    CleanupStack::PopAndDestroy(aPath);
+                    CleanupStack::PopAndDestroy(aFileName8);
+                    CleanupStack::PopAndDestroy(buf2);
+
+                    if (iWapiCompletionStatus != eap_status_ok)
+						{
+	                    EAP_TRACE_DEBUG_SYMBIAN(
+	                            (_L("wapi_am_core_symbian_c::ImportFilesL: iWapiCompletionStatus != eap_status_ok")));  
+						if (in_imported_certificate_data != NULL)
+							delete in_imported_certificate_data;
+						if (in_imported_certificate_file_name != NULL)
+							delete in_imported_certificate_file_name;
+ 						return EAP_STATUS_RETURN(iAmTools, iWapiCompletionStatus);
+						}
+					else
+						{
+                        EAP_TRACE_DEBUG_SYMBIAN(
+                                (_L("wapi_am_core_symbian_c::ImportFilesL: iWapiCompletionStatus == eap_status_ok")));  
+						iWapiCompletionStatus = iCertStorePartner->add_imported_certificate_file(
+							in_imported_certificate_data,
+							in_imported_certificate_file_name);
+                        EAP_TRACE_DEBUG_SYMBIAN(
+                                (_L("wapi_am_core_symbian_c::ImportFilesL: iCertStorePartner->add_imported_certificate_file == %d"), iWapiCompletionStatus));  
+                         if (iWapiCompletionStatus != eap_status_ok && iWapiCompletionStatus != eap_status_pending_request)
+                             {
+                             TBuf8<KMaxFileName> aFile;
+                             aFile.Copy(in_imported_certificate_file_name->get_data(in_imported_certificate_file_name->get_data_length()), in_imported_certificate_file_name->get_data_length());
+                             iImportedFilenames.Append(aFile);
+                             iWapiCompletionStatus = set_timer(
+                                      this,
+                                      EWapiAddCertificateFileTimerId, 
+                                      0,
+                                      0);
+                            }
+                        return EAP_STATUS_RETURN(iAmTools, iWapiCompletionStatus);	
+						}
+					}
+				}
+			else
+				{
+				aBadFile = true;
+				}
+			}
+	
+    delete aFiles;
+
+    CleanupStack::PopAndDestroy(aPath8);
+    CleanupStack::PopAndDestroy(aPath);
+    CleanupStack::PopAndDestroy(aFileName8);
+    CleanupStack::PopAndDestroy(buf2);
+	EAP_TRACE_DEBUG_SYMBIAN(
+		(_L("wapi_am_core_symbian_c::ImportFilesL: Operation failed or Complete")));	
+
+	
+	if(iWapiCompletionStatus != eap_status_pending_request || aFileFound == EFalse)
+		{
+			
+		if(aBadFile == true || aDirectoryEmpty == true ||  aDirectoryExists == false)   	
+				{
+				if (m_is_client)
+				    iWapiCompletionStatus = eap_status_file_does_not_exist;
+				else
+				    iWapiCompletionStatus = eap_status_ok;
+				iCertStorePartner->complete_initialize_certificate_store( iCompletionOperation );
+				}
+			else
+				{
+				iWapiCompletionStatus = eap_status_ok;
+				iCertStorePartner->complete_initialize_certificate_store( iCompletionOperation );
+				}
+		}
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::ImportFilesL() OUT\n" ) ) );
+	return iWapiCompletionStatus;
+	
+	} // wapi_am_core_symbian_c::ImportFilesL()
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::CheckFilenameL()
+// ---------------------------------------------------------
+//
+TBool wapi_am_core_symbian_c::CheckFilenameL(TPtr8 aFileNamePtr )
+    {
+    EAP_TRACE_DEBUG(iAmTools, 
+            TRACE_FLAGS_DEFAULT, (
+            EAPL("CheckFilenameL - Start\n")));
+
+    TBool aFound = EFalse;
+//    TBool aSaved = EFalse;
+    
+    RDbNamedDatabase& db = iCertificateStoreDb->GetCertificateStoreDb();
+    
+    // Create a buffer for the ascii strings - initialised in query
+    HBufC8* asciibuf = HBufC8::NewLC(KMaxFileName);
+    TPtr8 asciiString = asciibuf->Des();
+    asciiString.Zero();
+    
+    // Buffer for unicode parameter
+    HBufC* unicodebuf = HBufC::NewLC(KMaxFileName);
+    TPtr unicodeString = unicodebuf->Des();
+    
+    HBufC* buf = HBufC::NewLC(KMaxSqlQueryLength);
+    TPtr sqlStatement = buf->Des();
+
+    _LIT(KSQLQueryRow, "SELECT * FROM %S");
+    sqlStatement.Format(KSQLQueryRow, &KCsWapiCertFileTable);
+
+    EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+    "wapi_am_core_symbian_c::CheckFilenameL() sqlStatement for KCsWapiCertFileTable",
+    sqlStatement.Ptr(), 
+    sqlStatement.Size() ) );    
+  
+    TInt aFileCountInDB = 0;
+    RDbView view;
+    User::LeaveIfError(view.Prepare( db, TDbQuery(sqlStatement), TDbWindow::EUnlimited, RDbView::EUpdatable));
+    
+    CleanupClosePushL(view);
+    User::LeaveIfError(view.EvaluateAll()); 
+    if (view.FirstL())
+        {
+        do
+            {
+            view.GetL();        
+            switch (view.ColType(KDefaultColumnNumberOne))
+                {
+                case EDbColText:                
+                    {
+                    unicodeString = view.ColDes(KDefaultColumnNumberOne);
+                    // Convert to 8-bit
+                                                
+                    if (unicodeString.Size() > 0)
+                        {
+                        asciiString.Copy(unicodeString);
+                        if (aFileNamePtr.Compare(asciiString) == 0)
+                            {
+                                 aFound = ETrue;
+                            }
+                         } 
+                    else 
+                        {
+                        // Empty field. Do nothing
+                        break;
+                        }
+                    }
+                break;
+                case EDbColBinary:
+                    {
+                    TPtrC8 dbValuePtrC8 = view.ColDes8( KDefaultColumnNumberOne );
+                      
+                    asciiString.Copy( dbValuePtrC8 );
+                    
+                    if (asciiString.Size()>0 && aFileCountInDB<3)
+                        {
+                        if (aFileNamePtr.Compare(asciiString) == 0)
+                            {
+                                aFound = ETrue;
+                            }
+                        EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+                                "wapi_am_core_symbian_c::CheckFilenameL() BINARY value from DB",
+                                asciiString.Ptr(), asciiString.Size() ) );
+                        }
+                    }
+                break;
+               
+                default:
+                    {
+                    EAP_TRACE_DEBUG(
+                            iAmTools,
+                            TRACE_FLAGS_DEFAULT,
+                            (EAPL("wapi_am_core_symbian_c::CheckFilenameL: Unexpected column type. %s\n"), asciiString.Ptr(), asciiString.Size() )); 
+                    }
+                    break;
+                }
+            } while (view.NextL() != EFalse);
+    
+    
+    
+        }
+    
+    CleanupStack::PopAndDestroy(4); //  asciibuf, unicodebuf, buf, view
+    
+    EAP_TRACE_DEBUG(iAmTools, 
+            TRACE_FLAGS_DEFAULT, (
+            EAPL("CheckFilenameL - Out\n")));
+    return aFound;
+   }
+                
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::UpdatePasswordTimeL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::UpdatePasswordTimeL()
+	{
+
+	} // wapi_am_core_symbian_c::UpdatePasswordTimeL()
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::CheckPasswordTimeValidityL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::CheckPasswordTimeValidityL()
+	{
+	/* Check validity of password against timelimit */
+	
+	EAP_TRACE_DEBUG(iAmTools, 
+			TRACE_FLAGS_DEFAULT, (
+			EAPL("CheckPasswordTimeValidityL - Start\n")));
+
+	} // wapi_am_core_symbian_c::CheckPasswordTimeValidityL()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ConvertFromBuf8ToBuf16LC()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::ConvertFromBuf8ToBuf16LC(const TDesC8& aInBuf8,
+        HBufC16** aOutBuf16)
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                            "wapi_am_core_symbian_c::ConvertFromBuf8ToBuf16LC() IN\n" ) ) );
+
+    // convert utf8->unicode,
+    // aInBuf8 is UTF8 string, unicode max length is
+    // then the length of UTF8 string.
+    // NOTE, HBufC16 length means count of 16-bit objects.
+    *aOutBuf16 = HBufC16::NewL(aInBuf8.Size() );
+    CleanupStack::PushL(aOutBuf16);
+    TPtr16 outBufPtr16 = ( *aOutBuf16 )->Des();
+
+    const TPtrC8 inBufPtrC8(aInBuf8);
+
+    CnvUtfConverter::ConvertToUnicodeFromUtf8(outBufPtr16, inBufPtrC8);
+
+    // print data
+    EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                            "wapi_am_core_symbian_c::ConvertFromBuf8ToBuf16LC() aInBuf8" ),
+                    inBufPtrC8.Ptr(), inBufPtrC8.Size() ) );
+
+    EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                            "wapi_am_core_symbian_c::ConvertFromBuf8ToBuf16LC() aOutBuf16" ),
+                    outBufPtr16.Ptr(), outBufPtr16.Size() ) );
+
+     EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                            "wapi_am_core_symbian_c::ConvertFromBuf8ToBuf16LC() OUT\n" ) ) );
+
+    } // wapi_am_core_symbian_c::ConvertFromBuf8ToBuf16LC()
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::ReadIntDbValue()
+// ---------------------------------------------------------
+//
+TInt64 wapi_am_core_symbian_c::ReadIntDbValueL(
+	RDbNamedDatabase& aDb,
+	const TDesC& aColumnName,
+	const TDesC& aSqlStatement )
+    {
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, (
+			EAPL( "wapi_am_core_symbian_c::ReadIntDbValueL()\n" ) ) );
+    TPtrC columnName;    
+	columnName.Set( aColumnName );
+	
+	RDbView view;
+
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, (
+		EAPL( "ReadIntDbValue() prepare view\n" ) ) );
+
+	User::LeaveIfError( view.Prepare( aDb, TDbQuery(
+		aSqlStatement ) ) );
+	CleanupClosePushL( view );
+	
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, (
+		EAPL("ReadIntDbValue() evaluate view\n" ) ) );
+	User::LeaveIfError( view.EvaluateAll() );		
+	// Get the first (and only) row
+	view.FirstL();
+	view.GetL();
+	// Get column set so we get the correct column numbers
+	CDbColSet* colSet = view.ColSetL();
+	CleanupStack::PushL( colSet );
+	TInt64 retVal = view.ColInt64( colSet->ColNo( columnName ) );
+
+	CleanupStack::PopAndDestroy( colSet ); 
+	CleanupStack::PopAndDestroy( &view );
+
+	return retVal;
+    } // wapi_am_core_symbian_c::ReadIntDbValueL
+
+
+// ================= New, complete asynch. query methods in active object =======================
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::CompleteHandlingDeviceSeedQueryState()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::CompleteHandlingDeviceSeedQueryState()
+	{
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"wapi_am_core_symbian_c::CompleteHandlingDeviceSeedQueryState() IN\n" ) ) );
+	
+	if ( iStatus != KErrNone )
+		{
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+			"ERROR: wapi_am_core_symbian_c::CompleteHandlingDeviceSeedQueryState() \
+			aStatus=%d.\n" ), iStatus.Int() ) );
+		}
+	EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"Manufacturer" ), iDeviceId.iManufacturer.Ptr(),
+		iDeviceId.iManufacturer.Size() ) );
+	EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"Model"), iDeviceId.iModel.Ptr(), iDeviceId.iModel.Size() ) );
+	EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"Revision"), iDeviceId.iRevision.Ptr(), iDeviceId.iRevision.Size()));
+	EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		"SerialNumber"), iDeviceId.iSerialNumber.Ptr(),
+		iDeviceId.iSerialNumber.Size() ) );
+		
+	// Combine all needed items.			
+	TBuf<KMaxDeviceSeedLength> deviceSeed16;	
+	deviceSeed16 += iDeviceId.iManufacturer;
+	deviceSeed16 += iDeviceId.iModel;
+	deviceSeed16 += iDeviceId.iSerialNumber;
+		
+	TBuf8<KMaxDeviceSeedSize> deviceSeed8;
+	deviceSeed8.Copy(deviceSeed16);		
+
+	if ( iWapiDeviceSeed != NULL )
+		{
+		if( deviceSeed8.Size() > 0)
+		    {
+		    iWapiDeviceSeed->set_copy_of_buffer(
+			    deviceSeed8.Ptr(),
+				deviceSeed8.Size());
+			}
+		}
+	TRAPD(err, DisconnectMMETEL());
+ 	if (err)
+		{
+		EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+		        "ERROR: wapi_am_core_symbian_c::Leave from DisconnectMMETEL () err=%d.\n" ), err ) );
+		}
+	
+ 	iWapiCompletionStatus = set_timer(
+			this,
+			EWapiAddCertificateFileTimerId, 
+			0,
+			0);
+
+	EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	    "wapi_am_core_symbian_c::CompleteHandlingDeviceSeedQueryState() OUT\n" ) ) );
+	
+	}
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::CopyBufToEapVarL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::CopyBufToEapVarL(
+	const TDesC8& aInBuf, eap_variable_data_c& aOutEapVar )
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::CopyBufToEapVar() \
+         buf size=%d.\n" ), aInBuf.Size() ) );
+	
+    iWapiCompletionStatus = eap_status_ok;
+    
+	if ( aInBuf.Size() > 0 )
+		{
+		iWapiCompletionStatus = aOutEapVar.set_copy_of_buffer(
+		    aInBuf.Ptr(), aInBuf.Size() );
+		}
+	else
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+            "ERROR: wapi_am_core_symbian_c::CopyBufToEapVar() \
+            No data to copy!\n" ) ) );
+	    aOutEapVar.reset();
+	    return;
+		}
+	
+	if ( iWapiCompletionStatus != eap_status_ok )
+		{
+	    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+	        "ERROR: wapi_am_core_symbian_c::CopyBufToEapVar() \
+	        Failed to copy data, status=%d\n" ), iWapiCompletionStatus ) );
+		User::Leave( iAmTools->convert_eapol_error_to_am_error(
+		iWapiCompletionStatus ) );
+		}
+	
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+        "wapi_am_core_symbian_c::CopyBufToEapVar() OUT\n" ) ) );
+
+    } // wapi_am_core_symbian_c::CopyBufToEapVar()
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::complete_start_certificate_import()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::complete_start_certificate_import()
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "wapi_am_core_symbian_c::complete_start_certificate_import()" ) ) );
+    // Now that the certificate import was done, the list of available
+    // certificates can be queried.
+    // This functionality is completed with complete_query_certificate_list
+    
+    iWapiCompletionStatus = iCertStorePartner->query_certificate_list();
+    
+    return iWapiCompletionStatus;
+    
+    }
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::complete_query_certificate_list()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::complete_query_certificate_list(
+    EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const ca_certificates,
+    EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const user_certificates)
+    {
+
+    // Call the actual complete_query function with the implementation
+    TInt trapErr = KErrNone;
+    eap_status_e returnErr = eap_status_ok;
+    TRAP( trapErr, returnErr = complete_query_certificate_listL(ca_certificates, user_certificates ));
+    
+    // There was some allocation error in the trapped function
+    if ( trapErr != KErrNone )
+        {
+        return EAP_STATUS_RETURN( iAmTools, eap_status_allocation_error);
+        }
+    
+    return EAP_STATUS_RETURN( iAmTools, returnErr );
+    }
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::complete_query_certificate_list()
+// ---------------------------------------------------------
+//
+eap_status_e wapi_am_core_symbian_c::complete_query_certificate_listL(
+    EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const ca_certificates,
+    EAP_TEMPLATE_CONST eap_array_c<eap_variable_data_c> * const user_certificates)
+    {
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "wapi_am_core_symbian_c::complete_query_certificate_list() start" ) ) );
+    
+     TInt memIndex = 0;
+    eap_status_e status = eap_status_ok;
+    _LIT(KNone, "None");
+    _LIT8(KNone8, "None");
+
+    wapi_asn1_der_parser_c wapiAsn1(iAmTools);
+    if ( wapiAsn1.get_is_valid() == false )
+        {
+        EAP_TRACE_END(iAmTools, TRACE_FLAGS_DEFAULT);
+        return EAP_STATUS_RETURN(iAmTools, eap_status_allocation_error);
+        }
+
+    eap_variable_data_c subjectName(iAmTools);
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "wapi_am_core_symbian_c::complete_query_certificate_list() loops" ) ) );
+    // If there are CA labels, then we store them to the member variable
+    if ( ca_certificates != NULL )
+        {
+        if ( ca_certificates->get_object_count() > 0 )
+            {
+            // Create the array since data exists
+            *iCACerts = new(ELeave) RArray<TBuf<KCsMaxWapiCertLabelLen> >;
+            CleanupStack::PushL(*iCACerts);
+             memIndex++;
+            ( *iCACerts )->Reset();
+
+            *iCACertsData = new(ELeave) RArray<TBuf8<KMaxIdentityLength> >;
+            CleanupStack::PushL(*iCACertsData);
+             memIndex++;
+           
+            ( *iCACertsData )->Reset();
+
+            // Copy "none" as the first item into the array, requested by UI
+            HBufC* tmp = HBufC::NewLC( 4 );
+            HBufC8* tmpData = HBufC8::NewLC( 4 );
+            memIndex++;
+            memIndex++;
+            *tmp = KNone;
+            *tmpData = KNone8;
+            
+            EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                     "wapi_am_core_symbian_c::complete_query_certificate_list() add CA empty" ) ) );
+            ( *iCACerts )->AppendL( *tmp );
+            ( *iCACertsData )->AppendL( *tmpData );
+            
+            // Loop all the given identities through
+            for ( TInt i = 0; i < ca_certificates->get_object_count(); i++ )
+                {
+                EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                         "wapi_am_core_symbian_c::complete_query_certificate_list() loop CA" ) ) );
+                // Decode and store data to the RArray 
+                if (ca_certificates->get_object(i) != NULL)
+                    {
+                    status = wapiAsn1.get_decoded_subject_name(
+                            ca_certificates->get_object(i), &subjectName );
+                    // Don't store label if an error occurred
+                    if ( status != eap_status_ok )
+                        {
+                        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                                 "wapi_am_core_symbian_c::complete_query_certificate_list() decode fail" ) ) );
+                        }
+                    else
+                        {
+                        TBuf8<KCsMaxWapiCertLabelLen> tmpLabel;
+                        tmpLabel.Append( subjectName.get_data( subjectName.get_data_length() ),
+                                         subjectName.get_data_length() );
+                        HBufC16* tmp16Label;
+                        ConvertFromBuf8ToBuf16LC( tmpLabel, &tmp16Label );
+                        memIndex++;
+                       (*iCACerts)->AppendL( *tmp16Label );
+          
+                        HBufC8* tmpData = HBufC8::NewLC( ca_certificates->get_object(i)->get_data_length() );
+                        memIndex++;
+                        TPtr8 tmpDataPtr = tmpData->Des();
+                               
+                        tmpDataPtr.Copy(ca_certificates->get_object(i)->get_data(), ca_certificates->get_object(i)->get_data_length());
+     
+                        ( *iCACertsData )->AppendL( *tmpData );
+    
+                        EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+                            "wapi_am_core_symbian_c::complete_query_certificate_list() CA identity",
+                            tmpDataPtr.Ptr(), 
+                            tmpDataPtr.Size() ) );    
+                       }
+                    
+                    subjectName.reset();
+                    }
+                }
+            }
+        }
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "wapi_am_core_symbian_c::complete_query_certificate_list() looped CA continue with Client" ) ) );
+    
+    // If there are labels, then we store them to the member variable
+    if ( user_certificates != NULL )
+        {
+        if ( user_certificates->get_object_count() > 0 )
+            {
+            // Create the array since data exists
+            *iUserCerts = new(ELeave) RArray<TBuf<KCsMaxWapiCertLabelLen> >;
+            CleanupStack::PushL(*iUserCerts);
+            memIndex++;
+            ( *iUserCerts )->Reset();
+
+            *iUserCertsData = new(ELeave) RArray<TBuf8<KMaxIdentityLength> >;
+            CleanupStack::PushL(*iUserCertsData);
+             memIndex++;
+            ( *iUserCertsData )->Reset();
+
+            // Copy "none" as the first item into the array, requested by UI
+            HBufC* tmp = HBufC::NewLC( 4 );
+            HBufC8* tmpData = HBufC8::NewLC( 4 );
+            memIndex++;
+            memIndex++;
+            *tmp = KNone;
+            *tmpData = KNone8;
+            
+            ( *iUserCerts )->AppendL( *tmp );
+            ( *iUserCertsData )->AppendL( *tmpData );
+            
+            // Loop all the given identities through
+            for ( TInt i = 0; i < user_certificates->get_object_count(); i++ )
+                {
+                EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                         "wapi_am_core_symbian_c::complete_query_certificate_list() loop user" ) ) );
+                // Decode and store data to the RArray
+                if (user_certificates->get_object(i) != NULL)
+                    {
+                    status = wapiAsn1.get_decoded_subject_name(
+                            user_certificates->get_object(i), &subjectName );
+                    // Don't store label if an error occurred
+                    if (status != eap_status_ok)
+                        {
+                        EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                                 "wapi_am_core_symbian_c::complete_query_certificate_list() decode fail" ) ) );
+                        }
+                    else
+                        {
+                        TBuf8<KCsMaxWapiCertLabelLen> tmpLabel;
+                        tmpLabel.Append( subjectName.get_data( subjectName.get_data_length() ),
+                                         subjectName.get_data_length() );
+                        HBufC16* tmp16Label;
+                        ConvertFromBuf8ToBuf16LC( tmpLabel, &tmp16Label );
+                        memIndex++;
+                        ( *iUserCerts )->AppendL( *tmp16Label );
+                        
+                        HBufC8* tmpData = HBufC8::NewLC( user_certificates->get_object(i)->get_data_length() );
+                        memIndex++;
+                        TPtr8 tmpDataPtr = tmpData->Des();
+                               
+                        tmpDataPtr.Copy(user_certificates->get_object(i)->get_data(), user_certificates->get_object(i)->get_data_length());
+        
+                        ( *iUserCertsData )->AppendL( *tmpData);
+                         
+                        
+                        EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+                             "wapi_am_core_symbian_c::complete_query_certificate_list() client identity",
+                             tmpDataPtr.Ptr(), 
+                             tmpDataPtr.Size() ) ); 
+                         }
+                    subjectName.reset();
+                    }
+                }
+            }
+        }
+    if (*iCACerts)
+        {
+        for (TInt aCa = 0; aCa <(*iCACerts)->Count(); aCa++)
+            {
+            TPtrC certPtr;
+            certPtr.Set ((**iCACerts)[aCa]);
+            EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "CaCert:"), certPtr.Ptr(),
+                certPtr.Size() ));
+    
+            EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+                "wapi_am_core_symbian_c::complete_query_certificate_list() CA identity",
+                (**iCACertsData )[aCa].Ptr(), 
+                (**iCACertsData )[aCa].Size() ) ); 
+    
+            }
+        }
+    if (*iUserCerts)
+        {
+        for (TInt aCa = 0; aCa <(*iUserCerts)->Count(); aCa++)
+            {
+            TPtrC certPtr;
+            certPtr.Set ((**iUserCerts)[aCa]);
+            EAP_TRACE_DATA_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+                "ClientCert:"), certPtr.Ptr(),
+                certPtr.Size() ));
+    
+            EAP_TRACE_DATA_DEBUG_SYMBIAN( (
+                 "wapi_am_core_symbian_c::complete_query_certificate_list() client identity",
+                 (**iUserCertsData )[aCa].Ptr(), 
+                 (**iUserCertsData )[aCa].Size() ) ); 
+            }
+        }
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "wapi_am_core_symbian_c::complete_query_certificate_list() looping done" ) ) );
+
+    // The memory handling is up to the caller. The pointers to the arrays are set to NULL
+    // and the caller will handle the data and the memory hanling from now on
+    if (memIndex != 0)
+        {
+        CleanupStack::Pop(memIndex);
+        }
+
+    // if the status is failed, then we don't send any lists to the caller,
+    // delete the lists
+    if (status != eap_status_ok)
+        {
+        delete *iUserCerts;
+        delete *iCACerts;
+        delete *iUserCertsData;
+        delete *iCACertsData;
+        *iUserCerts = NULL;
+        *iCACerts = NULL;
+        *iUserCertsData = NULL;
+        *iCACertsData = NULL;
+        }
+    iUserCerts = NULL;
+    iCACerts = NULL;
+    iUserCertsData = NULL;
+    iCACertsData = NULL;
+
+    // Now the wapicertificates function can continue from its getAllCertificates
+    // function
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "wapi_am_core_symbian_c::complete_query_certificate_list(), labels ready" ) ) );
+    TRequestStatus* reqStatus = iWapiCertsStatus;
+    User::RequestComplete(reqStatus, KErrNone);
+
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "wapi_am_core_symbian_c::complete_query_certificate_list- end" )));
+
+    return status;
+    }
+
+
+// ---------------------------------------------------------
+// wapi_am_core_symbian_c::GetAllCertificateLabelsL()
+// ---------------------------------------------------------
+//
+void wapi_am_core_symbian_c::GetAllCertificateLabelsL( RArray<TBuf<KCsMaxWapiCertLabelLen> > **aUserCerts,
+        RArray<TBuf<KCsMaxWapiCertLabelLen> > **aCACerts,
+        RArray<TBuf8<KMaxIdentityLength> > **aUserCertsData,
+        RArray<TBuf8<KMaxIdentityLength> > **aCACertsData,
+        TRequestStatus& aStatus)
+
+    {
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "wapi_am_core_symbian_c::GetAllCertificateLabelsL() start" ) ) );
+    
+    // Check that the received pointers are valid
+
+    if ( aUserCerts == NULL || aCACerts == NULL || aUserCertsData == NULL || aCACertsData == NULL )
+        {
+        User::Leave( KErrArgument );
+        }
+    
+    // Set the WAPICertificates Active object status to pending
+    iWapiCertsStatus = &aStatus;
+    *iWapiCertsStatus = KRequestPending;
+    
+    eap_status_e status = eap_status_ok;
+    
+    if ( iCertStorePartner == NULL )
+        {
+        EAP_TRACE_ERROR(
+            iAmTools,
+            TRACE_FLAGS_DEFAULT,
+            (EAPL("ERROR: wapi_am_core_symbian_c::GetAllCertificateLabelsL \
+                    certStoreparner is NULL!\n"))); 
+        User::Leave( KErrGeneral );
+        }
+    
+    // Start certificate import and continue with certificate list query only if everything goes ok
+    status = iCertStorePartner->start_certificate_import();
+    if (status != eap_status_pending_request)
+        {  
+        EAP_TRACE_ERROR(
+            iAmTools,
+            TRACE_FLAGS_DEFAULT,
+            (EAPL("ERROR: wapi_am_core_symbian_c::GetAllCertificateLabelsL\
+                    configure failed!\n")));
+        User::Leave(iAmTools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(iAmTools, status)));
+        } 
+        
+    // store the given pointers to member variables to be able to update
+    // the lists when the operation is completed
+    iUserCerts = aUserCerts;
+    iCACerts = aCACerts;
+    iUserCertsData = aUserCertsData;
+    iCACertsData = aCACertsData;
+    
+    EAP_TRACE_DEBUG( iAmTools, TRACE_FLAGS_DEFAULT, ( EAPL(
+             "wapi_am_core_symbian_c::GetAllCertificateLabelsL() end" ) ) );
+    }
+    
+//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+//----------------------------------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_am_base_core_c *wapi_am_base_core_c::new_wapi_am_core(
+		abs_eap_am_tools_c * const tools,
+		abs_wapi_am_core_c * const partner,
+		const bool is_client_when_true,
+		const eap_am_network_id_c* eap_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("WAPI_Core: wapi_am_core_symbian_c::wapi_am_base_core_c():\n")));
+
+	EAP_TRACE_RETURN_STRING(tools, "returns: wapi_am_base_core_c::wapi_am_base_core_c()");
+
+	wapi_am_core_symbian_c * wapi_am_core_symbian = 0;
+#if defined(WAPI_USE_CERTIFICATE_STORE)
+
+	TRAPD( err, wapi_am_core_symbian = wapi_am_core_symbian_c::NewL(
+		tools,
+		partner,
+		is_client_when_true));
+
+	if (err || wapi_am_core_symbian == 0)
+	{
+		return 0;
+	}
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return wapi_am_core_symbian;
+
+#else
+
+	return 0;
+
+#endif //#if defined(WAPI_USE_CERTIFICATE_STORE)
+
+}
+
+
+//--------------------------------------------------	
+
+// End of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/wapi_core/symbian/wapi_am_wlan_authentication_symbian.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,1161 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/wapi_core/symbian/wapi_am_wlan_authentication_symbian.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 22.1.1 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// This is enumeration of EAPOL source code.
+#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+	#undef EAP_FILE_NUMBER_ENUM
+	#define EAP_FILE_NUMBER_ENUM 151 
+	#undef EAP_FILE_NUMBER_DATE 
+	#define EAP_FILE_NUMBER_DATE 1127594498 
+#endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES)
+
+#include "wapi_am_wlan_authentication_symbian.h"
+#include "abs_wapi_am_wlan_authentication.h"
+
+#include "eap_header_string.h"
+#include "eap_config.h"
+#include "eap_file_config.h"
+#include "eap_am_file_input_symbian.h"
+#include "eap_type_selection.h"
+#include "eapol_key_types.h"
+#include "eap_timer_queue.h"
+#include "eap_crypto_api.h"
+#include "abs_eapol_wlan_database_reference_if.h"
+#include "abs_eap_state_notification.h"
+#include "eap_state_notification.h"
+#include "eap_automatic_variable.h"
+#include "wapi_core.h"
+#include "WapiDbDefaults.h"
+#include "certificate_store_db_parameters.h"
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_am_wlan_authentication_symbian_c::~wapi_am_wlan_authentication_symbian_c()
+    {
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::~wapi_am_wlan_authentication_symbian_c(): this = 0x%08x\n"),
+		this));
+    }
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_am_wlan_authentication_symbian_c::wapi_am_wlan_authentication_symbian_c(
+	abs_eap_am_tools_c * const tools,
+	const bool is_client_when_true,
+	const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference)
+: CActive(CActive::EPriorityStandard)
+, m_am_partner(0)
+, m_am_tools(tools)
+, m_fileconfig(0)
+, m_SSID(tools)
+, m_wlan_database_reference(wlan_database_reference)
+, m_receive_network_id(tools)
+, m_selected_eapol_key_authentication_type(eapol_key_authentication_type_none)
+, m_is_client(is_client_when_true)
+, m_is_valid(false)
+, m_wapi_preshared_key(tools)
+, m_wapi_psk(tools)
+, iIapIndex(0)
+    {
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	m_is_valid = true;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+    }
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT bool wapi_am_wlan_authentication_symbian_c::get_is_valid()
+    {
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return m_is_valid;
+    }
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::reset_wapi_configuration()
+	{
+	
+	return eap_status_ok;
+	}
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::configure()
+    {
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::configure(): %s, this = 0x%08x => 0x%08x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+#if defined(USE_EAP_FILECONFIG)
+	{
+		eap_am_file_input_symbian_c * const fileio = new eap_am_file_input_symbian_c(m_am_tools);
+
+		eap_automatic_variable_c<eap_am_file_input_symbian_c> automatic_fileio(m_am_tools, fileio);
+
+		if (fileio != 0
+			&& fileio->get_is_valid() == true)
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("Initialize file configuration.\n")));
+
+			eap_variable_data_c file_name_c_data(m_am_tools);
+
+			eap_status_e status(eap_status_process_general_error);
+
+			{
+				#if defined(EAPOL_SYMBIAN_VERSION_7_0_s)
+					eap_const_string const FILECONFIG_FILENAME_C
+						= "c:\\system\\data\\wapi.conf";
+				#else
+					eap_const_string const FILECONFIG_FILENAME_C
+						= "c:\\private\\101F8EC5\\wapi.conf";
+				#endif
+
+				status = file_name_c_data.set_copy_of_buffer(
+					FILECONFIG_FILENAME_C,
+					m_am_tools->strlen(FILECONFIG_FILENAME_C));
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = file_name_c_data.add_end_null();
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+
+			eap_variable_data_c file_name_z_data(m_am_tools);
+
+			{
+				#if defined(EAPOL_SYMBIAN_VERSION_7_0_s)
+					eap_const_string const FILECONFIG_FILENAME_Z
+						= "z:\\system\\data\\wapi.conf";
+				#else
+					eap_const_string const FILECONFIG_FILENAME_Z
+						= "z:\\private\\101F8EC5\\wapi.conf";
+				#endif
+
+				status = file_name_z_data.set_copy_of_buffer(
+					FILECONFIG_FILENAME_Z,
+					m_am_tools->strlen(FILECONFIG_FILENAME_Z));
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+
+				status = file_name_z_data.add_end_null();
+				if (status != eap_status_ok)
+				{
+					EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+					return EAP_STATUS_RETURN(m_am_tools, status);
+				}
+			}
+
+
+
+			if (status == eap_status_ok)
+			{
+				// First try open from C: disk.
+				status = fileio->file_open(
+					&file_name_c_data,
+					eap_file_io_direction_read);
+				if (status == eap_status_ok)
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools,
+						TRACE_FLAGS_DEFAULT,
+						(EAPL("Opens configure file %s\n"),
+						file_name_c_data.get_data(file_name_c_data.get_data_length())));
+				}
+				else if (status != eap_status_ok)
+				{
+					// Second try open from Z: disk.
+					status = fileio->file_open(
+						&file_name_z_data,
+						eap_file_io_direction_read);
+					if (status == eap_status_ok)
+					{
+						EAP_TRACE_DEBUG(
+							m_am_tools,
+							TRACE_FLAGS_DEFAULT,
+							(EAPL("Opens configure file %s\n"),
+							 file_name_z_data.get_data(file_name_z_data.get_data_length())));
+					}
+				}
+
+				if (status == eap_status_ok)
+				{
+					// Some of the files were opened.
+
+					m_fileconfig = new eap_file_config_c(m_am_tools);
+					if (m_fileconfig != 0
+						&& m_fileconfig->get_is_valid() == true)
+					{
+						status = m_fileconfig->configure(fileio);
+						if (status != eap_status_ok)
+						{
+							EAP_TRACE_DEBUG(
+								m_am_tools,
+								TRACE_FLAGS_DEFAULT,
+								(EAPL("ERROR: Configure read from %s failed.\n"),
+								file_name_c_data.get_data(file_name_c_data.get_data_length())));
+						}
+						else
+						{
+							EAP_TRACE_DEBUG(
+								m_am_tools,
+								TRACE_FLAGS_DEFAULT,
+								(EAPL("Configure read from %s\n"),
+								file_name_c_data.get_data(file_name_c_data.get_data_length())));
+						}
+					}
+					else
+					{
+						// No file configuration.
+						delete m_fileconfig;
+						m_fileconfig = 0;
+
+						EAP_TRACE_DEBUG(
+							m_am_tools,
+							TRACE_FLAGS_DEFAULT,
+							(EAPL("ERROR: Cannot create configure object for file %s\n"),
+							file_name_c_data.get_data(file_name_c_data.get_data_length())));
+					}
+				}
+				else
+				{
+					EAP_TRACE_DEBUG(
+						m_am_tools,
+						TRACE_FLAGS_DEFAULT,
+						(EAPL("ERROR: Cannot open configure file neither %s nor %s\n"),
+						file_name_c_data.get_data(file_name_c_data.get_data_length()),
+						file_name_z_data.get_data(file_name_z_data.get_data_length())));
+				}
+			}
+		}
+		else
+		{
+			EAP_TRACE_DEBUG(
+				m_am_tools,
+				TRACE_FLAGS_DEFAULT,
+				(EAPL("Skips file configuration.\n")));
+		}
+	}
+
+#endif //#if defined(USE_EAP_FILECONFIG)
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+#if defined(USE_EAP_FILE_TRACE)
+	{
+		eap_variable_data_c trace_output_file(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAP_TRACE_output_file_name.get_field(),
+			&trace_output_file);
+		if (status == eap_status_ok
+			&& trace_output_file.get_is_valid_data() == true)
+		    {
+			status = m_am_tools->set_trace_file_name(&trace_output_file);
+			if (status == eap_status_ok)
+			    {
+				m_am_tools->set_trace_mask(
+					eap_am_tools_c::eap_trace_mask_debug
+					| eap_am_tools_c::eap_trace_mask_always
+					| eap_am_tools_c::eap_trace_mask_error
+					| eap_am_tools_c::eap_trace_mask_message_data);
+			    }
+            }
+	}
+#endif //#if defined(USE_EAP_FILE_TRACE)
+
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	{
+		eap_variable_data_c EAP_TRACE_enable_timer_queue_traces(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAP_TRACE_enable_timer_queue_traces.get_field(),
+			&EAP_TRACE_enable_timer_queue_traces);
+		if (status == eap_status_ok
+			&& EAP_TRACE_enable_timer_queue_traces.get_is_valid_data() == true)
+		    {
+			u32_t *enable_timer_queue_traces = reinterpret_cast<u32_t *>(
+				EAP_TRACE_enable_timer_queue_traces.get_data(sizeof(u32_t)));
+			if (enable_timer_queue_traces != 0
+				&& *enable_timer_queue_traces != 0)
+			    {
+				m_am_tools->set_trace_mask(
+					m_am_tools->get_trace_mask()
+					| eap_am_tools_c::eap_trace_mask_timer_queue
+					);
+			    }
+		    }
+	}
+
+	{
+		eap_variable_data_c EAP_TRACE_enable_function_traces(m_am_tools);
+
+		eap_status_e status = read_configure(
+			cf_str_EAP_TRACE_enable_function_traces.get_field(),
+			&EAP_TRACE_enable_function_traces);
+		if (status == eap_status_ok
+			&& EAP_TRACE_enable_function_traces.get_is_valid_data() == true)
+		{
+			u32_t *enable_function_traces = reinterpret_cast<u32_t *>(
+				EAP_TRACE_enable_function_traces.get_data(sizeof(u32_t)));
+			if (enable_function_traces != 0
+				&& *enable_function_traces != 0)
+			{
+				m_am_tools->set_trace_mask(
+					m_am_tools->get_trace_mask()
+					| eap_am_tools_c::eap_trace_mask_functions
+					);
+			}
+		}
+	}
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+    }
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::shutdown()
+    {
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_ALWAYS(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::shutdown(): %s, this = 0x%08x => 0x%08x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	delete m_fileconfig;
+    m_fileconfig = 0;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+    }
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::set_am_partner(
+	abs_wapi_am_wlan_authentication_c * am_partner
+	)
+    {
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_simulator_c::set_am_partner(): %s, this = 0x%08x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 this));
+
+	m_am_partner = am_partner;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+    }
+
+//--------------------------------------------------
+//--------------------------------------------------
+
+void wapi_am_wlan_authentication_symbian_c::send_error_notification(const eap_status_e error)
+    {
+	EAP_TRACE_DEBUG(m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::send_error_notification, error=%d\n"),
+		error));	
+
+   eap_general_state_variable_e general_state_variable(eap_general_state_authentication_error);
+    
+    if (error == eap_status_user_cancel_authentication)
+        {
+        general_state_variable = eap_general_state_authentication_cancelled;
+        }
+
+    // Here we swap the addresses.
+	eap_am_network_id_c send_network_id(m_am_tools,
+		m_receive_network_id.get_destination_id(),
+		m_receive_network_id.get_source_id(),
+		m_receive_network_id.get_type());
+
+	// Notifies the lower level of an authentication error.
+    eap_state_notification_c notification(
+        m_am_tools,
+        &send_network_id,
+        m_is_client,
+        eap_state_notification_eap,
+        eap_protocol_layer_general,
+        eap_type_none,
+        eap_state_none,
+        general_state_variable,
+        0,
+        false);
+
+    notification.set_authentication_error(error);
+
+    m_am_partner->state_notification(&notification);
+
+
+    }
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::set_wlan_parameters(
+	const eap_variable_data_c * const SSID,
+	const bool WPA_override_enabled,
+	const eap_variable_data_c * const wapi_preshared_key,
+	const eapol_key_authentication_type_e selected_eapol_key_authentication_type)
+    {
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::set_wlan_parameters(): %s, this = 0x%08x => 0x%08x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	m_selected_eapol_key_authentication_type = selected_eapol_key_authentication_type;
+
+	eap_status_e status = m_SSID.set_copy_of_buffer(SSID);
+	if (status != eap_status_ok)
+	    {
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	   }
+
+	status = m_wapi_preshared_key.set_copy_of_buffer(&m_wapi_psk);
+	if (status != eap_status_ok)
+	    {
+		send_error_notification(eap_status_key_error);
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	    }
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+    }
+
+//--------------------------------------------------
+
+//
+void wapi_am_wlan_authentication_symbian_c::state_notification(
+	const abs_eap_state_notification_c * const state)
+    {
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_UNREFERENCED_PARAMETER(state);
+	
+	// nothing to show to user, so do nothing
+	
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+    }
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::association(
+	const eap_am_network_id_c * const receive_network_id)
+    {
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::association(): %s, this = 0x%08x => 0x%08x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	eap_status_e status = m_receive_network_id.set_copy_of_network_id(receive_network_id);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+    }
+
+//--------------------------------------------------
+
+//
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::disassociation(
+	const eap_am_network_id_c * const /* receive_network_id */ ///< source includes remote address, destination includes local address.
+	)
+    {
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::disassociation(): %s, this = 0x%08x => 0x%08x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+    }
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::get_wlan_configuration(
+	eap_variable_data_c * const wapi_psk)
+    {
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	eap_status_e status = eap_status_ok;
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::get_wlan_configuration(): %s, this = 0x%08x => 0x%08x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+
+	TRAPD(err, status = GetWlanConfigurationL(wapi_psk ));
+	if (err)
+	    {
+	    EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	    return m_am_tools->convert_am_error_to_eapol_error(err);
+	    }
+	  
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return status;
+    }
+
+eap_status_e wapi_am_wlan_authentication_symbian_c::GetWlanConfigurationL(eap_variable_data_c * const wapi_psk )
+    {
+
+    EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+    
+    TIndexType index_type(ELan);
+    TUint index(0UL);
+
+    eap_status_e status = read_database_reference_values(
+        &index_type,
+        &index);
+    if (status != eap_status_ok)
+        {
+        EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+        User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)));
+        }
+
+    if (index_type == ELan)
+        {
+        EAP_TRACE_DEBUG(
+            m_am_tools,
+            TRACE_FLAGS_DEFAULT,
+            (EAPL("Beginning to read IAP settings - Type: %d, Index: %d.\n"), index_type, index));
+        
+        iIapIndex = index;
+        
+        CWLanSettings* wlan_settings = new(ELeave) CWLanSettings;
+        CleanupStack::PushL(wlan_settings);
+        SWLANSettings wlanSettings;
+        if (wlan_settings->Connect() != KErrNone)
+            {
+            // Could not connect to CommDB          
+            CleanupStack::PopAndDestroy(wlan_settings);
+            User::Leave(KErrCouldNotConnect);
+            }
+
+        EAP_TRACE_DEBUG(
+                m_am_tools,
+                TRACE_FLAGS_DEFAULT, (EAPL("Connected to CommDbIf.\n")));
+
+        if (wlan_settings->GetWlanSettingsForService(index, wlanSettings) != KErrNone)
+            {
+            wlan_settings->Disconnect();
+            CleanupStack::PopAndDestroy(wlan_settings);
+            User::Leave(KErrUnknown);
+            }
+
+        status = m_wapi_preshared_key.set_copy_of_buffer(
+                wlanSettings.WPAPreSharedKey.Ptr(),
+                wlanSettings.WPAPreSharedKey.Size());
+        if (status != eap_status_ok)
+            {
+            send_error_notification(eap_status_key_error);
+            wlan_settings->Disconnect();
+            CleanupStack::PopAndDestroy(wlan_settings);
+            EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+            User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)));
+           }
+
+       // Here we copy the SSID read from IAP.
+       TBuf8<32> tmp;
+       tmp.Copy(wlanSettings.SSID);
+       status = m_SSID.set_copy_of_buffer(tmp.Ptr(), tmp.Size());
+        if (status != eap_status_ok)
+           {
+           wlan_settings->Disconnect();
+           CleanupStack::PopAndDestroy(wlan_settings);
+           EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+           User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)));
+           }
+ 
+        EAP_TRACE_DATA_DEBUG(
+               m_am_tools,
+               TRACE_FLAGS_DEFAULT,
+               (EAPL("m_wapi_preshared_key"),
+                       m_wapi_preshared_key.get_data(),
+                       m_wapi_preshared_key.get_data_length()));
+
+        TInt aPskType = wlanSettings.PresharedKeyFormat;
+ 
+        if (aPskType == EWlanPresharedKeyFormatHex)
+            {
+            EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("PSK HEX\n")));
+    
+            m_wapi_psk.reset();
+            wapi_psk->reset();
+    
+            u32_t target_length(m_wapi_preshared_key.get_data_length() / 2);
+                 
+            status = m_wapi_psk.set_buffer_length(target_length);
+        
+            if (status != eap_status_ok)
+                {
+                EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("set_buffer_length NOT OK \n")));
+                send_error_notification(eap_status_key_error);
+                wlan_settings->Disconnect();                            
+                CleanupStack::PopAndDestroy(wlan_settings); 
+                EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+                return eap_status_key_error;
+                }
+            
+            status = m_wapi_psk.set_data_length(target_length);
+            if (status != eap_status_ok)
+                {
+                EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("set_data_length NOT OK \n")));
+                send_error_notification(eap_status_key_error);
+                wlan_settings->Disconnect();                            
+                CleanupStack::PopAndDestroy(wlan_settings); 
+                EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+                return eap_status_key_error;
+                }
+    
+            status = m_am_tools->convert_hex_ascii_to_bytes(
+                    m_wapi_preshared_key.get_data(m_wapi_preshared_key.get_data_length()),
+                    m_wapi_preshared_key.get_data_length(),
+                    m_wapi_psk.get_data(target_length),
+                    &target_length);
+            
+            if (status != eap_status_ok
+                    || target_length != (m_wapi_preshared_key.get_data_length()/2))
+                    {
+                    EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("convert_hex_ascii_to_bytes NOT OK \n")));
+                    send_error_notification(eap_status_key_error);
+                    wlan_settings->Disconnect();                            
+                    EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+                    CleanupStack::PopAndDestroy(wlan_settings);
+                   return eap_status_key_error;
+                    }
+                
+            status = wapi_psk->set_copy_of_buffer(&m_wapi_psk);
+            if (status != eap_status_ok)
+                {
+                EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("set_copy_of_buffer NOT OK \n")));
+                send_error_notification(eap_status_key_error);
+                wlan_settings->Disconnect();                            
+                EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+                CleanupStack::PopAndDestroy(wlan_settings); 
+                return eap_status_key_error;
+                }
+            }
+        else
+            {
+            EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("PSK ASCII\n")));
+            m_wapi_psk.reset();
+            wapi_psk->reset();
+
+            status = m_wapi_psk.set_copy_of_buffer(&m_wapi_preshared_key);
+            if (status != eap_status_ok)
+                {
+                EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("set_copy_of_buffer NOT OK \n")));
+                send_error_notification(eap_status_key_error);
+                wlan_settings->Disconnect();                            
+                EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+                CleanupStack::PopAndDestroy(wlan_settings); 
+                return eap_status_key_error;
+                }
+            
+            status = wapi_psk->set_copy_of_buffer(&m_wapi_psk); 
+            if (status != eap_status_ok)
+                {
+                EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("set_copy_of_buffer NOT OK \n")));
+                send_error_notification(eap_status_key_error);
+                wlan_settings->Disconnect();                            
+                EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+                CleanupStack::PopAndDestroy(wlan_settings); 
+               return eap_status_key_error;
+                }
+            }
+    
+        EAP_TRACE_DATA_DEBUG(
+                m_am_tools,
+                TRACE_FLAGS_DEFAULT,
+                (EAPL("new WPA-PSK SSID"),
+                        m_SSID.get_data(),
+                        m_SSID.get_data_length()));
+        
+        EAP_TRACE_DATA_DEBUG(
+                m_am_tools,
+                TRACE_FLAGS_DEFAULT,
+                (EAPL("new WPA-PSK preshared key"),
+                m_wapi_preshared_key.get_data(),
+                m_wapi_preshared_key.get_data_length()));
+            
+        EAP_TRACE_DATA_DEBUG(
+                m_am_tools,
+                TRACE_FLAGS_DEFAULT,
+                (EAPL("new WPA-PSK hash"),
+                m_wapi_psk.get_data(),
+                m_wapi_psk.get_data_length()));
+    
+        CleanupStack::PopAndDestroy(wlan_settings);
+        }
+    
+    EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+    return status;
+
+    }
+                                                         
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::authentication_finished(
+	const bool when_true_successfull,
+	const eapol_key_authentication_type_e authentication_type)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::authentication_finished(): %s, this = 0x%08x => 0x%08x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+eap_status_e wapi_am_wlan_authentication_symbian_c::read_database_reference_values(
+	TIndexType * const type,
+	TUint * const index)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::read_database_reference_values(): %s, this = 0x%08x => 0x%08x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+
+	eap_variable_data_c database_reference(m_am_tools);
+
+	eap_status_e status = m_wlan_database_reference->get_wlan_database_reference_values(&database_reference);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, status);
+	}
+
+	const eapol_wlan_database_reference_values_s * const database_reference_values
+		= reinterpret_cast<eapol_wlan_database_reference_values_s *>(
+		database_reference.get_data(sizeof(eapol_wlan_database_reference_values_s)));
+	if (database_reference_values == 0)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error);
+	}
+
+	*type = static_cast<TIndexType>(database_reference_values->m_database_index_type);
+	*index = database_reference_values->m_database_index;
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_am_wlan_authentication_symbian_c::read_database_reference_values(): Type=%d, Index=%d.\n"),
+		 *type,
+		 *index));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, eap_status_ok);
+}
+
+//--------------------------------------------------
+
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::read_configure(
+	const eap_configuration_field_c * const field,
+	eap_variable_data_c * const data)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	EAP_ASSERT_ALWAYS(data != NULL);
+	
+	EAP_TRACE_DEBUG(
+		m_am_tools, 
+		TRACE_FLAGS_DEFAULT, 
+		(EAPL("wapi_am_wlan_authentication_symbian_c::read_configure(): %s, this = 0x%08x => 0x%08x\n"),
+		 (m_is_client == true) ? "client": "server",
+		 this,
+		 dynamic_cast<abs_eap_base_timer_c *>(this)));
+	
+	eap_status_e status(eap_status_ok);
+
+	eap_variable_data_c wanted_field(m_am_tools);
+	eap_variable_data_c type_field(m_am_tools);
+	
+	status = wanted_field.set_buffer(
+		field->get_field(),
+		field->get_field_length(),
+		false,
+		false);
+	if (status != eap_status_ok)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return status;
+	}
+	
+	TInt err = KErrNone;
+	HBufC8* asciibuf = NULL;
+	TRAP( err, asciibuf = HBufC8::NewL(128));
+    if (err != KErrNone) 
+        {
+        EAP_TRACE_DEBUG(
+            m_am_tools,
+            TRACE_FLAGS_DEFAULT,
+            (EAPL("wapi_am_wlan_authentication_symbian_c::read_configure HBufC8::NewL LEAVE(): Type=%d.\n"),
+                    err));
+            status = m_am_tools->convert_am_error_to_eapol_error(err);
+            EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+            return status;
+        }
+   
+    if((cf_str_WAPI_database_reference_index.get_field()->compare((m_am_tools), field)) == true)
+        {
+        if (iIapIndex == 0)
+            {
+            TIndexType index_type(ELan);
+
+            eap_status_e status = read_database_reference_values(
+                &index_type,
+                &iIapIndex);
+            if (status != eap_status_ok)
+                {
+                EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+                User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)));
+                }
+            else
+                {
+                status = data->set_copy_of_buffer(&iIapIndex, sizeof(iIapIndex));
+                if (status != eap_status_ok)
+                    {
+                    EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+                    User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)));
+                    }
+                
+                 }
+            }
+        else
+            {
+            status = data->set_copy_of_buffer(&iIapIndex, sizeof(iIapIndex));
+            if (status != eap_status_ok)
+                {
+                EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+                User::Leave(m_am_tools->convert_eapol_error_to_am_error(EAP_STATUS_RETURN(m_am_tools, status)));
+                }
+            }
+        EAP_TRACE_DEBUG(
+              m_am_tools,
+              TRACE_FLAGS_DEFAULT,
+              (EAPL("wapi_am_wlan_authentication_symbian_c::read_configure(): index = %d\n"), iIapIndex));
+ 
+        }
+
+    TPtr8 asciiString = asciibuf->Des();
+    asciiString.Copy(reinterpret_cast<const unsigned char *>(field));
+
+    eap_variable_data_c aConfigField(m_am_tools);
+    aConfigField.set_copy_of_buffer(asciiString.Ptr(), asciiString.Size());
+
+    if ((cf_str_WAPI_CORE_PSK.get_field()->compare((m_am_tools), field)) == true)
+        {
+        TRAP( err, ReadConfigureL(
+            field->get_field(),
+            field,
+            field->get_field_length(),
+            data) );
+        }
+    delete asciibuf; 
+   
+	if (err != KErrNone) 
+        {
+        EAP_TRACE_DEBUG(
+            m_am_tools,
+            TRACE_FLAGS_DEFAULT,
+            (EAPL("wapi_am_wlan_authentication_symbian_c::read_configure ReadConfigureL LEAVE(): Type=%d.\n"),
+                    err));
+            status = m_am_tools->convert_am_error_to_eapol_error(err);
+
+
+#if defined(USE_EAP_FILECONFIG)
+		if (m_fileconfig != 0
+			&& m_fileconfig->get_is_valid() == true)
+		    {
+			status = m_fileconfig->read_configure(
+				field,
+				data);
+		    }
+#endif //#if defined(USE_EAP_FILECONFIG)
+        }
+	m_am_tools->trace_configuration(
+		status,
+		field,
+		data);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+void wapi_am_wlan_authentication_symbian_c::ReadConfigureL(
+	eap_config_string fieldx,
+	const eap_configuration_field_c * const field,
+	const u32_t /*field_length*/,
+	eap_variable_data_c * const data)
+{	
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+	
+	// Create a buffer for the ascii strings - initialised with the argument
+	HBufC8* asciibuf = HBufC8::NewLC(128);
+	TPtr8 asciiString = asciibuf->Des();
+	asciiString.Copy(reinterpret_cast<const unsigned char *>(field));
+		
+	// Buffer for unicode parameter
+	HBufC* unicodebuf = HBufC::NewLC(128);
+	TPtr unicodeString = unicodebuf->Des();
+	
+	// Convert to unicode 
+	unicodeString.Copy(asciiString);
+
+    eap_variable_data_c aConfigField(m_am_tools);
+
+    if ((cf_str_WAPI_CORE_PSK.get_field()->compare((m_am_tools), field)) == true )
+        {
+        if(m_wapi_psk.get_data_length()>0)
+            {
+            data->set_copy_of_buffer(&m_wapi_psk);
+            }
+        else
+            {
+            GetWlanConfigurationL(&aConfigField);
+            data->set_copy_of_buffer(&aConfigField);
+            }
+        CleanupStack::PopAndDestroy(2); // 2 buffers
+        return;
+        }
+
+	CleanupStack::PopAndDestroy(2); // 2 buffers
+
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::write_configure(
+	const eap_configuration_field_c * const /* field */,
+	eap_variable_data_c * const /* data */)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = eap_status_illegal_configure_field;
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::set_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id, 
+	void * const p_data,
+	const u32_t p_time_ms)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = m_am_tools->am_set_timer(
+		p_initializer, 
+		p_id, 
+		p_data,
+		p_time_ms);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::cancel_timer(
+	abs_eap_base_timer_c * const p_initializer, 
+	const u32_t p_id)
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = m_am_tools->am_cancel_timer(
+		p_initializer, 
+		p_id);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT eap_status_e wapi_am_wlan_authentication_symbian_c::cancel_all_timers()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	const eap_status_e status = m_am_tools->am_cancel_all_timers();
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+	return EAP_STATUS_RETURN(m_am_tools, status);
+}
+
+//--------------------------------------------------
+
+void wapi_am_wlan_authentication_symbian_c::RunL()
+{
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);	
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_am_wlan_authentication_symbian_c::RunL(): iStatus.Int() = %d\n"),
+		iStatus.Int()));
+
+	if (iStatus.Int() != KErrNone)
+	{
+		EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+		return;
+	}
+
+	// Authentication cancelled.
+	EAP_TRACE_ALWAYS(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+		(EAPL("Authentication cancelled.\n")));
+
+    eap_status_e status = m_am_partner->disassociation(
+        &m_receive_network_id);
+
+    if (status != eap_status_ok)
+    {
+        EAP_TRACE_DEBUG(
+            m_am_tools,
+            TRACE_FLAGS_DEFAULT,
+            (EAPL("Disassociation failed in RunL().\n")));
+        EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);
+        return;
+    }
+
+    EAP_TRACE_ALWAYS(
+		m_am_tools,
+		TRACE_FLAGS_ALWAYS|TRACE_FLAGS_DEFAULT,
+		(EAPL("Indication sent to WLM: EFailedCompletely.\n")));
+
+	   m_am_partner->wapi_indication(
+	        &m_receive_network_id,
+	        eapol_wlan_authentication_state_failed_completely);
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+}
+
+//--------------------------------------------------
+
+void wapi_am_wlan_authentication_symbian_c::DoCancel()
+{	
+	EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT);
+
+	EAP_TRACE_DEBUG(
+		m_am_tools,
+		TRACE_FLAGS_DEFAULT,
+		(EAPL("wapi_am_wlan_authentication_symbian_c::DoCancel()\n")));
+
+	EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT);	
+}
+
+//--------------------------------------------------
+
+EAP_FUNC_EXPORT wapi_am_wlan_authentication_c * wapi_am_wlan_authentication_c::new_wapi_am_wlan_authentication(
+	abs_eap_am_tools_c * const tools,
+	const bool is_client_when_true,
+	const abs_eapol_wlan_database_reference_if_c * const wlan_database_reference)
+{
+	EAP_TRACE_BEGIN(tools, TRACE_FLAGS_DEFAULT);
+
+	wapi_am_wlan_authentication_c * const wauth = new wapi_am_wlan_authentication_symbian_c(
+		tools,
+		is_client_when_true,
+		wlan_database_reference);
+
+	EAP_TRACE_END(tools, TRACE_FLAGS_DEFAULT);
+	return wauth;
+}
+
+
+//--------------------------------------------------
+// End.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/wlanwapiif/data/2001959f.rss	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,55 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/wlanwapiif/data/2001959f.rss
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : Resource definitions for project WAPI
+*  Version     : %version: 6 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1
+*/
+
+#include <registryinfo.rh>
+
+// ---------------------------------------------------------
+//   
+//    
+//    ECOM resource definitions for WlanWAPIIf plugin
+//
+// ---------------------------------------------------------
+//
+RESOURCE REGISTRY_INFO theInfo
+	{
+	// UID for the DLL
+	dll_uid = 0x2001959f;
+				
+	// Declare array of interface info
+	interfaces = 
+		{
+		INTERFACE_INFO
+			{
+			// UID of interface that is implemented
+			interface_uid = 0x200195a0;
+			implementations = 
+				{
+				// Info for WlanEapolClient
+				IMPLEMENTATION_INFO
+					{
+					implementation_uid = 0x200195a1;
+					version_no         = 1;
+					display_name       = "WlanWAPIIf";
+					default_data       = "";
+					opaque_data        = "";
+					}
+				};
+			}
+		};
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/wlanwapiif/inc/wlan_wapi_if_implementation.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,132 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/wlanwapiif/inc/wlan_wapi_if_implementation.h
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 5 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.2
+*/
+
+#ifndef _WLAN_WAPI_INTERFACE_IMPLEMENTATION_H_
+#define _WLAN_WAPI_INTERFACE_IMPLEMENTATION_H_
+
+// INCLUDES
+#include <e32std.h>
+#include <wlaneapolclient.h>
+
+#include "abs_wapi_message_wlan_authentication.h"
+
+/**
+ * Implementation for MWlanEapolInterface interface.
+ *
+ * @lib wlanwapiif.dll
+ */
+class CWlanWAPIInterfaceImplementation
+: public CWlanEapolClient
+, public abs_wapi_message_wlan_authentication_c
+{
+
+public:
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Functions from CWlanEapolClient.
+
+	/**
+	 * Static constructor.
+	 * @param aPartner Pointer to callback instance.
+	 * @return Pointer to the constructed instance.
+	 */
+	static CWlanWAPIInterfaceImplementation* NewL( MWlanEapolCallbackInterface * aPartner );
+
+	/**
+	 * Destructor.
+	 */
+	virtual ~CWlanWAPIInterfaceImplementation();
+
+	/**
+	 * Configure plugin implementation.
+	 *
+	 * @since S60 v3.2
+	 * @param aHeaderOffset Offset of EAP-header in packet_send.
+	 * @param aMTU Maximum transfer unit (MTU).
+	 * @param aTrailerLength Length of trailer needed by lower levels..
+	 * @return Return value is specified in interface specification.
+	 */
+	virtual TInt Configure(
+		const TInt aHeaderOffset,
+		const TInt aMTU,
+		const TInt aTrailerLength);
+
+	/**
+	 * Shutdown plugin implementation.
+	 *
+	 * @since S60 v3.2
+	 * @return Return value is specified in interface specification.
+	 */        
+	virtual TInt Shutdown();
+
+	/**
+	 * Send data to EAPOL.
+	 *
+	 * @since S60 v3.2
+	 * @param aData Pointer to the data to be sent.
+	 * @param aLength Length of the data to be sent.
+	 * @return Return value is specified in interface specification.
+	 */
+	virtual TInt ProcessData(
+		const void * const aData, 
+		const TInt aLength );
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+	// Functions from abs_eapol_message_wlan_authentication_c.
+
+	/// Function sends the data message to lower layer.
+	/// Data is formatted to Attribute-Value Pairs.
+	/// Look at eap_tlv_header_c and eap_tlv_message_data_c.
+	virtual wlan_eap_if_send_status_e send_data(const void * const data, const u32_t length);
+
+
+private:
+
+    /**
+     * C++ default constructor.
+     */
+    CWlanWAPIInterfaceImplementation();
+
+    /**
+     * Symbian 2nd phase constructor.
+     */
+    void ConstructL(MWlanEapolCallbackInterface * aPartner);
+
+	/**
+	 * The get_is_valid() function returns the status of the CWlanWAPIInterfaceImplementation object.
+	 * @return True indicates the object is initialized.
+	 */
+	bool get_is_valid();
+
+	// - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+	abs_eap_am_tools_c * m_am_tools;
+
+	MWlanEapolCallbackInterface * m_partner;
+
+	wapi_message_wlan_authentication_c * m_wauth;
+
+	bool m_is_valid;
+
+};
+
+
+#endif // _WLAN_EAPOL_INTERFACE_IMPLEMENTATION_H_
+
+// End of file.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eapol/eapol_framework/wapi_symbian/wlanwapiif/src/wlan_wapi_if_implementation.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,229 @@
+/*
+* ============================================================================
+*  Name        : ./accesssec/eapol/eapol_framework/wapi_symbian/wlanwapiif/src/wlan_wapi_if_implementation.cpp
+*  Part of     : WAPI / WAPI       *** Info from the SWAD
+*  Description : WAPI authentication
+*  Version     : %version: 5.1.2 % << Don't touch! Updated by Synergy at check-out.
+*
+*  Copyright © 2001-2009 Nokia.  All rights reserved.
+*  This material, including documentation and any related computer
+*  programs, is protected by copyright controlled by Nokia.  All
+*  rights are reserved.  Copying, including reproducing, storing,
+*  adapting or translating, any or all of this material requires the
+*  prior written consent of Nokia.  This material also contains
+*  confidential information which may not be disclosed to others
+*  without the prior written consent of Nokia.
+* ============================================================================
+* Template version: 4.1.1
+*/
+
+// INCLUDES
+#include <e32std.h>
+#include <implementationproxy.h>
+
+#include "abs_eap_am_tools.h"
+
+#include "wapi_message_wlan_authentication.h"
+#include "wlan_wapi_if_implementation.h"
+#include "wlan_eap_if_send_status.h"
+
+//-----------------------------------------------------------------------------------------
+
+/**
+ * Pairs ECom implementation UIDs with a pointer to the instantiation 
+ * method for that implementation. Required for all ECom implementation
+ * collections.
+ */
+const TImplementationProxy ImplementationTable[] =
+{
+    {{KCWlanWapiClientUid}, reinterpret_cast<TProxyNewLPtr>(CWlanWAPIInterfaceImplementation::NewL)} 
+};
+
+//-----------------------------------------------------------------------------------------
+
+/**
+ * Static constructor.
+ * @param aPartner Pointer to callback instance.
+ * @return Pointer to the constructed instance.
+ */
+CWlanWAPIInterfaceImplementation* CWlanWAPIInterfaceImplementation::NewL(MWlanEapolCallbackInterface * aPartner)
+{
+	CWlanWAPIInterfaceImplementation* self = new (ELeave) CWlanWAPIInterfaceImplementation;
+
+	CleanupStack::PushL(self);
+
+	self->ConstructL(aPartner);
+
+	if (self->get_is_valid() != true)
+	{
+		User::Leave(KErrGeneral);
+	}
+
+	CleanupStack::Pop(self);
+
+	return self;
+}
+
+//-----------------------------------------------------------------------------------------
+
+/**
+ * C++ default constructor.
+ */
+CWlanWAPIInterfaceImplementation::CWlanWAPIInterfaceImplementation()
+: m_am_tools(0)
+, m_partner(0)
+, m_wauth(0)
+, m_is_valid(true)
+{
+}
+
+//-----------------------------------------------------------------------------------------
+
+/**
+ * Destructor.
+ */
+CWlanWAPIInterfaceImplementation::~CWlanWAPIInterfaceImplementation()
+{
+	m_partner = 0;
+
+	delete m_wauth;
+	m_wauth = 0;
+
+  m_am_tools->am_cancel_all_timers();
+	abs_eap_am_tools_c::delete_abs_eap_am_tools_c(m_am_tools);
+	m_am_tools = 0;
+
+}
+
+//-----------------------------------------------------------------------------------------
+
+/**
+ * Configure plugin implementation.
+ *
+ * @since S60 v3.2
+ * @param aHeaderOffset Offset of EAP-header in packet_send.
+ * @param aMTU Maximum transfer unit (MTU).
+ * @param aTrailerLength Length of trailer needed by lower levels..
+ * @return Return value is specified in interface specification.
+ */
+TInt CWlanWAPIInterfaceImplementation::Configure(
+	const TInt aHeaderOffset,
+	const TInt aMTU,
+	const TInt aTrailerLength)
+{
+	m_am_tools = abs_eap_am_tools_c::new_abs_eap_am_tools_c();
+	
+	if (m_am_tools == 0)
+		{
+			return wlan_eap_if_send_status_conversion_c::convert(
+			EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error)); 			
+		}
+
+	// eapol_message_wlan_authentication_c object uses the tools object.
+	m_wauth = new wapi_message_wlan_authentication_c(
+		m_am_tools,
+		this);
+
+	if (m_wauth != 0
+		&& m_wauth->get_is_valid() == true)
+	{
+		eap_status_e status = m_wauth->configure(
+			aHeaderOffset,
+			aMTU,
+			aTrailerLength);
+		if (status != eap_status_ok)
+		{
+			return wlan_eap_if_send_status_conversion_c::convert(
+				EAP_STATUS_RETURN(m_am_tools, status));
+		}
+	}
+	else
+	{
+		return wlan_eap_if_send_status_conversion_c::convert(
+			EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error));
+	}
+
+	return wlan_eap_if_send_status_ok;
+}
+
+//-----------------------------------------------------------------------------------------
+
+/**
+ * Shutdown plugin implementation.
+ *
+ * @since S60 v3.2
+ * @return Return value is specified in interface specification.
+ */        
+TInt CWlanWAPIInterfaceImplementation::Shutdown()
+{
+	eap_status_e status = m_wauth->shutdown();
+
+	return wlan_eap_if_send_status_conversion_c::convert(
+			EAP_STATUS_RETURN(m_am_tools, status));
+}
+
+//-----------------------------------------------------------------------------------------
+
+/**
+ * Send data to EAPOL.
+ *
+ * @since S60 v3.2
+ * @param aData Pointer to the data to be sent.
+ * @param aLength Length of the data to be sent.
+ * @return Return value is specified in interface specification.
+ */
+TInt CWlanWAPIInterfaceImplementation::ProcessData(
+	const void * const aData, 
+	const TInt aLength )
+{
+	return m_wauth->process_data(aData, aLength);
+}
+
+//-----------------------------------------------------------------------------------------
+
+/**
+ * Symbian 2nd phase constructor.
+ */
+void CWlanWAPIInterfaceImplementation::ConstructL(MWlanEapolCallbackInterface * aPartner)
+{
+	m_partner = aPartner;
+}
+
+//-----------------------------------------------------------------------------------------
+
+bool CWlanWAPIInterfaceImplementation::get_is_valid()
+{
+	return m_is_valid;
+}
+
+//-----------------------------------------------------------------------------------------
+
+/// Function sends the data message to lower layer.
+/// Data is formatted to Attribute-Value Pairs.
+/// Look at eap_tlv_header_c and eap_tlv_message_data_c.
+wlan_eap_if_send_status_e CWlanWAPIInterfaceImplementation::send_data(const void * const data, const u32_t length)
+{
+	return static_cast<wlan_eap_if_send_status_e>(m_partner->SendData(
+        data, 
+        length));
+}
+
+//-----------------------------------------------------------------------------------------
+
+// ======== GLOBAL FUNCTIONS ========
+
+// ---------------------------------------------------------
+// Returns an instance of the proxy table.
+// Returns: KErrNone
+// ---------------------------------------------------------
+//
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
+    {
+    aTableCount = sizeof( ImplementationTable) / sizeof( TImplementationProxy );
+    return ImplementationTable;
+    }
+
+//-----------------------------------------------------------------------------------------
+
+// End of file.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/data/wapisecuritysettingsui.rss	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,342 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsui.rss
+*  Part of  : S60 WAPI Security Settings  UI
+*
+*  Description:
+*     This file contains all the resources for the WAPI Security Settings UI.
+*  Version: %version:  6.1.2 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+//  RESOURCE IDENTIFIER
+NAME    AWST // 4 letter ID
+
+//  INCLUDES
+#include <eikon.rh>
+#include <avkon.rsg>
+#include <avkon.rh>
+#include <avkon.loc>
+#include <avkon.hrh>
+#include <errorres.loc>
+
+#include "wapisecuritysettingsui.hrh"
+#include <wapisecuritysettingsui.loc>
+
+//  RESOURCE DEFINITIONS
+
+RESOURCE RSS_SIGNATURE { }
+
+RESOURCE TBUF { buf="WAPISecuritySettings"; }
+
+
+//----------------------------------------------------
+//
+//  r_wapi_security_settings_menubar
+//  Menubar    
+//
+//----------------------------------------------------
+//
+RESOURCE MENU_BAR r_wapi_security_settings_menubar
+    {
+    titles=
+        {
+        MENU_TITLE 
+            { 
+            menu_pane = r_wapi_security_settings_menu;
+            }
+        };
+    }
+
+
+//----------------------------------------------------
+//
+//  r_wapi_security_settings_menu
+//  The Options menu
+//
+//----------------------------------------------------
+//
+RESOURCE MENU_PANE r_wapi_security_settings_menu
+    {
+    items=
+        {
+        MENU_ITEM 
+            { 
+            command = EWapiSelCmdChange; 
+            txt = qtn_options_change;
+            flags = EEikMenuItemAction; 
+            },
+
+        MENU_ITEM 
+            { 
+            command = EWapiSelCmdReset;     
+            txt = qtn_wlan_options_reset_wapi_cert_store; 
+            },         
+           
+        MENU_ITEM 
+            { 
+            command = EAknCmdHelp; 
+            txt = qtn_options_help; 
+            },
+
+        MENU_ITEM 
+            { 
+            command = EAknCmdExit; 
+            txt = qtn_options_exit; 
+            }
+        };
+    }
+
+
+
+//----------------------------------------------------
+//
+//    r_wapisettings_pane_softkeys_options_back_edit
+//    WAPI Security Settings softkeys
+//
+//----------------------------------------------------
+//
+RESOURCE CBA r_wapisettings_pane_softkeys_options_back_edit
+    {
+    buttons =
+        {
+        CBA_BUTTON { id = EAknSoftkeyOptions; txt = text_softkey_option; },
+        CBA_BUTTON { id = EAknSoftkeyBack; txt = text_softkey_back; },
+        CBA_BUTTON { id = EWapiSelCmdChange; txt = qtn_msk_change; }
+        };
+    }
+
+
+
+//----------------------------------------------------
+//
+//  r_wapisettings_dialog
+//  WAPI Security Settings main dialog
+//
+//----------------------------------------------------
+//
+RESOURCE DIALOG r_wapisettings_dialog
+    {
+    flags = EEikDialogFlagWait | EEikDialogFlagNoDrag | 
+            EEikDialogFlagNoTitleBar | EEikDialogFlagFillAppClientRect |
+            EEikDialogFlagCbaButtons;
+
+    buttons = r_wapisettings_pane_softkeys_options_back_edit;
+
+    items =
+        {
+        DLG_LINE
+            {
+            type = EAknCtSettingListBox;
+            id = KWapiMainSettingsListboxId;
+            control = LISTBOX 
+                { 
+                flags = EAknListBoxSelectionList;
+                };
+            }
+        };
+    }
+
+
+//----------------------------------------------------
+//   
+//  r_setting_app_listbox
+//  Listbox for setting page
+//
+//----------------------------------------------------
+//
+RESOURCE LISTBOX r_setting_app_listbox
+    {
+    flags = EEikListBoxMultipleSelection;
+    }
+
+
+
+//----------------------------------------------------
+//
+//    r_wapisettings_pane_softkeys_ok_cancel_select
+//    WAPI Security Settings softkeys
+//
+//----------------------------------------------------
+//
+RESOURCE CBA r_wapisettings_pane_softkeys_ok_cancel_select
+    {
+    buttons =
+        {
+        CBA_BUTTON { id = EAknSoftkeyOk; txt = text_softkey_ok; },
+        CBA_BUTTON { id = EAknSoftkeyCancel; txt = text_softkey_cancel; },
+        CBA_BUTTON { id = EAknSoftkeyOk; txt = qtn_msk_select; }
+        };
+    }
+
+
+//----------------------------------------------------
+//   
+//  r_radio_button_setting_page
+//  Setting page with radio buttons
+//
+//----------------------------------------------------
+//
+RESOURCE AVKON_SETTING_PAGE r_radio_button_setting_page
+    {
+    number = EAknSettingPageNoOrdinalDisplayed;
+    softkey_resource = r_wapisettings_pane_softkeys_ok_cancel_select;
+    type =  EAknSetListBox;
+    editor_resource_id= r_setting_app_listbox;
+    }
+
+RESOURCE TBUF r_wapi_auth
+    { 
+    buf = qtn_wlan_sett_wapi_auth;
+    }
+
+RESOURCE TBUF r_wapi_auth_cert
+    { 
+    buf = qtn_wlan_sett_wapi_auth_cert;
+    }
+
+RESOURCE TBUF r_wapi_client_cert
+    { 
+    buf = qtn_wlan_sett_wapi_client_cert;
+    }
+
+RESOURCE TBUF r_wapi_root_cert
+    { 
+    buf = qtn_wlan_sett_wapi_root_cert;
+    }
+
+RESOURCE TBUF r_wapi_cert_not_defined
+    {
+    buf = qtn_wlan_sett_wapi_cert_not_defined;
+    }
+
+RESOURCE TBUF r_wapi_none
+    {
+    buf = qtn_wlan_sett_wapi_cert_none;
+    }
+
+RESOURCE TBUF r_wapi_done
+    {
+    buf = text_done; //from avkon.loc
+    }
+
+RESOURCE TBUF r_wapi_failure
+    {
+    buf = qtn_err_failure; //from errorres.loc
+    }
+
+RESOURCE TBUF r_wapi_preshared_key_format
+    { 
+    buf = qtn_wlan_sett_preshared_key_format;
+    }
+
+RESOURCE TBUF r_wapi_preshared_key_format_ascii
+    { 
+    buf = qtn_wlan_sett_preshared_key_format_ascii;
+    }
+
+RESOURCE TBUF r_wapi_preshared_key_format_hex
+    { 
+    buf = qtn_wlan_sett_preshared_key_format_hex;
+    }
+
+RESOURCE TBUF r_wapi_auth_psk
+    { 
+    buf = qtn_wlan_sett_wapi_auth_psk;
+    }
+
+//----------------------------------------------------
+//   
+//  r_psk_setting_page_key_data
+//  Setting page for entering PSK key data
+//
+//----------------------------------------------------
+//
+RESOURCE AVKON_SETTING_PAGE r_psk_setting_page_key_data
+    {
+    softkey_resource = R_AVKON_SOFTKEYS_OK_CANCEL__OK;
+    number= EAknSettingPageNoOrdinalDisplayed;
+    label= qtn_wlan_sett_preshared_key;
+    type = EEikCtEdwin;
+    editor_resource_id = r_setting_app_edwin_key_data;
+    }
+
+//----------------------------------------------------
+//   
+//  r_setting_app_edwin_key_data
+//  Window to enter key data
+//
+//----------------------------------------------------
+//
+RESOURCE EDWIN r_setting_app_edwin_key_data
+    {
+    avkon_flags = EAknEditorFlagNoT9;
+    allowed_input_modes = EAknEditorTextInputMode | 
+                          EAknEditorNumericInputMode | 
+                          EAknEditorHalfWidthTextInputMode;
+    default_case = EAknEditorLowerCase;
+    maxlength = KWapiMaxKeyLength;
+    lines = 8;
+    }
+
+RESOURCE TBUF r_wapi_preshared_key
+    { 
+    buf = qtn_wlan_sett_preshared_key;
+    }
+
+RESOURCE TBUF r_wapi_preshared_key_not_defined
+    { 
+    buf = qtn_wlan_sett_preshared_key_not_defined;
+    }
+
+RESOURCE TBUF r_wapi_info_preshared_key_illegal_chars
+    { 
+    buf = qtn_wlan_info_preshared_key_illegal_chars;
+    }
+
+RESOURCE TBUF r_wapi_quest_preshared_key_data_missing
+    {
+    buf = qtn_wlan_quest_preshared_key_data_missing;
+    }
+
+RESOURCE TBUF r_wapi_info_preshared_key_not_even
+    {
+    buf = qtn_wlan_info_psk_not_even;
+    }
+//----------------------------------------------------
+//   
+//    r_wapi_sec_sett_conf_query
+//    ConfirmationQuery dialog
+//
+//----------------------------------------------------
+//
+RESOURCE DIALOG r_wapi_sec_sett_conf_query
+    {
+    flags = EGeneralQueryFlags;
+    buttons = R_AVKON_SOFTKEYS_YES_NO__YES;
+    items =
+        {
+        DLG_LINE
+            {
+            type = EAknCtQuery;
+            id = EGeneralQuery;
+            control = AVKON_CONFIRMATION_QUERY
+                {
+                layout = EConfirmationQueryLayout;
+                };
+            }
+        };
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/group/bld.inf	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* ============================================================================
+*  Name     : bld.inf
+*  Part of  : S60 WAPI Security Settings UI
+*
+*  Description:
+*    This file provides the information required for building the
+*    whole of a wapisecuritysettingsui.
+*  Version: %version:  9 %
+*
+*  Copyright (C) 2008-2009 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+#include <platform_paths.hrh>
+
+PRJ_PLATFORMS
+DEFAULT
+
+//  Help exports
+#include "../help/group/bld.inf"
+
+PRJ_EXPORTS
+
+// export iby files
+../rom/wapisecuritysettingsui.iby		CORE_MW_LAYER_IBY_EXPORT_PATH(wapisecuritysettingsui.iby)
+../rom/wapisecuritysettingsuiresources.iby	LANGUAGE_MW_LAYER_IBY_EXPORT_PATH(wapisecuritysettingsuiresources.iby)
+
+// export localised loc file
+../loc/wapisecuritysettingsui.loc	MW_LAYER_LOC_EXPORT_PATH(wapisecuritysettingsui.loc)
+
+PRJ_MMPFILES
+./wapisecuritysettingsui.mmp
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/group/wapisecuritysettingsui.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,77 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsui.mmp
+*  Part of  : S60 WAPI Security Settings UI
+*
+*  Description:
+*     This is project specification file for the wapisecuritysettingsui.
+*  Version: %version:  7.1.3 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+#include <data_caging_paths.hrh>
+#include <platform_paths.hrh>
+
+
+TARGET      realwapisecuritysettingsui.dll
+TARGETTYPE  DLL
+
+CAPABILITY CAP_GENERAL_DLL
+VENDORID VID_DEFAULT
+
+
+START RESOURCE  ../data/wapisecuritysettingsui.rss
+HEADER
+TARGETPATH RESOURCE_FILES_DIR
+LANGUAGE_IDS
+END  // RESOURCE
+
+
+SOURCEPATH ../src
+
+SOURCE wapisecuritysettings.cpp
+SOURCE wapisecuritysettingsimpl.cpp
+SOURCE wapisecuritysettingsui.cpp
+SOURCE wapisecuritysettingsuiimpl.cpp
+SOURCE wapisecuritysettingsdlg.cpp
+SOURCE wapisecuritysettingsuipanic.cpp
+
+// Component specific internal headers 
+USERINCLUDE			../inc
+
+//Macro to /epoc32 headers
+MW_LAYER_SYSTEMINCLUDE
+APP_LAYER_SYSTEMINCLUDE
+
+LIBRARY hlplch.lib
+LIBRARY euser.lib
+LIBRARY cone.lib
+LIBRARY eikcore.lib
+LIBRARY eikcoctl.lib
+LIBRARY avkon.lib
+LIBRARY eikdlg.lib 
+LIBRARY bafl.lib
+LIBRARY commonengine.lib 
+LIBRARY FeatMgr.lib
+LIBRARY wapi.lib
+LIBRARY commsdat.lib
+
+#if defined( WINSCW )
+DEFFILE ../bwinscw/wapisecuritysettingsui.def
+#else
+DEFFILE ../eabi/wapisecuritysettingsui.def
+#endif
+
+
+// End of File
Binary file wlansecuritysettings/wapisecuritysettingsui/help/data/xhtml.zip has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/help/group/bld.inf	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,29 @@
+/*
+* ============================================================================
+*  Name     : bld.inf
+*  Part of  : WAPI Security Settings UI
+*
+*  Description: WAPI help build information
+*     
+*  Version: %version:  tr1cfwln#4 %
+*
+*  Copyright (C) 2009 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing, adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+#include <platform_paths.hrh>				
+PRJ_EXPORTS
+:zip ../data/xhtml.zip   /epoc32/data/z/resource/ overwrite
+:zip ../data/xhtml.zip   /epoc32/winscw/c/resource/ overwrite
+
+../inc/wapi.hlp.hrh	MW_LAYER_PLATFORM_EXPORT_PATH(csxhelp/wapi.hlp.hrh)
+../rom/wapisecuritysettingsuihelps_variant.iby		CUSTOMER_APP_LAYER_IBY_EXPORT_PATH(wapisecuritysettingsuihelps_variant.iby)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/help/inc/wapi.hlp.hrh	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,32 @@
+/*
+* ============================================================================
+*  Name     : wapi.hlp.hrh
+*  Part of  : WAPI Security Settings UI
+*
+*  Description: wapi.hlp.hrh generated by CSXHelp Utilities
+*     
+*  Version: %version:  tr1cfwln#11 %
+*
+*  Copyright (C) 2009 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing, adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+	
+//
+// wapi.hlp.hrh generated by CSXHelp Utilities.
+//           
+
+#ifndef __WAPI_HLP_HRH__
+#define __WAPI_HLP_HRH__
+
+_LIT(KSET_HLP_WLAN_WAPI_MAIN, "SET_HLP_WLAN_WAPI_MAIN"); // 
+
+#endif 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/help/rom/wapisecuritysettingsuihelps_variant.iby	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,11 @@
+#ifndef __WAPISECURITYSETTINGSUIHELPS_VARIANT_IBY__
+#define __WAPISECURITYSETTINGSUIHELPS_VARIANT_IBY__
+
+#if defined(FF_S60_HELPS_IN_USE) && defined(FF_WLAN_WAPI_INCLUDE_IN_ROM)
+    data=LOCALISE(DATAZ_\resource\xhtml\%02d\0x10009D8D\contents.zip, RESOURCE_FILES_DIR\xhtml\%02d\0x10009D8D\contents.zip)
+    data=LOCALISE(DATAZ_\resource\xhtml\%02d\0x10009D8D\index.xml, RESOURCE_FILES_DIR\xhtml\%02d\0x10009D8D\index.xml)
+    data=LOCALISE(DATAZ_\resource\xhtml\%02d\0x10009D8D\keywords.xml, RESOURCE_FILES_DIR\xhtml\%02d\0x10009D8D\keywords.xml)
+    data=LOCALISE(DATAZ_\resource\xhtml\%02d\0x10009D8D\meta.xml, RESOURCE_FILES_DIR\xhtml\%02d\0x10009D8D\meta.xml)
+#endif
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsdefs.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,50 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsdefs.h
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*     Definitions needed by WAPI security settings UI.
+*  Version: %version:  7 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+#include "wapisecuritysettingsui.hrh"
+
+#ifndef WAPISECURITYSETTINGSDEFS_H
+#define WAPISECURITYSETTINGSDEFS_H
+
+// CONSTANTS
+
+//Index for None certificate
+
+LOCAL_D const TInt KCertNone = 0;
+
+// Invalid id
+LOCAL_D const TUint32 KUidNone = 0;
+
+// Authentication mode
+enum TWapiAuth
+    {
+    EWapiAuthCert,
+    EWapiAuthPSK
+    };
+
+// UID of application containing help texts (General Settings).
+//LOCAL_D const TUid KWAPISecuritySettingsUiHelpMajor = { 0x100058EC };
+LOCAL_D const TUid KWAPISecuritySettingsUiHelpMajor = { 0x10009D8D };
+
+
+#endif  // WAPISECURITYSETTINGSDEFS_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsdlg.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,275 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsdlg.h
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*     Declares dialog.
+*  Version: %version:  7 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+#ifndef WAPI_SECURITY_SETTINGS_DLG_H
+#define WAPI_SECURITY_SETTINGS_DLG_H
+
+
+// INCLUDES
+#include <eiklbo.h>
+#include <AknDialog.h>
+#include <aknlists.h>
+#include <WapiCertificates.h>
+#include "wapisecuritysettingsdefs.h"
+
+// FORWARD DECLARATIONS
+class CAknTitlePane;
+
+// CLASS DECLARATION
+/**
+* CWAPISecuritySettingsDlg dialog class
+*/
+NONSHARABLE_CLASS( CWAPISecuritySettingsDlg ) : public CAknDialog, 
+                                               public MEikListBoxObserver
+    {
+    public: // Constructors and destructor
+
+        /**
+        * Create and launch dialog.
+        * @param aSecuritySettings Security settings
+        * @param aTitle Title of the dialog
+        * @return The ID of the button that closed the dialog
+        */
+        TInt ConstructAndRunLD( CWAPISecuritySettingsImpl* aSecuritySettings,
+                                const TDesC& aTitle );
+
+
+        /**
+        * Two-phase construction.
+        * @param aEventStore A reference to hold the events happened
+        * @return The constructed CWAPISecuritySettingsDlg object.
+        */
+        static CWAPISecuritySettingsDlg* NewL( TInt& aEventStore );
+
+
+        /**
+        * Destructor.
+        */
+        ~CWAPISecuritySettingsDlg();
+
+        
+    public: //Types
+         
+        enum TWapiMember
+            {
+            EWapiAuth,
+            EWapiUserCert,
+            EWapiCACert,
+            EWapiPSKFormat,
+            EWapiPSK
+            };   
+          
+    protected:
+        /**
+        * Constructor.
+        * @param aEventStore A reference to hold the events happened
+        */
+
+	    CWAPISecuritySettingsDlg( TInt& aEventStore );
+
+	    
+    public: // Functions from base classes
+        /**
+        * Handle key events. 
+        * @param aKeyEvent: key event
+        * @param aType: type of event
+        * @return The key response, if it was consumed or not. 
+        */
+		TKeyResponse OfferKeyEventL( const TKeyEvent& aKeyEvent,
+                                     TEventCode aType );
+
+	private:
+
+        /**
+        * This function is called by the dialog framework before the dialog is 
+        * sized and laid out.
+        */
+        virtual void PreLayoutDynInitL();
+
+
+        /**
+        * Handles a dialog button press for the specified button 
+        * @param aButtonId  The ID of the button that was activated.
+        * @return   ETrue to validate and exit the dialog, 
+        *           EFalse to keep the dialog active
+        */
+        TBool OkToExitL( TInt aButtonId );
+
+
+		/**
+        * Processes user commands.
+        * @param aCommandId ID of the command to respond to. 
+        */
+        virtual void ProcessCommandL( TInt aCommandId );
+
+
+		/**
+        * Handles list box events.
+        * @param aListBox   The originating list box. 
+        * @param aEventType A code for the event.
+        */
+        void HandleListBoxEventL( CEikListBox* aListBox, 
+                                  TListBoxEvent aEventType );
+
+        /**
+        * Get help context.
+        * @param aContext Help context is returned here.
+        */
+        void GetHelpContext( TCoeHelpContext& aContext ) const;
+
+        
+        /**
+        * Initialize menu pane.
+        * @param aResourceId Menu pane resource id.
+        * @param CEikMenuPane Menu pane.
+        */
+        void DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane );
+
+
+    protected:  // New functions
+
+        /**
+        * Handles listbox data change
+        */
+        void HandleListboxDataChangeL();
+
+
+        /**
+        * Fills up the listbox with data
+        * @param aItemArray Array where to add the elements
+        * @param arr        Array to be used as list elements
+        * @param aLength    The number of elements in the above array
+        * @param aRes       Array of resource IDs to be used for the 
+        *                   elements of arr
+        */
+        void FillListWithDataL( CDesCArrayFlat& aItemArray, 
+                                const TWapiMember& arr, 
+                                TInt aLength,
+                                const TInt* aRes );
+
+
+        /**
+        * Updates one listbox item for the given member
+        * @param aMember    Value specifying which member has to be added to 
+        *                   the list
+        * @param aRes       Resource ID for the 'title text' for this member
+        * @param aPos       The current position of the item in the list
+        */
+        void UpdateListBoxItemL( TWapiMember aMember, 
+                                 TInt aRes, TInt aPos );
+
+
+        /**
+        * Creates one 'textual' listbox item for the given member
+        * @param aMember    Value specifying which member has to be added to
+        *                   the list
+        * @param aRes       Resource ID for the 'title text' for this member
+        * @return The created listbox item text.
+        */
+        HBufC* CreateTextualListBoxItemL( TWapiMember aMember, 
+                                          TInt aRes );
+
+        HBufC* CWAPISecuritySettingsDlg::FormatCertTextualListBoxItemL( 
+                                                    TWapiMember aMember, TInt aRes );
+        /**
+        * Changes one setting. The setting, which is
+        * highlighted as current in the listbox is changed.
+        */
+        void ChangeSettingsL();
+
+
+        /**
+        * Shows a popup setting page (radio buttons) for the given member
+        * @param aDataMember    The member which needs to be changed
+        * @return   A boolean indicating whether the current setting
+        *           has been changed or not.
+        */
+        TBool   ShowPopupSettingPageL( TWapiMember aDataMember );
+
+        /**
+        * Shows a text setting page for setting PSK key.
+        * @return   A boolean indicating whether the current setting
+        *           has been changed or not.
+        */
+        TBool ShowPopupPSKSettingPageL();
+
+        /**
+        * Fills up a pop-up radio button setting page with the currently
+        * valid and available choices for the given member.
+        * @param aData      The member whose new setting is needed
+        * @param aCurrvalue The current value of the setting
+        * @return   An array of choices for the given member, pushed to the 
+        *           CleanupStack.
+        */
+        CDesCArrayFlat* FillPopupSettingPageLC( TWapiMember aData,
+                                                TInt& aCurrvalue );
+
+
+        /**
+        * Updates the given member's data with the new setting from the setting
+        * page.
+        * @param aData      The member to update
+        * @param aCurrvalue The new value
+        * @return An integer boolean indicating if the value is actually changed
+        */
+        TBool UpdateFromPopupSettingPage( TWapiMember aData, 
+                                          TInt aCurrvalue );
+        
+    private: //data
+
+        // Stores the name of the connection, to be showed as the title.
+      	TBuf<KMaxTextLength> iConnectionName;
+
+        // Title pane. Not owned.
+        CAknTitlePane* iTitlePane;
+
+        // Pointer to the old title. Owned.
+        HBufC* iOldTitleText;
+
+       // Owned through resources, destroyed automatically by the dialog.
+        CAknSettingStyleListBox* iList;
+
+        // Array of the items. Not owned.
+        CDesCArrayFlat* iItemArray;
+
+        // Fields of the main view. Not owned.
+        TWapiMember* iFieldsMain;
+
+        // Titles of the main view. Not owned.
+        TInt* iTitlesMain;
+
+        // Pointer to the WAPI Security Settings. Not owned.
+        CWAPISecuritySettingsImpl* iSecuritySettings;
+
+        // To hold the events. Not owned.
+        TInt* iEventStore;
+
+        //Pointers to certificate arrays. Not owned.
+        RArray<TBuf<KMaxLabelLength> >* iUserCertificates; 
+        RArray<TBuf<KMaxLabelLength> >* iCACertificates;
+        
+    };
+
+
+#endif      // WAPI_SECURITY_SETTINGS_DLG_H
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsimpl.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,258 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsimpl.h 
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*      Declaration of class CWAPISecuritySettingsImpl.
+*      
+*  Version: %version:  11.1.1 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+#ifndef WAPISECURITYSETTINGSIMPL_H
+#define WAPISECURITYSETTINGSIMPL_H
+
+// INCLUDES
+#include <e32base.h>
+#include <cmmanagerext.h>
+
+#include <wapisecuritysettingsui.h>
+#include "wapisecuritysettingsdefs.h"
+#include <WapiCertificates.h>
+
+#include <metadatabase.h>
+#include <commsdattypesv1_1.h>
+
+// FORWARD DECLARATIONS
+
+// CLASS DECLARATION
+
+/**
+* WAPI Security Settings.
+* Implementation behind proxy class CWAPISecuritySettings.
+*/
+NONSHARABLE_CLASS( CWAPISecuritySettingsImpl ) : public CBase
+    {
+
+    public:     // Constructors and destructor
+
+        /**
+        * Two-phased constructor. Leaves on failure.
+        * @return The constructed CWAPISecuritySettings object.
+        */
+        static CWAPISecuritySettingsImpl* NewL();
+
+        
+        /**
+        * Destructor.
+        */
+        virtual ~CWAPISecuritySettingsImpl();
+
+    protected:  // Constructors
+
+        /**
+        * Constructor.
+        * @param aEikEnv Eikon environment.
+        */
+        CWAPISecuritySettingsImpl();
+
+        
+        /**
+        * Second-phase constructor.
+        */
+        void ConstructL();
+
+    public:     // New methods
+
+
+        /**
+        * Load from database.
+        * @param aIapRecordId Iap record
+        * @param aSession Commsdat session
+        */
+        void LoadL( TUint32 aIapRecordId, CommsDat::CMDBSession& aSession );
+        
+        
+        /**
+        * Save to database.
+        * @param aIapRecordId Iap record
+        * @param aSession Commsdat session
+        */
+        void SaveL( TUint32 aIapRecordId, CommsDat::CMDBSession& aSession ) const;
+ 
+        
+        /**
+        * Resets certificate store from C drive
+        */
+        void ResetCertificateStoreL();
+ 
+        /**
+         * Load certificates. This was implemented for performance issues.
+         */
+        void LoadCertificatesL();
+        
+        
+        /**
+        * Delete AP related data from certificate database tables
+        *
+        * @param aId        Service table id
+        */
+        void DeleteAPSpecificDataL( const TInt aId );
+        
+        
+        /**
+         * Fetches table index by certificate label name
+         * @param aCertificates     Pointer to certificate array
+         * @param aCert             Certificate label
+         * @return  Index to corresponding certificate label
+         */
+         TInt GetIndexByCertLabel( 
+                             RArray<TBuf<KMaxLabelLength> >* aCertificates, 
+                             const TDesC& aCert);
+        
+
+         /**
+         * Read the value of the current user certificate label
+         * @param aUserCertInUse  Fetched certificate label
+         */
+        inline void GetUserCertInUse( TInt& aUserCertInUse );
+
+        
+        /**
+         * Read the value of the current CA certificate label
+         * @param aCACertInUse  Fetched certificate label
+         */
+        inline void GetCACertInUse( TInt& aCACertInUse );
+ 
+        
+        /**
+         * Sets the value of the current user certificate in use
+         * @param aSelectedCert  The new value for user certificate
+         */
+        inline void SetUserCertInUse( const TInt aSelectedCert );
+
+        
+        /**
+         * Sets the value of the current CA certificate in use
+         * @param aSelectedCert  The new value for CA certificate
+         */      
+        inline void SetCACertInUse( const TInt aSelectedCert );
+ 
+        
+        /**
+         * Fetches pointers to RARRAYS where user and CA certificates are
+         * stored.
+         * @param aUserCertificates Pointer reference to user certificates
+         * @param aCACertificates Pointer reference to CA certificates
+         */   
+        inline void GetCertificateLabels ( 
+                        RArray<TBuf<KMaxLabelLength> >*& aUserCertificates, 
+                        RArray<TBuf<KMaxLabelLength> >*& aCACertificates );
+        /**
+         * Sets preshared key format, key, and wapi to PSK mode.
+         */
+        void SetPreSharedKeyL( const CWAPISecuritySettings::TWapiKeyFormat aKeyFormat, const TDesC& aPreSharedKey );
+
+        /**
+         * Read the value of the current authentication
+         */
+        TWapiAuth GetAuthentication( );
+        
+        /**
+         * Sets the value of authentication  in use
+         * @param aWapiAuth  Authentication
+         */
+        void SetAuthentication( TWapiAuth aWapiAuth );
+        
+        /**
+         * Read the value of current key format
+         */
+        CWAPISecuritySettings::TWapiKeyFormat GetKeyFormat();
+        
+        /**
+         * Sets the value of key format
+         * @param aWapiKeyFormat Key format
+         */
+        void SetKeyFormat( CWAPISecuritySettings::TWapiKeyFormat aWapiKeyFormat ); 
+        
+        /**
+         * Returns true if psk key is set
+         */
+        TBool hasWapiPSKKey();
+        
+        /**
+         * Set the value of pre-shared wapi key
+         * @param aWapiPSKKey Pre-shared key 
+         */
+        TInt SetWapiPSKKeyL( const TDesC& aWapiPSKKey );
+        
+        /**
+         * Checks if current settings are valid.
+         */
+        TBool IsValid();
+        
+    private:
+        /**
+        * Checks whether the given string is a valid for current format
+        * @param aPsk The string to be checked
+        * @return ETrue if the string is a valid PSK, EFalse otherwise.
+        */
+        TBool IsValidPsk( const TDesC8& aPsk );
+
+        /**
+        * Checks whether the given string is a valid for given format
+        * @param aWapiKeyFormat Format (ascii/hex)
+        * @param aPsk The string to be checked
+        * @return ETrue if the string is a valid PSK, EFalse otherwise.
+        */
+        TBool IsValidPsk( const CWAPISecuritySettings::TWapiKeyFormat aWapiKeyFormat,
+                const TDesC8& aPsk );
+
+    private:    // Data 
+
+        CWapiCertificates*                  iCertificateStore; //owned
+
+        // Certificate label, identity and selected certificate.
+        RArray<TBuf<KMaxLabelLength> >*     iUserCertificates; //owned
+        RArray<TBuf8<KMaxIdentityLength> >*  iUserCertificateData; //owned
+        TInt                                iUserCertInUse; // Index of certificate data
+        RArray<TBuf<KMaxLabelLength> >*     iCACertificates; //owned
+        RArray<TBuf8<KMaxIdentityLength> >*  iCACertificateData; //owned
+        TInt                                iCACertInUse; // Index of certificate data
+
+        // Stores authentication method.
+        TWapiAuth                           iWapiAuth;
+
+        // True if PSK key is set
+        TBool                               iWapiPSKKeySet;
+        
+        // PSK key format
+        CWAPISecuritySettings::TWapiKeyFormat iWapiKeyFormat;
+        
+        // Stores PSK key.
+        TBuf8<KWapiMaxKeyLength>            iWapiPSKKey;
+        
+        // Caches wlan service id to allow later loading of certificates
+        // (solves performance issue)
+        TUint32                             iWlanServiceId;
+
+        // True if certificates have been loaded.
+        TBool                               iCertificatesLoaded;
+    };
+
+// Include inline functions
+#include "wapisecuritysettingsimpl.inl"
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsimpl.inl	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,83 @@
+/*
+* ==============================================================================
+*  Name        : wapisecuritysettingsimpl.inl
+*  Part of     : WAPI Security Settings UI
+*
+*  Description : CWAPISecuritySettingsImpl inline functions
+*  Version     : %version:  5 %
+*
+*  Copyright (c) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing, adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+* ==============================================================================
+*/
+
+
+#ifndef WAPISECURITYSETTINGSIMPL_INL
+#define WAPISECURITYSETTINGSIMPL_INL
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::GetUserCertInUse
+// ---------------------------------------------------------
+//
+inline void CWAPISecuritySettingsImpl::GetUserCertInUse(
+                                                TInt& aUserCertInUse )
+    {
+    aUserCertInUse = iUserCertInUse;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::GetCACertInUse
+// ---------------------------------------------------------
+//
+inline void CWAPISecuritySettingsImpl::GetCACertInUse(
+                                                TInt& aCACertInUse )
+    { 
+    aCACertInUse = iCACertInUse;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::SetUserCertInUse
+// ---------------------------------------------------------
+//
+inline void CWAPISecuritySettingsImpl::SetUserCertInUse( 
+                                                const TInt aSelectedCert )
+    {
+    iUserCertInUse = aSelectedCert;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::SetCACertInUse
+// ---------------------------------------------------------
+//
+inline void CWAPISecuritySettingsImpl::SetCACertInUse(
+                                                const TInt aSelectedCert )
+    {
+    iCACertInUse = aSelectedCert;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::GetCertificateLabels
+// ---------------------------------------------------------
+//
+inline void CWAPISecuritySettingsImpl::GetCertificateLabels( 
+                        RArray<TBuf<KMaxLabelLength> >*& aUserCertificates, 
+                        RArray<TBuf<KMaxLabelLength> >*& aCACertificates )
+    {
+    aUserCertificates = iUserCertificates;
+    aCACertificates = iCACertificates;
+    }
+
+#endif 
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsui.hrh	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,53 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsui.hrh
+*  Part of  : S60 WAPI Security Settings UI
+*
+*  Description:
+*     This file contains declarations for resources of wapisecuritysettingsui.
+*     The file can be included in C++ or resource file.
+*  Version: %version:  5 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+#ifndef WAPISECURITYSETTINGSUI_HRH
+#define WAPISECURITYSETTINGSUI_HRH
+
+
+// Menu command IDs
+enum TWapiSelectorMenuCommands
+    {
+    EWapiSelCmdChange = 1100,
+    EWapiSelCmdReset
+    };
+
+
+// dialog line IDs
+
+enum TWapiSelectorDllDlgLineId 
+    {
+    KWapiMainSettingsListboxId = 3 
+    };
+
+#endif      //  WAPISECURITYSETTINGSUI_HRH
+
+
+//Used to define max length for iConnectionName
+//Value taken from CommsDat::KMaxTextLength
+#define KMaxTextLength 50
+
+// Maximum length of Wapi key (HEX/ASCII)
+#define KWapiMaxKeyLength 64
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsuiimpl.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,100 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsuiimpl.h
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*      Declaration of class CWAPISecuritySettingsUiImpl.
+*      
+*  Version: %version:  3 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+#ifndef WAPISECURITYSETTINGSUIIMPL_H
+#define WAPISECURITYSETTINGSUIIMPL_H
+
+// INCLUDES
+
+#include <e32base.h>
+
+
+// FORWARD DECLARATIONS
+
+class CEikonEnv;
+class CWAPISecuritySettings;
+class CWAPISecuritySettingsUiImpl;
+class CWAPISecuritySettingsImpl;
+
+
+// CLASS DECLARATION
+
+/**
+* WAPI Security Settings UI implementation (behind proxy class
+* CWAPISecuritySettingsUi)
+*/
+NONSHARABLE_CLASS( CWAPISecuritySettingsUiImpl ) : public CBase
+    {
+
+    public:     // Constructors and destructor
+
+        /**
+        * Two-phased constructor. Leaves on failure.
+        * @param aEikEnv Eikon environment.
+        * @return The constructed CWAPISecuritySettingsUiImpl object.
+        */
+        static CWAPISecuritySettingsUiImpl* NewL( CEikonEnv& aEikEnv );
+
+        /**
+        * Destructor.
+        */
+        virtual ~CWAPISecuritySettingsUiImpl();
+
+    protected:  // Constructors
+
+        /**
+        * Constructor.
+        * @param aEikEnv Eikon environment.
+        */
+        CWAPISecuritySettingsUiImpl( CEikonEnv& aEikEnv );
+
+        /**
+        * Second-phase constructor.
+        */
+        void ConstructL();
+
+    public:     // New methods
+
+        /**
+        * Edit the settings.
+        * @param aSettings Settings to edit.
+        * @param aTitle Title Pane text to display during edit.
+        * @return Exit code. Value from CWAPISecuritySettings::TEvent bits 
+        * combined.
+        */
+        TInt EditL( CWAPISecuritySettingsImpl& aSettings, const TDesC& aTitle );
+
+
+    private:    // Data 
+
+        // To hold the events
+        TInt        iEventStore;
+
+        // Resource file offset.
+        TInt        iResOffset; 
+        
+        // Eikon environment. Not owned.
+        CEikonEnv*  iEikEnv;        
+    };
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/inc/wapisecuritysettingsuipanic.h	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,46 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsuipanic.h 
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*      Panic function and codes.   
+*      
+*  Version: %version:  3 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+#ifndef WAPISECURITYSETTINGSUIPANIC_H
+#define WAPISECURITYSETTINGSUIPANIC_H
+
+// TYPES
+
+/**
+* Panic reasons for WAPI Security Settings UI.
+*/
+enum TWapiSecuritySettingsPanicCodes
+    {
+    EUnknownCase
+    };
+
+
+// FUNCTION DECLARATIONS
+
+/**
+* Panic the thread.
+* @param aReason Reason for the panic.
+*/
+void Panic( TWapiSecuritySettingsPanicCodes aPanic );
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/loc/wapisecuritysettingsui.loc	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,150 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsui.loc
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*     This is a localisation file for wapisecuritysettingsui
+*     A .loc file is the one and only place where the logical strings
+*     to be localised are defined.
+*  Version: %version:  6 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+
+// LOCALISATION STRINGS
+
+
+//d:Command in options menu.
+//d:Resets the WAPI certificate store DB.
+//l:list_single_pane_t1_cp2
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_options_reset_wapi_cert_store  "Reset certificate store"
+
+
+//d:Item text in setting list.
+//l:list_setting_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_wapi_client_cert          "WAPI client certificate"
+
+
+//d:Item text in setting list.
+//l:list_setting_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_wapi_root_cert            "WAPI root certificate"
+
+
+//d:Item text in setting list.
+//l:list_set_graphic_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_wapi_cert_none            "None"
+
+
+//d:List pane for the setting value item list 
+//d:This is for qtn_wlan_sett_wapi_client_cert
+//d:or for qtn_wlan_sett_wapi_root_cert
+//l:list_set_graphic_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_wapi_cert_not_defined     "(not defined)"
+
+//d:Item text in setting list.
+//d:Defines the WAPI authentication method.
+//l:list_setting_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_wapi_auth  "WAPI authentication"
+
+//d:Item text in setting list.
+//l:list_set_graphic_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_wapi_auth_cert            "Certificate"
+
+//d:Item text in setting list.
+//l:list_set_graphic_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_wapi_auth_psk            "Pre-shared key"
+
+//d:Item text in setting list.
+//l:list_setting_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_preshared_key_format            "Pre-shared key format"
+
+//d:Item text in setting list.
+//l:list_set_graphic_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_preshared_key_format_ascii            "ASCII"
+
+//d:Item text in setting list.
+//l:list_set_graphic_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_preshared_key_format_hex            "Hexadecimal"
+
+//d:Item text in setting list.
+//l:list_setting_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_preshared_key            "Pre-shared key"
+
+//d:Item text in setting list.
+//l:list_set_graphic_pane_t1
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_sett_preshared_key_not_defined            "Must be defined"
+
+//d:Confirmation query showed to the user when not all compulsory data have
+//d:been entered
+//l:popup_note_window
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_quest_preshared_key_data_missing	"Pre-shared key data is compulsory. Security settings will not be saved. Continue?"
+
+//d:Information note showed to the user when pre-shared key contains illegal characters
+//l:popup_note_window
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_info_preshared_key_illegal_chars	"Illegal characters in pre-shared key"
+
+//d:Information note showed to the user when hexadecimal pre-shared key length is not even
+//l:popup_note_window
+//w:
+//r:5.0.1
+//
+#define qtn_wlan_info_psk_not_even                   "Hex key must be even length"
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettings.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,117 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettings.cpp 
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*      Implementation of class CWAPISecuritySettings.   
+*      
+*  Version: %version:  9 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+// INCLUDE FILES
+
+#include <wapisecuritysettingsui.h>
+
+#include "wapisecuritysettingsimpl.h"
+#include "wapisecuritysettingsuiimpl.h"
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CWAPISecuritySettings::NewL
+// ---------------------------------------------------------
+//
+EXPORT_C CWAPISecuritySettings* CWAPISecuritySettings::NewL()
+    {
+    CWAPISecuritySettings* settings = new ( ELeave ) CWAPISecuritySettings();
+    CleanupStack::PushL( settings );
+    settings->iImpl = CWAPISecuritySettingsImpl::NewL();
+    CleanupStack::Pop( settings ); 
+    return settings;    
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettings::~CWAPISecuritySettings
+// ---------------------------------------------------------
+//
+EXPORT_C CWAPISecuritySettings::~CWAPISecuritySettings()
+    {
+    delete iImpl;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettings::EditL
+// ---------------------------------------------------------
+//
+EXPORT_C TInt CWAPISecuritySettings::EditL( CWAPISecuritySettingsUi& aUi,
+                                           const TDesC& aTitle )
+    {
+    return aUi.iImpl->EditL( *iImpl, aTitle );
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettings::LoadL
+// ---------------------------------------------------------
+//
+EXPORT_C void CWAPISecuritySettings::LoadL( TUint32 aIapRecordId, CMDBSession& aSession )
+    {
+    iImpl->LoadL( aIapRecordId, aSession );
+    }
+    
+
+// ---------------------------------------------------------
+// CWAPISecuritySettings::SaveL
+// ---------------------------------------------------------
+//
+EXPORT_C TBool CWAPISecuritySettings::IsValid( ) const
+    {
+    return iImpl->IsValid( );
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettings::SaveL
+// ---------------------------------------------------------
+//
+EXPORT_C void CWAPISecuritySettings::SaveL( TUint32 aIapRecordId, CMDBSession& aSession ) const
+    {
+    iImpl->SaveL( aIapRecordId, aSession );
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettings::SetPreSharedKey
+// ---------------------------------------------------------
+//
+EXPORT_C void CWAPISecuritySettings::SetPreSharedKeyL( const TWapiKeyFormat aKeyFormat, const TDesC& aPreSharedKey )
+    {
+    iImpl->SetPreSharedKeyL(aKeyFormat, aPreSharedKey);
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettings::DeleteAPSpecificDataL
+// ---------------------------------------------------------
+//
+EXPORT_C void CWAPISecuritySettings::DeleteAPSpecificDataL( const TInt aId )
+    {
+    iImpl->DeleteAPSpecificDataL( aId );
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettingsdlg.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,1074 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsdlg.cpp
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*     Implementation of dialog.
+*
+*  Version: %version:  16 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+// INCLUDE FILES
+#include <aknnavide.h>
+#include <akntitle.h>
+#include <aknradiobuttonsettingpage.h>
+#include <akntextsettingpage.h>
+#include <aknmfnesettingpage.h>
+#include <barsread.h>
+#include <StringLoader.h>
+#include <aknnotewrappers.h>
+
+#include <wapisecuritysettingsui.h>
+#include <wapisecuritysettingsui.rsg>
+#include "wapisecuritysettingsimpl.h"
+#include "wapisecuritysettingsuipanic.h"
+#include "wapisecuritysettingsdlg.h"
+#include "wapisecuritysettingsui.hrh"
+
+#include <hlplch.h>
+#include <csxhelp/wapi.hlp.hrh>
+
+#include <featmgr.h>
+
+
+// CONSTANT DECLARATIONS
+
+// Number of fields of main view
+LOCAL_D const TInt KNumOfFieldsMain = 3;
+
+LOCAL_D const TInt KTitles_Wapi_Main_Cert[KNumOfFieldsMain] =
+                   {
+                   R_WAPI_AUTH,
+                   R_WAPI_CLIENT_CERT,
+                   R_WAPI_ROOT_CERT
+                   };
+LOCAL_D const TInt KFields_Wapi_Main_Cert[KNumOfFieldsMain] =
+                   {
+                   CWAPISecuritySettingsDlg::EWapiAuth,
+                   CWAPISecuritySettingsDlg::EWapiUserCert,
+                   CWAPISecuritySettingsDlg::EWapiCACert
+                   };
+
+LOCAL_D const TInt KTitles_Wapi_Main_PSK[KNumOfFieldsMain] =
+                   {
+                   R_WAPI_AUTH,
+                   R_WAPI_PRESHARED_KEY_FORMAT,
+                   R_WAPI_PRESHARED_KEY
+                   };
+LOCAL_D const TInt KFields_Wapi_Main_PSK[KNumOfFieldsMain] =
+                   {
+                   CWAPISecuritySettingsDlg::EWapiAuth,
+                   CWAPISecuritySettingsDlg::EWapiPSKFormat,
+                   CWAPISecuritySettingsDlg::EWapiPSK
+                   };
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::CWAPISecuritySettingsDlg
+// ---------------------------------------------------------
+//
+CWAPISecuritySettingsDlg::CWAPISecuritySettingsDlg( TInt& aEventStore )
+: iEventStore( &aEventStore )
+    {
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::~CWAPISecuritySettingsDlg
+// ---------------------------------------------------------
+//
+CWAPISecuritySettingsDlg::~CWAPISecuritySettingsDlg()
+    {
+    if ( iTitlePane )
+        {
+        // set old text back, if we have it...
+        if ( iOldTitleText )
+            {
+            TRAP_IGNORE( iTitlePane->SetTextL( *iOldTitleText ) );
+            delete iOldTitleText;
+            }
+        }
+    FeatureManager::UnInitializeLib();
+     }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::NewL
+// ---------------------------------------------------------
+//
+CWAPISecuritySettingsDlg* CWAPISecuritySettingsDlg::NewL( TInt& aEventStore )
+    {
+    CWAPISecuritySettingsDlg* secSett = 
+                        new ( ELeave )CWAPISecuritySettingsDlg( aEventStore );
+    return secSett;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::ConstructAndRunLD
+// ---------------------------------------------------------
+//
+TInt CWAPISecuritySettingsDlg::ConstructAndRunLD( 
+                                CWAPISecuritySettingsImpl* aSecuritySettings,
+                                const TDesC& aTitle )
+    {
+	CleanupStack::PushL( this );
+
+	iSecuritySettings = aSecuritySettings;
+    iConnectionName = aTitle;
+
+    // Build menu according to current authentication scheme.
+    if (iSecuritySettings->GetAuthentication() == EWapiAuthPSK)
+        {
+        iFieldsMain = ( TWapiMember* ) KFields_Wapi_Main_PSK;
+        iTitlesMain = MUTABLE_CAST( TInt*, KTitles_Wapi_Main_PSK );
+        }
+    else // ... == EWapiAuthCert
+        {
+        iFieldsMain = ( TWapiMember* ) KFields_Wapi_Main_Cert;
+        iTitlesMain = MUTABLE_CAST( TInt*, KTitles_Wapi_Main_Cert );
+        }
+    
+    //Let's fetch pointers to the certificate arrays
+
+    iSecuritySettings->GetCertificateLabels( iUserCertificates, iCACertificates );
+
+    #if defined( _DEBUG ) || defined( DEBUG )
+    if ( iUserCertificates )
+        {
+        RDebug::Print(_L("CWAPISecuritySettingsDlg::ConstructAndRunLD, %d user certs"), iUserCertificates->Count() );
+        }
+    else
+        {
+        RDebug::Print(_L("CWAPISecuritySettingsDlg::ConstructAndRunLD, no user certs") );
+        }
+    
+    if ( iCACertificates )
+        {
+        RDebug::Print(_L("CWAPISecuritySettingsDlg::ConstructAndRunLD, %d ca certs"), iCACertificates->Count() );
+        }
+    else
+        {
+        RDebug::Print(_L("CWAPISecuritySettingsDlg::ConstructAndRunLD, no ca certs") );
+        }
+    #endif
+    
+    FeatureManager::InitializeLibL();
+
+    ConstructL( R_WAPI_SECURITY_SETTINGS_MENUBAR );
+    
+    // ExecuteLD will PushL( this ), so we have to Pop it...
+    CleanupStack::Pop( this ); // this
+    return ExecuteLD( R_WAPISETTINGS_DIALOG );
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::OkToExitL
+// ---------------------------------------------------------
+//
+TBool CWAPISecuritySettingsDlg::OkToExitL( TInt aButtonId )
+{
+    // Translate the button presses into commands for the appui & current
+    // view to handle
+    TBool retval( EFalse );
+    if ( aButtonId == EAknSoftkeyOptions )
+        {
+        DisplayMenuL();
+        }
+    else if ( aButtonId == EEikCmdExit )        // ShutDown requested
+        {
+        *iEventStore |= CWAPISecuritySettings::EShutDownReq;
+        retval = ETrue;
+        }
+    else if ( aButtonId == EAknSoftkeyBack || aButtonId == EAknCmdExit )
+        {
+        if (iSecuritySettings->GetAuthentication() == EWapiAuthPSK)
+            {
+            if (iSecuritySettings->IsValid())
+                {
+                *iEventStore |= CWAPISecuritySettings::EValid;
+                retval = ETrue;
+                }
+            else if ( aButtonId == EAknSoftkeyBack )
+                {
+                HBufC* stringHolder = StringLoader::LoadL(
+                                R_WAPI_QUEST_PRESHARED_KEY_DATA_MISSING, iEikonEnv );
+                CleanupStack::PushL( stringHolder );
+    
+                CAknQueryDialog *queryDialog = new (ELeave) CAknQueryDialog();
+    
+                queryDialog->PrepareLC( R_WAPI_SEC_SETT_CONF_QUERY );
+                queryDialog->SetPromptL( stringHolder->Des() );
+                retval = queryDialog->RunLD();
+    
+                CleanupStack::PopAndDestroy( stringHolder );   // stringHolder
+    
+                }
+            else
+                {
+                retval = ETrue;
+                }
+            }
+        else
+            {
+            *iEventStore |= CWAPISecuritySettings::EValid;
+            retval = ETrue;
+            }
+        
+        if ( aButtonId == EAknCmdExit )
+            {
+            *iEventStore |= CWAPISecuritySettings::EExitReq;
+            }
+        
+        }
+    else if( aButtonId == EWapiSelCmdChange )
+        {
+        ChangeSettingsL();
+        retval = EFalse; // don't exit the dialog
+        }
+
+    return retval;
+}
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::OfferKeyEventL
+// ---------------------------------------------------------
+//
+TKeyResponse CWAPISecuritySettingsDlg::OfferKeyEventL( 
+                                const TKeyEvent& aKeyEvent, TEventCode aType )
+    {
+    TKeyResponse retval( EKeyWasNotConsumed );
+    TChar charCode( aKeyEvent.iCode );
+
+    // Only interested in standard key events
+    if ( aType == EEventKey )
+        {
+        // If a menu is showing offer key events to it.
+        if ( CAknDialog::MenuShowing() )
+            {
+            retval = CAknDialog::OfferKeyEventL( aKeyEvent, aType );
+            }
+        else
+            {
+            if ( iList )
+                {
+                // as list IS consuming, must handle because it IS 
+                //the SHUTDOWN or, a view switch is shutting us down...
+                if ( aKeyEvent.iCode == EKeyEscape )
+                    {
+                    ProcessCommandL( EEikCmdExit );
+                    retval = EKeyWasConsumed;
+                    }
+                else
+                    {
+                    retval = iList->OfferKeyEventL( aKeyEvent, aType );
+                    }
+                }
+            else
+                {
+                if ( aKeyEvent.iCode == EKeyOK )
+                    {
+                    ProcessCommandL( EWapiSelCmdChange );
+                    retval = EKeyWasConsumed;
+                    }
+                }
+            }
+        }
+    return retval;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::HandleListboxDataChangeL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsDlg::HandleListboxDataChangeL()
+    {
+    // fill up our new list with data
+    CDesCArrayFlat* itemArray = new ( ELeave ) CDesCArrayFlat( 4 );
+    CleanupStack::PushL( itemArray );
+
+    FillListWithDataL( *itemArray, *iFieldsMain, KNumOfFieldsMain, 
+            iTitlesMain );
+
+    iList->Model()->SetItemTextArray( itemArray );
+    
+    CleanupStack::Pop( itemArray ); // now it is owned by the LB, so pop it
+    iItemArray = itemArray;
+
+    iList->HandleItemAdditionL();
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::ProcessCommandL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsDlg::ProcessCommandL( TInt aCommandId )
+    {
+    if ( MenuShowing() )
+        {
+        HideMenu();
+        }
+
+    switch ( aCommandId )
+        {
+        case EWapiSelCmdChange:
+            {
+            ChangeSettingsL();
+            break;
+            }
+
+        case EWapiSelCmdReset:
+            {
+            TRAPD( err, iSecuritySettings->ResetCertificateStoreL() );
+
+            HBufC* label;
+                            
+            if ( err == KErrNone )
+                {
+                //Certificate store was emptied, RARRAY's were closed,
+                //pointer's were freed and certificates's in use were set
+                //to "None" when ResetcertificateStoreL was called.
+                //So we have to update the selections on the screen to
+                //"(Not defined)" and redraw
+                
+                //refresh pointers
+                iSecuritySettings->GetCertificateLabels( 
+                                      iUserCertificates, iCACertificates );
+                
+                
+                for ( TInt i = 0; i < KNumOfFieldsMain; i++ )
+                    {
+
+                    TWapiMember* ptr = iFieldsMain + i;
+                    TInt* tptr = iTitlesMain + i;
+                    
+                    UpdateListBoxItemL( *ptr, *tptr, i );
+                    *iEventStore |= CWAPISecuritySettings::EModified;
+
+                    iList->ScrollToMakeItemVisible( i );
+                    iList->DrawItem( i );
+                    }
+
+
+                
+                label = StringLoader::LoadL( R_WAPI_DONE, iEikonEnv );
+                }
+            else
+                {
+                label = StringLoader::LoadL( R_WAPI_FAILURE, iEikonEnv );
+                }
+
+            CleanupStack::PushL( label );
+            
+            CAknInformationNote* dialog = new (ELeave)CAknInformationNote( 
+                    ETrue );
+            dialog->ExecuteLD( *label );
+            
+            CleanupStack::PopAndDestroy( label );         
+
+            break;
+            }                  
+            
+        case EAknCmdHelp:
+            {
+            HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(),
+                                    iEikonEnv->EikAppUi()->AppHelpContextL() );
+            break;
+            }
+
+        case EAknSoftkeyBack:
+        case EAknCmdExit:
+        case EEikCmdExit:
+            {
+            TryExitL( aCommandId );
+            break;
+            }
+
+        default:
+            {
+            // silently ignore it
+            break;
+            }
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::HandleListBoxEventL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsDlg::HandleListBoxEventL( CEikListBox* /*aListBox*/,
+                                                   TListBoxEvent aEventType )
+    {
+    switch ( aEventType )
+        {
+        case EEventEnterKeyPressed:
+        case EEventItemSingleClicked:
+            {
+            ChangeSettingsL();
+            break;
+            }
+
+        case EEventEditingStarted:
+        case EEventEditingStopped:
+        case EEventPenDownOnItem:
+        case EEventItemDraggingActioned:
+            {
+            break;
+            }
+
+        default:
+            {
+            __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) );
+            break;
+            };
+        };
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::PreLayoutDynInitL()
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsDlg::PreLayoutDynInitL()
+    {
+    // first get StatusPane
+    CEikStatusPane* statusPane = iEikonEnv->AppUiFactory()->StatusPane();
+
+    // then get TitlePane
+    iTitlePane = ( CAknTitlePane* ) statusPane->ControlL( TUid::Uid( 
+                                                    EEikStatusPaneUidTitle ) );
+    // if not already stored, store it for restoring
+    if ( !iOldTitleText )
+        {
+        iOldTitleText = iTitlePane->Text()->AllocL();
+        }
+
+    // set new titlepane text
+    iTitlePane->SetTextL( iConnectionName );
+
+    iList = STATIC_CAST( CAknSettingStyleListBox*, 
+                         Control( KWapiMainSettingsListboxId ) );
+
+    iList->CreateScrollBarFrameL( ETrue );
+    iList->ScrollBarFrame()->SetScrollBarVisibilityL
+        ( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );
+
+    HandleListboxDataChangeL();
+
+    iList->SetCurrentItemIndex( 0 );
+    iList->SetListBoxObserver( this );
+    }
+
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::DynInitMenuPaneL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsDlg::DynInitMenuPaneL( TInt aResourceId, 
+                                                 CEikMenuPane* aMenuPane )
+    {
+    CAknDialog::DynInitMenuPaneL( aResourceId, aMenuPane );
+    if ( aResourceId == R_WAPI_SECURITY_SETTINGS_MENU )
+        {
+        if( !FeatureManager::FeatureSupported( KFeatureIdHelp ) )
+            {
+            aMenuPane->DeleteMenuItem( EAknCmdHelp );
+            }
+        }
+    }
+
+
+//----------------------------------------------------------
+// CWAPISecuritySettingsDlg::FillListWithDataL
+//----------------------------------------------------------
+//
+void CWAPISecuritySettingsDlg::FillListWithDataL( CDesCArrayFlat& aItemArray,
+                                                  const TWapiMember& arr, 
+                                                  TInt aLength,
+                                                  const TInt* aRes )
+    {
+    TWapiMember* wapiMember = MUTABLE_CAST( TWapiMember*, &arr );
+
+    for( TInt i = 0; i < aLength; i++ )
+        {
+        HBufC* itemText = CreateTextualListBoxItemL( *wapiMember, 
+                                                         *aRes );         
+        CleanupStack::PushL( itemText );
+        aItemArray.AppendL( itemText->Des() );
+        CleanupStack::PopAndDestroy( itemText );
+
+        wapiMember++;
+        aRes++;
+        }
+    }
+
+
+//----------------------------------------------------------
+// CWAPISecuritySettingsDlg::UpdateListBoxItemL
+//----------------------------------------------------------
+//
+void CWAPISecuritySettingsDlg::UpdateListBoxItemL( TWapiMember aMember, 
+                                                   TInt aRes, TInt aPos )
+    {
+    HBufC* itemText = CreateTextualListBoxItemL( aMember, aRes );
+    CleanupStack::PushL( itemText );
+    // first try to add, if Leaves, list will be untouched
+    iItemArray->InsertL( aPos, itemText->Des() );
+    // if successful, previous item is scrolled up with one,
+    // so delete that one...
+    if ( ++aPos < iItemArray->MdcaCount() )
+        {
+        iItemArray->Delete( aPos );
+        }
+    CleanupStack::PopAndDestroy( itemText );
+    }
+
+
+//----------------------------------------------------------
+// CWAPISecuritySettingsDlg::CreateTextualListBoxItemL
+//----------------------------------------------------------
+//
+HBufC* CWAPISecuritySettingsDlg::CreateTextualListBoxItemL( 
+                                            TWapiMember aMember, TInt aRes )
+    {
+    #if defined( _DEBUG ) || defined( DEBUG )
+    RDebug::Print(_L("CWAPISecuritySettingsDlg::CreateTextualListBoxItemL") );
+    #endif
+    
+    
+    // Define a heap descriptor to hold title text
+    // that are "WAPI client certificate" or
+    // "WAPI root certificate"
+    HBufC* titleText = iEikonEnv->AllocReadResourceLC( aRes );
+//
+//    TInt certIndex = KNone;
+//    TPtrC certPtr;   
+
+    HBufC* optText = NULL;
+
+
+    switch ( aMember )
+        {
+        case EWapiAuth:
+            {
+            if (iSecuritySettings->GetAuthentication() == EWapiAuthPSK)
+                {
+                optText = iEikonEnv->AllocReadResourceLC(R_WAPI_AUTH_PSK);
+                }
+            else // ... == EWapiAuthCert
+                {
+                optText = iEikonEnv->AllocReadResourceLC(R_WAPI_AUTH_CERT);
+                }
+            }
+            break;
+        case EWapiUserCert:
+        case EWapiCACert:
+            {
+            optText = FormatCertTextualListBoxItemL(aMember, aRes);
+            break;
+            }
+        case EWapiPSKFormat:
+            {
+            if (iSecuritySettings->GetKeyFormat() == CWAPISecuritySettings::EWapiKeyAscii)
+                {
+                optText = iEikonEnv->AllocReadResourceLC(R_WAPI_PRESHARED_KEY_FORMAT_ASCII);                
+                }
+            else // ... == EWapiKeyHex
+                {
+                optText = iEikonEnv->AllocReadResourceLC(R_WAPI_PRESHARED_KEY_FORMAT_HEX);
+                }
+            break;
+            }
+        case EWapiPSK:
+            {
+            if (!iSecuritySettings->hasWapiPSKKey())
+                {
+                // PSK key not set.
+                optText = iEikonEnv->AllocReadResourceLC(R_WAPI_PRESHARED_KEY_NOT_DEFINED);
+                }
+            else
+                {
+                // PSK key set.
+                _LIT( KStars, "****" );
+                optText = HBufC::NewLC( KStars().Length() );
+                optText->Des().Copy( KStars ); 
+
+                }
+            break;
+            }
+        default:
+            {
+            __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) );
+            break;
+            }
+        }
+    _LIT( KTxtListItemFormat, " \t%S\t\t%S" );
+    const TInt KSpaceAndTabsLength = 4;
+        
+    // Define a heap descriptor to hold all the item text
+    // +4 for space and tab characters
+
+    TInt length = titleText->Length() + optText->Length() 
+                  + KSpaceAndTabsLength;
+    
+    HBufC* itemText = HBufC::NewLC( length );
+
+    // Define a modifiable pointer descriptor to be able to append the title
+    // text and the certificate label to the non-modifiable heap descriptor
+    // itemText
+    TPtr itemTextPtr = itemText->Des();
+    itemTextPtr.Format( KTxtListItemFormat, titleText, optText );
+ 
+    CleanupStack::Pop( itemText ); // itemtext is popped
+
+    CleanupStack::PopAndDestroy( 2, titleText ); // optText, titleText
+    return itemText;
+    }
+
+//----------------------------------------------------------
+// CWAPISecuritySettingsDlg::FormatCertTextualListBoxItemL
+//----------------------------------------------------------
+//
+HBufC* CWAPISecuritySettingsDlg::FormatCertTextualListBoxItemL( 
+                                            TWapiMember aMember, TInt /* aRes */ )
+    {
+    #if defined( _DEBUG ) || defined( DEBUG )
+    RDebug::Print(_L("CWAPISecuritySettingsDlg::FormatCertTextualListBoxItemL") );
+    #endif
+    
+    TInt certIndex = KCertNone;
+    TPtrC certPtr;   
+
+    //Check that pointers are not null for example after
+    //certificate store has been reset.
+    switch ( aMember )
+        {
+        case EWapiUserCert:
+            {
+            #if defined( _DEBUG ) || defined( DEBUG )
+            RDebug::Print(_L("user certIndex = %d"), certIndex );
+            #endif
+                
+            if ( iUserCertificates )
+                {
+                iSecuritySettings->GetUserCertInUse( certIndex );
+                certPtr.Set ((*iUserCertificates)[certIndex]);
+                }
+                
+            #if defined( _DEBUG ) || defined( DEBUG )
+            RDebug::Print(_L("user certIndex = %d"), certIndex );
+            #endif
+                
+            break;
+            }
+
+        case EWapiCACert:
+            {
+            #if defined( _DEBUG ) || defined( DEBUG )
+            RDebug::Print(_L("ca certIndex = %d"), certIndex );
+            #endif
+                
+            if ( iCACertificates )
+                {
+                iSecuritySettings->GetCACertInUse( certIndex );
+                certPtr.Set ((*iCACertificates)[certIndex]);
+                }
+                
+            #if defined( _DEBUG ) || defined( DEBUG )
+            RDebug::Print(_L("ca certIndex = %d"), certIndex );
+            #endif
+                
+            break;
+            }
+        default:
+            {
+            __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) );
+            break;
+            }
+        }
+ 
+    // Define a heap descriptor to hold the certificate label text
+    HBufC16* certText;
+    
+    if ( certIndex == KCertNone )
+        {
+        // If "None" is selected from pop up setting page then 
+        // "(Not defined)" is shown on the main screen. This item
+        // has to localized text so read it from resource file.
+        certText = iEikonEnv->AllocReadResourceLC( R_WAPI_CERT_NOT_DEFINED );
+        }
+    else
+        {
+        //Use certificate text found from certificate array
+        //(pointer was set in switch case above)
+        certText = HBufC::NewLC( (certPtr.Length()) ); //pushes pointer 
+                                                       //to Cleanup stack
+        certText->Des().Copy( certPtr ); 
+        }
+
+    return certText;
+    }
+
+
+//----------------------------------------------------------
+// CWAPISecuritySettingsDlg::ShowPopupSettingPageL
+//----------------------------------------------------------
+//
+TBool CWAPISecuritySettingsDlg::ShowPopupSettingPageL( TWapiMember aData )
+    {
+    TInt currvalue( 0 );
+    TBool retval( EFalse );
+    CDesCArrayFlat* items = FillPopupSettingPageLC( aData,  currvalue );
+    
+    #if defined( _DEBUG ) || defined( DEBUG )
+    RDebug::Print(_L("CWAPISecuritySettingsDlg::ShowPopupSettingPageL, %d items"), items->Count() );
+    #endif
+
+    TInt attr_resid( 0 );
+
+    switch ( aData )
+        {
+        case EWapiUserCert:
+            {
+            attr_resid = R_WAPI_CLIENT_CERT;
+            break;
+            }
+
+        case EWapiCACert:
+            {
+            attr_resid = R_WAPI_ROOT_CERT;
+            break;
+            }
+  
+        default:
+            {
+            __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) );
+            attr_resid = 0;
+            break;
+            }
+        }
+
+    HBufC* titlebuf;
+    CAknRadioButtonSettingPage* dlg;
+    if ( attr_resid )
+        {
+        titlebuf = iEikonEnv->AllocReadResourceLC( attr_resid );
+        dlg = new ( ELeave )CAknRadioButtonSettingPage( 
+                            R_RADIO_BUTTON_SETTING_PAGE, currvalue, items );
+        CleanupStack::PushL( dlg ); 
+        TPtrC ptr( titlebuf->Des() );
+        dlg->SetSettingTextL( ptr );
+        CleanupStack::Pop( dlg ); // dlg
+        }
+    else
+        {
+        dlg = new ( ELeave )CAknRadioButtonSettingPage( 
+                            R_RADIO_BUTTON_SETTING_PAGE, currvalue, items );
+        }
+    if ( dlg->ExecuteLD( CAknSettingPage::EUpdateWhenAccepted ) )
+        {
+    	retval = UpdateFromPopupSettingPage( aData, currvalue );
+	    }
+
+    if ( attr_resid )
+        {
+        CleanupStack::PopAndDestroy( titlebuf ); // titlebuf
+        }
+
+    CleanupStack::PopAndDestroy( items );   // items. It deletes also all 
+                                            // elements in the array.
+    return retval;
+    }
+
+//----------------------------------------------------------
+// CWAPISecuritySettingsDlg::ShowPopupPSKSettingPageL
+//----------------------------------------------------------
+//
+TBool CWAPISecuritySettingsDlg::ShowPopupPSKSettingPageL()
+    {
+    TBool retval( EFalse );
+
+    HBufC16* bufKeyData = HBufC16::NewLC( KWapiMaxKeyLength );
+    TPtr16 ptrKeyData( bufKeyData->Des() );
+
+    TBool showPage( ETrue );
+    while ( showPage )
+        {
+        CAknTextSettingPage* settingPage = 
+                new( ELeave )CAknTextSettingPage( R_PSK_SETTING_PAGE_KEY_DATA,
+                ptrKeyData, EAknSettingPageNoOrdinalDisplayed );
+
+        if ( settingPage->ExecuteLD( CAknSettingPage::EUpdateWhenAccepted ) )
+            {
+            HBufC8* buf8 = HBufC8::NewLC( bufKeyData->Des().Length() );
+            buf8->Des().Copy( bufKeyData->Des() ); 
+
+            if ( iSecuritySettings->SetWapiPSKKeyL(ptrKeyData) != KErrNone )
+                {
+                TInt resourceId = R_WAPI_INFO_PRESHARED_KEY_ILLEGAL_CHARS;
+                if ( (iSecuritySettings->GetKeyFormat()
+                        == CWAPISecuritySettings::EWapiKeyHex)
+                        && (ptrKeyData.Length() % 2 != 0))
+                    {
+                    resourceId = R_WAPI_INFO_PRESHARED_KEY_NOT_EVEN;
+                    }
+                HBufC* stringLabel;
+                stringLabel = StringLoader::LoadL( resourceId );
+                CleanupStack::PushL( stringLabel );
+
+                CAknInformationNote* dialog = new ( ELeave )
+                                              CAknInformationNote( ETrue );
+
+                CleanupStack::Pop( stringLabel );
+
+                dialog->ExecuteLD( *stringLabel );
+                delete stringLabel;
+                }
+            else
+                {
+                retval = ETrue;
+                showPage = EFalse;
+                }
+
+            CleanupStack::PopAndDestroy( buf8 ); // buf8
+            }
+        else
+            {
+            showPage = EFalse;
+            }
+        }
+
+    CleanupStack::PopAndDestroy( bufKeyData ); // bufKeyData
+
+    return retval;
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::FillPopupSettingPageLC
+// ---------------------------------------------------------
+//
+CDesCArrayFlat* CWAPISecuritySettingsDlg::FillPopupSettingPageLC( 
+                                                            TWapiMember aData,
+                                                            TInt& aCurrvalue )
+    {
+    TInt certIndex = KCertNone;
+    CDesCArrayFlat* items = new( ELeave)CDesCArrayFlat( 1 );
+    CleanupStack::PushL( items );
+
+    
+    // "None" item is not read from the certificate table as it has to be 
+    // localized string
+     RBuf16 resourceText( iEikonEnv->AllocReadResourceL( R_WAPI_NONE ) );
+     items->AppendL( resourceText );
+     resourceText.Close();
+    
+    switch ( aData )
+        {
+        case EWapiUserCert:
+            {
+            // Let's add user certificate labels from RARRAY
+            if ( iUserCertificates )
+                {
+                #if defined( _DEBUG ) || defined( DEBUG )
+                RDebug::Print(_L("CWAPISecuritySettingsDlg::FillPopupSettingPageLC, %d user certificates"), iUserCertificates->Count() );
+                #endif
+                
+                TPtrC ptr;
+                for ( TInt i = 1; i < iUserCertificates->Count(); i++ )
+                    {
+                    ptr.Set ((*iUserCertificates)[i]); // AppendL needs a pointer
+                    items->AppendL( ptr );
+                    }
+                }       
+            iSecuritySettings->GetUserCertInUse( certIndex );   
+            break;
+            }
+            
+        case EWapiCACert:
+            {
+          //Lets add CA certificate labels from RARRAY
+            if (iCACertificates)
+                {
+                TPtrC ptr;
+                for ( TInt i = 1; i < iCACertificates->Count(); i++ )
+                    {
+                    ptr.Set((*iCACertificates)[i]); // AppendL needs a pointer
+                    items->AppendL( ptr );
+                    }
+                }            
+            iSecuritySettings->GetCACertInUse( certIndex );
+            break;
+            }
+
+        default:
+            {
+            __ASSERT_DEBUG( EFalse, Panic ( EUnknownCase ) );
+            break;
+            }
+        }
+    aCurrvalue = certIndex; //Set current choice
+    return items;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::UpdateFromPopupSettingPage
+// ---------------------------------------------------------
+//
+TBool CWAPISecuritySettingsDlg::UpdateFromPopupSettingPage( TWapiMember aData,
+                                                            TInt aCurrvalue )
+    {
+    #if defined( _DEBUG ) || defined( DEBUG )
+    RDebug::Print(_L("CWAPISecuritySettingsImpl::UpdateFromPopupSettingPage, aCurrvalue = %d"), aCurrvalue );
+    #endif
+    
+    TInt certIndex;
+    TBool retVal( EFalse );
+
+    switch ( aData )
+        {
+        case EWapiUserCert:
+            {
+            //Fetch the current certificate in use
+            iSecuritySettings->GetUserCertInUse( certIndex );
+            
+            if ( certIndex != aCurrvalue )
+                {
+                iSecuritySettings->SetUserCertInUse( aCurrvalue );
+                retVal = ETrue;
+                }
+            break;
+            }
+
+        case EWapiCACert:
+            {
+            //Fetch the current certificate in use
+            iSecuritySettings->GetCACertInUse( certIndex );
+            
+            if ( certIndex != aCurrvalue )
+                {
+                iSecuritySettings->SetCACertInUse( aCurrvalue );
+                retVal = ETrue;
+                }
+             break;
+  
+            }
+
+        default:
+            {
+            __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) );
+            break;
+            }
+        }
+    return retVal;
+    }
+
+
+//----------------------------------------------------------
+// CWAPISecuritySettingsDlg::ChangeSettingsL
+//----------------------------------------------------------
+//
+void CWAPISecuritySettingsDlg::ChangeSettingsL()
+    {
+    TInt itemIndex = Max( iList->CurrentItemIndex(), 0 );
+    TWapiMember* ptr = iFieldsMain + itemIndex;
+    TInt* tptr = iTitlesMain + itemIndex;
+
+    switch ( *ptr )
+        {
+        case EWapiAuth:
+            {
+            if (iSecuritySettings->GetAuthentication() == EWapiAuthCert)
+                {
+                iSecuritySettings->SetAuthentication( EWapiAuthPSK );
+                iFieldsMain = ( TWapiMember* ) KFields_Wapi_Main_PSK;
+                iTitlesMain = MUTABLE_CAST( TInt*, KTitles_Wapi_Main_PSK );
+                }
+            else // ... == EWapiAuthPSK
+                {
+                iSecuritySettings->SetAuthentication( EWapiAuthCert );
+                iFieldsMain = ( TWapiMember* ) KFields_Wapi_Main_Cert;
+                iTitlesMain = MUTABLE_CAST( TInt*, KTitles_Wapi_Main_Cert );
+                }
+            HandleListboxDataChangeL();
+            *iEventStore |= CWAPISecuritySettings::EModified;
+            break;
+            }
+        case EWapiCACert:
+        case EWapiUserCert:
+            {
+            if ( ShowPopupSettingPageL( *ptr ) )
+                {
+                UpdateListBoxItemL( *ptr, *tptr, itemIndex );
+                *iEventStore |= CWAPISecuritySettings::EModified;
+                }
+            break;
+            }
+        case EWapiPSKFormat:
+            {
+            if (iSecuritySettings->GetKeyFormat() == CWAPISecuritySettings::EWapiKeyAscii)
+                {
+                iSecuritySettings->SetKeyFormat(CWAPISecuritySettings::EWapiKeyHex);
+                }
+            else // ... == EWapiKeyHex
+                {
+                iSecuritySettings->SetKeyFormat(CWAPISecuritySettings::EWapiKeyAscii);
+                }
+            UpdateListBoxItemL( *ptr, *tptr, itemIndex );
+            *iEventStore |= CWAPISecuritySettings::EModified;
+            break;
+            }
+        case EWapiPSK:
+            {
+            if ( ShowPopupPSKSettingPageL())
+                {
+                UpdateListBoxItemL(*ptr, *tptr, itemIndex);
+                *iEventStore |= CWAPISecuritySettings::EModified;
+                }
+            break;
+            }
+        default:
+            {
+            __ASSERT_DEBUG( EFalse, Panic( EUnknownCase ) );
+            break;
+            }
+        }
+        
+    iList->ScrollToMakeItemVisible( itemIndex );
+    iList->SetCurrentItemIndexAndDraw( itemIndex );
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsDlg::GetHelpContext
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsDlg::GetHelpContext( TCoeHelpContext& aContext ) const
+    {
+    aContext.iMajor = KWAPISecuritySettingsUiHelpMajor;
+    aContext.iContext = KSET_HLP_WLAN_WAPI_MAIN;
+    
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettingsimpl.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,602 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsimpl.cpp 
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*      Implementation of class CWAPISecuritySettingsImpl.   
+*      
+*  Version: %version:  13.1.2 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+// INCLUDE FILES
+
+#include "wapisecuritysettingsimpl.h"
+#include "wapisecuritysettingsuipanic.h"
+#include "wapisecuritysettingsui.h"
+
+#include <featmgr.h>
+#include <cmdestinationext.h>
+#include <cmmanagerext.h>
+
+#include <wlancontainer.h>
+
+// CONSTANT DECLARATIONS
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::NewL
+// ---------------------------------------------------------
+//
+CWAPISecuritySettingsImpl* CWAPISecuritySettingsImpl::NewL()
+    {
+    CWAPISecuritySettingsImpl* settings = 
+                                    new ( ELeave ) CWAPISecuritySettingsImpl();
+    CleanupStack::PushL( settings );
+    settings->ConstructL();
+    CleanupStack::Pop( settings ); 
+    return settings;    
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::CWAPISecuritySettingsImpl
+// ---------------------------------------------------------
+//
+CWAPISecuritySettingsImpl::CWAPISecuritySettingsImpl()
+    {
+    iUserCertInUse = KCertNone;
+    iCACertInUse = KCertNone;
+    iCertificatesLoaded = EFalse;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::ConstructL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsImpl::ConstructL()
+    {
+    iCertificateStore =  CWapiCertificates::NewL(); 
+    
+    #if defined( _DEBUG ) || defined( DEBUG )
+    RDebug::Print(_L("CWAPISecuritySettingsImpl::ConstructL, iCertificateStore created.") );
+    #endif
+
+    FeatureManager::InitializeLibL();
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::~CWAPISecuritySettingsImpl
+// ---------------------------------------------------------
+//
+CWAPISecuritySettingsImpl::~CWAPISecuritySettingsImpl()
+    {
+    if (iUserCertificates)
+        {
+        iUserCertificates->Close();
+        delete iUserCertificates;
+        }
+    if (iUserCertificateData)
+        {
+        iUserCertificateData->Close();
+        delete iUserCertificateData;
+        }
+
+    if (iCACertificates)
+       {
+       iCACertificates->Close();
+       delete iCACertificates;
+       }
+    if (iCACertificateData)
+        {
+        iCACertificateData->Close();
+        delete iCACertificateData;
+        }
+
+    delete iCertificateStore;
+
+    FeatureManager::UnInitializeLib();
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::LoadL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsImpl::LoadL( TUint32 aIapRecordId, CMDBSession& aSession )
+    {
+    CCDIAPRecord *iapRecord = static_cast<CCDIAPRecord *>
+                            (CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord));
+                            
+    CleanupStack::PushL( iapRecord );
+    
+    iapRecord->SetRecordId( aIapRecordId );
+    
+    iapRecord->LoadL( aSession );
+    
+    TUint32 wlanServiceId = iapRecord->iService;
+    
+    CleanupStack::PopAndDestroy(iapRecord);
+    
+    #if defined( _DEBUG ) || defined( DEBUG )
+    RDebug::Print(_L("CWAPISecuritySettingsImpl::LoadL, aIapId = %d, wlanServiceId = %d"),
+            aIapRecordId, wlanServiceId );
+    #endif
+    
+    if ( wlanServiceId == KUidNone )
+        {
+        return;
+        }
+    
+    // search for the record    
+    CMDBGenericRecord* generic = static_cast<CMDBGenericRecord*>( 
+                                          CCDRecordBase::RecordFactoryL( 0 ) );
+    CleanupStack::PushL( generic );    
+    generic->InitializeL( TPtrC( WLAN_SERVICE ), NULL );
+    generic->LoadL( aSession );
+    
+    CMDBField<TUint32>* sidField = static_cast<CMDBField<TUint32>*>
+                             ( generic->GetFieldByIdL( KCDTIdWlanServiceId ) );
+    
+    // prime with service id                
+    *sidField = wlanServiceId;
+    
+    if (generic->FindL( aSession ))
+        {
+        // Get authentication
+        CMDBField<TUint>* enableWpaPskField = static_cast<CMDBField<TUint>*>
+                          ( generic->GetFieldByIdL( KCDTIdWlanEnableWpaPsk ) );
+        iWapiAuth = (*enableWpaPskField == 0 ) ? EWapiAuthCert : EWapiAuthPSK;
+
+        // Get preshared key format
+        CMDBField<CWAPISecuritySettings::TWapiKeyFormat>* wapiPskFormat = static_cast<CMDBField<CWAPISecuritySettings::TWapiKeyFormat>*>
+                       ( generic->GetFieldByIdL( KCDTIdWlanFormatKey1 ) );
+        iWapiKeyFormat = *wapiPskFormat;
+
+        // Get preshared key
+        CMDBField<TDesC8>* wpaPskField = static_cast<CMDBField<TDesC8>*>
+                       ( generic->GetFieldByIdL( KCDTIdWlanWpaPreSharedKey ) );
+        iWapiPSKKey = *wpaPskField;
+        
+        iWapiPSKKeySet = IsValidPsk(iWapiPSKKey);
+        }
+   
+    // Save aIapRecordId for later certificate loading.
+    iWlanServiceId = wlanServiceId;
+    
+    CleanupStack::PopAndDestroy( generic );
+   
+    }
+    
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::SaveL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsImpl::SaveL( TUint32 aIapRecordId, CMDBSession& aSession  ) const
+    {
+
+    CCDIAPRecord *iapRecord = static_cast<CCDIAPRecord *>
+                            (CCDRecordBase::RecordFactoryL(KCDTIdIAPRecord));
+                            
+    CleanupStack::PushL( iapRecord );
+    
+    iapRecord->SetRecordId( aIapRecordId );
+    
+    iapRecord->LoadL( aSession );
+    
+    TUint32 wlanServiceId = iapRecord->iService;
+
+    CleanupStack::PopAndDestroy(iapRecord);   
+    #if defined( _DEBUG ) || defined( DEBUG )
+    RDebug::Print(_L("CWAPISecuritySettingsImpl::SaveL, iapRecordId = %d, wlanServiceId = %d"),
+            aIapRecordId, wlanServiceId );
+    #endif
+
+    // Load WLAN service table
+    // first get WLAN table id
+    CMDBGenericRecord* generic = static_cast<CMDBGenericRecord*>
+        ( CCDRecordBase::RecordFactoryL( 0 ) );
+    CleanupStack::PushL( generic );    
+    generic->InitializeL( TPtrC( WLAN_SERVICE ), NULL );
+    generic->LoadL( aSession );
+    TMDBElementId wlanTableId = generic->TableId();
+    
+    CMDBField<TUint32>* sidField = static_cast<CMDBField<TUint32>*>
+                             ( generic->GetFieldByIdL( KCDTIdWlanServiceId ) );
+    
+    // prime with service id                
+    *sidField = wlanServiceId;
+
+    TBool found = generic->FindL( aSession);
+   
+    // If loading failed, WLAN service record will be 
+    // created and StoreL()-d, otherwise, ModifyL()
+    
+    // Set WPA mode
+    CMDBField<TUint>* enableWpaPskField = static_cast<CMDBField<TUint>*>
+                          ( generic->GetFieldByIdL( KCDTIdWlanEnableWpaPsk ) );
+    enableWpaPskField->SetL( iWapiAuth == EWapiAuthPSK ? 1 : 0 );
+    
+    if (iWapiAuth == EWapiAuthPSK)
+        {
+        if (iWapiPSKKeySet)
+            {
+
+            // Save PreShared Key format
+            CMDBField<TUint>* keyFormat = static_cast<CMDBField<TUint>*>
+                                ( generic->GetFieldByIdL( KCDTIdWlanFormatKey1 ) );
+            keyFormat->SetL( iWapiKeyFormat );
+            
+            // Save PreShared Key
+            CMDBField<TDesC8>* wapiPskField = static_cast<CMDBField<TDesC8>*>
+                               ( generic->GetFieldByIdL( KCDTIdWlanWpaPreSharedKey ) );
+            wapiPskField->SetL( iWapiPSKKey );
+    
+            // Save PreShared Key length
+            CMDBField<TUint>* keyLengthField = static_cast<CMDBField<TUint>*>
+                                ( generic->GetFieldByIdL( KCDTIdWlanWpaKeyLength ) );
+            keyLengthField->SetL( iWapiPSKKey.Length() );
+            }
+        }
+    // If certificates have not been loaded, i*CertInUse doesn't contain right values
+    else if ( iCertificateStore && iCertificatesLoaded != EFalse)
+        {
+        #if defined( _DEBUG ) || defined( DEBUG )
+        RDebug::Print(_L("Saving user cert index %d"), iUserCertInUse );
+        RDebug::Print(_L("Saving CA cert index %d"), iCACertInUse );
+        #endif  
+        
+        // "none" is communicated to wapicertificates as zero length identity
+        TBuf8<KMaxIdentityLength> certNone;
+        certNone.Zero();
+
+        if (iUserCertInUse == KCertNone)
+            {
+            iCertificateStore->SetUserCertL( wlanServiceId, certNone);
+            }
+        else
+            {
+            iCertificateStore->SetUserCertL( wlanServiceId, (*iUserCertificateData)[iUserCertInUse]);
+            }
+         
+        if (iCACertInUse == KCertNone)
+            {
+            iCertificateStore->SetCACertL( wlanServiceId, certNone);
+            }
+        else
+            {
+            iCertificateStore->SetCACertL( wlanServiceId, (*iCACertificateData)[iCACertInUse]);
+            }
+        }
+    // Saving changes
+    if ( !found )
+        {
+        // there wasn't any wlan service record, we have to create it now
+        generic->SetRecordId( KCDNewRecordRequest );
+        generic->StoreL( aSession );
+        }
+    else
+        {
+        // modify existing record
+        generic->ModifyL( aSession );
+        }
+        
+    CleanupStack::PopAndDestroy( generic );
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::SetPreSharedKeyL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsImpl::SetPreSharedKeyL( const CWAPISecuritySettings::TWapiKeyFormat aKeyFormat, const TDesC& aPreSharedKey )
+    {
+    HBufC8* buf8 = HBufC8::NewL( aPreSharedKey.Length() );
+    
+    TPtr8 pskPtr( buf8->Des() );
+    pskPtr.Copy( aPreSharedKey ); 
+
+    if ( !IsValidPsk( aKeyFormat, pskPtr ) )
+        {
+        delete buf8;
+        User::Leave(KErrArgument);
+        }
+    
+    SetAuthentication(EWapiAuthPSK);
+    SetKeyFormat( aKeyFormat );
+    SetWapiPSKKeyL( aPreSharedKey );
+
+    delete buf8;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::ResetCertificateStoreL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsImpl::ResetCertificateStoreL()
+    {
+    if ( iCertificateStore )
+        {
+        iCertificateStore->ResetCertificateStoreL();
+            
+        //Certificate store was reseted. Set certificates in use to "None" and
+        //Close RARRAY's
+        iUserCertInUse = KCertNone;
+        iCACertInUse = KCertNone;
+
+        // Reload certificate data: delete old and load new ones.
+        if (iUserCertificates)
+            {
+            iUserCertificates->Close();
+            delete iUserCertificates;
+            iUserCertificates = NULL;
+            }
+        if (iUserCertificateData)
+            {
+            iUserCertificateData->Close();
+            delete iUserCertificateData;
+            iUserCertificateData = NULL;
+            }
+        
+        if (iCACertificates)
+            {
+            iCACertificates->Close();
+            delete iCACertificates;
+            iCACertificates = NULL;
+            }
+        if (iCACertificateData)
+            {
+            iCACertificateData->Close();
+            delete iCACertificateData;
+            iCACertificateData = NULL;
+            }
+        
+        iCertificateStore->GetAllCertificateLabelsL(
+                &iUserCertificates, &iUserCertificateData,
+                &iCACertificates, &iCACertificateData);
+        }
+    }
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::LoadCertificatesL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsImpl::LoadCertificatesL()
+    {
+    #if defined( _DEBUG ) || defined( DEBUG )
+    RDebug::Print(_L("LoadCertificatesL()"));
+    #endif
+
+    if ( iCertificateStore && iCertificatesLoaded == EFalse)
+        {
+        iCertificateStore->GetAllCertificateLabelsL(
+                &iUserCertificates, &iUserCertificateData,
+                &iCACertificates, &iCACertificateData);
+       
+        //Define local variables for certificate labels
+        TBuf<KMaxLabelLength>               userCertLabel;
+        TBuf<KMaxLabelLength>               CACertLabel;
+        
+        //Fetch configuration from EAPOL
+        iCertificateStore->GetConfigurationL( 
+                                    iWlanServiceId, CACertLabel, userCertLabel );
+    
+        #if defined( _DEBUG ) || defined( DEBUG )
+        RDebug::Print(_L("CWAPISecuritySettingsImpl::LoadL, iWlanServiceId = %d"), iWlanServiceId );
+        RDebug::Print(_L("CWAPISecuritySettingsImpl::LoadL, CACertLabel = %S"), &CACertLabel );
+        RDebug::Print(_L("CWAPISecuritySettingsImpl::LoadL, userCertLabel = %S"), &userCertLabel );
+        #endif
+    
+        //Fetch matching indexes
+        iUserCertInUse = GetIndexByCertLabel(iUserCertificates, userCertLabel);
+        iCACertInUse = GetIndexByCertLabel(iCACertificates, CACertLabel);
+        
+        #if defined( _DEBUG ) || defined( DEBUG )
+        RDebug::Print(_L("iUserCertInUse = %d"), iUserCertInUse );
+        RDebug::Print(_L("iCACertInUse = %d"), iCACertInUse );
+        #endif
+        
+        // Don't load certificates again because it resets made configuration changes too.
+        iCertificatesLoaded = ETrue;
+        }
+    }
+
+
+//------------------------------------------------------------------------------
+// CWAPISecuritySettingsImpl::DeleteAPSpecificDataL
+//------------------------------------------------------------------------------
+//
+void CWAPISecuritySettingsImpl::DeleteAPSpecificDataL( const TInt aId )
+    {
+    if ( iCertificateStore )
+        {
+        iCertificateStore->DeleteAPSpecificDataL( aId );
+        }
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::GetIndexByCertLabel
+// ---------------------------------------------------------
+//
+TInt CWAPISecuritySettingsImpl::GetIndexByCertLabel( 
+                            RArray<TBuf<KMaxLabelLength> >* aCertificates, 
+                            const TDesC& aCert )
+    {
+    if ( aCertificates )
+        {
+        for ( TInt i = 0; i < aCertificates->Count(); i++ )
+            {
+            if ( aCert.Compare((*aCertificates)[i])== 0 ) //Compare returns zero
+                                                        //when result is matching
+                {
+                return i;
+                }
+            }
+        }
+    return KCertNone; // if certificate is not found return zero index
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::GetAuthentication
+// ---------------------------------------------------------
+//
+TWapiAuth CWAPISecuritySettingsImpl::GetAuthentication( )
+    {
+    return iWapiAuth;
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::SetAuthentication
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsImpl::SetAuthentication( TWapiAuth aWapiAuth )
+    {
+    iWapiAuth = aWapiAuth;
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::GetKeyFormat
+// ---------------------------------------------------------
+//
+CWAPISecuritySettings::TWapiKeyFormat CWAPISecuritySettingsImpl::GetKeyFormat()
+    {
+    return iWapiKeyFormat;
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::SetKeyFormat
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsImpl::SetKeyFormat( CWAPISecuritySettings::TWapiKeyFormat aWapiKeyFormat )
+    {
+    iWapiKeyFormat = aWapiKeyFormat;
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::GetWapiPSKKey
+// ---------------------------------------------------------
+//
+TBool CWAPISecuritySettingsImpl::hasWapiPSKKey()
+    {
+    return iWapiPSKKeySet;
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::SetWapiPSKKey
+// ---------------------------------------------------------
+//
+TInt CWAPISecuritySettingsImpl::SetWapiPSKKeyL( const TDesC& aWapiPSKKey )
+    {
+    TInt ret( KErrNone );
+    
+    #if defined( _DEBUG ) || defined( DEBUG )
+    RDebug::Print(_L("CWAPISecuritySettingsImpl::SetWapiPSKKeyL te"));
+    #endif
+    
+    HBufC8* buf8 = HBufC8::NewL( aWapiPSKKey.Length() );
+    
+    if ( buf8 )
+        {
+        TPtr8 pskPtr( buf8->Des() );
+        pskPtr.Copy( aWapiPSKKey ); 
+
+        if (IsValidPsk(pskPtr))
+            {
+            iWapiPSKKeySet = ETrue;
+            iWapiPSKKey = pskPtr;
+            iWapiAuth = EWapiAuthPSK;
+            }
+        else
+            {
+            ret = KErrArgument;
+            }
+        delete buf8;
+        }
+    else
+        {
+        ret = KErrNoMemory;
+        }
+    
+    return ret;
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::IsValidPsk
+// ---------------------------------------------------------
+//
+TBool CWAPISecuritySettingsImpl::IsValidPsk( const TDesC8& aPsk )
+    {
+    return IsValidPsk(iWapiKeyFormat, aPsk);
+    }
+
+TBool CWAPISecuritySettingsImpl::IsValidPsk(
+        const CWAPISecuritySettings::TWapiKeyFormat aWapiKeyFormat,
+        const TDesC8& aPsk )
+    {
+    TBool ret( EFalse );
+    
+    TInt len = aPsk.Length();
+    ret = (len >= 1 && len <= KWapiMaxKeyLength );
+    
+    if (ret && (aWapiKeyFormat == CWAPISecuritySettings::EWapiKeyHex))
+        {
+        ret = !(len % 2);   // Must be even length
+        if (ret)
+            {
+            // Check contents
+            for ( TInt i = 0; i < len; ++i )
+                {
+                TChar ch( aPsk[i] );
+                if ( !ch.IsHexDigit() )
+                    {
+                    // Got a bad character
+                    ret = EFalse;
+                    break;
+                    }
+                }
+            }
+        }
+    
+    return ret;
+
+    }
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsImpl::Valid
+// ---------------------------------------------------------
+//
+TBool CWAPISecuritySettingsImpl::IsValid( )
+    {
+    TBool ret( EFalse );
+
+    if (iWapiAuth == EWapiAuthPSK)
+        {
+        // Pre-shared key is compulsory.
+        ret = iWapiPSKKeySet;
+        }
+    else // ... == EWapiAuthCert
+        {
+        // Always valid.
+        ret = ETrue;
+        }
+    return ret;
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettingsui.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,57 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsui.cpp
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*      Implementation of class CWAPISecuritySettingsUi.
+*
+*  Version: %version:  3 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+// INCLUDE FILES
+#include <wapisecuritysettingsui.h>
+
+#include "wapisecuritysettingsuiimpl.h"
+
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsUi::NewLC
+// ---------------------------------------------------------
+//
+EXPORT_C CWAPISecuritySettingsUi* CWAPISecuritySettingsUi::NewL( 
+                                                        CEikonEnv& aEikEnv )
+    {
+    CWAPISecuritySettingsUi* secSett = new( ELeave ) CWAPISecuritySettingsUi();
+    CleanupStack::PushL( secSett );
+    secSett->iImpl = CWAPISecuritySettingsUiImpl::NewL( aEikEnv );
+    CleanupStack::Pop( secSett );
+    return secSett;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsUi::~CWAPISecuritySettingsUi
+// ---------------------------------------------------------
+//
+EXPORT_C CWAPISecuritySettingsUi::~CWAPISecuritySettingsUi()
+    {
+    delete iImpl;
+    }
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettingsuiimpl.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,121 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsuiimpl
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*      Implementation of class CWAPISecuritySettingsUiImpl.
+*  Version: %version:  4 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+// INCLUDE FILES
+#include <bautils.h>
+#include <wapisecuritysettingsui.h>
+
+#include <data_caging_path_literals.hrh>
+
+#include "wapisecuritysettingsuiimpl.h"
+#include "wapisecuritysettingsimpl.h"
+#include "wapisecuritysettingsdlg.h"
+
+
+// CONSTANTS
+_LIT( KDriveZ, "z:" );                                      // ROM folder
+_LIT( KResourceFileName, "wapisecuritysettingsui.rsc" );     // RSC file name.
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsUiImpl::NewL
+// ---------------------------------------------------------
+//
+CWAPISecuritySettingsUiImpl* CWAPISecuritySettingsUiImpl::NewL( 
+                                                        CEikonEnv& aEikEnv )
+    {
+    CWAPISecuritySettingsUiImpl* uiImpl = 
+                        new( ELeave ) CWAPISecuritySettingsUiImpl( aEikEnv );
+    CleanupStack::PushL( uiImpl );
+    uiImpl->ConstructL();
+    CleanupStack::Pop( uiImpl );
+    return uiImpl;
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsUiImpl::CWAPISecuritySettingsUiImpl
+// ---------------------------------------------------------
+//
+CWAPISecuritySettingsUiImpl::CWAPISecuritySettingsUiImpl( CEikonEnv& aEikEnv )
+: iEventStore( ENone ), 
+  iEikEnv( &aEikEnv )
+    {
+    }
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsUiImpl::~CWAPISecuritySettingsUiImpl
+// ---------------------------------------------------------
+//
+CWAPISecuritySettingsUiImpl::~CWAPISecuritySettingsUiImpl()
+    {
+    if ( iResOffset )
+        {
+        iEikEnv->DeleteResourceFile( iResOffset );
+        }
+    }
+
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsUiImpl::ConstructL
+// ---------------------------------------------------------
+//
+void CWAPISecuritySettingsUiImpl::ConstructL()
+    {
+    TFileName fileName;
+
+    fileName.Append( KDriveZ );
+    fileName.Append( KDC_RESOURCE_FILES_DIR );
+    fileName.Append( KResourceFileName );
+
+    BaflUtils::NearestLanguageFile( iEikEnv->FsSession(), fileName );
+    iResOffset = iEikEnv->AddResourceFileL( fileName );
+    }
+
+
+
+// ---------------------------------------------------------
+// CWAPISecuritySettingsUiImpl::EditL
+// ---------------------------------------------------------
+//
+TInt CWAPISecuritySettingsUiImpl::EditL( CWAPISecuritySettingsImpl& aSettings,
+                                        const TDesC& aTitle )
+    {
+    iEventStore = ENone;
+    
+    aSettings.LoadCertificatesL();
+    
+    CWAPISecuritySettingsDlg* secSettDlg = 
+                                CWAPISecuritySettingsDlg::NewL( iEventStore );
+    
+    
+    secSettDlg->ConstructAndRunLD( &aSettings, aTitle );
+
+    return iEventStore;
+    }
+
+
+// End of File
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlansecuritysettings/wapisecuritysettingsui/src/wapisecuritysettingsuipanic.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -0,0 +1,44 @@
+/*
+* ============================================================================
+*  Name     : wapisecuritysettingsuipanic.cpp 
+*  Part of  : WAPI Security Settings UI
+*
+*  Description:
+*      Implementation of panic function.   
+*      
+*  Version: %version:  3 %
+*
+*  Copyright (C) 2008 Nokia Corporation.
+*  This material, including documentation and any related 
+*  computer programs, is protected by copyright controlled by 
+*  Nokia Corporation. All rights are reserved. Copying, 
+*  including reproducing, storing,  adapting or translating, any 
+*  or all of this material requires the prior written consent of 
+*  Nokia Corporation. This material also contains confidential 
+*  information which may not be disclosed to others without the 
+*  prior written consent of Nokia Corporation.
+*
+* ============================================================================
+*/
+
+// INCLUDE FILES
+
+#include <e32std.h>
+
+#include "wapisecuritysettingsuipanic.h"
+
+
+// ================= LOCAL FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// Panic()
+// ---------------------------------------------------------
+//
+void Panic( TWapiSecuritySettingsPanicCodes aPanic )
+    {
+    _LIT( KWapiSet, "wapisecuritysettingsui" );
+    User::Panic( KWapiSet, aPanic );
+    }
+
+
+// End of File
--- a/wlansecuritysettings/wepsecuritysettingsui/group/wepsecuritysettingsuistub.mmp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wepsecuritysettingsui/group/wepsecuritysettingsuistub.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -17,7 +17,7 @@
 */
 
 /*
-* %version: 3 %
+* %version: 6 %
 */
 
 #include <data_caging_paths.hrh>
@@ -43,9 +43,9 @@
 LIBRARY euser.lib
 
 #if defined( WINSCW )
-    DEFFILE ../BWinsCw/WEPSecuritySettingsUI_EKA2_ALR.def
+    DEFFILE ../bwinscw/WEPSecuritySettingsUI_EKA2_ALR.def
 #else
-    DEFFILE ../EABI/WEPSecuritySettingsUI_EKA2_ALR.def
+    DEFFILE ../eabi/WEPSecuritySettingsUI_EKA2_ALR.def
 #endif
 
 // End of File
--- a/wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsDlg.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsDlg.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: tr1cfwln#8.1.21 %
+* %version: tr1cfwln#8.1.22 %
 */
 
 // INCLUDE FILES
@@ -42,7 +42,7 @@
 #include <hlplch.h>
 #include <csxhelp/cp.hlp.hrh>
 
-#include <FeatMgr.h>
+#include <featmgr.h>
 
 
 // CONSTANT DECLARATIONS
--- a/wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsImpl.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wepsecuritysettingsui/src/WEPSecuritySettingsImpl.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: tr1cfwln#25 %
+* %version: tr1cfwln#26 %
 */
 
 // INCLUDE FILES
@@ -26,7 +26,7 @@
 
 #include <WEPSecuritySettingsUI.h>
 #include <commdb.h>
-#include <FeatMgr.h>
+#include <featmgr.h>
 #include <WlanCdbCols.h>
 
 #include <commsdattypesv1_1.h>
--- a/wlansecuritysettings/wepsecuritysettingsui/src/wepsecuritysettingsstub.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wepsecuritysettingsui/src/wepsecuritysettingsstub.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -17,12 +17,12 @@
 */
 
 /*
-* %version: 2 %
+* %version: 3 %
 */
 
 // INCLUDE FILES
 
-#include <WEPSecuritySettingsUi.h>
+#include <WEPSecuritySettingsUI.h>
 
 
 
--- a/wlansecuritysettings/wepsecuritysettingsui/src/wepsecuritysettingsuistub.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wepsecuritysettingsui/src/wepsecuritysettingsuistub.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -17,12 +17,12 @@
 */
 
 /*
-* %version: 2 %
+* %version: 3 %
 */
 
 // INCLUDE FILES
 
-#include <WEPSecuritySettingsUi.h>
+#include <WEPSecuritySettingsUI.h>
 
 
 
--- a/wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotactiverunner.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wifiprotectedsetup/pluginsrc/wifiprotactiverunner.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: tr1cfwln#28 %
+* %version: tr1cfwln#29 %
 */
 
 //SYSTEM INCLUDES
@@ -52,7 +52,7 @@
 #include "wifiprotenterpindlg.h"
 #include "wifiprotinitiateeasysetupdlg.h"
 
-#include "FeatMgr.h"
+#include "featmgr.h"
 
 // valid Wep key lengths, to check wep key format
 // (wep key format depends on key length)
--- a/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUi.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUi.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,13 +16,13 @@
 */
 
 /*
-* %version: 14 %
+* %version: 15 %
 */
 
 // INCLUDE FILES
 #include "EapAkaUi.h"
 #include "EapAkaUiView.h"
-#include <EapAkaUi.rsg>
+#include <eapakaui.rsg>
 #include <bautils.h>
 #include <coemain.h>
 #include <aknnotewrappers.h>
--- a/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUiView.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapAka/ConfigUi/src/EapAkaUiView.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 28 %
+* %version: 29 %
 */
 
 // INCLUDE FILES
@@ -25,7 +25,7 @@
 #include <aknlists.h>
 #include "EapAkaUiView.h"
 #include "EapAkaUi.hrh"
-#include <EapAkaUi.rsg>
+#include <eapakaui.rsg>
 #include <akntextsettingpage.h>
 #include <aknsettingitemlist.h>
 #include "EapAkaUiSettingArray.h"
@@ -33,7 +33,7 @@
 #include <EapAkaUiDataConnection.h>
 #include <EapAkaUiAkaData.h> 
 
-#include <FeatMgr.h>
+#include <featmgr.h>
 #include <hlplch.h>
 #include <csxhelp/cp.hlp.hrh>
 
--- a/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUi.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUi.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,12 +16,12 @@
 */
 
 /*
-* %version: 14 %
+* %version: 15 %
 */
 
 // INCLUDE FILES
 #include <EapGtcUiConnection.h>
-#include <EapGtcUi.rsg>
+#include <eapgtcui.rsg>
 #include <bautils.h>
 #include <coemain.h>
 #include <aknnotewrappers.h>
--- a/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUiView.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/ConfigUi/src/EapGtcUiView.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,14 +16,14 @@
 */
 
 /*
-* %version: 27 %
+* %version: 28 %
 */
 
 // INCLUDE FILES
 #include <eikdialg.h>
 #include <AknDialog.h>
 #include <aknlists.h>
-#include <EapGtcUi.rsg>
+#include <eapgtcui.rsg>
 #include <akntextsettingpage.h>
 #include <aknsettingitemlist.h>
 #include <aknnavide.h>
@@ -36,7 +36,7 @@
 #include "EapGtcUi.hrh"
 #include "EapGtcUiSettingArray.h"
 
-#include <FeatMgr.h>
+#include <featmgr.h>
 #include <hlplch.h>
 #include <csxhelp/cp.hlp.hrh>
 
--- a/wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/src/GtcNotifDlgPlugin.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapGtc/NotifierUi/src/GtcNotifDlgPlugin.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 12.1.8 %
+* %version: 12.1.9 %
 */
 
 // INCLUDE FILES
@@ -24,7 +24,7 @@
 #include <eikenv.h>
 #include <bautils.h>
 #include <data_caging_path_literals.hrh>
-#include <GtcNotifDlgUi.rsg>
+#include <gtcnotifdlgui.rsg>
 #include <e32base.h>
 #include <StringLoader.h>
 
--- a/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2Ui.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2Ui.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,14 +16,14 @@
 */
 
 /*
-* %version: 15 %
+* %version: 16 %
 */
 
 // INCLUDE FILES
 #include "EapMschapv2Ui.h"
 #include <EapMsChapV2UiConnection.h>
 #include "EapMschapv2UiView.h"
-#include <EapMschapv2Ui.rsg>
+#include <eapmschapv2ui.rsg>
 #include <bautils.h>
 #include <coemain.h>
 #include <aknnotewrappers.h>
--- a/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2UiView.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/ConfigUi/src/EapMschapv2UiView.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 28 %
+* %version: 29 %
 */
 
 // INCLUDE FILES
@@ -25,7 +25,7 @@
 #include <aknlists.h>
 #include "EapMschapv2UiView.h"
 #include "EapMschapv2Ui.hrh"
-#include <EapMschapv2Ui.rsg>
+#include <eapmschapv2ui.rsg>
 #include <akntextsettingpage.h>
 #include <aknsettingitemlist.h>
 #include "EapMschapv2UiSettingArray.h"
@@ -35,7 +35,7 @@
 #include <EapMsChapV2UiDataConnection.h>
 #include <EapMsChapV2UiMsChapV2Data.h>
 
-#include <FeatMgr.h>
+#include <featmgr.h>
 #include <hlplch.h>
 #include <csxhelp/cp.hlp.hrh>
 
--- a/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/src/MsChapv2NotifDialog.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/src/MsChapv2NotifDialog.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,11 +16,11 @@
 */
 
 /*
-* %version: 17 %
+* %version: 18 %
 */
 
 // INCLUDE FILES
-#include <MsChapv2NotifDlgUi.rsg>
+#include <mschapv2notifdlgui.rsg>
 #include "MsChapv2NotifDlgPlugin.h"
 #include "MsChapv2NotifDialog.h"
 
--- a/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/src/MsChapv2NotifDlgPlugin.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapMschapv2/NotifierUi/src/MsChapv2NotifDlgPlugin.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 12.1.7 %
+* %version: 12.1.8 %
 */
 
 // INCLUDE FILES
@@ -24,7 +24,7 @@
 #include <eikenv.h>
 #include <bautils.h>
 #include <data_caging_path_literals.hrh>
-#include <MsChapv2NotifDlgUi.rsg>
+#include <mschapv2notifdlgui.rsg>
 
 #include <e32property.h>		// For RProperty 
 #include <UikonInternalPSKeys.h> // For KPSUidUikon and KUikGlobalNotesAllowed.
--- a/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUi.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUi.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,14 +16,14 @@
 */
 
 /*
-* %version: 14 %
+* %version: 15 %
 */
 
 // INCLUDE FILES
 #include "EapPeapUi.h"
 #include "EapTlsPeapUiConnection.h"
 #include "EapPeapUiView.h"
-#include <EapPeapUi.rsg>
+#include <eappeapui.rsg>
 #include <bautils.h>
 #include <coemain.h>
 #include <aknnotewrappers.h>
--- a/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUiView.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapPeap/ConfigUi/src/EapPeapUiView.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 37.1.7 %
+* %version: 37.1.8 %
 */
 
 // INCLUDE FILES
@@ -25,7 +25,7 @@
 #include <aknlists.h>
 #include "EapPeapUiView.h"
 #include "EapPeapUi.hrh"
-#include <EapPeapUi.rsg>
+#include <eappeapui.rsg>
 #include <akntextsettingpage.h>
 #include <aknsettingitemlist.h>
 #include "EapPeapUiSettingArray.h"
@@ -45,7 +45,7 @@
 #include <EapTypeInfo.h> // For EAP type info query
 #include <AknIconArray.h>
 #include <AknsUtils.h>
-#include <FeatMgr.h>
+#include <featmgr.h>
 #include <hlplch.h>
 #include <csxhelp/cp.hlp.hrh>
 
--- a/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPlugInConfigurationDlg.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPlugInConfigurationDlg.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 20.1.14 %
+* %version: 20.1.15 %
 */
 
 // INCLUDE FILES
@@ -29,7 +29,7 @@
 #include <aknnotewrappers.h>
 #include <EapType.h>
 
-#include <EAPPluginConfigRes.rsg>
+#include <eappluginconfigres.rsg>
 #include "EAPPluginConfig.hrh"
 
 #include <avkon.mbg>
@@ -39,7 +39,7 @@
 #include "EAPPluginConfigurationModel.h"
 
 
-#include <FeatMgr.h>
+#include <featmgr.h>
 #include <hlplch.h>
 #include <eikappui.h>
 #include <csxhelp/cp.hlp.hrh>
--- a/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPluginConfiguration.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapPluginConfig/src/EAPPluginConfiguration.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 23 %
+* %version: 24 %
 */
 
 // INCLUDE FILES
@@ -29,7 +29,7 @@
 
 #include <ecom/ecom.h>
 #include <data_caging_path_literals.hrh>
-#include <EAPPluginConfigRes.rsg>
+#include <eappluginconfigres.rsg>
 
 // CONSTANTS
 _LIT( KDriveZ, "z:" );                               // ROM folder
--- a/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUi.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUi.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,14 +16,14 @@
 */
 
 /*
-* %version: 14 %
+* %version: 15 %
 */
 
 // INCLUDE FILES
 #include "EapSimUi.h"
 #include <EapSimUiConnection.h>
 #include "EapSimUiView.h"
-#include <EapSimUi.rsg>
+#include <eapsimui.rsg>
 #include <bautils.h>
 #include <coemain.h>
 #include <aknnotewrappers.h>
--- a/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUiView.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapSim/ConfigUi/src/EapSimUiView.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 28 %
+* %version: 29 %
 */
 
 // INCLUDE FILES
@@ -25,7 +25,7 @@
 #include <aknlists.h>
 #include "EapSimUiView.h"
 #include "EapSimUi.hrh"
-#include <EapSimUi.rsg>
+#include <eapsimui.rsg>
 #include <akntextsettingpage.h>
 #include <aknsettingitemlist.h>
 #include "EapSimUiSettingArray.h"
@@ -35,7 +35,7 @@
 #include <EapSimUiDataConnection.h>
 #include <EapSimUiSimData.h>
 
-#include <FeatMgr.h>
+#include <featmgr.h>
 #include <hlplch.h>
 #include <csxhelp/cp.hlp.hrh>
 
--- a/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUi.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUi.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,14 +16,14 @@
 */
 
 /*
-* %version: 14 %
+* %version: 15 %
 */
 
 // INCLUDE FILES
 #include "EapTlsUi.h"
 #include "EapTlsPeapUiConnection.h"
 #include "EapTlsUiView.h"
-#include <EapTlsUi.rsg>
+#include <eaptlsui.rsg>
 #include <bautils.h>
 #include <coemain.h>
 #include <aknnotewrappers.h>
--- a/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUiView.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapTls/ConfigUi/src/EapTlsUiView.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 40 %
+* %version: 41 %
 */
 
 // INCLUDE FILES
@@ -25,7 +25,7 @@
 #include <aknlists.h>
 #include "EapTlsUiView.h"
 #include "EapTlsUi.hrh"
-#include <EapTlsUi.rsg>
+#include <eaptlsui.rsg>
 #include <akntextsettingpage.h>
 #include <aknsettingitemlist.h>
 #include "EapTlsUiSettingArray.h"
@@ -42,7 +42,7 @@
 #include <AknIconArray.h>
 #include <AknsUtils.h>
 
-#include <FeatMgr.h>
+#include <featmgr.h>
 #include <hlplch.h>
 #include <csxhelp/cp.hlp.hrh>
 
--- a/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUi.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUi.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,13 +16,13 @@
 */
 
 /*
-* %version: 14 %
+* %version: 15 %
 */
 
 // INCLUDE FILES
 #include "EapTtlsUi.h"
 #include "EapTtlsUiView.h"
-#include <EapTtlsUi.rsg>
+#include <eapttlsui.rsg>
 #include <bautils.h>
 #include <coemain.h>
 #include <aknnotewrappers.h>
--- a/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUiView.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/EapTtls/ConfigUi/src/EapTtlsUiView.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 27.1.1.1.8 %
+* %version: 27.1.1.1.9 %
 */
 
 // INCLUDE FILES
@@ -25,7 +25,7 @@
 #include <aknlists.h>
 #include "EapTtlsUiView.h"
 #include "EapTtlsUi.hrh"
-#include <EapTtlsUi.rsg>
+#include <eapttlsui.rsg>
 #include <akntextsettingpage.h>
 #include <aknsettingitemlist.h>
 #include "EapTtlsUiSettingArray.h"
@@ -43,7 +43,7 @@
 #include <AknIconArray.h>
 #include <AknsUtils.h>
 
-#include <FeatMgr.h>
+#include <featmgr.h>
 #include <hlplch.h>
 #include <csxhelp/cp.hlp.hrh>
 
--- a/wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papuiview.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wlaneapsettingsui/pap/configui/src/papuiview.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: 12 %
+* %version: 13 %
 */
 
 // INCLUDE FILES
@@ -37,7 +37,7 @@
 #include <EapTlsPeapUiConnection.h>
 #include <EapTlsPeapUiDataConnection.h>
 #include <EapTlsPeapUiTlsPeapData.h>
-#include <FeatMgr.h>
+#include <featmgr.h>
 #include <hlplch.h>
 #include <csxhelp/cp.hlp.hrh>
 
--- a/wlansecuritysettings/wpasecuritysettingsui/group/wpasecuritysettingsuistub.mmp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wpasecuritysettingsui/group/wpasecuritysettingsuistub.mmp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -17,7 +17,7 @@
 */
 
 /*
-* %version: 3 %
+* %version: 6 %
 */
 
 #include <data_caging_paths.hrh>
@@ -44,9 +44,9 @@
 LIBRARY euser.lib
 
 #if defined(ARMCC)
-    DEFFILE ../EABI/WPASecuritySettingsUI_EKA2_ALR.def
+    DEFFILE ../eabi/WPASecuritySettingsUI_EKA2_ALR.def
 #elif defined( WINSCW )
-    DEFFILE ../BWinsCw/WPASecuritySettingsUI_EKA2_ALR.def
+    DEFFILE ../bwinscw/WPASecuritySettingsUI_EKA2_ALR.def
 #endif
 
 // End of File
--- a/wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsDlg.cpp	Mon Jan 18 20:22:35 2010 +0200
+++ b/wlansecuritysettings/wpasecuritysettingsui/src/WPASecuritySettingsDlg.cpp	Fri Mar 19 09:29:58 2010 +0200
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2001-2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of the License "Eclipse Public License v1.0"
@@ -16,7 +16,7 @@
 */
 
 /*
-* %version: tr1cfwln#30 %
+* %version: tr1cfwln#31 %
 */
 
 // INCLUDE FILES
@@ -30,7 +30,7 @@
 #include <csxhelp/cp.hlp.hrh>
 #include <hlplch.h>
 
-#include <FeatMgr.h>
+#include <featmgr.h>
 
 #include <akntitle.h>
 #include <aknradiobuttonsettingpage.h>