[svn-commits] dvossel: branch dvossel/sip_resource_list_trunk r186713 - /team/dvossel/sip_r...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Apr 6 18:37:01 CDT 2009


Author: dvossel
Date: Mon Apr  6 18:36:55 2009
New Revision: 186713

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=186713
Log:
Added support dialogs to watch resource lists for notifications.

Modified:
    team/dvossel/sip_resource_list_trunk/channels/chan_sip.c

Modified: team/dvossel/sip_resource_list_trunk/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/team/dvossel/sip_resource_list_trunk/channels/chan_sip.c?view=diff&rev=186713&r1=186712&r2=186713
==============================================================================
--- team/dvossel/sip_resource_list_trunk/channels/chan_sip.c (original)
+++ team/dvossel/sip_resource_list_trunk/channels/chan_sip.c Mon Apr  6 18:36:55 2009
@@ -643,7 +643,8 @@
 	DIALOG_INFO_XML,
 	CPIM_PIDF_XML,
 	PIDF_XML,
-	MWI_NOTIFICATION
+	MWI_NOTIFICATION,
+	DIALOG_RLMI_XML
 };
 
 /*! \brief Subscription types that we support. We support
@@ -663,7 +664,8 @@
 	{ CPIM_PIDF_XML,   "presence", "application/cpim-pidf+xml",   "cpim-pidf+xml" },  /* RFC 3863 */
 	{ PIDF_XML,        "presence", "application/pidf+xml",        "pidf+xml" },       /* RFC 3863 */
 	{ XPIDF_XML,       "presence", "application/xpidf+xml",       "xpidf+xml" },       /* Pre-RFC 3863 with MS additions */
-	{ MWI_NOTIFICATION,	"message-summary", "application/simple-message-summary", "mwi" } /* RFC 3842: Mailbox notification */
+	{ MWI_NOTIFICATION,	"message-summary", "application/simple-message-summary", "mwi" }, /* RFC 3842: Mailbox notification */
+	{ DIALOG_RLMI_XML, "dialog",   "multipart/related;boundary=UniqueAsteriskRLMIBoundary;type=application/rlmi+xml", "application/rlmi+xml" } /* RFC 4662 */
 };
 
 
@@ -901,7 +903,7 @@
 	/* RFC3959: SIP Early session support */
 	{ SIP_OPT_EARLY_SESSION, NOT_SUPPORTED,	"early-session" },
 	/* SIMPLE events:  RFC4662 */
-	{ SIP_OPT_EVENTLIST,	NOT_SUPPORTED,	"eventlist" },
+	{ SIP_OPT_EVENTLIST,	SUPPORTED,	"eventlist" },
 	/* RFC 4916- Connected line ID updates */
 	{ SIP_OPT_FROMCHANGE,	NOT_SUPPORTED,	"from-change" },
 	/* GRUU: Globally Routable User Agent URI's */
@@ -1751,8 +1753,8 @@
 	int stateid;				/*!< SUBSCRIBE: ID for devicestate subscriptions */
 	int laststate;				/*!< SUBSCRIBE: Last known extension state */
 	int dialogver;				/*!< SUBSCRIBE: Version for subscription dialog-info */
-
-	struct sip_rlist *rlist;	/*!< SUBSCRIBE: prt to resource list */
+	struct sip_rlist *rlist;	/*!< SUBSCRIBE: Resource list to get notifications from */
+	AST_LIST_ENTRY(sip_pvt) rlist_entry; /* SUBSCRIBE: entry into resource list's list of watchers */
 
 	struct ast_dsp *vad;			/*!< Inband DTMF Detection dsp */
 
@@ -1898,6 +1900,7 @@
 	);
 	int version;
 	int the_mark;
+	AST_LIST_HEAD_NOLOCK(, sip_pvt) watchers;
 	AST_LIST_HEAD_NOLOCK(, sip_rlist_resource) resources;
 };
 
@@ -2443,6 +2446,10 @@
 static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target);
 static int do_magic_pickup(struct ast_channel *channel, const char *extension, const char *context);
 
+/* add and remove resource list watchers */
+static int rlist_add_watcher(struct sip_pvt *p);
+static int rlist_remove_watcher(struct sip_pvt *p);
+
 /*!
  * \brief generic function for determining if a correct transport is being 
  * used to contact a peer
@@ -2965,12 +2972,6 @@
 	return peer;
 }
 
-static void *unref_rlist(struct sip_rlist *rlist, char *tag)
-{
-	ao2_t_ref(rlist, -1, tag);
-	return NULL;
-}
-
 /*! \brief maintain proper refcounts for a sip_pvt's outboundproxy
  *
  * This function sets pvt's outboundproxy pointer to the one referenced
@@ -3030,6 +3031,9 @@
 		ast_extension_state_del(dialog->stateid, NULL);
 		dialog_unref(dialog, "removing extension_state, should unref the associated dialog ptr that was stored there.");
 		dialog->stateid = -1; /* shouldn't we 'zero' this out? */
+	}
+	if (dialog->rlist) {
+		rlist_remove_watcher(dialog);
 	}
 	/* Remove link from peer to subscription of MWI */
 	if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog)
@@ -4659,6 +4663,33 @@
 	return CMP_MATCH | CMP_STOP;
 }
 
+/*!
+ * \brief Locate resource list by name and context
+ *
+ * If sip_pvt *p is !NULL, then p->rlist is updated to point 
+ * to the matching resource list if found.
+ */
+static int rlist_find(const char *name, const char *context, struct sip_pvt *p)
+{
+	struct sip_rlist tmp_rlist;
+	struct sip_rlist *rlist = NULL;
+	int found = 0;
+	ast_copy_string(tmp_rlist.name, name, sizeof(tmp_rlist.name));
+
+	rlist = ao2_t_find(rlists, &tmp_rlist, OBJ_POINTER, "ao2_find in rlist_find()");
+
+	if (rlist) {
+		found = 1;
+		if (p) {
+			p->rlist = rlist;
+		} else {
+			ao2_t_ref(rlist, -1, "unref rlist in rlist_find");
+		}
+	}
+
+	return found;
+}
+
 /*! 
  * \brief Locate device by name or ip address 
  *
@@ -5359,6 +5390,10 @@
 	if (p->chanvars) {
 		ast_variables_destroy(p->chanvars);
 		p->chanvars = NULL;
+	}
+
+	if (p->rlist) {
+		ao2_t_ref(p->rlist, -1, "peer is destroyed, decrement ref of rlist.");
 	}
 
 	ast_string_field_free_memory(p);
@@ -12889,9 +12924,14 @@
 		ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
 
 	/* If this is a subscription we actually just need to see if a hint exists for the extension */
-	if (req->method == SIP_SUBSCRIBE) { //todohere search rlist for dest instead of just hints
+	if (req->method == SIP_SUBSCRIBE) {
 		char hint[AST_MAX_EXTENSION];
-		return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1);
+		int res;
+		res = ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1;
+		if (res) { /* if res is not 0, then hint not found, check rlists for destination. */
+			res = rlist_find(p->exten, p->context, NULL) ? 0 : -1;
+		}
+		return res;
 	} else {
 		decoded_uri = ast_strdupa(uri);
 		ast_uri_decode(decoded_uri);
@@ -20922,7 +20962,9 @@
 		/* Polycom phones only handle xpidf+xml, even if they say they can
 		   handle pidf+xml as well
 		*/
-		if (strstr(p->useragent, "Polycom")) {
+		if (strstr(acceptheader, " application/rlmi+xml")) {
+			p->subscribed = DIALOG_RLMI_XML;
+		} else if (strstr(p->useragent, "Polycom")) {
 			p->subscribed = XPIDF_XML;
 		} else if (strstr(acceptheader, "application/pidf+xml")) {
 			p->subscribed = PIDF_XML;         /* RFC 3863 format */
@@ -21007,12 +21049,21 @@
 
 	/* Add subscription for extension state from the PBX core */
 	if (p->subscribed != MWI_NOTIFICATION && !resubscribe) {
-		if (p->stateid > -1) {
-			ast_extension_state_del(p->stateid, cb_extensionstate);
-			/* we need to dec the refcount, now that the extensionstate is removed */
-			dialog_unref(p, "the extensionstate containing this dialog ptr was deleted");
-		}
-		p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, dialog_ref(p,"copying dialog ptr into extension state struct"));
+
+		if (p->subscribed == DIALOG_RLMI_XML) {
+//todohere add code to add this pvt to subscribe to rlist updates 
+			if (p->rlist) {
+				rlist_remove_watcher(p);
+			}
+			rlist_add_watcher(p);
+		} else {
+			if (p->stateid > -1) {
+				ast_extension_state_del(p->stateid, cb_extensionstate);
+				/* we need to dec the refcount, now that the extensionstate is removed */
+				dialog_unref(p, "the extensionstate containing this dialog ptr was deleted");
+			}
+			p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, dialog_ref(p,"copying dialog ptr into extension state struct"));
+		}
 	}
 
 	if (!req->ignore && p)
@@ -23194,7 +23245,37 @@
 	}
 }
 
-static int add_rlist_resource(struct sip_rlist *rlist, const char *monitorexten)
+static int rlist_add_watcher(struct sip_pvt *p)
+{
+	if (p) {
+		/* find and point p->rlist to match, rlist ref is incremented if found */
+		rlist_find(p->exten, p->context, p);
+		if (p->rlist) {
+			dialog_ref(p, "add sip_pvt watcher to resource list notifications");
+			AST_LIST_INSERT_TAIL(&p->rlist->watchers, p, rlist_entry);
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+static int rlist_remove_watcher(struct sip_pvt *p)
+{
+	if (!p) {
+		return -1;
+	}
+	if (p->rlist) {
+		AST_LIST_REMOVE(&p->rlist->watchers, p, rlist_entry);
+		ao2_t_ref(p->rlist, -1, "remove dialog's ref to resource list");
+		p->rlist = NULL;
+		dialog_unref(p, "remove sip_pvt from resource list notifications");
+		return 0;
+	}
+	return -1;
+}
+
+static int rlist_add_resource(struct sip_rlist *rlist, const char *monitorexten)
 {
 	struct sip_rlist_resource *resource;
 
@@ -23220,7 +23301,7 @@
 		AST_LIST_TRAVERSE(&rlist->resources, resource, entry) {
 			ast_log(LOG_NOTICE, "\tMONITOR EXTEN: %s\n", resource->exten);
 		}
-		unref_rlist(rlist, "print_rlist");
+		ao2_t_ref(rlist, -1, "print_rlist");
 	}
 } */
 
@@ -23247,16 +23328,16 @@
 		}
 
 		if (ast_string_field_init(rlist, 256)) {
-			unref_rlist(rlist, "rlist failed to init string field");
+			ao2_t_ref(rlist, -1, "rlist failed to init string field");
 			return NULL;
 		}
-;
+
 		ast_copy_string(rlist->name, name, sizeof(rlist->name));
 	}
 
 	for (; v || ((v = alt) && !(alt = NULL)); v = v->next) {
 		if (!strcasecmp(v->name, "monitor")) {
-			add_rlist_resource(rlist, v->value);
+			rlist_add_resource(rlist, v->value);
 		} else if (!strcasecmp(v->name, "context")) {
 			ast_string_field_set(rlist, context, v->value);
 		}
@@ -24542,9 +24623,9 @@
 				}
 			} else if (!strcasecmp(utype, "resourcelist")) {
 				rlist = build_rlist(cat, ast_variable_browse(cfg, cat), NULL, 0);
-				if (rlist) {  // todohere addrlists object and functions
+				if (rlist) {
 					ao2_t_link(rlists, rlist, "link rlist into rlists table");
-					unref_rlist(rlist, "unref the result of the build_rlist call. Now, the links from the tables are the only ones left,");
+					ao2_t_ref(rlist, -1, "unref the result of the build_rlist call. Now, the links from the tables are the only ones left,");
 				}
 			} else {
 				ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");




More information about the svn-commits mailing list