[asterisk-commits] mmichelson: branch group/CCSS r226224 - /team/group/CCSS/main/ccss.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Oct 27 16:50:28 CDT 2009
Author: mmichelson
Date: Tue Oct 27 16:50:24 2009
New Revision: 226224
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=226224
Log:
Clean up the state change function.
This moves each state operation to its own function so that
it the state change function itself will not grow to an
unmanageable size.
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=226224&r1=226223&r2=226224
==============================================================================
--- team/group/CCSS/main/ccss.c (original)
+++ team/group/CCSS/main/ccss.c Tue Oct 27 16:50:24 2009
@@ -2376,12 +2376,155 @@
return is_valid;
}
+static int cc_available(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
+{
+ /* This should never happen... */
+ ast_log(LOG_WARNING, "Someone requested to change to CC_AVAILABLE? Ignoring.\n");
+ return -1;
+}
+
+static int cc_caller_offered(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
+{
+ if (core_instance->agent->callbacks->start_offer_timer(core_instance->agent)) {
+ ast_cc_failed(core_instance->core_id, "Failed to start the offer timer\n");
+ return -1;
+ }
+ manager_event(EVENT_FLAG_CC, "CCOfferTimerStart",
+ "CoreID: %d\r\n"
+ "Caller: %s\r\n"
+ "Expires: %u\r\n",
+ core_instance->core_id, core_instance->agent->interface, core_instance->agent->cc_params->cc_offer_timer);
+ ast_log_dynamic_level(cc_logger_level, "Started the offer timer for the agent!\n");
+ return 0;
+}
+
+static int cc_caller_requested(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
+{
+ if (!ast_cc_request_within_limits()) {
+ ast_log(LOG_WARNING, "Cannot request CC since there is no more room for requests\n");
+ ast_cc_failed(core_instance->core_id, "Too many requests in the system");
+ return -1;
+ }
+ core_instance->agent->callbacks->stop_offer_timer(core_instance->agent);
+ cc_monitor_tree_init(args->core_id);
+ /* It doesn't matter what service we state for the root monitor, so we just use AST_CC_NONE */
+ core_instance->monitor->callbacks->request_cc(core_instance->monitor, core_instance->core_id, NULL);
+ manager_event(EVENT_FLAG_CC, "CCRequested",
+ "CoreID: %d\r\n"
+ "Caller: %s\r\n",
+ core_instance->core_id, core_instance->agent->interface);
+ return 0;
+}
+
+static int cc_active(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
+{
+ /* Either
+ * 1. Callee accepted CC request, call agent's ack callback.
+ * 2. Caller became available, call agent's stop_monitoring callback and
+ * call monitor's unsuspend callback.
+ */
+ if (previous_state == CC_CALLER_REQUESTED) {
+ core_instance->agent->callbacks->ack(core_instance->agent);
+ manager_event(EVENT_FLAG_CC, "CCRequestAcknowledged",
+ "CoreID: %d\r\n", core_instance->core_id);
+ } else if (previous_state == CC_CALLER_BUSY) {
+ core_instance->agent->callbacks->stop_monitoring(core_instance->agent);
+ manager_event(EVENT_FLAG_CC, "CCCallerStopMonitoring",
+ "CoreID: %d\r\n"
+ "Caller: %s\r\n",
+ core_instance->core_id, core_instance->agent->interface);
+ core_instance->monitor->callbacks->unsuspend(core_instance->monitor, core_instance->core_id);
+ }
+ /* Not possible for previous_state to be anything else due to the is_state_change_valid check at the beginning */
+ return 0;
+}
+
+static int cc_callee_ready(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
+{
+ if (core_instance->agent->callbacks->status_request(core_instance->agent) == AST_DEVICE_NOT_INUSE) {
+ ast_log_dynamic_level(cc_logger_level, "Both parties are ready. Attempting recall\n");
+ cc_request_state_change(CC_RECALLING, core_instance->core_id, "Both parties are available\n");
+ } else {
+ ast_log_dynamic_level(cc_logger_level, "Caller %s has become busy, begin monitoring\n", core_instance->agent->interface);
+ cc_request_state_change(CC_CALLER_BUSY, core_instance->core_id, "Caller is busy\n");
+ }
+ return 0;
+}
+
+static int cc_caller_busy(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
+{
+ /* Callee was available, but caller was busy, call agent's begin_monitoring callback
+ * and call monitor's suspend callback.
+ */
+ core_instance->monitor->callbacks->suspend(core_instance->monitor, core_instance->core_id);
+ core_instance->agent->callbacks->start_monitoring(core_instance->agent);
+ manager_event(EVENT_FLAG_CC, "CCCallerStartMonitoring",
+ "CoreID: %d\r\n"
+ "Caller: %s\r\n",
+ core_instance->core_id, core_instance->agent->interface);
+ return 0;
+}
+
+static int cc_recalling(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
+{
+ /* Both caller and callee are available, call agent's recall callback
+ */
+ core_instance->monitor->callbacks->cancel_available_timer(core_instance->monitor, core_instance->core_id, NULL);
+ core_instance->agent->callbacks->recall(core_instance->agent);
+ manager_event(EVENT_FLAG_CC, "CCCallerRecalling",
+ "CoreID: %d\r\n"
+ "Caller: %s\r\n",
+ core_instance->core_id, core_instance->agent->interface);
+ return 0;
+}
+
+static int cc_complete(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
+{
+ /* Recall has made progress, call agent and monitor destructor functions
+ */
+ manager_event(EVENT_FLAG_CC, "CCRecallComplete",
+ "CoreID: %d\r\n"
+ "Caller: %s\r\n",
+ core_instance->core_id, core_instance->agent->interface);
+ ao2_t_unlink(cc_core_instances, core_instance, "Unlink core instance since CC recall has completed");
+ return 0;
+}
+
+static int cc_failed(struct cc_core_instance *core_instance, struct cc_state_change_args *args, enum cc_state previous_state)
+{
+ /* Something along the way failed, call agent and monitor destructor functions
+ */
+ manager_event(EVENT_FLAG_CC, "CCFailure",
+ "CoreID: %d\r\n"
+ "Caller: %s\r\n"
+ "Reason: %s\r\n",
+ core_instance->core_id, core_instance->agent->interface, args->debug);
+ ao2_t_unlink(cc_core_instances, core_instance, "Unlink core instance since CC failed");
+ return 0;
+}
+
+static struct cc_function_table {
+ enum cc_state state;
+ int (*func)(struct cc_core_instance *, struct cc_state_change_args *, enum cc_state previous_state);
+} state_change_funcs[] = {
+ {CC_AVAILABLE, cc_available},
+ {CC_CALLER_OFFERED, cc_caller_offered},
+ {CC_CALLER_REQUESTED, cc_caller_requested},
+ {CC_ACTIVE, cc_active},
+ {CC_CALLEE_READY, cc_callee_ready},
+ {CC_CALLER_BUSY, cc_caller_busy},
+ {CC_RECALLING, cc_recalling},
+ {CC_COMPLETE, cc_complete},
+ {CC_FAILED, cc_failed},
+};
+
static int cc_do_state_change(void *datap)
{
struct cc_state_change_args *args = datap;
struct cc_core_instance *core_instance;
struct cc_core_instance finder = { .core_id = args->core_id };
enum cc_state previous_state;
+ int res;
ast_log_dynamic_level(cc_logger_level, "State change to %d requested. Reason: %s\n", args->state, args->debug);
@@ -2400,117 +2543,11 @@
return -1;
}
- switch (args->state) {
- case CC_AVAILABLE:
- /* This should never happen... */
- ast_log(LOG_WARNING, "Someone requested to change to CC_AVAILABLE? Ignoring.\n");
- break;
- case CC_CALLER_OFFERED:
- if (core_instance->agent->callbacks->start_offer_timer(core_instance->agent)) {
- ast_cc_failed(core_instance->core_id, "Failed to start the offer timer\n");
- break;
- }
- manager_event(EVENT_FLAG_CC, "CCOfferTimerStart",
- "CoreID: %d\r\n"
- "Caller: %s\r\n"
- "Expires: %u\r\n",
- core_instance->core_id, core_instance->agent->interface, core_instance->agent->cc_params->cc_offer_timer);
- ast_log_dynamic_level(cc_logger_level, "Started the offer timer for the agent!\n");
- break;
- case CC_CALLER_REQUESTED:
- if (!ast_cc_request_within_limits()) {
- ast_log(LOG_WARNING, "Cannot request CC since there is no more room for requests\n");
- ast_cc_failed(core_instance->core_id, "Too many requests in the system");
- break;
- }
- core_instance->agent->callbacks->stop_offer_timer(core_instance->agent);
- cc_monitor_tree_init(args->core_id);
- /* It doesn't matter what service we state for the root monitor, so we just use AST_CC_NONE */
- core_instance->monitor->callbacks->request_cc(core_instance->monitor, core_instance->core_id, NULL);
- manager_event(EVENT_FLAG_CC, "CCRequested",
- "CoreID: %d\r\n"
- "Caller: %s\r\n",
- core_instance->core_id, core_instance->agent->interface);
- break;
- case CC_ACTIVE:
- /* Either
- * 1. Callee accepted CC request, call agent's ack callback.
- * 2. Caller became available, call agent's stop_monitoring callback and
- * call monitor's unsuspend callback.
- */
- if (previous_state == CC_CALLER_REQUESTED) {
- core_instance->agent->callbacks->ack(core_instance->agent);
- manager_event(EVENT_FLAG_CC, "CCRequestAcknowledged",
- "CoreID: %d\r\n", core_instance->core_id);
- } else if (previous_state == CC_CALLER_BUSY) {
- core_instance->agent->callbacks->stop_monitoring(core_instance->agent);
- manager_event(EVENT_FLAG_CC, "CCCallerStopMonitoring",
- "CoreID: %d\r\n"
- "Caller: %s\r\n",
- core_instance->core_id, core_instance->agent->interface);
- core_instance->monitor->callbacks->unsuspend(core_instance->monitor, core_instance->core_id);
- }
- /* Not possible for previous_state to be anything else due to the is_state_change_valid check at the beginning */
- break;
- case CC_CALLEE_READY:
- /* Callee has become available, call agent's status request callback
- */
- if (core_instance->agent->callbacks->status_request(core_instance->agent) == AST_DEVICE_NOT_INUSE) {
- ast_log_dynamic_level(cc_logger_level, "Both parties are ready. Attempting recall\n");
- cc_request_state_change(CC_RECALLING, core_instance->core_id, "Both parties are available\n");
- } else {
- ast_log_dynamic_level(cc_logger_level, "Caller %s has become busy, begin monitoring\n", core_instance->agent->interface);
- cc_request_state_change(CC_CALLER_BUSY, core_instance->core_id, "Caller is busy\n");
- }
- break;
- case CC_CALLER_BUSY:
- /* Callee was available, but caller was busy, call agent's begin_monitoring callback
- * and call monitor's suspend callback.
- */
- core_instance->monitor->callbacks->suspend(core_instance->monitor, core_instance->core_id);
- core_instance->agent->callbacks->start_monitoring(core_instance->agent);
- manager_event(EVENT_FLAG_CC, "CCCallerStartMonitoring",
- "CoreID: %d\r\n"
- "Caller: %s\r\n",
- core_instance->core_id, core_instance->agent->interface);
- break;
- case CC_RECALLING:
- /* Both caller and callee are available, call agent's recall callback
- */
- core_instance->monitor->callbacks->cancel_available_timer(core_instance->monitor, core_instance->core_id, NULL);
- core_instance->agent->callbacks->recall(core_instance->agent);
- manager_event(EVENT_FLAG_CC, "CCCallerRecalling",
- "CoreID: %d\r\n"
- "Caller: %s\r\n",
- core_instance->core_id, core_instance->agent->interface);
- break;
- case CC_COMPLETE:
- /* Recall has made progress, call agent and monitor destructor functions
- */
- manager_event(EVENT_FLAG_CC, "CCRecallComplete",
- "CoreID: %d\r\n"
- "Caller: %s\r\n",
- core_instance->core_id, core_instance->agent->interface);
- ao2_t_unlink(cc_core_instances, core_instance, "Unlink core instance since CC recall has completed");
- break;
- case CC_FAILED:
- /* Something along the way failed, call agent and monitor destructor functions
- */
- manager_event(EVENT_FLAG_CC, "CCFailure",
- "CoreID: %d\r\n"
- "Caller: %s\r\n"
- "Reason: %s\r\n",
- core_instance->core_id, core_instance->agent->interface, args->debug);
- ao2_t_unlink(cc_core_instances, core_instance, "Unlink core instance since CC failed");
- break;
- default:
- ast_log(LOG_WARNING, "Asked to change to non-existent state %d. Ignoring\n", args->state);
- break;
- }
+ res = state_change_funcs[core_instance->current_state].func(core_instance, args, previous_state);
ast_free(args);
cc_unref(core_instance, "Unref since state change has completed"); /* From ao2_find */
- return 0;
+ return res;
}
int cc_request_state_change(enum cc_state state, const int core_id,
More information about the asterisk-commits
mailing list