[asterisk-commits] mmichelson: branch group/CCSS_Monitor_Restructure r241621 - /team/group/CCSS_...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 20 13:21:59 CST 2010


Author: mmichelson
Date: Wed Jan 20 13:21:57 2010
New Revision: 241621

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=241621
Log:
Get the request_cc implementation in place for generic monitors.


Modified:
    team/group/CCSS_Monitor_Restructure/main/ccss.c

Modified: team/group/CCSS_Monitor_Restructure/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS_Monitor_Restructure/main/ccss.c?view=diff&rev=241621&r1=241620&r2=241621
==============================================================================
--- team/group/CCSS_Monitor_Restructure/main/ccss.c (original)
+++ team/group/CCSS_Monitor_Restructure/main/ccss.c Wed Jan 20 13:21:57 2010
@@ -871,6 +871,54 @@
 	}
 }
 
+/*!
+ * \internal
+ * \brief An item in a CC interface tree.
+ *
+ * These are the individual items in an interface tree.
+ * The key difference between this structure and the ast_cc_interface
+ * is that this structure contains data which is intrinsic to the item's
+ * placement in the tree, such as who its parent is.
+ */
+struct cc_monitor {
+	/* Information regarding the interface.
+	 */
+	struct ast_cc_interface *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 cc_monitors
+	 * representing dialplan extensions.
+	 */
+	enum ast_cc_service_type service_offered;
+	/*!
+	 * Name that should be used to recall specified interface
+	 *
+	 * When issuing a CC recall, some technologies will require
+	 * that a name other than the device name is dialed. For instance,
+	 * with SIP, a specific URI will be used which chan_sip will be able
+	 * to recognize as being a CC recall. Similarly, ISDN will need a specific
+	 * dial string to know that the call is a recall.
+	 */
+	char *dialable_name;
+	/*!
+	 * The ID of the available timer used by the current monitor
+	 */
+	int available_timer_id;
+	/*!
+	 * Monitor callbacks
+	 */
+	const struct ast_cc_monitor_callbacks *callbacks;
+	AST_DLLIST_ENTRY(cc_monitor) next;
+};
+
 static int cc_butt_extension_monitor_init(struct ast_cc_monitor *monitor, const int core_id);
 static int cc_extension_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link);
 static int cc_extension_monitor_suspend(struct ast_cc_monitor *monitor, const int core_id);
@@ -1008,6 +1056,7 @@
 
 static int cc_generic_monitor_init(struct ast_cc_monitor *monitor, const int core_id);
 static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link);
+static int cc_generic_monitor_request_cc2(struct cc_monitor *monitor, int *available_timer_id);
 static int cc_generic_monitor_suspend(struct ast_cc_monitor *monitor, const int core_id);
 static int cc_generic_monitor_status_response(struct ast_cc_monitor *monitor, const int core_id, enum ast_device_state devstate);
 static int cc_generic_monitor_unsuspend(struct ast_cc_monitor *monitor, const int core_id);
@@ -1019,6 +1068,7 @@
 	.type = "generic",
 	.init = cc_generic_monitor_init,
 	.request_cc = cc_generic_monitor_request_cc,
+	.request_cc2 = cc_generic_monitor_request_cc2,
 	.suspend = cc_generic_monitor_suspend,
 	.status_response = cc_generic_monitor_status_response,
 	.unsuspend = cc_generic_monitor_unsuspend,
@@ -1031,7 +1081,7 @@
 
 struct generic_monitor_instance {
 	struct cc_monitor *monitor;
-	AST_LIST_ENTRY(next);
+	AST_LIST_ENTRY(generic_monitor_instance) next;
 };
 
 struct generic_monitor_instance_list {
@@ -1078,6 +1128,55 @@
 	return !strcmp(generic_list1->device_name, generic_list2->device_name) ? CMP_MATCH | CMP_STOP : 0;
 }
 
+static struct generic_monitor_instance_list *find_generic_monitor_instance_list(const char * const device_name)
+{
+	struct generic_monitor_instance_list finder = {.device_name = device_name};
+
+	return ao2_find(generic_monitors, &finder, OBJ_POINTER);
+}
+
+static void generic_monitor_instance_list_destructor(void *obj)
+{
+	struct generic_monitor_instance_list *generic_list = obj;
+	struct generic_monitor_instance *generic_instance;
+
+	while ((generic_instance = AST_LIST_REMOVE_HEAD(&generic_list->list, next))) {
+		/* Really, this shouldn't be necessary, since we'll only be calling
+		 * the destructor on the list when it is empty. Of course, it never hurts
+		 * to be safe.
+		 */
+		cc_unref(generic_instance->monitor, "Generic monitor instance list destructor");
+		ast_free(generic_instance);
+	}
+	ast_free((char *)generic_list->device_name);
+	generic_list->sub = ast_event_unsubscribe(generic_list->sub);
+}
+
+static void generic_monitor_devstate_cb(const struct ast_event *event, void *userdata);
+static struct generic_monitor_instance_list *create_new_generic_list(struct cc_monitor *monitor)
+{
+	struct generic_monitor_instance_list *generic_list = ao2_alloc(sizeof(*generic_list), generic_monitor_instance_list_destructor);
+
+	if (!generic_list) {
+		return NULL;
+	}
+
+	if (!(generic_list->device_name = ast_strdup(monitor->interface->name))) {
+		cc_unref(generic_list, "Failed to strdup the monitor's device name");
+		return NULL;
+	}
+
+	if (!(generic_list->sub = ast_event_subscribe(AST_EVENT_DEVICE_STATE, generic_monitor_devstate_cb,
+				"Requesting CC", monitor, AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, 
+				monitor->interface->name, AST_EVENT_IE_END))) {
+		cc_unref(generic_list, "Failed to subscribe to device state");
+		return NULL;
+	}
+	generic_list->current_state = ast_device_state(monitor->interface->name);
+	ao2_link(generic_monitors, generic_list);
+	return generic_list;
+}
+
 static int cc_generic_monitor_init(struct ast_cc_monitor *monitor, const int core_id)
 {
 	struct generic_monitor_pvt *gen_mon_pvt = ast_calloc(1, sizeof(*gen_mon_pvt));
@@ -1148,6 +1247,27 @@
 	return ast_cc_monitor_failed(link->core_id, link->child->interface->name, link->child->interface->monitor_type);
 }
 
+static int cc_generic_monitor_request_cc2(struct cc_monitor *monitor, int *available_timer_id)
+{
+	struct generic_monitor_instance_list *generic_list;
+	struct generic_monitor_instance *generic_instance;
+
+	if (!(generic_list = find_generic_monitor_instance_list(monitor->interface->name))) {
+		if (!(generic_list = create_new_generic_list(monitor))) {
+			return -1;
+		}
+	}
+
+	if (!(generic_instance = ast_calloc(1, sizeof(*generic_instance)))) {
+		/* The generic monitor destructor will take care of the appropriate
+		 * deallocations
+		 */
+		cc_unref(generic_list, "Generic monitor instance failed to allocate");
+		return -1;
+	}
+	cc_unref(generic_list, "Finished with monitor instance reference in request cc callback");
+	return 0;
+}
 
 static int cc_generic_monitor_request_cc(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *parent_link)
 {
@@ -1260,54 +1380,6 @@
 {
 	/* Move along.  Move along.  Nothing to do here. */
 }
-
-/*!
- * \internal
- * \brief An item in a CC interface tree.
- *
- * These are the individual items in an interface tree.
- * The key difference between this structure and the ast_cc_interface
- * is that this structure contains data which is intrinsic to the item's
- * placement in the tree, such as who its parent is.
- */
-struct cc_monitor {
-	/* Information regarding the interface.
-	 */
-	struct ast_cc_interface *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 cc_monitors
-	 * representing dialplan extensions.
-	 */
-	enum ast_cc_service_type service_offered;
-	/*!
-	 * Name that should be used to recall specified interface
-	 *
-	 * When issuing a CC recall, some technologies will require
-	 * that a name other than the device name is dialed. For instance,
-	 * with SIP, a specific URI will be used which chan_sip will be able
-	 * to recognize as being a CC recall. Similarly, ISDN will need a specific
-	 * dial string to know that the call is a recall.
-	 */
-	char *dialable_name;
-	/*!
-	 * The ID of the available timer used by the current monitor
-	 */
-	int available_timer_id;
-	/*!
-	 * Monitor callbacks
-	 */
-	const struct ast_cc_monitor_callbacks *callbacks;
-	AST_DLLIST_ENTRY(cc_monitor) next;
-};
 
 /*!
  * \brief The "tree" of interfaces that is dialed.




More information about the asterisk-commits mailing list