[Freeswitch-svn] [commit] r5530 - freeswitch/trunk/scripts/contrib/trixter
Freeswitch SVN
trixter at freeswitch.org
Thu Jul 12 00:51:34 EDT 2007
Author: trixter
Date: Thu Jul 12 00:51:34 2007
New Revision: 5530
Added:
freeswitch/trunk/scripts/contrib/trixter/mod_xml_cdr.c
Log:
this is a replacement until other patches can be applied, it contains all my current patches to fix various things
Added: freeswitch/trunk/scripts/contrib/trixter/mod_xml_cdr.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/contrib/trixter/mod_xml_cdr.c Thu Jul 12 00:51:34 2007
@@ -0,0 +1,284 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct at yahoo.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthmct at yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Brian West <brian.west at mac.com>
+ * Bret McDanel <trixter AT 0xdecafbad.com>
+ *
+ * mod_xml_cdr.c -- XML CDR Module to files or curl
+ *
+ */
+#include <sys/stat.h>
+#include <switch.h>
+#include <curl/curl.h>
+
+static struct {
+ char *cred;
+ char *url;
+ char *logDir;
+ char *errLogDir;
+ uint32_t delay;
+ uint32_t retries;
+ uint32_t shutdown;
+} globals;
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_xml_cdr_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_cdr_shutdown);
+SWITCH_MODULE_DEFINITION(mod_xml_cdr, mod_xml_cdr_load, NULL, NULL);
+
+/* this function would have access to the HTML returned by the webserver, we dont need it
+ * and the default curl activity is to print to stdout, something not as desirable
+ * so we have a dummy function here
+ */
+static void httpCallBack()
+{
+ return;
+}
+
+static switch_status_t my_on_hangup(switch_core_session_t *session)
+{
+ switch_xml_t cdr;
+ char *xml_text;
+ char *path;
+ int fd = -1;
+ uint32_t curTry;
+ long httpRes;
+ CURL *curl_handle = NULL;
+ char *curl_xml_text;
+ char *logdir;
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ int i;
+
+ if (switch_ivr_generate_xml_cdr(session, &cdr) == SWITCH_STATUS_SUCCESS) {
+
+ /* build the XML */
+ if(!(xml_text = switch_mprintf("<?xml version=\"1.0\"?>\n%s",switch_xml_toxml(cdr)) )) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ /* do we log to the disk no matter what? */
+ /* all previous functionality is retained */
+
+ if (!(logdir = switch_channel_get_variable(channel, "xml_cdr_base"))) {
+ logdir = globals.logDir;
+ }
+
+ if(!switch_strlen_zero(logdir)) {
+ if ((path = switch_mprintf("%s/xml_cdr/%s.cdr.xml", logdir, switch_core_session_get_uuid(session)))) {
+ if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
+ write(fd, xml_text, (unsigned) strlen(xml_text));
+ close(fd);
+ fd = -1;
+ } else {
+ char ebuf[512] = { 0 };
+#ifdef WIN32
+ strerror_s(ebuf, sizeof(ebuf), errno);
+#else
+ strerror_r(errno, ebuf, sizeof(ebuf));
+#endif
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error![%s]\n", ebuf);
+ }
+ free(path);
+ }
+ }
+
+ /* try to post it to the web server */
+ if(!switch_strlen_zero(globals.url)) {
+ curl_handle = curl_easy_init();
+ if(!(curl_xml_text = switch_mprintf("cdr=%s",xml_text) )) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+ free(xml_text);
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (!switch_strlen_zero(globals.cred)) {
+ curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+ curl_easy_setopt(curl_handle, CURLOPT_USERPWD, globals.cred);
+ }
+
+ curl_easy_setopt(curl_handle, CURLOPT_POST, 1);
+ curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, curl_xml_text);
+ curl_easy_setopt(curl_handle, CURLOPT_URL, globals.url);
+ curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-xml/1.0");
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, httpCallBack);
+
+
+ /* these were used for testing, optionally they may be enabled if someone desires
+ curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 120); // tcp timeout
+ curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); // 302 recursion level
+ */
+
+ for(curTry=0;curTry<=globals.retries;curTry++) {
+ curl_easy_perform(curl_handle);
+ curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE,&httpRes);
+ if(httpRes==200) {
+ curl_easy_cleanup(curl_handle);
+ free(curl_xml_text);
+ free(xml_text);
+ return SWITCH_STATUS_SUCCESS;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Got error [%ld] posting to web server\n",httpRes);
+ }
+
+ /* make sure we dont sleep on the last try */
+ for(i=0;i<globals.delay && (curTry != (globals.retries));i++) {
+ switch_sleep(1000);
+ if(globals.shutdown) {
+ /* we are shutting down so dont try to webpost any more */
+ i=globals.delay;
+ curTry=globals.retries;
+ }
+ }
+
+ }
+ free(curl_xml_text);
+ curl_easy_cleanup(curl_handle);
+
+ /* if we are here the web post failed for some reason */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to post to web server, writing to file\n");
+
+ if ((path = switch_mprintf("%s/%s.cdr.xml", globals.errLogDir, switch_core_session_get_uuid(session)))) {
+ if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
+ write(fd, xml_text, (unsigned) strlen(xml_text));
+ close(fd);
+ fd = -1;
+ } else {
+ char ebuf[512] = { 0 };
+#ifdef WIN32
+ strerror_s(ebuf, sizeof(ebuf), errno);
+#else
+ strerror_r(errno, ebuf, sizeof(ebuf));
+#endif
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error![%s]\n", ebuf);
+ }
+ free(path);
+ }
+ }
+ free(xml_text);
+ switch_xml_free(cdr);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Generating Data!\n");
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+static switch_state_handler_table_t state_handlers = {
+ /*.on_init */ NULL,
+ /*.on_ring */ NULL,
+ /*.on_execute */ NULL,
+ /*.on_hangup */ my_on_hangup,
+ /*.on_loopback */ NULL,
+ /*.on_transmit */ NULL
+};
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_xml_cdr_load)
+{
+ char *cf = "xml_cdr.conf";
+ switch_xml_t cfg, xml, settings, param;
+
+
+ /* test global state handlers */
+ switch_core_add_state_handler(&state_handlers);
+
+ *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+
+ memset(&globals,0,sizeof(globals));
+
+ /* parse the config */
+ if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
+ return SWITCH_STATUS_TERM;
+ }
+
+ if ((settings = switch_xml_child(cfg, "settings"))) {
+ for (param = switch_xml_child(settings, "param"); param; param = param->next) {
+ char *var = (char *) switch_xml_attr_soft(param, "name");
+ char *val = (char *) switch_xml_attr_soft(param, "value");
+
+ if (!strcasecmp(var, "cred")) {
+ globals.cred = val;
+ } else if (!strcasecmp(var, "url")) {
+ globals.url = val;
+ } else if (!strcasecmp(var, "delay")) {
+ globals.delay = (uint32_t) atoi(val);
+ } else if (!strcasecmp(var, "retries")) {
+ globals.retries = (uint32_t) atoi(val);
+ } else if (!strcasecmp(var, "logDir")) {
+ if (switch_strlen_zero(val)) {
+ globals.logDir = SWITCH_GLOBAL_dirs.log_dir;
+ } else {
+ globals.logDir = val;
+ }
+ } else if (!strcasecmp(var, "errLogDir")) {
+ globals.errLogDir = val;
+ }
+
+ }
+ }
+ if(globals.retries < 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "retries is negative, setting to 0\n");
+ globals.retries = 0;
+ }
+
+
+ if(globals.retries && globals.delay<=0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "retries set but delay 0 setting to 5000ms\n");
+ globals.delay = 5000;
+ }
+
+ if(!switch_strlen_zero(globals.url) && switch_strlen_zero(globals.errLogDir)) {
+ if (!(globals.errLogDir = switch_mprintf("%s/xml_cdr", SWITCH_GLOBAL_dirs.log_dir))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+ return SWITCH_STATUS_FALSE;
+ }
+ }
+
+
+ /* indicate that the module should continue to be loaded */
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_cdr_shutdown)
+{
+
+ globals.shutdown=1;
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
+ */
More information about the Freeswitch-svn
mailing list