mod_callcenter: Generate per member uuid different from the member session uuid. Might fix transfer between queue. More changes are commings

This commit is contained in:
Marc Olivier Chouinard 2011-03-31 05:17:04 -04:00
parent b986e13a58
commit b63a72f8b3
1 changed files with 135 additions and 73 deletions

View File

@ -177,6 +177,7 @@ static char members_sql[] =
" queue VARCHAR(255),\n" " queue VARCHAR(255),\n"
" system VARCHAR(255),\n" " system VARCHAR(255),\n"
" uuid VARCHAR(255) NOT NULL DEFAULT '',\n" " uuid VARCHAR(255) NOT NULL DEFAULT '',\n"
" session_uuid VARCHAR(255) NOT NULL DEFAULT '',\n"
" caller_number VARCHAR(255),\n" " caller_number VARCHAR(255),\n"
" caller_name VARCHAR(255),\n" " caller_name VARCHAR(255),\n"
" system_epoch INTEGER NOT NULL DEFAULT 0,\n" " system_epoch INTEGER NOT NULL DEFAULT 0,\n"
@ -704,7 +705,7 @@ static cc_queue_t *load_queue(const char *queue_name)
goto end; goto end;
} }
switch_cache_db_test_reactive(dbh, "select count(rejoined_epoch) from members", "drop table members", members_sql); switch_cache_db_test_reactive(dbh, "select count(session_uuid) from members", "drop table members", members_sql);
switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", NULL, "alter table agents add ready_time integer not null default 0;" switch_cache_db_test_reactive(dbh, "select count(ready_time) from agents", NULL, "alter table agents add ready_time integer not null default 0;"
"alter table agents add reject_delay_time integer not null default 0;" "alter table agents add reject_delay_time integer not null default 0;"
"alter table agents add busy_delay_time integer not null default 0;"); "alter table agents add busy_delay_time integer not null default 0;");
@ -718,7 +719,7 @@ static cc_queue_t *load_queue(const char *queue_name)
/* Reset a unclean shutdown */ /* Reset a unclean shutdown */
sql = switch_mprintf("UPDATE agents SET state = 'Waiting', uuid = '' WHERE system = 'single_box';" sql = switch_mprintf("UPDATE agents SET state = 'Waiting', uuid = '' WHERE system = 'single_box';"
"UPDATE tiers SET state = 'Ready' WHERE agent IN (SELECT name FROM agents WHERE system = 'single_box');" "UPDATE tiers SET state = 'Ready' WHERE agent IN (SELECT name FROM agents WHERE system = 'single_box');"
"UPDATE members SET state = '%q', uuid = '' WHERE system = 'single_box';", "UPDATE members SET state = '%q', session_uuid = '' WHERE system = 'single_box';",
cc_member_state2str(CC_MEMBER_STATE_ABANDONED)); cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
cc_execute_sql(NULL, sql, NULL); cc_execute_sql(NULL, sql, NULL);
@ -756,6 +757,7 @@ static cc_queue_t *get_queue(const char *queue_name)
struct call_helper { struct call_helper {
const char *member_uuid; const char *member_uuid;
const char *member_session_uuid;
const char *queue_name; const char *queue_name;
const char *queue_strategy; const char *queue_strategy;
const char *member_joined_epoch; const char *member_joined_epoch;
@ -1356,7 +1358,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
char *sql = NULL; char *sql = NULL;
char *dialstr = NULL; char *dialstr = NULL;
cc_tier_state_t tiers_state = CC_TIER_STATE_READY; cc_tier_state_t tiers_state = CC_TIER_STATE_READY;
switch_core_session_t *member_session = switch_core_session_locate(h->member_uuid); switch_core_session_t *member_session = switch_core_session_locate(h->member_session_uuid);
switch_event_t *ovars; switch_event_t *ovars;
switch_time_t t_agent_called = 0; switch_time_t t_agent_called = 0;
switch_time_t t_agent_answered = 0; switch_time_t t_agent_answered = 0;
@ -1369,7 +1371,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
/* member is gone before we could process it */ /* member is gone before we could process it */
if (!member_session) { if (!member_session) {
sql = switch_mprintf("UPDATE members SET state = '%q', uuid = '', abandoned_epoch = '%ld' WHERE system = 'single_box' AND uuid = '%q' AND state != '%q'", sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%ld' WHERE system = 'single_box' AND uuid = '%q' AND state != '%q'",
cc_member_state2str(CC_MEMBER_STATE_ABANDONED), (long) switch_epoch_time_now(NULL), h->member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED)); cc_member_state2str(CC_MEMBER_STATE_ABANDONED), (long) switch_epoch_time_now(NULL), h->member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
cc_execute_sql(NULL, sql, NULL); cc_execute_sql(NULL, sql, NULL);
@ -1384,7 +1386,8 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-Type", h->agent_type); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-Type", h->agent_type);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", h->member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", h->member_session_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", h->member_caller_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", h->member_caller_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", h->member_caller_number); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", h->member_caller_number);
switch_event_fire(&event); switch_event_fire(&event);
@ -1395,9 +1398,11 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS); switch_event_create(&ovars, SWITCH_EVENT_REQUEST_PARAMS);
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_queue", "%s", h->queue_name); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_queue", "%s", h->queue_name);
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_member_uuid", "%s", h->member_uuid); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_member_uuid", "%s", h->member_uuid);
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_member_session_uuid", "%s", h->member_session_uuid);
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_member_pre_answer_uuid", "%s", h->member_uuid); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_member_pre_answer_uuid", "%s", h->member_uuid);
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_agent", "%s", h->agent_name); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_agent", "%s", h->agent_name);
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_agent_type", "%s", h->agent_type); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_agent_type", "%s", h->agent_type);
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "cc_side", "%s", "agent");
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "ignore_early_media", "true"); switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "ignore_early_media", "true");
t_agent_called = switch_epoch_time_now(NULL); t_agent_called = switch_epoch_time_now(NULL);
@ -1414,10 +1419,12 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_t *event; switch_event_t *event;
const char *cc_warning_tone = switch_channel_get_variable(agent_channel, "cc_warning_tone"); const char *cc_warning_tone = switch_channel_get_variable(agent_channel, "cc_warning_tone");
switch_channel_set_variable(agent_channel, "cc_side", "agent");
switch_channel_set_variable(agent_channel, "cc_queue", h->queue_name); switch_channel_set_variable(agent_channel, "cc_queue", h->queue_name);
switch_channel_set_variable(agent_channel, "cc_agent", h->agent_name); switch_channel_set_variable(agent_channel, "cc_agent", h->agent_name);
switch_channel_set_variable(agent_channel, "cc_agent_type", h->agent_type); switch_channel_set_variable(agent_channel, "cc_agent_type", h->agent_type);
switch_channel_set_variable(agent_channel, "cc_member_uuid", h->member_uuid); switch_channel_set_variable(agent_channel, "cc_member_uuid", h->member_uuid);
switch_channel_set_variable(agent_channel, "cc_member_session_uuid", h->member_session_uuid);
/* Playback this to the agent */ /* Playback this to the agent */
if (cc_warning_tone && switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { if (cc_warning_tone && switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) {
@ -1469,6 +1476,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_channel_set_variable(agent_channel, "cc_agent", h->agent_name); switch_channel_set_variable(agent_channel, "cc_agent", h->agent_name);
switch_channel_set_variable(agent_channel, "cc_agent_type", h->agent_type); switch_channel_set_variable(agent_channel, "cc_agent_type", h->agent_type);
switch_channel_set_variable(agent_channel, "cc_member_uuid", h->member_uuid); switch_channel_set_variable(agent_channel, "cc_member_uuid", h->member_uuid);
switch_channel_set_variable(agent_channel, "cc_member_session_uuid", h->member_session_uuid);
} }
switch_core_session_rwunlock(other_loopback_session); switch_core_session_rwunlock(other_loopback_session);
} }
@ -1511,7 +1519,8 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%ld", (long) t_agent_called); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Called-Time", "%ld", (long) t_agent_called);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Caller-Joined-Time", "%ld", (long) t_member_called); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Caller-Joined-Time", "%ld", (long) t_member_called);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", h->member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", h->member_session_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", h->member_caller_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", h->member_caller_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", h->member_caller_number); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", h->member_caller_number);
switch_event_fire(&event); switch_event_fire(&event);
@ -1544,7 +1553,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Agent %s answered \"%s\" <%s> from queue %s%s\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Agent %s answered \"%s\" <%s> from queue %s%s\n",
h->agent_name, h->member_caller_name, h->member_caller_number, h->queue_name, (h->record_template?" (Recorded)":"")); h->agent_name, h->member_caller_name, h->member_caller_number, h->queue_name, (h->record_template?" (Recorded)":""));
switch_ivr_uuid_bridge(h->member_uuid, switch_core_session_get_uuid(agent_session)); switch_ivr_uuid_bridge(h->member_session_uuid, switch_core_session_get_uuid(agent_session));
/* This is used for the waiting caller to quit waiting for a agent */ /* This is used for the waiting caller to quit waiting for a agent */
switch_channel_set_variable(member_channel, "cc_agent_uuid", agent_uuid); switch_channel_set_variable(member_channel, "cc_agent_uuid", agent_uuid);
@ -1567,7 +1576,8 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Caller-Joined-Time", "%ld", (long) t_member_called); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Caller-Joined-Time", "%ld", (long) t_member_called);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Bridge-Terminated-Time", "%ld", (long) switch_epoch_time_now(NULL)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Bridge-Terminated-Time", "%ld", (long) switch_epoch_time_now(NULL));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", h->member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", h->member_session_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", h->member_caller_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", h->member_caller_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", h->member_caller_number); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", h->member_caller_number);
switch_event_fire(&event); switch_event_fire(&event);
@ -1601,7 +1611,8 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Agent-Answered-Time", "%ld", (long) t_agent_answered);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Caller-Leaving-Time", "%ld", (long) switch_epoch_time_now(NULL)); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Caller-Leaving-Time", "%ld", (long) switch_epoch_time_now(NULL));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Caller-Joined-Time", "%ld", (long) t_member_called); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Caller-Joined-Time", "%ld", (long) t_member_called);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", h->member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", h->member_session_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", h->member_caller_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", h->member_caller_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", h->member_caller_number); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", h->member_caller_number);
switch_event_fire(&event); switch_event_fire(&event);
@ -1669,7 +1680,8 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Hangup-Cause", switch_channel_cause2str(cause)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Hangup-Cause", switch_channel_cause2str(cause));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent", h->agent_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Agent-System", h->agent_system);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", h->member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", h->member_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", h->member_session_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", h->member_caller_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", h->member_caller_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", h->member_caller_number); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", h->member_caller_number);
switch_event_fire(&event); switch_event_fire(&event);
@ -1713,10 +1725,12 @@ done:
struct agent_callback { struct agent_callback {
const char *queue_name; const char *queue_name;
const char *system; const char *system;
const char *uuid; const char *member_uuid;
const char *caller_number; const char *member_session_uuid;
const char *caller_name; const char *member_caller_number;
const char *joined_epoch; const char *member_caller_name;
const char *member_joined_epoch;
const char *member_score;
const char *strategy; const char *strategy;
const char *record_template; const char *record_template;
switch_bool_t tier_rules_apply; switch_bool_t tier_rules_apply;
@ -1735,15 +1749,23 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
agent_callback_t *cbt = (agent_callback_t *) pArg; agent_callback_t *cbt = (agent_callback_t *) pArg;
char *sql = NULL; char *sql = NULL;
char res[256]; char res[256];
char *agent_status = argv[2]; const char *agent_system = argv[0];
char *agent_tier_state = argv[9]; const char *agent_name = argv[1];
char *agent_last_bridge_end = argv[10]; const char *agent_status = argv[2];
char *agent_wrap_up_time = argv[11]; const char *agent_originate_string = argv[3];
char *agent_state = argv[12]; const char *agent_no_answer_count = argv[4];
char *agent_ready_time = argv[13]; const char *agent_max_no_answer = argv[5];
char *agent_tier_level = argv[14]; const char *agent_reject_delay_time = argv[6];
char *agent_type = argv[15]; const char *agent_busy_delay_time = argv[7];
char *agent_uuid = argv[16]; const char *agent_no_answer_delay_time = argv[8];
const char *agent_tier_state = argv[9];
const char *agent_last_bridge_end = argv[10];
const char *agent_wrap_up_time = argv[11];
const char *agent_state = argv[12];
const char *agent_ready_time = argv[13];
const char *agent_tier_level = argv[14];
const char *agent_type = argv[15];
const char *agent_uuid = argv[16];
switch_bool_t contact_agent = SWITCH_TRUE; switch_bool_t contact_agent = SWITCH_TRUE;
@ -1756,11 +1778,11 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
if (cbt->tier_rule_no_agent_no_wait == SWITCH_TRUE && cbt->tier_agent_available == 0) { if (cbt->tier_rule_no_agent_no_wait == SWITCH_TRUE && cbt->tier_agent_available == 0) {
cbt->tier = atoi(agent_tier_level); cbt->tier = atoi(agent_tier_level);
/* Multiple the tier level by the tier wait time */ /* Multiple the tier level by the tier wait time */
} else if (cbt->tier_rule_wait_multiply_level == SWITCH_TRUE && (long) switch_epoch_time_now(NULL) - atol(cbt->joined_epoch) >= atoi(agent_tier_level) * cbt->tier_rule_wait_second) { } else if (cbt->tier_rule_wait_multiply_level == SWITCH_TRUE && (long) switch_epoch_time_now(NULL) - atol(cbt->member_joined_epoch) >= atoi(agent_tier_level) * cbt->tier_rule_wait_second) {
cbt->tier = atoi(agent_tier_level); cbt->tier = atoi(agent_tier_level);
cbt->tier_agent_available = 0; cbt->tier_agent_available = 0;
/* Just check if joined is bigger than next tier wait time */ /* Just check if joined is bigger than next tier wait time */
} else if (cbt->tier_rule_wait_multiply_level == SWITCH_FALSE && (long) switch_epoch_time_now(NULL) - atol(cbt->joined_epoch) >= cbt->tier_rule_wait_second) { } else if (cbt->tier_rule_wait_multiply_level == SWITCH_FALSE && (long) switch_epoch_time_now(NULL) - atol(cbt->member_joined_epoch) >= cbt->tier_rule_wait_second) {
cbt->tier = atoi(agent_tier_level); cbt->tier = atoi(agent_tier_level);
cbt->tier_agent_available = 0; cbt->tier_agent_available = 0;
} else { } else {
@ -1792,7 +1814,7 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
} }
/* If agent isn't on this box */ /* If agent isn't on this box */
if (strcasecmp(argv[0],"single_box" /* SELF */)) { if (strcasecmp(agent_system,"single_box" /* SELF */)) {
if (!strcasecmp(cbt->strategy, "ring-all")) { if (!strcasecmp(cbt->strategy, "ring-all")) {
return 1; /* Abort finding agent for member if we found a match but for a different Server */ return 1; /* Abort finding agent for member if we found a match but for a different Server */
} else { } else {
@ -1802,7 +1824,7 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
if (!strcasecmp(cbt->strategy,"ring-all")) { if (!strcasecmp(cbt->strategy,"ring-all")) {
/* Check if member is a ring-all mode */ /* Check if member is a ring-all mode */
sql = switch_mprintf("SELECT count(*) FROM members WHERE serving_agent = 'ring-all' AND uuid = '%q' AND system = 'single_box'", cbt->uuid); sql = switch_mprintf("SELECT count(*) FROM members WHERE serving_agent = 'ring-all' AND uuid = '%q' AND system = 'single_box'", cbt->member_uuid);
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res)); cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql); switch_safe_free(sql);
@ -1810,14 +1832,14 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
/* Map the Agent to the member */ /* Map the Agent to the member */
sql = switch_mprintf("UPDATE members SET serving_agent = '%q', serving_system = 'single_box', state = '%q'" sql = switch_mprintf("UPDATE members SET serving_agent = '%q', serving_system = 'single_box', state = '%q'"
" WHERE state = '%q' AND uuid = '%q' AND system = 'single_box'", " WHERE state = '%q' AND uuid = '%q' AND system = 'single_box'",
argv[1], cc_member_state2str(CC_MEMBER_STATE_TRYING), agent_name, cc_member_state2str(CC_MEMBER_STATE_TRYING),
cc_member_state2str(CC_MEMBER_STATE_WAITING), cbt->uuid); cc_member_state2str(CC_MEMBER_STATE_WAITING), cbt->member_uuid);
cc_execute_sql(NULL, sql, NULL); cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql); switch_safe_free(sql);
/* Check if we won the race to get the member to our selected agent (Used for Multi system purposes) */ /* Check if we won the race to get the member to our selected agent (Used for Multi system purposes) */
sql = switch_mprintf("SELECT count(*) FROM members WHERE serving_agent = '%q' AND serving_system = 'single_box' AND uuid = '%q' AND system = 'single_box'", sql = switch_mprintf("SELECT count(*) FROM members WHERE serving_agent = '%q' AND serving_system = 'single_box' AND uuid = '%q' AND system = 'single_box'",
argv[1], cbt->uuid); agent_name, cbt->member_uuid);
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res)); cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql); switch_safe_free(sql);
} }
@ -1836,24 +1858,25 @@ static int agents_callback(void *pArg, int argc, char **argv, char **columnNames
switch_core_new_memory_pool(&pool); switch_core_new_memory_pool(&pool);
h = switch_core_alloc(pool, sizeof(*h)); h = switch_core_alloc(pool, sizeof(*h));
h->pool = pool; h->pool = pool;
h->member_uuid = switch_core_strdup(h->pool, cbt->uuid); h->member_uuid = switch_core_strdup(h->pool, cbt->member_uuid);
h->member_session_uuid = switch_core_strdup(h->pool, cbt->member_session_uuid);
h->queue_strategy = switch_core_strdup(h->pool, cbt->strategy); h->queue_strategy = switch_core_strdup(h->pool, cbt->strategy);
h->originate_string = switch_core_strdup(h->pool, argv[3]); h->originate_string = switch_core_strdup(h->pool, agent_originate_string);
h->agent_name = switch_core_strdup(h->pool, argv[1]); h->agent_name = switch_core_strdup(h->pool, agent_name);
h->agent_system = switch_core_strdup(h->pool, "single_box"); h->agent_system = switch_core_strdup(h->pool, "single_box");
h->agent_status = switch_core_strdup(h->pool, argv[2]); h->agent_status = switch_core_strdup(h->pool, agent_status);
h->agent_type = switch_core_strdup(h->pool, agent_type); h->agent_type = switch_core_strdup(h->pool, agent_type);
h->agent_uuid = switch_core_strdup(h->pool, agent_uuid); h->agent_uuid = switch_core_strdup(h->pool, agent_uuid);
h->member_joined_epoch = switch_core_strdup(h->pool, cbt->joined_epoch); h->member_joined_epoch = switch_core_strdup(h->pool, cbt->member_joined_epoch);
h->member_caller_name = switch_core_strdup(h->pool, cbt->caller_name); h->member_caller_name = switch_core_strdup(h->pool, cbt->member_caller_name);
h->member_caller_number = switch_core_strdup(h->pool, cbt->caller_number); h->member_caller_number = switch_core_strdup(h->pool, cbt->member_caller_number);
h->queue_name = switch_core_strdup(h->pool, cbt->queue_name); h->queue_name = switch_core_strdup(h->pool, cbt->queue_name);
h->record_template = switch_core_strdup(h->pool, cbt->record_template); h->record_template = switch_core_strdup(h->pool, cbt->record_template);
h->no_answer_count = atoi(argv[4]); h->no_answer_count = atoi(agent_no_answer_count);
h->max_no_answer = atoi(argv[5]); h->max_no_answer = atoi(agent_max_no_answer);
h->reject_delay_time = atoi(argv[6]); h->reject_delay_time = atoi(agent_reject_delay_time);
h->busy_delay_time = atoi(argv[7]); h->busy_delay_time = atoi(agent_busy_delay_time);
h->no_answer_delay_time = atoi(argv[8]); h->no_answer_delay_time = atoi(agent_no_answer_delay_time);
cc_agent_update("state", cc_agent_state2str(CC_AGENT_STATE_RECEIVING), h->agent_name); cc_agent_update("state", cc_agent_state2str(CC_AGENT_STATE_RECEIVING), h->agent_name);
@ -1897,9 +1920,22 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
uint32_t discard_abandoned_after; uint32_t discard_abandoned_after;
switch_bool_t abandoned_resume_allowed; switch_bool_t abandoned_resume_allowed;
agent_callback_t cbt; agent_callback_t cbt;
const char *member_state = NULL;
const char *member_abandoned_epoch = NULL;
memset(&cbt, 0, sizeof(cbt));
if (!argv[0] || !(queue = get_queue(argv[0]))) { cbt.queue_name = argv[0];
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found locally, skip this member\n", argv[0]); cbt.member_uuid = argv[1];
cbt.member_session_uuid = argv[2];
cbt.member_caller_number = argv[3];
cbt.member_caller_name = argv[4];
cbt.member_joined_epoch = argv[5];
cbt.member_score = argv[6];
member_state = argv[7];
member_abandoned_epoch = argv[8];
if (!cbt.queue_name || !(queue = get_queue(cbt.queue_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found locally, skip this member\n", cbt.queue_name);
goto end; goto end;
} else { } else {
queue_name = strdup(queue->name); queue_name = strdup(queue->name);
@ -1917,21 +1953,27 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
queue_rwunlock(queue); queue_rwunlock(queue);
} }
if (!strcasecmp(argv[6], cc_member_state2str(CC_MEMBER_STATE_ABANDONED))) { /* Checking for cleanup Abandonded calls from the db */
long abandoned_epoch = atol(argv[7]); if (!strcasecmp(member_state, cc_member_state2str(CC_MEMBER_STATE_ABANDONED))) {
long abandoned_epoch = atol(member_abandoned_epoch);
if (abandoned_epoch == 0) { if (abandoned_epoch == 0) {
abandoned_epoch = atol(argv[4]); abandoned_epoch = atol(cbt.member_joined_epoch);
} }
/* Once we pass a certain point, we want to get rid of the abandoned call */ /* Once we pass a certain point, we want to get rid of the abandoned call */
if (abandoned_epoch + discard_abandoned_after < (long) switch_epoch_time_now(NULL)) { if (abandoned_epoch + discard_abandoned_after < (long) switch_epoch_time_now(NULL)) {
sql = switch_mprintf("DELETE FROM members WHERE system = 'single_box' AND uuid = '%q' AND (abandoned_epoch = '%ld' OR joined_epoch = '%q')", argv[1], abandoned_epoch, argv[4]); sql = switch_mprintf("DELETE FROM members WHERE system = 'single_box' AND uuid = '%q' AND (abandoned_epoch = '%ld' OR joined_epoch = '%q')", cbt.member_uuid, abandoned_epoch, cbt.member_joined_epoch);
cc_execute_sql(NULL, sql, NULL); cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql); switch_safe_free(sql);
} }
/* Skip this member */ /* Skip this member */
goto end; goto end;
} }
memset(&cbt, 0, sizeof(cbt));
/* Check if member is in the queue waiting */
if (zstr(cbt.member_session_uuid)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Member %s <%s> in Queue %s have no session uuid, skip this member\n", cbt.member_caller_name, cbt.member_caller_number, cbt.queue_name);
}
cbt.tier = 0; cbt.tier = 0;
cbt.tier_agent_available = 0; cbt.tier_agent_available = 0;
@ -1940,11 +1982,6 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
cbt.tier_rule_wait_multiply_level = tier_rule_wait_multiply_level; cbt.tier_rule_wait_multiply_level = tier_rule_wait_multiply_level;
cbt.tier_rule_no_agent_no_wait = tier_rule_no_agent_no_wait; cbt.tier_rule_no_agent_no_wait = tier_rule_no_agent_no_wait;
cbt.uuid = argv[1];
cbt.caller_number = argv[2];
cbt.caller_name = argv[3];
cbt.joined_epoch = argv[4];
cbt.queue_name = argv[0];
cbt.strategy = queue_strategy; cbt.strategy = queue_strategy;
cbt.record_template = queue_record_template; cbt.record_template = queue_record_template;
cbt.agent_found = SWITCH_FALSE; cbt.agent_found = SWITCH_FALSE;
@ -1957,7 +1994,7 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
sql_order_by = switch_mprintf("level, agents.calls_answered, position"); sql_order_by = switch_mprintf("level, agents.calls_answered, position");
} else if (!strcasecmp(queue_strategy, "ring-all")) { } else if (!strcasecmp(queue_strategy, "ring-all")) {
sql = switch_mprintf("UPDATE members SET state = '%q' WHERE state = '%q' AND uuid = '%q' AND system = 'single_box'", sql = switch_mprintf("UPDATE members SET state = '%q' WHERE state = '%q' AND uuid = '%q' AND system = 'single_box'",
cc_member_state2str(CC_MEMBER_STATE_TRYING), cc_member_state2str(CC_MEMBER_STATE_WAITING), cbt.uuid); cc_member_state2str(CC_MEMBER_STATE_TRYING), cc_member_state2str(CC_MEMBER_STATE_WAITING), cbt.member_uuid);
cc_execute_sql(NULL, sql, NULL); cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql); switch_safe_free(sql);
sql_order_by = switch_mprintf("level, position"); sql_order_by = switch_mprintf("level, position");
@ -1982,8 +2019,8 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
switch_safe_free(sql_order_by); switch_safe_free(sql_order_by);
/* We update a field in the queue struct so we can kick caller out if waiting for too long with no agent */ /* We update a field in the queue struct so we can kick caller out if waiting for too long with no agent */
if (!argv[0] || !(queue = get_queue(argv[0]))) { if (!cbt.queue_name || !(queue = get_queue(cbt.queue_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found locally, skip this member\n", argv[0]); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Queue %s not found locally, skip this member\n", cbt.queue_name);
goto end; goto end;
} else { } else {
queue->last_agent_exist_check = switch_epoch_time_now(NULL); queue->last_agent_exist_check = switch_epoch_time_now(NULL);
@ -2025,7 +2062,7 @@ void *SWITCH_THREAD_FUNC cc_agent_dispatch_thread_run(switch_thread_t *thread, v
while (globals.running == 1) { while (globals.running == 1) {
char *sql = NULL; char *sql = NULL;
sql = switch_mprintf("SELECT queue,uuid,caller_number,caller_name,joined_epoch,(%ld-joined_epoch)+base_score+skill_score AS score, state, abandoned_epoch FROM members" sql = switch_mprintf("SELECT queue,uuid,session_uuid,caller_number,caller_name,joined_epoch,(%ld-joined_epoch)+base_score+skill_score AS score, state, abandoned_epoch FROM members"
" WHERE state = '%q' OR state = '%q' OR (serving_agent = 'ring-all' AND state = '%q') ORDER BY score DESC", " WHERE state = '%q' OR state = '%q' OR (serving_agent = 'ring-all' AND state = '%q') ORDER BY score DESC",
(long) switch_epoch_time_now(NULL), (long) switch_epoch_time_now(NULL),
cc_member_state2str(CC_MEMBER_STATE_WAITING), cc_member_state2str(CC_MEMBER_STATE_ABANDONED), cc_member_state2str(CC_MEMBER_STATE_TRYING)); cc_member_state2str(CC_MEMBER_STATE_WAITING), cc_member_state2str(CC_MEMBER_STATE_ABANDONED), cc_member_state2str(CC_MEMBER_STATE_TRYING));
@ -2073,8 +2110,9 @@ void cc_agent_dispatch_thread_start(void)
} }
struct member_thread_helper { struct member_thread_helper {
const char *member_uuid;
const char *queue_name; const char *queue_name;
const char *member_uuid;
const char *member_session_uuid;
switch_time_t t_member_called; switch_time_t t_member_called;
cc_member_cancel_reason_t member_cancel_reason; cc_member_cancel_reason_t member_cancel_reason;
@ -2085,7 +2123,7 @@ struct member_thread_helper {
void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj) void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj)
{ {
struct member_thread_helper *m = (struct member_thread_helper *) obj; struct member_thread_helper *m = (struct member_thread_helper *) obj;
switch_core_session_t *member_session = switch_core_session_locate(m->member_uuid); switch_core_session_t *member_session = switch_core_session_locate(m->member_session_uuid);
switch_channel_t *member_channel = NULL; switch_channel_t *member_channel = NULL;
switch_mutex_lock(globals.mutex); switch_mutex_lock(globals.mutex);
@ -2150,8 +2188,8 @@ void *SWITCH_THREAD_FUNC cc_member_thread_run(switch_thread_t *thread, void *obj
} }
struct moh_dtmf_helper { struct moh_dtmf_helper {
const char *queue_name; const char *queue_name;
char dtmf; char dtmf;
}; };
static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) { static switch_status_t moh_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) {
@ -2188,7 +2226,7 @@ SWITCH_STANDARD_APP(callcenter_function)
switch_core_session_t *member_session = session; switch_core_session_t *member_session = session;
switch_channel_t *member_channel = switch_core_session_get_channel(member_session); switch_channel_t *member_channel = switch_core_session_get_channel(member_session);
char *sql = NULL; char *sql = NULL;
char *member_uuid = switch_core_session_get_uuid(member_session); char *member_session_uuid = switch_core_session_get_uuid(member_session);
struct member_thread_helper *h = NULL; struct member_thread_helper *h = NULL;
switch_thread_t *thread; switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL; switch_threadattr_t *thd_attr = NULL;
@ -2203,6 +2241,8 @@ SWITCH_STANDARD_APP(callcenter_function)
switch_time_t t_member_called = switch_epoch_time_now(NULL); switch_time_t t_member_called = switch_epoch_time_now(NULL);
long abandoned_epoch = 0; long abandoned_epoch = 0;
const char *agent_uuid = NULL; const char *agent_uuid = NULL;
switch_uuid_t smember_uuid;
char member_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
if (!zstr(data)) { if (!zstr(data)) {
mydata = switch_core_session_strdup(member_session, data); mydata = switch_core_session_strdup(member_session, data);
@ -2233,13 +2273,29 @@ SWITCH_STANDARD_APP(callcenter_function)
char res[256]; char res[256];
/* Check to see if agent already exist */ /* Check to see if agent already exist */
sql = switch_mprintf("SELECT abandoned_epoch FROM members WHERE queue = '%q' AND caller_number = '%q' AND state = '%q' ORDER BY abandoned_epoch DESC", sql = switch_mprintf("SELECT uuid FROM members WHERE queue = '%q' AND caller_number = '%q' AND state = '%q' ORDER BY abandoned_epoch DESC",
queue_name, switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), cc_member_state2str(CC_MEMBER_STATE_ABANDONED)); queue_name, switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res)); cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql); switch_safe_free(sql);
abandoned_epoch = atol(res); strncpy(member_uuid, res, sizeof(member_uuid));
if (!zstr(member_uuid)) {
sql = switch_mprintf("SELECT abandoned_epoch FROM members WHERE uuid = '%q'", member_uuid);
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql);
abandoned_epoch = atol(res);
}
} }
/* If no existing uuid is restored, let create a new one */
if (abandoned_epoch == 0) {
switch_uuid_get(&smember_uuid);
switch_uuid_format(member_uuid, &smember_uuid);
}
switch_channel_set_variable(member_channel, "cc_side", "member");
switch_channel_set_variable(member_channel, "cc_member_uuid", member_uuid);
/* Add manually imported score */ /* Add manually imported score */
if (cc_base_score) { if (cc_base_score) {
cc_base_score_int += atoi(cc_base_score); cc_base_score_int += atoi(cc_base_score);
@ -2254,7 +2310,8 @@ SWITCH_STANDARD_APP(callcenter_function)
switch_channel_event_set_data(member_channel, event); switch_channel_event_set_data(member_channel, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Queue", queue_name); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Queue", queue_name);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Action", "member-queue-%s", (abandoned_epoch==0?"start":"resume")); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Action", "member-queue-%s", (abandoned_epoch==0?"start":"resume"));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", member_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", member_session_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name"))); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number"))); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")));
switch_event_fire(&event); switch_event_fire(&event);
@ -2266,10 +2323,11 @@ SWITCH_STANDARD_APP(callcenter_function)
if (abandoned_epoch == 0) { if (abandoned_epoch == 0) {
/* Add the caller to the member queue */ /* Add the caller to the member queue */
sql = switch_mprintf("INSERT INTO members" sql = switch_mprintf("INSERT INTO members"
" (queue,system,uuid,system_epoch,joined_epoch,base_score,skill_score,caller_number,caller_name,serving_agent,serving_system,state)" " (queue,system,uuid,session_uuid,system_epoch,joined_epoch,base_score,skill_score,caller_number,caller_name,serving_agent,serving_system,state)"
" VALUES('%q','single_box','%q','%q','%ld','%d','%d','%q','%q','%q','','%q')", " VALUES('%q','single_box','%q','%q','%q','%ld','%d','%d','%q','%q','%q','','%q')",
queue_name, queue_name,
member_uuid, member_uuid,
member_session_uuid,
start_epoch, start_epoch,
(long) switch_epoch_time_now(NULL), (long) switch_epoch_time_now(NULL),
cc_base_score_int, cc_base_score_int,
@ -2283,18 +2341,20 @@ SWITCH_STANDARD_APP(callcenter_function)
} else { } else {
char res[256]; char res[256];
/* Update abandoned member */ /* Update abandoned member */
sql = switch_mprintf("UPDATE members SET uuid = '%q', state = '%q', rejoined_epoch = '%ld' WHERE caller_number = '%q' AND abandoned_epoch = '%ld' AND state = '%q' AND queue = '%q'", sql = switch_mprintf("UPDATE members SET session_uuid = '%q', state = '%q', rejoined_epoch = '%ld' WHERE uuid = '%q' AND state = '%q'",
member_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), (long) switch_epoch_time_now(NULL), switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")), abandoned_epoch, cc_member_state2str(CC_MEMBER_STATE_ABANDONED), queue_name); member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), (long) switch_epoch_time_now(NULL), member_uuid, cc_member_state2str(CC_MEMBER_STATE_ABANDONED));
cc_execute_sql(queue, sql, NULL); cc_execute_sql(queue, sql, NULL);
switch_safe_free(sql); switch_safe_free(sql);
/* Confirm we took that member in */ /* Confirm we took that member in */
sql = switch_mprintf("SELECT abandoned_epoch FROM members WHERE uuid = '%q' AND state = '%q' AND queue = '%q'", member_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), queue_name); sql = switch_mprintf("SELECT abandoned_epoch FROM members WHERE uuid = '%q' AND session_uuid = '%q' AND state = '%q' AND queue = '%q'", member_session, member_session_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), queue_name);
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res)); cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql); switch_safe_free(sql);
if (atol(res) == 0) { if (atol(res) == 0) {
/* Failed to get the member !!! */ /* Failed to get the member !!! */
/* TODO Loop back to just create a uuid and add the member as a new member */
/* TODO ERROR MSG */
queue_rwunlock(queue); queue_rwunlock(queue);
goto end; goto end;
} }
@ -2310,6 +2370,7 @@ SWITCH_STANDARD_APP(callcenter_function)
h->pool = pool; h->pool = pool;
h->member_uuid = switch_core_strdup(h->pool, member_uuid); h->member_uuid = switch_core_strdup(h->pool, member_uuid);
h->member_session_uuid = switch_core_strdup(h->pool, member_session_uuid);
h->queue_name = switch_core_strdup(h->pool, queue_name); h->queue_name = switch_core_strdup(h->pool, queue_name);
h->t_member_called = t_member_called; h->t_member_called = t_member_called;
h->member_cancel_reason = CC_MEMBER_CANCEL_REASON_NONE; h->member_cancel_reason = CC_MEMBER_CANCEL_REASON_NONE;
@ -2376,7 +2437,7 @@ SWITCH_STANDARD_APP(callcenter_function)
/* Canceled for some reason */ /* Canceled for some reason */
if (!switch_channel_up(member_channel) || h->member_cancel_reason != CC_MEMBER_CANCEL_REASON_NONE) { if (!switch_channel_up(member_channel) || h->member_cancel_reason != CC_MEMBER_CANCEL_REASON_NONE) {
/* Update member state */ /* Update member state */
sql = switch_mprintf("UPDATE members SET state = '%q', uuid = '', abandoned_epoch = '%ld' WHERE system = 'single_box' AND uuid = '%q'", sql = switch_mprintf("UPDATE members SET state = '%q', session_uuid = '', abandoned_epoch = '%ld' WHERE system = 'single_box' AND uuid = '%q'",
cc_member_state2str(CC_MEMBER_STATE_ABANDONED), (long) switch_epoch_time_now(NULL), member_uuid); cc_member_state2str(CC_MEMBER_STATE_ABANDONED), (long) switch_epoch_time_now(NULL), member_uuid);
cc_execute_sql(NULL, sql, NULL); cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql); switch_safe_free(sql);
@ -2393,7 +2454,8 @@ SWITCH_STANDARD_APP(callcenter_function)
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Caller-Joined-Time", "%ld", (long) t_member_called); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Caller-Joined-Time", "%ld", (long) t_member_called);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Cause", "Cancel"); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Cause", "Cancel");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Cancel-Reason", cc_member_cancel_reason2str(h->member_cancel_reason)); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Cancel-Reason", cc_member_cancel_reason2str(h->member_cancel_reason));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", member_uuid); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", member_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-UUID", member_session_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name"))); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Name", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number"))); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Caller-CID-Number", switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")));
switch_event_fire(&event); switch_event_fire(&event);