add bridged timestamp and hangup_complete_with_xml=true to add xml_cdr to the body of hangup_complete events
This commit is contained in:
parent
a391d82b57
commit
bd471fc6a9
|
@ -49,6 +49,7 @@ SWITCH_BEGIN_EXTERN_C struct switch_channel_timetable {
|
|||
switch_time_t hungup;
|
||||
switch_time_t transferred;
|
||||
switch_time_t resurrected;
|
||||
switch_time_t bridged;
|
||||
struct switch_channel_timetable *next;
|
||||
};
|
||||
|
||||
|
@ -597,7 +598,7 @@ SWITCH_DECLARE(int) switch_channel_test_app_flag_key(const char *app, switch_cha
|
|||
#define switch_channel_clear_app_flag(_c, _f) switch_channel_clear_app_flag_key(__FILE__, _c, _f)
|
||||
#define switch_channel_test_app_flag(_c, _f) switch_channel_test_app_flag_key(__FILE__, _c, _f)
|
||||
|
||||
|
||||
SWITCH_DECLARE(void) switch_channel_set_bridge_time(switch_channel_t *channel);
|
||||
SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel);
|
||||
SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_t *channel);
|
||||
SWITCH_DECLARE(switch_core_session_t *) switch_channel_get_session(switch_channel_t *channel);
|
||||
|
|
|
@ -239,20 +239,23 @@ SWITCH_DECLARE(switch_size_t) switch_fd_read_line(int fd, char *buf, switch_size
|
|||
SWITCH_DECLARE(switch_status_t) switch_frame_alloc(switch_frame_t **frame, switch_size_t size);
|
||||
SWITCH_DECLARE(switch_status_t) switch_frame_dup(switch_frame_t *orig, switch_frame_t **clone);
|
||||
SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame);
|
||||
SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
|
||||
|
||||
/*!
|
||||
\brief Evaluate the truthfullness of a string expression
|
||||
\param expr a string expression
|
||||
\return true or false
|
||||
*/
|
||||
#define switch_true(expr)\
|
||||
((expr && ( !strcasecmp(expr, "yes") ||\
|
||||
!strcasecmp(expr, "on") ||\
|
||||
!strcasecmp(expr, "true") ||\
|
||||
!strcasecmp(expr, "enabled") ||\
|
||||
!strcasecmp(expr, "active") ||\
|
||||
!strcasecmp(expr, "allow") ||\
|
||||
(switch_is_number(expr) && atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE)
|
||||
static inline int switch_true(const char *expr)
|
||||
{
|
||||
return ((expr && ( !strcasecmp(expr, "yes") ||
|
||||
!strcasecmp(expr, "on") ||
|
||||
!strcasecmp(expr, "true") ||
|
||||
!strcasecmp(expr, "enabled") ||
|
||||
!strcasecmp(expr, "active") ||
|
||||
!strcasecmp(expr, "allow") ||
|
||||
(switch_is_number(expr) && atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE);
|
||||
}
|
||||
|
||||
#define switch_true_buf(expr)\
|
||||
((( !strcasecmp(expr, "yes") ||\
|
||||
|
@ -268,14 +271,16 @@ SWITCH_DECLARE(switch_status_t) switch_frame_free(switch_frame_t **frame);
|
|||
\param expr a string expression
|
||||
\return true or false
|
||||
*/
|
||||
#define switch_false(expr)\
|
||||
((expr && ( !strcasecmp(expr, "no") ||\
|
||||
!strcasecmp(expr, "off") ||\
|
||||
!strcasecmp(expr, "false") ||\
|
||||
!strcasecmp(expr, "disabled") ||\
|
||||
!strcasecmp(expr, "inactive") ||\
|
||||
!strcasecmp(expr, "disallow") ||\
|
||||
(switch_is_number(expr) && !atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE)
|
||||
static inline int switch_false(const char *expr)
|
||||
{
|
||||
return ((expr && ( !strcasecmp(expr, "no") ||
|
||||
!strcasecmp(expr, "off") ||
|
||||
!strcasecmp(expr, "false") ||
|
||||
!strcasecmp(expr, "disabled") ||
|
||||
!strcasecmp(expr, "inactive") ||
|
||||
!strcasecmp(expr, "disallow") ||
|
||||
(switch_is_number(expr) && !atoi(expr)))) ? SWITCH_TRUE : SWITCH_FALSE);
|
||||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_resolve_host(const char *host, char *buf, size_t buflen);
|
||||
|
@ -670,7 +675,7 @@ SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in);
|
|||
SWITCH_DECLARE(unsigned int) switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen);
|
||||
SWITCH_DECLARE(unsigned int) switch_separate_string_string(char *buf, char *delim, _Post_count_(return) char **array, unsigned int arraylen);
|
||||
|
||||
SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str);
|
||||
|
||||
SWITCH_DECLARE(char *) switch_strip_spaces(char *str, switch_bool_t dup);
|
||||
SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str);
|
||||
SWITCH_DECLARE(char *) switch_strip_commas(char *in, char *out, switch_size_t len);
|
||||
|
|
|
@ -2513,11 +2513,21 @@ SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_caller_extension(
|
|||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(void) switch_channel_set_bridge_time(switch_channel_t *channel)
|
||||
{
|
||||
switch_mutex_lock(channel->profile_mutex);
|
||||
if (channel->caller_profile && channel->caller_profile->times) {
|
||||
channel->caller_profile->times->bridged = switch_micro_time_now();
|
||||
}
|
||||
switch_mutex_unlock(channel->profile_mutex);
|
||||
}
|
||||
|
||||
|
||||
SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel)
|
||||
{
|
||||
if (channel->caller_profile && channel->caller_profile->times && !channel->caller_profile->times->hungup) {
|
||||
if (channel->caller_profile && channel->caller_profile->times && !channel->caller_profile->times->bridged) {
|
||||
switch_mutex_lock(channel->profile_mutex);
|
||||
channel->caller_profile->times->hungup = switch_micro_time_now();
|
||||
channel->caller_profile->times->bridged = switch_micro_time_now();
|
||||
switch_mutex_unlock(channel->profile_mutex);
|
||||
}
|
||||
}
|
||||
|
@ -3348,14 +3358,14 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *
|
|||
switch_caller_profile_t *caller_profile, *ocp;
|
||||
switch_app_log_t *app_log, *ap;
|
||||
char *last_app = NULL, *last_arg = NULL;
|
||||
char start[80] = "", resurrect[80] = "", answer[80] = "", progress[80] = "", progress_media[80] = "", end[80] = "", tmp[80] = "",
|
||||
char start[80] = "", resurrect[80] = "", answer[80] = "", bridge[80] = "", progress[80] = "", progress_media[80] = "", end[80] = "", tmp[80] = "",
|
||||
profile_start[80] = "";
|
||||
int32_t duration = 0, legbillsec = 0, billsec = 0, mduration = 0, billmsec = 0, legbillmsec = 0, progressmsec = 0, progress_mediamsec = 0;
|
||||
int32_t answersec = 0, answermsec = 0;
|
||||
int32_t answersec = 0, answermsec = 0, waitsec = 0, waitmsec = 0;
|
||||
switch_time_t answerusec = 0;
|
||||
switch_time_t uduration = 0, legbillusec = 0, billusec = 0, progresssec = 0, progressusec = 0, progress_mediasec = 0, progress_mediausec = 0;
|
||||
time_t tt_created = 0, tt_answered = 0, tt_resurrected = 0,
|
||||
tt_progress = 0, tt_progress_media = 0, tt_hungup = 0, mtt_created = 0, mtt_answered = 0,
|
||||
switch_time_t uduration = 0, legbillusec = 0, billusec = 0, progresssec = 0, progressusec = 0, progress_mediasec = 0, progress_mediausec = 0, waitusec = 0;
|
||||
time_t tt_created = 0, tt_answered = 0, tt_resurrected = 0, tt_bridged,
|
||||
tt_progress = 0, tt_progress_media = 0, tt_hungup = 0, mtt_created = 0, mtt_answered = 0, mtt_bridged = 0,
|
||||
mtt_hungup = 0, tt_prof_created, mtt_prof_created, mtt_progress = 0, mtt_progress_media = 0;
|
||||
void *pop;
|
||||
char dtstr[SWITCH_DTMF_LOG_LEN + 1] = "";
|
||||
|
@ -3427,6 +3437,12 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *
|
|||
switch_channel_set_variable(channel, "answer_stamp", answer);
|
||||
}
|
||||
|
||||
if (caller_profile->times->bridged) {
|
||||
switch_time_exp_lt(&tm, caller_profile->times->bridged);
|
||||
switch_strftime_nocheck(bridge, &retsize, sizeof(bridge), fmt, &tm);
|
||||
switch_channel_set_variable(channel, "bridge_stamp", bridge);
|
||||
}
|
||||
|
||||
if (caller_profile->times->resurrected) {
|
||||
switch_time_exp_lt(&tm, caller_profile->times->resurrected);
|
||||
switch_strftime_nocheck(resurrect, &retsize, sizeof(resurrect), fmt, &tm);
|
||||
|
@ -3470,6 +3486,13 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *
|
|||
switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered);
|
||||
switch_channel_set_variable(channel, "answer_uepoch", tmp);
|
||||
|
||||
tt_bridged = (time_t) (caller_profile->times->bridged / 1000000);
|
||||
mtt_bridged = (time_t) (caller_profile->times->bridged / 1000);
|
||||
switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_bridged);
|
||||
switch_channel_set_variable(channel, "bridge_epoch", tmp);
|
||||
switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->bridged);
|
||||
switch_channel_set_variable(channel, "bridge_uepoch", tmp);
|
||||
|
||||
tt_resurrected = (time_t) (caller_profile->times->resurrected / 1000000);
|
||||
switch_snprintf(tmp, sizeof(tmp), "%" TIME_T_FMT, tt_resurrected);
|
||||
switch_channel_set_variable(channel, "resurrect_epoch", tmp);
|
||||
|
@ -3501,6 +3524,16 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *
|
|||
mduration = (int32_t) (mtt_hungup - mtt_created);
|
||||
uduration = caller_profile->times->hungup - caller_profile->times->created;
|
||||
|
||||
if (caller_profile->times->bridged > caller_profile->times->created) {
|
||||
waitsec = (int32_t) (tt_bridged - tt_created);
|
||||
waitmsec = (int32_t) (mtt_bridged - mtt_created);
|
||||
waitusec = caller_profile->times->bridged - caller_profile->times->created;
|
||||
} else {
|
||||
waitsec = 0;
|
||||
waitmsec = 0;
|
||||
waitusec = 0;
|
||||
}
|
||||
|
||||
if (caller_profile->times->answered) {
|
||||
billsec = (int32_t) (tt_hungup - tt_answered);
|
||||
billmsec = (int32_t) (mtt_hungup - mtt_answered);
|
||||
|
@ -3545,6 +3578,9 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *
|
|||
switch_snprintf(tmp, sizeof(tmp), "%d", answersec);
|
||||
switch_channel_set_variable(channel, "answersec", tmp);
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", waitsec);
|
||||
switch_channel_set_variable(channel, "waitsec", tmp);
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", progress_mediasec);
|
||||
switch_channel_set_variable(channel, "progress_mediasec", tmp);
|
||||
|
||||
|
@ -3563,6 +3599,9 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *
|
|||
switch_snprintf(tmp, sizeof(tmp), "%d", answermsec);
|
||||
switch_channel_set_variable(channel, "answermsec", tmp);
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", waitmsec);
|
||||
switch_channel_set_variable(channel, "waitmsec", tmp);
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%d", progress_mediamsec);
|
||||
switch_channel_set_variable(channel, "progress_mediamsec", tmp);
|
||||
|
||||
|
@ -3581,6 +3620,9 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *
|
|||
switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, answerusec);
|
||||
switch_channel_set_variable(channel, "answerusec", tmp);
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, waitusec);
|
||||
switch_channel_set_variable(channel, "waitusec", tmp);
|
||||
|
||||
switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, progress_mediausec);
|
||||
switch_channel_set_variable(channel, "progress_mediausec", tmp);
|
||||
|
||||
|
|
|
@ -636,6 +636,18 @@ SWITCH_DECLARE(void) switch_core_session_reporting_state(switch_core_session_t *
|
|||
if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hangup-Cause", switch_channel_cause2str(cause));
|
||||
switch_channel_event_set_data(session->channel, event);
|
||||
if (switch_true(switch_channel_get_variable(session->channel, "hangup_complete_with_xml"))) {
|
||||
switch_xml_t cdr = NULL;
|
||||
char *xml_cdr_text;
|
||||
|
||||
if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {
|
||||
xml_cdr_text = switch_xml_toxml(cdr, SWITCH_FALSE);
|
||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "CDR-Attached", "xml");
|
||||
switch_event_add_body(event, "%s", xml_cdr_text);
|
||||
switch_xml_free(cdr);
|
||||
switch_safe_free(xml_cdr_text);
|
||||
}
|
||||
}
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
|
||||
|
|
|
@ -2219,6 +2219,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_
|
|||
switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered);
|
||||
switch_xml_set_txt_d(time_tag, tmp);
|
||||
|
||||
if (!(time_tag = switch_xml_add_child_d(x_times, "bridged_time", t_off++))) {
|
||||
goto error;
|
||||
}
|
||||
switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->bridged);
|
||||
switch_xml_set_txt_d(time_tag, tmp);
|
||||
|
||||
if (!(time_tag = switch_xml_add_child_d(x_times, "hangup_time", t_off++))) {
|
||||
goto error;
|
||||
}
|
||||
|
|
|
@ -201,7 +201,9 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
|
|||
|
||||
chan_a = switch_core_session_get_channel(session_a);
|
||||
chan_b = switch_core_session_get_channel(session_b);
|
||||
|
||||
|
||||
switch_channel_set_bridge_time(chan_a);
|
||||
|
||||
if ((exec_app = switch_channel_get_variable(chan_a, "bridge_pre_execute_app"))) {
|
||||
exec_data = switch_channel_get_variable(chan_a, "bridge_pre_execute_data");
|
||||
}
|
||||
|
@ -1067,6 +1069,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_signal_bridge(switch_core_session_t *
|
|||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(session));
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
|
||||
switch_channel_set_bridge_time(caller_channel);
|
||||
switch_channel_set_bridge_time(peer_channel);
|
||||
|
||||
switch_channel_set_state_flag(caller_channel, CF_RESET);
|
||||
switch_channel_set_state_flag(peer_channel, CF_RESET);
|
||||
|
|
Loading…
Reference in New Issue