[svn-commits] oej: branch group/pinana-publish-1.4 r296516 - /team/group/pinana-publish-1.4...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sun Nov 28 07:47:15 CST 2010


Author: oej
Date: Sun Nov 28 07:47:09 2010
New Revision: 296516

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=296516
Log:
Introducing new interesting segfaults.

Modified:
    team/group/pinana-publish-1.4/channels/chan_sip.c

Modified: team/group/pinana-publish-1.4/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pinana-publish-1.4/channels/chan_sip.c?view=diff&rev=296516&r1=296515&r2=296516
==============================================================================
--- team/group/pinana-publish-1.4/channels/chan_sip.c (original)
+++ team/group/pinana-publish-1.4/channels/chan_sip.c Sun Nov 28 07:47:09 2010
@@ -1165,7 +1165,7 @@
 
 /*! Publish filters */
 struct pubsub_filter {
-	const char *criteria;
+	char criteria[AST_MAX_EXTENSION];
 	AST_LIST_ENTRY(pubsub_filter) next;
 };
 
@@ -1211,7 +1211,7 @@
 	 * in which we must send a message identical to the
 	 * one previously sent
 	 */
-	char body[SIPBUFSIZE];
+	char body[SIPBUFSIZE * 2];
 	/*!
 	 * Every event package has some constant data and
 	 * callbacks that all instances will share. This
@@ -1225,6 +1225,16 @@
 	 */
 	void *instance_data;
 };
+
+/*! Structure that we have one per device for keeping control of PUBLISH states */
+struct sip_published_device {
+	struct sip_epa_entry *status;
+	char name[AST_MAX_EXTENSION];		/* Device name for entry */
+	char pubname[AST_MAX_EXTENSION];	/* Publisher name */
+};
+
+static struct ao2_container *pub_dev;
+
 
 /*!
  * Data which is the same for all instances of an EPA for a
@@ -1254,7 +1264,7 @@
 
 static void dlginfo_handle_publish_error(struct sip_pvt *pvt, const int resp, struct sip_request *req, struct sip_epa_entry *epa_entry)
 {
-	/* ???? */
+	/* Do we really care of errors here? */
 	return;
 }
 
@@ -8163,7 +8173,7 @@
 	} else {
 		ast_build_string(&t, maxbytes, "<dialog id=\"%s\">\n", p->exten);
 	}
-	ast_build_string(&t, &maxbytes, "<state>%s</state>\n", statestring);
+	ast_build_string(&t, maxbytes, "<state>%s</state>\n", statestring);
 	if (state == AST_EXTENSION_ONHOLD) {
 		ast_build_string(&t, maxbytes, "<local>\n<target uri=\"%s\">\n"
 	                         "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n"
@@ -9844,15 +9854,47 @@
 	return 0;
 }
 
+/*! \brief Generate a PUBLISH request for one server */
 static int sip_devicestate_publish(struct sip_publisher *pres_server, struct statechange *sc)
 {
-	/* XXX MARQUIS Just a template for now */
+	struct sip_published_device *device = NULL;
+	struct ao2_iterator i;
+	int found = FALSE;
+
+	if (!pres_server) {
+		ast_log(LOG_ERROR, "??? No presence server. What's up? \n");
+		return -1;
+	}
+
 	ast_log(LOG_DEBUG, "---PUBLISH: publishing device state changes to %s for %s\n", pres_server->name, sc->dev);
+
+	i = ao2_iterator_init(pub_dev, 0);
+	while ((device = ao2_iterator_next(&i))) {
+		ast_log(LOG_DEBUG, "   PUBLISH: Comparing %s and device %s\n", device->name, sc->dev);
+		if (!strcasecmp(device->pubname, pres_server->name) && !strcasecmp(device->name, sc->dev)) {
+			found = TRUE;
+			ast_log(LOG_DEBUG, "*** Found our friend %s in the existing list \n", device->name);
+			/* Do stuff here */
+		}
+		ao2_ref(device, -1);
+	}
+
+	ao2_iterator_destroy(&i);
+
 	/* At this point we have a device state change to publish to one presence server. */
+	if (!found) {
+		ast_log(LOG_DEBUG, "*** Creating new publish device for %s\n", device->name);
+		device = ast_calloc(1, sizeof(*device));
+		ast_copy_string(device->name, sc->dev, sizeof(device->name));
+		ast_copy_string(device->pubname, pres_server->name, sizeof(device->pubname));
+		/* Initiate stuff */
+		ao2_link(pub_dev, device);
+		/* Do stuff here */
+	}
 	return 0;
 }
 
-/*! \Publish the state of a device if it matches a publisher and one of its filters */
+/*! \brief Publish the state of a device if it matches a publisher and one of its filters */
 static void *handle_statechange(struct statechange *sc)
 {
 	struct ao2_iterator i;
@@ -9862,9 +9904,16 @@
 	ast_log(LOG_DEBUG, "---PUBLISH: Handling device state changes \n");
 	i = ao2_iterator_init(devstate_publishers, 0);
 	while ((p = ao2_iterator_next(&i))) {
-		AST_LIST_TRAVERSE(&p->filters, curfilter, next) {
-			if (!strncmp(curfilter->criteria, sc->dev, strlen(curfilter->criteria))) {
-				sip_devicestate_publish(p, sc);
+		ast_log(LOG_DEBUG, "*** Checking publisher %s\n", p->name);
+		if (&p->filters == NULL) {
+			ast_log(LOG_DEBUG, "   *** No filters for %s\n", p->name);
+			sip_devicestate_publish(p, sc);
+		} else {
+			AST_LIST_TRAVERSE(&p->filters, curfilter, next) {
+				ast_log(LOG_DEBUG, "   *** Comparing -%s- with device -%s-\n", curfilter->criteria, sc->dev);
+				if (!strncasecmp(curfilter->criteria, sc->dev, strlen(curfilter->criteria))) {
+					sip_devicestate_publish(p, sc);
+				}
 			}
 		}
 		ao2_ref(p, -1);
@@ -19168,6 +19217,7 @@
 /*! \brief Destroy presence subscription object */
 static void sip_subscribe_pres_destroy(struct sip_subscription_pres *pres)
 {
+	/* The question here is if this ever really happens */
 	if (pres->call) {
 		sip_pres_unsubscribe(pres);
 		/* We need to know if we're doing this because of unload/shutdown of chan_sip or if the hint is just not
@@ -19558,9 +19608,8 @@
 }
 
 static struct sip_publisher *sip_publisher_init(const char *name, const char *host,
-		const char *domain, char* filter)
-{
-	struct pubsub_filter *filter_head;
+		const char *domain, char *filter)
+{
 	struct sip_publisher *publisher = ao2_alloc(sizeof(*publisher), publisher_destructor_cb);
 
 	if (!publisher) {
@@ -19572,34 +19621,58 @@
 		return NULL;
 	}
 	if (name) {
-		ast_log(LOG_DEBUG, "Setting name to %s\n", name);
+		ast_log(LOG_DEBUG, " Publisher: name %s\n", name);
 		ast_string_field_set(publisher, name, name);
 	}
 	if (host) {
 		ast_string_field_set(publisher, host, host);
-		ast_log(LOG_WARNING, "Setting host\n");
+		ast_log(LOG_DEBUG, " Publisher: %s host %s\n", name, host);
 	}
 	if (domain) {
 		ast_string_field_set(publisher, domain, domain);
-		ast_log(LOG_WARNING, "Setting domain\n");
-	}
-
-	if (!(filter_head = ast_calloc(1, sizeof(*filter_head)))) {
-		return NULL;
-	}
-	filter_head->criteria = filter;
-	AST_LIST_HEAD_SET_NOLOCK(&publisher->filters, filter_head);
-	while(strchr(filter, ',')) {
-		*filter++ = '\0';
-		struct pubsub_filter *next_filter;
-		if (!(next_filter = ast_calloc(1, sizeof(*filter_head)))) {
-			return NULL;
-		}
-		next_filter->criteria = ast_skip_blanks(filter);
-		AST_LIST_INSERT_TAIL(&publisher->filters, next_filter, next);
+		ast_log(LOG_DEBUG, " Publisher: %s domain %s\n", name, domain);
+	}
+
+	if (!ast_strlen_zero(filter)) {
+		char *nextfilter = filter;
+
+		while(nextfilter) {
+			struct pubsub_filter *newfilter;
+			/* First, cut off string if needed */
+			nextfilter = strchr(nextfilter, ',');
+			if (nextfilter) {
+				*nextfilter++ = '\0';
+			}
+			if (!(newfilter = ast_calloc(1, sizeof(*newfilter)))) {
+				ast_log(LOG_ERROR, "Failed to allocate data for filter %s\n", filter);
+				return NULL;
+			}
+			ast_log(LOG_DEBUG, " Publisher: %s - Adding filter %s\n", publisher->name, filter);
+			ast_copy_string(newfilter->criteria, ast_skip_blanks(filter), sizeof(newfilter->criteria));
+
+			if (&publisher->filters == NULL) {
+				AST_LIST_HEAD_SET_NOLOCK(&publisher->filters, newfilter);
+			} else {
+				AST_LIST_INSERT_TAIL(&publisher->filters, newfilter, next);
+			}
+		}
 	}
 
 	return publisher;
+}
+
+static int pubdev_hash_cb(const void *obj, const int flags)
+{
+	const struct sip_published_device *device = obj;
+	ast_log(LOG_DEBUG, "--- XXX Here I am \n");
+	return ast_str_case_hash(device->name);
+}
+
+static int pubdev_cmp_cb(void *obj, void *arg, int flags)
+{
+	const struct sip_published_device *device = obj, *device2 = arg;
+	ast_log(LOG_DEBUG, "--- XXX Here I am \n");
+	return !strcasecmp(device->name, device2->name) ? CMP_MATCH | CMP_STOP : 0;
 }
 
 static int publisher_hash_cb(const void *obj, const int flags)
@@ -19633,9 +19706,10 @@
 		char* domain = NULL;
 		char* filter = NULL;
 		if (!strcasecmp(cat, "general")) {
-					continue;
-		}
-
+			continue;
+		}
+
+		ast_log(LOG_DEBUG, "Presence: Found category %s \n", cat);
 		for (v = ast_variable_browse(pcfg, cat); v; v = v->next) {
 			if (!strcasecmp(v->name, "type")) {
 				type = ast_strdupa(v->value);
@@ -20975,6 +21049,7 @@
 
 	/* Initialise structure for state publishers */
 	devstate_publishers= ao2_container_alloc(11, publisher_hash_cb, publisher_cmp_cb);
+	pub_dev = ao2_container_alloc(11, pubdev_hash_cb, pubdev_cmp_cb);
 
 	if (!(sched = sched_context_create())) {
 		ast_log(LOG_ERROR, "Unable to create scheduler context\n");




More information about the svn-commits mailing list