[svn-commits] mmichelson: branch mmichelson/rls-subscribe r417730 - /team/mmichelson/rls-su...

SVN commits to the Digium repositories svn-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(&current->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 svn-commits mailing list