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

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jan 21 10:54:31 CST 2014


Author: mmichelson
Date: Tue Jan 21 10:54:26 2014
New Revision: 406019

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=406019
Log:
Separate body generators from supplements.

Having primary and supplementary generators seemed like
it was a bit odd. Instead, having two separate types appears
to work much beter.

This commit also has some compile fixes for presence-related
functions.


Modified:
    team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_presence_xml.h
    team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_pubsub.h
    team/mmichelson/pubsub_bodies/res/res_pjsip_mwi_body_generator.c
    team/mmichelson/pubsub_bodies/res/res_pjsip_pidf.c
    team/mmichelson/pubsub_bodies/res/res_pjsip_pidf_body_generator.c
    team/mmichelson/pubsub_bodies/res/res_pjsip_pubsub.c
    team/mmichelson/pubsub_bodies/res/res_pjsip_xpidf_body_generator.c

Modified: team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_presence_xml.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_presence_xml.h?view=diff&rev=406019&r1=406018&r2=406019
==============================================================================
--- team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_presence_xml.h (original)
+++ team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_presence_xml.h Tue Jan 21 10:54:26 2014
@@ -37,8 +37,8 @@
  * \param[out] pidfnote
  * \param[out] local_state
  */
-void exten_state_to_str(int state, char **statestring, char **pidfstate,
-			       char **pidfnote, enum ast_sip_pidf_state *local_state);
+void ast_pjsip_presence_exten_state_to_str(int state, char **statestring,
+		char **pidfstate, char **pidfnote, enum ast_sip_pidf_state *local_state);
 
 /*!
  * \brief Create XML attribute

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=406019&r1=406018&r2=406019
==============================================================================
--- team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_pubsub.h (original)
+++ team/mmichelson/pubsub_bodies/include/asterisk/res_pjsip_pubsub.h Tue Jan 21 10:54:26 2014
@@ -537,32 +537,6 @@
 void ast_sip_unregister_subscription_handler(struct ast_sip_subscription_handler *handler);
 
 /*!
- * The types of body generators
- */
-enum ast_sip_pubsub_body_generator_type {
-	/*!
-	 * \brief Primary body generator
-	 *
-	 * A primary body generator is expected to follow whichever
-	 * RFC or RFCs define the behavior for a given event package
-	 * and a given body type. A primary body generator is required
-	 * in order to create NOTIFY or PUBLISH requests. Only one
-	 * primary body generator of a given type is permitted.
-	 */
-	AST_SIP_PUBSUB_BODY_GENERATOR_PRIMARY,
-	/*!
-	 * \brief Supplementary body generator
-	 *
-	 * A supplementary body generator adds onto the body created
-	 * by the primary body generator. Supplementary body generators
-	 * are typically used to provide proprietary or other nonstandard
-	 * information in a body. There is no limit on the number of
-	 * supplementary body generators allowed for a given type.
-	 */
-	AST_SIP_PUBSUB_BODY_GENERATOR_SUPPLEMENTARY,
-};
-
-/*!
  * \brief Pubsub body generator
  *
  * A body generator is responsible for taking Asterisk content
@@ -581,13 +555,9 @@
 	 */
 	const char *subtype;
 	/*!
-	 * Type of body generator this is
-	 */
-	enum ast_sip_pubsub_body_generator_type generator_type;
-	/*!
 	 * \brief allocate body structure.
 	 *
-	 * Primary body generators will have this method called when a NOTIFY
+	 * Body generators will have this method called when a NOTIFY
 	 * or PUBLISH body needs to be created. The type returned depends on
 	 * the type of content being produced for the body. The data parameter
 	 * is provided by the subscription handler and will vary between different
@@ -601,10 +571,8 @@
 	/*!
 	 * \brief Add content to the body of a SIP request
 	 *
-	 * The body of the request has already been allocated. Primary body
-	 * generators will be given an empty body and will populate it with the
-	 * initial set of data. Supplementary body generators will then be given
-	 * the generated body to edit or augment as desired.
+	 * The body of the request has already been allocated by the body generator's
+	 * allocate_body callback.
 	 *
 	 * \param body The body of the SIP request. The type is determined by the
 	 * content type.
@@ -629,6 +597,40 @@
 	 */
 	void (*destroy_body)(void *body);
 	AST_LIST_ENTRY(ast_sip_pubsub_body_generator) list;
+};
+
+/*!
+ * \brief Body supplement
+ *
+ * Body supplements provide additions to bodies not already
+ * provided by body generators. This may include proprietary
+ * extensions, optional content, or other nonstandard fare.
+ */
+struct ast_sip_pubsub_body_supplement {
+	/*!
+	 * \brief Content type
+	 * In "plain/text", "plain" is the type
+	 */
+	const char *type;
+	/*!
+	 * \brief Content subtype
+	 * In "plain/text", "text" is the subtype
+	 */
+	const char *subtype;
+	/*!
+	 * \brief Add additional content to a SIP request body.
+	 *
+	 * A body generator will have already allocated a body and populated
+	 * it with base data for the event. The supplement's duty is, if desired,
+	 * to extend the body to have optional data beyond what a base RFC specifies.
+	 *
+	 * \param body The body of the SIP request. The type is determined by the
+	 * body generator that allocated the body.
+	 * \param data The subscription data used to populate the body. The type is
+	 * determined by the content type.
+	 */
+	int (*supplement_body)(void *body, void *data);
+	AST_LIST_ENTRY(ast_sip_pubsub_body_supplement) list;
 };
 
 /*!
@@ -674,6 +676,28 @@
 
 /*!
  * \since 13.0.0
+ * \brief Register a body generator with the pubsub core.
+ *
+ * This may fail if an attempt is made to register a primary body supplement
+ * for a given content type if a primary body supplement for that content type
+ * has already been registered.
+ * 
+ * \param generator Body generator to register
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_pubsub_register_body_supplement(struct ast_sip_pubsub_body_supplement *supplement);
+
+/*!
+ * \since 13.0.0
+ * \brief Unregister a body generator with the pubsub core.
+ *
+ * \param generator Body generator to unregister
+ */
+void ast_sip_pubsub_unregister_body_supplement(struct ast_sip_pubsub_body_supplement *supplement);
+
+/*!
+ * \since 13.0.0
  * \brief Get the body type used for this subscription
  */
 const char *ast_sip_subscription_get_body_type(struct ast_sip_subscription *sub);

Modified: team/mmichelson/pubsub_bodies/res/res_pjsip_mwi_body_generator.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pubsub_bodies/res/res_pjsip_mwi_body_generator.c?view=diff&rev=406019&r1=406018&r2=406019
==============================================================================
--- team/mmichelson/pubsub_bodies/res/res_pjsip_mwi_body_generator.c (original)
+++ team/mmichelson/pubsub_bodies/res/res_pjsip_mwi_body_generator.c Tue Jan 21 10:54:26 2014
@@ -85,7 +85,6 @@
 static struct ast_sip_pubsub_body_generator mwi_generator = {
 	.type = MWI_TYPE,
 	.subtype = MWI_SUBTYPE,
-	.generator_type = AST_SIP_PUBSUB_BODY_GENERATOR_PRIMARY,
 	.allocate_body = mwi_allocate_body,
 	.generate_body_content = mwi_generate_body_content,
 	.to_string = mwi_to_string,

Modified: team/mmichelson/pubsub_bodies/res/res_pjsip_pidf.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pubsub_bodies/res/res_pjsip_pidf.c?view=diff&rev=406019&r1=406018&r2=406019
==============================================================================
--- team/mmichelson/pubsub_bodies/res/res_pjsip_pidf.c (original)
+++ team/mmichelson/pubsub_bodies/res/res_pjsip_pidf.c Tue Jan 21 10:54:26 2014
@@ -36,7 +36,7 @@
 #include "asterisk/res_pjsip_presence_xml.h"
 #include "asterisk/res_pjsip_body_generator_types.h"
 
-void exten_state_to_str(int state, char **statestring, char **pidfstate,
+void ast_pjsip_presence_exten_state_to_str(int state, char **statestring, char **pidfstate,
 			       char **pidfnote, enum ast_sip_pidf_state *local_state)
 {
 	switch (state) {

Modified: team/mmichelson/pubsub_bodies/res/res_pjsip_pidf_body_generator.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pubsub_bodies/res/res_pjsip_pidf_body_generator.c?view=diff&rev=406019&r1=406018&r2=406019
==============================================================================
--- team/mmichelson/pubsub_bodies/res/res_pjsip_pidf_body_generator.c (original)
+++ team/mmichelson/pubsub_bodies/res/res_pjsip_pidf_body_generator.c Tue Jan 21 10:54:26 2014
@@ -32,7 +32,7 @@
 #include "asterisk/module.h"
 #include "asterisk/res_pjsip.h"
 #include "asterisk/res_pjsip_pubsub.h"
-#include "asterisk/res_pjsip_xml.h"
+#include "asterisk/res_pjsip_presence_xml.h"
 #include "asterisk/res_pjsip_body_generator_types.h"
 
 /*!
@@ -55,11 +55,11 @@
 	static const char *XMLNS_EP = "xmlns:ep";
 	static const char *XMLNS_RPID_PERSON = "urn:ietf:params:xml:ns:pidf:rpid:rpid-person";
 
-	pj_xml_node *person = create_node(pool, node, "pp:person");
-	pj_xml_node *status = create_node(pool, person, "status");
+	pj_xml_node *person = ast_pjsip_presence_xml_create_node(pool, node, "pp:person");
+	pj_xml_node *status = ast_pjsip_presence_xml_create_node(pool, person, "status");
 
 	if (pidfstate[0] != '-') {
-		pj_xml_node *activities = create_node(pool, status, "ep:activities");
+		pj_xml_node *activities = ast_pjsip_presence_xml_create_node(pool, status, "ep:activities");
 		size_t str_size = sizeof("ep:") + strlen(pidfstate);
 
 		activities->content.ptr = pj_pool_alloc(pool, str_size);
@@ -67,9 +67,9 @@
 				"ep:%s", pidfstate);
 	}
 
-	create_attr(pool, node, XMLNS_PP, XMLNS_PERSON);
-	create_attr(pool, node, XMLNS_ES, XMLNS_RPID_STATUS);
-	create_attr(pool, node, XMLNS_EP, XMLNS_RPID_PERSON);
+	ast_pjsip_presence_xml_create_attr(pool, node, XMLNS_PP, XMLNS_PERSON);
+	ast_pjsip_presence_xml_create_attr(pool, node, XMLNS_ES, XMLNS_RPID_STATUS);
+	ast_pjsip_presence_xml_create_attr(pool, node, XMLNS_EP, XMLNS_RPID_PERSON);
 }
 
 /*!
@@ -124,12 +124,12 @@
 	pjpidf_tuple *tuple;
 	pj_str_t note, id, contact, priority;
 	char *statestring = NULL, *pidfstate = NULL, *pidfnote = NULL;
-	int local_state;
+	enum ast_sip_pidf_state local_state;
 	char sanitized[PJSIP_MAX_URL_SIZE];
 	pjpidf_pres *pres = body;
 	struct ast_sip_exten_state_data *state_data = data;
 
-	exten_state_to_str(state_data->exten_state, &statestring, &pidfstate,
+	ast_pjsip_presence_exten_state_to_str(state_data->exten_state, &statestring, &pidfstate,
 			   &pidfnote, &local_state);
 
 	add_non_standard(state_data->pool, pres, pidfstate);
@@ -183,7 +183,6 @@
 static struct ast_sip_pubsub_body_generator pidf_body_generator = {
 	.type = "application",
 	.subtype = "pidf+xml",
-	.generator_type = AST_SIP_PUBSUB_BODY_GENERATOR_PRIMARY,
 	.allocate_body = pidf_allocate_body,
 	.generate_body_content = pidf_generate_body_content,
 	.to_string = pidf_to_string,

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=406019&r1=406018&r2=406019
==============================================================================
--- team/mmichelson/pubsub_bodies/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/pubsub_bodies/res/res_pjsip_pubsub.c Tue Jan 21 10:54:26 2014
@@ -197,7 +197,7 @@
 	pjsip_evsub *evsub;
 	/*! The underlying PJSIP dialog */
 	pjsip_dialog *dlg;
-	/*! Primary body generaator for NOTIFYs */
+	/*! Body generaator for NOTIFYs */
 	struct ast_sip_pubsub_body_generator *body_generator;
 	/*! Next item in the list */
 	AST_LIST_ENTRY(ast_sip_subscription) next;
@@ -211,6 +211,7 @@
 AST_RWLIST_HEAD_STATIC(subscriptions, ast_sip_subscription);
 
 AST_RWLIST_HEAD_STATIC(body_generators, ast_sip_pubsub_body_generator);
+AST_RWLIST_HEAD_STATIC(body_supplements, ast_sip_pubsub_body_supplement);
 
 static void add_subscription(struct ast_sip_subscription *obj)
 {
@@ -708,15 +709,6 @@
 	SCOPED_LOCK(lock, &body_generators, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
 
 	AST_LIST_TRAVERSE(&body_generators, iter, list) {
-		/* If we've reached the supplementary body generators and don't have a match,
-		 * then there is no primary body generator match, which means we cannot
-		 * handle the subscription
-		 */
-		if (iter->generator_type ==
-				AST_SIP_PUBSUB_BODY_GENERATOR_SUPPLEMENTARY) {
-			iter = NULL;
-			break;
-		}
 		if (!strcmp(iter->type, content_type) &&
 				!strcmp(iter->subtype, content_subtype)) {
 			break;
@@ -1102,19 +1094,9 @@
 	pj_str_t accept;
 	pj_size_t accept_len;
 
-	if (generator->generator_type == AST_SIP_PUBSUB_BODY_GENERATOR_SUPPLEMENTARY) {
-		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.
-	 */
 	existing = find_body_generator_type_subtype(generator->type, generator->subtype);
 	if (existing) {
-		ast_log(LOG_WARNING, "Cannot register primary body generator of %s/%s."
+		ast_log(LOG_WARNING, "Cannot register body generator of %s/%s."
 				"One is already registered.\n", generator->type, generator->subtype);
 		return -1;
 	}
@@ -1153,6 +1135,29 @@
 	AST_RWLIST_TRAVERSE_SAFE_END;
 }
 
+int ast_sip_pubsub_register_body_supplement(struct ast_sip_pubsub_body_supplement *supplement)
+{
+	AST_RWLIST_WRLOCK(&body_supplements);
+	AST_RWLIST_INSERT_TAIL(&body_supplements, supplement, list);
+	AST_RWLIST_UNLOCK(&body_supplements);
+
+	return 0;
+}
+
+void ast_sip_pubsub_unregister_body_supplement(struct ast_sip_pubsub_body_supplement *supplement)
+{
+	struct ast_sip_pubsub_body_supplement *iter;
+	SCOPED_LOCK(lock, &body_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
+
+	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&body_supplements, iter, list) {
+		if (iter == supplement) {
+			AST_LIST_REMOVE_CURRENT(list);
+			break;
+		}
+	}
+	AST_RWLIST_TRAVERSE_SAFE_END;
+}
+
 const char *ast_sip_subscription_get_body_type(struct ast_sip_subscription *sub)
 {
 	return sub->body_generator->type;
@@ -1166,48 +1171,45 @@
 int ast_sip_pubsub_generate_body_content(const char *type, const char *subtype,
 		void *data, struct ast_str **str)
 {
-	struct ast_sip_pubsub_body_generator *supplement;
-	struct ast_sip_pubsub_body_generator *primary;
+	struct ast_sip_pubsub_body_supplement *supplement;
+	struct ast_sip_pubsub_body_generator *generator;
 	int res;
 	void *body;
 
-	primary = find_body_generator_type_subtype(type, subtype);
-	if (!primary) {
+	generator = find_body_generator_type_subtype(type, subtype);
+	if (!generator) {
 		return -1;
 	}
 
-	body = primary->allocate_body(data);
+	body = generator->allocate_body(data);
 	if (!body) {
 		return -1;
 	}
 
-	if (primary->generate_body_content(body, data)) {
+	if (generator->generate_body_content(body, data)) {
 		res = -1;
 		goto end;
 	}
 
-	AST_RWLIST_RDLOCK(&body_generators);
-	AST_RWLIST_TRAVERSE(&body_generators, supplement, list) {
-		if (supplement->generator_type != AST_SIP_PUBSUB_BODY_GENERATOR_SUPPLEMENTARY) {
-			continue;
-		}
-		if (!strcmp(primary->type, supplement->type) &&
-				!strcmp(primary->subtype, supplement->subtype)) {
-			res = supplement->generate_body_content(body, data);
+	AST_RWLIST_RDLOCK(&body_supplements);
+	AST_RWLIST_TRAVERSE(&body_supplements, supplement, list) {
+		if (!strcmp(generator->type, supplement->type) &&
+				!strcmp(generator->subtype, supplement->subtype)) {
+			res = supplement->supplement_body(body, data);
 			if (res) {
 				break;
 			}
 		}
 	}
-	AST_RWLIST_UNLOCK(&body_generators);
+	AST_RWLIST_UNLOCK(&body_supplements);
 
 	if (!res) {
-		primary->to_string(body, str);
+		generator->to_string(body, str);
 	}
 
 end:
-	if (primary->destroy_body) {
-		primary->destroy_body(body);
+	if (generator->destroy_body) {
+		generator->destroy_body(body);
 	}
 
 	return res;

Modified: team/mmichelson/pubsub_bodies/res/res_pjsip_xpidf_body_generator.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/pubsub_bodies/res/res_pjsip_xpidf_body_generator.c?view=diff&rev=406019&r1=406018&r2=406019
==============================================================================
--- team/mmichelson/pubsub_bodies/res/res_pjsip_xpidf_body_generator.c (original)
+++ team/mmichelson/pubsub_bodies/res/res_pjsip_xpidf_body_generator.c Tue Jan 21 10:54:26 2014
@@ -33,7 +33,7 @@
 #include "asterisk/module.h"
 #include "asterisk/res_pjsip.h"
 #include "asterisk/res_pjsip_pubsub.h"
-#include "asterisk/res_pjsip_xml.h"
+#include "asterisk/res_pjsip_presence_xml.h"
 #include "asterisk/res_pjsip_body_generator_types.h"
 
 static void *xpidf_allocate_body(void *data)
@@ -53,31 +53,31 @@
 	static pj_str_t STR_ADDR_PARAM = { ";user=ip", 8 };
 	char *statestring = NULL, *pidfstate = NULL, *pidfnote = NULL;
 	pj_xml_attr *attr;
-	int local_state;
+	enum ast_sip_pidf_state local_state;
 	pj_str_t name, uri;
 
-	exten_state_to_str(state_data->exten_state, &statestring, &pidfstate,
-			   &pidfnote, &local_state);
+	ast_pjsip_presence_exten_state_to_str(state_data->exten_state, &statestring,
+			&pidfstate, &pidfnote, &local_state);
 
-	attr = find_node_attr(state_data->pool, pres, "atom", "id");
+	attr = ast_pjsip_presence_xml_find_node_attr(state_data->pool, pres, "atom", "id");
 	pj_strdup2(state_data->pool, &attr->value, state_data->exten);
 
-	attr = find_node_attr(state_data->pool, pres, "address", "uri");
+	attr = ast_pjsip_presence_xml_find_node_attr(state_data->pool, pres, "address", "uri");
 
 	uri.ptr = (char*) pj_pool_alloc(state_data->pool, strlen(state_data->remote) + STR_ADDR_PARAM.slen);
 	pj_strcpy2( &uri, state_data->remote);
 	pj_strcat( &uri, &STR_ADDR_PARAM);
 	pj_strdup(state_data->pool, &attr->value, &uri);
 
-	create_attr(state_data->pool, pj_xml_find_node(pres, pj_cstr(&name, "address")),
+	ast_pjsip_presence_xml_create_attr(state_data->pool, pj_xml_find_node(pres, pj_cstr(&name, "address")),
 		    "priority", "0.80000");
 
-	attr = find_node_attr(state_data->pool, pres, "status", "status");
+	attr = ast_pjsip_presence_xml_find_node_attr(state_data->pool, pres, "status", "status");
 	pj_strdup2(state_data->pool, &attr->value,
 		   (local_state ==  NOTIFY_OPEN) ? "open" :
 		   (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
 
-	attr = find_node_attr(state_data->pool, pres, "msnsubstatus", "substatus");
+	attr = ast_pjsip_presence_xml_find_node_attr(state_data->pool, pres, "msnsubstatus", "substatus");
 	pj_strdup2(state_data->pool, &attr->value,
 		   (local_state == NOTIFY_OPEN) ? "online" :
 		   (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
@@ -115,7 +115,6 @@
 static struct ast_sip_pubsub_body_generator xpidf_body_generator = {
 	.type = "application",
 	.subtype = "xpidf+xml",
-	.generator_type = AST_SIP_PUBSUB_BODY_GENERATOR_PRIMARY,
 	.allocate_body = xpidf_allocate_body,
 	.generate_body_content = xpidf_generate_body_content,
 	.to_string = xpidf_to_string,
@@ -125,7 +124,6 @@
 static struct ast_sip_pubsub_body_generator cpim_pidf_body_generator = {
 	.type = "application",
 	.subtype = "cpim-pidf+xml",
-	.generator_type = AST_SIP_PUBSUB_BODY_GENERATOR_PRIMARY,
 	.allocate_body = xpidf_allocate_body,
 	.generate_body_content = xpidf_generate_body_content,
 	.to_string = xpidf_to_string,




More information about the asterisk-commits mailing list