Index: extensions/app_diameap/CMakeLists.txt
===================================================================
--- extensions/app_diameap/CMakeLists.txt	(revision 431)
+++ extensions/app_diameap/CMakeLists.txt	(revision 438)
@@ -25,5 +25,4 @@
     diameap_user.h
     diameap.tab.h
-    diameap_init.h
     diameap.tab.c
     lex.diameap.c        
Index: extensions/app_diameap/diameap.c
===================================================================
--- extensions/app_diameap/diameap.c	(revision 425)
+++ extensions/app_diameap/diameap.c	(revision 438)
@@ -38,7 +38,5 @@
 #include "diameap_common.h"
 
-/* Define the entry point */
-EXTENSION_ENTRY("DiamEAP", diameap_main)
-;
+
 
 /* DiamEAP Configuration */
@@ -84,2 +82,6 @@
 	return;
 }
+
+/* Define the entry point */
+EXTENSION_ENTRY("DiamEAP", diameap_main)
+;
Index: extensions/app_diameap/diameap.h
===================================================================
--- extensions/app_diameap/diameap.h	(revision 425)
+++ extensions/app_diameap/diameap.h	(revision 438)
@@ -71,6 +71,10 @@
 extern struct diameap_conf *diameap_config;
 
-/* Main function of DiamEAP extension */
-static int diameap_main(char * conffile);
+/* Initialize the configuration of DiamEAP*/
+int diameap_init(char * conffile);
+
+/* parser */
+int diameapparse(struct diameap_conf * config);
+
 
 #endif /* DIAMEAP_H_ */
Index: extensions/app_diameap/diameap.l
===================================================================
--- extensions/app_diameap/diameap.l	(revision 425)
+++ extensions/app_diameap/diameap.l	(revision 438)
@@ -50,4 +50,5 @@
 	}	
  
+#define YY_NO_INPUT
 %}
 
@@ -58,5 +59,5 @@
 %option bison-bridge 
 %option bison-locations
-
+%option nounput
 
 %%
Index: extensions/app_diameap/diameap_common.h
===================================================================
--- extensions/app_diameap/diameap_common.h	(revision 425)
+++ extensions/app_diameap/diameap_common.h	(revision 438)
@@ -44,5 +44,4 @@
 #include "diameap.h"
 #include "diameap_plugins.h"
-#include "diameap_init.h"
 #include "diameap_eap.h"
 #include "diameap_server.h"
Index: extensions/app_diameap/diameap_eap.c
===================================================================
--- extensions/app_diameap/diameap_eap.c	(revision 425)
+++ extensions/app_diameap/diameap_eap.c	(revision 438)
@@ -38,4 +38,217 @@
 #include "diameap_common.h"
 
+static void diameap_ba_nextid(struct eap_state_machine * sm, int * id)
+{
+	TRACE_ENTRY("%p %p",sm,id);
+
+	if (sm->currentId < 0)
+	{
+		*id = (u8) (255 * rand() / RAND_MAX) & 0xFFU;
+	}
+	else
+	{
+		*id = (sm->currentId++) & 0xFFU;
+	}
+	if (*id == sm->lastId)
+	{
+		*id=*id+1;
+	}
+}
+
+static void diameap_ba_policyupdate(struct eap_state_machine * eap_sm,
+		struct eap_packet eapPacket)
+{
+	TRACE_ENTRY("%p %p",eap_sm, eapPacket);
+	if ((eap_sm->respMethod == TYPE_NAK))
+	{
+		int id;
+		eap_sm->user.pmethods = 0;
+		u32 vendor;
+		eap_type type;
+		u8 *data = (u8 *) eapPacket.data;
+		data += 5;
+		id = 5;
+		while (id < eapPacket.length)
+		{
+			vendor = VENDOR_IETF;
+			type = G8(data);
+			if (diameap_plugin_exist(vendor, type) == TRUE)
+			{
+				eap_sm->user.proposedmethods[id - 5].method = type;
+				eap_sm->user.proposedmethods[id - 5].vendor = vendor;
+				eap_sm->user.pmethods++;
+			}
+			data++;
+			id++;
+		}
+		eap_sm->user.methodId = -1;
+	}
+}
+
+static int diameap_ba_policygetnextmethod(struct eap_state_machine * eap_sm,
+		eap_type * eaptype, u32 * vendor)
+{
+	TRACE_ENTRY("%p %p %p",eap_sm,eaptype,vendor);
+	*vendor = 0;
+	*eaptype = TYPE_NONE;
+	eap_sm->selectedMethod = NULL;
+
+	if (eap_sm == NULL)
+	{
+		return EINVAL;
+	}
+
+	if (eap_sm->user.userid == NULL)
+	{
+		if ((eap_sm->currentMethod == TYPE_NONE))
+		{
+			*vendor = VENDOR_IETF;
+			*eaptype = TYPE_IDENTITY;
+			if (eap_sm->selectedMethod != NULL)
+			{
+				(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
+				eap_sm->methodData = NULL;
+			}
+			CHECK_FCT(diameap_plugin_get(VENDOR_IETF,TYPE_IDENTITY,&eap_sm->selectedMethod));
+			return 0;
+		}
+
+		eap_sm->selectedMethod = NULL;
+		*vendor = 0;
+		*eaptype = TYPE_NONE;
+		return 0;
+	}
+
+	if (eap_sm->user.methodId == -1)
+	{
+		if (eap_sm->user.proposed_eap_method >= TYPE_EAP_MD5)
+		{
+			*vendor = eap_sm->user.proposed_eap_method_vendor;
+			if (*vendor == VENDOR_IETF)
+			{
+				*eaptype = eap_sm->user.proposed_eap_method;
+			}
+			else
+			{
+				*eaptype = TYPE_EXPANDED_TYPES;
+			}
+			if (eap_sm->selectedMethod != NULL)
+			{
+				(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
+				eap_sm->methodData = NULL;
+			}
+			CHECK_FCT_DO(diameap_plugin_get(*vendor,*eaptype,&eap_sm->selectedMethod),
+					{	TRACE_DEBUG(INFO,"%s [EAP Protocol] Invalid EAP-TYPE %d (vendor %d)",DIAMEAP_EXTENSION,*eaptype,*vendor);return 1;});
+
+		}
+		eap_sm->user.proposed_eap_method = TYPE_NONE;
+	}
+	else
+	{
+		*vendor = eap_sm->user.proposedmethods[eap_sm->user.methodId].vendor;
+		if (eap_sm->user.proposedmethods[eap_sm->user.methodId].vendor
+				== VENDOR_IETF)
+		{
+			*eaptype
+					= eap_sm->user.proposedmethods[eap_sm->user.methodId].method;
+		}
+		else
+		{
+			*eaptype = TYPE_EXPANDED_TYPES;
+		}
+		if (eap_sm->selectedMethod != NULL)
+		{
+			(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
+			eap_sm->methodData=NULL;
+		}
+		CHECK_FCT(diameap_plugin_get(eap_sm->user.proposedmethods[eap_sm->user.methodId].vendor,eap_sm->user.proposedmethods[eap_sm->user.methodId].method,&eap_sm->selectedMethod));
+
+		eap_sm->user.methodId++;
+	}
+
+	return 0;
+}
+
+static int diameap_ba_policygetdecision(struct eap_state_machine * eap_sm,
+		struct diameap_eap_interface * eap_i, decision * gdecision)
+{
+	TRACE_ENTRY("%p %p %p",eap_sm,eap_i,gdecision);
+
+	if (eap_sm->user.userid != NULL)
+	{
+
+		if (eap_sm->methodState == EAP_M_END)
+		{
+
+			if (eap_sm->respMethod == TYPE_IDENTITY)
+			{
+
+				*gdecision = DECISION_CONTINUE;
+				return 0;
+			}
+
+			if ((eap_sm->respMethod == TYPE_NAK) || ((eap_sm->respMethod
+					== TYPE_EXPANDED_TYPES) && (eap_sm->respVendor
+					== VENDOR_IETF) && (eap_sm->respVendorMethod == TYPE_NAK)))
+			{
+				goto SelectNextMethod;
+			}
+
+			if (eap_sm->user.success == TRUE)
+			{
+
+				*gdecision = DECISION_SUCCESS;
+			}
+			else
+			{
+
+				*gdecision = DECISION_FAILURE;
+			}
+
+		}
+		else
+		{
+			goto SelectNextMethod;
+		}
+		return 0;
+
+		SelectNextMethod: if ((eap_sm->user.methodId
+				== (MAXPROPOSEDMETHODS - 1))
+				|| ((eap_sm->user.proposedmethods[eap_sm->user.methodId + 1].method
+						== TYPE_NONE)
+						&& (eap_sm->user.proposedmethods[eap_sm->user.methodId
+								+ 1].vendor == VENDOR_IETF)))
+		{
+			TRACE_DEBUG(FULL+1,
+					"%s [EAP protocol] None of proposed EAP Methods authenticated the user.(FAILURE)",DIAMEAP_EXTENSION);
+			*gdecision = DECISION_FAILURE;
+			return 0;
+		}
+
+		eap_sm->user.methodId = 0;
+		*gdecision = DECISION_CONTINUE;
+		return 0;
+	}
+
+	if (eap_sm->currentMethod == TYPE_IDENTITY)
+	{
+		*gdecision = DECISION_FAILURE;
+		return 0;
+	}
+
+	*gdecision = DECISION_CONTINUE;
+	return 0;
+}
+
+static boolean diameap_ba_policydopickup(eap_type type)
+{
+	TRACE_ENTRY("%p",type);
+	if (type == TYPE_IDENTITY)
+	{
+		return TRUE;
+	}
+	return FALSE;
+}
+
 int diameap_eap_statemachine(struct eap_state_machine * eap_sm,
 		struct diameap_eap_interface * eap_i, boolean * non_fatal_error)
@@ -375,5 +588,9 @@
 			}
 			break;
+
 		case EAP_END:
+			break;
+
+		case EAP_IDLE:
 			break;
 		}
@@ -383,214 +600,2 @@
 }
 
-static void diameap_ba_nextid(struct eap_state_machine * sm, int * id)
-{
-	TRACE_ENTRY("%p %p",sm,id);
-
-	if (sm->currentId < 0)
-	{
-		*id = (u8) (255 * rand() / RAND_MAX) & 0xFFU;
-	}
-	else
-	{
-		*id = (sm->currentId++) & 0xFFU;
-	}
-	if (*id == sm->lastId)
-	{
-		*id++;
-	}
-}
-
-static void diameap_ba_policyupdate(struct eap_state_machine * eap_sm,
-		struct eap_packet eapPacket)
-{
-	TRACE_ENTRY("%p %p",eap_sm, eapPacket);
-	if ((eap_sm->respMethod == TYPE_NAK))
-	{
-		int id;
-		eap_sm->user.pmethods = 0;
-		u32 vendor;
-		eap_type type;
-		u8 *data = (u8 *) eapPacket.data;
-		data += 5;
-		id = 5;
-		while (id < eapPacket.length)
-		{
-			vendor = VENDOR_IETF;
-			type = G8(data);
-			if (diameap_plugin_exist(vendor, type) == TRUE)
-			{
-				eap_sm->user.proposedmethods[id - 5].method = type;
-				eap_sm->user.proposedmethods[id - 5].vendor = vendor;
-				eap_sm->user.pmethods++;
-			}
-			data++;
-			id++;
-		}
-		eap_sm->user.methodId = -1;
-	}
-}
-
-static int diameap_ba_policygetnextmethod(struct eap_state_machine * eap_sm,
-		eap_type * eaptype, u32 * vendor)
-{
-	TRACE_ENTRY("%p %p %p",eap_sm,eaptype,vendor);
-	*vendor = 0;
-	*eaptype = TYPE_NONE;
-	eap_sm->selectedMethod = NULL;
-
-	if (eap_sm == NULL)
-	{
-		return EINVAL;
-	}
-
-	if (eap_sm->user.userid == NULL)
-	{
-		if ((eap_sm->currentMethod == TYPE_NONE))
-		{
-			*vendor = VENDOR_IETF;
-			*eaptype = TYPE_IDENTITY;
-			if (eap_sm->selectedMethod != NULL)
-			{
-				(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
-				eap_sm->methodData = NULL;
-			}
-			CHECK_FCT(diameap_plugin_get(VENDOR_IETF,TYPE_IDENTITY,&eap_sm->selectedMethod));
-			return 0;
-		}
-
-		eap_sm->selectedMethod = NULL;
-		*vendor = 0;
-		*eaptype = TYPE_NONE;
-		return 0;
-	}
-
-	if (eap_sm->user.methodId == -1)
-	{
-		if (eap_sm->user.proposed_eap_method >= TYPE_EAP_MD5)
-		{
-			*vendor = eap_sm->user.proposed_eap_method_vendor;
-			if (*vendor == VENDOR_IETF)
-			{
-				*eaptype = eap_sm->user.proposed_eap_method;
-			}
-			else
-			{
-				*eaptype = TYPE_EXPANDED_TYPES;
-			}
-			if (eap_sm->selectedMethod != NULL)
-			{
-				(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
-				eap_sm->methodData = NULL;
-			}
-			CHECK_FCT_DO(diameap_plugin_get(*vendor,*eaptype,&eap_sm->selectedMethod),
-					{	TRACE_DEBUG(INFO,"%s [EAP Protocol] Invalid EAP-TYPE %d (vendor %d)",DIAMEAP_EXTENSION,*eaptype,*vendor);return 1;});
-
-		}
-		eap_sm->user.proposed_eap_method = TYPE_NONE;
-	}
-	else
-	{
-		*vendor = eap_sm->user.proposedmethods[eap_sm->user.methodId].vendor;
-		if (eap_sm->user.proposedmethods[eap_sm->user.methodId].vendor
-				== VENDOR_IETF)
-		{
-			*eaptype
-					= eap_sm->user.proposedmethods[eap_sm->user.methodId].method;
-		}
-		else
-		{
-			*eaptype = TYPE_EXPANDED_TYPES;
-		}
-		if (eap_sm->selectedMethod != NULL)
-		{
-			(*eap_sm->selectedMethod->eap_method_free)(eap_sm->methodData);
-			eap_sm->methodData;
-		}
-		CHECK_FCT(diameap_plugin_get(eap_sm->user.proposedmethods[eap_sm->user.methodId].vendor,eap_sm->user.proposedmethods[eap_sm->user.methodId].method,&eap_sm->selectedMethod));
-
-		eap_sm->user.methodId++;
-	}
-
-	return 0;
-}
-
-static int diameap_ba_policygetdecision(struct eap_state_machine * eap_sm,
-		struct diameap_eap_interface * eap_i, decision * gdecision)
-{
-	TRACE_ENTRY("%p %p %p",eap_sm,eap_i,gdecision);
-
-	if (eap_sm->user.userid != NULL)
-	{
-
-		if (eap_sm->methodState == EAP_M_END)
-		{
-
-			if (eap_sm->respMethod == TYPE_IDENTITY)
-			{
-
-				*gdecision = DECISION_CONTINUE;
-				return 0;
-			}
-
-			if ((eap_sm->respMethod == TYPE_NAK) || ((eap_sm->respMethod
-					== TYPE_EXPANDED_TYPES) && (eap_sm->respVendor
-					== VENDOR_IETF) && (eap_sm->respVendorMethod == TYPE_NAK)))
-			{
-				goto SelectNextMethod;
-			}
-
-			if (eap_sm->user.success == TRUE)
-			{
-
-				*gdecision = DECISION_SUCCESS;
-			}
-			else
-			{
-
-				*gdecision = DECISION_FAILURE;
-			}
-
-		}
-		else
-		{
-			goto SelectNextMethod;
-		}
-		return 0;
-
-		SelectNextMethod: if ((eap_sm->user.methodId
-				== (MAXPROPOSEDMETHODS - 1))
-				|| ((eap_sm->user.proposedmethods[eap_sm->user.methodId + 1].method
-						== TYPE_NONE)
-						&& (eap_sm->user.proposedmethods[eap_sm->user.methodId
-								+ 1].vendor == VENDOR_IETF)))
-		{
-			TRACE_DEBUG(FULL+1,
-					"%s [EAP protocol] None of proposed EAP Methods authenticated the user.(FAILURE)",DIAMEAP_EXTENSION);
-			*gdecision = DECISION_FAILURE;
-			return 0;
-		}
-
-		eap_sm->user.methodId = 0;
-		*gdecision = DECISION_CONTINUE;
-		return 0;
-	}
-
-	if (eap_sm->currentMethod == TYPE_IDENTITY)
-	{
-		*gdecision = DECISION_FAILURE;
-		return 0;
-	}
-
-	*gdecision = DECISION_CONTINUE;
-	return 0;
-}
-
-static boolean diameap_ba_policydopickup(eap_type type)
-{
-	TRACE_ENTRY("%p",type);
-	if (type == TYPE_IDENTITY)
-	{
-		return TRUE;
-	}
-	return FALSE;
-}
Index: extensions/app_diameap/diameap_eap.h
===================================================================
--- extensions/app_diameap/diameap_eap.h	(revision 425)
+++ extensions/app_diameap/diameap_eap.h	(revision 438)
@@ -67,9 +67,5 @@
 
 int diameap_eap_statemachine(struct eap_state_machine * sm, struct diameap_eap_interface * eap_i, boolean * error);
-static void diameap_ba_nextid(struct eap_state_machine * sm, int * id);
-static void	diameap_ba_policyupdate(struct eap_state_machine * sm, struct eap_packet eapPacket);
-static int diameap_ba_policygetnextmethod(struct eap_state_machine * sm, eap_type * eaptype, u32 * vendor);
-static int diameap_ba_policygetdecision(struct eap_state_machine * sm,	struct diameap_eap_interface * eap_i, decision * gdecision);
-static boolean diameap_ba_policydopickup(eap_type type);
+
 
 #endif /* EAP_H_ */
Index: extensions/app_diameap/diameap_init.c
===================================================================
--- extensions/app_diameap/diameap_init.c	(revision 425)
+++ extensions/app_diameap/diameap_init.c	(revision 438)
@@ -113,36 +113,5 @@
 struct dict_object * dataobj_user_name = NULL;
 
-int diameap_init(char * conffile)
-{
-	TRACE_ENTRY("%p",conffile);
-
-	/* Initialize the diameap_config structure*/
-	CHECK_FCT(diameap_init_config(conffile));
-
-	if (diameap_config->conffile)
-	{
-		/* parse the configuration file*/
-		CHECK_FCT(diameap_parse_conffile());
-
-		/* Load EAP methods plug-ins */
-		CHECK_FCT(diameap_plugin_load());
-
-	}
-	else
-	{
-		TRACE_DEBUG(FULL,"%sNo EAP method plug-in available with a default configuration.",DIAMEAP_EXTENSION);
-	}
-
-	/* Initialize Dictionary templates */
-	CHECK_FCT(diameap_init_obj());
-
-	/* Initialize access to user's information Database */
-	CHECK_FCT(diameap_mysql_connect());
-
-	/* Dump DiamEAP extension configuration */
-	diameap_conf_dump();
-
-	return 0;
-}
+
 
 static int diameap_init_config(char * conffile)
@@ -389,23 +358,4 @@
 	}
 	return 0;
-}
-
-/* Reconnecting to MySQL Database */
-int diameap_mysql_reconnect()
-{
-	TRACE_ENTRY();
-	CHECK_POSIX(pthread_mutex_lock( &db_cs_mutex ));
-	if (db_conn == NULL)
-	{
-		TRACE_DEBUG(INFO,"%sReconnecting to MySQL server.",DIAMEAP_EXTENSION);
-		if(diameap_mysql_connect()==0){
-			TRACE_DEBUG(INFO,"%s Reconnected successfully to MySQL Server.",DIAMEAP_EXTENSION);
-		}else{
-			return 1;
-		}
-	}
-	CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
-	return 0;
-
 }
 
@@ -440,2 +390,35 @@
 			"-------- DiamEAP extension : Configuration parameters (End) ---------------\n");
 }
+
+int diameap_init(char * conffile)
+{
+	TRACE_ENTRY("%p",conffile);
+
+	/* Initialize the diameap_config structure*/
+	CHECK_FCT(diameap_init_config(conffile));
+
+	if (diameap_config->conffile)
+	{
+		/* parse the configuration file*/
+		CHECK_FCT(diameap_parse_conffile());
+
+		/* Load EAP methods plug-ins */
+		CHECK_FCT(diameap_plugin_load());
+
+	}
+	else
+	{
+		TRACE_DEBUG(FULL,"%sNo EAP method plug-in available with a default configuration.",DIAMEAP_EXTENSION);
+	}
+
+	/* Initialize Dictionary templates */
+	CHECK_FCT(diameap_init_obj());
+
+	/* Initialize access to user's information Database */
+	CHECK_FCT(diameap_mysql_connect());
+
+	/* Dump DiamEAP extension configuration */
+	diameap_conf_dump();
+
+	return 0;
+}
Index: extensions/app_diameap/diameap_mysql.c
===================================================================
--- extensions/app_diameap/diameap_mysql.c	(revision 425)
+++ extensions/app_diameap/diameap_mysql.c	(revision 438)
@@ -38,4 +38,7 @@
 #include "diameap_mysql.h"
 
+static pthread_mutex_t db_cs_mutex =
+PTHREAD_MUTEX_INITIALIZER;
+
 int diameap_get_eap_user(struct eap_user * user, char * username)
 {
@@ -44,8 +47,7 @@
 	{
 		TRACE_DEBUG(INFO, "%sNot connected to the MySQL Database server.",DIAMEAP_EXTENSION);
-		if (diameap_mysql_reconnect())
-		{
-			return EINVAL;
-		}
+
+		return EINVAL;
+
 	}
 	mysql_thread_init();
@@ -67,6 +69,4 @@
 		CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
 		TRACE_DEBUG(INFO, "%sQuery execution fail. %s",DIAMEAP_EXTENSION, mysql_error(db_conn));
-		db_conn = NULL;
-		diameap_mysql_reconnect();
 		mysql_thread_end();
 		free(query);
@@ -83,7 +83,7 @@
 
 		user->id = atoi(row[0]);
-		user->userid = strdup(row[1]);
+		memcpy(user->userid,row[1],strlen(row[1]));
 		user->useridLength = strlen(row[1]);
-		user->password = strdup(row[2]);
+		memcpy(user->password, row[2],strlen(row[2]));
 		user->passwordLength = strlen(row[2]);
 		user->proposed_eap_method = atoi(row[3]);
@@ -115,8 +115,7 @@
 	{
 		TRACE_DEBUG(INFO, "%sNot connected to the MySQL Database server.",DIAMEAP_EXTENSION);
-		if (diameap_mysql_reconnect())
-		{
-			return EINVAL;
-		}
+
+		return EINVAL;
+
 	}
 
@@ -138,6 +137,4 @@
 		CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
 		TRACE_DEBUG(INFO, "%sQuery execution fail. %s",DIAMEAP_EXTENSION, mysql_error(db_conn));
-		db_conn = NULL;
-		diameap_mysql_reconnect();
 		mysql_thread_end();
 		free(query);
@@ -178,8 +175,7 @@
 	{
 		TRACE_DEBUG(INFO, "%sNot connected to the MySQL Database server.",DIAMEAP_EXTENSION);
-		if (diameap_mysql_reconnect())
-		{
-			return EINVAL;
-		}
+
+		return EINVAL;
+
 	}
 
@@ -202,6 +198,4 @@
 		CHECK_POSIX(pthread_mutex_unlock( &db_cs_mutex ));
 		TRACE_DEBUG(INFO, "%sQuery execution fail. %s",DIAMEAP_EXTENSION, mysql_error(db_conn));
-		db_conn = NULL;
-		diameap_mysql_reconnect();
 		mysql_thread_end();
 		free(query);
@@ -233,5 +227,6 @@
 }
 
-void diameap_mysql_disconnect(){
+void diameap_mysql_disconnect()
+{
 	mysql_close(db_conn);
 }
Index: extensions/app_diameap/diameap_mysql.h
===================================================================
--- extensions/app_diameap/diameap_mysql.h	(revision 425)
+++ extensions/app_diameap/diameap_mysql.h	(revision 438)
@@ -43,25 +43,23 @@
 #include <mysql.h>
 
-	/* MySQL Database connection */
-	MYSQL *db_conn;
+/* MySQL Database connection */
+MYSQL *db_conn;
 
-	static pthread_mutex_t db_cs_mutex = PTHREAD_MUTEX_INITIALIZER;
+int diameap_get_eap_user(struct eap_user * user, char * username);
 
-	int diameap_get_eap_user(struct eap_user * user, char * username);
+int diameap_mysql_connect();
 
-	int diameap_mysql_connect();
+int diameap_mysql_reconnect();
 
-	int diameap_mysql_reconnect();
+int diameap_set_mysql_param(char * user, char * passwd, char * server, char * database);
 
-	int diameap_set_mysql_param(char * user, char * passwd, char * server, char * database);
+void diameap_mysql_disconnect();
 
-	void diameap_mysql_disconnect();
-
-	/**/
-	int diameap_authentication_get_attribs(struct eap_user user,
+/* */
+int diameap_authentication_get_attribs(struct eap_user user,
 			struct fd_list * attribute_list);
 
-	/**/
-	int diameap_authorization_get_attribs(struct eap_user user,
+/* */
+int diameap_authorization_get_attribs(struct eap_user user,
 			struct fd_list * attribute_list);
 
Index: extensions/app_diameap/diameap_server.c
===================================================================
--- extensions/app_diameap/diameap_server.c	(revision 425)
+++ extensions/app_diameap/diameap_server.c	(revision 438)
@@ -38,4 +38,11 @@
 #include "diameap_common.h"
 
+/* handler for DiamEAP server callback */
+static struct disp_hdl * handle;
+
+/* session handler for DiamEAP sessions state machine */
+static struct session_handler * diameap_server_reg = NULL;
+
+
 struct avp_max_occurences auth_avps[] =
 {
@@ -76,326 +83,5 @@
 { "Originating-Line-Info", 0 } };
 
-static int diameap_server_callback(struct msg ** rmsg, struct avp * ravp,
-		struct session * sess, enum disp_action * action)
-{
-	TRACE_ENTRY("%p %p %p %p", rmsg, ravp, sess, action);
-
-	struct diameap_sess_data_sm * diameap_sess_data = NULL;
-	struct diameap_state_machine * diameap_sm = NULL;
-	struct diameap_eap_interface eap_i;
-	struct msg *req, *ans;
-	boolean non_fatal_error = FALSE;
-
-	if (rmsg == NULL)
-		return EINVAL;
-
-	req = *rmsg;
-
-	CHECK_FCT_DO(fd_sess_state_retrieve(diameap_server_reg, sess, &diameap_sess_data),
-			{	TRACE_DEBUG(INFO,"%s retrieving session state failed.",DIAMEAP_EXTENSION); goto s_end;});
-
-	CHECK_MALLOC_DO(diameap_sm = malloc(sizeof(struct diameap_state_machine)),
-			goto s_end);
-	memset(diameap_sm, 0, sizeof(struct diameap_state_machine));
-
-	if (diameap_sess_data)
-	{
-		diameap_sm->state = DIAMEAP_RECEIVED;
-		diameap_sm->eap_sm.eap_state = EAP_IDLE;
-	}
-	else
-	{
-		diameap_sm->state = DIAMEAP_DISABLED;
-		diameap_sm->eap_sm.eap_state = EAP_INITIALIZE;
-	}
-
-	while (diameap_sm->state != DIAMEAP_IDLE && diameap_sm->state
-			!= DIAMEAP_END)
-	{
-		switch (diameap_sm->state)
-		{
-		case DIAMEAP_DISABLED:
-			if (rmsg)
-			{
-				diameap_sm->state = DIAMEAP_INITIALIZE;
-			}
-			else
-			{
-				TRACE_DEBUG(INFO,"%sReceived empty Diameter EAP Request message.",DIAMEAP_EXTENSION);
-				goto s_end;
-			}
-			break;
-
-		case DIAMEAP_INITIALIZE:
-
-			CHECK_FCT_DO(diameap_initialize_diameap_sm(diameap_sm,diameap_sess_data),
-					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP state machine failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			CHECK_FCT_DO(diameap_initialize_diameap_eap_interface(&eap_i),
-					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP-EAP Interface failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			TRACE_DEBUG(FULL+1,"%sParsing AVPs",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO(diameap_parse_avps(diameap_sm, req, &eap_i), TRACE_DEBUG(INFO,"%s Unable to parse Diameter-EAP-Request AVPs.",DIAMEAP_EXTENSION))
-			;
-
-			if ((diameap_sm->result_code != 0))
-			{
-				diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
-			}
-			else
-			{
-				diameap_sm->state = DIAMEAP_AUTHENTICATION_VERIFY;
-			}
-			break;
-
-		case DIAMEAP_RECEIVED:
-
-			CHECK_FCT_DO(diameap_initialize_diameap_sm(diameap_sm,diameap_sess_data),
-					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP state machine failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			CHECK_FCT_DO(diameap_initialize_diameap_eap_interface(&eap_i),
-					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP-EAP Interface failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			TRACE_DEBUG(FULL+1,"%sParsing AVPs",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO(diameap_parse_avps(diameap_sm, req, &eap_i), TRACE_DEBUG(INFO,"%s Unable to parse Diameter-EAP-Request AVPs.",DIAMEAP_EXTENSION))
-			;
-
-			if (diameap_sm->result_code != 0)
-			{
-				diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
-			}
-			else
-			{
-				diameap_sm->state = DIAMEAP_AUTHENTICATION_VERIFY;
-			}
-			break;
-
-		case DIAMEAP_AUTHENTICATION_VERIFY:
-		{
-
-			TRACE_DEBUG(FULL+1,"%sVerify authentication",DIAMEAP_EXTENSION);
-			CHECK_FCT_DO(diameap_eap_statemachine(&diameap_sm->eap_sm, &eap_i,&non_fatal_error),
-					{	TRACE_DEBUG(INFO,"%s EAP process failed.",DIAMEAP_EXTENSION); goto s_end;});
-
-			if (non_fatal_error == TRUE)
-			{
-				TRACE_DEBUG(FULL+1,"%sAuthentication verify finished with a non-fatal-error.",DIAMEAP_EXTENSION);
-				diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
-			}
-			else
-			{
-				diameap_sm->state = DIAMEAP_SELECT_DECISION;
-
-			}
-		}
-			break;
-
-		case DIAMEAP_SELECT_DECISION:
-
-			CHECK_FCT_DO( diameap_policy_decision(diameap_sm,eap_i),
-					goto s_end)
-			;
-
-			if ((eap_i.aaaSuccess == TRUE) && (diameap_sm->auth_request_val
-					== AUTHORIZE_AUTHENTICATE)
-					&& (diameap_sm->verify_authorization == FALSE))
-			{
-				diameap_sm->state = DIAMEAP_AUTHORIZATION_VERIFY;
-			}
-			else
-			{
-				diameap_sm->state = DIAMEAP_DIAMETER_EAP_ANSWER;
-			}
-			break;
-
-		case DIAMEAP_AUTHORIZATION_VERIFY:
-			diameap_sm->verify_authorization = TRUE;
-			TRACE_DEBUG(FULL+1,"%sVerify authorization",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO(diameap_authorize(diameap_sm),
-					{	TRACE_DEBUG(INFO,"%s Authorization check process failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			diameap_sm->state = DIAMEAP_SELECT_DECISION;
-
-			break;
-
-		case DIAMEAP_DIAMETER_EAP_ANSWER:
-			TRACE_DEBUG(FULL+1,"%screate Diameter EAP Answer",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, rmsg, 0),
-					goto s_end)
-			;
-			ans = *rmsg;
-			TRACE_DEBUG(FULL+1,"%sAdding AVPs to Diameter EAP Answer.",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO( diameap_add_avps(diameap_sm, ans,req),
-					{	TRACE_DEBUG(INFO,"%s Unable to add AVPs to Diameter-EAP-Answer message.",DIAMEAP_EXTENSION);goto s_end;})
-			;
-			if (diameap_sm->authFailure == FALSE)
-			{
-				if (diameap_sm->eap_sm.user.id != 0)
-				{
-					TRACE_DEBUG(FULL+1,"%sSelect authentication attributes.",DIAMEAP_EXTENSION);
-					CHECK_FCT_DO(diameap_authentication_get_attribs(diameap_sm->eap_sm.user, &diameap_sm->attributes),
-							{	TRACE_DEBUG(INFO,"%s Unable to get user's session attributes.",DIAMEAP_EXTENSION); goto s_end;});
-					TRACE_DEBUG(FULL+1,"%sCreate answer authentication attributes.",DIAMEAP_EXTENSION);
-					CHECK_FCT_DO(diameap_answer_avp_attributes(diameap_sm),
-							{	TRACE_DEBUG(INFO,"% Unable to generate answer attributes.",DIAMEAP_EXTENSION); goto s_end;});
-				}
-
-				if (diameap_sm->authSuccess == FALSE)
-				{
-					diameap_sm->state = DIAMEAP_SEND_REQUEST;
-				}
-				else
-				{
-
-					diameap_sm->state = DIAMEAP_SEND_SUCCESS;
-				}
-			}
-			else
-			{
-				diameap_sm->state = DIAMEAP_SEND_FAILURE;
-			}
-			break;
-
-		case DIAMEAP_SEND_REQUEST:
-			TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
-					{	TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,eap_i),
-					{	TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			TRACE_DEBUG(FULL+1,"%sStoring DiamEAP session data.",DIAMEAP_EXTENSION)
-			;
-			CHECK_MALLOC(diameap_sess_data = malloc(sizeof(struct diameap_sess_data_sm)))
-			;
-			memset(diameap_sess_data, 0, sizeof(struct diameap_sess_data_sm));
-			diameap_sess_data_new(diameap_sess_data, diameap_sm);
-
-			CHECK_FCT_DO(fd_sess_state_store(diameap_server_reg, sess, &diameap_sess_data),
-					{	TRACE_DEBUG(INFO,"%s Storing session state failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-
-			CHECK_FCT_DO( diameap_send(rmsg),
-					goto s_end)
-			;
-
-			diameap_sm->state = DIAMEAP_IDLE;
-			break;
-
-		case DIAMEAP_SEND_FAILURE:
-			TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
-					{	TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,eap_i),
-					{	TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-
-			CHECK_FCT_DO( diameap_send(rmsg),
-					goto s_end)
-			;
-			diameap_sm->state = DIAMEAP_END;
-			break;
-
-		case DIAMEAP_SEND_SUCCESS:
-			TRACE_DEBUG(FULL+1,"%sAdding User session AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO(diameap_add_user_sessions_avps(diameap_sm,ans),
-					{	TRACE_DEBUG(INFO,"%s Adding user's session AVPs failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-
-			if (diameap_sm->auth_request_val == AUTHORIZE_AUTHENTICATE)
-			{
-				TRACE_DEBUG(FULL+1,"%sAdding Authorization AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION);
-				CHECK_FCT_DO(diameap_add_authorization_avps(diameap_sm,ans),
-						{	TRACE_DEBUG(INFO,"%s Adding Authorization AVPs failed.",DIAMEAP_EXTENSION); goto s_end;});
-			}
-			TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
-					{	TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,eap_i),
-					{	TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			TRACE_DEBUG(FULL+1,"%sAdding EAP success AVPs AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO( diameap_add_eap_success_avps(diameap_sm, ans, eap_i),
-					goto s_end)
-			;
-			TRACE_DEBUG(FULL+1,"%sAdding Accounting-EAP-Auth-Method AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
-			;
-			CHECK_FCT_DO(diameap_add_accounting_eap_auth_method(diameap_sm, ans),
-					{	TRACE_DEBUG(INFO,"%s Adding accounting AVP failed",DIAMEAP_EXTENSION); goto s_end;})
-			;
-			CHECK_FCT_DO( diameap_send(rmsg),
-					goto s_end)
-			;
-			diameap_sm->state = DIAMEAP_END;
-			break;
-
-		case DIAMEAP_SEND_ERROR_MSG:
-			diameap_sm->invalid_eappackets++;
-			if (diameap_sm->invalid_eappackets
-					== diameap_config->max_invalid_eap_packet)
-			{
-				diameap_sm->result_code = 4001;//DIAMETER_AUTHENTICATION_REJECTED
-				TRACE_DEBUG(FULL,"%s Maximum permitted invalid EAP Packet reached. Diameter Authentication Rejected.",DIAMEAP_EXTENSION);
-			}
-
-			CHECK_FCT_DO(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, rmsg, 0),
-					goto s_end)
-			;
-
-			ans = *rmsg;
-			CHECK_FCT_DO( diameap_add_avps(diameap_sm, ans,req),
-					{	TRACE_DEBUG(INFO,"%s Adding AVPs to Diameter-EAP-Answer message failed.",DIAMEAP_EXTENSION);goto s_end;})
-			;
-			if ((non_fatal_error == TRUE) && (diameap_sm->result_code == 0))
-			{
-				diameap_sm->result_code = 1001;
-			}
-
-			if (diameap_sm->result_code == 1001)
-			{
-				CHECK_FCT_DO( diameap_add_eap_reissued_payload(ans,req), goto s_end);
-			}
-
-			if (diameap_sm->result_code == 5004)
-			{
-				CHECK_FCT_DO( fd_msg_avp_add( ans , MSG_BRW_LAST_CHILD, diameap_sm->failedavp ),goto s_end );
-			}
-
-			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess), goto s_end)
-			;
-
-			CHECK_FCT_DO( diameap_send(rmsg), goto s_end)
-			;
-			diameap_sm->state = DIAMEAP_IDLE;
-			break;
-
-		case DIAMEAP_END:
-
-			break;
-		}
-	}
-
-	diameap_free(diameap_sm);
-
-	s_end: return 0;
-}
+
 
 void diameap_cli_sess_cleanup(void * arg, char * sid)
@@ -630,560 +316,4 @@
 }
 
-static int diameap_parse_avps(struct diameap_state_machine * diameap_sm,
-		struct msg * req, struct diameap_eap_interface * eap_i)
-{
-	TRACE_ENTRY("%p %p %p",diameap_sm,req,eap_i);
-	struct avp * avp, *avp2;
-	struct avp_hdr * avpdata;
-	int ret;
-	int depth;
-
-	/* EAP-Payload data*/
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_eap_payload, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		CHECK_FCT(diameap_eappacket_new(&eap_i->aaaEapRespData, avpdata));
-		eap_i->aaaEapResp = TRUE;
-		u16 length;
-		diameap_eap_get_length(eap_i->aaaEapRespData, &length);
-		if (length >= 4)
-		{
-			eap_code code;
-			CHECK_FCT(diameap_eap_get_code(eap_i->aaaEapRespData,&code));
-
-			if (code != EAP_RESPONSE)
-			{
-				diameap_sm->result_code = 5004; /* DIAMETER_INVALID_AVP_VALUE 5004 */
-				struct avp * invalidavp;
-				union avp_value val;
-				CHECK_FCT( fd_msg_avp_new ( dataobj_eap_payload, 0, &invalidavp));
-				val.os.data = (char *) eap_i->aaaEapRespData.data;
-				val.os.len = eap_i->aaaEapRespData.length;
-				CHECK_FCT( fd_msg_avp_setvalue( invalidavp, &val ))
-				CHECK_FCT( diameap_failed_avp(diameap_sm, invalidavp));
-				TRACE_DEBUG(INFO,"%sIncorrect EAP Packet. EAP Code != Response.",DIAMEAP_EXTENSION);
-				return 0;
-			}
-			else
-			{
-				CHECK_FCT(diameap_parse_eap_resp(&diameap_sm->eap_sm,eap_i->aaaEapRespData));
-				if (diameap_sm->eap_sm.rxResp == FALSE)
-				{
-					diameap_sm->result_code = 1001; /*DIAMETER_MULTI_ROUND_AUTH*/
-					eap_i->aaaEapNoReq = TRUE;
-					eap_i->aaaEapResp = FALSE;
-				}
-			}
-		}
-		else
-		{
-			if (diameap_sm->eap_sm.currentMethod != TYPE_NONE)
-			{
-				diameap_sm->result_code = 5004; /* DIAMETER_INVALID_AVP_VALUE 5004 */
-				CHECK_FCT(diameap_failed_avp(diameap_sm, avp));
-				TRACE_DEBUG(INFO,"%sEAP packet length < Minimum EAP packet length.",DIAMEAP_EXTENSION);
-				return 1;
-			}
-			//EAP start received
-
-		}
-	}
-
-	/* User-Name AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_user_name, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "User-Name";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* EAP-Key-Name AVP */
-
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_eap_key_name, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "EAP-Key-Name";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Auth-Request-Type AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_request_type, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		diameap_sm->auth_request_val = avpdata->avp_value->i32;
-	}
-
-	/* Authorization-Lifetime AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_authorization_lifetime, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Authorization-Lifetime";
-		attribute->value.u32 = avpdata->avp_value->u32;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Auth-Grace-Period AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_grace_period, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Auth-Grace-Period";
-		attribute->value.u32 = avpdata->avp_value->u32;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Auth-Session-State AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_session_state, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Auth-Session-State";
-		attribute->value.i32 = avpdata->avp_value->i32;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Origin-state-Id AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_origin_state_id, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Origin-state-Id AVP";
-		attribute->value.u32 = avpdata->avp_value->u32;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* NAS-Port AVP*/
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "NAS-Port";
-		attribute->value.u32 = avpdata->avp_value->u32;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* NAS-Port-Id AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port_id, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "NAS-Port-Id";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* NAS-Port-Type AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port_type, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "NAS-Port-Type";
-		attribute->value.u32 = avpdata->avp_value->u32;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Called-Station-Id AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_called_station_id, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Called-Station-Id";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Calling-Station-Id AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_calling_station_id, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Calling-Station-Id";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Connect-Info AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_connect_info, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Connect-Info";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Originating-Line-Info AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_originating_line_info, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Originating-Line-Info";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Service-Type AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_service_type, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Service-Type";
-		attribute->value.u32 = avpdata->avp_value->u32;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Callback-Number AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_callback_number, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Callback-Number";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Port-Limit AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_port_limit, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Port-Limit";
-		attribute->value.u32 = avpdata->avp_value->u32;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Framed-Protocol AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_protocol, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Framed-Protocol";
-		attribute->value.u32 = avpdata->avp_value->u32;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Framed-MTU AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_mtu, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Framed-MTU";
-		attribute->value.u32 = avpdata->avp_value->u32;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Framed-Compression AVP */
-	avp = NULL;
-	avp2 = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_compression, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		u32 Pi_Code = avpdata->avp_code;
-		int depth;
-		do
-		{
-			struct avp_attribute * attribute;
-			CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-			memset(attribute, 0, sizeof(struct avp_attribute));
-			fd_list_init(&attribute->chain, attribute);
-			attribute->attrib = "Framed-Compression";
-			attribute->value.u32 = avpdata->avp_value->u32;
-			fd_list_insert_before(&diameap_sm->req_attributes,
-					&attribute->chain);
-			ret = 0;
-			depth = 0;
-			ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
-			if (avp2 != NULL)
-			{
-				CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
-			}
-			avp = avp2;
-		} while ((avp2 != NULL) && (ret == 0) && (ret == 0)
-				&& (avpdata->avp_code == Pi_Code));
-	}
-
-	/* Framed-IP-Address AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ip_address, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Framed-IP-Address";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Framed-IP-Netmask AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ip_netmask, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Framed-IP-Netmask";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Framed-Interface-Id AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_interface_id, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "Framed-Interface-Id";
-		attribute->value.u64 = avpdata->avp_value->u64;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* Framed-IPv6-Prefix AVP */
-	avp = NULL;
-	avp2 = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ipv6_prefix, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		u32 Pi_Code = avpdata->avp_code;
-		do
-		{
-			struct avp_attribute * attribute;
-			CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-			memset(attribute, 0, sizeof(struct avp_attribute));
-			fd_list_init(&attribute->chain, attribute);
-			attribute->attrib = "Framed-IPv6-Prefix";
-			attribute->value.u32 = avpdata->avp_value->u32;
-			fd_list_insert_before(&diameap_sm->req_attributes,
-					&attribute->chain);
-			ret = 0;
-			depth = 0;
-			ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
-			if (avp2 != NULL)
-			{
-				CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
-			}
-			avp = avp2;
-		} while ((avp2 != NULL) && (ret == 0) && (ret == 0)
-				&& (avpdata->avp_code == Pi_Code));
-	}
-
-	/* Tunneling AVP */
-	avp = NULL;
-	avp2 = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_tunneling, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		u32 Pi_Code = avpdata->avp_code;
-		int depth;
-		do
-		{
-			struct avp_attribute * attribute;
-			CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-			memset(attribute, 0, sizeof(struct avp_attribute));
-			fd_list_init(&attribute->chain, attribute);
-			attribute->attrib = "Tunneling";
-			//grouped AVP
-			fd_list_insert_before(&diameap_sm->req_attributes,
-					&attribute->chain);
-			ret = 0;
-			depth = 0;
-			ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
-			if (avp2 != NULL)
-			{
-				CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
-			}
-			avp = avp2;
-		} while ((avp2 != NULL) && (ret == 0) && (ret == 0)
-				&& (avpdata->avp_code == Pi_Code));
-	}
-
-	/* NAS-Identifier AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_identifier, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "NAS-Identifier";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* NAS-IP-Address AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_ip_address, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "NAS-IP-Address";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* NAS-IPv6-Address AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_ipv6_address, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "NAS-IPv6-Address";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	/* State AVP */
-	avp = NULL;
-	CHECK_FCT(fd_msg_search_avp(req, dataobj_state, &avp));
-	if (avp != NULL)
-	{
-		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
-		struct avp_attribute * attribute;
-		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
-		memset(attribute, 0, sizeof(struct avp_attribute));
-		fd_list_init(&attribute->chain, attribute);
-		attribute->attrib = "State";
-		attribute->value.os.data = avpdata->avp_value->os.data;
-		attribute->value.os.len = avpdata->avp_value->os.len;
-		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
-	}
-
-	return 0;
-}
-
 static int diameap_failed_avp(struct diameap_state_machine * diameap_sm,
 		struct avp * invalidavp)
@@ -1214,6 +344,4 @@
 {
 	TRACE_ENTRY("%p %p",eap_sm, eappacket)
-
-	unsigned int len;
 
 	eap_sm->rxResp = FALSE;
@@ -1286,6 +414,6 @@
 	{
 		u8 *data = (u8 *) eappacket.data;
-		int len = 0;
-		u32 respVendor, respVendorMethod;
+		//int len = 0;
+		//u32 respVendor, respVendorMethod;
 		data += 5;
 		eap_sm->respVendor = G24BIGE(data);
@@ -1325,4 +453,561 @@
 }
 
+static int diameap_parse_avps(struct diameap_state_machine * diameap_sm,
+		struct msg * req, struct diameap_eap_interface * eap_i)
+{
+	TRACE_ENTRY("%p %p %p",diameap_sm,req,eap_i);
+	struct avp * avp, *avp2;
+	struct avp_hdr * avpdata;
+	int ret;
+	int depth;
+
+	/* EAP-Payload data*/
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_eap_payload, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		CHECK_FCT(diameap_eappacket_new(&eap_i->aaaEapRespData, avpdata));
+		eap_i->aaaEapResp = TRUE;
+		u16 length;
+		diameap_eap_get_length(eap_i->aaaEapRespData, &length);
+		if (length >= 4)
+		{
+			eap_code code;
+			CHECK_FCT(diameap_eap_get_code(eap_i->aaaEapRespData,&code));
+
+			if (code != EAP_RESPONSE)
+			{
+				diameap_sm->result_code = 5004; /* DIAMETER_INVALID_AVP_VALUE 5004 */
+				struct avp * invalidavp;
+				union avp_value val;
+				CHECK_FCT( fd_msg_avp_new ( dataobj_eap_payload, 0, &invalidavp));
+				val.os.data = eap_i->aaaEapRespData.data;
+				val.os.len = eap_i->aaaEapRespData.length;
+				CHECK_FCT( fd_msg_avp_setvalue( invalidavp, &val ))
+				CHECK_FCT( diameap_failed_avp(diameap_sm, invalidavp));
+				TRACE_DEBUG(INFO,"%sIncorrect EAP Packet. EAP Code != Response.",DIAMEAP_EXTENSION);
+				return 0;
+			}
+			else
+			{
+				CHECK_FCT(diameap_parse_eap_resp(&diameap_sm->eap_sm,eap_i->aaaEapRespData));
+				if (diameap_sm->eap_sm.rxResp == FALSE)
+				{
+					diameap_sm->result_code = 1001; /*DIAMETER_MULTI_ROUND_AUTH*/
+					eap_i->aaaEapNoReq = TRUE;
+					eap_i->aaaEapResp = FALSE;
+				}
+			}
+		}
+		else
+		{
+			if (diameap_sm->eap_sm.currentMethod != TYPE_NONE)
+			{
+				diameap_sm->result_code = 5004; /* DIAMETER_INVALID_AVP_VALUE 5004 */
+				CHECK_FCT(diameap_failed_avp(diameap_sm, avp));
+				TRACE_DEBUG(INFO,"%sEAP packet length < Minimum EAP packet length.",DIAMEAP_EXTENSION);
+				return 1;
+			}
+			//EAP start received
+
+		}
+	}
+
+	/* User-Name AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_user_name, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "User-Name";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* EAP-Key-Name AVP */
+
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_eap_key_name, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "EAP-Key-Name";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Auth-Request-Type AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_request_type, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		diameap_sm->auth_request_val = avpdata->avp_value->i32;
+	}
+
+	/* Authorization-Lifetime AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_authorization_lifetime, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Authorization-Lifetime";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Auth-Grace-Period AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_grace_period, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Auth-Grace-Period";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Auth-Session-State AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_auth_session_state, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Auth-Session-State";
+		attribute->value.i32 = avpdata->avp_value->i32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Origin-state-Id AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_origin_state_id, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Origin-state-Id AVP";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* NAS-Port AVP*/
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-Port";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* NAS-Port-Id AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port_id, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-Port-Id";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* NAS-Port-Type AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_port_type, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-Port-Type";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Called-Station-Id AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_called_station_id, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Called-Station-Id";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Calling-Station-Id AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_calling_station_id, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Calling-Station-Id";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Connect-Info AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_connect_info, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Connect-Info";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Originating-Line-Info AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_originating_line_info, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Originating-Line-Info";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Service-Type AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_service_type, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Service-Type";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Callback-Number AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_callback_number, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Callback-Number";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Port-Limit AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_port_limit, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Port-Limit";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-Protocol AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_protocol, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Framed-Protocol";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-MTU AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_mtu, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Framed-MTU";
+		attribute->value.u32 = avpdata->avp_value->u32;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-Compression AVP */
+	avp = NULL;
+	avp2 = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_compression, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		u32 Pi_Code = avpdata->avp_code;
+		int depth;
+		do
+		{
+			struct avp_attribute * attribute;
+			CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+			memset(attribute, 0, sizeof(struct avp_attribute));
+			fd_list_init(&attribute->chain, attribute);
+			attribute->attrib = "Framed-Compression";
+			attribute->value.u32 = avpdata->avp_value->u32;
+			fd_list_insert_before(&diameap_sm->req_attributes,
+					&attribute->chain);
+			ret = 0;
+			depth = 0;
+			ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
+			if (avp2 != NULL)
+			{
+				CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
+			}
+			avp = avp2;
+		} while ((avp2 != NULL) && (ret == 0) && (ret == 0)
+				&& (avpdata->avp_code == Pi_Code));
+	}
+
+	/* Framed-IP-Address AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ip_address, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Framed-IP-Address";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-IP-Netmask AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ip_netmask, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Framed-IP-Netmask";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-Interface-Id AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_interface_id, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "Framed-Interface-Id";
+		attribute->value.u64 = avpdata->avp_value->u64;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* Framed-IPv6-Prefix AVP */
+	avp = NULL;
+	avp2 = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_framed_ipv6_prefix, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		u32 Pi_Code = avpdata->avp_code;
+		do
+		{
+			struct avp_attribute * attribute;
+			CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+			memset(attribute, 0, sizeof(struct avp_attribute));
+			fd_list_init(&attribute->chain, attribute);
+			attribute->attrib = "Framed-IPv6-Prefix";
+			attribute->value.u32 = avpdata->avp_value->u32;
+			fd_list_insert_before(&diameap_sm->req_attributes,
+					&attribute->chain);
+			ret = 0;
+			depth = 0;
+			ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
+			if (avp2 != NULL)
+			{
+				CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
+			}
+			avp = avp2;
+		} while ((avp2 != NULL) && (ret == 0) && (ret == 0)
+				&& (avpdata->avp_code == Pi_Code));
+	}
+
+	/* Tunneling AVP */
+	avp = NULL;
+	avp2 = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_tunneling, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		u32 Pi_Code = avpdata->avp_code;
+		int depth;
+		do
+		{
+			struct avp_attribute * attribute;
+			CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+			memset(attribute, 0, sizeof(struct avp_attribute));
+			fd_list_init(&attribute->chain, attribute);
+			attribute->attrib = "Tunneling";
+			//grouped AVP
+			fd_list_insert_before(&diameap_sm->req_attributes,
+					&attribute->chain);
+			ret = 0;
+			depth = 0;
+			ret = fd_msg_browse ( avp, MSG_BRW_NEXT, &avp2, &depth);
+			if (avp2 != NULL)
+			{
+				CHECK_FCT(fd_msg_avp_hdr(avp2, &avpdata));
+			}
+			avp = avp2;
+		} while ((avp2 != NULL) && (ret == 0) && (ret == 0)
+				&& (avpdata->avp_code == Pi_Code));
+	}
+
+	/* NAS-Identifier AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_identifier, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-Identifier";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* NAS-IP-Address AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_ip_address, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-IP-Address";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* NAS-IPv6-Address AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_nas_ipv6_address, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "NAS-IPv6-Address";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	/* State AVP */
+	avp = NULL;
+	CHECK_FCT(fd_msg_search_avp(req, dataobj_state, &avp));
+	if (avp != NULL)
+	{
+		CHECK_FCT(fd_msg_avp_hdr(avp, &avpdata));
+		struct avp_attribute * attribute;
+		CHECK_MALLOC(attribute = malloc(sizeof(struct avp_attribute)));
+		memset(attribute, 0, sizeof(struct avp_attribute));
+		fd_list_init(&attribute->chain, attribute);
+		attribute->attrib = "State";
+		attribute->value.os.data = avpdata->avp_value->os.data;
+		attribute->value.os.len = avpdata->avp_value->os.len;
+		fd_list_insert_before(&diameap_sm->req_attributes, &attribute->chain);
+	}
+
+	return 0;
+}
+
+
 static int diameap_sess_data_new(
 		struct diameap_sess_data_sm *diameap_sess_data,
@@ -1407,69 +1092,50 @@
 }
 
-static void diameap_free(struct diameap_state_machine * diameap_sm)
-{
-
-	if (diameap_sm->eap_sm.user.userid != NULL)
-	{
-		free(diameap_sm->eap_sm.user.userid);
-		diameap_sm->eap_sm.user.userid = NULL;
-	}
-
-	if (diameap_sm->eap_sm.user.password != NULL)
-	{
-		free(diameap_sm->eap_sm.user.password);
-		diameap_sm->eap_sm.user.password = NULL;
-	}
-
-	diameap_sm->eap_sm.selectedMethod = NULL;
-
-	if (diameap_sm->eap_sm.methodData != NULL)
-	{
-
-		struct plugin * cplugin;
-		if (diameap_plugin_get(diameap_sm->eap_sm.currentVendor,
-				diameap_sm->eap_sm.currentMethod, &cplugin))
-		{
-			TRACE_DEBUG(INFO,"%sUnable to access EAP Method plugin {Type=%d, Vendor=%d}.",DIAMEAP_EXTENSION,diameap_sm->eap_sm.currentMethod,diameap_sm->eap_sm.currentVendor);
-		}
-
-		if (cplugin->eap_method_free)
-		{
-			(*cplugin->eap_method_free)(diameap_sm->eap_sm.methodData);
-			diameap_sm->eap_sm.methodData = NULL;
-		}
-		else
-		{
-			TRACE_DEBUG(INFO,"%s[%s plugin] datafree function not available.",DIAMEAP_EXTENSION,cplugin->methodname);
-			if (diameap_sm->eap_sm.methodData != NULL)
-			{
-				free(diameap_sm->eap_sm.methodData);
-				diameap_sm->eap_sm.methodData = NULL;
-			}
-		}
-		if (diameap_sm->eap_sm.methodData)
-		{
-			TRACE_DEBUG(INFO,"%sSession state was not been freed correctly!!!",DIAMEAP_EXTENSION);
-		}
-	}
-
-	if (diameap_sm->failedavp != NULL)
-	{
-		CHECK_FCT_DO(fd_msg_free(diameap_sm->failedavp), );
-	}
-
-	if (diameap_sm->lastReqEAPavp != NULL)
-	{
-		CHECK_FCT_DO(fd_msg_free(diameap_sm->lastReqEAPavp), );
-	}
-
-	CHECK_FCT_DO(diameap_unlink_attributes_lists(diameap_sm), );
-
-	if (diameap_sm != NULL)
-	{
-		free(diameap_sm);
-		diameap_sm = NULL;
-	}
-
+static void free_attrib(struct auth_attribute * auth_attrib)
+{
+	if (auth_attrib == NULL)
+	{
+		return;
+	}
+	if (auth_attrib->attrib != NULL)
+	{
+		free(auth_attrib->attrib);
+		auth_attrib->attrib = NULL;
+	}
+	if (auth_attrib->op != NULL)
+	{
+		free(auth_attrib->op);
+		auth_attrib->op = NULL;
+	}
+	if (auth_attrib->value != NULL)
+	{
+		free(auth_attrib->value);
+		auth_attrib->value = NULL;
+	}
+	free(auth_attrib);
+	auth_attrib = NULL;
+}
+
+static void free_avp_attrib(struct avp_attribute * avp_attrib)
+{
+	if(avp_attrib){
+	free(avp_attrib);
+	avp_attrib = NULL;
+	}
+}
+
+static void free_ans_attrib(struct avp_attribute * ans_attrib)
+{
+	if (ans_attrib->tofree == 1)
+	{
+		if(ans_attrib->value.os.data){
+		free(ans_attrib->value.os.data);
+		ans_attrib->value.os.data = NULL;
+		}
+	}
+	if(ans_attrib){
+	free(ans_attrib);
+	ans_attrib = NULL;
+	}
 }
 
@@ -1509,4 +1175,174 @@
 	}
 
+	return 0;
+}
+
+static void diameap_free(struct diameap_state_machine * diameap_sm)
+{
+
+	if (diameap_sm->eap_sm.user.userid != NULL)
+	{
+		free(diameap_sm->eap_sm.user.userid);
+		diameap_sm->eap_sm.user.userid = NULL;
+	}
+
+	if (diameap_sm->eap_sm.user.password != NULL)
+	{
+		free(diameap_sm->eap_sm.user.password);
+		diameap_sm->eap_sm.user.password = NULL;
+	}
+
+	diameap_sm->eap_sm.selectedMethod = NULL;
+
+	if (diameap_sm->eap_sm.methodData != NULL)
+	{
+
+		struct plugin * cplugin;
+		if (diameap_plugin_get(diameap_sm->eap_sm.currentVendor,
+				diameap_sm->eap_sm.currentMethod, &cplugin))
+		{
+			TRACE_DEBUG(INFO,"%sUnable to access EAP Method plugin {Type=%d, Vendor=%d}.",DIAMEAP_EXTENSION,diameap_sm->eap_sm.currentMethod,diameap_sm->eap_sm.currentVendor);
+		}
+
+		if (cplugin->eap_method_free)
+		{
+			(*cplugin->eap_method_free)(diameap_sm->eap_sm.methodData);
+			diameap_sm->eap_sm.methodData = NULL;
+		}
+		else
+		{
+			TRACE_DEBUG(INFO,"%s[%s plugin] datafree function not available.",DIAMEAP_EXTENSION,cplugin->methodname);
+			if (diameap_sm->eap_sm.methodData != NULL)
+			{
+				free(diameap_sm->eap_sm.methodData);
+				diameap_sm->eap_sm.methodData = NULL;
+			}
+		}
+		if (diameap_sm->eap_sm.methodData)
+		{
+			TRACE_DEBUG(INFO,"%sSession state was not been freed correctly!!!",DIAMEAP_EXTENSION);
+		}
+	}
+
+	if (diameap_sm->failedavp != NULL)
+	{
+		CHECK_FCT_DO(fd_msg_free(diameap_sm->failedavp), );
+	}
+
+	if (diameap_sm->lastReqEAPavp != NULL)
+	{
+		CHECK_FCT_DO(fd_msg_free(diameap_sm->lastReqEAPavp), );
+	}
+
+	CHECK_FCT_DO(diameap_unlink_attributes_lists(diameap_sm), );
+
+	if (diameap_sm != NULL)
+	{
+		free(diameap_sm);
+		diameap_sm = NULL;
+	}
+
+}
+
+static int diameap_get_avp_attribute(struct fd_list * avp_attributes,
+		char * attribute, struct avp_attribute ** avp_attrib, int unlink,
+		int *ret)
+{
+	TRACE_ENTRY("%p %p %p %p %p", avp_attributes, attribute, avp_attrib, ret);
+	if (avp_attributes == NULL)
+	{
+		return EINVAL;
+	}
+	if (attribute == NULL)
+	{
+		return EINVAL;
+	}
+	struct fd_list * attrib;
+	for (attrib = avp_attributes->next; attrib != avp_attributes; attrib
+			= attrib->next)
+	{
+		*avp_attrib = (struct avp_attribute *) attrib;
+		if (strcmp((*avp_attrib)->attrib, attribute) == 0)
+		{
+			*ret = 0;
+			if (unlink == 1)
+			{
+				fd_list_unlink(&(*avp_attrib)->chain);
+			}
+			return 0;
+		}
+	}
+	*avp_attrib = NULL;
+	*ret = 1;
+	return 0;
+}
+
+static int diameap_get_auth_attribute(struct fd_list * auth_attributes,
+		char * attribute, struct auth_attribute ** auth_attrib, int unlink,
+		int *ret)
+{
+
+	TRACE_ENTRY("%p %p %p %p %p", auth_attributes, attribute, auth_attrib, ret);
+
+	if (auth_attributes == NULL)
+	{
+		return EINVAL;
+	}
+	if (attribute == NULL)
+	{
+		return EINVAL;
+	}
+
+	struct fd_list * attrib;
+
+	for (attrib = auth_attributes->next; attrib != auth_attributes; attrib
+			= attrib->next)
+	{
+		*auth_attrib = (struct auth_attribute *) attrib;
+		if (strcmp((*auth_attrib)->attrib, attribute) == 0)
+		{
+			*ret = 0;
+			if (unlink == 1)
+			{
+				fd_list_unlink(&(*auth_attrib)->chain);
+			}
+			return 0;
+		}
+	}
+	*auth_attrib = NULL;
+	*ret = 1;
+	return 0;
+}
+
+static int diameap_get_ans_attribute(struct fd_list * ans_attributes,
+		char * attribute, struct avp_attribute ** ans_attrib, int unlink,
+		int *ret)
+{
+	TRACE_ENTRY("%p %p %p %p %p", ans_attributes, attribute, ans_attrib, ret);
+	if (ans_attributes == NULL)
+	{
+		return EINVAL;
+	}
+	if (attribute == NULL)
+	{
+		return EINVAL;
+	}
+	struct fd_list * attrib;
+	for (attrib = ans_attributes->next; attrib != ans_attributes; attrib
+			= attrib->next)
+	{
+		*ans_attrib = (struct avp_attribute *) attrib;
+		if (strcmp((*ans_attrib)->attrib, attribute) == 0)
+		{
+			*ret = 0;
+			if (unlink == 1)
+			{
+				fd_list_unlink(&(*ans_attrib)->chain);
+			}
+			return 0;
+		}
+	}
+	*ans_attrib = NULL;
+	*ret = 1;
 	return 0;
 }
@@ -1855,5 +1691,5 @@
 					operator) == TRUE))
 			{
-				if (strcmp(A.os.data, B) == 0)
+				if (strcmp((char *)A.os.data, B) == 0)
 					return TRUE;
 				else
@@ -1903,5 +1739,5 @@
 				regex_t rule_regexp;
 				regcomp(&rule_regexp, B, REG_EXTENDED | REG_NOSUB | REG_ICASE);
-				if (regexec(&rule_regexp, A.os.data, 0, NULL, 0) != 0)
+				if (regexec(&rule_regexp, (char *)A.os.data, 0, NULL, 0) != 0)
 				{
 					authorized = FALSE;
@@ -2056,5 +1892,5 @@
 					operator) == TRUE))
 			{
-				if (strcmp(A.os.data, B) != 0)
+				if (strcmp((char *)A.os.data, B) != 0)
 					return TRUE;
 				else
@@ -2096,4 +1932,5 @@
 		}
 	}
+	return FALSE;
 }
 
@@ -2155,8 +1992,6 @@
 	if (datatype == AVP_TYPE_OCTETSTRING)
 	{
-		rval->os.data = strdup(A.os.data);
-
+		memcpy(rval->os.data,A.os.data,A.os.len);
 		rval->os.len = A.os.len;
-
 		*tofree = 1;
 	}
@@ -2174,6 +2009,5 @@
 	{
 
-		rval->os.data = strdup(B);
-
+		memcpy(rval->os.data,B,strlen(B));
 		rval->os.len = strlen(B);
 
@@ -2333,106 +2167,5 @@
 }
 
-static int diameap_get_avp_attribute(struct fd_list * avp_attributes,
-		char * attribute, struct avp_attribute ** avp_attrib, int unlink,
-		int *ret)
-{
-	TRACE_ENTRY("%p %p %p %p %p", avp_attributes, attribute, avp_attrib, ret);
-	if (avp_attributes == NULL)
-	{
-		return EINVAL;
-	}
-	if (attribute == NULL)
-	{
-		return EINVAL;
-	}
-	struct fd_list * attrib;
-	for (attrib = avp_attributes->next; attrib != avp_attributes; attrib
-			= attrib->next)
-	{
-		*avp_attrib = (struct avp_attribute *) attrib;
-		if (strcmp((*avp_attrib)->attrib, attribute) == 0)
-		{
-			*ret = 0;
-			if (unlink == 1)
-			{
-				fd_list_unlink(&(*avp_attrib)->chain);
-			}
-			return 0;
-		}
-	}
-	*avp_attrib = NULL;
-	*ret = 1;
-	return 0;
-}
-
-static int diameap_get_auth_attribute(struct fd_list * auth_attributes,
-		char * attribute, struct auth_attribute ** auth_attrib, int unlink,
-		int *ret)
-{
-
-	TRACE_ENTRY("%p %p %p %p %p", auth_attributes, attribute, auth_attrib, ret);
-
-	if (auth_attributes == NULL)
-	{
-		return EINVAL;
-	}
-	if (attribute == NULL)
-	{
-		return EINVAL;
-	}
-
-	struct fd_list * attrib;
-
-	for (attrib = auth_attributes->next; attrib != auth_attributes; attrib
-			= attrib->next)
-	{
-		*auth_attrib = (struct auth_attribute *) attrib;
-		if (strcmp((*auth_attrib)->attrib, attribute) == 0)
-		{
-			*ret = 0;
-			if (unlink == 1)
-			{
-				fd_list_unlink(&(*auth_attrib)->chain);
-			}
-			return 0;
-		}
-	}
-	*auth_attrib = NULL;
-	*ret = 1;
-	return 0;
-}
-
-static int diameap_get_ans_attribute(struct fd_list * ans_attributes,
-		char * attribute, struct avp_attribute ** ans_attrib, int unlink,
-		int *ret)
-{
-	TRACE_ENTRY("%p %p %p %p %p", ans_attributes, attribute, ans_attrib, ret);
-	if (ans_attributes == NULL)
-	{
-		return EINVAL;
-	}
-	if (attribute == NULL)
-	{
-		return EINVAL;
-	}
-	struct fd_list * attrib;
-	for (attrib = ans_attributes->next; attrib != ans_attributes; attrib
-			= attrib->next)
-	{
-		*ans_attrib = (struct avp_attribute *) attrib;
-		if (strcmp((*ans_attrib)->attrib, attribute) == 0)
-		{
-			*ret = 0;
-			if (unlink == 1)
-			{
-				fd_list_unlink(&(*ans_attrib)->chain);
-			}
-			return 0;
-		}
-	}
-	*ans_attrib = NULL;
-	*ret = 1;
-	return 0;
-}
+
 
 static int diameap_policy_decision(struct diameap_state_machine * diameap_sm,
@@ -3234,6 +2967,6 @@
 		{
 			CHECK_FCT(fd_msg_avp_new(dataobj_eap_key_name, 0, &avp));
-			avp_val.os.data = " ";//
-			avp_val.os.len = 1;//
+			avp_val.os.data = NULL;//
+			avp_val.os.len = 0;//
 			CHECK_FCT(fd_msg_avp_setvalue(avp, &avp_val));
 			CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
@@ -3301,5 +3034,5 @@
 		CHECK_FCT( fd_msg_avp_hdr(avp, &avphdr));
 		CHECK_FCT( fd_msg_avp_new(dataobj_eap_reissued_payload, 0, &re_avp));
-		avp_val.os.data = strdup(avphdr->avp_value->os.data);
+		memcpy(avp_val.os.data,avphdr->avp_value->os.data,avphdr->avp_value->os.len);
 		avp_val.os.len = avphdr->avp_value->os.len;
 		CHECK_FCT(fd_msg_avp_setvalue(re_avp, &avp_val));
@@ -3315,8 +3048,336 @@
 }
 
+
+
+
+static int diameap_server_callback(struct msg ** rmsg, struct avp * ravp,
+		struct session * sess, enum disp_action * action)
+{
+	TRACE_ENTRY("%p %p %p %p", rmsg, ravp, sess, action);
+
+	struct diameap_sess_data_sm * diameap_sess_data = NULL;
+	struct diameap_state_machine * diameap_sm = NULL;
+	struct diameap_eap_interface eap_i;
+	struct msg *req, *ans;
+	boolean non_fatal_error = FALSE;
+
+	if (rmsg == NULL)
+		return EINVAL;
+
+	req = *rmsg;
+
+	CHECK_FCT_DO(fd_sess_state_retrieve(diameap_server_reg, sess, &diameap_sess_data),
+			{	TRACE_DEBUG(INFO,"%s retrieving session state failed.",DIAMEAP_EXTENSION); goto s_end;});
+
+	CHECK_MALLOC_DO(diameap_sm = malloc(sizeof(struct diameap_state_machine)),
+			goto s_end);
+	memset(diameap_sm, 0, sizeof(struct diameap_state_machine));
+
+	if (diameap_sess_data)
+	{
+		diameap_sm->state = DIAMEAP_RECEIVED;
+		diameap_sm->eap_sm.eap_state = EAP_IDLE;
+	}
+	else
+	{
+		diameap_sm->state = DIAMEAP_DISABLED;
+		diameap_sm->eap_sm.eap_state = EAP_INITIALIZE;
+	}
+
+	while (diameap_sm->state != DIAMEAP_IDLE && diameap_sm->state
+			!= DIAMEAP_END)
+	{
+		switch (diameap_sm->state)
+		{
+		case DIAMEAP_DISABLED:
+			if (rmsg)
+			{
+				diameap_sm->state = DIAMEAP_INITIALIZE;
+			}
+			else
+			{
+				TRACE_DEBUG(INFO,"%sReceived empty Diameter EAP Request message.",DIAMEAP_EXTENSION);
+				goto s_end;
+			}
+			break;
+
+		case DIAMEAP_INITIALIZE:
+
+			CHECK_FCT_DO(diameap_initialize_diameap_sm(diameap_sm,diameap_sess_data),
+					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP state machine failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			CHECK_FCT_DO(diameap_initialize_diameap_eap_interface(&eap_i),
+					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP-EAP Interface failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sParsing AVPs",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(diameap_parse_avps(diameap_sm, req, &eap_i), TRACE_DEBUG(INFO,"%s Unable to parse Diameter-EAP-Request AVPs.",DIAMEAP_EXTENSION))
+			;
+
+			if ((diameap_sm->result_code != 0))
+			{
+				diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
+			}
+			else
+			{
+				diameap_sm->state = DIAMEAP_AUTHENTICATION_VERIFY;
+			}
+			break;
+
+		case DIAMEAP_RECEIVED:
+
+			CHECK_FCT_DO(diameap_initialize_diameap_sm(diameap_sm,diameap_sess_data),
+					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP state machine failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			CHECK_FCT_DO(diameap_initialize_diameap_eap_interface(&eap_i),
+					{	TRACE_DEBUG(INFO,"%s Initializing DiamEAP-EAP Interface failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sParsing AVPs",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(diameap_parse_avps(diameap_sm, req, &eap_i), TRACE_DEBUG(INFO,"%s Unable to parse Diameter-EAP-Request AVPs.",DIAMEAP_EXTENSION))
+			;
+
+			if (diameap_sm->result_code != 0)
+			{
+				diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
+			}
+			else
+			{
+				diameap_sm->state = DIAMEAP_AUTHENTICATION_VERIFY;
+			}
+			break;
+
+		case DIAMEAP_AUTHENTICATION_VERIFY:
+		{
+
+			TRACE_DEBUG(FULL+1,"%sVerify authentication",DIAMEAP_EXTENSION);
+			CHECK_FCT_DO(diameap_eap_statemachine(&diameap_sm->eap_sm, &eap_i,&non_fatal_error),
+					{	TRACE_DEBUG(INFO,"%s EAP process failed.",DIAMEAP_EXTENSION); goto s_end;});
+
+			if (non_fatal_error == TRUE)
+			{
+				TRACE_DEBUG(FULL+1,"%sAuthentication verify finished with a non-fatal-error.",DIAMEAP_EXTENSION);
+				diameap_sm->state = DIAMEAP_SEND_ERROR_MSG;
+			}
+			else
+			{
+				diameap_sm->state = DIAMEAP_SELECT_DECISION;
+
+			}
+		}
+			break;
+
+		case DIAMEAP_SELECT_DECISION:
+
+			CHECK_FCT_DO( diameap_policy_decision(diameap_sm,eap_i),
+					goto s_end)
+			;
+
+			if ((eap_i.aaaSuccess == TRUE) && (diameap_sm->auth_request_val
+					== AUTHORIZE_AUTHENTICATE)
+					&& (diameap_sm->verify_authorization == FALSE))
+			{
+				diameap_sm->state = DIAMEAP_AUTHORIZATION_VERIFY;
+			}
+			else
+			{
+				diameap_sm->state = DIAMEAP_DIAMETER_EAP_ANSWER;
+			}
+			break;
+
+		case DIAMEAP_AUTHORIZATION_VERIFY:
+			diameap_sm->verify_authorization = TRUE;
+			TRACE_DEBUG(FULL+1,"%sVerify authorization",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(diameap_authorize(diameap_sm),
+					{	TRACE_DEBUG(INFO,"%s Authorization check process failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			diameap_sm->state = DIAMEAP_SELECT_DECISION;
+
+			break;
+
+		case DIAMEAP_DIAMETER_EAP_ANSWER:
+			TRACE_DEBUG(FULL+1,"%screate Diameter EAP Answer",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, rmsg, 0),
+					goto s_end)
+			;
+			ans = *rmsg;
+			TRACE_DEBUG(FULL+1,"%sAdding AVPs to Diameter EAP Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_avps(diameap_sm, ans,req),
+					{	TRACE_DEBUG(INFO,"%s Unable to add AVPs to Diameter-EAP-Answer message.",DIAMEAP_EXTENSION);goto s_end;})
+			;
+			if (diameap_sm->authFailure == FALSE)
+			{
+				if (diameap_sm->eap_sm.user.id != 0)
+				{
+					TRACE_DEBUG(FULL+1,"%sSelect authentication attributes.",DIAMEAP_EXTENSION);
+					CHECK_FCT_DO(diameap_authentication_get_attribs(diameap_sm->eap_sm.user, &diameap_sm->attributes),
+							{	TRACE_DEBUG(INFO,"%s Unable to get user's session attributes.",DIAMEAP_EXTENSION); goto s_end;});
+					TRACE_DEBUG(FULL+1,"%sCreate answer authentication attributes.",DIAMEAP_EXTENSION);
+					CHECK_FCT_DO(diameap_answer_avp_attributes(diameap_sm),
+							{	TRACE_DEBUG(INFO,"% Unable to generate answer attributes.",DIAMEAP_EXTENSION); goto s_end;});
+				}
+
+				if (diameap_sm->authSuccess == FALSE)
+				{
+					diameap_sm->state = DIAMEAP_SEND_REQUEST;
+				}
+				else
+				{
+
+					diameap_sm->state = DIAMEAP_SEND_SUCCESS;
+				}
+			}
+			else
+			{
+				diameap_sm->state = DIAMEAP_SEND_FAILURE;
+			}
+			break;
+
+		case DIAMEAP_SEND_REQUEST:
+			TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
+					{	TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,eap_i),
+					{	TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sStoring DiamEAP session data.",DIAMEAP_EXTENSION)
+			;
+			CHECK_MALLOC(diameap_sess_data = malloc(sizeof(struct diameap_sess_data_sm)))
+			;
+			memset(diameap_sess_data, 0, sizeof(struct diameap_sess_data_sm));
+			diameap_sess_data_new(diameap_sess_data, diameap_sm);
+
+			CHECK_FCT_DO(fd_sess_state_store(diameap_server_reg, sess, &diameap_sess_data),
+					{	TRACE_DEBUG(INFO,"%s Storing session state failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+
+			CHECK_FCT_DO( diameap_send(rmsg),
+					goto s_end)
+			;
+
+			diameap_sm->state = DIAMEAP_IDLE;
+			break;
+
+		case DIAMEAP_SEND_FAILURE:
+			TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
+					{	TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,eap_i),
+					{	TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+
+			CHECK_FCT_DO( diameap_send(rmsg),
+					goto s_end)
+			;
+			diameap_sm->state = DIAMEAP_END;
+			break;
+
+		case DIAMEAP_SEND_SUCCESS:
+			TRACE_DEBUG(FULL+1,"%sAdding User session AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(diameap_add_user_sessions_avps(diameap_sm,ans),
+					{	TRACE_DEBUG(INFO,"%s Adding user's session AVPs failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+
+			if (diameap_sm->auth_request_val == AUTHORIZE_AUTHENTICATE)
+			{
+				TRACE_DEBUG(FULL+1,"%sAdding Authorization AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION);
+				CHECK_FCT_DO(diameap_add_authorization_avps(diameap_sm,ans),
+						{	TRACE_DEBUG(INFO,"%s Adding Authorization AVPs failed.",DIAMEAP_EXTENSION); goto s_end;});
+			}
+			TRACE_DEBUG(FULL+1,"%sAdding Result Code AVP to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess),
+					{	TRACE_DEBUG(INFO,"%s Adding Result-Code AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sAdding EAP-Payload to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_eap_payload(diameap_sm, ans,eap_i),
+					{	TRACE_DEBUG(INFO,"%s Adding EAP-Payload AVP failed.",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			TRACE_DEBUG(FULL+1,"%sAdding EAP success AVPs AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO( diameap_add_eap_success_avps(diameap_sm, ans, eap_i),
+					goto s_end)
+			;
+			TRACE_DEBUG(FULL+1,"%sAdding Accounting-EAP-Auth-Method AVPs to Diameter-EAP-Answer.",DIAMEAP_EXTENSION)
+			;
+			CHECK_FCT_DO(diameap_add_accounting_eap_auth_method(diameap_sm, ans),
+					{	TRACE_DEBUG(INFO,"%s Adding accounting AVP failed",DIAMEAP_EXTENSION); goto s_end;})
+			;
+			CHECK_FCT_DO( diameap_send(rmsg),
+					goto s_end)
+			;
+			diameap_sm->state = DIAMEAP_END;
+			break;
+
+		case DIAMEAP_SEND_ERROR_MSG:
+			diameap_sm->invalid_eappackets++;
+			if (diameap_sm->invalid_eappackets
+					== diameap_config->max_invalid_eap_packet)
+			{
+				diameap_sm->result_code = 4001;//DIAMETER_AUTHENTICATION_REJECTED
+				TRACE_DEBUG(FULL,"%s Maximum permitted invalid EAP Packet reached. Diameter Authentication Rejected.",DIAMEAP_EXTENSION);
+			}
+
+			CHECK_FCT_DO(fd_msg_new_answer_from_req(fd_g_config->cnf_dict, rmsg, 0),
+					goto s_end)
+			;
+
+			ans = *rmsg;
+			CHECK_FCT_DO( diameap_add_avps(diameap_sm, ans,req),
+					{	TRACE_DEBUG(INFO,"%s Adding AVPs to Diameter-EAP-Answer message failed.",DIAMEAP_EXTENSION);goto s_end;})
+			;
+			if ((non_fatal_error == TRUE) && (diameap_sm->result_code == 0))
+			{
+				diameap_sm->result_code = 1001;
+			}
+
+			if (diameap_sm->result_code == 1001)
+			{
+				CHECK_FCT_DO( diameap_add_eap_reissued_payload(ans,req), goto s_end);
+			}
+
+			if (diameap_sm->result_code == 5004)
+			{
+				CHECK_FCT_DO( fd_msg_avp_add( ans , MSG_BRW_LAST_CHILD, diameap_sm->failedavp ),goto s_end );
+			}
+
+			CHECK_FCT_DO( diameap_add_result_code(diameap_sm, ans, sess), goto s_end)
+			;
+
+			CHECK_FCT_DO( diameap_send(rmsg), goto s_end)
+			;
+			diameap_sm->state = DIAMEAP_IDLE;
+			break;
+
+		case DIAMEAP_END:
+			break;
+
+		case DIAMEAP_IDLE:
+			break;
+		}
+	}
+
+	diameap_free(diameap_sm);
+
+	s_end: return 0;
+}
+
 int diameap_start_server(void)
 {
 	struct disp_when when;
-	int ret;
+
 	/*create handler for sessions */
 	CHECK_FCT(fd_sess_handler_create(&diameap_server_reg, diameap_cli_sess_cleanup));
@@ -3339,46 +3400,4 @@
 }
 
-static void free_attrib(struct auth_attribute * auth_attrib)
-{
-	if (auth_attrib == NULL)
-	{
-		return;
-	}
-	if (auth_attrib->attrib != NULL)
-	{
-		free(auth_attrib->attrib);
-		auth_attrib->attrib = NULL;
-	}
-	if (auth_attrib->op != NULL)
-	{
-		free(auth_attrib->op);
-		auth_attrib->op = NULL;
-	}
-	if (auth_attrib->value != NULL)
-	{
-		free(auth_attrib->value);
-		auth_attrib->value = NULL;
-	}
-	free(auth_attrib);
-	auth_attrib = NULL;
-}
-
-static void free_avp_attrib(struct avp_attribute * avp_attrib)
-{
-	free(avp_attrib);
-	avp_attrib = NULL;
-}
-
-static void free_ans_attrib(struct avp_attribute * ans_attrib)
-{
-	if (ans_attrib->tofree == 1)
-	{
-		free(ans_attrib->value.os.data);
-		ans_attrib->value.os.data = NULL;
-	}
-	free(ans_attrib);
-	ans_attrib = NULL;
-}
-
 int diameap_stop_server(void)
 {
Index: extensions/app_diameap/diameap_server.h
===================================================================
--- extensions/app_diameap/diameap_server.h	(revision 425)
+++ extensions/app_diameap/diameap_server.h	(revision 438)
@@ -40,9 +40,4 @@
 #define DIAMEAP_SERVER_H_
 
-/* handler for DiamEAP server callback */
-static struct disp_hdl * handle;
-
-/* session handler for DiamEAP sessions state machine */
-static struct session_handler * diameap_server_reg = NULL;
 
 /* session data structure to store */
@@ -120,43 +115,43 @@
 int diameap_stop_server(void);
 
-/* Initialize DiamEAP state machine variables */
+/* Initialize DiamEAP state machine variables
 static int diameap_initialize_diameap_sm(
 		struct diameap_state_machine * diameap_sm,
 		struct diameap_sess_data_sm * diameap_sess_data);
 
-/* Initialize interface between the diameap and the eap states machines */
+ Initialize interface between the diameap and the eap states machines
 static int diameap_initialize_diameap_eap_interface(
 		struct diameap_eap_interface * eap_i);
 
-/* Parse received message */
+ Parse received message
 static int diameap_parse_avps(struct diameap_state_machine * diameap_sm,
 		struct msg * req, struct diameap_eap_interface * eap_i);
 
-/* Add an avp to Failed_AVP AVP for answer message */
+ Add an avp to Failed_AVP AVP for answer message
 static int diameap_failed_avp(struct diameap_state_machine * diameap_sm,
 		struct avp * invalidavp);
 
-/* Parse EAP Response */
+ Parse EAP Response
 static int diameap_parse_eap_resp(struct eap_state_machine * eap_sm,
 		struct eap_packet eappacket);
 
-/* */
+
 static int diameap_eappacket_new(struct eap_packet * eapPacket,
 		struct avp_hdr * avpdata);
 
-/* */
+
 static int diameap_sess_data_new(
 		struct diameap_sess_data_sm *diameap_sess_data,
 		struct diameap_state_machine *diameap_sm);
 
-/* */
+
 static int diameap_unlink_attributes_lists(
 		struct diameap_state_machine * diameap_sm);
 
-/**/
+
 static int diameap_answer_avp_attributes(
 		struct diameap_state_machine * diameap_sm);
 
-/**/
+
 static int diameap_answer_authorization_attributes(
 		struct diameap_state_machine * diameap_sm);
@@ -166,66 +161,66 @@
 static void free_ans_attrib(struct avp_attribute * ans_attrib);
 
-/* */
+
 static int diameap_get_avp_attribute(struct fd_list * avp_attributes,
 		char * attribute, struct avp_attribute ** avp_attrib, int unlink,
 		int *ret);
 
-/* */
+
 static int diameap_get_auth_attribute(struct fd_list * auth_attributes,
 		char * attribute, struct auth_attribute ** auth_attrib, int unlink,
 		int *ret);
 
-/**/
+
 static int diameap_get_ans_attribute(struct fd_list * ans_attributes,
 		char * attribute, struct avp_attribute ** ans_attrib, int unlink,
 		int *ret);
 
-/* */
+
 static int diameap_policy_decision(struct diameap_state_machine * diameap_sm,
 		struct diameap_eap_interface eap_i);
 
-/* */
+
 static int diameap_add_avps(struct diameap_state_machine * diameap_sm,
 		struct msg * ans, struct msg * req);
 
-/* */
+
 static int diameap_add_user_sessions_avps(
 		struct diameap_state_machine * diameap_sm, struct msg * ans);
 
-/* */
+
 static int diameap_add_result_code(struct diameap_state_machine * diameap_sm,
 		struct msg * ans, struct session * sess);
 
-/* */
+
 static int diameap_add_eap_payload(struct diameap_state_machine * diameap_sm,
 		struct msg * ans, struct diameap_eap_interface eap_i);
 
-/* */
+
 static int diameap_add_authorization_avps(struct diameap_state_machine * diameap_sm,
 		struct msg * ans);
 
-/* */
+
 static int diameap_send(struct msg ** rmsg);
 
-/* */
+
 static int diameap_add_eap_success_avps(
 		struct diameap_state_machine * diameap_sm, struct msg * ans,
 		struct diameap_eap_interface eap_i);
 
-/* */
+
 void diameap_cli_sess_cleanup(void * arg, char * sid);
 
-/* */
+
 static void diameap_free(struct diameap_state_machine * diameap_sm);
 
-/* */
+
 static void diameap_sess_data_free(
 		struct diameap_sess_data_sm * diameap_sess_data);
 
-/* */
+
 static int diameap_add_accounting_eap_auth_method(
 		struct diameap_state_machine * diameap_sm, struct msg * ans);
 
-/* */
-static int diameap_add_eap_reissued_payload(struct msg * ans,struct msg * req);
+
+static int diameap_add_eap_reissued_payload(struct msg * ans,struct msg * req);*/
 #endif /* DIAMEAP_SERVER_H_ */
Index: extensions/app_diameap/diameap_tls.c
===================================================================
--- extensions/app_diameap/diameap_tls.c	(revision 425)
+++ extensions/app_diameap/diameap_tls.c	(revision 438)
@@ -39,4 +39,6 @@
 #include "diameap_tls.h"
 
+//GCRY_THREAD_OPTION_PTHREAD_IMPL;
+
 int diameap_tls_init(struct tls_config * tls_conf)
 {
@@ -102,5 +104,5 @@
 	if (text == NULL)
 		return;
-	msg = strdup(text);
+	msg = (u8 *) strdup(text);
 	int i;
 	for (i = 0; (G8(text+i) != '\n') && (G8(text+i) != '\0'); i++)
@@ -170,8 +172,5 @@
 		size_t length)
 {
-	int i;
 	struct tls_data * data = (struct tls_data *) ptr;
-	u8 * buff;
-
 	data->tlsReq.data = realloc(data->tlsReq.data, data->tlsReq.datalength
 			+ length);
@@ -251,5 +250,5 @@
 
 int diameap_tls_get_data(struct tls_msg tlsmsg, u8** tls_data,
-		int * data_length)
+		u32 * data_length)
 {
 	if (tlsmsg.datalength > 0)
@@ -332,5 +331,5 @@
 
 	if (data == NULL)
-		return;
+		return EINVAL;
 	int pos = 0;
 	diameap_tls_new(tlsmsg);
Index: extensions/app_diameap/diameap_tls.h
===================================================================
--- extensions/app_diameap/diameap_tls.h	(revision 425)
+++ extensions/app_diameap/diameap_tls.h	(revision 438)
@@ -46,5 +46,4 @@
 #include <pthread.h>
 
-GCRY_THREAD_OPTION_PTHREAD_IMPL;
 
 
@@ -96,5 +95,5 @@
 int diameap_tls_set_flags(struct tls_msg * tlsmsg, u8 flags);
 
-int diameap_tls_get_data(struct tls_msg tlsmsg, u8** tls_data, int * data_length);
+int diameap_tls_get_data(struct tls_msg tlsmsg, u8** tls_data, u32 * data_length);
 int diameap_tls_set_data(struct tls_msg * tlsmsg, u8* tls_data, int data_length);
 
Index: extensions/app_diameap/plugins.h
===================================================================
--- extensions/app_diameap/plugins.h	(revision 425)
+++ extensions/app_diameap/plugins.h	(revision 438)
@@ -44,10 +44,10 @@
 
 
-static struct register_plugin *registerplugin = NULL;
 
-static int isregistered = 0;
 
 /* Macro that define the register functions of an EAP method */
 #define REGISTER_METHOD(_methodName, _configFunction, _initFunction, _initPickUpFunction, _buildReqFunction, _getTimeoutFunction, _checkFunction, _processFunction, _isDoneFunction, _getKeyFunction, _unregisterFunction, _datafreeFunction  ) \
+static struct register_plugin *registerplugin = NULL;	\
+static int isregistered = 0;	\
 int diameap_plugin_register() {	\
 		if (!isregistered){	\
Index: extensions/app_diameap/plugins/CMakeLists.txt
===================================================================
--- extensions/app_diameap/plugins/CMakeLists.txt	(revision 431)
+++ extensions/app_diameap/plugins/CMakeLists.txt	(revision 438)
@@ -14,8 +14,8 @@
 
 # EAP Identity plugin
-OPTION(BUILD_IDENTITY "Build EAP Identity Plugin " ON)
-	IF (BUILD_IDENTITY)
+OPTION(BUILD_EAP_IDENTITY "Build EAP Identity Plugin " ON)
+	IF (BUILD_EAP_IDENTITY)
 	   ADD_SUBDIRECTORY(eap_identity)
-	ENDIF (BUILD_IDENTITY)
+	ENDIF (BUILD_EAP_IDENTITY)
 
 # EAP MD5 plugin
Index: extensions/app_diameap/plugins/eap_identity/eap_identity.c
===================================================================
--- extensions/app_diameap/plugins/eap_identity/eap_identity.c	(revision 425)
+++ extensions/app_diameap/plugins/eap_identity/eap_identity.c	(revision 438)
@@ -136,5 +136,5 @@
 		goto end;
 	}
-	U8COPY(user,0,len,Respdata);
+	U8COPY((u8 *)user,0,len,Respdata);
 	user[length-5]='\0';
 
Index: extensions/app_diameap/plugins/eap_tls/eap_tls.h
===================================================================
--- extensions/app_diameap/plugins/eap_tls/eap_tls.h	(revision 425)
+++ extensions/app_diameap/plugins/eap_tls/eap_tls.h	(revision 438)
@@ -47,4 +47,5 @@
 int diameap_eap_tls_buildReq_data(struct tls_data * data,int id,struct eap_packet * eapPacket);
 int diameap_eap_tls_parse(struct tls_msg * eaptls,struct eap_packet eapPacket);
+int eaptlsparse(struct tls_config * conf);
 
 #endif /* EAP_TLS_H_ */
Index: extensions/app_diameap/plugins/eap_tls/eaptls.l
===================================================================
--- extensions/app_diameap/plugins/eap_tls/eaptls.l	(revision 425)
+++ extensions/app_diameap/plugins/eap_tls/eaptls.l	(revision 438)
@@ -47,4 +47,6 @@
 	yylloc->last_column += yyleng +1;	\
 	}	 
+	
+#define YY_NO_INPUT
 %}
 
@@ -53,5 +55,5 @@
 %option bison-bridge 
 %option bison-locations
-
+%option nounput
 %%
 	/* List of patterns and actions */
Index: extensions/app_diameap/plugins/eap_tls/eaptls.y
===================================================================
--- extensions/app_diameap/plugins/eap_tls/eaptls.y	(revision 425)
+++ extensions/app_diameap/plugins/eap_tls/eaptls.y	(revision 438)
@@ -127,5 +127,5 @@
 		if (fl == NULL) {
 			int ret = errno;
-			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open certificate file %s for reading",DIAMEAP_EXTENSION,certfile);
+			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open certificate file %s for reading: %s",DIAMEAP_EXTENSION,certfile,strerror(ret));
 			yyerror (&yylloc, config, "Error configuring certificate for EAP-TLS"); 
 			YYERROR;
@@ -144,5 +144,5 @@
 		if (fl == NULL) {
 			int ret = errno;
-			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open privateKey file %s for reading",DIAMEAP_EXTENSION,keyfile);
+			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open privateKey file %s for reading: %s",DIAMEAP_EXTENSION,keyfile,strerror(ret));
 			yyerror (&yylloc, config, "Error configuring privateKey for EAP-TLS"); 
 			YYERROR;
@@ -179,5 +179,5 @@
 		if (fl == NULL) {
 			int ret = errno;
-			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open CA file %s for reading",DIAMEAP_EXTENSION,cafile);
+			TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open CA file %s for reading: %s",DIAMEAP_EXTENSION,cafile,strerror(ret));
 			yyerror (&yylloc, config, "Error configuring CA file for EAP-TLS"); 
 			YYERROR;
@@ -211,5 +211,5 @@
 			if (fl == NULL) {
 				int ret = errno;
-				TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open CRL file %s for reading",DIAMEAP_EXTENSION,crlfile);
+				TRACE_DEBUG(INFO,"%s[EAP TLS plugin] Unable to open CRL file %s for reading: %s",DIAMEAP_EXTENSION,crlfile,strerror(ret));
 				yyerror (&yylloc, config, "Error configuring CRL file for EAP-TLS"); 
 				YYERROR;
