freeswitch-callcenter源码逻辑

更新时间:2023-06-30 10:56:56 阅读: 评论:0

freeswitch-callcenter源码逻辑
SWITCH_STANDARD_APP(callcenter_function)
{
char *argv[6] = { 0 };
char *mydata = NULL;
cc_queue_t *queue = NULL;
const char *queue_name = NULL;
switch_core_ssion_t *member_ssion = ssion;
switch_channel_t *member_channel = switch_core_ssion_get_channel(member_ssion);
char *sql = NULL;
char *member_ssion_uuid = switch_core_ssion_get_uuid(member_ssion);
struct member_thread_helper *h = NULL;
switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL;
switch_memory_pool_t *pool;
switch_channel_timetable_t *times = NULL;
const char *cc_moh_override = switch_channel_get_variable(member_channel, "cc_moh_override");facebook是什么意思
const char *cc_ba_score = switch_channel_get_variable(member_channel, "cc_ba_score");
int cc_ba_score_int = 0;
const char *cur_moh = NULL;
char *moh_expanded = NULL;
char start_epoch[64];
switch_event_t *event;
switch_time_t t_member_called = local_epoch_time_now(NULL);
long abandoned_epoch = 0;
switch_uuid_t smember_uuid;
char member_uuid[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
switch_bool_t agent_found = SWITCH_FALSE;
switch_bool_t moh_valid = SWITCH_TRUE;
const char *p;
if (!zstr(data)) {
mydata = switch_core_ssion_strdup(member_ssion, data);
switch_parate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
} el {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_ssion), SWITCH_LOG_WARNING, "No Queue name provided\n");
goto end;
}
if (argv[0]) {
queue_name = argv[0];
waist}
if (!queue_name || !(queue = get_queue(queue_name))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_ssion), SWITCH_LOG_WARNING, "Queue %s not found\n", queue_name);
goto end;
}
/* Make sure we answer the channel before getting the switch_channel_time_table_t answer time */
switch_channel_answer(member_channel);
/* Grab the start epoch of a channel */
times = switch_channel_get_timetable(member_channel);
switch_snprintf(start_epoch, sizeof(start_epoch), "%" SWITCH_TIME_T_FMT, times->answered / 1000000);
/* Check if we support and have a queued abandoned member we can resume from */
if (queue->abandoned_resume_allowed == SWITCH_TRUE) {
char res[256];
/* Check to e if agent already exist */
sql = switch_mprintf("SELECT uuid FROM members WHERE queue = '%q' AND cid_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  cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql);
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_t_variable(member_channel, "cc_side", "member");
switch_channel_t_variable(member_channel, "cc_member_uuid", member_uuid);
/* Add manually imported score */
if (cc_ba_score) {
cc_ba_score_int += atoi(cc_ba_score);
}
/* If system, will add the total time the ssion is up to the ba score */
if (!switch_strlen_zero(start_epoch) && !strcacmp("system", queue->time_ba_score)) {
cc_ba_score_int += ((long) local_epoch_time_now(NULL) - atol(start_epoch));
}
/* for xml_cdr needs */
switch_channel_t_variable_printf(member_channel, "cc_queue_joined_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
switch_channel_t_variable(member_channel, "cc_queue", queue_name);
/* We have a previous abandoned ur, let's try to recover his place */
creep什么意思
if (abandoned_epoch > 0) {
char res[256];
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_ssion), SWITCH_LOG_DEBUG, "Member %s <%s> restoring it previous position in queue %
/* Update abandoned member */
sql = switch_mprintf("UPDATE members SET ssion_uuid = '%q', state = '%q', rejoined_epoch = '%" SWITCH_TIME_T_FMT "' WHERE uuid = '%q' AND state =    member_ssion_uuid, cc_member_state2str(CC_MEMBER_STATE_WAITING), local_epoch_time_now(NULL), member_uuid, cc_member_state2str(CC_ME  cc_execute_sql(queue, sql, NULL);
switch_safe_free(sql);restapi
/* Confirm we took that member in */
sql = switch_mprintf("SELECT abandoned_epoch FROM members WHERE uuid = '%q' AND ssion_uuid = '%q' AND state = '%q' AND queue = '%q'", member_  cc_execute_sql2str(NULL, NULL, sql, res, sizeof(res));
switch_safe_free(sql);
abandoned_epoch = atol(res);
if (abandoned_epoch == 0) {
/* Failed to get the member  */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_ssion), SWITCH_LOG_ERROR, "Member %s <%s> restoring action failed in queue %s, join    //queue_rwunlock(queue);
} el {
}
}
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_t_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_string(event, SWITCH_STACK_BOTTOM, "CC-Member-UUID", member_uuid);韩国搞笑电视剧
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", member_ssion_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", switch_str_nil(switch_channel_get_variable(member_channel,  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Number", switch_str_nil(switch_channel_get_variable(member_channe  switch_event_fire(&event);
}
if (abandoned_epoch == 0) {
char *strategy_str = NULL;
/* Add the caller to the member queue */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_ssion), SWITCH_LOG_DEBUG, "Member %s <%s> joining queue %s\n", switch_str_nil(switc
if (!strcacmp(queue->strategy,"ring-all")) {
strategy_str = "ring-all";
} el if (!strcacmp(queue->strategy,"ring-progressively")) {
strategy_str = "ring-progressively";
} el {
strategy_str = "";
}
sql = switch_mprintf("INSERT INTO members"
" (queue,system,uuid,ssion_uuid,system_epoch,joined_epoch,ba_score,skill_score,cid_number,cid_name,rving_agent,rving_system,state)"
" VALUES('%q','single_box','%q','%q','%q','%" SWITCH_TIME_T_FMT "','%d','%d','%q','%q','%q','','%q')",
queue_name,
member_uuid,
member_ssion_uuid,
start_epoch,
local_epoch_time_now(NULL),
号外是什么意思cc_ba_score_int,
0 /*TODO SKILL score*/,
switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")),
switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")),
strategy_str,
cc_member_state2str(CC_MEMBER_STATE_WAITING));
cc_execute_sql(queue, sql, NULL);
switch_safe_free(sql);
}
/* Send Event with queue count */
cc_queue_count(queue_name);
/* Start Thread that will playback different prompt to the channel */
switch_core_new_memory_pool(&pool);
h = switch_core_alloc(pool, sizeof(*h));
h->pool = pool;
h->member_uuid = switch_core_strdup(h->pool, member_uuid);
h->member_ssion_uuid = switch_core_strdup(h->pool, member_ssion_uuid);
h->member_cid_name = switch_core_strdup(h->pool, switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")));
h->member_cid_number = switch_core_strdup(h->pool, switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")));
h->queue_name = switch_core_strdup(h->pool, queue_name);
h->t_member_called = t_member_called;
h->member_cancel_reason = CC_MEMBER_CANCEL_REASON_NONE;
h->running = 1;
switch_threadattr_create(&thd_attr, h->pool);
switch_threadattr_detach_t(thd_attr, 1);
switch_threadattr_stacksize_t(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&thread, thd_attr, cc_member_thread_run, h, h->pool);
/* Playback MOH */
if (cc_moh_override) {
cur_moh = switch_core_ssion_strdup(member_ssion, cc_moh_override);
} el {
} el {
cur_moh = switch_core_ssion_strdup(member_ssion, queue->moh);
}
queue_rwunlock(queue);
moh_expanded = switch_channel_expand_variables(member_channel, cur_moh);
while (switch_channel_ready(member_channel)) {
switch_input_args_t args = { 0 };
struct moh_dtmf_helper ht;
ht.dtmf = '\0';
args.input_callback = moh_on_dtmf;
args.buf = (void *) &ht;
args.buflen = sizeof(h);
/* An agent was found, time to exit and let the bridge do it job */
if ((p = switch_channel_get_variable(member_channel, "cc_agent_found")) && (agent_found = switch_true(p))) {
break;
}
/* If the member thread t a different reason, we monitor it so we can quit the wait */
if (h->member_cancel_reason != CC_MEMBER_CANCEL_REASON_NONE) {
break;
}
switch_core_ssion_flush_private_events(member_ssion);
if (moh_valid && moh_expanded) {
switch_status_t status = switch_ivr_play_file(member_ssion, NULL, moh_expanded, &args);
if (status == SWITCH_STATUS_FALSE /* Invalid Recording */ && SWITCH_READ_ACCEPTABLE(status)) {
/* Sadly, there doesn't em to be a return to switch_ivr_play_file that tell you the file wasn't found.  FALSE also mean that the channel got switch to BRAKE sta    switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_ssion), SWITCH_LOG_WARNING, "Couldn't play file '%s', continuing wait with no audio\n",    moh_valid = SWITCH_FALSE;
} el if (status == SWITCH_STATUS_BREAK) {
char buf[2] = { ht.dtmf, 0 };
switch_channel_t_variable(member_channel, "cc_exit_key", buf);
break;
} el if (!SWITCH_READ_ACCEPTABLE(status)) {
break;
}
} el {
if ((switch_ivr_collect_digits_callback(member_ssion, &args, 0, 0)) == SWITCH_STATUS_BREAK) {
char buf[2] = { ht.dtmf, 0 };
switch_channel_t_variable(member_channel, "cc_exit_key", buf);
break;
}
}
switch_yield(1000);
}
if (moh_expanded != cur_moh) {
switch_safe_free(moh_expanded);
ideos}
/* Make sure an agent was found, as we might break above without tting it */
if (!agent_found && (p = switch_channel_get_variable(member_channel, "cc_agent_found"))) {
agent_found = switch_true(p);
}
/* Stop member thread */
if (h) {
h->running = 0;
}
/* Check if we were removed becau FS Core(BREAK) asked us to */
if (h->member_cancel_reason == CC_MEMBER_CANCEL_REASON_NONE && !agent_found) {
h->member_cancel_reason = CC_MEMBER_CANCEL_REASON_BREAK_OUT;
夏奇拉最好听的歌}
switch_channel_t_variable(member_channel, "cc_agent_found", NULL);
/* Canceled for some reason */
if (!switch_channel_up(member_channel) || h->member_cancel_reason != CC_MEMBER_CANCEL_REASON_NONE) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_ssion), SWITCH_LOG_DEBUG, "Member %s <%s> abandoned waiting in queue %s\n", switc
/* Update member state */
sql = switch_mprintf("UPDATE members SET state = '%q', ssion_uuid = '', abandoned_epoch = '%" SWITCH_TIME_T_FMT "' WHERE system = 'single_box' A    cc_member_state2str(CC_MEMBE
R_STATE_ABANDONED), local_epoch_time_now(NULL), member_uuid);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
/* Hangup any callback agents  */
语言表达方式switch_core_ssion_hupall_matching_var("cc_member_pre_answer_uuid", member_uuid, SWITCH_CAUSE_ORIGINATOR_CANCEL);
/* Generate an event */
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CALLCENTER_EVENT) == SWITCH_STATUS_SUCCESS) {
switch_channel_event_t_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-Action", "member-queue-
生活中需要善意的谎言
end");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Leaving-Time", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "CC-Member-Joined-Time", "%" SWITCH_TIME_T_FMT, t_member_called);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Cau", "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-Member-UUID", member_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-Session-UUID", member_ssion_uuid);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Name", swi
tch_str_nil(switch_channel_get_variable(member_channel,  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CC-Member-CID-Number", switch_str_nil(switch_channel_get_variable(member_channe    switch_event_fire(&event);
}
/* Update some channel variables for xml_cdr needs */
switch_channel_t_variable_printf(member_channel, "cc_queue_canceled_epoch", "%" SWITCH_TIME_T_FMT, local_epoch_time_now(NULL));
switch_channel_t_variable_printf(member_channel, "cc_cau", "%s", "cancel");
switch_channel_t_variable_printf(member_channel, "cc_cancel_reason", "%s", cc_member_cancel_reason2str(h->member_cancel_reason));
/* Print some debug log information */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_ssion), SWITCH_LOG_DEBUG, "Member \"%s\" <%s> exit queue %s due to %s\n",
switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_name")),
switch_str_nil(switch_channel_get_variable(member_channel, "caller_id_number")),
queue_name, cc_member_cancel_reason2str(h->member_cancel_reason));
if ((queue = get_queue(queue_name))) {
queue->calls_abandoned++;
queue_rwunlock(queue);
}
} el {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member_ssion), SWITCH_LOG_DEBUG, "Member %s <%s> is answered by an agent in queue %s\n"
/* Update member state */
sql = switch_mprintf("UPDATE members SET state = '%q', bridge_epoch = '%" SWITCH_TIME_T_FMT "' WHERE system = 'single_box' AND uuid = '%q'",
cc_member_state2str(CC_MEMBER_STATE_ANSWERED), local_epoch_time_now(NULL), member_uuid);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);
/* Update some channel variables for xml_cdr needs */
switch_channel_t_variable_printf(member_channel, "cc_cau", "%s", "answered");
if ((queue = get_queue(queue_name))) {
queue->calls_answered++;
queue_rwunlock(queue);
}
}
/* Send Event with queue count */

本文发布于:2023-06-30 10:56:56,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/162535.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:需要   善意   韩国   逻辑   语言表达   电视剧   源码
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图