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@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@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?