From 50390a7083bef86373a86935db9f464cda9c79c1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 Oct 2007 19:58:06 +0000 Subject: [PATCH] improve mod-fifo git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5779 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_ivr.h | 2 + src/mod/applications/mod_fifo/mod_fifo.c | 372 +++++++++++++++++++++-- src/switch_channel.c | 5 +- src/switch_ivr.c | 64 ++-- 4 files changed, 384 insertions(+), 59 deletions(-) diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 395ed95fba..e2b27fc2e3 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -89,6 +89,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_activate_unicast(switch_core_session_ \note on success the xml object must be freed */ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_t *session, switch_xml_t * xml_cdr); +SWITCH_DECLARE(int) switch_ivr_set_xml_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_profile, int off); +SWITCH_DECLARE(int) switch_ivr_set_xml_chan_vars(switch_xml_t xml, switch_channel_t *channel, int off); /*! \brief Parse command from an event diff --git a/src/mod/applications/mod_fifo/mod_fifo.c b/src/mod/applications/mod_fifo/mod_fifo.c index 011c410aa5..a630cc1069 100644 --- a/src/mod/applications/mod_fifo/mod_fifo.c +++ b/src/mod/applications/mod_fifo/mod_fifo.c @@ -34,6 +34,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown); SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load); SWITCH_MODULE_DEFINITION(mod_fifo, mod_fifo_load, mod_fifo_shutdown, NULL); +#define FIFO_EVENT "fifo::info" + static switch_status_t on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen) @@ -79,20 +81,41 @@ static switch_status_t read_frame_callback(switch_core_session_t *session, switc static struct { switch_hash_t *fifo_hash; + switch_mutex_t *mutex; switch_memory_pool_t *pool; } globals; + +struct fifo_node { + char *name; + switch_mutex_t *mutex; + switch_queue_t *fifo; + switch_hash_t *caller_hash; + switch_hash_t *consumer_hash; + int caller_count; + int consumer_count; +}; + +typedef struct fifo_node fifo_node_t; + #define FIFO_DESC "Fifo for stacking parked calls." #define FIFO_USAGE " [in [|undef] [|undef] | out [wait|nowait] [|undef] [|undef]]" SWITCH_STANDARD_APP(fifo_function) { int argc; char *mydata = NULL, *argv[5] = { 0 }; - switch_queue_t *fifo; + fifo_node_t *node; switch_channel_t *channel; int nowait = 0; char *moh = NULL; char *announce = NULL; + switch_event_t *event = NULL; + char date[80] = ""; + switch_time_exp_t tm; + switch_time_t ts = switch_time_now(); + switch_size_t retsize; + + if (switch_strlen_zero(data)) { @@ -107,11 +130,19 @@ SWITCH_STANDARD_APP(fifo_function) return; } - if (!(fifo = switch_core_hash_find(globals.fifo_hash, argv[0]))) { - switch_queue_create(&fifo, SWITCH_CORE_QUEUE_LEN, globals.pool); - assert(fifo); - switch_core_hash_insert(globals.fifo_hash, argv[0], fifo); + switch_mutex_lock(globals.mutex); + if (!(node = switch_core_hash_find(globals.fifo_hash, argv[0]))) { + node = switch_core_alloc(globals.pool, sizeof(*node)); + node->name = switch_core_strdup(globals.pool, argv[0]); + switch_queue_create(&node->fifo, SWITCH_CORE_QUEUE_LEN, globals.pool); + switch_core_hash_init(&node->caller_hash, globals.pool); + switch_core_hash_init(&node->consumer_hash, globals.pool); + assert(node->fifo); + switch_mutex_init(&node->mutex, SWITCH_MUTEX_NESTED, globals.pool); + switch_core_hash_insert(globals.fifo_hash, argv[0], node); } + switch_mutex_unlock(globals.mutex); + channel = switch_core_session_get_channel(session); moh = switch_channel_get_variable(channel, "fifo_music"); @@ -129,7 +160,7 @@ SWITCH_STANDARD_APP(fifo_function) if (argc > 2) { announce = argv[2]; } - + if (argc > 3) { moh = argv[3]; } @@ -143,10 +174,29 @@ SWITCH_STANDARD_APP(fifo_function) } switch_channel_set_flag(channel, CF_TAGGED); + + switch_mutex_lock(node->mutex); + node->caller_count++; + switch_core_hash_insert(node->caller_hash, uuid, session); + switch_queue_push(node->fifo, uuid); + switch_mutex_unlock(node->mutex); + + switch_time_exp_lt(&tm, ts); + switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); + switch_channel_set_variable(channel, "fifo_status", "WAITING"); + switch_channel_set_variable(channel, "fifo_timestamp", date); - switch_queue_push(fifo, uuid); + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "push"); + switch_event_fire(&event); + } + switch_ivr_park(session, NULL); - + + + if (switch_channel_ready(channel)) { if (announce) { switch_ivr_play_file(session, NULL, announce, NULL); @@ -156,7 +206,24 @@ SWITCH_STANDARD_APP(fifo_function) switch_channel_clear_flag(channel, CF_TAGGED); if (switch_channel_ready(channel)) { - switch_channel_set_state(channel, CS_HIBERNATE); + switch_channel_set_state(channel, CS_HIBERNATE); + } else { + + switch_time_exp_lt(&tm, ts); + switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); + switch_channel_set_variable(channel, "fifo_status", "ABORTED"); + switch_channel_set_variable(channel, "fifo_timestamp", date); + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "abort"); + switch_event_fire(&event); + } + switch_mutex_lock(node->mutex); + node->caller_count--; + switch_core_hash_delete(node->caller_hash, uuid); + switch_mutex_unlock(node->mutex); } return; @@ -179,31 +246,50 @@ SWITCH_STANDARD_APP(fifo_function) check_string(announce); check_string(moh); - + if (!nowait) { + switch_mutex_lock(node->mutex); + node->consumer_count++; + switch_core_hash_insert(node->consumer_hash, switch_core_session_get_uuid(session), session); + switch_mutex_unlock(node->mutex); switch_channel_answer(channel); } - for (;;) { + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "consumer_start"); + switch_event_fire(&event); + } + + + switch_time_exp_lt(&tm, ts); + switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); + switch_channel_set_variable(channel, "fifo_status", "WAITING"); + switch_channel_set_variable(channel, "fifo_timestamp", date); + + + + while(switch_channel_ready(channel)) { if (moh) { args.read_frame_callback = read_frame_callback; - args.user_data = fifo; + args.user_data = node->fifo; switch_ivr_play_file(session, NULL, moh, &args); } - if (switch_queue_trypop(fifo, &pop) != SWITCH_STATUS_SUCCESS) { + if (switch_queue_trypop(node->fifo, &pop) != SWITCH_STATUS_SUCCESS) { if (nowait) { - return; + break; } status = switch_core_session_read_frame(session, &read_frame, -1, 0); if (!SWITCH_READ_ACCEPTABLE(status)) { - return; + break; } continue; } if (!pop) { - return; + break; } uuid = (char *) pop; @@ -211,20 +297,40 @@ SWITCH_STANDARD_APP(fifo_function) if ((other_session = switch_core_session_locate(uuid))) { switch_channel_t *other_channel = switch_core_session_get_channel(other_session); switch_caller_profile_t *cloned_profile; + + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(other_channel, event); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "caller_pop"); + switch_event_fire(&event); + } + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "consumer_pop"); + switch_event_fire(&event); + } + + if (announce) { switch_ivr_play_file(session, NULL, announce, NULL); } else { switch_ivr_sleep(session, 500); } - switch_channel_clear_flag(other_channel, CF_CONTROLLED); - switch_channel_clear_flag(other_channel, CF_BROADCAST); - switch_channel_set_flag(other_channel, CF_BREAK); - switch_core_session_kill_channel(other_session, SWITCH_SIG_BREAK); - while (switch_channel_test_flag(other_channel, CF_TAGGED)) { - status = switch_core_session_read_frame(session, &read_frame, -1, 0); - if (!SWITCH_READ_ACCEPTABLE(status)) { - break; + + if (switch_channel_test_flag(other_channel, CF_TAGGED)) { + switch_channel_clear_flag(other_channel, CF_CONTROLLED); + switch_channel_clear_flag(other_channel, CF_BROADCAST); + switch_channel_set_flag(other_channel, CF_BREAK); + switch_core_session_kill_channel(other_session, SWITCH_SIG_BREAK); + while (switch_channel_test_flag(other_channel, CF_TAGGED)) { + status = switch_core_session_read_frame(session, &read_frame, -1, 0); + if (!SWITCH_READ_ACCEPTABLE(status)) { + break; + } } } @@ -238,7 +344,29 @@ SWITCH_STANDARD_APP(fifo_function) assert(cloned_profile->next == NULL); switch_channel_set_originatee_caller_profile(channel, cloned_profile); + switch_time_exp_lt(&tm, ts); + switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); + switch_channel_set_variable(channel, "fifo_status", "TALKING"); + switch_channel_set_variable(channel, "fifo_target", uuid); + switch_channel_set_variable(channel, "fifo_timestamp", date); + + switch_channel_set_variable(other_channel, "fifo_status", "TALKING"); + switch_channel_set_variable(other_channel, "fifo_timestamp", date); + switch_channel_set_variable(other_channel, "fifo_target", switch_core_session_get_uuid(session)); switch_ivr_multi_threaded_bridge(session, other_session, on_dtmf, other_session, session); + + switch_time_exp_lt(&tm, ts); + switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); + switch_channel_set_variable(channel, "fifo_status", "WAITING"); + switch_channel_set_variable(channel, "fifo_timestamp", date); + + switch_channel_set_variable(other_channel, "fifo_status", "DONE"); + switch_channel_set_variable(other_channel, "fifo_timestamp", date); + + switch_mutex_lock(node->mutex); + node->caller_count--; + switch_core_hash_delete(node->caller_hash, uuid); + switch_mutex_unlock(node->mutex); switch_core_session_rwunlock(other_session); if (nowait) { done = 1; @@ -251,23 +379,206 @@ SWITCH_STANDARD_APP(fifo_function) break; } } + + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, FIFO_EVENT) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, event); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Name", "%s", argv[0]); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "FIFO-Action", "consumer_stop"); + switch_event_fire(&event); + } + + if (!nowait) { + switch_mutex_lock(node->mutex); + switch_core_hash_delete(node->consumer_hash, switch_core_session_get_uuid(session)); + node->consumer_count--; + switch_mutex_unlock(node->mutex); + } + } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "USAGE %s\n", FIFO_USAGE); } } +static int xml_hash(switch_xml_t xml, switch_hash_t *hash, char *container, char *tag, int cc_off, int verbose) +{ + switch_xml_t x_tmp, x_caller, x_cp, variables; + switch_hash_index_t *hi; + switch_core_session_t *session; + switch_channel_t *channel; + void *val; + const void *var; + + x_tmp = switch_xml_add_child_d(xml, container, cc_off++); + assert(x_tmp); + + for (hi = switch_hash_first(NULL, hash); hi; hi = switch_hash_next(hi)) { + int c_off = 0, d_off = 0; + char *status; + char *ts; + + switch_hash_this(hi, &var, NULL, &val); + session = (switch_core_session_t *) val; + channel = switch_core_session_get_channel(session); + x_caller = switch_xml_add_child_d(x_tmp, tag, c_off++); + assert(x_caller); + + switch_xml_set_attr_d(x_caller, "uuid", switch_core_session_get_uuid(session)); + + if ((status = switch_channel_get_variable(channel, "fifo_status"))) { + switch_xml_set_attr_d(x_caller, "status", status); + } + + if ((ts = switch_channel_get_variable(channel, "fifo_timestamp"))) { + switch_xml_set_attr_d(x_caller, "timestamp", ts); + } + + if ((ts = switch_channel_get_variable(channel, "fifo_target"))) { + switch_xml_set_attr_d(x_caller, "target", ts); + } + + if (!(x_cp = switch_xml_add_child_d(x_caller, "caller_profile", d_off++))) { + abort(); + } + if (verbose) { + d_off += switch_ivr_set_xml_profile_data(x_cp, switch_channel_get_caller_profile(channel), d_off); + + if (!(variables = switch_xml_add_child_d(x_caller, "variables", c_off++))) { + abort(); + } + + switch_ivr_set_xml_chan_vars(variables, channel, c_off); + } + + } + + return cc_off; +} + +static void list_node(fifo_node_t *node, switch_xml_t x_report, int *off, int verbose) +{ + + switch_xml_t x_fifo; + int cc_off = 0; + char tmp[35]; + + x_fifo = switch_xml_add_child_d(x_report, "fifo", (*off)++);; + assert(x_fifo); + + switch_xml_set_attr_d(x_fifo, "name", node->name); + snprintf(tmp, sizeof(tmp), "%d", node->consumer_count); + switch_xml_set_attr_d(x_fifo, "consumer_count", tmp); + snprintf(tmp, sizeof(tmp), "%d", node->caller_count); + switch_xml_set_attr_d(x_fifo, "caller_count", tmp); + + cc_off = xml_hash(x_fifo, node->caller_hash, "callers", "caller", cc_off, verbose); + cc_off = xml_hash(x_fifo, node->consumer_hash, "consumers", "consumer", cc_off, verbose); + +} + +#define FIFO_API_SYNTAX "count " +SWITCH_STANDARD_API(fifo_api_function) +{ + int len = 0; + fifo_node_t *node; + char *data; + int argc = 0; + char *argv[5] = { 0 }; + switch_hash_index_t *hi; + void *val; + const void *var; + int x = 0, verbose = 0; + + if (!switch_strlen_zero(cmd)) { + data = strdup(cmd); + assert(data); + } + + if (switch_strlen_zero(cmd) || (argc = switch_separate_string(data, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) < 1) { + stream->write_function(stream, "%s\n", FIFO_API_SYNTAX); + return SWITCH_STATUS_SUCCESS; + } + + switch_mutex_lock(globals.mutex); + verbose = !strcasecmp(argv[0], "list_verbose"); + + if (!strcasecmp(argv[0], "list") || verbose) { + char *xml_text = NULL; + switch_xml_t x_report = switch_xml_new("fifo_report"); + assert(x_report); + + if (argc < 2) { + for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &var, NULL, &val); + node = (fifo_node_t *) val; + switch_mutex_lock(node->mutex); + list_node(node, x_report, &x, verbose); + switch_mutex_unlock(node->mutex); + } + } else { + if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { + switch_mutex_lock(node->mutex); + list_node(node, x_report, &x, verbose); + switch_mutex_unlock(node->mutex); + } + } + xml_text = switch_xml_toxml(x_report); + assert(xml_text); + stream->write_function(stream, "%s\n", xml_text); + switch_xml_free(x_report); + switch_safe_free(xml_text); + + } else if (!strcasecmp(argv[0], "count")) { + if (argc < 2) { + for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &var, NULL, &val); + node = (fifo_node_t *) val; + len = switch_queue_size(node->fifo); + switch_mutex_lock(node->mutex); + stream->write_function(stream, "%s:%d:%d:%d\n", (char *)var, node->consumer_count, node->caller_count, len); + switch_mutex_unlock(node->mutex); + x++; + } + + if (!x) { + stream->write_function(stream, "none\n"); + } + } else { + if ((node = switch_core_hash_find(globals.fifo_hash, argv[1]))) { + len = switch_queue_size(node->fifo); + } + switch_mutex_lock(node->mutex); + stream->write_function(stream, "%s:%d:%d:%d\n", argv[1], node->consumer_count, node->caller_count, len); + switch_mutex_unlock(node->mutex); + } + } + + switch_mutex_unlock(globals.mutex); + return SWITCH_STATUS_SUCCESS; +} + + SWITCH_MODULE_LOAD_FUNCTION(mod_fifo_load) { switch_application_interface_t *app_interface; + switch_api_interface_t *commands_api_interface; + + + /* create/register custom event message type */ + if (switch_event_reserve_subclass(FIFO_EVENT) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", FIFO_EVENT); + return SWITCH_STATUS_TERM; + } switch_core_new_memory_pool(&globals.pool); switch_core_hash_init(&globals.fifo_hash, globals.pool); + switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool); /* connect my internal structure to the blank pointer passed to me */ *module_interface = switch_loadable_module_create_module_interface(pool, modname); SWITCH_ADD_APP(app_interface, "fifo", "Park with FIFO", FIFO_DESC, fifo_function, FIFO_USAGE, SAF_NONE); - + SWITCH_ADD_API(commands_api_interface, "fifo", "Return data about a fifo", fifo_api_function, FIFO_API_SYNTAX); return SWITCH_STATUS_SUCCESS; } @@ -279,16 +590,19 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_fifo_shutdown) { switch_hash_index_t *hi; void *val, *pop; - switch_queue_t *fifo; - + fifo_node_t *node; + switch_mutex_lock(globals.mutex); /* Cleanup*/ for (hi = switch_hash_first(NULL, globals.fifo_hash); hi; hi = switch_hash_next(hi)) { switch_hash_this(hi, NULL, NULL, &val); - fifo = (switch_queue_t *) val; - while (switch_queue_trypop(fifo, &pop) == SWITCH_STATUS_SUCCESS) { + node = (fifo_node_t *) val; + while (switch_queue_trypop(node->fifo, &pop) == SWITCH_STATUS_SUCCESS) { free(pop); } + switch_core_hash_destroy(&node->caller_hash); + switch_core_hash_destroy(&node->consumer_hash); } + switch_mutex_unlock(globals.mutex); switch_core_hash_destroy(&globals.fifo_hash); switch_core_destroy_memory_pool(&globals.pool); return SWITCH_STATUS_SUCCESS; diff --git a/src/switch_channel.c b/src/switch_channel.c index 373a76cb3d..63920f358b 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -404,11 +404,10 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_variable(switch_channel_t *ch if (!switch_strlen_zero(varname)) { switch_mutex_lock(channel->profile_mutex); + switch_event_del_header(channel->variables, varname); if (value) { switch_event_add_header(channel->variables, SWITCH_STACK_BOTTOM, varname, "%s", value); - } else { - switch_event_del_header(channel->variables, varname); - } + } switch_mutex_unlock(channel->profile_mutex); return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 9362b7110e..9aff836db8 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1206,7 +1206,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_digit_stream_parser_set_terminator(sw return status; } -static int set_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_profile, int off) +SWITCH_DECLARE(int) switch_ivr_set_xml_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_profile, int off) { switch_xml_t param; @@ -1278,14 +1278,43 @@ static int set_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_pr return off; } +SWITCH_DECLARE(int) switch_ivr_set_xml_chan_vars(switch_xml_t xml, switch_channel_t *channel, int off) +{ + switch_event_header_t *hi; + switch_xml_t variable; + + if ((hi = switch_channel_variable_first(channel))) { + for (; hi; hi = hi->next) { + char *vvar = hi->name; + char *vval = hi->value; + if (vvar && vval) { + if ((variable = switch_xml_add_child_d(xml, (char *) vvar, off++))) { + char *data; + char *value = (char *) vval; + switch_size_t dlen = strlen(value) * 3; + + if ((data = malloc(dlen))) { + memset(data, 0, dlen); + switch_url_encode(value, data, dlen); + switch_xml_set_txt_d(variable, data); + free(data); + } + } + } + } + switch_channel_variable_last(channel); + } + + return off; +} + SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_t *session, switch_xml_t * xml_cdr) { switch_channel_t *channel; switch_caller_profile_t *caller_profile; - switch_xml_t variable, variables, cdr, x_main_cp, x_caller_profile, x_caller_extension, x_times, time_tag, + switch_xml_t variables, cdr, x_main_cp, x_caller_profile, x_caller_extension, x_times, time_tag, x_application, x_callflow, x_inner_extension, x_apps, x_o; switch_app_log_t *app_log; - switch_event_header_t *hi; char tmp[512]; int cdr_off = 0, v_off = 0; @@ -1318,27 +1347,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_ } } - - if ((hi = switch_channel_variable_first(channel))) { - for (; hi; hi = hi->next) { - char *vvar = hi->name; - char *vval = hi->value; - if (vvar && vval) { - if ((variable = switch_xml_add_child_d(variables, (char *) vvar, v_off++))) { - char *data; - char *value = (char *) vval; - switch_size_t dlen = strlen(value) * 3; - - if ((data = switch_core_session_alloc(session, dlen))) { - switch_url_encode(value, data, dlen); - switch_xml_set_txt_d(variable, data); - } - } - } - } - switch_channel_variable_last(channel); - } - + switch_ivr_set_xml_chan_vars(variables, channel, v_off); + caller_profile = switch_channel_get_caller_profile(channel); while (caller_profile) { @@ -1419,7 +1429,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_ goto error; } - cp_off += set_profile_data(x_main_cp, caller_profile, 0); + cp_off += switch_ivr_set_xml_profile_data(x_main_cp, caller_profile, 0); if (caller_profile->originator_caller_profile) { switch_caller_profile_t *cp = NULL; @@ -1432,7 +1442,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_ if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originator_caller_profile", off++))) { goto error; } - set_profile_data(x_caller_profile, cp, 0); + switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0); } } @@ -1446,7 +1456,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_ if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originatee_caller_profile", off++))) { goto error; } - set_profile_data(x_caller_profile, caller_profile->originatee_caller_profile, 0); + switch_ivr_set_xml_profile_data(x_caller_profile, caller_profile->originatee_caller_profile, 0); } }