[asterisk-commits] mmichelson: branch mmichelson/rls-rlmi r418221 - /team/mmichelson/rls-rlmi/res/
SVN commits to the Asterisk project
asterisk-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(¤t->children); ++i) {
struct ast_sip_subscription *child;
-
- child = create_virtual_subscriptions(handler, resource, generator,
- tree, AST_VECTOR_GET(¤t->children, i));
+ struct tree_node *child_node = AST_VECTOR_GET(¤t->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 asterisk-commits
mailing list