[asterisk-commits] mmichelson: branch mmichelson/rls-subscribe r417730 - /team/mmichelson/rls-su...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jul 1 17:10:00 CDT 2014
Author: mmichelson
Date: Tue Jul 1 17:09:54 2014
New Revision: 417730
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417730
Log:
Add documentation and make some name changes.
Modified:
team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c
Modified: team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c?view=diff&rev=417730&r1=417729&r2=417730
==============================================================================
--- team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c Tue Jul 1 17:09:54 2014
@@ -277,6 +277,11 @@
};
/*!
+ * \brief A vector of strings commonly used throughout this module
+ */
+AST_VECTOR(resources, const char *);
+
+/*!
* \brief Resource list configuration item
*/
struct resource_list {
@@ -284,7 +289,7 @@
/*! SIP event package the list uses. */
char event[32];
/*! Strings representing resources in the list. */
- AST_VECTOR(, const char *) items;
+ struct resources items;
/*! Indicates if Asterisk sends full or partial state on notifications. */
unsigned int full_state;
/*! Time, in milliseconds Asterisk waits before sending a batched notification.*/
@@ -629,17 +634,26 @@
return find_body_generator(accept, num_accept_headers);
}
-static struct ast_sip_subscription *notifier_create_subscription(const struct ast_sip_subscription_handler *handler,
+static struct ast_sip_subscription *create_real_subscription(const struct ast_sip_subscription_handler *handler,
struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *resource,
struct ast_sip_pubsub_body_generator *generator);
-AST_VECTOR(resources, const char *);
-
+/*!
+ * \brief A node for a resource tree.
+ */
struct tree_node {
AST_VECTOR(, struct tree_node *) children;
char resource[0];
};
+/*!
+ * \brief Helper function for retrieving a resource list for a given event.
+ *
+ * This will retrieve a resource list that corresponds to the resource and event provided.
+ *
+ * \param resource The name of the resource list to retrieve
+ * \param event The expected event name on the resource list
+ */
static struct resource_list *retrieve_resource_list(const char *resource, const char *event)
{
struct resource_list *list;
@@ -659,6 +673,18 @@
return list;
}
+/*!
+ * \brief Allocate a tree node
+ *
+ * In addition to allocating and initializing the tree node, the node is also added
+ * to the vector of visited resources. See \ref build_resource_tree for more information
+ * on the visited resources.
+ *
+ * \param resource The name of the resource for this tree node.
+ * \param visited The vector of resources that have been visited.
+ * \retval NULL Allocation failure.
+ * \retval non-NULL The newly-allocated tree_node
+ */
static struct tree_node *tree_node_alloc(const char *resource, struct resources *visited)
{
struct tree_node *node;
@@ -677,6 +703,15 @@
return node;
}
+/*!
+ * \brief Destructor for a tree node
+ *
+ * This function calls recursively in order to destroy
+ * all nodes lower in the tree from the given node in
+ * addition to the node itself.
+ *
+ * \param node The node to destroy.
+ */
static void tree_node_destroy(struct tree_node *node)
{
int i;
@@ -691,6 +726,14 @@
ast_free(node);
}
+/*!
+ * \brief Determine if this resource has been visited already
+ *
+ * See \ref build_resource_tree for more information
+ *
+ * \param resource The resource currently being visited
+ * \param visited The resources that have previously been visited
+ */
static int have_visited(const char *resource, struct resources *visited)
{
int i;
@@ -704,7 +747,28 @@
return 0;
}
-static void recurse_list(struct ast_sip_endpoint *endpoint, const struct ast_sip_subscription_handler *handler,
+/*!
+ * \brief Build child nodes for a given parent.
+ *
+ * This iterates through the items on a resource list and creates tree nodes for each one. The
+ * tree nodes created are children of the supplied parent node. If an item in the resource
+ * list is itself a list, then this function is called recursively to provide children for
+ * the the new node.
+ *
+ * If an item in a resource list is not a list, then the supplied subscription handler is
+ * called into as if a new SUBSCRIBE for the list item were presented. The handler's response
+ * is used to determine if the node can be added to the tree or not.
+ *
+ * If a parent node ends up having no child nodes added under it, then the parent node is
+ * pruned from the tree.
+ *
+ * \param endpoint The endpoint that sent the inbound SUBSCRIBE.
+ * \param handler The subscription handler for leaf nodes in the tree.
+ * \param list The configured resource list from which the child node is being built.
+ * \param parent The parent node for these children.
+ * \param visited The resources that have already been visited.
+ */
+static void build_node_children(struct ast_sip_endpoint *endpoint, const struct ast_sip_subscription_handler *handler,
struct resource_list *list, struct tree_node *parent, struct resources *visited)
{
int i;
@@ -727,7 +791,7 @@
}
} else {
current = tree_node_alloc(resource, visited);
- recurse_list(endpoint, handler, child_list, current, visited);
+ build_node_children(endpoint, handler, child_list, current, visited);
if (AST_VECTOR_SIZE(¤t->children) > 0) {
AST_VECTOR_APPEND(&parent->children, current);
} else {
@@ -738,10 +802,35 @@
}
}
+/*!
+ * \brief A resource tree
+ *
+ * When an inbound SUBSCRIBE arrives, the resource being subscribed to may
+ * be a resource list. If this is the case, the resource list may contain resources
+ * that are themselves lists. The structure needed to hold the resources is
+ * a tree.
+ *
+ * Upon receipt of the SUBSCRIBE, the tree is built by determining if subscriptions
+ * to the individual resources in the tree would be successful or not. Any successful
+ * subscriptions result in a node in the tree being created. Any unsuccessful subscriptions
+ * result in no node being created.
+ *
+ * This tree can be seen as a bare-bones analog of the tree of ast_sip_subscriptions that
+ * will end up being created to actually carry out the duties of a SIP SUBSCRIBE dialog.
+ */
struct resource_tree {
struct tree_node *root;
};
+/*!
+ * \brief Destroy a resource tree.
+ *
+ * This function makes no assumptions about how the tree itself was
+ * allocated and does not attempt to free the tree itself. Callers
+ * of this function are responsible for freeing the tree.
+ *
+ * \param tree The tree to destroy.
+ */
static void resource_tree_destroy(struct resource_tree *tree)
{
if (tree) {
@@ -749,6 +838,24 @@
}
}
+/*!
+ * \brief Build a resource tree
+ *
+ * This function builds a resource tree based on the requested resource in a SUBSCRIBE request.
+ *
+ * This function also creates a container that has all resources that have been visited during
+ * creation of the tree, whether those resources resulted in a tree node being created or not.
+ * Keeping this container of visited resources allows for misconfigurations such as loops in
+ * the tree or duplicated resources to be detected.
+ *
+ * \param endpoint The endpoint that sent the SUBSCRIBE request.
+ * \param handler The subscription handler for leaf nodes in the tree.
+ * \param resource The resource requested in the SUBSCRIBE request.
+ * \param tree The tree that is to be built.
+ *
+ * \retval 200-299 Successfully subscribed to at least one resource.
+ * \retval 300-699 Failure to subscribe to requested resource.
+ */
static int build_resource_tree(struct ast_sip_endpoint *endpoint, const struct ast_sip_subscription_handler *handler,
const char *resource, struct resource_tree *tree)
{
@@ -763,7 +870,7 @@
AST_VECTOR_INIT(&visited, AST_VECTOR_SIZE(&list->items));
tree->root = tree_node_alloc(resource, &visited);
- recurse_list(endpoint, handler, list, tree->root, &visited);
+ build_node_children(endpoint, handler, list, tree->root, &visited);
AST_VECTOR_FREE(&visited);
ao2_cleanup(list);
@@ -878,6 +985,17 @@
return sub;
}
+/*!
+ * \brief Create a tree of virtual subscriptions based on a resource tree node.
+ *
+ * \param handler The handler to supply to leaf subscriptions.
+ * \param endpoint The endpoint that sent the SUBSCRIBE request to Asterisk.
+ * \param rdata The SUBSCRIBE request content.
+ * \param resource The requested resource in the SUBSCRIBE request.
+ * \param generator Body generator to use for leaf subscriptions.
+ * \param parent The subscription (real or virtual) that is parent to the subscriptions created here.
+ * \param parent_resource The tree node that corresponds to the parent subscription.
+ */
static void create_virtual_subscriptions(const struct ast_sip_subscription_handler *handler,
struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *resource,
struct ast_sip_pubsub_body_generator *generator, struct ast_sip_subscription *parent,
@@ -890,6 +1008,9 @@
sub = allocate_subscription(handler, endpoint, resource,
AST_SIP_NOTIFIER, SIP_SUBSCRIPTION_VIRTUAL);
+ if (!sub) {
+ continue;
+ }
/* XXX For subscriptions with children, the generator will need to be
* the multipart RLMI generator instead. This will be handled in
* ASTERISK-23869 or ASTERISK-23867
@@ -902,6 +1023,24 @@
}
}
+/*!
+ * \brief Create a subscription tree based on a resource tree.
+ *
+ * Using the previously-determined valid resources in the provided resource tree,
+ * a corresponding tree of ast_sip_subscriptions are created. The root of the
+ * subscription tree is a real subscription, and the rest in the tree are
+ * virtual subscriptions.
+ *
+ * \param handler The handler to use for leaf subscriptions
+ * \param endpoint The endpoint that sent the SUBSCRIBE request
+ * \param rdata The SUBSCRIBE content
+ * \param resource The requested resource in the SUBSCRIBE request
+ * \param generator The body generator to use in leaf subscriptions
+ * \param tree The resource tree on which the subscription tree is based
+ *
+ * \retval NULL Could not create the subscription tree
+ * \retval non-NULL The root of the created subscription tree
+ */
static struct ast_sip_subscription *create_subscription_tree(const struct ast_sip_subscription_handler *handler,
struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *resource,
struct ast_sip_pubsub_body_generator *generator, struct resource_tree *tree)
@@ -910,14 +1049,15 @@
/* Start by creating the root subscription. It's the only real subscription.
* XXX Since this is the root of a subscription tree, it should actually use the
- * multipart RLMI generator instead. This will be handled in ASTERISK-23869 or
- * ASTERISK-23867
+ * multipart RLMI generator instead if this is a list. This will be handled in
+ * ASTERISK-23869 or ASTERISK-23867
*/
- sub = notifier_create_subscription(handler, endpoint, rdata, resource, generator);
-
- /* Now we need to create virtual subscriptions */
+ sub = create_real_subscription(handler, endpoint, rdata, resource, generator);
+ if (!sub) {
+ return NULL;
+ }
+
create_virtual_subscriptions(handler, endpoint, rdata, resource, generator, sub, tree->root);
-
return sub;
}
@@ -1145,7 +1285,7 @@
pjsip_evsub_set_mod_data(sip_subscription_get_evsub(sub), pubsub_module.id, sub);
}
-static struct ast_sip_subscription *notifier_create_subscription(const struct ast_sip_subscription_handler *handler,
+static struct ast_sip_subscription *create_real_subscription(const struct ast_sip_subscription_handler *handler,
struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *resource,
struct ast_sip_pubsub_body_generator *generator)
{
More information about the asterisk-commits
mailing list