[asterisk-commits] mmichelson: branch mmichelson/pubsub_bodies r405907 - in /team/mmichelson/pub...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jan 20 11:24:24 CST 2014


Author: mmichelson
Date: Mon Jan 20 11:24:20 2014
New Revision: 405907

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=405907
Log:
Further decouple subscription handlers and body generators.

Subscription handlers no longer require a list of accept types they
handle. Instead, the accept field of a subscription handler is used
solely when in the role of a subscriber. The default accept type is
now specified for a handler since that is a property of the handler.

While this compiles, there are a couple of problems here:

1) Subscribe handlers are making assumptions about the body types
to generate. MWI, for instance, will always try to create an
application/simple-message-summary body, even if a different body
type is to be used for the subscription. The body generator in use
needs to be stored on the subscription, and allocation of the body
type to be used by body generators should be performed by the
primary body generator for the subscription.

2) Exten state providers need to be converted to be body generators
instead. Currently, errors will occur on startup because each of the
providers results in a subscription handler being created. Instead,
only a single "presence" subscription handler is needed, but multiple
body generators need to be registered with the pubsub core.


Modified:
    team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_pubsub.h
    team/mmichelson/pubsub_bodies/res/res_pjsip_exten_state.c
    team/mmichelson/pubsub_bodies/res/res_pjsip_mwi.c
    team/mmichelson/pubsub_bodies/res/res_pjsip_pubsub.c

Modified: team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_pubsub.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_pubsub.h?view=diff&rev=405907&r1=405906&r2=405907
==============================================================================
--- team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_pubsub.h (original)
+++ team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_pubsub.h Mon Jan 20 11:24:20 2014
@@ -226,23 +226,22 @@
 struct ast_sip_subscription_handler {
 	/*! The name of the event this handler deals with */
 	const char *event_name;
-	/*! The types of body this handler accepts */
+	/*! The types of body this handler accepts.
+	 *
+	 * \note This option has no bearing when the handler is used in the
+	 * notifier role. When in a subscriber role, this header is used to
+	 * populate the Accept: header of an outbound SUBSCRIBE request
+	 */
 	const char *accept[AST_SIP_MAX_ACCEPT];
 	/*!
-	 * \brief Indicates if this handler can be used as a default handler for an event type.
+	 * \brief Default body type defined for the event package this handler handles.
 	 *
 	 * Typically, a SUBSCRIBE request will contain one or more Accept headers that tell
 	 * what format they expect the body of NOTIFY requests to use. However, every event
 	 * package is required to define a default body format type to be used if a SUBSCRIBE
 	 * request for the event contains no Accept header.
-	 *
-	 * If this value is non-zero, then this handler provides the default body format for
-	 * the event package and can handle SUBSCRIBES with no Accept headers present.
-	 * If this value is zero, then this handler provides an alternative body format
-	 * from the default for the event package and cannot handle SUBSCRIBEs with no
-	 * Accept header.
-	 */
-	unsigned int handles_default_accept;
+	 */
+	const char *default_accept;
 	/*!
 	 * \brief Called when a subscription is to be destroyed
 	 *

Modified: team/mmichelson/pubsub_bodies/res/res_pjsip_exten_state.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pubsub_bodies/res/res_pjsip_exten_state.c?view=diff&rev=405907&r1=405906&r2=405907
==============================================================================
--- team/mmichelson/pubsub_bodies/res/res_pjsip_exten_state.c (original)
+++ team/mmichelson/pubsub_bodies/res/res_pjsip_exten_state.c Mon Jan 20 11:24:20 2014
@@ -548,10 +548,7 @@
 
 	handler->event_name = event_name;
 	handler->accept[0] = accept;
-	if (!strcmp(accept, DEFAULT_PRESENCE_BODY)) {
-		handler->handles_default_accept = 1;
-	}
-
+	handler->default_accept = DEFAULT_PRESENCE_BODY;
 	handler->subscription_shutdown = subscription_shutdown;
 	handler->new_subscribe = new_subscribe;
 	handler->resubscribe = resubscribe;

Modified: team/mmichelson/pubsub_bodies/res/res_pjsip_mwi.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pubsub_bodies/res/res_pjsip_mwi.c?view=diff&rev=405907&r1=405906&r2=405907
==============================================================================
--- team/mmichelson/pubsub_bodies/res/res_pjsip_mwi.c (original)
+++ team/mmichelson/pubsub_bodies/res/res_pjsip_mwi.c Mon Jan 20 11:24:20 2014
@@ -63,7 +63,7 @@
 static struct ast_sip_subscription_handler mwi_handler = {
 	.event_name = "message-summary",
 	.accept = { MWI_TYPE"/"MWI_SUBTYPE, },
-	.handles_default_accept = 1,
+	.default_accept =  MWI_TYPE"/"MWI_SUBTYPE,
 	.subscription_shutdown = mwi_subscription_shutdown,
 	.new_subscribe = mwi_new_subscribe,
 	.resubscribe = mwi_resubscribe,

Modified: team/mmichelson/pubsub_bodies/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pubsub_bodies/res/res_pjsip_pubsub.c?view=diff&rev=405907&r1=405906&r2=405907
==============================================================================
--- team/mmichelson/pubsub_bodies/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/pubsub_bodies/res/res_pjsip_pubsub.c Mon Jan 20 11:24:20 2014
@@ -633,31 +633,35 @@
 	ast_module_ref(ast_module_info->self);
 }
 
-static int sub_handler_exists_for_event_name(const char *event_name)
+static struct ast_sip_subscription_handler *find_sub_handler_for_event_name(const char *event_name)
 {
 	struct ast_sip_subscription_handler *iter;
 	SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
 
 	AST_RWLIST_TRAVERSE(&subscription_handlers, iter, next) {
 		if (!strcmp(iter->event_name, event_name)) {
-			return 1;
-		}
-	}
-	return 0;
+			break;
+		}
+	}
+	return iter;
 }
 
 int ast_sip_register_subscription_handler(struct ast_sip_subscription_handler *handler)
 {
+	pj_str_t event;
 	pj_str_t accept[AST_SIP_MAX_ACCEPT];
+	struct ast_sip_subscription_handler *existing;
 	int i;
 
 	if (ast_strlen_zero(handler->event_name)) {
-		ast_log(LOG_ERROR, "No event package specifief for subscription handler. Cannot register\n");
+		ast_log(LOG_ERROR, "No event package specified for subscription handler. Cannot register\n");
 		return -1;
 	}
 
-	if (ast_strlen_zero(handler->accept[0])) {
-		ast_log(LOG_ERROR, "Subscription handler must supply at least one 'Accept' format\n");
+	existing = find_sub_handler_for_event_name(handler->event_name);
+	if (existing) {
+		ast_log(LOG_ERROR, "Unable to register subscription handler for event %s."
+				"A handler is already registered\n", handler->event_name);
 		return -1;
 	}
 
@@ -665,19 +669,12 @@
 		pj_cstr(&accept[i], handler->accept[i]);
 	}
 
-	if (!sub_handler_exists_for_event_name(handler->event_name)) {
-		pj_str_t event;
-
-		pj_cstr(&event, handler->event_name);
-
-		if (!strcmp(handler->event_name, "message-summary")) {
-			pjsip_mwi_init_module(ast_sip_get_pjsip_endpoint(), pjsip_evsub_instance());
-		} else {
-			pjsip_evsub_register_pkg(&pubsub_module, &event, DEFAULT_EXPIRES, i, accept);
-		}
+	pj_cstr(&event, handler->event_name);
+
+	if (!strcmp(handler->event_name, "message-summary")) {
+		pjsip_mwi_init_module(ast_sip_get_pjsip_endpoint(), pjsip_evsub_instance());
 	} else {
-		pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), &pubsub_module, PJSIP_H_ACCEPT, NULL,
-			i, accept);
+		pjsip_evsub_register_pkg(&pubsub_module, &event, DEFAULT_EXPIRES, i, accept);
 	}
 
 	sub_add_handler(handler);
@@ -698,8 +695,8 @@
 	AST_RWLIST_TRAVERSE_SAFE_END;
 }
 
-static struct ast_sip_pubsub_body_generator *find_body_generator_type_subtype(char *content_type,
-		char *content_subtype)
+static struct ast_sip_pubsub_body_generator *find_body_generator_type_subtype(const char *content_type,
+		const char *content_subtype)
 {
 	struct ast_sip_pubsub_body_generator *iter;
 	SCOPED_LOCK(lock, &body_generators, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
@@ -738,52 +735,45 @@
 
 static struct ast_sip_subscription_handler *find_sub_handler(const char *event, char accept[AST_SIP_MAX_ACCEPT][64], size_t num_accept)
 {
-	struct ast_sip_subscription_handler *iter;
-	int match = 0;
-	SCOPED_LOCK(lock, &subscription_handlers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
-	AST_RWLIST_TRAVERSE(&subscription_handlers, iter, next) {
-		int i;
-		int j;
-		if (strcmp(event, iter->event_name)) {
-			ast_debug(3, "Event %s does not match %s\n", event, iter->event_name);
-			continue;
-		}
-		ast_debug(3, "Event name match: %s = %s\n", event, iter->event_name);
-		if (!num_accept && iter->handles_default_accept) {
-			/* The SUBSCRIBE contained no Accept headers, and this subscription handler
-			 * provides the default body type, so it's a match!
-			 */
-			break;
-		}
-		for (i = 0; i < num_accept; ++i) {
-			for (j = 0; j < num_accept; ++j) {
-				if (ast_strlen_zero(iter->accept[i])) {
-					ast_debug(3, "Breaking because subscription handler has run out of 'accept' types\n");
-					break;
-				}
-				if (!strcmp(accept[j], iter->accept[i])) {
-					struct ast_sip_pubsub_body_generator *generator;
-
-					ast_debug(3, "Accept headers match: %s = %s\n", accept[j], iter->accept[i]);
-					generator = find_body_generator_accept(accept[j]);
-					if (generator) {
-						ast_debug(3, "Body generator %p matches this content type\n", generator);
-						match = 1;
-					}
-					break;
-				}
-				ast_debug(3, "Accept %s does not match %s\n", accept[j], iter->accept[i]);
-			}
-			if (match) {
-				break;
-			}
-		}
-		if (match) {
-			break;
-		}
-	}
-
-	return iter;
+	struct ast_sip_subscription_handler *handler;
+	int i;
+
+	handler = find_sub_handler_for_event_name(event);
+	if (!handler) {
+		ast_log(LOG_WARNING, "No subscription handler found for event %s\n", event);
+		return NULL;
+	}
+
+	/* If a SUBSCRIBE contains no Accept headers, then we must assume that
+	 * the default accept type for the event package is to be used.
+	 */
+	if (num_accept == 0) {
+		struct ast_sip_pubsub_body_generator *generator;
+
+		generator = find_body_generator_accept(handler->default_accept);
+		if (generator) {
+			ast_debug(3, "Body generator %p found for accept type %s\n", generator, handler->default_accept);
+			return handler;
+		} else {
+			ast_log(LOG_WARNING, "No body generator found for default accept type %s\n", handler->default_accept);
+			return NULL;
+		}
+	}
+
+	for (i = 0; i < num_accept; ++i) {
+		struct ast_sip_pubsub_body_generator *generator;
+
+		generator = find_body_generator_accept(accept[i]);
+		if (generator) {
+			ast_debug(3, "Body generator %p found for accept type %s\n", generator, accept[i]);
+			return handler;
+		} else {
+			ast_debug(3, "No body generator found for accept type %s\n", accept[i]);
+		}
+	}
+
+	ast_log(LOG_WARNING, "No body generator found for any Accept headers\n");
+	return NULL;
 }
 
 static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata)
@@ -1112,30 +1102,44 @@
 
 int ast_sip_pubsub_register_body_generator(struct ast_sip_pubsub_body_generator *generator)
 {
-	struct ast_sip_pubsub_body_generator *iter;
-	SCOPED_LOCK(lock, &body_generators, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+	struct ast_sip_pubsub_body_generator *existing;
+	pj_str_t accept;
+	pj_size_t accept_len;
 
 	if (generator->generator_type == AST_SIP_PUBSUB_BODY_GENERATOR_SUPPLEMENTARY) {
-		AST_LIST_INSERT_TAIL(&body_generators, generator, list);
+		AST_RWLIST_WRLOCK(&body_generators);
+		AST_RWLIST_INSERT_TAIL(&body_generators, generator, list);
+		AST_RWLIST_UNLOCK(&body_generators);
 		return 0;
 	}
 
 	/* Primary body generators have to be checked in case they clash with a registered
 	 * body primary body generator.
 	 */
-	AST_LIST_TRAVERSE(&body_generators, iter, list) {
-		if (iter->generator_type == AST_SIP_PUBSUB_BODY_GENERATOR_SUPPLEMENTARY) {
-			continue;
-		}
-		if (!strcmp(iter->type, generator->type) &&
-				!strcmp(iter->subtype, generator->subtype)) {
-			ast_log(LOG_WARNING, "Cannot register primary body generator of %s/%s."
-					"One is already registered.\n", generator->type, generator->subtype);
-			return -1;
-		}
-	}
-
+	existing = find_body_generator_type_subtype(generator->type, generator->subtype);
+	if (existing) {
+		ast_log(LOG_WARNING, "Cannot register primary body generator of %s/%s."
+				"One is already registered.\n", generator->type, generator->subtype);
+		return -1;
+	}
+
+	AST_RWLIST_WRLOCK(&body_generators);
 	AST_LIST_INSERT_HEAD(&body_generators, generator, list);
+	AST_RWLIST_UNLOCK(&body_generators);
+
+	/* Lengths of type and subtype plus space for a slash. pj_str_t is not
+	 * null-terminated, so there is no need to allocate for the extra null
+	 * byte
+	 */
+	accept_len = strlen(generator->type) + strlen(generator->subtype) + 1;
+
+	accept.ptr = alloca(accept_len);
+	accept.slen = accept_len;
+	/* Safe use of sprintf */
+	sprintf(accept.ptr, "%s/%s", generator->type, generator->subtype);
+	pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), &pubsub_module,
+			PJSIP_H_ACCEPT, NULL, 1, &accept);
+
 	return 0;
 }
 




More information about the asterisk-commits mailing list