Index: libfdcore/messages.c
===================================================================
--- libfdcore/messages.c	(revision 1383)
+++ libfdcore/messages.c	(revision 1425)
@@ -43,4 +43,7 @@
 static struct dict_object * dict_avp_FAVP= NULL; /* Failed-AVP */
 static struct dict_object * dict_avp_RC  = NULL; /* Result-Code */
+static struct dict_object * dict_avp_ER  = NULL; /* Experimental-Result */
+static struct dict_object * dict_avp_VI  = NULL; /* Vendor-Id */
+static struct dict_object * dict_avp_ERC = NULL; /* Experimental-Result-Code */
 struct dict_object * fd_dict_avp_OSI = NULL; /* Origin-State-Id */
 struct dict_object * fd_dict_cmd_CER = NULL; /* Capabilities-Exchange-Request */
@@ -64,4 +67,7 @@
 	CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Error-Reporting-Host", &dict_avp_ERH , ENOENT)  );
 	CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Failed-AVP",      	&dict_avp_FAVP, ENOENT)  );
+	CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Experimental-Result", &dict_avp_ER, ENOENT)  );
+	CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Vendor-Id",		&dict_avp_VI, ENOENT)  );
+	CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Experimental-Result-Code", &dict_avp_ERC, ENOENT)  );
 
 	CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Disconnect-Cause", 	&fd_dict_avp_DC , ENOENT)  );
@@ -167,28 +173,24 @@
 
 
-/* Add Result-Code and eventually Failed-AVP, Error-Message and Error-Reporting-Host AVPs */
-int fd_msg_rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id )
+/* Add Result-Code or Experimental-Result, and eventually Failed-AVP, Error-Message and Error-Reporting-Host AVPs */
+int fd_msg_add_result( struct msg * msg, vendor_id_t vendor, struct dict_object * restype, char * rescode, char * errormsg, struct avp * optavp, int type_id )
 {
 	union avp_value val;
-	struct avp * avp_RC  = NULL;
-	struct avp * avp_EM  = NULL;
-	struct avp * avp_ERH = NULL;
-	struct avp * avp_FAVP= NULL;
 	uint32_t rc_val = 0;
 	int set_e_bit=0;
 	int std_err_msg=0;
 
-	TRACE_ENTRY("%p %s %p %p %d", msg, rescode, errormsg, optavp, type_id);
-
-	CHECK_PARAMS(  msg && rescode  );
+	TRACE_ENTRY("%p %d %p %s %p %p %d", msg, vendor, restype, rescode, errormsg, optavp, type_id);
+
+	CHECK_PARAMS(  msg && restype && rescode  );
 
 	/* Find the enum value corresponding to the rescode string, this will give the class of error */
 	{
 		struct dict_object * enum_obj = NULL;
+
+		/* Search in the restype */
 		struct dict_enumval_request req;
 		memset(&req, 0, sizeof(struct dict_enumval_request));
-
-		/* First, get the enumerated type of the Result-Code AVP (this is fast, no need to cache the object) */
-		CHECK_FCT(  fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, dict_avp_RC, &(req.type_obj), ENOENT  )  );
+		req.type_obj = restype;
 
 		/* Now search for the value given as parameter */
@@ -208,18 +210,56 @@
 	}
 
-	/* Create the Result-Code AVP */
-	CHECK_FCT( fd_msg_avp_new( dict_avp_RC, 0, &avp_RC ) );
-
-	/* Set its value */
-	memset(&val, 0, sizeof(val));
-	val.u32  = rc_val;
-	CHECK_FCT( fd_msg_avp_setvalue( avp_RC, &val ) );
-
-	/* Add it to the message */
-	CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_RC ) );
+	if (vendor == 0) {
+		/* Vendor 0; create the Result-Code AVP */
+		struct avp * avp_RC  = NULL;
+		CHECK_FCT( fd_msg_avp_new( dict_avp_RC, 0, &avp_RC ) );
+
+		/* Set its value */
+		memset(&val, 0, sizeof(val));
+		val.u32  = rc_val;
+		CHECK_FCT( fd_msg_avp_setvalue( avp_RC, &val ) );
+
+		/* Add it to the message */
+		CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_RC ) );
+	} else {
+		/* Vendor !0; create the Experimental-Result AVP */
+		struct avp * avp_ER  = NULL;
+		CHECK_FCT( fd_msg_avp_new( dict_avp_ER, 0, &avp_ER ) );
+
+		/* Create the Vendor-Id AVP and add to Experimental-Result */
+		{
+			struct avp * avp_VI  = NULL;
+			CHECK_FCT( fd_msg_avp_new( dict_avp_VI, 0, &avp_VI ) );
+
+			/* Set Vendor-Id value to vendor */
+			memset(&val, 0, sizeof(val));
+			val.u32  = vendor;
+			CHECK_FCT( fd_msg_avp_setvalue( avp_VI, &val ) );
+
+			/* Add it to Experimental-Result */
+			CHECK_FCT( fd_msg_avp_add( avp_ER, MSG_BRW_LAST_CHILD, avp_VI ) );
+		}
+
+		/* Create the Experimental-Result-Code AVP and add to Experimental-Result */
+		{
+			struct avp * avp_ERC  = NULL;
+			CHECK_FCT( fd_msg_avp_new( dict_avp_ERC, 0, &avp_ERC ) );
+
+			/* Set Experimental-Result-Code value to rc_val */
+			memset(&val, 0, sizeof(val));
+			val.u32  = rc_val;
+			CHECK_FCT( fd_msg_avp_setvalue( avp_ERC, &val ) );
+
+			/* Add it to Experimental-Result */
+			CHECK_FCT( fd_msg_avp_add( avp_ER, MSG_BRW_LAST_CHILD, avp_ERC ) );
+		}
+
+		/* Add it to the message */
+		CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_ER ) );
+	}
 
 	if (type_id == 2) {
 		/* Add the Error-Reporting-Host AVP */
-
+		struct avp * avp_ERH = NULL;
 		CHECK_FCT( fd_msg_avp_new( dict_avp_ERH, 0, &avp_ERH ) );
 
@@ -232,9 +272,9 @@
 		/* Add it to the message */
 		CHECK_FCT( fd_msg_avp_add( msg, MSG_BRW_LAST_CHILD, avp_ERH ) );
-
-	}
-
-	/* Now add the optavp in a FailedAVP if provided */
+	}
+
+	/* Now add the optavp in a Failed-AVP if provided */
 	if (optavp) {
+		struct avp * avp_FAVP= NULL;
 		struct avp * optavp_cpy = NULL;
 		struct avp_hdr *opt_hdr, *optcpy_hdr;
@@ -310,5 +350,5 @@
 	if (std_err_msg || errormsg) {
 		/* Add the Error-Message AVP */
-
+		struct avp * avp_EM  = NULL;
 		CHECK_FCT( fd_msg_avp_new( dict_avp_EM, 0, &avp_EM ) );
 
@@ -330,4 +370,11 @@
 
 	return 0;
+}
+
+int fd_msg_rescode_set( struct msg * msg, char * rescode, char * errormsg, struct avp * optavp, int type_id )
+{
+	struct dict_object * restype = NULL;
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_TYPE, TYPE_OF_AVP, dict_avp_RC, &restype, ENOENT ) );
+	return fd_msg_add_result(msg, 0, restype, rescode, errormsg, optavp, type_id);
 }
 
