[asterisk-commits] mmichelson: branch mmichelson/rls-rlmi r418254 - /team/mmichelson/rls-rlmi/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jul 9 14:52:58 CDT 2014
Author: mmichelson
Date: Wed Jul 9 14:52:53 2014
New Revision: 418254
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=418254
Log:
Implement partial state notification for RLS.
Now if a subset of resources in a resource list changes
states, only those updated resources will be communicated
in NOTIFYs. Forced full state NOTIFYs are still working
properly.
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=418254&r1=418253&r2=418254
==============================================================================
--- team/mmichelson/rls-rlmi/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/rls-rlmi/res/res_pjsip_pubsub.c Wed Jul 9 14:52:53 2014
@@ -412,6 +412,8 @@
pjsip_evsub_state subscription_state;
/*! For lists, the current version to place in the RLMI body */
unsigned int version;
+ /*! For lists, indicates if full state should always be communicated. */
+ unsigned int full_state;
/*! Name of resource being subscribed to */
char resource[0];
};
@@ -1466,10 +1468,18 @@
ast_sip_presence_xml_create_attr(pool, instance, "cid", ast_strip_quoted(ast_strdupa(cid), "<", ">"));
}
-AST_VECTOR(cid_list, const char *);
+struct body_part {
+ const char *cid;
+ const char *resource;
+ const char *uri;
+ pjsip_evsub_state state;
+ pjsip_multipart_part *part;
+};
+
+AST_VECTOR(body_part_list, struct body_part *);
static pj_xml_node *build_rlmi_body(pj_pool_t *pool, struct ast_sip_subscription *sub,
- struct cid_list *cids)
+ struct body_part_list *body_parts, int full_state)
{
pj_xml_node *rlmi;
pj_xml_node *name;
@@ -1487,38 +1497,63 @@
ast_sip_subscription_get_local_uri(sub, uri, sizeof(uri));
ast_sip_presence_xml_create_attr(pool, rlmi, "uri", uri);
- /* XXX Hardcoding RLMI fullState attribute for the moment. */
snprintf(version_str, sizeof(version_str), "%u", sub->version++);
ast_sip_presence_xml_create_attr(pool, rlmi, "version", version_str);
- ast_sip_presence_xml_create_attr(pool, rlmi, "fullState", "true");
+ ast_sip_presence_xml_create_attr(pool, rlmi, "fullState", full_state ? "true" : "false");
name = ast_sip_presence_xml_create_node(pool, rlmi, "name");
pj_strdup2(pool, &name->content, ast_sip_subscription_get_resource_name(sub));
- for (i = 0; i < AST_VECTOR_SIZE(cids); ++i) {
- /* XXX Using a hardcoded URI for the moment */
- add_rlmi_resource(pool, rlmi, AST_VECTOR_GET(cids, i),
- AST_VECTOR_GET(&sub->children, i)->resource, "sip:johndoe at example.org",
- AST_VECTOR_GET(&sub->children, i)->subscription_state);
+ for (i = 0; i < AST_VECTOR_SIZE(body_parts); ++i) {
+ const struct body_part *part = AST_VECTOR_GET(body_parts, i);
+
+ add_rlmi_resource(pool, rlmi, part->cid, part->resource, part->uri, part->state);
}
return rlmi;
}
-static pjsip_msg_body *generate_notify_body(pj_pool_t *pool, struct ast_sip_subscription *root);
-
-static void free_cids(struct cid_list *cids)
+static pjsip_msg_body *generate_notify_body(pj_pool_t *pool, struct ast_sip_subscription *root,
+ int force_full_state);
+
+static void free_body_parts(struct body_part_list *parts)
{
int i;
- for (i = 0; i < AST_VECTOR_SIZE(cids); ++i) {
- ast_free((char *) AST_VECTOR_GET(cids, i));
- }
-
- AST_VECTOR_FREE(cids);
-}
-
-static pjsip_msg_body *generate_list_body(pj_pool_t *pool, struct ast_sip_subscription *sub)
+ for (i = 0; i < AST_VECTOR_SIZE(parts); ++i) {
+ struct body_part *part = AST_VECTOR_GET(parts, i);
+ ast_free((char *) part->cid);
+ ast_free(part);
+ }
+
+ AST_VECTOR_FREE(parts);
+}
+
+static struct body_part *allocate_body_part(const struct ast_sip_subscription *sub)
+{
+ struct body_part *bp;
+
+ bp = ast_calloc(1, sizeof(*bp));
+ if (!bp) {
+ return NULL;
+ }
+
+ bp->cid = ast_strdup("<prawnstar at bass-turd.org>");
+ if (!bp->cid) {
+ ast_free(bp);
+ return NULL;
+ }
+
+ bp->resource = sub->resource;
+ bp->state = sub->subscription_state;
+ /* XXX This is hardcoded */
+ bp->uri = "sip:johndoe at example.org";
+
+ return bp;
+}
+
+static pjsip_msg_body *generate_list_body(pj_pool_t *pool, struct ast_sip_subscription *sub,
+ int force_full_state)
{
int i;
pj_xml_node *rlmi;
@@ -1532,21 +1567,39 @@
static const pj_str_t rlmi_type = { "application", 11};
static const pj_str_t rlmi_subtype = {"rlmi+xml", 8};
pj_str_t rlmi_text;
- struct cid_list cids;
-
- AST_VECTOR_INIT(&cids, AST_VECTOR_SIZE(&sub->children));
+ struct body_part_list body_parts;
+ int use_full_state = force_full_state ? 1 : sub->full_state;
+
+ AST_VECTOR_INIT(&body_parts, AST_VECTOR_SIZE(&sub->children));
multipart = pjsip_multipart_create(pool, &media_type, NULL);
- /* Start by generating content IDs for children.
- * Do this by creating a parallel vector to the vector of child subscriptions.
- */
for (i = 0; i < AST_VECTOR_SIZE(&sub->children); ++i) {
- /* XXX Using a hard-coded value for the moment */
- AST_VECTOR_APPEND(&cids, ast_strdup("<prawnstar at bass-turd.org>"));
+ /* XXX This should probably be factored into a function */
+ struct ast_sip_subscription *child = AST_VECTOR_GET(&sub->children, i);
+ struct body_part *bp = allocate_body_part(child);
+ pjsip_generic_string_hdr *cid;
+ static const pj_str_t cid_name = { "Content-ID", 10 };
+ pjsip_msg_body *body;
+ pj_str_t cid_value;
+
+ body = generate_notify_body(pool, child, use_full_state);
+ if (!body) {
+ /* Partial state was requested and the resource has not changed state */
+ continue;
+ }
+
+ bp->part = pjsip_multipart_create_part(pool);
+ bp->part->body = body;
+
+ pj_cstr(&cid_value, bp->cid);
+ cid = pjsip_generic_string_hdr_create(pool, &cid_name, &cid_value);
+ pj_list_insert_before(&bp->part->hdr, cid);
+
+ AST_VECTOR_APPEND(&body_parts, bp);
}
- rlmi = build_rlmi_body(pool, sub, &cids);
+ rlmi = build_rlmi_body(pool, sub, &body_parts, use_full_state);
pj_xml_print(rlmi, rlmi_str, sizeof(rlmi_str) - 1, PJ_TRUE);
pj_cstr(&rlmi_text, rlmi_str);
@@ -1554,53 +1607,45 @@
rlmi_part->body = pjsip_msg_body_create(pool, &rlmi_type, &rlmi_subtype, &rlmi_text);
pjsip_multipart_add_part(pool, multipart, rlmi_part);
- 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;
- static const pj_str_t cid_name = { "Content-ID", 10 };
- pj_str_t cid_value;
-
- part->body = generate_notify_body(pool, child);
-
- pj_cstr(&cid_value, AST_VECTOR_GET(&cids, i));
- 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);
- }
-
- free_cids(&cids);
+ for (i = 0; i < AST_VECTOR_SIZE(&body_parts); ++i) {
+ pjsip_multipart_add_part(pool, multipart, AST_VECTOR_GET(&body_parts, i)->part);
+ }
+
+ free_body_parts(&body_parts);
return multipart;
}
-static pjsip_msg_body *generate_notify_body(pj_pool_t *pool, struct ast_sip_subscription *root)
+static pjsip_msg_body *generate_notify_body(pj_pool_t *pool, struct ast_sip_subscription *root,
+ int force_full_state)
{
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.
- */
- 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;
+ if (force_full_state || root->body_changed) {
+ /* Not a list. We've already generated the body and saved it on the subscription.
+ * Use that directly.
+ */
+ 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;
+ } else {
+ body = NULL;
+ }
} else {
- body = generate_list_body(pool, root);
+ body = generate_list_body(pool, root, force_full_state);
}
return body;
}
-static int send_notify(struct sip_subscription_tree *sub_tree)
+static int send_notify(struct sip_subscription_tree *sub_tree, int force_full_state)
{
pjsip_evsub *evsub = sub_tree->evsub;
pjsip_tx_data *tdata;
@@ -1610,7 +1655,7 @@
return -1;
}
- tdata->msg->body = generate_notify_body(tdata->pool, sub_tree->root);
+ tdata->msg->body = generate_notify_body(tdata->pool, sub_tree->root, force_full_state);
if (sip_subscription_send_request(sub_tree, tdata)) {
pjsip_tx_data_dec_ref(tdata);
@@ -1635,7 +1680,7 @@
return 0;
}
- send_notify(sub_tree);
+ send_notify(sub_tree, 0);
ao2_cleanup(sub_tree);
return 0;
}
@@ -1681,7 +1726,7 @@
if (sub->tree->notification_batch_interval) {
return schedule_notification(sub->tree);
} else {
- return send_notify(sub->tree);
+ return send_notify(sub->tree, 0);
}
}
@@ -2122,7 +2167,7 @@
if (generate_initial_notify(sub_tree->root)) {
pjsip_evsub_terminate(sub_tree->evsub, PJ_TRUE);
}
- send_notify(sub_tree);
+ send_notify(sub_tree, 1);
}
resource_tree_destroy(&tree);
@@ -2620,7 +2665,7 @@
set_state_terminated(sub_tree->root);
}
- if (send_notify(sub_tree)) {
+ if (send_notify(sub_tree, 1)) {
*p_st_code = 500;
}
@@ -2670,7 +2715,7 @@
struct sip_subscription_tree *sub_tree = userdata;
set_state_terminated(sub_tree->root);
- send_notify(sub_tree);
+ send_notify(sub_tree, 1);
ao2_cleanup(sub_tree);
return 0;
More information about the asterisk-commits
mailing list