]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add new xml call detail function to the core and a way to use it from javascript
authorAnthony Minessale <anthony.minessale@gmail.com>
Wed, 14 Feb 2007 15:19:01 +0000 (15:19 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Wed, 14 Feb 2007 15:19:01 +0000 (15:19 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4257 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/include/switch_ivr.h
src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
src/switch_ivr.c

index 5712d7af8a1677e72e27c21b15eaf7a7c8e1d7e5..2dbb9919fbc220ce254771f4d6ae0768a11b09aa 100644 (file)
@@ -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
index c8e63c332f026513bbf999f945e186e71e65d073..3adf4eac57b35a2a7b44a8229cfc2bfe78a5ea74 100644 (file)
@@ -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}, 
index 4a25b291ec287202281749b05b9e7165a89cfb0a..a0c5b29136ed474427c08098f7a7cd84b9beed70 100644 (file)
@@ -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