[sr-dev] git:carstenbock/ims: - Start of implementation of storage into usrloc

Carsten Bock carsten at bock.info
Wed Apr 6 18:32:10 CEST 2011


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

Author: Carsten Bock <carsten at bock.info>
Committer: Carsten Bock <carsten at bock.info>
Date:   Wed Apr  6 18:09:43 2011 +0200

- Start of implementation of storage into usrloc

---

 modules_k/pua_reginfo/notify.c |  205 +++++++++++++++++++++++++++++-----------
 1 files changed, 148 insertions(+), 57 deletions(-)

diff --git a/modules_k/pua_reginfo/notify.c b/modules_k/pua_reginfo/notify.c
index e753053..eeb9450 100644
--- a/modules_k/pua_reginfo/notify.c
+++ b/modules_k/pua_reginfo/notify.c
@@ -24,8 +24,10 @@
 #include "notify.h"
 #include "../../parser/parse_from.h"
 #include "../../parser/parse_content.h"
+#include "../../parser/parse_uri.h"
 #include "../../modules_k/usrloc/usrloc.h"
 #include <libxml/parser.h>
+#include "pua_reginfo.h"
 
 /*<?xml version="1.0"?>
 <reginfo xmlns="urn:ietf:params:xml:ns:reginfo" version="0" state="full">
@@ -56,6 +58,33 @@
 #define EVENT_REFRESHED 4
 #define EVENT_EXPIRED 5
 
+#define RESULT_ERROR -1
+#define RESULT_CONTACTS_FOUND 1
+#define RESULT_NO_CONTACTS 2
+
+int process_contact(udomain_t * domain, urecord_t ** ul_record, str aor, str callid, int cseq, int expires, int event, str contact_uri) {
+	if (*ul_record == NULL) {
+		switch(event) {
+			case EVENT_REGISTERED:
+			case EVENT_CREATED:
+			case EVENT_REFRESHED:
+				/* In case, no record exists and new one should be created,
+				   create a new entry for this user in the usrloc-DB */
+				if (ul.insert_urecord(domain, &aor, ul_record) < 0) {
+					LM_ERR("failed to insert new user-record\n");
+					return RESULT_NO_CONTACTS;
+				}
+				break;
+			default:
+				/* No entry in usrloc and the contact is expired, deleted, unregistered, whatever:
+                                   We do not need to do anything. */
+				return RESULT_NO_CONTACTS;
+				break;
+		}
+	}
+	return RESULT_NO_CONTACTS;
+}
+
 xmlNodePtr xmlGetNodeByName(xmlNodePtr parent, const char *name) {
 	xmlNodePtr cur = parent;
 	xmlNodePtr match = NULL;
@@ -127,18 +156,20 @@ int reginfo_parse_event(char * s) {
 }
 
 int process_body(str notify_body, udomain_t * domain) {
-	xmlNodePtr doc_root = NULL;
 	xmlDocPtr doc= NULL;
-	xmlNodePtr registrations = NULL;
-	xmlNodePtr contacts = NULL;
-	xmlNodePtr uris = NULL;
+	xmlNodePtr doc_root = NULL, registrations = NULL, contacts = NULL, uris = NULL;
 	str aor = {0, 0};
 	str callid = {0, 0};
 	str contact_uri = {0, 0};
-	int state;
-	int event;
-	char * expires_char;
-	int expires;
+	int state, event, expires, result, final_result = RESULT_ERROR;
+	char * expires_char,  * cseq_char;
+	int cseq;
+	urecord_t * ul_record;
+	ucontact_t * ul_contact;
+	struct sip_uri parsed_aor;
+
+	/* Temporary */
+	int mem_only = 1;
 
 	doc = xmlParseMemory(notify_body.s, notify_body.len);
 	if(doc== NULL)  {
@@ -167,70 +198,128 @@ int process_body(str notify_body, udomain_t * domain) {
 			goto next_registration;
 		}
 		aor.len = strlen(aor.s);
-		LM_ERR("AOR %.*s has state \"%d\"\n", aor.len, aor.s, state);
-		/* Now lets process the Contact's from this Registration: */
-		contacts = registrations->children;
-		while (contacts) {
-			if (xmlStrcasecmp(contacts->name, BAD_CAST "contact") != 0)
-				goto next_contact;
-			callid.s = xmlGetAttrContentByName(contacts, "callid");
-			if (callid.s == NULL) {
-				LM_ERR("No Call-ID for this contact!\n");		
-				goto next_contact;
-			}
-			callid.len = strlen(callid.s);
+		LM_DBG("AOR %.*s has state \"%d\"\n", aor.len, aor.s, state);
 
-			event = reginfo_parse_event(xmlGetAttrContentByName(contacts, "event"));
-			if (event == EVENT_UNKNOWN) {
-				LM_ERR("No event for this contact!\n");		
-				goto next_contact;
-			}
-			expires_char = xmlGetAttrContentByName(contacts, "expires");
-			if (expires_char == NULL) {
-				LM_ERR("No expires for this contact!\n");		
-				goto next_contact;
-			}
-			expires = atoi(expires_char);
-			if (expires < 0) {
-				LM_ERR("No valid expires for this contact!\n");		
-				goto next_contact;
+		/* Get username part of the AOR, search for @ in the AOR. */
+		if (parse_uri(aor.s, aor.len, &parsed_aor) < 0) {
+			LM_ERR("failed to parse Address of Record (%.*s)\n",
+				aor.len, aor.s);
+			goto next_registration;
+		}
+
+		/* Now let's lock that domain for this AOR: */		
+		ul.lock_udomain(domain, &parsed_aor.user);
+		/* and retrieve the user-record for this user: */
+		result = ul.get_urecord(domain, &parsed_aor.user, &ul_record);
+		if (result < 0) {
+			ul.unlock_udomain(domain, &parsed_aor.user);
+			LM_ERR("failed to query usrloc (User %.*s)\n",
+				parsed_aor.user.len, parsed_aor.user.s);
+			goto next_registration;
+		}
+		/* If no contacts found, then set the ul_record to NULL */
+		if (result != 0) ul_record = NULL;
+
+		/* If the state is terminated, we just can delete all bindings */
+		if (state == STATE_TERMINATED) {
+			if (ul_record) {
+				ul_contact = ul_record->contacts;
+				while(ul_contact) {
+					if (mem_only) {
+						ul_contact->flags |= FL_MEM;
+					} else {
+						ul_contact->flags &= ~FL_MEM;
+					}
+					ul_contact = ul_contact->next;
+				}
+				if (ul.delete_urecord(domain, &parsed_aor.user, ul_record) < 0) {
+					LM_ERR("failed to remove record from usrloc\n");
+				}
+				/* If already a registration with contacts was found, then keep that result.
+				   otherwise the result is now "No contacts found" */
+				if (final_result != RESULT_CONTACTS_FOUND) final_result = RESULT_NO_CONTACTS;
 			}
-			LM_ERR("%.*s: Event \"%d\", expires %d\n",
-				callid.len, callid.s, event, expires);
-			/* Now lets process the URI's from this Contact: */
-			uris = contacts->children;
-			while (uris) {
-				if (xmlStrcasecmp(uris->name, BAD_CAST "uri") != 0)
-					goto next_uri;
-				contact_uri.s = (char*)xmlNodeGetContent(uris);	
-				if (contact_uri.s == NULL) {
-					LM_ERR("No URI for this contact!\n");		
-					goto next_registration;
+		/* Otherwise, process the content */
+		} else {
+			/* Now lets process the Contact's from this Registration: */
+			contacts = registrations->children;
+			while (contacts) {
+				if (xmlStrcasecmp(contacts->name, BAD_CAST "contact") != 0)
+					goto next_contact;
+				callid.s = xmlGetAttrContentByName(contacts, "callid");
+				if (callid.s == NULL) {
+					LM_ERR("No Call-ID for this contact!\n");		
+					goto next_contact;
+				}
+				callid.len = strlen(callid.s);
+
+				event = reginfo_parse_event(xmlGetAttrContentByName(contacts, "event"));
+				if (event == EVENT_UNKNOWN) {
+					LM_ERR("No event for this contact!\n");		
+					goto next_contact;
+				}
+				expires_char = xmlGetAttrContentByName(contacts, "expires");
+				if (expires_char == NULL) {
+					LM_ERR("No expires for this contact!\n");		
+					goto next_contact;
 				}
-				contact_uri.len = strlen(contact_uri.s);
-				LM_ERR("Contact: %.*s\n",
-					contact_uri.len, contact_uri.s);
+				expires = atoi(expires_char);
+				if (expires < 0) {
+					LM_ERR("No valid expires for this contact!\n");		
+					goto next_contact;
+				}
+				LM_DBG("%.*s: Event \"%d\", expires %d\n",
+					callid.len, callid.s, event, expires);
+
+				cseq_char = xmlGetAttrContentByName(contacts, "cseq");
+				if (cseq_char == NULL) {
+					LM_WARN("No cseq for this contact!\n");		
+				} else {
+					cseq = atoi(cseq_char);
+					if (cseq < 0) {
+						LM_WARN("No valid cseq for this contact!\n");		
+					}
+				}
+
+				/* Now lets process the URI's from this Contact: */
+				uris = contacts->children;
+				while (uris) {
+					if (xmlStrcasecmp(uris->name, BAD_CAST "uri") != 0)
+						goto next_uri;
+					contact_uri.s = (char*)xmlNodeGetContent(uris);	
+					if (contact_uri.s == NULL) {
+						LM_ERR("No URI for this contact!\n");		
+						goto next_registration;
+					}
+					contact_uri.len = strlen(contact_uri.s);
+					LM_DBG("Contact: %.*s\n",
+						contact_uri.len, contact_uri.s);
+				
+					/* Process the result */
+					if (final_result != RESULT_CONTACTS_FOUND) final_result = result;
 next_uri:
-				uris = uris->next;
-			}
+					uris = uris->next;
+				}
 next_contact:
-			contacts = contacts->next;
+				contacts = contacts->next;
+			}
 		}
 next_registration:
+		if (ul_record) ul.release_urecord(ul_record);		
+		/* Unlock the domain for this AOR: */
+		ul.unlock_udomain(domain, &parsed_aor.user);
+
 		registrations = registrations->next;
 	}
-	/* Free the XML-Document */
-    	if(doc) xmlFreeDoc(doc);
-
-	return 1;
 error:
 	/* Free the XML-Document */
     	if(doc) xmlFreeDoc(doc);
-	return -1;
+	return final_result;
 }
 
 int reginfo_handle_notify(struct sip_msg* msg, char* domain, char* s2) {
  	str body;
+	int result = 0;
 
   	/* If not done yet, parse the whole message now: */
   	if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
@@ -252,6 +341,8 @@ int reginfo_handle_notify(struct sip_msg* msg, char* domain, char* s2) {
 
 	LM_DBG("Body is %.*s\n", body.len, body.s);
 	
-	return process_body(body, (udomain_t*)domain);
+	result = process_body(body, (udomain_t*)domain);
+
+	return result;
 }
 




More information about the sr-dev mailing list