[svn-commits] mmichelson: branch group/CCSS r213630 - in /team/group/CCSS: apps/ include/as...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Aug 21 15:22:43 CDT 2009


Author: mmichelson
Date: Fri Aug 21 15:22:39 2009
New Revision: 213630

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=213630
Log:
Commit some "progress"

I say "progress" because, well, app_dial is somewhat of a mess
right now. However, what's there compiles, so that's a start.


Modified:
    team/group/CCSS/apps/app_dial.c
    team/group/CCSS/include/asterisk/ccss.h
    team/group/CCSS/main/ccss.c

Modified: team/group/CCSS/apps/app_dial.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/CCSS/apps/app_dial.c?view=diff&rev=213630&r1=213629&r2=213630
==============================================================================
--- team/group/CCSS/apps/app_dial.c (original)
+++ team/group/CCSS/apps/app_dial.c Fri Aug 21 15:22:39 2009
@@ -1625,6 +1625,149 @@
 	return 1; /* success */
 }
 
+static int dial_cc_interface_counter;
+
+/*!
+ * \brief data stored in CC datastore
+ *
+ * The datastore creates a list of interfaces that were
+ * dialed, including both extensions and devices. In addition
+ * to the intrinsic data of the tree, some extra information
+ * is needed for use by app_dial.
+ */
+struct dial_cc_interfaces {
+	/*!
+	 * When a new Dial application is started, and the datastore
+	 * already exists on the channel, we can figure out where
+	 * in the existing interface tree to insert the new information
+	 * by using this number.
+	 */
+	unsigned int dial_parent_id;
+	/*!
+	 * When a new Dial application is started, and the datastore
+	 * already exists on the channel, we can determine if we
+	 * should be adding any new interface information to tree.
+	 */
+	char done;
+	/*!
+	 * Reference-counted "tree" of interfaces.
+	 */
+	struct ast_cc_interface_tree *interface_tree;
+};
+
+static void dial_cc_interfaces_destroy(void *data)
+{
+	struct dial_cc_interfaces *cc_interfaces = data;
+	ao2_ref(cc_interfaces->interface_tree, -1);
+	ast_free(cc_interfaces);
+}
+
+static void *dial_cc_interfaces_duplicate(void *data)
+{
+	/* STUB */
+	return NULL;
+}
+
+static const struct ast_datastore_info dial_cc_interfaces_info = {
+	.type = "Dial CC Interfaces",
+	.duplicate = dial_cc_interfaces_duplicate,
+	.destroy = dial_cc_interfaces_destroy,
+};
+
+static struct ast_cc_interface *cc_extension_interface_init(const char * const exten, const char * const context, const unsigned int parent_id)
+{
+	struct ast_str *str = ast_str_alloca(2 * AST_MAX_EXTENSION);
+	struct ast_cc_interface *cc_interface;
+
+	ast_str_set(&str, 0, "%s@%s\n", exten, context);
+
+	if (!(cc_interface = ast_calloc(1, sizeof(*cc_interface) + ast_str_strlen(str)))) {
+		return NULL;
+	}
+
+	cc_interface->id = ast_atomic_fetchadd_int(&dial_cc_interface_counter, +1);
+	cc_interface->parent_id = parent_id;
+	strcpy(cc_interface->name, ast_str_buffer(str));
+	return cc_interface;
+}
+
+static int cc_interfaces_datastore_init(struct ast_channel *chan) {
+	struct dial_cc_interfaces *interfaces;
+	struct ast_cc_interface *cc_interface;
+	struct ast_datastore *dial_cc_datastore;
+
+	if (!(interfaces = ast_calloc(1, sizeof(*interfaces)))) {
+		return -1;
+	}
+
+	if (!(cc_interface = cc_extension_interface_init(chan->exten, chan->context, 1))) {
+		ast_free(interfaces);
+		return -1;
+	}
+
+	if (!(dial_cc_datastore = ast_datastore_alloc(&dial_cc_interfaces_info, NULL))) {
+		ast_free(cc_interface);
+		ast_free(interfaces);
+		return -1;
+	}
+
+	if (!(interfaces->interface_tree = ao2_alloc(sizeof(*interfaces->interface_tree), ast_cc_interface_tree_destroy))) {
+		ast_datastore_free(dial_cc_datastore);
+		ast_free(cc_interface);
+		ast_free(interfaces);
+		return -1;
+	}
+
+	/* Finally, all that allocation is done... */
+	AST_LIST_HEAD_INIT(interfaces->interface_tree);
+	AST_LIST_INSERT_TAIL(interfaces->interface_tree, cc_interface, next);
+	dial_cc_datastore->data = interfaces;
+	ast_channel_lock(chan);
+	ast_channel_datastore_add(chan, dial_cc_datastore);
+	ast_channel_unlock(chan);
+	return 0;
+}
+
+static int create_root_cc_interface(struct ast_channel *chan)
+{
+	/* All right. So here's the deal. There are three things
+	 * that can happen here:
+	 *
+	 * 1. The channel does not have a cc_interface datastore on
+	 * it. This means that this is the first time that Dial has
+	 * been called. We need to create/initialize the datastore.
+	 *
+	 * 2. The channel does have a cc_interface datastore on it and
+	 * the "done" indicator is 0. This means that a Local channel
+	 * was called by a "parent" dial. We can check the datastore's
+	 * parent field to see who the root of this particular dial tree
+	 * is.
+	 *
+	 * 3. The channel does have a cc_interface datastore on it and
+	 * the "done" indicator is 1. This means that a second Dial call
+	 * is being made from an extension. In this case, we do not
+	 * want to make any additions/modifications to the datastore. We
+	 * will instead set a flag to indicate that CCSS is completely
+	 * disabled for this Dial attempt.
+	 */
+
+	struct ast_datastore *cc_interfaces_datastore;
+	struct dial_cc_interfaces *interfaces;
+	ast_channel_lock(chan);
+	if (!(cc_interfaces_datastore = ast_channel_datastore_find(chan, &dial_cc_interfaces_info, NULL))) {
+		/* Situation 1 has occurred */
+		return cc_interfaces_datastore_init(chan);
+	}
+
+	interfaces = cc_interfaces_datastore->data;
+	if (!interfaces->done) {
+		/* Situation 2 has occurred */
+	} else {
+		/* Situation 3 has occurred */
+	}
+	return 0;
+}
+
 static void end_bridge_callback(void *data)
 {
 	char buf[80];
@@ -1703,6 +1846,10 @@
 		return -1;
 	}
 
+	ast_log(LOG_NOTICE, "Out of curiosity, what are the channel's exten and context?\n");
+	ast_log(LOG_NOTICE, "Exten is '%s' and context is '%s'\n", chan->exten, chan->context);
+	ast_log(LOG_NOTICE, "Macroexten is '%s' and macrocontext is '%s'\n", chan->macroexten, chan->macrocontext);
+
 	parse = ast_strdupa(data);
 
 	AST_STANDARD_APP_ARGS(args, parse);
@@ -1718,6 +1865,8 @@
 		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
 		goto done;
 	}
+
+	create_root_cc_interface(chan);
 
 	if (ast_test_flag64(&opts, OPT_OPERMODE)) {
 		opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);

Modified: team/group/CCSS/include/asterisk/ccss.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/CCSS/include/asterisk/ccss.h?view=diff&rev=213630&r1=213629&r2=213630
==============================================================================
--- team/group/CCSS/include/asterisk/ccss.h (original)
+++ team/group/CCSS/include/asterisk/ccss.h Fri Aug 21 15:22:39 2009
@@ -27,7 +27,9 @@
 #include "asterisk.h"
 #include "asterisk/linkedlists.h"
 
-enum service_type {
+enum ast_cc_service_type {
+	/* No Service available/requested */
+	AST_CC_NONE,
 	/* Call Completion Busy Subscriber */
 	AST_CC_CCBS,
 	/* Call Completion No Response */
@@ -348,6 +350,10 @@
  * Of course the other problem is that if this is going to exist
  * as a datastore on the channel, then dialing local channels should
  * probably result in their increasing a reference count on the data.
+ *
+ * Actually, there really doesn't need to be a new lock for this structure.
+ * After all, since I'll be using a datastore, I'll need to lock the channel
+ * to operate on the datastore.
  */
 
 /* So the gory datastore details will be in app_dial. However, the structure
@@ -363,6 +369,60 @@
  * the list. We can guarantee that we will generally be going in a top-to-bottom
  * order.
  */
+
+/* This may be a candidate for opacity. Who the heck knows. */
+struct ast_cc_interface {
+	/* Every interface has an id associated with it. Think of
+	 * it like a "primary key"
+	 */
+	unsigned int id;
+	/* Who is this interface's parent interface? The "root" of
+	 * the tree will have 0 for this. Everyone else will have at
+	 * least 1 as their parent_id.
+	 */
+	unsigned int parent_id;
+	/* What service was offered by the endpoint. Note that
+	 * this field is completely irrelevant for ast_cc_interfaces
+	 * representing dialplan extensions.
+	 */
+	enum ast_cc_service_type service_offered;
+	AST_LIST_ENTRY(ast_cc_interface) next;
+	/* The name of the interface/extension. local channels will
+	 * have 'exten at context' for a name. Other channel types will
+	 * have 'tech/device' for a name.
+	 */
+	char name[1];
+};
+
+/*!
+ * \brief The "tree" of interfaces that is dialed.
+ *
+ * It is reference counted since several threads may need
+ * to use it, and it may last beyond the lifetime of a single
+ * thread.
+ */
+AST_LIST_HEAD(ast_cc_interface_tree, ast_cc_interface);
+
+/*!
+ * \brief Destructor function for an ast_cc_interface tree
+ *
+ * \param data The ast_cc_interface_tree whose refcount has reached 0
+ */
+void ast_cc_interface_tree_destroy(void *cc_interface_tree);
+
+/* So what APIs do we need... At least preliminarily, I'll need
+ * a debugging function so I can be sure the "tree" is built properly.
+ * Then, there will need to be a function to store the information in 
+ * the CC core once app_dial has completed. Further, there should
+ * be some core internal functions to build the monitor tree (or add
+ * to the existing monitor graph as it may be) using the given list.
+ */
+
+int ast_store_cc_interface_tree(struct ast_cc_interface_tree *cc_interface_tree);
+
+int ast_add_cc_interface_to_tree(struct ast_cc_interface_tree *cc_interface_tree, struct ast_cc_interface *cc_interface);
+
+void ast_print_cc_interface_tree(struct ast_cc_interface_tree *cc_interface_tree);
 
 /* END TREE STRUCTURES AND API FOR APP_DIAL'S USE */
 
@@ -424,7 +484,7 @@
 	/*! We need to remember which type of service to request/was requested
 	 * by this specific device monitor so we don't cause problems downstream
 	 */
-	enum service_type service_requested;
+	enum ast_cc_service_type service_requested;
 	/*! A device name, formatted in a way that is understood by ast_device_state*
 	 * functions.
 	 */

Modified: team/group/CCSS/main/ccss.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=213630&r1=213629&r2=213630
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Fri Aug 21 15:22:39 2009
@@ -352,3 +352,18 @@
 		ast_copy_string(config->cc_callback_macro, value, sizeof(config->cc_callback_macro));
 	}
 }
+
+int ast_add_cc_interface_to_tree(struct ast_cc_interface_tree *cc_interface_tree, struct ast_cc_interface *cc_interface)
+{
+	AST_LIST_INSERT_TAIL(cc_interface_tree, cc_interface, next);
+	return 0;
+}
+
+void ast_cc_interface_tree_destroy(void *data)
+{
+	struct ast_cc_interface_tree *cc_interface_tree = data;
+	struct ast_cc_interface *cc_interface;
+	while ((cc_interface = AST_LIST_REMOVE_HEAD(cc_interface_tree, next))) {
+		ast_free(cc_interface);
+	}
+}




More information about the svn-commits mailing list