add new xml call detail function to the core and a way to use it from javascript
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4257 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
b0901fe4ce
commit
fdac4282b6
|
@ -52,6 +52,15 @@ SWITCH_BEGIN_EXTERN_C
|
|||
*/
|
||||
|
||||
|
||||
/*!
|
||||
\brief Generate an XML CDR report.
|
||||
\param session the session to get the data from.
|
||||
\param xml_cdr pointer to the xml_record
|
||||
\return SWITCH_STATUS_SUCCESS if successful
|
||||
\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);
|
||||
|
||||
/*!
|
||||
\brief Parse command from an event
|
||||
\param session the session to send the message to
|
||||
|
|
|
@ -1340,6 +1340,27 @@ static JSBool session_answer(JSContext *cx, JSObject *obj, uintN argc, jsval *ar
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static JSBool session_cdr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
struct js_session *jss = JS_GetPrivate(cx, obj);
|
||||
switch_xml_t cdr;
|
||||
|
||||
/*Always a pessimist... sheesh!*/
|
||||
*rval = BOOLEAN_TO_JSVAL( JS_FALSE );
|
||||
|
||||
if (switch_ivr_generate_xml_cdr(jss->session, &cdr) == SWITCH_STATUS_SUCCESS) {
|
||||
char *xml_text;
|
||||
if ((xml_text = switch_xml_toxml(cdr))) {
|
||||
*rval = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, xml_text));
|
||||
}
|
||||
switch_safe_free(xml_text);
|
||||
switch_xml_free(cdr);
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool session_ready(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
struct js_session *jss = JS_GetPrivate(cx, obj);
|
||||
|
@ -1716,6 +1737,7 @@ static JSFunctionSpec session_methods[] = {
|
|||
{"getVariable", session_get_variable, 1},
|
||||
{"getDigits", session_get_digits, 1},
|
||||
{"answer", session_answer, 0},
|
||||
{"generateXmlCdr", session_cdr, 0},
|
||||
{"ready", session_ready, 0},
|
||||
{"waitForAnswer", session_wait_for_answer, 0},
|
||||
{"waitForMedia", session_wait_for_media, 0},
|
||||
|
|
211
src/switch_ivr.c
211
src/switch_ivr.c
|
@ -4833,6 +4833,217 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *s
|
|||
}
|
||||
|
||||
|
||||
static int set_profile_data(switch_xml_t xml, switch_caller_profile_t *caller_profile, int off)
|
||||
{
|
||||
switch_xml_t param;
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "username", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->username);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "dialplan", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->dialplan);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "caller_id_name", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->caller_id_name);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "ani", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->ani);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "aniii", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->aniii);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "caller_id_number", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->caller_id_number);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "network_addr", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->network_addr);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "rdnis", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->rdnis);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "destination_number", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->destination_number);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "uuid", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->uuid);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "source", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->source);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "context", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->context);
|
||||
|
||||
if (!(param = switch_xml_add_child_d(xml, "chan_name", off++))) {
|
||||
return -1;
|
||||
}
|
||||
switch_xml_set_txt(param, caller_profile->chan_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_hash_index_t *hi;
|
||||
void *vval;
|
||||
const void *vvar;
|
||||
switch_xml_t variable,
|
||||
variables,
|
||||
cdr,
|
||||
x_caller_profile,
|
||||
x_caller_extension,
|
||||
x_times,
|
||||
x_application,
|
||||
x_callflow;
|
||||
char tmp[512];
|
||||
int cdr_off = 0, v_off = 0;
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
assert(channel != NULL);
|
||||
|
||||
if (!(cdr = switch_xml_new("cdr"))) {
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!(variables = switch_xml_add_child_d(cdr, "variables", cdr_off++))) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (hi = switch_channel_variable_first(channel, switch_core_session_get_pool(session)); hi; hi = switch_hash_next(hi)) {
|
||||
switch_hash_this(hi, &vvar, NULL, &vval);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
caller_profile = switch_channel_get_caller_profile(channel);
|
||||
|
||||
while (caller_profile) {
|
||||
int cf_off = 0;
|
||||
|
||||
if (!(x_callflow = switch_xml_add_child_d(cdr, "callflow", cdr_off++))) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (caller_profile->caller_extension) {
|
||||
switch_caller_application_t *ap;
|
||||
|
||||
if (!(x_caller_extension = switch_xml_add_child_d(x_callflow, "extension", cf_off++))) {
|
||||
goto error;
|
||||
}
|
||||
switch_xml_set_attr_d(x_caller_extension, "name", caller_profile->caller_extension->extension_name);
|
||||
switch_xml_set_attr_d(x_caller_extension, "number", caller_profile->caller_extension->extension_number);
|
||||
if (caller_profile->caller_extension->current_application) {
|
||||
switch_xml_set_attr_d(x_caller_extension, "current_app", caller_profile->caller_extension->current_application->application_name);
|
||||
}
|
||||
|
||||
for(ap = caller_profile->caller_extension->applications; ap; ap = ap->next) {
|
||||
if (!(x_application = switch_xml_add_child_d(x_callflow, "application", cf_off++))) {
|
||||
goto error;
|
||||
}
|
||||
switch_xml_set_attr_d(x_application, "app_name", ap->application_name);
|
||||
switch_xml_set_attr_d(x_application, "app_data", ap->application_data);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(x_caller_profile = switch_xml_add_child_d(x_callflow, "caller_profile", cf_off++))) {
|
||||
goto error;
|
||||
}
|
||||
set_profile_data(x_caller_profile, caller_profile, 0);
|
||||
|
||||
if (caller_profile->originator_caller_profile) {
|
||||
if (!(x_caller_profile = switch_xml_add_child_d(x_callflow, "originator_caller_profile", cf_off++))) {
|
||||
goto error;
|
||||
}
|
||||
set_profile_data(x_caller_profile, caller_profile->originator_caller_profile, 0);
|
||||
}
|
||||
|
||||
if (caller_profile->originatee_caller_profile) {
|
||||
if (!(x_caller_profile = switch_xml_add_child_d(x_callflow, "originatee_caller_profile", cf_off++))) {
|
||||
goto error;
|
||||
}
|
||||
set_profile_data(x_caller_profile, caller_profile->originatee_caller_profile, 0);
|
||||
}
|
||||
|
||||
|
||||
if (caller_profile->times) {
|
||||
if (!(x_times = switch_xml_add_child_d(x_callflow, "created_time", cf_off++))) {
|
||||
goto error;
|
||||
}
|
||||
snprintf(tmp, sizeof(tmp), "%"APR_TIME_T_FMT, caller_profile->times->created);
|
||||
switch_xml_set_txt_d(x_times, tmp);
|
||||
|
||||
if (!(x_times = switch_xml_add_child_d(x_callflow, "answered_time", cf_off++))) {
|
||||
goto error;
|
||||
}
|
||||
snprintf(tmp, sizeof(tmp), "%"APR_TIME_T_FMT, caller_profile->times->answered);
|
||||
switch_xml_set_txt_d(x_times, tmp);
|
||||
|
||||
if (!(x_times = switch_xml_add_child_d(x_callflow, "hangup_time", cf_off++))) {
|
||||
goto error;
|
||||
}
|
||||
snprintf(tmp, sizeof(tmp), "%"APR_TIME_T_FMT, caller_profile->times->hungup);
|
||||
switch_xml_set_txt_d(x_times, tmp);
|
||||
|
||||
if (!(x_times = switch_xml_add_child_d(x_callflow, "transfer_time", cf_off++))) {
|
||||
goto error;
|
||||
}
|
||||
snprintf(tmp, sizeof(tmp), "%"APR_TIME_T_FMT, caller_profile->times->transferred);
|
||||
switch_xml_set_txt_d(x_times, tmp);
|
||||
}
|
||||
|
||||
caller_profile = caller_profile->next;
|
||||
}
|
||||
|
||||
*xml_cdr = cdr;
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
error:
|
||||
|
||||
if (cdr) {
|
||||
switch_xml_free(cdr);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
|
Loading…
Reference in New Issue