[Freeswitch-branches] [commit] r4020 - freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr

Freeswitch SVN mishehu at freeswitch.org
Mon Jan 22 16:41:06 EST 2007


Author: mishehu
Date: Mon Jan 22 16:41:06 2007
New Revision: 4020

Added:
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/curlcdr.cpp
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/curlcdr.h
Modified:
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/Makefile
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/basecdr.cpp
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/basecdr.h
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/pddcdr.cpp
   freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/pddcdr.h

Log:
Added in Bret's curlcdr.h/cpp files, made a change in BaseCDR for escaping the strings, added in the ability to adjust the timestamps for SqliteCDR so that you can log according to lt or utc.

Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/Makefile
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/Makefile	(original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/Makefile	Mon Jan 22 16:41:06 2007
@@ -2,6 +2,7 @@
 CFLAGS  += $(shell mysql_config --include) 
 CFLAGS  += -DSWITCH_QUEUE_ENHANCED
 LDFLAGS += $(shell mysql_config --libs)
+#LDFLAGS += -lcurl
 
 CPPCC = g++
 OBJS=cdrcontainer.o basecdr.o baseregistry.o mysqlcdr.o pddcdr.o csvcdr.o xmlcdr.o

Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/basecdr.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/basecdr.cpp	(original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/basecdr.cpp	Mon Jan 22 16:41:06 2007
@@ -377,6 +377,35 @@
 	}
 }
 
+void BaseCDR::escape_string(std::string& src)
+{
+	std::string::size_type pos = 0;
+	
+	// find all occurences of ' and replace them with \'
+	while ( ( pos = src.find( "'", pos ) ) != std::string::npos ) 
+	{
+		src.replace( pos, 1, "\\'" );
+		pos += 2;
+	}
+}
+
+std::string BaseCDR::escape_chararray(char* src)
+{
+	std::string src_string = src;
+	
+	std::string::size_type pos = 0;
+	
+	// find all occurences of ' and replace them with \'
+	while ( ( pos = src_string.find( "'", pos ) ) != std::string::npos ) 
+	{
+		src_string.replace( pos, 1, "\\'" );
+		pos += 2;
+	}
+	
+	return src_string;
+}
+
+
 /* For Emacs:
  * Local Variables:
  * mode:c++

Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/basecdr.h
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/basecdr.h	(original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/basecdr.h	Mon Jan 22 16:41:06 2007
@@ -84,6 +84,8 @@
 		void parse_channel_variables_xconfig(std::string& unparsed,std::list<std::string>& chanvarslist,std::vector<switch_mod_cdr_sql_types_t>& chanvars_fixed_types);  // Typically used for SQL types
 		void process_channel_variables(const std::list<std::string>& stringlist,const std::list<std::string>& fixedlist,switch_channel_t *channel,bool repeat = 1); //This is used for supplemental chanvars
 		void process_channel_variables(const std::list<std::string>& stringlist,switch_channel_t *channel); // This is used for fixed chanvars
+		void escape_string(std::string& src);
+		std::string escape_chararray(char* src);
 		switch_time_t callstartdate;
 		switch_time_t callanswerdate;
 		switch_time_t callenddate;

Added: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/curlcdr.cpp
==============================================================================
--- (empty file)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/curlcdr.cpp	Mon Jan 22 16:41:06 2007
@@ -0,0 +1,384 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application Call Detail Recorder module
+ * Copyright 2006, Author: Yossi Neiman of Cartis Solutions, Inc. <freeswitch AT cartissolutions.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 Call Detail Recorder module
+ *
+ * This code is largely derived from csvcdr.cpp with minor code snippets from mod_xml_curl.c and edited by 
+ * Bret McDanel <trixter AT 0xdecafbad.com>
+ * The Initial Developer of the Original Code is
+ * Yossi Neiman <freeswitch AT cartissolutions.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Yossi Neiman <freeswitch AT cartissolutions.com>
+ * Bret McDanel <trixter AT 0xdecafbad.com>
+ * Anthony Minessale II <anthmct at yahoo.com>
+ *
+ * Description: This C++ source file describes the CurlCDR class that handles processing CDRs to HTTP endpoint.
+ * This is the standard Curl module, and has a list of predefined variables to log out which can be
+ * added to, but never have the default ones removed.  If you want to use one that allows you to explicity
+ * set all data variables to be logged and in what order, then this is not the class you want to use, and
+ * one will be coming in the future to do just that.
+ *
+ * curlcdr.cpp
+ *
+ */
+
+#include <switch.h>
+#include "curlcdr.h"
+#include <string>
+#include <curl/curl.h>
+
+
+CurlCDR::CurlCDR() : BaseCDR()
+{
+	memset(formattedcallstartdate,0,100);
+	memset(formattedcallanswerdate,0,100);
+	memset(formattedcallenddate,0,100);
+}
+
+CurlCDR::CurlCDR(switch_mod_cdr_newchannel_t *newchannel) : BaseCDR(newchannel)
+{
+	memset(formattedcallstartdate,0,100);
+	memset(formattedcallanswerdate,0,100);
+	memset(formattedcalltransferdate,0,100);
+	memset(formattedcallenddate,0,100);
+	
+	if(newchannel != 0)
+	{
+		switch_time_exp_t tempcallstart, tempcallanswer, tempcalltransfer, tempcallend;
+		memset(&tempcallstart,0,sizeof(tempcallstart));
+		memset(&tempcalltransfer,0,sizeof(tempcalltransfer));
+		memset(&tempcallanswer,0,sizeof(tempcallanswer));
+		memset(&tempcallend,0,sizeof(tempcallend));
+		convert_time(&tempcallstart, callstartdate);
+		convert_time(&tempcallanswer, callanswerdate);
+		convert_time(&tempcalltransfer, calltransferdate);
+		convert_time(&tempcallend, callenddate);
+		
+		// Format the times
+		apr_size_t retsizecsd, retsizecad, retsizectd, retsizeced;  //csd == callstartdate, cad == callanswerdate, ced == callenddate, ceff == callenddate_forfile
+		char format[] = "%Y-%m-%d %H:%M:%S";
+		switch_strftime(formattedcallstartdate,&retsizecsd,sizeof(formattedcallstartdate),format,&tempcallstart);
+		switch_strftime(formattedcallanswerdate,&retsizecad,sizeof(formattedcallanswerdate),format,&tempcallanswer);
+		switch_strftime(formattedcalltransferdate,&retsizectd,sizeof(formattedcalltransferdate),format,&tempcalltransfer);
+		switch_strftime(formattedcallenddate,&retsizeced,sizeof(formattedcallenddate),format,&tempcallend);
+
+		process_channel_variables(chanvars_fixed_list,newchannel->channel);
+		process_channel_variables(chanvars_supp_list,chanvars_fixed_list,newchannel->channel,0);
+	}
+}
+
+CurlCDR::~CurlCDR()
+{
+
+}
+
+bool CurlCDR::activated=0;
+bool CurlCDR::logchanvars=0;
+bool CurlCDR::connectionstate=0;
+modcdr_time_convert_t CurlCDR::convert_time = switch_time_exp_lt;
+const char *CurlCDR::gateway_url;
+const char *CurlCDR::gateway_credentials;
+std::list<std::string> CurlCDR::chanvars_fixed_list;
+std::list<std::string> CurlCDR::chanvars_supp_list;
+std::string CurlCDR::display_name = "CurlCDR - The HTTP CDR logger";
+std::string CurlCDR::postdata;
+
+
+void CurlCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settings, switch_xml_t& param)
+{
+	switch_console_printf(SWITCH_CHANNEL_LOG, "CurlCDR::connect() - Loading configuration file.\n");
+	activated = 0; // Set it as inactive initially
+	connectionstate = 0; // Initialize it to false to show that we aren't yet connected.
+
+    switch_console_printf(SWITCH_CHANNEL_LOG,"Checking to see if curlcdr is valid\n");
+	if ((settings = switch_xml_child(cfg, "curlcdr"))) 
+	{
+        switch_console_printf(SWITCH_CHANNEL_LOG,"curlcdr appears to be!!!\n");
+		int count_config_params = 0;  // Need to make sure all params are set before we load
+		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 (!strcmp(var, "gateway_url"))
+			{
+				if(val != 0)
+					gateway_url = val;
+				count_config_params++;
+			}
+            else if (!strcmp(var, "gateway_credentials"))
+            {
+                if(val != 0)
+                    gateway_credentials=val;
+                count_config_params++;
+            }
+            else if (!strcmp(var, "chanvars_supp")) 
+            {
+				if(val != 0)
+				{
+					std::string unparsed;
+					unparsed = val;
+					if(unparsed.size() > 0)
+					{
+						bool fixed = 0;
+						parse_channel_variables_xconfig(unparsed,chanvars_supp_list,fixed);
+						logchanvars=1;
+					}
+				}
+			}
+			else if (!strcmp(var, "chanvars_fixed"))
+			{
+				if(val != 0)
+				{
+					std::string unparsed;
+					unparsed = val;
+					if(unparsed.size() > 0)
+					{
+						bool fixed = 1;
+						parse_channel_variables_xconfig(unparsed,chanvars_fixed_list,fixed);
+						logchanvars=1;
+					}
+				}
+			}
+			else if(!strcmp(var,"timezone"))
+			{
+				if(!strcmp(val,"utc"))
+					convert_time = switch_time_exp_gmt;
+				else if(!strcmp(val,"local"))
+					convert_time = switch_time_exp_lt;
+				else
+				{
+					switch_console_printf(SWITCH_CHANNEL_LOG,"Invalid configuration parameter for timezone.  Possible values are utc and local.  You entered: %s\nDefaulting to local.\n",val);
+					convert_time = switch_time_exp_lt;
+				}
+			}
+		}
+		
+		if(count_config_params > 0)
+		{
+            if(strlen(gateway_url))
+			{
+				activated = 1;
+				switch_console_printf(SWITCH_CHANNEL_LOG,"CurlCDR activated");
+			}
+            else
+                switch_console_printf(SWITCH_CHANNEL_LOG,"CurlCDR::connect(): You must specify a gateway_url to have the records logged to.\n");
+		}
+		else
+			switch_console_printf(SWITCH_CHANNEL_LOG,"CurlCDR::connect(): You did not specify the minimum parameters for using this module.  You must specify at least a gateway_url to have the records logged to.\n");
+	}
+}
+
+
+
+// from Bjarne Stroustrup's page (the guy who designed and implemented C++)
+// surely his code has to be better than mine - ok he did say this was the
+// *easiest* way and made no comment on it being best :)
+std::string CurlCDR::itos(int i)
+{
+    std::stringstream s;
+    s << i;
+    return s.str();
+}
+
+std::string CurlCDR::lltos(long long ll)
+{
+    std::stringstream s;
+    s << ll;
+    return s.str();
+}
+
+
+bool CurlCDR::process_record()
+{
+    CURL *curl_handle = NULL;
+    static char curl_errorstr[CURL_ERROR_SIZE];
+	bool retval = 0;
+    char *curlescaped;
+
+
+    curl_handle = curl_easy_init();
+    if(!strncasecmp(gateway_url,"https",5)) {
+        curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0);
+        curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,0);
+    }
+
+    // build the HTTP POST data block
+    // WARNING - We need to make sure that the data added is properly escaped, else some sneaky person could set
+    //           their CLID to "My Name&billusec=0" for example, which would result in a post of 
+    //           clid=My+Name&billusec=0
+    //           Simply calculating the billusec in the web app wont solve this because they could play the same
+    //           game with callstarttime and all of that.  
+    //
+    //           The solution I came up with was to use curl_easy_escape() which does a strlen() for every value, 
+    //           as well as a malloc of some sort, and thus requires a curl_free().  This is *not* efficient, if 
+    //           anyone has a better idea, that would be great.  We cant rely on this after the string is assembled
+    //           however because things like the real & would be escaped and that would break things.
+    //           
+    //           To compensate I only do this where its likely to be a problem.  Preformatted dates are not likely
+    //           to ever have such data in them.
+    postdata.append("callstartdate=" + lltos(callstartdate));
+    postdata.append("&formattedcallstartdate=");
+    postdata.append(formattedcallstartdate);
+    postdata.append("&callanswerdate=" + lltos(callanswerdate));
+    postdata.append("&formattedcallanswerdate=");
+    postdata.append(formattedcallanswerdate);
+    postdata.append("&calltransferdate=" + lltos(calltransferdate));
+    postdata.append("&formattedcalltransferdate=");
+    postdata.append(formattedcalltransferdate);
+    postdata.append("&callenddate=" + lltos(callenddate));
+    postdata.append("&formattedcallenddate=");
+    postdata.append(formattedcallenddate);
+    postdata.append("&hangupcause_text=");
+    postdata.append(hangupcause_text);
+    postdata.append("&hangupcause=" + itos(hangupcause));
+    postdata.append("&clid=");
+    curlescaped = curl_easy_escape(curl_handle,clid,0);
+    postdata.append(curlescaped);
+    curl_free(curlescaped);
+    postdata.append(originated==FALSE?"&originated=0":"&originated=1");
+    postdata.append("&dialplan=");
+    curlescaped = curl_easy_escape(curl_handle,dialplan,0); // admin may have used 'bad chars' in the dialplan name
+    postdata.append(curlescaped);
+    curl_free(curlescaped);
+    postdata.append("&myuuid=");
+    postdata.append(myuuid);
+    postdata.append("&destuuid=");
+    postdata.append(destuuid);
+    postdata.append("&src=");
+    curlescaped = curl_easy_escape(curl_handle,src,0);
+    postdata.append(curlescaped);
+    curl_free(curlescaped);
+    postdata.append("&dst=");
+    curlescaped = curl_easy_escape(curl_handle,dst,0);
+    postdata.append(curlescaped);
+    curl_free(curlescaped);
+    postdata.append("&srcchannel=");
+    curlescaped = curl_easy_escape(curl_handle,srcchannel,0);
+    postdata.append(curlescaped);
+    curl_free(curlescaped);
+    postdata.append("&dstchannel=");
+    curlescaped = curl_easy_escape(curl_handle,dstchannel,0);
+    postdata.append(curlescaped);
+    curl_free(curlescaped);
+    postdata.append("&ani=");
+    postdata.append(ani); // this may need to be escaped but is likely to be safe since it should be numeric
+    postdata.append("&aniii=");
+    postdata.append(aniii); // this has to be numeric to be valid
+    postdata.append("&network_addr=");
+    postdata.append(network_addr);
+    postdata.append("&lastapp=");
+    curlescaped = curl_easy_escape(curl_handle,lastapp,0);
+    postdata.append(curlescaped);
+    curl_free(curlescaped);
+    postdata.append("&lastdata=");
+    curlescaped = curl_easy_escape(curl_handle,lastdata,0);
+    postdata.append(curlescaped);
+    curl_free(curlescaped);
+    
+    postdata.append("&billusec=" + lltos(billusec));
+    postdata.append("&disposition=" + itos(disposition));
+    postdata.append("&amaflags=" + itos(amaflags));
+
+    // Now to process chanvars, fixed ones first
+    if(chanvars_fixed.size() > 0 ) {
+        std::list<std::pair<std::string,std::string> >::iterator iItr, iEnd;
+        for(iItr = chanvars_fixed.begin(), iEnd = chanvars_fixed.end(); iItr != iEnd; iItr++) {
+            curlescaped = curl_easy_escape(curl_handle,iItr->second.c_str(),0);
+            if(curlescaped != (char *)NULL) {
+                postdata.append("&" + iItr->first + "=" + curlescaped);
+                curl_free(curlescaped);
+            }
+        }
+    }
+		
+    if(chanvars_supp.size() > 0 ) {
+        std::map<std::string,std::string>::iterator iItr,iEnd;
+        for(iItr = chanvars_supp.begin(), iEnd = chanvars_supp.end() ; iItr != iEnd; iItr++) {
+            curlescaped = curl_easy_escape(curl_handle,iItr->second.c_str(),0);
+            if(curlescaped != (char *)NULL) {
+                postdata.append("&" + iItr->first + "=");
+                postdata.append(curlescaped);
+                curl_free(curlescaped);
+            }
+        }
+    }
+
+        
+    if(!switch_strlen_zero(gateway_credentials)) {
+        curl_easy_setopt(curl_handle,CURLOPT_HTTPAUTH,CURLAUTH_ANY);
+        curl_easy_setopt(curl_handle,CURLOPT_USERPWD,gateway_credentials);
+    }
+    curl_easy_setopt(curl_handle,CURLOPT_POST,1);
+    curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,postdata.c_str());
+    curl_easy_setopt(curl_handle,CURLOPT_URL,gateway_url);
+    curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"freeswitch-xml/1.0");
+    curl_easy_setopt(curl_handle,CURLOPT_ERRORBUFFER,curl_errorstr);
+    if(curl_easy_perform(curl_handle)) {
+        switch_log_printf(SWITCH_CHANNEL_LOG,SWITCH_LOG_ERROR,"CurlCDR::process_record() - Error logging CDR record - %s\n",curl_errorstr);
+    }
+    curl_easy_cleanup(curl_handle);
+
+	retval = 1;
+	return retval;
+}
+
+bool CurlCDR::is_activated()
+{
+	return activated;
+}
+
+void CurlCDR::tempdump_record()
+{
+
+}
+
+void CurlCDR::reread_tempdumped_records()
+{
+
+}
+
+std::string CurlCDR::get_display_name()
+{
+	return display_name;
+}
+
+void CurlCDR::disconnect()
+{
+	activated = 0;
+	logchanvars = 0;
+	chanvars_fixed_list.clear();
+	chanvars_supp_list.clear();
+	connectionstate = 0;
+	switch_console_printf(SWITCH_CHANNEL_LOG,"Shutting down CurlCDR...  Done!");	
+}
+
+AUTO_REGISTER_BASECDR(CurlCDR);
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c++
+ * indent-tabs-mode:nil
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
+ */

Added: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/curlcdr.h
==============================================================================
--- (empty file)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/curlcdr.h	Mon Jan 22 16:41:06 2007
@@ -0,0 +1,97 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application Call Detail Recorder module
+ * Copyright 2006, Author: Yossi Neiman of Cartis Solutions, Inc. <freeswitch AT cartissolutions.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 Call Detail Recorder module
+ *
+ * This code is largely derived from csvcdr.cpp with minor code snippets from mod_xml_curl.c and edited by 
+ * Bret McDanel <trixter AT 0xdecafbad.com>
+ * The Initial Developer of the Original Code is
+ * Yossi Neiman <freeswitch AT cartissolutions.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Yossi Neiman <freeswitch AT cartissolutions.com>
+ * Bret McDanel <trixter AT 0xdecafbad.com>
+ * Anthony Minessale II <anthmct at yahoo.com>
+ *
+ * Description: This C++ source file describes the CurlCDR class that handles processing CDRs to HTTP endpoint.
+ * This is the standard Curl module, and has a list of predefined variables to log out which can be
+ * added to, but never have the default ones removed.  If you want to use one that allows you to explicity
+ * set all data variables to be logged and in what order, then this is not the class you want to use, and
+ * one will be coming in the future to do just that.
+ *
+ * curlcdr.h
+ *
+ */
+
+#include "baseregistry.h"
+#include <switch.h>
+#include <iostream>
+#include <fstream>
+#include <list>
+#include <sstream>
+
+
+#ifndef CURLCDR
+#define CURLCDR
+
+class CurlCDR : public BaseCDR {
+	public:
+		CurlCDR();
+		CurlCDR(switch_mod_cdr_newchannel_t *newchannel);
+		//CurlCDR(const CurlCDR& copyFrom);
+		virtual ~CurlCDR();
+		virtual bool process_record();
+		virtual void connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settings, switch_xml_t& param); // connect and disconnect need to be static because we're persisting connections until shutdown
+		virtual void disconnect();
+		virtual bool is_activated();
+		virtual void tempdump_record();
+		virtual void reread_tempdumped_records();
+		virtual std::string get_display_name();
+    virtual std::string itos(int i);
+    virtual std::string lltos(long long ll);
+
+	private:
+		static bool activated; // Is this module activated?
+		static bool connectionstate; // What is the status of the connection?
+		static bool logchanvars;
+		static modcdr_time_convert_t convert_time;
+		static const char *gateway_url; // The URL to send data to
+		static const char *gateway_credentials; // The credentials for http auth
+		static std::list<std::string> chanvars_fixed_list; // Normally this would be used, but not in this class
+		static std::list<std::string> chanvars_supp_list; // This will hold the list for all chanvars here
+		static std::string display_name;
+        static std::string postdata;
+		char formattedcallstartdate[100];
+		char formattedcallanswerdate[100];
+		char formattedcalltransferdate[100];
+		char formattedcallenddate[100];
+};
+
+#endif
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c++
+ * indent-tabs-mode:nil
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
+ */

Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/pddcdr.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/pddcdr.cpp	(original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/pddcdr.cpp	Mon Jan 22 16:41:06 2007
@@ -172,41 +172,45 @@
 	{
 		// Format the call record and proceed from here...
 		outputfile << "$VAR1 = {" << std::endl;
-		outputfile << "\t\'callstartdate\' = \'" << callstartdate << "\'," << std::endl;
-		outputfile <<  "\t\'formattedcallstartdate\' = \'" << formattedcallstartdate << "\'," << std::endl;
-		outputfile << "\t\'callanswerdate\' = \'" << callanswerdate << "\'," << std::endl;
-		outputfile << "\t\'formattedcallanswerdate\' = \'" << formattedcallanswerdate << "\'," << std::endl;
-		outputfile << "\t\'calltransferdate\' = \'" << calltransferdate << "\'," << std::endl;
-		outputfile << "\t\'formattedcalltransferdate\' = \'" << formattedcalltransferdate << "\'," << std::endl;
-		outputfile << "\t\'callenddate\' = \'" << callenddate << "\'," << std::endl;
-		outputfile << "\t\'formatcallenddate\' = \'" << formattedcallenddate << "\'," << std::endl;
-		outputfile << "\t\'hangupcause\' = \'" << hangupcause_text << "\'," << std::endl;
-		outputfile << "\t\'hangupcausecode\' = \'" << hangupcause << "\'," << std::endl;
-		outputfile << "\t\'clid\' = \'" << clid << "\'," << std::endl;
-		outputfile << "\t\'originated\' = \'" << originated << "\'," << std::endl;
-		outputfile << "\t\'dialplan\' = \'" << dialplan << "\'," << std::endl;
-		outputfile << "\t\'myuuid\' = \'" << myuuid << "\'," << std::endl;
-		outputfile << "\t\'destuuid\' = \'" << destuuid << "\'," << std::endl;
-		outputfile << "\t\'src\' = \'" << src << "\'," << std::endl;
-		outputfile << "\t\'dst\' = \'" << dst << "\'," << std::endl;
-		outputfile << "\t\'srcchannel\' = \'" << srcchannel << "\'," << std::endl;
-		outputfile << "\t\'dstchannel\' = \'" << dstchannel << "\'," << std::endl;
-		outputfile << "\t\'ani\' = \'" << ani << "\'," << std::endl;
-		outputfile << "\t\'aniii\' = \'" << aniii << "\'," << std::endl;
-		outputfile << "\t\'network_addr\' = \'" << network_addr << "\'," << std::endl;
-		outputfile << "\t\'lastapp\' = \'" << lastapp << "\'," << std::endl;
-		outputfile << "\t\'lastdata\' = \'" << lastdata << "\'," << std::endl;
-		outputfile << "\t\'billusec\' = \'" << billusec << "\'," << std::endl;
-		outputfile << "\t\'disposition\' = \'" << disposition << "\'," << std::endl;
-		outputfile << "\t\'amaflags\' = \'" << amaflags << "\'," << std::endl;
+		outputfile << "\t\'callstartdate\' => \'" << callstartdate << "\'," << std::endl;
+		outputfile << "\t\'formattedcallstartdate\' => \'" << formattedcallstartdate << "\'," << std::endl;
+		outputfile << "\t\'callanswerdate\' => \'" << callanswerdate << "\'," << std::endl;
+		outputfile << "\t\'formattedcallanswerdate\' => \'" << formattedcallanswerdate << "\'," << std::endl;
+		outputfile << "\t\'calltransferdate\' => \'" << calltransferdate << "\'," << std::endl;
+		outputfile << "\t\'formattedcalltransferdate\' => \'" << formattedcalltransferdate << "\'," << std::endl;
+		outputfile << "\t\'callenddate\' => \'" << callenddate << "\'," << std::endl;
+		outputfile << "\t\'formattedcallenddate\' => \'" << formattedcallenddate << "\'," << std::endl;
+		outputfile << "\t\'hangupcause\' => \'" << hangupcause_text << "\'," << std::endl;
+		outputfile << "\t\'hangupcausecode\' => \'" << hangupcause << "\'," << std::endl;
+		outputfile << "\t\'clid\' => \'" << escape_chararray(clid) << "\'," << std::endl;
+		outputfile << "\t\'originated\' => \'" << originated << "\'," << std::endl;
+		outputfile << "\t\'dialplan\' => \'" << dialplan << "\'," << std::endl;
+		outputfile << "\t\'myuuid\' => \'" << myuuid << "\'," << std::endl;
+		outputfile << "\t\'destuuid\' => \'" << destuuid << "\'," << std::endl;
+		outputfile << "\t\'src\' => \'" << src << "\'," << std::endl;
+		outputfile << "\t\'dst\' => \'" << dst << "\'," << std::endl;
+		outputfile << "\t\'srcchannel\' => \'" << srcchannel << "\'," << std::endl;
+		outputfile << "\t\'dstchannel\' => \'" << dstchannel << "\'," << std::endl;
+		outputfile << "\t\'ani\' => \'" << ani << "\'," << std::endl;
+		outputfile << "\t\'aniii\' => \'" << aniii << "\'," << std::endl;
+		outputfile << "\t\'network_addr\' => \'" << network_addr << "\'," << std::endl;
+		outputfile << "\t\'lastapp\' => \'" << lastapp << "\'," << std::endl;
+		outputfile << "\t\'lastdata\' => \'" << lastdata << "\'," << std::endl;
+		outputfile << "\t\'billusec\' => \'" << billusec << "\'," << std::endl;
+		outputfile << "\t\'disposition\' => \'" << disposition << "\'," << std::endl;
+		outputfile << "\t\'amaflags\' => \'" << amaflags << "\'," << std::endl;
 		
 		// Now to process chanvars
 		outputfile << "\t\'chanvars\' => {" << std::endl;
 		if(chanvars_supp.size() > 0 )
 		{
-			std::map<std::string,std::string>::iterator iItr,iEnd;
+			std::map< std::string,std::string >::iterator iItr,iEnd;
 			for(iItr = chanvars_supp.begin(), iEnd = chanvars_supp.end() ; iItr != iEnd; iItr++)
-				outputfile << "\t\t\'" << iItr->first << "\' = \'" << iItr->second << "\'," << std::endl;
+			{
+				escape_string(iItr->second);
+				outputfile << "\t\t\'" << iItr->first;
+				outputfile << "\' => \'" << iItr->second << "\'," << std::endl;
+			}
 		}
 		outputfile << "\t}," << std::endl << "};" << std::endl << std::endl;
 		retval = 1;

Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/pddcdr.h
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/pddcdr.h	(original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/pddcdr.h	Mon Jan 22 16:41:06 2007
@@ -24,6 +24,7 @@
  * Contributor(s):
  * 
  * Yossi Neiman <freeswitch AT cartissolutions.com>
+ * Bret McDanel <trixter AT 0xdecafbad.com>
  *
  * Description: This C++ header file describes the PddCDR class which handles formatting a CDR out to
  * individual text files in a Perl Data Dumper format.
@@ -54,7 +55,6 @@
 		virtual void tempdump_record();
 		virtual void reread_tempdumped_records();
 		virtual std::string get_display_name();
-
 	private:
 		static bool activated; // Is this module activated?
 		static bool connectionstate; // What is the status of the connection?



More information about the Freeswitch-branches mailing list