Parcourir la source

modules/ims_usrloc_scscf: New features to fully support subscription to reg_event
Main change add API to presence module library to store the callid/totag/fromtag presentity combination
Also only remove IMPU from usrloc if there are no subscriptions to it

Richard Good il y a 11 ans
Parent
commit
73ad320cc6

+ 27 - 19
modules/ims_usrloc_scscf/impurecord.c

@@ -67,6 +67,9 @@ extern int unreg_validity;
 extern int maxcontact_behaviour;
 extern int maxcontact;
 
+extern int sub_dialog_hash_size;
+extern shtable_t sub_dialog_table;
+
 /*!
  * \brief Create and initialize new record structure
  * \param _dom domain name
@@ -109,6 +112,7 @@ int new_impurecord(str* _dom, str* public_identity, int reg_state, int barring,
     if (barring >= 0) { //just in case we call this with no barring -1 will ignore
         (*_r)->barring = barring;
     }
+    (*_r)->send_sar_on_delete = 1; /*defaults to 1 */
     if (ccf1 && ccf1->len > 0) STR_SHM_DUP((*_r)->ccf1, *ccf1, "CCF1");
     if (ccf2 && ccf2->len > 0) STR_SHM_DUP((*_r)->ccf2, *ccf2, "CCF2");
     if (ecf1 && ecf1->len > 0) STR_SHM_DUP((*_r)->ecf1, *ecf1, "ECF1");
@@ -330,8 +334,11 @@ void mem_delete_ucontact(impurecord_t* _r, ucontact_t* _c) {
  */
 static inline void nodb_timer(impurecord_t* _r) {
     ucontact_t* ptr, *t;
+    
+    unsigned int hash_code = 0;
 
     reg_subscriber *s;
+    subs_t* sub_dialog;
 
     get_act_time();
 
@@ -346,6 +353,20 @@ static inline void nodb_timer(impurecord_t* _r) {
             LM_DBG("DBG:registrar_timer: Subscriber with watcher_contact <%.*s> and presentity uri <%.*s> is valid and expires in %d seconds.\n",
                     s->watcher_contact.len, s->watcher_contact.s, s->presentity_uri.len, s->presentity_uri.s,
                     (unsigned int) (s->expires - time(NULL)));
+	    hash_code = core_hash(&s->call_id, &s->to_tag, sub_dialog_hash_size);
+	    LM_DBG("Hash size: <%i>", sub_dialog_hash_size);
+	    LM_DBG("Searching sub dialog hash info with call_id: <%.*s> and ttag <%.*s> ftag <%.*s> and hash code <%i>", s->call_id.len, s->call_id.s, s->to_tag.len, s->to_tag.s, s->from_tag.len, s->from_tag.s, hash_code);
+	    /* search the record in hash table */
+	    lock_get(&sub_dialog_table[hash_code].lock);
+	    sub_dialog= pres_search_shtable(sub_dialog_table, s->call_id, s->to_tag, s->from_tag, hash_code);
+	    if(sub_dialog== NULL)
+	    {
+		LM_ERR("DBG:registrar_timer: Subscription has no dialog record in hash table\n");
+	    }else {
+		LM_DBG("DBG:registrar_timer: Subscription has dialog record in hash table with presentity uri <%.*s>\n", sub_dialog->pres_uri.len, sub_dialog->pres_uri.s);
+	    }
+	    
+	    lock_release(&sub_dialog_table[hash_code].lock);
         }
         s = s->next;
     }
@@ -451,22 +472,6 @@ int insert_ucontact(impurecord_t* _r, str* _contact, ucontact_info_t* _ci, ucont
  */
 int delete_ucontact(impurecord_t* _r, struct ucontact* _c) {
     int ret = 0;
-    reg_subscriber *s;
-
-    //Richard added this  - fix to remove subscribes that have presentity and watcher uri same as a contact aor that is being removed
-    s = _r->shead;
-    LM_DBG("Checking if there is a subscription to this IMPU that has same watcher contact as this contact");
-    while (s) {
-        
-        LM_DBG("Subscription for this impurecord: watcher uri [%.*s] presentity uri [%.*s] watcher contact [%.*s] ", s->watcher_uri.len, s->watcher_uri.s, 
-                s->presentity_uri.len, s->presentity_uri.s, s->watcher_contact.len, s->watcher_contact.s);
-        LM_DBG("Contact to be removed [%.*s] ", _c->c.len, _c->c.s);
-        if ((s->watcher_contact.len == _c->c.len) && (strncasecmp(s->watcher_contact.s, _c->c.s, _c->c.len) == 0)) {
-            LM_DBG("This contact has a subscription to its own status - so going to delete the subscription");
-            delete_subscriber(_r, s);
-        }
-        s = s->next;
-    }
     
     if (exists_ulcb_type(_c->cbs, UL_CONTACT_DELETE)) {
         run_ul_callbacks(_c->cbs, UL_CONTACT_DELETE, _r, _c);
@@ -680,7 +685,7 @@ void free_ims_subscription_data(ims_subscription *s) {
  * make sure yuo lock the domain before calling this and unlock it afterwards
  * return: 0 on success, -1 on failure
  */
-int update_impurecord(struct udomain* _d, str* public_identity, int reg_state, int barring, int is_primary, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, struct impurecord** _r) {
+int update_impurecord(struct udomain* _d, str* public_identity, int reg_state, int send_sar_on_delete, int barring, int is_primary, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, struct impurecord** _r) {
     int res;
 
     res = get_impurecord(_d, public_identity, _r);
@@ -704,8 +709,8 @@ int update_impurecord(struct udomain* _d, str* public_identity, int reg_state, i
                 return 0;
             }
         } else {
-            LM_ERR("no IMPU found to update and data not valid to create new one\n");
-            return -1;
+            LM_DBG("no IMPU found to update and data not valid to create new one - not a problem record was probably removed as it has no contacts\n");
+            return 0;
         }
 
     }
@@ -718,6 +723,9 @@ int update_impurecord(struct udomain* _d, str* public_identity, int reg_state, i
         (*_r)->expires = time(NULL) + unreg_validity;
     }
     if (barring >= 0) (*_r)->barring = barring;
+    
+    if (send_sar_on_delete >= 0) (*_r)->send_sar_on_delete = send_sar_on_delete;
+    
     if (ccf1) {
         if ((*_r)->ccf1.s)
             shm_free((*_r)->ccf1.s);

+ 1 - 1
modules/ims_usrloc_scscf/impurecord.h

@@ -180,6 +180,6 @@ int get_ucontact(impurecord_t* _r, str* _c, str* _callid, str* _path,
 		int _cseq,
 		struct ucontact** _co);
 
-int update_impurecord(struct udomain* _d, str* public_identity, int reg_state, int barring, int is_primary, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, struct impurecord** _r);
+int update_impurecord(struct udomain* _d, str* public_identity, int reg_state, int send_sar_on_delete, int barring, int is_primary, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, struct impurecord** _r);
 
 #endif

+ 97 - 6
modules/ims_usrloc_scscf/subscribe.c

@@ -48,7 +48,17 @@
 #include "utime.h"
 #include "udomain.h"
 
+#include "../presence/subscribe.h"
+#include "../presence/utils_func.h"
+#include "../presence/hash.h"
 
+#include "../../hashes.h"
+
+#include "ul_mod.h"
+
+
+extern int sub_dialog_hash_size;
+extern shtable_t sub_dialog_table;
 
 int get_subscriber(impurecord_t* urec, str *presentity_uri, str *watcher_contact, int event, reg_subscriber** r_subscriber) {
     
@@ -86,11 +96,15 @@ int get_subscriber(impurecord_t* urec, str *presentity_uri, str *watcher_contact
 }
 
 reg_subscriber* new_subscriber(str* presentity_uri, str* watcher_uri, str* watcher_contact, subscriber_data_t* subscriber_data) {
+    subs_t subs;
     reg_subscriber *s;
 
     int len;
     char *p;
-
+    unsigned int hash_code = 0;
+    
+    memset(&subs, 0, sizeof(subs_t));
+    
     len = sizeof (reg_subscriber) + subscriber_data->callid->len
             + subscriber_data->ftag->len + subscriber_data->ttag->len
             + watcher_contact->len + watcher_uri->len + presentity_uri->len
@@ -158,10 +172,65 @@ reg_subscriber* new_subscriber(str* presentity_uri, str* watcher_uri, str* watch
         free_subscriber(s);
         return 0;
     }
+    
+    /*This lets us get presentity URI info for subsequent SUBSCRIBEs that don't have presentity URI as req URI*/
+    
+    subs.pres_uri = s->presentity_uri;
+    subs.from_tag = s->from_tag;
+    subs.to_tag = s->to_tag;
+    subs.callid = s->call_id;
+    
+    hash_code = core_hash(&subs.callid, &subs.to_tag, sub_dialog_hash_size);
+    
+    LM_DBG("Adding sub dialog hash info with call_id: <%.*s> and ttag <%.*s> amd ftag <%.*s> and hash code <%d>", subs.callid.len, subs.callid.s, subs.to_tag.len, subs.to_tag.s, subs.from_tag.len,  subs.from_tag.s, hash_code);
+    
+    if (pres_insert_shtable(sub_dialog_table, hash_code, &subs))
+    {
+	LM_ERR("while adding new subscription\n");
+	return 0;
+    }
 
     return s;
 }
 
+/* Used for subsequent SUBSCRIBE messages to get presentity URI from dialog struct*/
+/* NB: free returned result str when done from shm */
+str get_presentity_from_subscriber_dialog(str *callid, str *to_tag, str *from_tag) {
+    subs_t* s;
+    unsigned int hash_code = 0;
+    str pres_uri = {0,0};
+    
+    hash_code = core_hash(callid, to_tag, sub_dialog_hash_size);
+    
+    /* search the record in hash table */
+    lock_get(&sub_dialog_table[hash_code].lock);
+
+    LM_DBG("Searching sub dialog hash info with call_id: <%.*s> and ttag <%.*s> and ftag <%.*s> and hash code <%d>", callid->len, callid->s, to_tag->len, to_tag->s, from_tag->len, from_tag->s, hash_code);
+    
+    s= pres_search_shtable(sub_dialog_table, *callid,
+		    *to_tag, *from_tag, hash_code);
+    if(s== NULL)
+    {
+	    LM_DBG("Subscriber dialog record not found in hash table\n");
+	    lock_release(&sub_dialog_table[hash_code].lock);
+	    return pres_uri;
+    }
+
+    //make copy of pres_uri
+    pres_uri.s = (char*) shm_malloc(s->pres_uri.len);
+    if (pres_uri.s==0) {
+	LM_ERR("no more shm mem\n");
+	return pres_uri;
+    }
+    memcpy(pres_uri.s, s->pres_uri.s, s->pres_uri.len);
+    pres_uri.len = s->pres_uri.len;
+    
+    lock_release(&sub_dialog_table[hash_code].lock);
+    
+    LM_DBG("Found subscriber dialog record in hash table with pres_uri: [%.*s]", pres_uri.len, pres_uri.s);
+    return pres_uri;
+}
+
 int add_subscriber(impurecord_t* urec,
         str *watcher_uri, str *watcher_contact,
         subscriber_data_t* subscriber_data, reg_subscriber** _reg_subscriber) {
@@ -203,16 +272,17 @@ int update_subscriber(impurecord_t* urec,
     }
 }
 
-void external_delete_subscriber(reg_subscriber *s, udomain_t* _t) {
+
+void external_delete_subscriber(reg_subscriber *s, udomain_t* _t, int lock_domain) {
     LM_DBG("Deleting subscriber");
     impurecord_t* urec;
-
+   
     LM_DBG("Updating reg subscription in IMPU record");
 
-    lock_udomain(_t, &s->presentity_uri);
+    if(lock_domain) lock_udomain(_t, &s->presentity_uri);
     int res = get_impurecord(_t, &s->presentity_uri, &urec);
     if (res != 0) {
-        unlock_udomain(_t, &s->presentity_uri);
+        if(lock_domain) unlock_udomain(_t, &s->presentity_uri);
         return;
     }
 
@@ -223,7 +293,7 @@ void external_delete_subscriber(reg_subscriber *s, udomain_t* _t) {
     LM_DBG("About to free subscriber memory");
     free_subscriber(s);
 
-    unlock_udomain(_t, &s->presentity_uri);
+    if(lock_domain) unlock_udomain(_t, &s->presentity_uri);
 
 }
 
@@ -238,7 +308,28 @@ void delete_subscriber(impurecord_t* urec, reg_subscriber *s) {
 }
 
 void free_subscriber(reg_subscriber *s) {
+    
+    unsigned int hash_code=0;
+    subs_t subs;
+    
     LM_DBG("Freeing subscriber memory");
+    
+    memset(&subs, 0, sizeof(subs_t));
+    
+    subs.pres_uri = s->presentity_uri;
+    subs.from_tag = s->from_tag;
+    subs.to_tag = s->to_tag;
+    subs.callid = s->call_id;
+    
+    /* delete from cache table */
+    hash_code= core_hash(&s->call_id, &s->to_tag, sub_dialog_hash_size);
+    
+    LM_DBG("Removing sub dialog hash info with call_id: <%.*s> and ttag <%.*s> and ftag <%.*s> and hash code <%d>", s->call_id.len, s->call_id.s, s->to_tag.len, s->to_tag.s, s->from_tag.len, s->from_tag.s, hash_code);
+    if(pres_delete_shtable(sub_dialog_table,hash_code, &subs)< 0)
+    {
+	    LM_ERR("record not found in hash table\n");
+    }
+    
     if (s) {
         shm_free(s);
     }

+ 8 - 1
modules/ims_usrloc_scscf/subscribe.h

@@ -43,6 +43,9 @@
  * 
  */
 
+#ifndef SUBSCRIBE_USRLOC_H
+#define SUBSCRIBE_USRLOC_H
+
 #include "usrloc.h"
 
 reg_subscriber* new_subscriber(str* presentity_uri, str* watcher_uri,
@@ -66,8 +69,12 @@ int update_subscriber(impurecord_t* urec,
 
 void delete_subscriber(impurecord_t* urec, reg_subscriber *s);
 
-void external_delete_subscriber(reg_subscriber *s, udomain_t* _t);
+void external_delete_subscriber(reg_subscriber *s, udomain_t* _t, int lock_domain);
 
 void free_subscriber(reg_subscriber *s);
 
 int valid_subscriber(reg_subscriber *s);
+
+str get_presentity_from_subscriber_dialog(str *callid, str *to_tag, str *from_tag);
+
+#endif /* SUBSCRIBE_USRLOC_H */

+ 15 - 5
modules/ims_usrloc_scscf/udomain.c

@@ -65,6 +65,8 @@
 #include "usrloc.h"
 #include "bin_utils.h"
 
+extern int unreg_validity;
+
 #ifdef STATISTICS
 static char *build_stat_name( str* domain, char *var_name)
 {
@@ -322,19 +324,27 @@ void mem_timer_udomain(udomain_t* _d)
 			t = ptr;
 			ptr = ptr->next;
 
-			if (t->reg_state == IMPU_NOT_REGISTERED) {
+			if (t->reg_state == IMPU_NOT_REGISTERED && t->shead == 0) {
 				//remove it - housekeeping - not sure why its still here...?
 				if (exists_ulcb_type(t->cbs, UL_IMPU_NR_DELETE))
 					run_ul_callbacks(t->cbs, UL_IMPU_NR_DELETE, t, NULL);
 				mem_delete_impurecord(_d, t);
 			} else if (t->reg_state == IMPU_UNREGISTERED) {//Remove IMPU record if it is in state IMPU_UNREGISTERED and has expired
-				if (time_now >= t->expires) {
+			    
+				if (time_now >= t->expires) {//check here and only remove if no subscribes - if there is a subscribe then bump the validity by unreg_validity
+				    if(t->shead != 0){
+					LM_DBG("This impurecord still has subscriptions - extending the expiry");
+					t->expires = time(NULL) + unreg_validity;
+				    } else {
 					if (exists_ulcb_type(t->cbs, UL_IMPU_UNREG_EXPIRED))
 						run_ul_callbacks(t->cbs, UL_IMPU_UNREG_EXPIRED, t, NULL);
 					mem_delete_impurecord(_d, t);
+				    }
 				}
-			} else if (t->reg_state != IMPU_UNREGISTERED && t->contacts == 0) { /* Remove the entire record if it is empty IFF it is not an UNREGISTERED RECORD */
-																				/* TS 23.228 5.3.2.1 (release 11) */
+			//} else if (t->reg_state != IMPU_UNREGISTERED && t->contacts == 0) { /* Remove the entire record if it is empty IFF it is not an UNREGISTERED RECORD */
+			} else if (t->reg_state != IMPU_UNREGISTERED && t->contacts == 0 && t->shead == 0) { /* Remove the entire record if it is empty IFF it is not an UNREGISTERED RECORD */
+																								/* TS 23.228 5.3.2.1 (release 11) */
+				//need a way of distinguishing between deletes that need a SAR (expired) and deletes that do not need a SAR (explicit de reg)
 				//we only want to send one SAR for each implicit IMPU set
 				//make sure all IMPU's associated with this set are de-registered before calling the callbacks
 				int first=1;
@@ -358,7 +368,7 @@ void mem_timer_udomain(udomain_t* _d)
 						} else {
 							//set all other implicits to not registered
 							if (update_impurecord(_d, &impu->public_identity, IMPU_NOT_REGISTERED,
-														-1/*barring*/, 0/*is_primary*/, NULL, NULL, NULL, NULL, NULL, &temp_impu) != 0) {
+														-1/*barring*/, -1 /*do not change send sar on delete */, 0/*is_primary*/, NULL, NULL, NULL, NULL, NULL, &temp_impu) != 0) {
 								LM_ERR("Unable to update impurecord for <%.*s>\n", impu->public_identity.len, impu->public_identity.s);
 							}
 						}

+ 64 - 1
modules/ims_usrloc_scscf/ul_mod.c

@@ -60,6 +60,9 @@
 #include "usrloc.h"
 #include "hslot_sp.h"
 
+#include "../presence/bind_presence.h"
+#include "../presence/hash.h"
+
 MODULE_VERSION
 
 #define DEFAULT_DBG_FILE "/var/log/usrloc_debug"
@@ -96,6 +99,17 @@ int subs_hash_size = 9;					/*!<number of ims subscription slots*/
 unsigned int nat_bflag = (unsigned int)-1;
 unsigned int init_flag = 0;
 
+int sub_dialog_hash_size = 9;
+shtable_t sub_dialog_table;
+
+new_shtable_t pres_new_shtable;
+insert_shtable_t pres_insert_shtable;
+search_shtable_t pres_search_shtable;
+update_shtable_t pres_update_shtable;
+delete_shtable_t pres_delete_shtable;
+destroy_shtable_t pres_destroy_shtable;
+extract_sdialog_info_t pres_extract_sdialog_info;
+
 /*! \brief
  * Exported functions
  */
@@ -125,6 +139,7 @@ static param_export_t params[] = {
     {"unreg_validity",		INT_PARAM, &unreg_validity},
     {"maxcontact_behaviour", INT_PARAM, &maxcontact_behaviour},
     {"maxcontact",			INT_PARAM, &maxcontact},
+    {"sub_dialog_hash_size", INT_PARAM, &sub_dialog_hash_size},
 	{0, 0, 0}
 };
 
@@ -216,6 +231,50 @@ static int mod_init(void) {
 		return -1;
 	}
 
+	/* presence binding for subscribe processing*/
+	presence_api_t pres;
+	bind_presence_t bind_presence;
+
+	bind_presence= (bind_presence_t)find_export("bind_presence", 1,0);
+	if (!bind_presence) {
+	    LM_ERR("can't bind presence\n");
+	    return -1;
+	}
+	if (bind_presence(&pres) < 0) {
+	    LM_ERR("can't bind pua\n");
+	    return -1;
+	}
+
+	pres_extract_sdialog_info= pres.extract_sdialog_info;
+	pres_new_shtable          = pres.new_shtable;
+	pres_destroy_shtable      = pres.destroy_shtable;
+	pres_insert_shtable       = pres.insert_shtable;
+	pres_delete_shtable       = pres.delete_shtable;
+	pres_update_shtable       = pres.update_shtable;
+	pres_search_shtable       = pres.search_shtable;
+
+
+	if(!pres_new_shtable || !pres_destroy_shtable || !pres_insert_shtable || !pres_delete_shtable
+		     || !pres_update_shtable || !pres_search_shtable || !pres_extract_sdialog_info) {
+	    LM_ERR("could not import add_event\n");
+	    return -1;
+	}
+
+	/* subscriber dialog hash table */
+	if(sub_dialog_hash_size<=1) {
+	    sub_dialog_hash_size= 512;
+	}
+	else {
+	    sub_dialog_hash_size = 1<<sub_dialog_hash_size;
+	}
+
+	sub_dialog_table= pres_new_shtable(sub_dialog_hash_size);
+	if(sub_dialog_table== NULL)
+	{
+		LM_ERR("while creating new hash table\n");
+		return -1;
+	}
+
 	/* Register cache timer */
 	register_timer(timer, 0, timer_interval);
 
@@ -235,7 +294,7 @@ static int mod_init(void) {
 	}
 
 	init_flag = 1;
-
+	
 	return 0;
 }
 
@@ -251,6 +310,10 @@ static int child_init(int rank)
  */
 static void destroy(void)
 {
+	if(sub_dialog_table)
+	{
+	    pres_destroy_shtable(sub_dialog_table, sub_dialog_hash_size);
+	}	
 	free_all_udomains();
 	ul_destroy_locks();
 

+ 11 - 0
modules/ims_usrloc_scscf/ul_mod.h

@@ -67,6 +67,8 @@
 #define UL_TABLE_VERSION 1004
 
 #include "../../lib/ims/useful_defs.h"
+#include "../presence/event_list.h"
+#include "../presence/hash.h"
 
 extern int timer_interval;
 extern int desc_time_order;
@@ -74,6 +76,15 @@ extern int cseq_delay;
 extern int ul_fetch_rows;
 extern int ul_hash_size;
 
+/* functions imported from presence to handle subscribe hash table */
+extern new_shtable_t pres_new_shtable;
+extern insert_shtable_t pres_insert_shtable;
+extern search_shtable_t pres_search_shtable;
+extern update_shtable_t pres_update_shtable;
+extern delete_shtable_t pres_delete_shtable;
+extern destroy_shtable_t pres_destroy_shtable;
+extern extract_sdialog_info_t pres_extract_sdialog_info;
+
 /*
  * Matching algorithms
  */

+ 2 - 0
modules/ims_usrloc_scscf/usrloc.c

@@ -96,6 +96,8 @@ int bind_usrloc(usrloc_api_t* api) {
 	api->update_subscriber = update_subscriber;
 
 	api->get_impus_from_subscription_as_string = get_impus_from_subscription_as_string;
+	
+	api->get_presentity_from_subscriber_dialog = get_presentity_from_subscriber_dialog;
         
     api->register_ulcb = register_ulcb;
 

+ 8 - 2
modules/ims_usrloc_scscf/usrloc.h

@@ -349,6 +349,7 @@ typedef struct impurecord {
     ucontact_t* contacts; 			/*!< One or more contact fields */
     reg_subscriber *shead, *stail; 	/**< list of subscribers attached			*/
     time_t expires; 				/*!< timer when this IMPU expires - currently only used for unreg IMPU */
+    int send_sar_on_delete;			/* used to distinguish between explicit contact removal and contact expiry - SAR only sent on contact expiry*/
 
     struct hslot* slot; 			/*!< Collision slot in the hash table array we belong to */
     struct ulcb_head_list* cbs;		/**< individual callbacks per impurecord */
@@ -373,7 +374,7 @@ typedef int (*get_impurecord_t)(struct udomain* _d, str* _aor, struct impurecord
 
 typedef int (*delete_impurecord_t)(struct udomain* _d, str* _aor, struct impurecord* _r);
 
-typedef int (*update_impurecord_t)(struct udomain* _d, str* public_identity, int reg_state, int barring, int is_primary, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, struct impurecord** _r);
+typedef int (*update_impurecord_t)(struct udomain* _d, str* public_identity, int reg_state, int send_sar_on_delete, int barring, int is_primary, ims_subscription** s, str* ccf1, str* ccf2, str* ecf1, str* ecf2, struct impurecord** _r);
 
 typedef int (*update_ucontact_t)(struct impurecord* _r, struct ucontact* _c, struct ucontact_info* _ci);
 
@@ -399,7 +400,7 @@ typedef int (*update_subscriber_t)(impurecord_t* urec,
         str *watcher_uri, str *watcher_contact,
         int *expires, reg_subscriber** _reg_subscriber);
 
-typedef void (*external_delete_subscriber_t)(reg_subscriber *s, udomain_t* _t);
+typedef void (*external_delete_subscriber_t)(reg_subscriber *s, udomain_t* _t, int lock_domain);
 
 //typedef int (*get_subscriber_t)(udomain_t* _d, impurecord_t* urec, str *watcher_contact, str *presentity_uri, int event, reg_subscriber** reg_subscriber);
 typedef int (*get_subscriber_t)(impurecord_t* urec, str *watcher_contact, str *presentity_uri, int event, reg_subscriber** reg_subscriber);
@@ -414,6 +415,8 @@ typedef int (*add_subscriber_t)(impurecord_t* urec,
 
 typedef int (*get_impus_from_subscription_as_string_t)(udomain_t* _d, impurecord_t* impu_rec, int barring, str** impus, int* num_impus);
 
+typedef str (*get_presentity_from_subscriber_dialog_t)(str *callid, str *to_tag, str *from_tag);
+
 /*! usrloc API export structure */
 typedef struct usrloc_api {
     int use_domain; /*! use_domain module parameter */
@@ -445,6 +448,9 @@ typedef struct usrloc_api {
     get_impus_from_subscription_as_string_t get_impus_from_subscription_as_string;
 
     register_ulcb_t register_ulcb;
+    
+    get_presentity_from_subscriber_dialog_t get_presentity_from_subscriber_dialog;
+    
 } usrloc_api_t;
 
 /*! usrloc API export bind function */