[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