Module: sip-router
Branch: master
Commit: f149fe0bf499c2ed9a4238cea5bdf2ecbb28c941
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=f149fe0bf499c2ed9a4238cea5bdf2ecbb28c941

Author: Richard Good <[email protected]>
Committer: Richard Good <[email protected]>
Date:   Fri May  2 12:15:05 2014 +0200

modules/ims_registrar_scscf: Fix to not send notifies to UEs that explicitly 
deregister

---

 modules/ims_registrar_scscf/registrar_notify.c |  100 +++++++++++++++++++-----
 modules/ims_registrar_scscf/registrar_notify.h |    3 +
 2 files changed, 82 insertions(+), 21 deletions(-)

diff --git a/modules/ims_registrar_scscf/registrar_notify.c 
b/modules/ims_registrar_scscf/registrar_notify.c
index 3f04dbe..e5086a5 100644
--- a/modules/ims_registrar_scscf/registrar_notify.c
+++ b/modules/ims_registrar_scscf/registrar_notify.c
@@ -90,6 +90,8 @@ static str subss_hdr2 = {"\r\n", 2};
 static str ctype_hdr1 = {"Content-Type: ", 14};
 static str ctype_hdr2 = {"\r\n", 2};
 
+extern int ue_unsubscribe_on_dereg;
+
 int notify_init() {
     notification_list = shm_malloc(sizeof (reg_notification_list));
     if (!notification_list) return 0;
@@ -468,7 +470,7 @@ int event_reg(udomain_t* _d, impurecord_t* r_passed, 
ucontact_t* c_passed, int e
                 return 0;
             }
 
-            content = get_reginfo_partial(r_passed, c_passed, event_type);
+           content = get_reginfo_partial(r_passed, c_passed, event_type);
             create_notifications(_d, r_passed, c_passed, presentity_uri, 
watcher_contact, content, event_type);
             if (content.s) pkg_free(content.s);
             //                        if (send_now) notification_timer(0, 0);
@@ -1202,6 +1204,52 @@ int subscribe_reply(struct sip_msg *msg, int code, char 
*text, int *expires, str
 
 }
 
+/* function to convert contact aor to only have data after @ - ie strip user 
part */
+int aor_to_contact(str* aor, str* contact) {
+       char* p;
+       int ret = 0;    //success
+
+       contact->s = aor->s;
+       contact->len = aor->len;
+       if (memcmp(aor->s, "sip:", 4) == 0) {
+               contact->s = aor->s + 4;
+               contact->len-=4;
+       }
+
+       if ((p=memchr(contact->s, '@', contact->len))) {
+               contact->len -= (p - contact->s + 1);
+               contact->s = p+1;
+       }
+
+       if ((p=memchr(contact->s, ';', contact->len))) {
+               contact->len = p - contact->s;
+       }
+
+       if ((p=memchr(contact->s, '>', contact->len))) {
+               contact->len = p - contact->s;
+       }
+
+       return ret;
+}
+
+/*!
+ * \brief Match a contact record to a contact string but only compare the ip 
port portion
+ * \param ptr contact record
+ * \param _c contact string
+ * \return ptr on successfull match, 0 when they not match
+ */
+int contact_port_ip_match(str *c1, str *c2) {
+    
+    str ip_port1, ip_port2;
+    aor_to_contact(c1, &ip_port1);//strip userpart from test contact
+    aor_to_contact(c2, &ip_port2);//strip userpart from test contact
+    LM_DBG("Matching contact using only port and ip - comparing [%.*s] and 
[%.*s]\n", ip_port1.len, ip_port1.s, ip_port2.len, ip_port2.s);
+    if ((ip_port1.len == ip_port2.len) && !memcmp(ip_port1.s, ip_port2.s, 
ip_port1.len)) {
+       return 1;
+    }
+    return 0;
+}
+
 static str subs_terminated = {"terminated", 10};
 static str subs_active = {"active;expires=", 15};
 
@@ -1268,10 +1316,10 @@ void create_notifications(udomain_t* _t, impurecord_t* 
r_passed, ucontact_t* c_p
             LM_DBG("Subscription state: [%.*s]", subscription_state.len, 
subscription_state.s);
         }
 
-        //This is a fix to ensure that when a user subscribes a full reg info 
is only sent to that UE
+       //This is a fix to ensure that when a user subscribes a full reg info 
is only sent to that UE
         if (event_type == IMS_REGISTRAR_SUBSCRIBE) {
-            if ((watcher_contact->len == s->watcher_contact.len) && 
(strncasecmp(s->watcher_contact.s, watcher_contact->s, watcher_contact->len) == 
0) &&
-                    (presentity_uri->len == s->presentity_uri.len) && 
(strncasecmp(s->presentity_uri.s, presentity_uri->s, presentity_uri->len) == 
0)) {
+           if (contact_port_ip_match(watcher_contact, &s->watcher_contact) &&
+                    (presentity_uri->len == s->presentity_uri.len) && 
(memcmp(s->presentity_uri.s, presentity_uri->s, presentity_uri->len) == 0)) {
                 LM_DBG("This is a fix to ensure that we only send full reg 
info XML to the UE that just subscribed");
                 LM_DBG("about to make new notification!");
                 n = new_notification(subscription_state, content_type, content,
@@ -1291,23 +1339,33 @@ void create_notifications(udomain_t* _t, impurecord_t* 
r_passed, ucontact_t* c_p
                 }
             }
         } else {
-            LM_DBG("about to make new notification!");
-            n = new_notification(subscription_state, content_type, content,
-                    s->version++, s);
-            if (n) {
-                //LM_DBG("Notification exists - about to add it");
-                //add_notification(n);
-
-                //Richard just gonna send it - not bother queueing etc.
-                //TODO look at impact of this - sending straight away vs 
queueing and getting another process to send
-                LM_DBG("About to send notification");
-                send_notification(n);
-                LM_DBG("About to free notification");
-                free_notification(n);
-            } else {
-                LM_DBG("Notification does not exist");
-            }
-        }
+           
+           if(event_type == IMS_REGISTRAR_CONTACT_UNREGISTERED && 
!ue_unsubscribe_on_dereg && 
+                   (contact_port_ip_match(&c_passed->c, &s->watcher_contact) &&
+                       (r_passed->public_identity.len == 
s->presentity_uri.len) && (memcmp(s->presentity_uri.s, 
r_passed->public_identity.s, r_passed->public_identity.len) == 0))){
+               //if this is UNREGISTER and the UEs do not unsubscribe to dereg 
and this is a UE subscribing to its own reg event
+               //then we do not send notifications
+               LM_DBG("This is a UNREGISTER event for a UE that subscribed to 
its own state that does not unsubscribe to dereg - therefore no notification");
+           }
+           else{
+               LM_DBG("about to make new notification!");
+               n = new_notification(subscription_state, content_type, content,
+                       s->version++, s);
+               if (n) {
+                   //LM_DBG("Notification exists - about to add it");
+                   //add_notification(n);
+
+                   //Richard just gonna send it - not bother queueing etc.
+                   //TODO look at impact of this - sending straight away vs 
queueing and getting another process to send
+                   LM_DBG("About to send notification");
+                   send_notification(n);
+                   LM_DBG("About to free notification");
+                   free_notification(n);
+               } else {
+                   LM_DBG("Notification does not exist");
+               }
+           }
+       }
         //}
         s = s->next;
 
diff --git a/modules/ims_registrar_scscf/registrar_notify.h 
b/modules/ims_registrar_scscf/registrar_notify.h
index cbac7d3..8886316 100644
--- a/modules/ims_registrar_scscf/registrar_notify.h
+++ b/modules/ims_registrar_scscf/registrar_notify.h
@@ -144,4 +144,7 @@ dlg_t* build_dlg_t_from_notification(reg_notification* n);
 int notify_init();
 void notify_destroy();
 
+int aor_to_contact(str* aor, str* contact);
+int contact_port_ip_match(str *c1, str *c2);
+
 #endif //S_CSCF_REGISTRAR_NOTIFY_H_


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to