[asterisk-commits] mmichelson: branch group/CCSS r223310 - /team/group/CCSS/main/ccss.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Oct 9 14:24:03 CDT 2009
Author: mmichelson
Date: Fri Oct 9 14:23:59 2009
New Revision: 223310
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=223310
Log:
Move generic agent callbacks to single area.
Modified:
team/group/CCSS/main/ccss.c
Modified: team/group/CCSS/main/ccss.c
URL: http://svnview.digium.com/svn/asterisk/team/group/CCSS/main/ccss.c?view=diff&rev=223310&r1=223309&r2=223310
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Fri Oct 9 14:23:59 2009
@@ -56,6 +56,10 @@
</application>
***/
+/* Some forward declarations, prototypes, and constants that don't
+ * really fit well anywhere else
+ */
+static struct ast_sched_thread *cc_sched_thread;
/*!
* \since 1.6.4
* \brief A structure for holding the configuration parameters
@@ -480,7 +484,6 @@
return callbacks;
}
-
#define cc_ref(obj, debug) ({ao2_t_ref((obj), +1, (debug)); (obj);})
#define cc_unref(obj, debug) ({ao2_t_ref((obj), -1, (debug)); NULL;})
@@ -508,12 +511,6 @@
.destructor = cc_generic_agent_destructor,
};
-static struct ast_cc_monitor *root_monitor;
-/* The parsed configuration value */
-static unsigned int global_cc_max_requests;
-/* The actual number of CC requests in the system */
-static int cc_request_count;
-
struct cc_generic_agent_pvt {
/*!
* Subscription to device state
@@ -530,6 +527,186 @@
int offer_timer_id;
};
+static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan)
+{
+ struct cc_generic_agent_pvt *generic_pvt = ast_calloc(1, sizeof(*generic_pvt));
+
+ if (!generic_pvt) {
+ return -1;
+ }
+
+ generic_pvt->offer_timer_id = -1;
+ agent->private_data = generic_pvt;
+ ast_set_flag(agent, AST_CC_AGENT_SKIP_OFFER);
+ return 0;
+}
+
+static int offer_timer_expire(const void *data)
+{
+ const struct ast_cc_agent *agent = data;
+ struct cc_generic_agent_pvt *agent_pvt = agent->private_data;
+ ast_log(LOG_NOTICE, "Queuing change request because offer timer has expired.\n");
+ agent_pvt->offer_timer_id = -1;
+ ast_cc_request_state_change(CC_FAILED, agent->core_id, "Generic agent offer timer expired");
+ return 0;
+}
+
+static int cc_generic_agent_start_offer_timer(struct ast_cc_agent *agent)
+{
+ int when;
+ int sched_id;
+ struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
+
+ ast_assert(cc_sched_thread != NULL);
+ ast_assert(agent->cc_params != NULL);
+
+ when = ast_get_cc_offer_timer(agent->cc_params) * 1000;
+ ast_log(LOG_NOTICE, "About to schedule timer expiration for %d ms\n", when);
+ if ((sched_id = ast_sched_thread_add(cc_sched_thread, when, offer_timer_expire, agent)) == -1) {
+ return -1;
+ }
+ generic_pvt->offer_timer_id = sched_id;
+ return 0;
+}
+
+static int cc_generic_agent_stop_offer_timer(struct ast_cc_agent *agent)
+{
+ struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
+
+ if (generic_pvt->offer_timer_id != -1) {
+ ast_sched_thread_del(cc_sched_thread, generic_pvt->offer_timer_id);
+ generic_pvt->offer_timer_id = -1;
+ }
+ return 0;
+}
+
+static void cc_generic_agent_ack(struct ast_cc_agent *agent)
+{
+ /* The generic agent doesn't have to do anything special to
+ * acknowledge a CC request. Just return.
+ */
+ return;
+}
+
+static enum ast_device_state cc_generic_agent_status_request(struct ast_cc_agent *agent)
+{
+ return ast_device_state(agent->interface);
+}
+
+static void generic_devstate_cb(const struct ast_event *event, void *userdata)
+{
+ struct ast_cc_agent *agent = userdata;
+ struct ast_str *str = ast_str_alloca(128);
+ ast_str_set(&str, 0, "%s is no longer busy\n", agent->interface);
+ ast_cc_request_state_change(CC_ACTIVE, agent->core_id, ast_str_buffer(str));
+}
+
+static int cc_generic_agent_start_monitoring(struct ast_cc_agent *agent)
+{
+ struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
+ struct ast_str *str = ast_str_alloca(128);
+
+ ast_assert(generic_pvt->sub == NULL);
+ ast_str_set(&str, 0, "Starting to monitor %s device state since it is busy\n", agent->interface);
+
+ if (!(generic_pvt->sub = ast_event_subscribe(
+ AST_EVENT_DEVICE_STATE, generic_devstate_cb, ast_str_buffer(str), agent,
+ AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, agent->interface,
+ AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, AST_DEVICE_NOT_INUSE,
+ AST_EVENT_IE_END))) {
+ return -1;
+ }
+ return 0;
+}
+
+static int cc_generic_agent_stop_monitoring(struct ast_cc_agent *agent)
+{
+ struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
+
+ ast_assert(generic_pvt->sub != NULL);
+
+ generic_pvt->sub = ast_event_unsubscribe(generic_pvt->sub);
+ return 0;
+}
+
+static void *generic_recall(void *data)
+{
+ struct ast_cc_agent *agent = data;
+ char *interface = ast_strdupa(agent->interface);
+ char *tech;
+ char *target;
+ int reason;
+ struct ast_channel *chan;
+ struct ast_cc_tree_item *tree_item = AST_LIST_FIRST(agent->interface_tree);
+ char *full_extension = ast_strdupa(tree_item->interface->name);
+ char *context;
+ char *exten;
+ const char *callback_macro = ast_get_cc_callback_macro(agent->cc_params);
+ tech = interface;
+ if ((target = strchr(interface, '/'))) {
+ *target++ = '\0';
+ }
+ if (!(chan = ast_request_and_dial(tech, AST_FORMAT_SLINEAR, NULL, target, 20000, &reason, NULL, NULL))) {
+ /* Hmm, no channel. Sucks for you, bud.
+ */
+ ast_log(LOG_NOTICE, "Failed to call back %s for reason %d\n", agent->interface, reason);
+ ast_cc_request_state_change(CC_FAILED, agent->core_id, "Failed to call back interface\n");
+ return NULL;
+ }
+ if (!ast_strlen_zero(callback_macro)) {
+ ast_log(LOG_NOTICE, "There's a callback macro configured\n");
+ if (ast_app_run_macro(NULL, chan, callback_macro, NULL)) {
+ ast_cc_request_state_change(CC_FAILED, agent->core_id, "Callback macro failed. Maybe a hangup?");
+ ast_hangup(chan);
+ return NULL;
+ }
+ }
+ /* We have a channel. It's time now to set up the datastore of recalled CC interfaces.
+ * This will be a common task for all recall functions. If it were possible, I'd have
+ * the core do it automatically, but alas I cannot. Instead, I will provide a public
+ * function to do so.
+ */
+ ast_setup_cc_recall_datastore(chan, agent);
+ ast_set_cc_interfaces_chanvar(chan, full_extension);
+ /* Now we can bust apart the outbound name so that the PBX will run. */
+ exten = full_extension;
+ if ((context = strchr(full_extension, '@'))) {
+ *context++ = '\0';
+ }
+ ast_copy_string(chan->exten, exten, sizeof(chan->exten));
+ ast_copy_string(chan->context, context, sizeof(chan->context));
+ chan->priority = 1;
+ ast_pbx_start(chan);
+ return NULL;
+}
+
+static int cc_generic_agent_recall(struct ast_cc_agent *agent)
+{
+ pthread_t clotho;
+ ast_pthread_create_detached_background(&clotho, NULL, generic_recall, agent);
+ return 0;
+}
+
+static void cc_generic_agent_destructor(struct ast_cc_agent *agent)
+{
+ struct cc_generic_agent_pvt *agent_pvt = agent->private_data;
+ if (!agent_pvt) {
+ return;
+ }
+
+ if (agent_pvt->sub) {
+ agent_pvt->sub = ast_event_unsubscribe(agent_pvt->sub);
+ }
+
+ ast_free(agent_pvt);
+}
+
+static struct ast_cc_monitor *root_monitor;
+/* The parsed configuration value */
+static unsigned int global_cc_max_requests;
+/* The actual number of CC requests in the system */
+static int cc_request_count;
+
static void prune_links(struct ast_cc_monitor *monitor, const int core_id, struct ast_cc_monitor_link *link_parent);
#if 0
@@ -542,7 +719,6 @@
#endif
struct ast_taskprocessor *cc_core_taskprocessor;
-struct ast_sched_thread *cc_sched_thread;
void ast_cc_interface_destroy(void *data)
{
@@ -1341,180 +1517,6 @@
res = ast_cc_request_state_change(CC_CALLER_OFFERED, core_id, "Offer CC to caller");
return res;
-}
-
-static int cc_generic_agent_init(struct ast_cc_agent *agent, struct ast_channel *chan)
-{
- struct cc_generic_agent_pvt *generic_pvt = ast_calloc(1, sizeof(*generic_pvt));
-
- if (!generic_pvt) {
- return -1;
- }
-
- generic_pvt->offer_timer_id = -1;
- agent->private_data = generic_pvt;
- ast_set_flag(agent, AST_CC_AGENT_SKIP_OFFER);
- return 0;
-}
-
-static int offer_timer_expire(const void *data)
-{
- const struct ast_cc_agent *agent = data;
- struct cc_generic_agent_pvt *agent_pvt = agent->private_data;
- ast_log(LOG_NOTICE, "Queuing change request because offer timer has expired.\n");
- agent_pvt->offer_timer_id = -1;
- ast_cc_request_state_change(CC_FAILED, agent->core_id, "Generic agent offer timer expired");
- return 0;
-}
-
-static int cc_generic_agent_start_offer_timer(struct ast_cc_agent *agent)
-{
- int when;
- int sched_id;
- struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
-
- ast_assert(cc_sched_thread != NULL);
- ast_assert(agent->cc_params != NULL);
-
- when = ast_get_cc_offer_timer(agent->cc_params) * 1000;
- ast_log(LOG_NOTICE, "About to schedule timer expiration for %d ms\n", when);
- if ((sched_id = ast_sched_thread_add(cc_sched_thread, when, offer_timer_expire, agent)) == -1) {
- return -1;
- }
- generic_pvt->offer_timer_id = sched_id;
- return 0;
-}
-
-static int cc_generic_agent_stop_offer_timer(struct ast_cc_agent *agent)
-{
- struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
-
- if (generic_pvt->offer_timer_id != -1) {
- ast_sched_thread_del(cc_sched_thread, generic_pvt->offer_timer_id);
- generic_pvt->offer_timer_id = -1;
- }
- return 0;
-}
-
-static void cc_generic_agent_ack(struct ast_cc_agent *agent)
-{
- /* The generic agent doesn't have to do anything special to
- * acknowledge a CC request. Just return.
- */
- return;
-}
-
-static enum ast_device_state cc_generic_agent_status_request(struct ast_cc_agent *agent)
-{
- return ast_device_state(agent->interface);
-}
-
-static void generic_devstate_cb(const struct ast_event *event, void *userdata)
-{
- struct ast_cc_agent *agent = userdata;
- struct ast_str *str = ast_str_alloca(128);
- ast_str_set(&str, 0, "%s is no longer busy\n", agent->interface);
- ast_cc_request_state_change(CC_ACTIVE, agent->core_id, ast_str_buffer(str));
-}
-
-static int cc_generic_agent_start_monitoring(struct ast_cc_agent *agent)
-{
- struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
- struct ast_str *str = ast_str_alloca(128);
-
- ast_assert(generic_pvt->sub == NULL);
- ast_str_set(&str, 0, "Starting to monitor %s device state since it is busy\n", agent->interface);
-
- if (!(generic_pvt->sub = ast_event_subscribe(
- AST_EVENT_DEVICE_STATE, generic_devstate_cb, ast_str_buffer(str), agent,
- AST_EVENT_IE_DEVICE, AST_EVENT_IE_PLTYPE_STR, agent->interface,
- AST_EVENT_IE_STATE, AST_EVENT_IE_PLTYPE_UINT, AST_DEVICE_NOT_INUSE,
- AST_EVENT_IE_END))) {
- return -1;
- }
- return 0;
-}
-
-static int cc_generic_agent_stop_monitoring(struct ast_cc_agent *agent)
-{
- struct cc_generic_agent_pvt *generic_pvt = agent->private_data;
-
- ast_assert(generic_pvt->sub != NULL);
-
- generic_pvt->sub = ast_event_unsubscribe(generic_pvt->sub);
- return 0;
-}
-
-static void *generic_recall(void *data)
-{
- struct ast_cc_agent *agent = data;
- char *interface = ast_strdupa(agent->interface);
- char *tech;
- char *target;
- int reason;
- struct ast_channel *chan;
- struct ast_cc_tree_item *tree_item = AST_LIST_FIRST(agent->interface_tree);
- char *full_extension = ast_strdupa(tree_item->interface->name);
- char *context;
- char *exten;
- const char *callback_macro = ast_get_cc_callback_macro(agent->cc_params);
- tech = interface;
- if ((target = strchr(interface, '/'))) {
- *target++ = '\0';
- }
- if (!(chan = ast_request_and_dial(tech, AST_FORMAT_SLINEAR, NULL, target, 20000, &reason, NULL, NULL))) {
- /* Hmm, no channel. Sucks for you, bud.
- */
- ast_log(LOG_NOTICE, "Failed to call back %s for reason %d\n", agent->interface, reason);
- ast_cc_request_state_change(CC_FAILED, agent->core_id, "Failed to call back interface\n");
- return NULL;
- }
- if (!ast_strlen_zero(callback_macro)) {
- ast_log(LOG_NOTICE, "There's a callback macro configured\n");
- if (ast_app_run_macro(NULL, chan, callback_macro, NULL)) {
- ast_cc_request_state_change(CC_FAILED, agent->core_id, "Callback macro failed. Maybe a hangup?");
- ast_hangup(chan);
- return NULL;
- }
- }
- /* We have a channel. It's time now to set up the datastore of recalled CC interfaces.
- * This will be a common task for all recall functions. If it were possible, I'd have
- * the core do it automatically, but alas I cannot. Instead, I will provide a public
- * function to do so.
- */
- ast_setup_cc_recall_datastore(chan, agent);
- ast_set_cc_interfaces_chanvar(chan, full_extension);
- /* Now we can bust apart the outbound name so that the PBX will run. */
- exten = full_extension;
- if ((context = strchr(full_extension, '@'))) {
- *context++ = '\0';
- }
- ast_copy_string(chan->exten, exten, sizeof(chan->exten));
- ast_copy_string(chan->context, context, sizeof(chan->context));
- chan->priority = 1;
- ast_pbx_start(chan);
- return NULL;
-}
-
-static int cc_generic_agent_recall(struct ast_cc_agent *agent)
-{
- pthread_t clotho;
- ast_pthread_create_detached_background(&clotho, NULL, generic_recall, agent);
- return 0;
-}
-
-static void cc_generic_agent_destructor(struct ast_cc_agent *agent)
-{
- struct cc_generic_agent_pvt *agent_pvt = agent->private_data;
- if (!agent_pvt) {
- return;
- }
-
- if (agent_pvt->sub) {
- agent_pvt->sub = ast_event_unsubscribe(agent_pvt->sub);
- }
-
- ast_free(agent_pvt);
}
static void monitor_destroy(void *data)
More information about the asterisk-commits
mailing list