changeset 420:c8a61dabea55

app_sip:Added LIR/LIA for SL
author Alexandre Westfahl <awestfahl@freediameter.net>
date Mon, 19 Jul 2010 16:46:33 +0900
parents 9cc48cd22e67
children 4cb54e85fc71
files extensions/app_sip/CMakeLists.txt extensions/app_sip/TODO extensions/app_sip/diamsip.c extensions/app_sip/diamsip.h extensions/app_sip/libdiamsip.c extensions/app_sip/locationinfo.c extensions/app_sip/locationinfosl.c extensions/app_sip/multimediaauth.c extensions/app_sip/pushprofile.c extensions/app_sip/registrationtermination.c extensions/test_sip/CMakeLists.txt extensions/test_sip/locationinfo.c extensions/test_sip/test_sip.c extensions/test_sip/test_sip.h
diffstat 14 files changed, 1023 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/app_sip/CMakeLists.txt	Mon Jul 12 22:56:33 2010 +0900
+++ b/extensions/app_sip/CMakeLists.txt	Mon Jul 19 16:46:33 2010 +0900
@@ -20,6 +20,9 @@
 	md5.c
 	multimediaauth.c
 	registrationtermination.c
+	pushprofile.c
+	locationinfo.c
+	locationinfosl.c
 )
 
 # Compile as a module
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_sip/TODO	Mon Jul 19 16:46:33 2010 +0900
@@ -0,0 +1,39 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net>						 *
+*													 *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. 	 *		
+*													 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the Teraoka Laboratory nor the 							 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of Teraoka Laboratory 						 *
+*   													 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+
+
+TODO List
+* add in malloc the size of char
--- a/extensions/app_sip/diamsip.c	Mon Jul 12 22:56:33 2010 +0900
+++ b/extensions/app_sip/diamsip.c	Mon Jul 19 16:46:33 2010 +0900
@@ -35,6 +35,7 @@
 *********************************************************************************************************/
 #include "diamsip.h"
 
+//Diameter-SIP server
 struct disp_hdl * diamsip_MAR_hdl=NULL;
 struct disp_hdl * diamsip_LIR_hdl=NULL;
 struct disp_hdl * diamsip_UAR_hdl=NULL;
@@ -42,6 +43,10 @@
 struct disp_hdl * diamsip_PPA_hdl=NULL;
 struct disp_hdl * diamsip_RTA_hdl=NULL;
 
+//Suscriber Locator
+struct disp_hdl * diamsipSL_LIR_hdl=NULL;
+
+
 
 struct disp_hdl * diamsip_default_hdl=NULL;
 struct session_handler * ds_sess_hdl;
@@ -70,6 +75,7 @@
 	TRACE_DEBUG(FULL,"# mysql_database: *%s*",as_conf->mysql_database);
 	TRACE_DEBUG(FULL,"# mysql_server: *%s*",as_conf->mysql_server);
 	TRACE_DEBUG(FULL,"# mysql_port: *%d*",as_conf->mysql_port);
+	TRACE_DEBUG(FULL,"# mysql_port: *%d*",as_conf->mysql_prefix);
 	TRACE_DEBUG(FULL,"***End of Diameter-SIP configuration extension***");
 }
 
@@ -89,7 +95,7 @@
 	
 	struct dict_object * app=NULL;
 	struct disp_when data;
-	pthread_t rtr_thread;
+	pthread_t rtr_thread, ppr_thread;
 	
 	/* Initialize configuration */
 	CHECK_FCT( as_conf_init() );
@@ -104,6 +110,9 @@
 		TRACE_DEBUG(INFO, "We need a configuration file for Diameter-SIP extension. See doc/ for an example.");
 	}
 	
+	//TODO: replace by configuration file!!
+	strcpy(as_conf->mysql_prefix,"as_");
+	
 	//We can dump the configuration extracted from app_sip.conf
 	//dump_config();
 	
@@ -117,6 +126,8 @@
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &sip_dict.Auth_Application_Id, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &sip_dict.Destination_Host, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sip_dict.Session_Id, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host", &sip_dict.Redirect_Host, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Redirect-Host-Usage", &sip_dict.Redirect_Host_Usage, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Auth-Data-Item", &sip_dict.SIP_Auth_Data_Item, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authorization", &sip_dict.SIP_Authorization, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authenticate", &sip_dict.SIP_Authenticate, ENOENT) );
@@ -142,7 +153,6 @@
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Algorithm", &sip_dict.Digest_Algorithm, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-QoP", &sip_dict.Digest_QOP, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "User-Name", &sip_dict.User_Name, ENOENT) );
-	
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-HA1", &sip_dict.Digest_HA1, ENOENT) );
 	
 	
@@ -150,22 +160,35 @@
 	memset(&data, 0, sizeof(data));
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Session Initiation Protocol (SIP) Application", &data.app, ENOENT) );
 	
-	
-	//**Command Codes
-	//MAR
-	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Multimedia-Auth-Request", &data.command, ENOENT) );
-	CHECK_FCT( fd_disp_register( diamsip_MAR_cb, DISP_HOW_CC, &data, &diamsip_MAR_hdl ) );
-	//RTA
-	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Answer", &data.command, ENOENT) );
-	CHECK_FCT( fd_disp_register( diamsip_RTA_cb, DISP_HOW_CC, &data, &diamsip_RTA_hdl ) );
-	
+	if(as_conf->mode==1)
+	{
+	  //**Command Codes
+	  //MAR
+	  CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Multimedia-Auth-Request", &data.command, ENOENT) );
+	  CHECK_FCT( fd_disp_register( diamsip_MAR_cb, DISP_HOW_CC, &data, &diamsip_MAR_hdl ) );
+	  //RTA
+	  CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Answer", &data.command, ENOENT) );
+	  CHECK_FCT( fd_disp_register( diamsip_RTA_cb, DISP_HOW_CC, &data, &diamsip_RTA_hdl ) );
+	  //PPA
+	  CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Push-Profile-Answer", &data.command, ENOENT) );
+	  CHECK_FCT( fd_disp_register( diamsip_PPA_cb, DISP_HOW_CC, &data, &diamsip_PPA_hdl ) );
+	  //LIR
+	  CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Request", &data.command, ENOENT) );
+	  CHECK_FCT( fd_disp_register( diamsip_LIR_cb, DISP_HOW_CC, &data, &diamsip_LIR_hdl ) );
+	}
+	if(as_conf->mode==2)
+	{
+	  //LIR
+	  CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Request", &data.command, ENOENT) );
+	  CHECK_FCT( fd_disp_register( diamsipSL_LIR_cb, DISP_HOW_CC, &data, &diamsipSL_LIR_hdl ) );
+	}
 	//Callback for unexpected messages
 	CHECK_FCT( fd_disp_register( diamsip_default_cb, DISP_HOW_APPID, &data, &diamsip_default_hdl ) );
 	
 	
 	//We start database connection
 	if(start_mysql_connection())
-		return 1;
+		return EINVAL;
 	
 	CHECK_FCT(fd_sess_handler_create(&ds_sess_hdl, free));
 	
@@ -173,7 +196,13 @@
 	if(pthread_create(&rtr_thread, NULL,rtr_socket, NULL))
 	{
 		TRACE_DEBUG(INFO,"Creation of thread failed, abort!");
-		return 1;
+		return EINVAL;
+	}
+	//Creation of thread for Push Profile	
+	if(pthread_create(&ppr_thread, NULL,ppr_socket, NULL))
+	{
+		TRACE_DEBUG(INFO,"Creation of thread failed, abort!");
+		return EINVAL;
 	}
 		
 
@@ -187,7 +216,7 @@
 //Cleanup callback
 void fd_ext_fini(void)
 {
-	
+	//TODO:unregister other callbacks
 	
 	(void) fd_disp_unregister(&diamsip_MAR_hdl);
 	CHECK_FCT_DO( fd_sess_handler_destroy(&ds_sess_hdl),return);
--- a/extensions/app_sip/diamsip.h	Mon Jul 12 22:56:33 2010 +0900
+++ b/extensions/app_sip/diamsip.h	Mon Jul 19 16:46:33 2010 +0900
@@ -52,6 +52,8 @@
 #define MODE_DSSERVER	0x1
 #define	MODE_SL	0x2
 
+//Redirect_Host_Usage
+#define ALL_USER	6
 
 /* The module configuration */
 struct as_conf {
@@ -61,7 +63,8 @@
 	char * mysql_password;
 	char * mysql_database;
 	char * mysql_server;
-	uint16_t  mysql_port;
+	char mysql_prefix[10]; //default: as_
+	uint16_t  mysql_port; //if 0, default port will be used
 	
 };
 extern struct as_conf * as_conf;
@@ -77,9 +80,14 @@
 void calc_md5(char *buffer, char * data);
 void clear_digest(uint8_t * digest, char * readable_digest, int digestlength);
 struct avp_hdr * walk_digest(struct avp *avp, int avp_code);
+
+
+//MySQL part
 int start_mysql_connection();
 void request_mysql(char *query);
 void close_mysql_connection();
+int get_diameter_uri(const unsigned char *sip_aor, const size_t sipaorlen, char ** diameter_uri, size_t *diameterurilen);
+
 
 void DigestCalcHA1(char * pszAlg,char * pszUserName,char * pszRealm,char * pszPassword,char * pszNonce,char * pszCNonce,HASHHEX SessionKey);
 void DigestCalcResponse(HASHHEX HA1,char * pszNonce,char * pszNonceCount,char * pszCNonce,char * pszQop,char * pszMethod,char * pszDigestUri,HASHHEX HEntity,HASHHEX Response);
@@ -89,6 +97,7 @@
 
 //thread procedure
 void *rtr_socket(void *);
+void *ppr_socket(void *);
 
 struct rtrsipaor
 {
@@ -100,7 +109,17 @@
 	char desthost[200];
 	int reason;
 };
+struct pprsipaor
+{
+	char username[200];
+	char label1[200];
+	char value1[200];
+	char label2[200];
+	char value2[200];
+	char desthost[200];  
+};
 int diamsip_RTR_cb(struct rtrsipaor structure);
+int diamsip_PPR_cb(struct pprsipaor structure);
 #define PORT 666 //TODO:put in conf file
 
 int ds_entry();
@@ -108,12 +127,22 @@
 int diamsip_default_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act);
 int diamsip_MAR_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act);
 int diamsip_RTA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act);
+int diamsip_PPA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act);
+int diamsip_LIR_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act);
+
+//Suscriber Locator
+int diamsipSL_LIR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act);
+//int diamsipSL_SAR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act);
+
 #define SQL_GETPASSWORD "SELECT `password` FROM ds_users WHERE `username` ='%s'"
 #define SQL_GETPASSWORD_LEN 52
 
-#define SQL_GETSIPURI "SELECT `sip_server_uri` FROM ds_users WHERE `username` ='%s'"
+#define SQL_GETSIPURI  "SELECT `sip_server_uri` FROM ds_users WHERE `username` ='%s'"
 #define SQL_GETSIPURI_LEN 60
 
+#define SQL_GETDIAMURI "SELECT `diameter_uri` FROM sl_sip_aor_map WHERE `sip_aor` ='%s'"
+#define SQL_GETDIAMURI_LEN 61
+
 #define SQL_SETSIPURI "UPDATE ds_users SET `sip_server_uri`='%s', `flag`=1 WHERE `username` ='%s'"
 #define SQL_SETSIPURI_LEN 74
 
@@ -139,6 +168,8 @@
 	struct dict_object * Destination_Host;
 	struct dict_object * User_Name;
 	struct dict_object * Session_Id;
+	struct dict_object * Redirect_Host;
+	struct dict_object * Redirect_Host_Usage;
 	struct dict_object * SIP_Auth_Data_Item;
 	struct dict_object * SIP_Authorization;
 	struct dict_object * SIP_Authenticate;
--- a/extensions/app_sip/libdiamsip.c	Mon Jul 12 22:56:33 2010 +0900
+++ b/extensions/app_sip/libdiamsip.c	Mon Jul 19 16:46:33 2010 +0900
@@ -33,7 +33,7 @@
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
 *********************************************************************************************************/
-#include <mysql.h>
+//#include <mysql.h>
 #include "diamsip.h"
 
 MYSQL *conn;
@@ -184,6 +184,86 @@
 	mysql_close(conn);
 	
 }
+
+int get_diameter_uri(const unsigned char *sip_aor, const size_t sipaorlen, char ** diameter_uri, size_t *diameterurilen)
+{
+  CHECK_PARAMS(sip_aor && sipaorlen);
+  
+  size_t querylen, sipaorpurelen;
+  char *query, *sipaor_pure;
+  int not_found=1;
+  
+  
+  
+      
+  //a sip aor must begin by "sip:" or "sips:" so it must at least be longer than 4 chars
+  if(sipaorlen<5)
+    return 2;
+  
+  //NOTE: each method has to purify sip_aor itself. You must remove quotes or special chars for security
+  
+  switch(as_conf->datasource)
+  {
+    //MySQL
+    case ASMYSQL:
+
+      querylen=SQL_GETDIAMURI_LEN + sipaorlen;
+      
+	  
+	  //We allocate the double size of SIP-URI because at worst it can be all quotes
+	  CHECK_MALLOC(sipaor_pure=malloc(sipaorlen*2+1));
+	  //We purify SIP-URI not to have forbidden characters
+	  sipaorpurelen=mysql_real_escape_string(conn, sipaor_pure, (const char *)sip_aor, sipaorlen);
+	  
+	  
+      query = malloc(querylen+sipaorpurelen+ 2);
+	  snprintf(query, querylen+1, SQL_GETDIAMURI, sipaor_pure);
+      
+      MYSQL_RES *res;
+      MYSQL_ROW row;
+      
+
+      //We make the query	
+      request_mysql(query);
+      res=mysql_use_result(conn);
+      if(res==NULL)
+      {
+		//We couldn't make the request
+		diameter_uri=NULL;
+		return 2;
+      }
+      TRACE_DEBUG(INFO,"***********%d|%d****************\n%s\n*********************************",sipaorlen,sipaorpurelen,query);
+      while ((row = mysql_fetch_row(res)) != NULL)
+      {
+		*diameterurilen=strlen(row[0]);
+		if(*diameterurilen>0)
+		{
+			CHECK_MALLOC(*diameter_uri=malloc(*diameterurilen+1));
+			strcpy(*diameter_uri,row[0]);
+			not_found=0;
+			break;
+		}
+      }
+      mysql_free_result(res);
+      free(query);
+	  free(sipaor_pure);
+      break;
+      
+    default:
+      
+      //We must never go here, if so, we must stop diameter_sip
+      diameter_uri=NULL;
+      return 2;
+      
+      break;
+  }
+  
+  //0 if it was found
+  return not_found;
+  
+}
+
+
 /*
 void nonce_add_element(char * nonce)
 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_sip/locationinfo.c	Mon Jul 19 16:46:33 2010 +0900
@@ -0,0 +1,114 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net>						 *
+*													 *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. 	 *		
+*													 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the Teraoka Laboratory nor the 							 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of Teraoka Laboratory 						 *
+*   													 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+#include "diamsip.h"
+
+
+int diamsip_LIR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act)
+{
+	TRACE_ENTRY("%p %p %p %p", msg, paramavp, sess, act);
+	
+	struct msg *ans, *qry;
+	struct avp *avp, *groupedavp;
+	struct avp_hdr *avphdr;
+	union avp_value value;
+	
+	//Result_Code to return in the answer
+	char result[55];
+	
+	if (msg == NULL)
+		return EINVAL;
+
+	
+	// Create answer header 
+	qry = *msg;
+	CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+	ans = *msg;
+	
+	// Add the Auth-Session-State AVP 
+	{
+		
+		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+		CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
+		
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+		CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+		CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	
+	//TODO: wait for answer from authors to clear how to find SIP server!
+	//Add a SIP_Server_URI
+	{
+		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
+		CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
+		
+		//We extract Realm from SIP_AOR
+		char *realm=NULL;
+		
+		
+		realm = strtok( (char *)(avphdr->avp_value->os.data), "@" );
+		realm = strtok( NULL, "@" );
+		
+		if(realm!=NULL)
+		{
+			CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_URI, 0, &avp ) );
+			value.os.data=(unsigned char *)realm;
+			value.os.len=strlen(realm);
+			CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+			CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+		}
+		else
+		{
+			strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+			goto out;
+		}
+	}
+	
+	
+	
+	
+out:
+	CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) );
+	
+	//DEBUG
+	fd_msg_dump_walk(INFO,qry);
+	fd_msg_dump_walk(INFO,ans);
+	
+	CHECK_FCT( fd_msg_send( msg, NULL, NULL ));
+	
+	
+	
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_sip/locationinfosl.c	Mon Jul 19 16:46:33 2010 +0900
@@ -0,0 +1,177 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net>						 *
+*													 *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. 	 *		
+*													 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the Teraoka Laboratory nor the 							 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of Teraoka Laboratory 						 *
+*   													 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+#include "diamsip.h"
+
+//This callback is specific to SUSCRIBER LOCATOR. We must look for the "serving" SIP server
+int diamsipSL_LIR_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act)
+{
+	TRACE_ENTRY("%p %p %p %p", msg, paramavp, sess, act);
+	
+	struct msg *ans, *qry;
+	struct avp *avp, *groupedavp;
+	struct avp_hdr *avphdr;
+	union avp_value value;
+	
+	//Result_Code to return in the answer
+	char result[55];
+	int ret=0;
+	
+	
+	if (msg == NULL)
+		return EINVAL;
+
+	
+	
+	// Create answer header 
+	qry = *msg;
+	CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+	ans = *msg;
+	
+	//DEBUG
+	fd_msg_dump_walk(INFO,qry);
+	
+	//Add the Auth-Application-Id 
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+		value.i32 = 6;
+		CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+	}
+	
+	// Add the Auth-Session-State AVP 
+	{
+		
+		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+		CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
+		
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+		CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+		CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	
+	
+	// Add the Redirect Host AVP 
+	{
+		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
+		CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
+		int diameterurilen;
+		char * diameter_uri=NULL;
+		
+		TRACE_DEBUG(INFO,"***********%d*********************************************",avphdr->avp_value->os.len);
+		
+		ret=get_diameter_uri(avphdr->avp_value->os.data, avphdr->avp_value->os.len, &diameter_uri, &diameterurilen);
+		
+		//found
+		if(ret==0)
+		{
+		  if(diameter_uri==NULL)
+		  {
+			  //There is a problem because we must get a Diameter_URI here
+			  strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+			  goto out;
+		  }
+		  else
+		  {
+		    CHECK_FCT( fd_msg_avp_new ( sip_dict.Redirect_Host, 0, &avp ) );
+		    value.os.data=diameter_uri;
+		    value.os.len=strlen(diameter_uri);
+		    CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		    CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+		    
+		    CHECK_FCT( fd_msg_avp_new ( sip_dict.Redirect_Host_Usage, 0, &avp ) );
+		    value.i32=ALL_USER; //All the request about the same user must be sent to this server
+		    CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		    CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+		    strcpy(result,"DIAMETER_SUCCESS");
+		  }
+		}
+		else if(ret==1)
+		{//not found
+			//We don't know this SIP_AOR in SL, that means 
+			strcpy(result,"DIAMETER_ERROR_USER_UNKNOWN");
+			goto out;
+		}
+		else
+		{// returned 2, impossible to make request
+			//We couldn't make the request, we must stop process!
+			strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+			goto out;
+		}
+	}
+	
+	/*
+	//TODO: wait for answer from authors to clear how to find SIP server!
+	//Add a SIP_Server_URI
+	{
+		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_AOR, &avp) );
+		CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
+		
+		//We extract Realm from SIP_AOR
+		char *realm=NULL;
+		
+		
+		realm = strtok( (char *)(avphdr->avp_value->os.data), "@" );
+		realm = strtok( NULL, "@" );
+		
+		if(realm!=NULL)
+		{
+			CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Server_URI, 0, &avp ) );
+			value.os.data=(unsigned char *)realm;
+			value.os.len=strlen(realm);
+			CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+			CHECK_FCT( fd_msg_avp_add ( ans, MSG_BRW_LAST_CHILD, avp) );
+		}
+		else
+		{
+			strcpy(result,"DIAMETER_UNABLE_TO_COMPLY");
+			goto out;
+		}
+	}
+	
+	*/
+	
+	
+out:
+	CHECK_FCT( fd_msg_rescode_set( ans, result, NULL, NULL, 1 ) );
+	
+	
+	
+	CHECK_FCT( fd_msg_send( msg, NULL, NULL ));
+	
+	
+	
+	return 0;
+}
--- a/extensions/app_sip/multimediaauth.c	Mon Jul 12 22:56:33 2010 +0900
+++ b/extensions/app_sip/multimediaauth.c	Mon Jul 19 16:46:33 2010 +0900
@@ -56,7 +56,7 @@
 	struct ds_nonce *storednonce=NULL;
 	
 	
-	TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
+	TRACE_ENTRY("%p %p %p %p", msg, paramavp, sess, act);
 	
 	if (msg == NULL)
 		return EINVAL;
@@ -222,14 +222,14 @@
 				int sipurilen=0;
 
 				//We allocate the double size of SIP-URI because at worst it can be all quotes
-				sipuri=malloc(avphdr->avp_value->os.len*2+1);
+				CHECK_MALLOC(sipuri=malloc(avphdr->avp_value->os.len*2+1));
 				//We purify SIP-URI not to have forbidden characters
 				sipurilen=mysql_real_escape_string(conn, sipuri, (const char *)avphdr->avp_value->os.data, avphdr->avp_value->os.len);
 				
 				
 				//We get the SIP-URI assignated to the user
 				querylen=SQL_GETSIPURI_LEN + usernamelen;
-				query = malloc(querylen+2);
+				CHECK_MALLOC(query = malloc(querylen+2));
 				snprintf(query, querylen+1, SQL_GETSIPURI, username);
 
 				//We make the query
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_sip/pushprofile.c	Mon Jul 19 16:46:33 2010 +0900
@@ -0,0 +1,319 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net>						 *
+*													 *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. 	 *		
+*													 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the Teraoka Laboratory nor the 							 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of Teraoka Laboratory 						 *
+*   													 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+#include "diamsip.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+typedef int SOCKET;
+typedef struct sockaddr_in SOCKADDR_IN;
+typedef struct sockaddr SOCKADDR;
+
+//Procedure which always wait for data on socket 
+void *ppr_socket(void *arg)
+{
+	/*
+	SOCKET sock;
+    SOCKADDR_IN sin, csin;
+    struct rtrsipaor rtrsip;
+    int rcvbytes=0;
+	sock = socket(AF_INET, SOCK_STREAM, 0);
+	sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+    sin.sin_family = AF_INET;
+    sin.sin_port = htons(PORT);
+    socklen_t sinsize = sizeof(csin);
+	int accepted=0;
+
+    
+	if(!bind(sock, (SOCKADDR*)&sin, sizeof(sin)))
+	{
+		if(listen(sock,1))
+		{
+			TRACE_DEBUG(INFO,"ERROR on listen!");
+		}
+		
+		while(1)
+		{
+			accepted=accept(sock, (struct sockaddr *)&csin,&sinsize);
+			if(accepted>-1)
+			{
+				rcvbytes=recv(accepted, &rtrsip, sizeof(struct rtrsipaor),0);
+				
+				if(rcvbytes>-1)
+				{
+					//We received something, we can send an PPR
+					diamsip_PPR_cb(pprsip);
+				}
+			}
+		}
+		
+		
+	}
+	else
+		TRACE_DEBUG(INFO,"Can't create socket!");
+*/	
+	
+	pthread_exit(NULL);
+	
+}
+//Called to send a PPR
+int diamsip_PPR_cb(struct pprsipaor structure)
+{
+	/*
+	TRACE_ENTRY("%p", structure);
+	
+	int got_username=0;
+	int got_streason=0;
+	int num_aor=0;//How many SIP-AOR?
+	struct dict_object * rtr_model=NULL;
+	struct msg * message=NULL;
+	struct avp *groupedavp=NULL, *avp=NULL;
+	struct session *sess=NULL;
+	union avp_value value;
+	
+	//We must check that we have all needed value in structure
+	if(structure.username[0]!='\0')
+		got_username=1;
+	
+	if(structure.sip_aor1[0]!='\0')
+	{	
+		num_aor++;
+		if(structure.sip_aor2[0]!='\0')
+		{
+			num_aor++;
+			if(structure.sip_aor3[0]!='\0')
+				num_aor++;
+		}
+	}
+	
+	if(structure.strreason!='\0')
+		got_streason=1;
+	
+	
+	TRACE_DEBUG(INFO,"We have %d SIP_AOR",num_aor);
+	
+	if((got_username + num_aor)==0)
+	{
+		//We must have a least a SIP_AOR or a Username
+		TRACE_DEBUG(INFO,"Can not proceed because there is no SIP_AOR or Username");
+		return EINVAL;
+	}
+	if(structure.reason<0)
+	{
+		//We must have a least a SIP_AOR or a Username
+		TRACE_DEBUG(INFO,"Incorrect Reason-Code");
+		return EINVAL;
+	}
+	
+	if(structure.desthost[0]=='\0')
+	{
+		//We must have a least a SIP_AOR or a Username
+		TRACE_DEBUG(INFO,"No Destination_Host was provided!");
+		return EINVAL;
+	}
+	//Create the base message for an RTR
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Request", &rtr_model, ENOENT) );
+	CHECK_FCT( fd_msg_new (rtr_model, 0, &message));
+	
+	// Create a new session 
+	{
+		CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, "app_sip", 7 ));
+		char * sid;
+		CHECK_FCT( fd_sess_getsid ( sess, &sid ));
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
+		value.os.data = (uint8_t *)sid;
+		value.os.len  = strlen(sid);
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
+	}
+	
+	
+	//Auth_Session_State
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+		value.i32=1;
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	
+	//Origin_Host & Origin_Realm
+	CHECK_FCT( fd_msg_add_origin ( message, 0 ));
+	
+	//Destination_Host
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) );
+		value.os.data=(unsigned char *)structure.desthost;
+		value.os.len=(size_t)strlen(structure.desthost);
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	
+	
+	//SIP Deregistration Reason (Grouped AVP)
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Deregistration_Reason, 0, &groupedavp ) );
+		
+		//Reason Code
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Reason_Code, 0, &avp ) );
+		value.i32=structure.reason;
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add( groupedavp, MSG_BRW_LAST_CHILD, avp ) );
+		
+		if(got_streason)
+		{
+			//Reason Info
+			CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Reason_Info, 0, &avp ) );
+			value.os.data=(unsigned char *)structure.strreason;
+			value.os.len=(size_t)strlen(structure.strreason);
+			CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+			CHECK_FCT( fd_msg_avp_add( groupedavp, MSG_BRW_LAST_CHILD, avp ) );
+		}
+		
+		//We add the grouped AVP to the message
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, groupedavp ) );
+	}
+	
+	//Username
+	{
+		if(got_username)
+		{
+			CHECK_FCT( fd_msg_avp_new ( sip_dict.User_Name, 0, &avp ) );
+			value.os.data=(unsigned char *)structure.username;
+			value.os.len=(size_t)strlen(structure.username);
+			CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+			CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+		}
+	}
+	
+	//SIP_AOR
+	{
+		if(num_aor>0)
+		{
+			CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+			value.os.data=(unsigned char *)structure.sip_aor1;
+			value.os.len=(size_t)strlen(structure.sip_aor1);
+			CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+			CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+			if(num_aor>1)
+			{
+				CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+				value.os.data=(unsigned char *)structure.sip_aor2;
+				value.os.len=(size_t)strlen(structure.sip_aor2);
+				CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+				CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+				if(num_aor>2)
+				{
+					CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+					value.os.data=(unsigned char *)structure.sip_aor3;
+					value.os.len=(size_t)strlen(structure.sip_aor3);
+					CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+					CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+				}
+			}
+		}
+	}
+	
+	fd_msg_dump_walk(INFO,message);
+	CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
+	*/
+	return 0;
+}
+
+//Called when an PPA arrive
+int diamsip_PPA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act)
+{
+	//TODO: PPA reception
+/*
+	//TODO:remove unused variables
+	struct msg *ans, *qry;
+	struct avp *avp, *a2, *authdataitem;
+	struct msg_hdr * header = NULL;
+	struct avp_hdr * avphdr=NULL, *avpheader=NULL, *avpheader_auth=NULL,*digestheader=NULL;
+	union avp_value val;
+	int found_cnonce=0;
+	struct avp * tempavp=NULL,*sipAuthentication=NULL,*sipAuthenticate=NULL;
+	char * result;
+	int idx=0, idx2=0, number_of_auth_items=0,i=0;
+	//Flags and variables for Database
+	int sipurinotstored=0, authenticationpending=0, querylen=0, usernamelen=0;
+	char *query=NULL,*username=NULL;
+	
+	
+	
+	TRACE_ENTRY("%p %p %p %p", msg, avp, sess, act);
+	
+	if (msg == NULL)
+		return EINVAL;
+	
+	
+	// Create answer header 
+	qry = *msg;
+	CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
+	ans = *msg;	
+	
+	
+	// Add the Auth-Session-State AVP 
+	{
+		
+		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
+		CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
+		
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+		CHECK_FCT( fd_msg_avp_setvalue( avp, avphdr->avp_value ) );
+		CHECK_FCT( fd_msg_avp_add( ans, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	
+	CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.SIP_Deregistration_Reason, &avp) );
+	CHECK_FCT( fd_msg_avp_hdr( avp, &avphdr )  );
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	*/
+	return 0;
+	
+}
+
--- a/extensions/app_sip/registrationtermination.c	Mon Jul 12 22:56:33 2010 +0900
+++ b/extensions/app_sip/registrationtermination.c	Mon Jul 19 16:46:33 2010 +0900
@@ -47,18 +47,16 @@
 void *rtr_socket(void *arg)
 {
 	SOCKET sock;
-    SOCKADDR_IN sin, csin;
-    struct rtrsipaor rtrsip;
-    int rcvbytes=0;
+	SOCKADDR_IN sin, csin;
+	struct rtrsipaor rtrsip;
+	int rcvbytes=0;
 	sock = socket(AF_INET, SOCK_STREAM, 0);
 	sin.sin_addr.s_addr = inet_addr("127.0.0.1");
-    sin.sin_family = AF_INET;
-    sin.sin_port = htons(PORT);
-    socklen_t sinsize = sizeof(csin);
+	sin.sin_family = AF_INET;
+	sin.sin_port = htons(PORT);
+	socklen_t sinsize = sizeof(csin);
 	int accepted=0;
 
-    TRACE_DEBUG(INFO,"############********************THREAD OPEN \n********************\n********************\n");
-    
 	if(!bind(sock, (SOCKADDR*)&sin, sizeof(sin)))
 	{
 		if(listen(sock,1))
@@ -72,27 +70,19 @@
 			if(accepted>-1)
 			{
 				rcvbytes=recv(accepted, &rtrsip, sizeof(struct rtrsipaor),0);
-	
 				
 				if(rcvbytes>-1)
 				{
+					//We received something, we can send an RTR
 					diamsip_RTR_cb(rtrsip);
-					
-					
 				}
 			}
 		}
-		
-		
 	}
 	else
 		TRACE_DEBUG(INFO,"Can't create socket!");
 
 	
-	
-	
-	
-	TRACE_DEBUG(INFO,"############********************THREAD CLOSED \n********************\n********************\n");
 	pthread_exit(NULL);
 	
 }
@@ -129,7 +119,7 @@
 		got_streason=1;
 	
 	
-	TRACE_DEBUG(INFO,"We have %d SIP_AOR",num_aor);
+	TRACE_DEBUG(FULL,"Request for %d SIP_AOR to be deregistred.",num_aor);
 	
 	if((got_username + num_aor)==0)
 	{
@@ -166,6 +156,13 @@
 		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
 	}
 	
+	//Add the Auth-Application-Id 
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+		value.i32 = 6;
+		CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, avp) );
+	}
 	
 	//Auth_Session_State
 	{
@@ -252,6 +249,7 @@
 		}
 	}
 	
+	//TODO:remove for debug
 	fd_msg_dump_walk(INFO,message);
 	CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
 	
--- a/extensions/test_sip/CMakeLists.txt	Mon Jul 12 22:56:33 2010 +0900
+++ b/extensions/test_sip/CMakeLists.txt	Mon Jul 19 16:46:33 2010 +0900
@@ -8,6 +8,9 @@
 SET( TEST_SIP_SRC
 	test_sip.c
 	test_sip.h
+	multimediaauth.c
+	locationinfo.c
+	registrationtermination.c
 )
 
 # Compile as a module
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/test_sip/locationinfo.c	Mon Jul 19 16:46:33 2010 +0900
@@ -0,0 +1,133 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net>						 *
+*													 *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. 	 *		
+*													 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the Teraoka Laboratory nor the 							 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of Teraoka Laboratory 						 *
+*   													 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+#include "test_sip.h"
+
+//Called to send a LIR
+int test_sip_LIR_cb()
+{
+	struct dict_object * lir_model=NULL;
+	struct msg * message=NULL;
+	struct avp *avp=NULL;
+	struct session *sess=NULL;
+	union avp_value value;
+	
+	//Fake values START
+	unsigned char *sip_aor="sip:aw-lappy@tera.ics.keio.ac.jp";
+	size_t aor_len=strlen(sip_aor); 
+	char *destination_realm="tera.ics.keio.ac.jp";
+	size_t destination_realmlen=strlen(destination_realm);
+	char *destination_host="biwa.tera.ics.keio.ac.jp";
+	size_t destination_hostlen=strlen(destination_host);
+	//Fake values STOP
+	
+	//Create the base message for an RTR
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Request", &lir_model, ENOENT) );
+	CHECK_FCT( fd_msg_new (lir_model, 0, &message));
+	
+	
+		
+	// Create a new session 
+	{
+		CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, "appsip", 6 ));
+		char * sid;
+		CHECK_FCT( fd_sess_getsid ( sess, &sid ));
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
+		value.os.data = (uint8_t *)sid;
+		value.os.len  = strlen(sid);
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
+	}
+	
+	//Add the Auth-Application-Id 
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Application_Id, 0, &avp ) );
+		value.i32 = 6;
+		CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add ( message, MSG_BRW_LAST_CHILD, avp) );
+	}
+	
+	//Auth_Session_State
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+		value.i32=1;
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	
+	//Origin_Host & Origin_Realm
+	CHECK_FCT( fd_msg_add_origin ( message, 0 ));
+	
+	//Destination_Host
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) );
+		value.os.data=(unsigned char *)destination_host;
+		value.os.len=destination_hostlen;
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	//Destination_Realm
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Realm, 0, &avp ) );
+		value.os.data=(unsigned char *)destination_realm;
+		value.os.len=destination_realmlen;
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	
+	
+	
+	//SIP_AOR
+	{
+		
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+		value.os.data=sip_aor;
+		value.os.len=aor_len;
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+			
+	}
+	
+	fd_msg_dump_walk(INFO,message);
+	CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
+	
+	return 0;
+}
+
+int test_sip_LIA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act)
+{
+	
+	return 0;
+}
--- a/extensions/test_sip/test_sip.c	Mon Jul 12 22:56:33 2010 +0900
+++ b/extensions/test_sip/test_sip.c	Mon Jul 19 16:46:33 2010 +0900
@@ -37,7 +37,12 @@
 
 #include"test_sip.h"
 
-
+struct disp_hdl * test_sip_MAR_hdl=NULL;
+struct disp_hdl * test_sip_LIR_hdl=NULL;
+struct disp_hdl * test_sip_UAR_hdl=NULL;
+struct disp_hdl * test_sip_SAR_hdl=NULL;
+struct disp_hdl * test_sip_PPA_hdl=NULL;
+struct disp_hdl * test_sip_RTA_hdl=NULL;
 
 struct disp_hdl * test_sip_MAA_hdl=NULL;
 struct disp_hdl * test_sip_LIA_hdl=NULL;
@@ -52,10 +57,11 @@
 
 //configuration stucture
 struct ts_conf * ts_conf=NULL;
-static struct ts_conf app_sip_conf;
+static struct ts_conf test_sip_conf;
+
 
 //dictionary of SIP
-struct test_sip_dict sip_dict;
+struct sip_dict sip_dict;
 
 int test_sip_default_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act)
 {
@@ -64,14 +70,8 @@
 	return 0;
 }
 
-username = "awestfahl"
-password = "test"
-sip_aor = "sip:awestfahl@tera.ics.keio.ac.jp"
 
-#Destination information
-destination_realm = "freediameter.net"
-destination_sip = "sip:awestfahl@freediameter.net"
-
+/*
 void dump_config()
 {
 	TRACE_DEBUG(FULL,"***Configuration of TEST Diameter-SIP extension***");
@@ -82,7 +82,7 @@
 	TRACE_DEBUG(FULL,"# destination_sip: *%s*",ts_conf->destination_sip);
 	TRACE_DEBUG(FULL,"***End of TEST Diameter-SIP configuration extension***");
 }
-
+*/
 static int ts_conf_init(void)
 {
 	ts_conf=&test_sip_conf;
@@ -93,15 +93,15 @@
 }
 
 /* entry point */
-int as_entry(char * conffile)
+int ts_entry(char * conffile)
 {
 	TRACE_ENTRY("%p", conffile);
 	
 	struct dict_object * app=NULL;
 	struct disp_when data;
 	
-	/* Initialize configuration */
-	CHECK_FCT( ts_conf_init() );
+	/* Initialize configuration 
+	//CHECK_FCT( ts_conf_init() );
 	
 	
 	//We parse the configuration file
@@ -115,6 +115,8 @@
 	
 	//We can dump the configuration extracted from app_sip.conf
 	dump_config();
+	*/
+	
 	
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_APPLICATION, APPLICATION_BY_NAME, "Diameter Session Initiation Protocol (SIP) Application", &app, ENOENT) );
 	CHECK_FCT( fd_disp_app_support ( app, NULL, 1, 0 ) );
@@ -124,6 +126,9 @@
 	//We set usefull AVPs 
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Session-State", &sip_dict.Auth_Session_State, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &sip_dict.Auth_Application_Id, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &sip_dict.Destination_Host, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Realm", &sip_dict.Destination_Realm, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sip_dict.Session_Id, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Auth-Data-Item", &sip_dict.SIP_Auth_Data_Item, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authorization", &sip_dict.SIP_Authorization, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authenticate", &sip_dict.SIP_Authenticate, ENOENT) );
@@ -133,6 +138,9 @@
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-URI", &sip_dict.SIP_Server_URI, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Method", &sip_dict.SIP_Method, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-AOR", &sip_dict.SIP_AOR, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Deregistration-Reason", &sip_dict.SIP_Deregistration_Reason, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Code", &sip_dict.SIP_Reason_Code, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Info", &sip_dict.SIP_Reason_Info, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Realm", &sip_dict.Digest_Realm, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-URI", &sip_dict.Digest_URI, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Nonce", &sip_dict.Digest_Nonce, ENOENT) );
@@ -156,23 +164,31 @@
 	
 	
 	//**Command Codes
+	/**/
 	//MAR
-	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Multimedia-Auth-Request", &data.command, ENOENT) );
-	CHECK_FCT( fd_disp_register( test_sip_MAR_cb, DISP_HOW_CC, &data, &test_sip_MAR_hdl ) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Multimedia-Auth-Answer", &data.command, ENOENT) );
+	CHECK_FCT( fd_disp_register( test_sip_MAA_cb, DISP_HOW_CC, &data, &test_sip_MAA_hdl ) );
+	
 	//RTR
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Request", &data.command, ENOENT) );
-	CHECK_FCT( fd_disp_register( test_sip_RTR_cb, DISP_HOW_CC, &data, &test_sip_RTA_hdl ) );
+	CHECK_FCT( fd_disp_register( test_sip_RTR_cb, DISP_HOW_CC, &data, &test_sip_RTR_hdl ) );
+	
+	//LIA
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Location-Info-Answer", &data.command, ENOENT) );
+	CHECK_FCT( fd_disp_register( test_sip_LIA_cb, DISP_HOW_CC, &data, &test_sip_LIA_hdl ) );
 	
 	
 	//Callback for unexpected messages
 	CHECK_FCT( fd_disp_register( test_sip_default_cb, DISP_HOW_APPID, &data, &test_sip_default_hdl ) );
 	
-	
+	/*
 	//We start database connection
 	if(start_mysql_connection())
 		return 1;
+	*/
 	
-	CHECK_FCT(fd_sess_handler_create(&ds_sess_hdl, free));
+	CHECK_FCT(fd_sess_handler_create(&ts_sess_hdl, free));
+	CHECK_FCT( fd_sig_register(30, "test_sip", (void *)test_sip_LIR_cb ) );
 	
 	return 0;
 }
@@ -180,14 +196,14 @@
 //Cleanup callback
 void fd_ext_fini(void)
 {
-	
+	/*
 	if (test_sip_MAR_cb) {
 		(void) fd_disp_unregister(&test_sip_MAR_hdl);
 		CHECK_FCT_DO( fd_sess_handler_destroy(&ds_sess_hdl),return);
 	}
-	
+	*/
 	//We close database connection
-	close_mysql_connection();
+	//close_mysql_connection();
 	
 
 	
--- a/extensions/test_sip/test_sip.h	Mon Jul 12 22:56:33 2010 +0900
+++ b/extensions/test_sip/test_sip.h	Mon Jul 19 16:46:33 2010 +0900
@@ -33,24 +33,33 @@
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
 *********************************************************************************************************/
-
+#include <freeDiameter/extension.h>
+#include <sys/time.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <gcrypt.h>
+#include <string.h>
+#include <mysql.h>
 
 /* The module configuration */
-struct test_sip_conf {
+struct ts_conf {
 	char * destination_sip; 
 	char * destination_realm;
 	char * username;
 	char * password;
 	char * sip_aor;
 };
-extern struct test_sip_conf * test_sip_conf;
-
+extern struct ts_conf * ts_conf;
 
 //Storage for some usefull AVPs
 struct sip_dict{
 	struct dict_object * Auth_Session_State;
 	struct dict_object * Auth_Application_Id;
+	struct dict_object * Destination_Host;
+	struct dict_object * Destination_Realm;
 	struct dict_object * User_Name;
+	struct dict_object * Session_Id;
 	struct dict_object * SIP_Auth_Data_Item;
 	struct dict_object * SIP_Authorization;
 	struct dict_object * SIP_Authenticate;
@@ -60,6 +69,9 @@
 	struct dict_object * SIP_Server_URI;
 	struct dict_object * SIP_Method;
 	struct dict_object * SIP_AOR;
+	struct dict_object * SIP_Deregistration_Reason;
+	struct dict_object * SIP_Reason_Code;
+	struct dict_object * SIP_Reason_Info;
 	struct dict_object * Digest_URI;		
 	struct dict_object * Digest_Nonce;
 	struct dict_object * Digest_Nonce_Count;
@@ -75,12 +87,15 @@
 };
 
 extern  struct sip_dict  sip_dict;
-
+extern struct session_handler * ts_sess_hdl;
 
+int ts_entry();
+void fd_ext_fini(void);
 
+int test_sip_LIR_cb();
 
 int test_sip_default_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act);
 int test_sip_MAA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act);
 int test_sip_RTR_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act);
+int test_sip_LIA_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act);
 
-
"Welcome to our mercurial repository"