提交 c5d86f3e authored 作者: Yossi Neiman's avatar Yossi Neiman

Merged changes in from my branch at r4020.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4022 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 d3e1f400
CFLAGS += $(shell mysql_config --include) CFLAGS += $(shell mysql_config --include)
CFLAGS += -DSWITCH_QUEUE_ENHANCED
LDFLAGS += $(shell mysql_config --libs) LDFLAGS += $(shell mysql_config --libs)
#LDFLAGS += -lcurl
CPPCC = g++ CPPCC = g++
OBJS=cdrcontainer.o basecdr.o baseregistry.o mysqlcdr.o pddcdr.o csvcdr.o xmlcdr.o OBJS=cdrcontainer.o basecdr.o baseregistry.o mysqlcdr.o pddcdr.o csvcdr.o xmlcdr.o
......
...@@ -82,6 +82,14 @@ Configuration: Section <odbccdr> ...@@ -82,6 +82,14 @@ Configuration: Section <odbccdr>
<param name="chanvars_supp" value=""/> value is a comma separated list of supplemental channel variables to log. Can be a wildcard (*) (optional) <param name="chanvars_supp" value=""/> value is a comma separated list of supplemental channel variables to log. Can be a wildcard (*) (optional)
<param name="chanvars_supp_repeat_fixed" value=""/> value is 0 for no, 1 for yes, and determines whether or not to repeat any of the fixed channel variables as key / value pairs in the chanvars table. <param name="chanvars_supp_repeat_fixed" value=""/> value is 0 for no, 1 for yes, and determines whether or not to repeat any of the fixed channel variables as key / value pairs in the chanvars table.
<param name="timezone" value=""/> value is utc for utc time, local for localtime. If not specified or incorrectly specified, localtime is assumed. <param name="timezone" value=""/> value is utc for utc time, local for localtime. If not specified or incorrectly specified, localtime is assumed.
Class: SqliteCDR, located in sqlitecdr.h and sqlitecdr.cpp
This class uses the Sqlite3 library as included with FreeSWITCH's core. Sqlite is not strict in its handling of column types, and in theory you can toss any sort of data at any sort of column. That being said, this logger was designed to at least attempt to match the column types to the type of data being sent to it. It will warn you if the schema does not match what chanvars_fixed types you specify, but it will not fail on them. However, due to the use of prepared statements, it is likely that you will have unexpected results if you mismatch your chanvars_fixed logging to db schema. The is the first SQL logger to automatically create the db schema and even update it on its own.
Configuration: Section <sqlitecdr>
<param name="path" value=""/> value is the path to the database to open or create (required)
<param name="chanvars_fixed" value=""/> Is a comma separated list of key=type pairs. Types are x for decimal, s for string (varchar), d for double, i for integer, t for tiny. If no type is provided, it defaults that column to string (varchar). It cannot accept wildcards (*). You must have a matching column of matching type in the main freeswitchcdr table. The logger will attempt to automatically update the schema, but it cannot if a column by that name already exists.(optional)
<param name="chanvars_supp" value=""/> value is a comma separated list of supplemental channel variables to log. Can be a wildcard (*) (optional)
<param name="chanvars_supp_repeat_fixed" value=""/> value is 0 for no, 1 for yes, and determines whether or not to repeat any of the fixed channel variables as key / value pairs in the chanvars table.
FAQ: FAQ:
......
...@@ -60,6 +60,7 @@ BaseCDR::BaseCDR(switch_mod_cdr_newchannel_t *newchannel) ...@@ -60,6 +60,7 @@ BaseCDR::BaseCDR(switch_mod_cdr_newchannel_t *newchannel)
if(newchannel != 0) if(newchannel != 0)
{ {
errorstate = 0; errorstate = 0;
originated=1; // One-legged calls are always considered the originator
memset(clid,0,80); memset(clid,0,80);
memset(dialplan,0,80); memset(dialplan,0,80);
memset(myuuid,0,37); memset(myuuid,0,37);
...@@ -132,7 +133,6 @@ BaseCDR::BaseCDR(switch_mod_cdr_newchannel_t *newchannel) ...@@ -132,7 +133,6 @@ BaseCDR::BaseCDR(switch_mod_cdr_newchannel_t *newchannel)
// Or were we maybe we were the caller? // Or were we maybe we were the caller?
if(newchannel->callerprofile->originatee_caller_profile) if(newchannel->callerprofile->originatee_caller_profile)
{ {
originated = 1;
if (newchannel->callerprofile) { if (newchannel->callerprofile) {
if(newchannel->callerprofile->caller_id_number != 0) if(newchannel->callerprofile->caller_id_number != 0)
strncpy(src,newchannel->callerprofile->caller_id_number,strlen(newchannel->callerprofile->caller_id_number)); strncpy(src,newchannel->callerprofile->caller_id_number,strlen(newchannel->callerprofile->caller_id_number));
...@@ -377,6 +377,35 @@ void BaseCDR::process_channel_variables(const std::list<std::string>& stringlist ...@@ -377,6 +377,35 @@ void BaseCDR::process_channel_variables(const std::list<std::string>& stringlist
} }
} }
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: /* For Emacs:
* Local Variables: * Local Variables:
* mode:c++ * mode:c++
......
...@@ -84,6 +84,8 @@ class BaseCDR { ...@@ -84,6 +84,8 @@ class BaseCDR {
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 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,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 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 callstartdate;
switch_time_t callanswerdate; switch_time_t callanswerdate;
switch_time_t callenddate; switch_time_t callenddate;
......
...@@ -179,7 +179,7 @@ void CsvCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& setting ...@@ -179,7 +179,7 @@ void CsvCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& setting
if(outputfile.good()) if(outputfile.good())
{ {
activated = 1; activated = 1;
switch_console_printf(SWITCH_CHANNEL_LOG,"CsvCDR activated, log rotation will occur at or after %d MB",(filesize_limit/1024/1024)); switch_console_printf(SWITCH_CHANNEL_LOG,"CsvCDR activated, log rotation will occur at or after %d MB\n",(filesize_limit/1024/1024));
} }
} }
else else
...@@ -228,7 +228,21 @@ void CsvCDR::open_file() ...@@ -228,7 +228,21 @@ void CsvCDR::open_file()
switch_console_printf(SWITCH_CHANNEL_LOG,"Could not open the CSV file %s . CsvCDR logger will not be functional until this is resolved and a reload is issued. Failbit is set to %d.\n",filename.c_str(),outputfile.fail()); switch_console_printf(SWITCH_CHANNEL_LOG,"Could not open the CSV file %s . CsvCDR logger will not be functional until this is resolved and a reload is issued. Failbit is set to %d.\n",filename.c_str(),outputfile.fail());
activated = 0; activated = 0;
} }
else
{
outputfile << "callstartdate,formattedcallstartdate,callanswerdate,formattedcallanswerdate,calltransferdate,formattedcalltransferdate,callendate,formattedcallenddate,hangupcause_text,hangupcause,clid,originated,dialplan,myuuid,destuuid,src,dst,srcchannel,dstchannel,ani,aniii,network_address,lastapp,lastdata,billusec,disposition,amaflags";
if(chanvars_fixed_list.size())
{
std::list<std::string>::iterator iItr, iEnd;
for(iItr = chanvars_fixed_list.begin(),iEnd = chanvars_fixed_list.end(); iItr != iEnd; iItr++)
outputfile << "," << *iItr;
}
if(logchanvars)
outputfile << ",chanvars_supp";
outputfile << std::endl;
}
} }
bool CsvCDR::process_record() bool CsvCDR::process_record()
...@@ -315,7 +329,7 @@ void CsvCDR::disconnect() ...@@ -315,7 +329,7 @@ void CsvCDR::disconnect()
chanvars_fixed_list.clear(); chanvars_fixed_list.clear();
chanvars_supp_list.clear(); chanvars_supp_list.clear();
connectionstate = 0; connectionstate = 0;
switch_console_printf(SWITCH_CHANNEL_LOG,"Shutting down CsvCDR... Done!"); switch_console_printf(SWITCH_CHANNEL_LOG,"Shutting down CsvCDR... Done!\n");
} }
AUTO_REGISTER_BASECDR(CsvCDR); AUTO_REGISTER_BASECDR(CsvCDR);
......
差异被折叠。
/*
* 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:
*/
...@@ -62,6 +62,7 @@ MysqlCDR::MysqlCDR(switch_mod_cdr_newchannel_t *newchannel) : BaseCDR(newchannel ...@@ -62,6 +62,7 @@ MysqlCDR::MysqlCDR(switch_mod_cdr_newchannel_t *newchannel) : BaseCDR(newchannel
dstchannel_length = (long unsigned int)strlen(dstchannel); dstchannel_length = (long unsigned int)strlen(dstchannel);
lastapp_length = (long unsigned int)strlen(lastapp); lastapp_length = (long unsigned int)strlen(lastapp);
lastdata_length = (long unsigned int)strlen(lastdata); lastdata_length = (long unsigned int)strlen(lastdata);
network_addr_length = (long unsigned int)strlen(network_addr);
if(chanvars_fixed_list.size() > 0) if(chanvars_fixed_list.size() > 0)
process_channel_variables(chanvars_fixed_list,newchannel->channel); process_channel_variables(chanvars_fixed_list,newchannel->channel);
...@@ -195,7 +196,7 @@ void MysqlCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& setti ...@@ -195,7 +196,7 @@ void MysqlCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& setti
if(activated) if(activated)
{ {
tmp_sql_query = "INSERT INTO freeswitchcdr (callstartdate,callanswerdate,calltransferdate,callenddate,originated,clid,src,dst,ani,aniii,dialplan,myuuid,destuuid,srcchannel,dstchannel,lastapp,lastdata,billusec,disposition,hangupcause,amaflags"; tmp_sql_query = "INSERT INTO freeswitchcdr (callstartdate,callanswerdate,calltransferdate,callenddate,originated,clid,src,dst,ani,aniii,dialplan,myuuid,destuuid,srcchannel,dstchannel,network_addr,lastapp,lastdata,billusec,disposition,hangupcause,amaflags";
int items_appended = 0; int items_appended = 0;
...@@ -213,7 +214,7 @@ void MysqlCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& setti ...@@ -213,7 +214,7 @@ void MysqlCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& setti
} }
} }
tmp_sql_query.append(") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?"); tmp_sql_query.append(") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?");
if(chanvars_fixed_list.size() > 0 ) if(chanvars_fixed_list.size() > 0 )
{ {
...@@ -334,13 +335,13 @@ bool MysqlCDR::process_record() ...@@ -334,13 +335,13 @@ bool MysqlCDR::process_record()
set_mysql_time(tm1,my_callstartdate); set_mysql_time(tm1,my_callstartdate);
set_mysql_time(tm2,my_callanswerdate); set_mysql_time(tm2,my_callanswerdate);
set_mysql_time(tm3,my_calltransferdate); set_mysql_time(tm3,my_calltransferdate);
set_mysql_time(tm4,my_calltransferdate); set_mysql_time(tm4,my_callenddate);
// Why is this out of order? I don't know, it doesn't make sense. // Why is this out of order? I don't know, it doesn't make sense.
add_parameter(my_callstartdate,MYSQL_TYPE_DATETIME); add_parameter(my_callstartdate,MYSQL_TYPE_DATETIME);
add_parameter(my_callanswerdate,MYSQL_TYPE_DATETIME); add_parameter(my_callanswerdate,MYSQL_TYPE_DATETIME);
add_parameter(my_callenddate,MYSQL_TYPE_DATETIME);
add_parameter(my_calltransferdate,MYSQL_TYPE_DATETIME); add_parameter(my_calltransferdate,MYSQL_TYPE_DATETIME);
add_parameter(my_callenddate,MYSQL_TYPE_DATETIME);
add_parameter(originated,MYSQL_TYPE_TINY); add_parameter(originated,MYSQL_TYPE_TINY);
add_string_parameter(clid,clid_length,MYSQL_TYPE_VAR_STRING,0); add_string_parameter(clid,clid_length,MYSQL_TYPE_VAR_STRING,0);
...@@ -353,6 +354,7 @@ bool MysqlCDR::process_record() ...@@ -353,6 +354,7 @@ bool MysqlCDR::process_record()
add_string_parameter(destuuid,destuuid_length,MYSQL_TYPE_VAR_STRING,0); add_string_parameter(destuuid,destuuid_length,MYSQL_TYPE_VAR_STRING,0);
add_string_parameter(srcchannel,srcchannel_length,MYSQL_TYPE_VAR_STRING,0); add_string_parameter(srcchannel,srcchannel_length,MYSQL_TYPE_VAR_STRING,0);
add_string_parameter(dstchannel,dstchannel_length,MYSQL_TYPE_VAR_STRING,0); add_string_parameter(dstchannel,dstchannel_length,MYSQL_TYPE_VAR_STRING,0);
add_string_parameter(network_addr,network_addr_length,MYSQL_TYPE_VAR_STRING,0);
add_string_parameter(lastapp,lastapp_length,MYSQL_TYPE_VAR_STRING,0); add_string_parameter(lastapp,lastapp_length,MYSQL_TYPE_VAR_STRING,0);
add_string_parameter(lastdata,lastdata_length,MYSQL_TYPE_VAR_STRING,0); add_string_parameter(lastdata,lastdata_length,MYSQL_TYPE_VAR_STRING,0);
add_parameter(billusec,MYSQL_TYPE_LONGLONG,0); add_parameter(billusec,MYSQL_TYPE_LONGLONG,0);
......
...@@ -95,6 +95,7 @@ class MysqlCDR : public BaseCDR { ...@@ -95,6 +95,7 @@ class MysqlCDR : public BaseCDR {
long unsigned int aniii_length; long unsigned int aniii_length;
long unsigned int lastapp_length; long unsigned int lastapp_length;
long unsigned int lastdata_length; long unsigned int lastdata_length;
long unsigned int network_addr_length;
// Now a couple internal methods // Now a couple internal methods
template <typename T> void add_parameter(T& param, enum_field_types type, bool *is_null=0); template <typename T> void add_parameter(T& param, enum_field_types type, bool *is_null=0);
void add_string_parameter(char* param, long unsigned int& param_length, enum_field_types type, bool* is_null=0); void add_string_parameter(char* param, long unsigned int& param_length, enum_field_types type, bool* is_null=0);
......
...@@ -222,7 +222,7 @@ void OdbcCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settin ...@@ -222,7 +222,7 @@ void OdbcCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settin
{ {
tmp_sql_query = "INSERT INTO "; tmp_sql_query = "INSERT INTO ";
tmp_sql_query.append(tablename); tmp_sql_query.append(tablename);
tmp_sql_query.append(" (callstartdate,callanswerdate,calltransferdate,callenddate,originated,clid,src,dst,ani,aniii,dialplan,myuuid,destuuid,srcchannel,dstchannel,lastapp,lastdata,billusec,disposition,hangupcause,amaflags"); tmp_sql_query.append(" (callstartdate,callanswerdate,calltransferdate,callenddate,originated,clid,src,dst,ani,aniii,dialplan,myuuid,destuuid,srcchannel,dstchannel,network_addr,lastapp,lastdata,billusec,disposition,hangupcause,amaflags");
int items_appended = 0; int items_appended = 0;
...@@ -240,7 +240,7 @@ void OdbcCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settin ...@@ -240,7 +240,7 @@ void OdbcCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settin
} }
} }
tmp_sql_query.append(") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?"); tmp_sql_query.append(") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?");
if(chanvars_fixed_list.size() > 0 ) if(chanvars_fixed_list.size() > 0 )
{ {
...@@ -422,6 +422,7 @@ bool OdbcCDR::process_record() ...@@ -422,6 +422,7 @@ bool OdbcCDR::process_record()
SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(destuuid), 0, destuuid, 0, 0); SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(destuuid), 0, destuuid, 0, 0);
SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(srcchannel), 0, srcchannel, 0, 0); SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(srcchannel), 0, srcchannel, 0, 0);
SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(dstchannel), 0, dstchannel, 0, 0); SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(dstchannel), 0, dstchannel, 0, 0);
SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(network_addr), 0, network_addr, 0, 0);
SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(lastapp), 0, lastapp, 0, 0); SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(lastapp), 0, lastapp, 0, 0);
SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(lastdata), 0, lastdata, 0, 0); SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(lastdata), 0, lastdata, 0, 0);
SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_BIGINT, 0, 0, &billusec, 0, 0); SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_UBIGINT, SQL_BIGINT, 0, 0, &billusec, 0, 0);
......
...@@ -172,41 +172,45 @@ bool PddCDR::process_record() ...@@ -172,41 +172,45 @@ bool PddCDR::process_record()
{ {
// Format the call record and proceed from here... // Format the call record and proceed from here...
outputfile << "$VAR1 = {" << std::endl; outputfile << "$VAR1 = {" << std::endl;
outputfile << "\t\'callstartdate\' = \'" << callstartdate << "\'," << std::endl; outputfile << "\t\'callstartdate\' => \'" << callstartdate << "\'," << std::endl;
outputfile << "\t\'formattedcallstartdate\' = \'" << formattedcallstartdate << "\'," << std::endl; outputfile << "\t\'formattedcallstartdate\' => \'" << formattedcallstartdate << "\'," << std::endl;
outputfile << "\t\'callanswerdate\' = \'" << callanswerdate << "\'," << std::endl; outputfile << "\t\'callanswerdate\' => \'" << callanswerdate << "\'," << std::endl;
outputfile << "\t\'formattedcallanswerdate\' = \'" << formattedcallanswerdate << "\'," << std::endl; outputfile << "\t\'formattedcallanswerdate\' => \'" << formattedcallanswerdate << "\'," << std::endl;
outputfile << "\t\'calltransferdate\' = \'" << calltransferdate << "\'," << std::endl; outputfile << "\t\'calltransferdate\' => \'" << calltransferdate << "\'," << std::endl;
outputfile << "\t\'formattedcalltransferdate\' = \'" << formattedcalltransferdate << "\'," << std::endl; outputfile << "\t\'formattedcalltransferdate\' => \'" << formattedcalltransferdate << "\'," << std::endl;
outputfile << "\t\'callenddate\' = \'" << callenddate << "\'," << std::endl; outputfile << "\t\'callenddate\' => \'" << callenddate << "\'," << std::endl;
outputfile << "\t\'formatcallenddate\' = \'" << formattedcallenddate << "\'," << std::endl; outputfile << "\t\'formattedcallenddate\' => \'" << formattedcallenddate << "\'," << std::endl;
outputfile << "\t\'hangupcause\' = \'" << hangupcause_text << "\'," << std::endl; outputfile << "\t\'hangupcause\' => \'" << hangupcause_text << "\'," << std::endl;
outputfile << "\t\'hangupcausecode\' = \'" << hangupcause << "\'," << std::endl; outputfile << "\t\'hangupcausecode\' => \'" << hangupcause << "\'," << std::endl;
outputfile << "\t\'clid\' = \'" << clid << "\'," << std::endl; outputfile << "\t\'clid\' => \'" << escape_chararray(clid) << "\'," << std::endl;
outputfile << "\t\'originated\' = \'" << originated << "\'," << std::endl; outputfile << "\t\'originated\' => \'" << originated << "\'," << std::endl;
outputfile << "\t\'dialplan\' = \'" << dialplan << "\'," << std::endl; outputfile << "\t\'dialplan\' => \'" << dialplan << "\'," << std::endl;
outputfile << "\t\'myuuid\' = \'" << myuuid << "\'," << std::endl; outputfile << "\t\'myuuid\' => \'" << myuuid << "\'," << std::endl;
outputfile << "\t\'destuuid\' = \'" << destuuid << "\'," << std::endl; outputfile << "\t\'destuuid\' => \'" << destuuid << "\'," << std::endl;
outputfile << "\t\'src\' = \'" << src << "\'," << std::endl; outputfile << "\t\'src\' => \'" << src << "\'," << std::endl;
outputfile << "\t\'dst\' = \'" << dst << "\'," << std::endl; outputfile << "\t\'dst\' => \'" << dst << "\'," << std::endl;
outputfile << "\t\'srcchannel\' = \'" << srcchannel << "\'," << std::endl; outputfile << "\t\'srcchannel\' => \'" << srcchannel << "\'," << std::endl;
outputfile << "\t\'dstchannel\' = \'" << dstchannel << "\'," << std::endl; outputfile << "\t\'dstchannel\' => \'" << dstchannel << "\'," << std::endl;
outputfile << "\t\'ani\' = \'" << ani << "\'," << std::endl; outputfile << "\t\'ani\' => \'" << ani << "\'," << std::endl;
outputfile << "\t\'aniii\' = \'" << aniii << "\'," << std::endl; outputfile << "\t\'aniii\' => \'" << aniii << "\'," << std::endl;
outputfile << "\t\'network_addr\' = \'" << network_addr << "\'," << std::endl; outputfile << "\t\'network_addr\' => \'" << network_addr << "\'," << std::endl;
outputfile << "\t\'lastapp\' = \'" << lastapp << "\'," << std::endl; outputfile << "\t\'lastapp\' => \'" << lastapp << "\'," << std::endl;
outputfile << "\t\'lastdata\' = \'" << lastdata << "\'," << std::endl; outputfile << "\t\'lastdata\' => \'" << lastdata << "\'," << std::endl;
outputfile << "\t\'billusec\' = \'" << billusec << "\'," << std::endl; outputfile << "\t\'billusec\' => \'" << billusec << "\'," << std::endl;
outputfile << "\t\'disposition\' = \'" << disposition << "\'," << std::endl; outputfile << "\t\'disposition\' => \'" << disposition << "\'," << std::endl;
outputfile << "\t\'amaflags\' = \'" << amaflags << "\'," << std::endl; outputfile << "\t\'amaflags\' => \'" << amaflags << "\'," << std::endl;
// Now to process chanvars // Now to process chanvars
outputfile << "\t\'chanvars\' => {" << std::endl; outputfile << "\t\'chanvars\' => {" << std::endl;
if(chanvars_supp.size() > 0 ) 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++) 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; outputfile << "\t}," << std::endl << "};" << std::endl << std::endl;
retval = 1; retval = 1;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
* Contributor(s): * Contributor(s):
* *
* Yossi Neiman <freeswitch AT cartissolutions.com> * 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 * 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. * individual text files in a Perl Data Dumper format.
...@@ -54,7 +55,6 @@ class PddCDR : public BaseCDR { ...@@ -54,7 +55,6 @@ class PddCDR : public BaseCDR {
virtual void tempdump_record(); virtual void tempdump_record();
virtual void reread_tempdumped_records(); virtual void reread_tempdumped_records();
virtual std::string get_display_name(); virtual std::string get_display_name();
private: private:
static bool activated; // Is this module activated? static bool activated; // Is this module activated?
static bool connectionstate; // What is the status of the connection? static bool connectionstate; // What is the status of the connection?
......
...@@ -15,6 +15,7 @@ create table freeswitchcdr ( ...@@ -15,6 +15,7 @@ create table freeswitchcdr (
destuuid char(36) NOT NULL, destuuid char(36) NOT NULL,
srcchannel varchar(80) NOT NULL, srcchannel varchar(80) NOT NULL,
dstchannel varchar(80) NOT NULL, /* Need to decide - this might be redundant as you can link the records via uuid */ dstchannel varchar(80) NOT NULL, /* Need to decide - this might be redundant as you can link the records via uuid */
network_addr varchar(40) default "",
lastapp varchar(80) default "", lastapp varchar(80) default "",
lastdata varchar(255) default "", lastdata varchar(255) default "",
billusec bigint default 0, billusec bigint default 0,
......
差异被折叠。
/*
* 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
*
* 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>
*
* Description: This C++ header file describes the SqliteCDR class which handles formatting a CDR out to
* a SQLite database using prepared statements.
*
* sqlitecdr.h
*
*/
#include "baseregistry.h"
#include <list>
#include <sstream>
#ifndef SQLITECDR
#define SQLITECDR
class SqliteCDR : public BaseCDR {
public:
SqliteCDR();
SqliteCDR(switch_mod_cdr_newchannel_t *newchannel);
//SqliteCDR(const SqliteCDR& copyFrom);
virtual ~SqliteCDR();
virtual bool process_record();
virtual void connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settings, switch_xml_t& param);
virtual void disconnect();
virtual bool is_activated();
virtual void tempdump_record();
virtual void reread_tempdumped_records();
virtual std::string get_display_name();
private:
static bool activated;
static char sql_query[1024];
static std::string tmp_sql_query; // Object must exist to bind the statement, this used for generating the sql
static char sql_query_chanvars[100];
static std::string db_filename;
static bool use_utc_time;
switch_time_t sqlite_callstartdate;
switch_time_t sqlite_callanswerdate;
switch_time_t sqlite_calltransferdate;
switch_time_t sqlite_callenddate;
static switch_core_db_t *db;
static switch_core_db_stmt_t *stmt;
static switch_core_db_stmt_t *stmt_chanvars;
static switch_core_db_stmt_t *stmt_begin;
static switch_core_db_stmt_t *stmt_commit;
static bool connectionstate;
static bool logchanvars;
static std::list<std::string> chanvars_fixed_list;
static std::vector<switch_mod_cdr_sql_types_t> chanvars_fixed_types;
static std::list<std::string> chanvars_supp_list; // The supplemental list
static bool repeat_fixed_in_supp;
static std::string display_name;
};
#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:
*/
...@@ -171,7 +171,7 @@ bool XmlCDR::process_record() ...@@ -171,7 +171,7 @@ bool XmlCDR::process_record()
switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record(): Unable to open file %s to commit the call record to. Invalid path name, invalid permissions, or no space available?\n",outputfile_name.c_str()); switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record(): Unable to open file %s to commit the call record to. Invalid path name, invalid permissions, or no space available?\n",outputfile_name.c_str());
else else
{ {
switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record(): Preping the CDR to %s.\n",outputfile_name.c_str()); //switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record(): Preping the CDR to %s.\n",outputfile_name.c_str());
// Format the call record and proceed from here... // Format the call record and proceed from here...
outputfile << "<?xml version=\"1.0\"?>" << std::endl; outputfile << "<?xml version=\"1.0\"?>" << std::endl;
outputfile << "<document type=\"freeswitch-cdr/xml\">" << std::endl; outputfile << "<document type=\"freeswitch-cdr/xml\">" << std::endl;
...@@ -213,7 +213,7 @@ bool XmlCDR::process_record() ...@@ -213,7 +213,7 @@ bool XmlCDR::process_record()
} }
outputfile << "\t</chanvars>" << std::endl << "</document>" << std::endl << std::endl; outputfile << "\t</chanvars>" << std::endl << "</document>" << std::endl << std::endl;
switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record(): Dumping the CDR to %s.\n",outputfile_name.c_str()); //switch_console_printf(SWITCH_CHANNEL_LOG, "XmlCDR::process_record(): Dumping the CDR to %s.\n",outputfile_name.c_str());
retval = 1; retval = 1;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论