[svn-commits] mmichelson: branch mmichelson/rls-rlmi r418221 - /team/mmichelson/rls-rlmi/res/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jul 9 09:38:43 CDT 2014


Author: mmichelson
Date: Wed Jul  9 09:38:37 2014
New Revision: 418221

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=418221
Log:
Initial skeleton of generating multipart bodies with RLMI.

This takes care of constructing a multipart body, but there are loads of issues
still to deal with:

1) Lots of hardcoded values for the moment
2) The RLMI body is the last part instead of the first part
3) Current algorithm will not work with a list of lists

Plus, this is where I will likely catch bugs from previous tasks that
were untestable until now.


Modified:
    team/mmichelson/rls-rlmi/res/res_pjsip_pubsub.c

Modified: team/mmichelson/rls-rlmi/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/rls-rlmi/res/res_pjsip_pubsub.c?view=diff&rev=418221&r1=418220&r2=418221
==============================================================================
--- team/mmichelson/rls-rlmi/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/rls-rlmi/res/res_pjsip_pubsub.c Wed Jul  9 09:38:37 2014
@@ -44,6 +44,7 @@
 #include "asterisk/manager.h"
 #include "asterisk/test.h"
 #include "res_pjsip/include/res_pjsip_private.h"
+#include "asterisk/res_pjsip_presence_xml.h"
 
 /*** DOCUMENTATION
 	<manager name="PJSIPShowSubscriptionsInbound" language="en_US">
@@ -603,7 +604,7 @@
 
 		for (i = 0; i < accept_header->count; ++i) {
 			if (!exceptional_accept(&accept_header->values[i])) {
-				ast_copy_pj_str(accept[i], &accept_header->values[i], sizeof(accept[i]));
+				ast_copy_pj_str(accept[num_accept_headers], &accept_header->values[i], sizeof(accept[num_accept_headers]));
 				++num_accept_headers;
 			}
 		}
@@ -1018,9 +1019,10 @@
 
 	for (i = 0; i < AST_VECTOR_SIZE(&current->children); ++i) {
 		struct ast_sip_subscription *child;
-
-		child = create_virtual_subscriptions(handler, resource, generator,
-				tree, AST_VECTOR_GET(&current->children, i));
+		struct tree_node *child_node = AST_VECTOR_GET(&current->children, i);
+
+		child = create_virtual_subscriptions(handler, child_node->resource, generator,
+				tree, child_node);
 
 		if (!child) {
 			continue;
@@ -1439,75 +1441,173 @@
 	return res;
 }
 
-static int generate_list_body(struct ast_sip_subscription *sub, struct ast_str **str)
-{
-	/* XXX This is where a multipart/related body would be created with
-	 * an RLMI part and the bodies of all child parts of the subscription.
-	 * The generated multipart/related body is then saved on sub->body_text.
-	 *
-	 * This will be added when working on ASTERISK-23867. For now, this is
-	 * just a STUB.
+static void add_rlmi_resource(pj_pool_t *pool, pj_xml_node *rlmi, const char *cid)
+{
+	pj_xml_node *resource;
+	pj_xml_node *name;
+	pj_xml_node *instance;
+	char uri[PJSIP_MAX_URL_SIZE];
+	char id[AST_UUID_STR_LEN];
+
+	resource = ast_sip_presence_xml_create_node(pool, rlmi, "resource");
+	name = ast_sip_presence_xml_create_node(pool, resource, "name");
+	instance = ast_sip_presence_xml_create_node(pool, resource, "instance");
+
+	/* XXX Hardcoding a resource URI for the moment. */
+	ast_copy_string(uri, "johndoe at example.org", sizeof(uri));
+	ast_sip_presence_xml_create_attr(pool, resource, "uri", uri);
+
+	/* XXX This is hardcoded too! */
+	pj_strdup2(pool, &name->content, "CAT-URINE");
+
+	ast_uuid_generate_str(id, sizeof(id));
+	ast_sip_presence_xml_create_attr(pool, instance, "id", id);
+	/* XXX More hardcodedness */
+	ast_sip_presence_xml_create_attr(pool, instance, "state", "active");
+	ast_sip_presence_xml_create_attr(pool, instance, "cid", ast_strip_quoted(ast_strdupa(cid), "<", ">"));
+}
+
+static pj_xml_node *build_rlmi_body(pj_pool_t *pool, struct ast_sip_subscription *sub,
+		pjsip_msg_body *body)
+{
+	pj_xml_node *rlmi;
+	pj_xml_node *name;
+	char version_str[32];
+	char uri[PJSIP_MAX_URL_SIZE];
+	pjsip_multipart_part *part_iter;
+
+	rlmi = ast_sip_presence_xml_create_node(pool, NULL, "list");
+	ast_sip_presence_xml_create_attr(pool, rlmi, "xmlns", "urn:ietf:params:xml:ns:rlmi");
+
+	/* XXX This works for the top-level list, but any sub lists will
+	 * have an incorrect URI. Probably should come up with a scheme
+	 * like list_name at host for this URI.
 	 */
-	return 0;
-}
-
-static int generate_notify_body(struct ast_sip_subscription *root, struct ast_str **body_text)
-{
+	ast_sip_subscription_get_local_uri(sub, uri, sizeof(uri));
+	ast_sip_presence_xml_create_attr(pool, rlmi, "uri", uri);
+
+	/* XXX Hardcoding RLMI version and fullState  attributes for the moment. */
+	snprintf(version_str, sizeof(version_str), "%u", 0);
+	ast_sip_presence_xml_create_attr(pool, rlmi, "version", version_str);
+	ast_sip_presence_xml_create_attr(pool, rlmi, "fullState", "true");
+
+	name = ast_sip_presence_xml_create_node(pool, rlmi, "name");
+	pj_strdup2(pool, &name->content, ast_sip_subscription_get_resource_name(sub));
+
+	for (part_iter = pjsip_multipart_get_first_part(body);
+			part_iter;
+			part_iter = pjsip_multipart_get_next_part(body, part_iter)) {
+		/* XXX This is where we'd search for the Content-ID header on
+		 * the multipart part. However, we currently have a hard-coded
+		 * Content-ID anyway, so just use that for the moment.
+		 */
+		add_rlmi_resource(pool, rlmi, "<prawnstar at bass-turd.org>");
+	}
+	return rlmi;
+}
+
+static pjsip_msg_body *generate_list_body(pj_pool_t *pool, struct ast_sip_subscription *sub)
+{
+	int i;
+	pj_xml_node *rlmi;
+	char rlmi_str[2048];
+	pjsip_msg_body *multipart;
+	pjsip_media_type media_type = {
+		.type = { "multipart", 9 },
+		.subtype = { "related", 7 },
+	};
+	pjsip_multipart_part *rlmi_part;
+	static const pj_str_t rlmi_type = { "application", 11};
+	static const pj_str_t rlmi_subtype = {"rlmi+xml", 8};
+	pj_str_t rlmi_text;
+	
+	multipart = pjsip_multipart_create(pool, &media_type, NULL);
+
+	for (i = 0; i < AST_VECTOR_SIZE(&sub->children); ++i) {
+		/* XXX This should probably be factored into a function */
+		struct ast_sip_subscription *child = AST_VECTOR_GET(&sub->children, i);
+		pjsip_multipart_part *part = pjsip_multipart_create_part(pool);
+		pjsip_generic_string_hdr *cid;
+		pj_str_t type;
+		pj_str_t subtype;
+		pj_str_t text;
+		static const pj_str_t cid_name = { "Content-ID", 10 };
+		/* XXX Hard-coded for the moment */
+		pj_str_t cid_value = {"<prawnstar at bass-turd.org>", 25 };
+
+		pj_cstr(&type, ast_sip_subscription_get_body_type(child));
+		pj_cstr(&subtype, ast_sip_subscription_get_body_subtype(child));
+		pj_cstr(&text, ast_str_buffer(child->body_text));
+
+		/* XXX This assumes that child is not a list. If child were a list, then
+		 * we would make a recursive call to create the message body.
+		 */
+		part->body = pjsip_msg_body_create(pool, &type, &subtype, &text);
+
+		cid = pjsip_generic_string_hdr_create(pool, &cid_name, &cid_value);
+		pj_list_insert_before(&part->hdr, cid);
+
+		pjsip_multipart_add_part(pool, multipart, part);
+	}
+
+	/* Once we've built the other bodies, we can build our RLMI body! */
+	/* XXX It would be better to have the RLMI body as the first part in
+	 * the multipart body. This currently places it at the end.
+	 */
+	rlmi = build_rlmi_body(pool, sub, multipart);
+	pj_xml_print(rlmi, rlmi_str, sizeof(rlmi_str) - 1, PJ_TRUE);
+	pj_cstr(&rlmi_text, rlmi_str);
+
+	rlmi_part = pjsip_multipart_create_part(pool);
+	rlmi_part->body = pjsip_msg_body_create(pool, &rlmi_type, &rlmi_subtype, &rlmi_text);
+	pjsip_multipart_add_part(pool, multipart, rlmi_part);
+
+	return multipart;
+}
+
+static pjsip_msg_body *generate_notify_body(pj_pool_t *pool, struct ast_sip_subscription *root)
+{
+	pjsip_msg_body *body;
+
 	if (AST_VECTOR_SIZE(&root->children) == 0) {
 		/* Not a list. We've already generated the body and saved it on the subscription.
 		 * Use that directly.
 		 */
-		ast_str_copy_string(body_text, root->body_text);
+		pj_str_t type;
+		pj_str_t subtype;
+		pj_str_t text;
+
+		pj_cstr(&type, ast_sip_subscription_get_body_type(root));
+		pj_cstr(&subtype, ast_sip_subscription_get_body_subtype(root));
+		pj_cstr(&text, ast_str_buffer(root->body_text));
+
+		body = pjsip_msg_body_create(pool, &type, &subtype, &text);
 		root->body_changed = 0;
-		return 0;
-	}
-
-	return generate_list_body(root, body_text);
+	} else {
+		body = generate_list_body(pool, root);
+	}
+
+	return body;
 }
 
 static int send_notify(struct sip_subscription_tree *sub_tree)
 {
 	pjsip_evsub *evsub = sub_tree->evsub;
 	pjsip_tx_data *tdata;
-	struct ast_sip_body body = {
-		.type = ast_sip_subscription_get_body_type(sub_tree->root),
-		.subtype = ast_sip_subscription_get_body_subtype(sub_tree->root),
-	};
-	struct ast_str *body_text;
-
-	body_text = ast_str_create(64);
-	if (!body_text) {
-		return -1;
-	}
 
 	if (pjsip_evsub_notify(evsub, sub_tree->root->subscription_state,
 				NULL, NULL, &tdata) != PJ_SUCCESS) {
-		ast_free(body_text);
 		return -1;
 	}
 
-	if (generate_notify_body(sub_tree->root, &body_text)) {
-		pjsip_tx_data_dec_ref(tdata);
-		ast_free(body_text);
-		return -1;
-	}
-
-	body.body_text = ast_str_buffer(body_text);
-
-	if (ast_sip_add_body(tdata, &body)) {
-		pjsip_tx_data_dec_ref(tdata);
-		ast_free(body_text);
-		return -1;
-	}
+	tdata->msg->body = generate_notify_body(tdata->pool, sub_tree->root);
 
 	if (sip_subscription_send_request(sub_tree, tdata)) {
 		pjsip_tx_data_dec_ref(tdata);
-		ast_free(body_text);
 		return -1;
 	}
 
 	sub_tree->send_scheduled_notify = 0;
-	ast_free(body_text);
 
 	return 0;
 }
@@ -1897,10 +1997,6 @@
 	void *notify_data;
 	int res;
 
-	if (sub->handler->notifier->subscription_established(sub)) {
-		return -1;
-	}
-
 	if (AST_VECTOR_SIZE(&sub->children) > 0) {
 		int i;
 
@@ -1911,6 +2007,10 @@
 		}
 
 		return 0;
+	}
+
+	if (sub->handler->notifier->subscription_established(sub)) {
+		return -1;
 	}
 
 	notify_data = sub->handler->notifier->get_notify_data(sub);




More information about the svn-commits mailing list