فهرست منبع

ims_registrar_pcscf: Added functionality to unREGISTER a contact, eg. based on a failed network ping

Carsten Bock 10 سال پیش
والد
کامیت
b859f8ca20

+ 75 - 2
modules/ims_registrar_pcscf/reg_mod.c

@@ -114,6 +114,7 @@ static int w_follows_service_routes(struct sip_msg* _m, char* _d, char* _foo);
 static int w_force_service_routes(struct sip_msg* _m, char* _d, char* _foo);
 static int w_is_registered(struct sip_msg* _m, char* _d, char* _foo);
 static int w_reginfo_handle_notify(struct sip_msg* _m, char* _d, char* _foo);
+static int w_unregister(struct sip_msg* _m, char* _d, char* _aor, char* _received_host, char* _received_port);
 
 static int w_assert_identity(struct sip_msg* _m, char* _d, char* _preferred_uri);
 static int w_assert_called_identity(struct sip_msg* _m, char* _d, char* _foo);
@@ -125,6 +126,7 @@ static int domain_fixup(void** param, int param_no);
 static int domain_uri_fixup(void** param, int param_no);
 static int save_fixup2(void** param, int param_no);
 static int assert_identity_fixup(void ** param, int param_no);
+static int unregister_fixup(void ** param, int param_no);
 
 /* Pseudo-Variables */
 static int pv_get_asserted_identity_f(struct sip_msg *, pv_param_t *, pv_value_t *);
@@ -151,7 +153,8 @@ static cmd_export_t cmds[] = {
 	{"pcscf_assert_called_identity",(cmd_function)w_assert_called_identity, 1,      assert_identity_fixup,  0,ONREPLY_ROUTE },
 	{"reginfo_handle_notify",       (cmd_function)w_reginfo_handle_notify,  1,      domain_fixup,           0,REQUEST_ROUTE},
         {"lookup_transport",		(cmd_function)w_lookup_transport,       1,      domain_fixup,           0,REQUEST_ROUTE|FAILURE_ROUTE},
-        {"lookup_transport",		(cmd_function)w_lookup_transport,       2,      domain_uri_fixup,        0,REQUEST_ROUTE|FAILURE_ROUTE},
+        {"lookup_transport",		(cmd_function)w_lookup_transport,       2,      domain_uri_fixup,       0,REQUEST_ROUTE|FAILURE_ROUTE},
+        {"pcscf_unregister",		(cmd_function)w_unregister,		4,      unregister_fixup,       0,ANY_ROUTE},
 	
 	{0, 0, 0, 0, 0, 0}
 };
@@ -373,7 +376,7 @@ static int domain_uri_fixup(void** param, int param_no)
 		}
 		*param = (void*)d;
 	} else {
-            fixup_var_pve_12(param, param_no);
+            fixup_var_pve_str_12(param, param_no);
         }
         
 	return 0;
@@ -486,6 +489,76 @@ static int w_assert_identity(struct sip_msg* _m, char* _d, char* _preferred_uri)
 	return assert_identity( _m, (udomain_t*)_d, identity);
 }
 
+/*! \brief
+ * Fixup for "assert_identity" function - both domain and URI to be asserted
+ */
+static int unregister_fixup(void ** param, int param_no) {
+	if (param_no == 1) {
+		return domain_fixup(param,param_no);
+	} else {
+		pv_elem_t *model=NULL;
+		str s;
+
+		/* convert to str */
+		s.s = (char*)*param;
+		s.len = strlen(s.s);
+
+		model = NULL;
+		if(s.len==0) {
+			LM_ERR("no param!\n");
+			return E_CFG;
+		}
+		if(pv_parse_format(&s, &model)<0 || model==NULL) {
+			LM_ERR("wrong format [%s]!\n", s.s);
+			return E_CFG;
+		}
+		*param = (void*)model;
+		return 0;
+	}
+	return E_CFG;
+}
+
+
+static int w_unregister(struct sip_msg* _m, char* _d, char* _aor, char* _received_host, char* _received_port) {
+	pv_elem_t *model;
+	str aor;
+	str received_host;
+	str received_port;
+	int port = 0;
+
+	if ((_aor == NULL) || (_received_host == NULL) || (_received_port == NULL)) {
+		LM_ERR("error - bad parameters\n");
+		return -1;
+	}
+
+	model = (pv_elem_t*)_aor;
+	if (pv_printf_s(_m, model, &aor)<0) {
+		LM_ERR("error - cannot print the format\n");
+		return -1;
+	}
+	LM_DBG("URI: %.*s\n", aor.len, aor.s);
+
+	model = (pv_elem_t*)_received_host;
+	if (pv_printf_s(_m, model, &received_host)<0) {
+		LM_ERR("error - cannot print the format\n");
+		return -1;
+	}
+	LM_DBG("Received-Host: %.*s\n", received_host.len, received_host.s);
+
+	model = (pv_elem_t*)_received_port;
+	if (pv_printf_s(_m, model, &received_port)<0) {
+		LM_ERR("error - cannot print the format\n");
+		return -1;
+	}
+	LM_DBG("Received-Port: %.*s\n", received_port.len, received_port.s);
+	if (str2sint(&received_port, &port) != 0) {
+		LM_ERR("error - cannot convert %.*s to an int!\n", received_port.len, received_port.s);
+		return -1;
+	}
+
+	return unregister((udomain_t*)_d, &aor, &received_host, port);
+}
+
 static int w_assert_called_identity(struct sip_msg* _m, char* _d, char* _foo) {
 	return assert_called_identity( _m, (udomain_t*)_d);
 }

+ 1 - 1
modules/ims_registrar_pcscf/save.h

@@ -55,7 +55,7 @@
  */
 int save(struct sip_msg* _m, udomain_t* _d, int _cflags);
 int save_pending(struct sip_msg* _m, udomain_t* _d);
-int unregister(struct sip_msg* _m, char* _d, char* _uri);
+// int unregister(struct sip_msg* _m, char* _d, char* _uri);
 struct sip_msg* get_request_from_reply(struct sip_msg* reply);
 
 

+ 24 - 0
modules/ims_registrar_pcscf/service_routes.c

@@ -488,6 +488,30 @@ int is_registered(struct sip_msg* _m, udomain_t* _d) {
 	return -1;	
 }
 
+int unregister(udomain_t* _d, str * uri, str * received_host, int received_port) {
+	int result = -1;
+	struct pcontact * pcontact;
+	struct pcontact_info ci;
+    	memset(&ci, 0, sizeof (struct pcontact_info));
+
+	if (ul.get_pcontact(_d, uri, received_host, received_port, &pcontact) == 0) {
+		/* Lock this record while working with the data: */
+		ul.lock_udomain(_d, &pcontact->aor, received_host, received_port);
+
+		LM_DBG("Updating contact [%.*s]: setting state to PCONTACT_DEREG_PENDING_PUBLISH\n", pcontact->aor.len, pcontact->aor.s);
+
+		ci.reg_state = PCONTACT_DEREG_PENDING_PUBLISH;
+		ci.num_service_routes = 0;
+		if (ul.update_pcontact(_d, &ci, pcontact) == 0) result = 1;
+
+		// if (ul.delete_pcontact(_d, &pc->aor, received_host, received_port, pcontact) == 0) result = 1;
+
+		/* Unlock domain */
+		ul.unlock_udomain(_d, &pcontact->aor, received_host, received_port);
+	}
+	return result;
+}
+
 /**
  * Get the current asserted identity for the user
  */

+ 5 - 0
modules/ims_registrar_pcscf/service_routes.h

@@ -61,4 +61,9 @@ int assert_identity(struct sip_msg* _m, udomain_t* _d, str identity);
  */
 int assert_called_identity(struct sip_msg* _m, udomain_t* _d);
 
+/**
+ * Unregister a contact
+ */
+int unregister(udomain_t* _d, str * uri, str * received_host, int received_port);
+
 #endif /* SERVICE_ROUTES_H */