[svn-commits] mmichelson: branch group/CCSS r223310 - /team/group/CCSS/main/ccss.c

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