Freeswitch-svn
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
December 2006
- 10 participants
- 350 discussions
[commit] r3550 - freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr
by Freeswitch SVN 05 Dec '06
by Freeswitch SVN 05 Dec '06
05 Dec '06
Author: mishehu
Date: Tue Dec 5 18:08:55 2006
New Revision: 3550
Modified:
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/README
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/basecdr.h
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/cdrcontainer.cpp
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/cdrcontainer.h
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.cpp
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.h
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mod_cdr.cpp
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mysqlcdr.cpp
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mysqlcdr.h
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/odbccdr.cpp
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/odbccdr.h
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/pddcdr.cpp
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/pddcdr.h
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/schema.sql
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.cpp
freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.h
Log:
Finished updating the mod_cdr classes for core changes to switch_channel_t, also added some api commands and updated the documentation and db schemas.
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/README
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/README (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/README Tue Dec 5 18:08:55 2006
@@ -39,6 +39,7 @@
<param name="chanvars_fixed" value=""/> value is a comma separated list of fixed channel variables to log. This cannot be a wildcard (*). (optional)
<param name="chanvars_supp" value=""/> value is a comma separated list of supplemental channel variables to log. It can be a wildcard (*). (optional)
<param name="repeat_fixed_in_supp" value=""/> value is a 0 for no, 1 for yes, and is for the case that you might want any fixed channel variables to be repeated in the supplemental list.
+ <param name="timezone" value=""/> value is utc for utc time, local for localtime. If not specified or incorrectly specified, localtime is assumed.
Class: PddCDR, located in pddcdr.h and pddcdr.cpp
Description: This is the Perl Data Dumper output class. It writes each record to an individual text file
@@ -46,18 +47,20 @@
Configuration: Section name: <pddcdr>
<param name="path" value=""/> value is the path where you want the output files (required)
<param name="chanvars" value=""/> value is a comma separated list of channel variables to log. It can accept a wildcard (*) (optional)
+ <param name="timezone" value=""/> value is utc for utc time, local for localtime. If not specified or incorrectly specified, localtime is assumed.
Class: MysqlCDR, located in mysqlcdr.h and mysqlcdr.cpp
Description: This class logs the call detail record to a MySQL 4.1.x or greater database using prepared
- statements. This class is a little more complex than the prior two in that the fixed channel variables are treated as additional columns on the main freeswitchcdr database table for improved normalization of the database. As such, you need to specify the format of each fixed channel variable as well. If you do not specify, it will default to a varchar column type, and will not execute if the table schema does not match. Therefore it is very important to make sure that any fixed channel variables you log exist as columns on the table. The supplemental channel variables are stored in a separate table using a key / value pair linking to the callid of the call. Recommended to use at least one other logger in conjuction with this one just to be on the safe side, as failover handling of errors to write to the db are not yet implemented, and therefore there is a risk of data loss if the database connection is lost entirely (it will be limited to only those records created at the time of the loss of connection) or some other fatal error is encountered.
+ statements. This class is a little more complex than the prior two in that the fixed channel variables are treated as additional columns on the main freeswitchcdr database table for improved normalization of the database. As such, you need to specify the format of each fixed channel variable as well. If you do not specify, it will default to a varchar column type, and will not execute if the table schema does not match the columns being operated upon. Therefore it is very important to make sure that any fixed channel variables you log exist as columns on the table. The supplemental channel variables are stored in a separate table using a key / value pair linking to the callid of the call. Recommended to use at least one other logger in conjuction with this one just to be on the safe side, as failover handling of errors to write to the db are not yet implemented, and therefore there is a risk of data loss if the database connection is lost entirely (it will be limited to only those records created at the time of the loss of connection) or some other fatal error is encountered. As of 2006-12-05, we have added a new column named "calltransferdate" to match changes in the core. Please update your schema to match.
Configuration: Section: <mysqlcdr>
<param name="hostname" value=""/> value is the hostname or IP of the MySQL server (required)
<param name="username" value=""/> value is the username to connect to the MySQL server with (required)
<param name="password" value=""/> value is the password to use to authenticate to the MySQL server with (required)
<param name="dbname" value=""/> value is the name of the database to connect to (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 (*). (optional)
+ <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. (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="timezone" value=""/> value is utc for utc time, local for localtime. If not specified or incorrectly specified, localtime is assumed.
Class: OdbcCDR, located in odbccdr.h and odbccdr.cpp
This class logs the call detail record to an ODBC database using prepared
@@ -73,6 +76,7 @@
<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 (*). (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="timezone" value=""/> value is utc for utc time, local for localtime. If not specified or incorrectly specified, localtime is assumed.
FAQ:
@@ -90,29 +94,38 @@
Q: What happened to the ani2 field?
A: Oops, you caught us. The real name for is it aniii. You will need to update any database schemas or external handlers for this change.
+
+Q: Are there any API commands (executable from the console) that can be run?
+A: Yes, there are the following commands:
+ modcdr_reload - causes the freeswitch.xml to be reloaded and reruns the configure on all mod_cdr modules
+ modcdr_queue_pause - pauses the queue from extracting items for processing, useful if you need to free up some free space without taking the system down.
+ modcdr_queue_resume - resumes normal processing of items in the queue.
+ modcdr_show_active - displays the active backend loggers.
+ modcdr_show_available - displays the available (compiled-in) backend loggers.
Example configuration:
<configuration name="mod_cdr.conf" description="CDR Configuration">
<pddcdr>
<param name="path" value="/work/temp/pddcdr"/>
- <param name="chanvars" value="username,accountcode"/>
- <param name="chanvars_fixed" value="*"/>
+ <!-- <param name="chanvars" value="username,accountcode"/> -->
+ <!-- <param name="chanvars_fixed" value="foo"/> -->
</pddcdr>
<csvcdr>
<param name="path" value="/work/temp/csvcdr"/>
<param name="size_limit" value="25"/>
- <param name="chanvars_fixed" value="username"/>
- <param name="chanvars_supp" value="*"/>
- <param name="repeat_fixed_in_supp" value="0"/>
+ <!-- <param name="chanvars_fixed" value="username"/> -->
+ <!-- <param name="chanvars_supp" value="*"/> -->
+ <!-- <param name="repeat_fixed_in_supp" value="0"/> -->
</csvcdr>
<mysqlcdr>
<param name="hostname" value="10.0.0.1"/>
<param name="username" value="test"/>
<param name="password" value="test"/>
<param name="dbname" value="testing"/>
- <param name="chanvars_fixed" value="username=s,The_Kow=t"/>
- <!-- This previous line logs username as a varchar, and The_Kow as a tiny -->
+ <!-- This following line logs username as a varchar, and The_Kow as a tiny -->
+ <!-- <param name="chanvars_fixed" value="username=s,The_Kow=t"/> -->
+ <!-- If you do not want to log any and all chanvars to the chanvar table, comment the next 2 lines out -->
<param name="chanvars_supp" value="*"/>
<param name="chanvars_supp_repeat_fixed" value="0"/>
</mysqlcdr>
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 Tue Dec 5 18:08:55 2006
@@ -59,6 +59,8 @@
enum switch_mod_cdr_sql_types_t { CDR_INTEGER,CDR_STRING,CDR_DECIMAL,CDR_DOUBLE,CDR_TINY };
+typedef apr_status_t (*modcdr_time_convert_t)(apr_time_exp_t*,apr_time_t);
+
class BaseCDR {
public:
BaseCDR();
@@ -70,6 +72,7 @@
virtual bool is_activated() = 0;
virtual void tempdump_record() = 0;
virtual void reread_tempdumped_records() = 0;
+ virtual std::string get_display_name() = 0; // Get the module name
protected:
void parse_channel_variables_xconfig(std::string& unparsed,std::list<std::string>& chanvarslist,bool fixed);
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
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/cdrcontainer.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/cdrcontainer.cpp (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/cdrcontainer.cpp Tue Dec 5 18:08:55 2006
@@ -171,6 +171,38 @@
}
+void CDRContainer::active(switch_stream_handle_t *stream)
+{
+ switch_mod_cdr_newchannel_t *newchannel; // = new switch_mod_cdr_newchannel_t;
+ newchannel = 0;
+
+ stream->write_function(stream,"The following mod_cdr logging backends are currently marked as active:\n");
+ BaseRegistry& registry(BaseRegistry::get());
+ for(BaseRegistry::iterator it = registry.active_begin(); it != registry.active_end(); ++it)
+ {
+ basecdr_creator func = *it;
+ BaseCDR* _ptr = func(newchannel);
+ std::auto_ptr<BaseCDR> ptr(_ptr);
+ stream->write_function(stream,"%s\n",ptr->get_display_name().c_str());
+ }
+}
+
+void CDRContainer::available(switch_stream_handle_t *stream)
+{
+ switch_mod_cdr_newchannel_t *newchannel; // = new switch_mod_cdr_newchannel_t;
+ newchannel = 0;
+
+ stream->write_function(stream,"The following mod_cdr logging backends are currently avaible for use (providing you configure them):\n");
+ BaseRegistry& registry(BaseRegistry::get());
+ for(BaseRegistry::iterator it = registry.begin(); it != registry.end(); ++it)
+ {
+ basecdr_creator func = *it;
+ BaseCDR* _ptr = func(newchannel);
+ std::auto_ptr<BaseCDR> ptr(_ptr);
+ stream->write_function(stream,"%s\n",ptr->get_display_name().c_str());
+ }
+}
+
void CDRContainer::add_cdr(switch_core_session_t *session)
{
switch_mod_cdr_newchannel_t *newchannel = new switch_mod_cdr_newchannel_t;
@@ -183,21 +215,20 @@
newchannel->callerextension = switch_channel_get_caller_extension(newchannel->channel);
newchannel->callerprofile = switch_channel_get_caller_profile(newchannel->channel);
- BaseRegistry& registry(BaseRegistry::get());
- for(BaseRegistry::iterator it = registry.active_begin(); it != registry.active_end(); ++it)
+ while (newchannel->callerprofile)
{
- basecdr_creator func = *it;
-
- do
+ BaseRegistry& registry(BaseRegistry::get());
+ for(BaseRegistry::iterator it = registry.active_begin(); it != registry.active_end(); ++it)
{
+ basecdr_creator func = *it;
+
BaseCDR* newloggerobject = func(newchannel);
switch_console_printf(SWITCH_CHANNEL_LOG,"Adding a new logger object to the queue.\n");
switch_queue_push(cdrqueue,newloggerobject);
- newchannel->callerprofile = newchannel->callerprofile->next;
- if(newchannel->callerextension)
- newchannel->callerextension = newchannel->callerextension->next;
- } while (newchannel->callerprofile);
-
+ }
+ newchannel->callerprofile = newchannel->callerprofile->next;
+ if(newchannel->callerextension)
+ newchannel->callerextension = newchannel->callerextension->next;
}
delete newchannel;
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/cdrcontainer.h
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/cdrcontainer.h (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/cdrcontainer.h Tue Dec 5 18:08:55 2006
@@ -61,6 +61,8 @@
void reload(switch_stream_handle_t *stream);
void queue_pause(switch_stream_handle_t *stream);
void queue_resume(switch_stream_handle_t *stream);
+ void active(switch_stream_handle_t *stream);
+ void available(switch_stream_handle_t *stream);
protected:
private:
switch_xml_t cfg, xml, settings, param;
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.cpp (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.cpp Tue Dec 5 18:08:55 2006
@@ -55,19 +55,22 @@
if(newchannel != 0)
{
- switch_time_exp_t tempcallstart, tempcallanswer, tempcallend;
+ 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));
- switch_time_exp_lt(&tempcallstart, callstartdate);
- switch_time_exp_lt(&tempcallanswer, callanswerdate);
- switch_time_exp_lt(&tempcallend, callenddate);
+ convert_time(&tempcallstart, callstartdate);
+ convert_time(&tempcallanswer, callanswerdate);
+ convert_time(&tempcalltransfer, calltransferdate);
+ convert_time(&tempcallend, callenddate);
// Format the times
- apr_size_t retsizecsd, retsizecad, retsizeced; //csd == callstartdate, cad == callanswerdate, ced == callenddate, ceff == callenddate_forfile
- char format[] = "%Y-%m-%d-%H-%M-%S";
+ 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);
@@ -84,11 +87,13 @@
bool CsvCDR::logchanvars=0;
bool CsvCDR::connectionstate=0;
bool CsvCDR::repeat_fixed_in_supp=0;
+modcdr_time_convert_t CsvCDR::convert_time = switch_time_exp_lt;
std::string CsvCDR::outputfile_path;
std::ofstream CsvCDR::outputfile;
std::ofstream::pos_type CsvCDR::filesize_limit = (10 * 1024 * 1024); // Default file size is 10MB
std::list<std::string> CsvCDR::chanvars_fixed_list;
std::list<std::string> CsvCDR::chanvars_supp_list;
+std::string CsvCDR::display_name = "CsvCDR - The simple comma separated values CDR logger";
void CsvCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settings, switch_xml_t& param)
{
@@ -153,6 +158,18 @@
std::cout << "File size limit from config file is " << filesize_limit << " byte(s)." << std::endl;
}
}
+ 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)
@@ -220,8 +237,13 @@
// Format the call record and proceed from here...
outputfile << "\"" << callstartdate << "\",\"";
+ outputfile << formattedcallstartdate << "\",\"";
outputfile << callanswerdate << "\",\"";
+ outputfile << formattedcallanswerdate << "\",\"";
+ outputfile << calltransferdate << "\",\"";
+ outputfile << formattedcalltransferdate << "\",\"";
outputfile << callenddate << "\",\"";
+ outputfile << formattedcallenddate << "\",\"";
outputfile << hangupcause_text << "\",\"";
outputfile << hangupcause << "\",\"";
outputfile << clid << "\",\"";
@@ -277,13 +299,18 @@
}
+std::string CsvCDR::get_display_name()
+{
+ return display_name;
+}
+
void CsvCDR::disconnect()
{
outputfile.close();
activated = 0;
logchanvars = 0;
repeat_fixed_in_supp = 0;
- outfile_path.clear();
+ outputfile_path.clear();
chanvars_fixed_list.clear();
chanvars_supp_list.clear();
connectionstate = 0;
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.h
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.h (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/csvcdr.h Tue Dec 5 18:08:55 2006
@@ -56,17 +56,21 @@
virtual bool is_activated();
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?
static bool logchanvars;
+ static modcdr_time_convert_t convert_time;
static bool repeat_fixed_in_supp; // Repeat the fixed chanvars in the supplemental?
static std::string outputfile_path; // The directory we'll dump these into
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;
char formattedcallstartdate[100];
char formattedcallanswerdate[100];
+ char formattedcalltransferdate[100];
char formattedcallenddate[100];
static std::ofstream outputfile;
static std::ofstream::pos_type filesize_limit;
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mod_cdr.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mod_cdr.cpp (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mod_cdr.cpp Tue Dec 5 18:08:55 2006
@@ -47,6 +47,8 @@
static switch_status_t modcdr_reload(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
static switch_status_t modcdr_queue_pause(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
static switch_status_t modcdr_queue_resume(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
+static switch_status_t modcdr_show_active(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
+static switch_status_t modcdr_show_available(char *dest, switch_core_session_t *isession, switch_stream_handle_t *stream);
static switch_thread_rwlock_t *cdr_rwlock;
/* Now begins the glue that will tie this into the system.
@@ -61,12 +63,28 @@
/*.on_transmit */ NULL
};
+static switch_api_interface_t modcdr_show_available_api = {
+ /*.interface_name */ "modcdr_show_available",
+ /*.desc */ "Displays the currently compiled-in mod_cdr backend loggers.",
+ /*.function */ modcdr_show_available,
+ /*.syntax */ "modcdr_queue_show_available",
+ /*.next */ 0
+};
+
+static switch_api_interface_t modcdr_show_active_api = {
+ /*.interface_name */ "modcdr_show_active",
+ /*.desc */ "Displays the currently active mod_cdr backend loggers.",
+ /*.function */ modcdr_show_active,
+ /*.syntax */ "modcdr_queue_show_active",
+ /*.next */ &modcdr_show_available_api
+};
+
static switch_api_interface_t modcdr_queue_resume_api = {
/*.interface_name */ "modcdr_queue_resume",
/*.desc */ "Manually resumes the popping of objects from the queue.",
/*.function */ modcdr_queue_resume,
/*.syntax */ "modcdr_queue_resume",
- /*.next */ 0
+ /*.next */ &modcdr_show_active_api
};
static switch_api_interface_t modcdr_queue_pause_api = {
@@ -150,6 +168,18 @@
static switch_status_t modcdr_queue_resume(char *dest=0, switch_core_session_t *isession=0, switch_stream_handle_t *stream=0)
{
newcdrcontainer->queue_resume(stream);
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t modcdr_show_active(char *dest=0, switch_core_session_t *isession=0, switch_stream_handle_t *stream=0)
+{
+ newcdrcontainer->active(stream);
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t modcdr_show_available(char *dest=0, switch_core_session_t *isession=0, switch_stream_handle_t *stream=0)
+{
+ newcdrcontainer->available(stream);
return SWITCH_STATUS_SUCCESS;
}
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mysqlcdr.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mysqlcdr.cpp (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mysqlcdr.cpp Tue Dec 5 18:08:55 2006
@@ -93,6 +93,8 @@
char MysqlCDR::username[255] ="";
char MysqlCDR::dbname[255] = "";
char MysqlCDR::password[255] = "";
+modcdr_time_convert_t MysqlCDR::convert_time = switch_time_exp_lt;
+std::string MysqlCDR::display_name = "MysqlCDR - The MySQL 4.1+ CDR logger using prepared statements";
//fstream MysqlCDR::tmpfile;
void MysqlCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settings, switch_xml_t& param)
@@ -172,6 +174,18 @@
repeat_fixed_in_supp = 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==4)
@@ -181,7 +195,7 @@
if(activated)
{
- tmp_sql_query = "INSERT INTO freeswitchcdr (callstartdate,callanswerdate,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,lastapp,lastdata,billusec,disposition,hangupcause,amaflags";
int items_appended = 0;
@@ -199,7 +213,7 @@
}
}
- tmp_sql_query.append(") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?");
+ tmp_sql_query.append(") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?");
if(chanvars_fixed_list.size() > 0 )
{
@@ -299,24 +313,32 @@
}
+std::string MysqlCDR::get_display_name()
+{
+ return display_name;
+}
bool MysqlCDR::process_record()
{
- switch_time_exp_t tm1,tm2,tm3; // One for call start
+ switch_time_exp_t tm1,tm2,tm3,tm4; // One for call start, answer, transfer, and end
memset(&tm1,0,sizeof(tm1));
memset(&tm2,0,sizeof(tm2));
memset(&tm3,0,sizeof(tm3));
+ memset(&tm4,0,sizeof(tm4));
- switch_time_exp_lt(&tm1,callstartdate);
- switch_time_exp_lt(&tm2,callanswerdate);
- switch_time_exp_lt(&tm3,callenddate);
+ convert_time(&tm1,callstartdate);
+ convert_time(&tm2,callanswerdate);
+ convert_time(&tm3,calltransferdate);
+ convert_time(&tm4,callenddate);
set_mysql_time(tm1,my_callstartdate);
set_mysql_time(tm2,my_callanswerdate);
- set_mysql_time(tm3,my_callenddate);
+ set_mysql_time(tm3,my_calltransferdate);
+ set_mysql_time(tm4,my_calltransferdate);
add_parameter(my_callstartdate,MYSQL_TYPE_DATETIME);
add_parameter(my_callanswerdate,MYSQL_TYPE_DATETIME);
+ add_parameter(my_calltransferdate,MYSQL_TYPE_DATETIME);
add_parameter(my_callenddate,MYSQL_TYPE_DATETIME);
add_parameter(originated,MYSQL_TYPE_TINY);
@@ -583,6 +605,11 @@
chanvars_supp_list.clear();
chanvars_fixed_types.clear();
connectionstate = 0;
+ memset(hostname,0,255);
+ memset(username,0,255);
+ memset(password,0,255);
+ memset(dbname,0,255);
+ memset(sql_query,0,1024);
tmp_sql_query.clear();
}
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mysqlcdr.h
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mysqlcdr.h (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/mysqlcdr.h Tue Dec 5 18:08:55 2006
@@ -53,6 +53,7 @@
virtual bool is_activated();
virtual void tempdump_record();
virtual void reread_tempdumped_records();
+ virtual std::string get_display_name();
private:
static bool activated;
@@ -72,11 +73,14 @@
static char username[255];
static char dbname[255];
static char password[255];
+ static modcdr_time_convert_t convert_time;
+ static std::string display_name;
//static fstream tmpfile;
std::vector<MYSQL_BIND> bindme;
//MYSQL_BIND *bindme;
MYSQL_TIME my_callstartdate;
MYSQL_TIME my_callanswerdate;
+ MYSQL_TIME my_calltransferdate;
MYSQL_TIME my_callenddate;
// Why all these long unsigned int's? MySQL's prep statement API expects these to actually exist and not just be params passed to the function calls. The are to measure the length of actual data in the char* arrays.
long unsigned int clid_length;
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/odbccdr.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/odbccdr.cpp (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/odbccdr.cpp Tue Dec 5 18:08:55 2006
@@ -43,19 +43,22 @@
{
if(newchannel != 0)
{
- switch_time_exp_t tempcallstart, tempcallanswer, tempcallend;
+ switch_time_exp_t tempcallstart, tempcallanswer, tempcalltransfer, tempcallend;
memset(&tempcallstart,0,sizeof(tempcallstart));
memset(&tempcallanswer,0,sizeof(tempcallanswer));
+ memset(&tempcalltransfer,0,sizeof(tempcalltransfer));
memset(&tempcallend,0,sizeof(tempcallend));
- switch_time_exp_lt(&tempcallstart, callstartdate);
- switch_time_exp_lt(&tempcallanswer, callanswerdate);
- switch_time_exp_lt(&tempcallend, callenddate);
+ convert_time(&tempcallstart, callstartdate);
+ convert_time(&tempcallanswer, callanswerdate);
+ convert_time(&tempcalltransfer, calltransferdate);
+ convert_time(&tempcallend, callenddate);
// Format the times
- switch_size_t retsizecsd, retsizecad, retsizeced; //csd == callstartdate, cad == callanswerdate, ced == callenddate, ceff == callenddate_forfile
+ switch_size_t retsizecsd, retsizecad, retsizectd, retsizeced; //csd == callstartdate, cad == callanswerdate, ced == callenddate, ceff == callenddate_forfile
char format[] = "%Y-%m-%d %T";
switch_strftime(odbc_callstartdate,&retsizecsd,sizeof(odbc_callstartdate),format,&tempcallstart);
switch_strftime(odbc_callanswerdate,&retsizecad,sizeof(odbc_callanswerdate),format,&tempcallanswer);
+ switch_strftime(odbc_calltransferdate,&retsizectd,sizeof(odbc_calltransferdate),format,&tempcalltransfer);
switch_strftime(odbc_callenddate,&retsizeced,sizeof(odbc_callenddate),format,&tempcallend);
if(chanvars_fixed_list.size() > 0)
@@ -74,6 +77,8 @@
bool OdbcCDR::connectionstate = 0;
bool OdbcCDR::logchanvars = 0;
bool OdbcCDR::repeat_fixed_in_supp = 0;
+std::string OdbCDR::display_name = "OdbcCDR - The Open Database Backend Connector CDR logger backend";
+modcdr_time_convert_t OdbcCDR::convert_time;
std::list<std::string> OdbcCDR::chanvars_fixed_list;
std::list<std::string> OdbcCDR::chanvars_supp_list;
std::vector<switch_mod_cdr_sql_types_t> OdbcCDR::chanvars_fixed_types;
@@ -188,6 +193,18 @@
if(val != 0)
strncpy(tablename_chanvars,val,strlen(val));
}
+ 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(strlen(tablename) == 0)
strncpy(tablename,"freeswitchcdr",13);
@@ -205,7 +222,7 @@
{
tmp_sql_query = "INSERT INTO ";
tmp_sql_query.append(tablename);
- tmp_sql_query.append(" (callstartdate,callanswerdate,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,lastapp,lastdata,billusec,disposition,hangupcause,amaflags");
int items_appended = 0;
@@ -223,7 +240,7 @@
}
}
- tmp_sql_query.append(") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?");
+ tmp_sql_query.append(") VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?");
if(chanvars_fixed_list.size() > 0 )
{
@@ -287,8 +304,8 @@
In this case, the default username and password will be used from odbc.conf */
ODBC_res = SQLConnect(ODBC_con, (SQLCHAR*)dsn, SQL_NTS, (SQLCHAR*)username, SQL_NTS, (SQLCHAR*)password, SQL_NTS);
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
- {
+ if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO))
+ {
switch_console_printf(SWITCH_CHANNEL_LOG,"Error connecting to the ODBC database on %d\n",ODBC_res);
SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
@@ -390,8 +407,9 @@
int index = 1;
SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(odbc_callstartdate), 0, odbc_callstartdate, 0, 0);
- SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(odbc_callstartdate), 0, odbc_callstartdate, 0, 0);
- SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(odbc_callstartdate), 0, odbc_callenddate, 0, 0);
+ SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(odbc_callanswerdate), 0, odbc_callanswerdate, 0, 0);
+ SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(odbc_calltransferdate), 0, odbc_calltransferdate, 0, 0);
+ SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(odbc_callenddate), 0, odbc_callenddate, 0, 0);
SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_TINYINT,0, 0,&originated, 0, 0);
SQLBindParameter(ODBC_stmt, index++, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(clid), 0, clid, 0, 0);
@@ -583,6 +601,11 @@
chanvars_supp_list.clear();
chanvars_fixed_types.clear();
connectionstate = 0;
+ memset(hostname,0,255);
+ memset(username,0,255);
+ memset(password,0,255);
+ memset(dbname,0,255);
+ memset(sql_query,0,1024);
tmp_sql_query.clear();
//tmp_sql_query_chanvars.clear();
}
@@ -597,6 +620,11 @@
SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
connectionstate = 0;
+}
+
+std::string OdbcCDR::get_display_name()
+{
+ return display_name;
}
AUTO_REGISTER_BASECDR(OdbcCDR);
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/odbccdr.h
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/odbccdr.h (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/odbccdr.h Tue Dec 5 18:08:55 2006
@@ -64,10 +64,13 @@
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 modcdr_time_convert_t convert_time;
+ static std::string display_name;
static std::string tmp_sql_query; // Object must exist to bind the statement, this used for generating the sql
static char sql_query_chanvars[355];
static char sql_query_ping[10];
@@ -92,6 +95,7 @@
//static fstream tmpfile;
char odbc_callstartdate[128];
char odbc_callanswerdate[128];
+ char odbc_calltransferdate[128];
char odbc_callenddate[128];
void disconnect_stage_1();
void connect_to_database();
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 Tue Dec 5 18:08:55 2006
@@ -47,22 +47,26 @@
memset(formattedcallstartdate,0,100);
memset(formattedcallanswerdate,0,100);
memset(formattedcallenddate,0,100);
+ memset(formattedcalltransferdate,0,100);
if(newchannel != 0)
{
- switch_time_exp_t tempcallstart, tempcallanswer, tempcallend;
+ switch_time_exp_t tempcallstart, tempcallanswer, tempcalltransfer, tempcallend;
memset(&tempcallstart,0,sizeof(tempcallstart));
memset(&tempcallanswer,0,sizeof(tempcallanswer));
+ memset(&tempcalltransfer,0,sizeof(tempcalltransfer));
memset(&tempcallend,0,sizeof(tempcallend));
- switch_time_exp_lt(&tempcallstart, callstartdate);
- switch_time_exp_lt(&tempcallanswer, callanswerdate);
- switch_time_exp_lt(&tempcallend, callenddate);
+ convert_time(&tempcallstart, callstartdate);
+ convert_time(&tempcallanswer, callanswerdate);
+ convert_time(&tempcalltransfer, calltransferdate);
+ convert_time(&tempcallend, callenddate);
// Format the times
- size_t retsizecsd, retsizecad, retsizeced; //csd == callstartdate, cad == callanswerdate, ced == callenddate, ceff == callenddate_forfile
- char format[] = "%Y-%m-%d-%H-%M-%S";
+ 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);
std::ostringstream ostring;
@@ -88,9 +92,11 @@
bool PddCDR::activated=0;
bool PddCDR::logchanvars=0;
bool PddCDR::connectionstate=0;
+modcdr_time_convert_t PddCDR::convert_time = switch_time_exp_lt;
std::string PddCDR::outputfile_path;
std::list<std::string> PddCDR::chanvars_fixed_list;
std::list<std::string> PddCDR::chanvars_supp_list;
+std::string PddCDR::display_name = "PddCDR - Perl Data Dumper CDR logger";
void PddCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settings, switch_xml_t& param)
{
@@ -134,6 +140,18 @@
{
switch_console_printf(SWITCH_CHANNEL_LOG,"PddCDR has no need for a fixed or supplemental list of channel variables due to the nature of the format. Please use the setting parameter of \"chanvars\" instead and try again.\n");
}
+ 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)
@@ -155,8 +173,13 @@
// 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;
@@ -205,6 +228,11 @@
void PddCDR::reread_tempdumped_records()
{
+}
+
+std::string PddCDR::get_display_name()
+{
+ return display_name;
}
void PddCDR::disconnect()
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 Tue Dec 5 18:08:55 2006
@@ -53,16 +53,20 @@
virtual bool is_activated();
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?
static bool logchanvars;
+ static modcdr_time_convert_t convert_time;
static std::string outputfile_path; // The directory we'll dump these into
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;
char formattedcallstartdate[100];
char formattedcallanswerdate[100];
+ char formattedcalltransferdate[100];
char formattedcallenddate[100];
std::string outputfile_name;
std::ofstream outputfile;
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/schema.sql
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/schema.sql (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/schema.sql Tue Dec 5 18:08:55 2006
@@ -2,6 +2,7 @@
callid bigint unsigned default 0 primary key, /* This will need to be handled specially for auto increment, as that might not be standard */
callstartdate datetime NOT NULL,
callanswerdate datetime NOT NULL,
+ calltransferdate datetime NOT NULL,
callenddate datetime NOT NULL,
originated tinyint default 0,
clid varchar(80) default "Freeswitch - Unknown",
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.cpp
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.cpp (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.cpp Tue Dec 5 18:08:55 2006
@@ -51,19 +51,22 @@
if(newchannel != 0)
{
- switch_time_exp_t tempcallstart, tempcallanswer, tempcallend;
+ switch_time_exp_t tempcallstart, tempcallanswer, tempcalltransfer, tempcallend;
memset(&tempcallstart,0,sizeof(tempcallstart));
memset(&tempcallanswer,0,sizeof(tempcallanswer));
memset(&tempcallend,0,sizeof(tempcallend));
- switch_time_exp_lt(&tempcallstart, callstartdate);
- switch_time_exp_lt(&tempcallanswer, callanswerdate);
- switch_time_exp_lt(&tempcallend, callenddate);
+ memset(&tempcalltransfer,0,sizeof(tempcalltransfer));
+ convert_time(&tempcallstart, callstartdate);
+ convert_time(&tempcallanswer, callanswerdate);
+ convert_time(&tempcalltransfer, calltransferdate);
+ convert_time(&tempcallend, callenddate);
// Format the times
- size_t retsizecsd, retsizecad, retsizeced; //csd == callstartdate, cad == callanswerdate, ced == callenddate, ceff == callenddate_forfile
- char format[] = "%Y-%m-%d-%H-%M-%S";
+ 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);
std::ostringstream ostring;
@@ -90,9 +93,11 @@
bool XmlCDR::activated=0;
bool XmlCDR::logchanvars=0;
bool XmlCDR::connectionstate=0;
+modcdr_time_convert_t XmlCDR::convert_time = switch_time_exp_lt;
std::string XmlCDR::outputfile_path;
std::list<std::string> XmlCDR::chanvars_fixed_list;
std::list<std::string> XmlCDR::chanvars_supp_list;
+std::string XmlCDR::display_name = "XmlCDR - The rough implementation of XML CDR logger";
void XmlCDR::connect(switch_xml_t& cfg, switch_xml_t& xml, switch_xml_t& settings, switch_xml_t& param)
{
@@ -136,6 +141,18 @@
{
switch_console_printf(SWITCH_CHANNEL_LOG,"XmlCDR has no need for a fixed or supplemental list of channel variables due to the nature of the format. Please use the setting parameter of \"chanvars\" instead and try again.\n");
}
+ 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)
@@ -159,8 +176,13 @@
outputfile << "<?xml version=\"1.0\"?>" << std::endl;
outputfile << "<document type=\"freeswitch-cdr/xml\">" << std::endl;
outputfile << "\t<callstartdate data=\"" << callstartdate << "\" />" << std::endl;
+ outputfile << "\t<formattedcallstartdate data=\"" << formattedcallstartdate << "\" />" << std::endl;
outputfile << "\t<callanswerdate data=\"" << callanswerdate << "\" />" << std::endl;
+ outputfile << "\t<formattedcallanswerdate data=\"" << formattedcallanswerdate << "\" />" << std::endl;
+ outputfile << "\t<calltransferdate data=\"" << calltransferdate << "\" />" << std::endl;
+ outputfile << "\t<formattedcalltransferdate data=\"" << formattedcalltransferdate << "\" />" << std::endl;
outputfile << "\t<callenddate data=\"" << callenddate << "\" />" << std::endl;
+ outputfile << "\t<formattedcallenddate data=\"" << formattedcallenddate << "\" />" << std::endl;
outputfile << "\t<hangupcause data=\"" << hangupcause_text << "\" />" << std::endl;
outputfile << "\t<hangupcausecode data=\"" << hangupcause << "\" />" << std::endl;
outputfile << "\t<clid data=\"" << clid << "\" />" << std::endl;
@@ -211,6 +233,11 @@
void XmlCDR::reread_tempdumped_records()
{
+}
+
+std::string XmlCDR::get_display_name()
+{
+ return display_name;
}
void XmlCDR::disconnect()
Modified: freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.h
==============================================================================
--- freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.h (original)
+++ freeswitch/branches/mishehu/src/mod/event_handlers/mod_cdr/xmlcdr.h Tue Dec 5 18:08:55 2006
@@ -54,16 +54,20 @@
virtual bool is_activated();
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?
static bool logchanvars;
+ static modcdr_time_convert_t convert_time;
static std::string outputfile_path; // The directory we'll dump these into
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;
char formattedcallstartdate[100];
char formattedcallanswerdate[100];
+ char formattedcalltransferdate[100];
char formattedcallenddate[100];
std::string outputfile_name;
std::ofstream outputfile;
1
0
[commit] r3549 - in freeswitch/trunk/src: . include mod/endpoints/mod_sofia
by Freeswitch SVN 05 Dec '06
by Freeswitch SVN 05 Dec '06
05 Dec '06
Author: anthm
Date: Tue Dec 5 18:08:14 2006
New Revision: 3549
Modified:
freeswitch/trunk/src/include/switch_channel.h
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
freeswitch/trunk/src/switch_channel.c
Log:
answer tweak
Modified: freeswitch/trunk/src/include/switch_channel.h
==============================================================================
--- freeswitch/trunk/src/include/switch_channel.h (original)
+++ freeswitch/trunk/src/include/switch_channel.h Tue Dec 5 18:08:14 2006
@@ -274,6 +274,12 @@
const char *file,
const char *func,
int line);
+
+SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_channel_t *channel,
+ const char *file,
+ const char *func,
+ int line);
+
/*!
\brief Answer a channel (initiate/acknowledge a successful connection)
\param channel channel to answer
@@ -281,6 +287,12 @@
*/
#define switch_channel_answer(channel) switch_channel_perform_answer(channel, __FILE__, __FUNCTION__, __LINE__)
+/*!
+ \brief Mark a channel answered with no indication (for outbound calls)
+ \param channel channel to mark answered
+ \return SWITCH_STATUS_SUCCESS if channel was answered successfully
+*/
+#define switch_channel_mark_answered(channel) switch_channel_perform_mark_answered(channel, __FILE__, __FUNCTION__, __LINE__)
SWITCH_DECLARE(switch_status_t) switch_channel_perform_ringback(switch_channel_t *channel,
const char *file,
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Tue Dec 5 18:08:14 2006
@@ -2721,7 +2721,7 @@
if (r_sdp) {
if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) {
switch_set_flag_locked(tech_pvt, TFLAG_ANS);
- switch_channel_set_flag(channel, CF_ANSWERED);
+ switch_channel_mark_answered(channel);
if ((uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)) && (other_session = switch_core_session_locate(uuid))) {
other_channel = switch_core_session_get_channel(other_session);
switch_channel_answer(other_channel);
@@ -2749,7 +2749,7 @@
switch_channel_set_variable(channel, "endpoint_disposition", "ANSWER");
tech_choose_port(tech_pvt);
activate_rtp(tech_pvt);
- switch_channel_set_flag(channel, CF_ANSWERED);
+ switch_channel_mark_answered(channel);
return;
}
@@ -2759,7 +2759,7 @@
} else if (switch_test_flag(tech_pvt, TFLAG_EARLY_MEDIA)) {
switch_set_flag_locked(tech_pvt, TFLAG_ANS);
switch_channel_set_variable(channel, "endpoint_disposition", "ANSWER");
- switch_channel_set_flag(channel, CF_ANSWERED);
+ switch_channel_mark_answered(channel);
return;
} //else probably an ack
}
Modified: freeswitch/trunk/src/switch_channel.c
==============================================================================
--- freeswitch/trunk/src/switch_channel.c (original)
+++ freeswitch/trunk/src/switch_channel.c Tue Dec 5 18:08:14 2006
@@ -1049,6 +1049,41 @@
return status;
}
+SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_channel_t *channel,
+ const char *file,
+ const char *func,
+ int line)
+{
+ switch_event_t *event;
+
+ assert(channel != NULL);
+
+ if (channel->state >= CS_HANGUP) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ if (switch_channel_test_flag(channel, CF_ANSWERED)) {
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ if (channel->caller_profile && channel->caller_profile->times) {
+ switch_mutex_lock(channel->profile_mutex);
+ channel->caller_profile->times->answered = switch_time_now();
+ switch_mutex_unlock(channel->profile_mutex);
+ }
+
+ switch_channel_set_flag(channel, CF_ANSWERED);
+
+ if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_ANSWER) == SWITCH_STATUS_SUCCESS) {
+ switch_channel_event_set_data(channel, event);
+ switch_event_fire(&event);
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, (char *) file, func, line, SWITCH_LOG_NOTICE, "Channel [%s] has been answered\n", channel->name);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *channel,
const char *file,
const char *func,
@@ -1065,21 +1100,7 @@
}
if (switch_core_session_answer_channel(channel->session) == SWITCH_STATUS_SUCCESS) {
- switch_event_t *event;
-
- if (channel->caller_profile && channel->caller_profile->times) {
- switch_mutex_lock(channel->profile_mutex);
- channel->caller_profile->times->answered = switch_time_now();
- switch_mutex_unlock(channel->profile_mutex);
- }
-
- switch_channel_set_flag(channel, CF_ANSWERED);
- switch_log_printf(SWITCH_CHANNEL_ID_LOG, (char *) file, func, line, SWITCH_LOG_NOTICE, "Answer %s!\n", channel->name);
- if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_ANSWER) == SWITCH_STATUS_SUCCESS) {
- switch_channel_event_set_data(channel, event);
- switch_event_fire(&event);
- }
- return SWITCH_STATUS_SUCCESS;
+ return switch_channel_perform_mark_answered(channel, file, func, line);
}
return SWITCH_STATUS_FALSE;
1
0
05 Dec '06
Author: mikej
Date: Tue Dec 5 17:58:26 2006
New Revision: 3548
Modified:
freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
initial bits of conference control changes.
Modified: freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c Tue Dec 5 17:58:26 2006
@@ -71,10 +71,44 @@
uint32_t threads;
} globals;
+typedef enum {
+ CALLER_CONTROL_MUTE,
+ CALLER_CONTROL_DEAF_MUTE,
+ CALLER_CONTROL_ENERGY_UP,
+ CALLER_CONTROL_ENERGY_EQU_CONF,
+ CALLER_CONTROL_ENERGEY_DN,
+ CALLER_CONTROL_VOL_TALK_UP,
+ CALLER_CONTROL_VOL_TALK_ZERO,
+ CALLER_CONTROL_VOL_TALK_DN,
+ CALLER_CONTROL_VOL_LISTEN_UP,
+ CALLER_CONTROL_VOL_LISTEN_ZERO,
+ CALLER_CONTROL_VOL_LISTEN_DN,
+ CALLER_CONTROL_HANGUP,
+ CALLER_CONTROL_MENU,
+ CALLER_CONTROL_DIAL,
+} caller_control_t;
+
/* forward declaration for conference_obj and caller_control */
struct conference_member;
typedef struct conference_member conference_member_t;
+typedef struct caller_control_fn_table {
+ char *key;
+ char *digits;
+ caller_control_t action;
+ void (*handler)(conference_member_t *, void *);
+} caller_control_fn_table_t;
+
+typedef struct caller_control_actions {
+ caller_control_fn_table_t *fndesc;
+ void *data;
+} caller_control_action_t;
+
+typedef struct caller_control_menu_info {
+ switch_ivr_menu_t *stack;
+ char *name;
+} caller_control_menu_info_t;
+
typedef enum {
MFLAG_RUNNING = (1 << 0),
MFLAG_CAN_SPEAK = (1 << 1),
@@ -130,6 +164,7 @@
char *kicked_sound;
char *caller_id_name;
char *caller_id_number;
+ switch_ivr_digit_stream_parser_t *dtmf_parser;
char *pin;
char *pin_sound;
char *bad_pin_sound;
@@ -198,6 +233,14 @@
switch_memory_pool_t *pool;
} conference_record_t;
+/* API command parser */
+typedef struct api_command {
+ char *pname;
+ void *pfnapicmd;
+ int fntype;
+ char *psyntax;
+} api_command_t;
+
/* Function Prototypes */
static uint32_t next_member_id(void);
static conference_relationship_t *member_get_relationship(conference_member_t *member, conference_member_t *other_member);
@@ -232,6 +275,10 @@
static conference_obj_t *conference_new(char *name, switch_xml_t profile, switch_memory_pool_t *pool);
static switch_status_t chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint);
static void launch_conference_record_thread(conference_obj_t *conference, char *path);
+
+typedef int (*conf_api_args_cmd_t)(conference_obj_t*, switch_stream_handle_t*, int, char**);
+typedef int (*conf_api_member_cmd_t)(conference_member_t*, switch_stream_handle_t*, void*);
+typedef int (*conf_api_text_cmd_t)(conference_obj_t*, switch_stream_handle_t*, char*);
static void conference_member_itterator(conference_obj_t *conference,
switch_stream_handle_t *stream,
1
0
05 Dec '06
Author: mikej
Date: Tue Dec 5 17:28:30 2006
New Revision: 3547
Modified:
freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
cleanups in mod_conference from Neal Horman.
Modified: freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c Tue Dec 5 17:28:30 2006
@@ -47,6 +47,13 @@
#define CONF_DBUFFER_MAX 0
#define CONF_CHAT_PROTO "conf"
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+/* this doesn't work correctly yet, don't bother trying! */
+//#define OPTION_IVR_MENU_SUPPORT */
+
typedef enum {
FILE_STOP_CURRENT,
FILE_STOP_ALL
@@ -64,9 +71,8 @@
uint32_t threads;
} globals;
+/* forward declaration for conference_obj and caller_control */
struct conference_member;
-struct conference_obj;
-typedef struct conference_obj conference_obj_t;
typedef struct conference_member conference_member_t;
typedef enum {
@@ -78,7 +84,6 @@
MFLAG_NOCHANNEL = (1 << 5)
} member_flag_t;
-
typedef enum {
CFLAG_RUNNING = (1 << 0),
CFLAG_DYNAMIC = (1 << 1),
@@ -98,7 +103,7 @@
NODE_TYPE_SPEECH
} node_type_t;
-struct confernce_file_node {
+typedef struct confernce_file_node {
switch_file_handle_t fh;
switch_speech_handle_t sh;
node_type_t type;
@@ -106,12 +111,10 @@
switch_memory_pool_t *pool;
uint32_t leadin;
struct confernce_file_node *next;
-};
+} confernce_file_node_t;
-typedef struct confernce_file_node confernce_file_node_t;
-
/* Conference Object */
-struct conference_obj {
+typedef struct conference_obj {
char *name;
char *timer_name;
char *tts_engine;
@@ -146,15 +149,14 @@
uint32_t count;
int32_t energy_level;
uint8_t min;
-};
+} conference_obj_t;
/* Relationship with another member */
-struct conference_relationship {
+typedef struct conference_relationship {
uint32_t id;
uint32_t flags;
struct conference_relationship *next;
-};
-typedef struct conference_relationship conference_relationship_t;
+} conference_relationship_t;
/* Conference Member Object */
struct conference_member {
@@ -190,12 +192,11 @@
};
/* Record Node */
-struct conference_record {
+typedef struct conference_record {
conference_obj_t *conference;
char *path;
switch_memory_pool_t *pool;
-};
-typedef struct conference_record conference_record_t;
+} conference_record_t;
/* Function Prototypes */
static uint32_t next_member_id(void);
@@ -282,6 +283,7 @@
return rel;
}
+/* traverse the conference member list for the specified member id and return it's pointer */
static conference_member_t *conference_member_get(conference_obj_t *conference, uint32_t id)
{
conference_member_t *member = NULL;
@@ -300,6 +302,7 @@
return member;
}
+/* stop the specified recording */
static int conference_record_stop(conference_obj_t *conference, char *path)
{
conference_member_t *member = NULL;
@@ -696,12 +699,12 @@
if (!switch_test_flag(imember, MFLAG_NOCHANNEL)) {
channel = switch_core_session_get_channel(imember->session);
- // add this little bit to preserve the bridge cause code in case of an early media call that
- // never answers
+ /* add this little bit to preserve the bridge cause code in case of an early media call that */
+ /* never answers */
if (switch_test_flag(conference, CFLAG_ANSWERED)) {
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
} else {
- // put actual cause code from outbound channel hangup here
+ /* put actual cause code from outbound channel hangup here */
switch_channel_hangup(channel, conference->bridge_hangup_cause);
}
}
@@ -784,6 +787,8 @@
/* Start a thread to read data and feed it into the buffer and use this thread to generate output */
launch_input_thread(member, switch_core_session_get_pool(member->session));
+ /* Fair WARNING, If you expect the caller to hear anything or for digit handling to be proccessed, */
+ /* you better not block this thread loop for more than the duration of member->conference->timer_name! */
while(switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD) && switch_channel_ready(channel)) {
char dtmf[128] = "";
uint8_t file_frame[CONF_BUFFER_SIZE] = {0};
@@ -814,7 +819,7 @@
}
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
- // test to see if outbound channel has answered
+ /* test to see if outbound channel has answered */
if (switch_channel_test_flag(channel, CF_ANSWERED) && !switch_test_flag(member->conference, CFLAG_ANSWERED)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Outbound conference channel answered, setting CFLAG_ANSWERED");
switch_set_flag(member->conference, CFLAG_ANSWERED);
@@ -826,6 +831,7 @@
}
}
+ /* if we have caller digits, feed them to the parser to find an action */
if (switch_channel_has_dtmf(channel)) {
switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
@@ -951,7 +957,9 @@
}
}
+ /* handle file and TTS frames */
if (member->fnode) {
+ /* if we are done, clean it up */
if (member->fnode->done) {
confernce_file_node_t *fnode;
switch_memory_pool_t *pool;
@@ -973,9 +981,10 @@
switch_core_destroy_memory_pool(&pool);
} else {
+ /* skip this frame until leadin time has expired */
if (member->fnode->leadin) {
member->fnode->leadin--;
- } else {
+ } else { /* send the node frame instead of the conference frame to the call leg */
if (member->fnode->type == NODE_TYPE_SPEECH) {
switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_BLOCKING;
uint32_t rate = member->conference->rate;
@@ -1014,10 +1023,9 @@
switch_core_timer_next(&timer);
}
}
- } else {
+ } else { /* send the conferecne frame to the call leg */
switch_buffer_t *use_buffer = NULL;
uint32_t mux_used = (uint32_t)switch_buffer_inuse(member->mux_buffer);
- //uint32_t res_used = member->mux_resampler ? switch_buffer_inuse(member->resample_buffer) : 0;
if (mux_used) {
/* Flush the output buffer and write all the data (presumably muxed) back to the channel */
@@ -1051,7 +1059,7 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Channel leaving conference, cause: %s\n",
switch_channel_cause2str(switch_channel_get_cause(channel)));
- // if it's an outbound channel, store the release cause in the conference struct, we might need it
+ /* if it's an outbound channel, store the release cause in the conference struct, we might need it */
if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
member->conference->bridge_hangup_cause = switch_channel_get_cause(channel);
}
@@ -1194,6 +1202,7 @@
return count;
}
+/* stop playing a file for the member of the conference */
static uint32_t conference_member_stop_file(conference_member_t *member, file_stop_t stop)
{
confernce_file_node_t *nptr;
@@ -1218,7 +1227,7 @@
return count;
}
-/* Play a file in the conference rooom */
+/* Play a file in the conference room */
static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel)
{
confernce_file_node_t *fnode, *nptr;
@@ -1238,12 +1247,12 @@
return SWITCH_STATUS_FALSE;
}
- if (channel) {
- if ((expanded = switch_channel_expand_variables(channel, file)) != file) {
- file = expanded;
- frexp = 1;
- }
- }
+ if (channel) {
+ if ((expanded = switch_channel_expand_variables(channel, file)) != file) {
+ file = expanded;
+ frexp = 1;
+ }
+ }
#ifdef WIN32
@@ -1252,14 +1261,14 @@
if (*file != '/') {
#endif
status = conference_say(conference, file, leadin);
- goto done;
+ goto done;
}
/* Setup a memory pool to use. */
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");
status = SWITCH_STATUS_MEMERR;
- goto done;
+ goto done;
}
/* Create a node object*/
@@ -1267,7 +1276,7 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Alloc Failure\n");
switch_core_destroy_memory_pool(&pool);
status = SWITCH_STATUS_MEMERR;
- goto done;
+ goto done;
}
fnode->type = NODE_TYPE_FILE;
@@ -1280,7 +1289,7 @@
pool) != SWITCH_STATUS_SUCCESS) {
switch_core_destroy_memory_pool(&pool);
status = SWITCH_STATUS_NOTFOUND;
- goto done;
+ goto done;
}
fnode->pool = pool;
@@ -1305,7 +1314,7 @@
return status;
}
-/* Play a file in the conference rooom to a member */
+/* Play a file in the conference room to a member */
static switch_status_t conference_member_play_file(conference_member_t *member, char *file, uint32_t leadin)
{
confernce_file_node_t *fnode, *nptr;
@@ -1343,6 +1352,7 @@
fnode->pool = pool;
/* Queue the node */
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "queueing file '%s' for play\n",file);
switch_mutex_lock(member->flag_mutex);
for (nptr = member->fnode; nptr && nptr->next; nptr = nptr->next);
@@ -1356,7 +1366,7 @@
return SWITCH_STATUS_SUCCESS;
}
-/* Say some thing with TTS in the conference rooom */
+/* Say some thing with TTS in the conference room */
static switch_status_t conference_member_say(conference_obj_t *conference, conference_member_t *member, char *text, uint32_t leadin)
{
confernce_file_node_t *fnode, *nptr;
@@ -1415,7 +1425,7 @@
return SWITCH_STATUS_SUCCESS;
}
-/* Say some thing with TTS in the conference rooom */
+/* Say some thing with TTS in the conference room */
static switch_status_t conference_say(conference_obj_t *conference, char *text, uint32_t leadin)
{
confernce_file_node_t *fnode, *nptr;
@@ -2419,6 +2429,7 @@
}
+/* outbound call bridge progress call state callback handler */
static switch_status_t audio_bridge_on_ring(switch_core_session_t *session)
{
switch_channel_t *channel = NULL;
@@ -2443,6 +2454,7 @@
/*.on_hold */ NULL,
};
+/* generate an outbound call from the conference */
static switch_status_t conference_outcall(conference_obj_t *conference,
switch_core_session_t *session,
char *bridgeto,
@@ -2469,6 +2481,7 @@
}
+ /* establish an outbound call leg */
if (switch_ivr_originate(session,
&peer_session,
&cause,
@@ -2490,6 +2503,7 @@
peer_channel = switch_core_session_get_channel(peer_session);
assert(peer_channel != NULL);
+ /* make sure the conference still exists */
if (!switch_test_flag(conference, CFLAG_RUNNING)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Conference is gone now, nevermind..\n");
if (caller_channel) {
@@ -2503,8 +2517,11 @@
switch_channel_answer(caller_channel);
}
+ /* if the outbound call leg is ready */
if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
switch_caller_extension_t *extension = NULL;
+
+ /* build an extension name object */
if ((extension = switch_caller_extension_new(peer_session, conference->name, conference->name)) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "memory error!\n");
status = SWITCH_STATUS_MEMERR;
@@ -2538,6 +2555,7 @@
uint32_t x = 0;
switch_status_t status = SWITCH_STATUS_SUCCESS;
+ /* generate some space infront of the file to be played */
for (x = 0; x < leadin; x++) {
switch_frame_t *read_frame;
switch_status_t status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
@@ -2547,6 +2565,7 @@
}
}
+ /* if all is well, really play the file */
if (status == SWITCH_STATUS_SUCCESS) {
status = switch_ivr_play_file(session, NULL, path, NULL, NULL, NULL, 0);
}
@@ -2590,7 +2609,7 @@
return;
}
-
+ /* Start the conference muted or deaf ? */
if ((flags_str=strstr(mydata, flags_prefix))) {
char *p;
@@ -2607,6 +2626,7 @@
}
}
+ /* is this a bridging conference ? */
if (!strncasecmp(mydata, bridge_prefix, strlen(bridge_prefix))) {
isbr = 1;
mydata += strlen(bridge_prefix);
@@ -2620,10 +2640,12 @@
conf_name = mydata;
+ /* is there a conference pin ? */
if ((dpin = strchr(conf_name, '+'))) {
*dpin++ = '\0';
}
+ /* is there profile specification ? */
if ((profile_name = strchr(conf_name, '@'))) {
*profile_name++ = '\0';
@@ -2638,6 +2660,8 @@
}
}
+ /* if this is a bridging call, and it's not a duplicate, build a */
+ /* conference object, and skip pin handling, and locked checking */
if (isbr) {
char *uuid = switch_core_session_get_uuid(session);
@@ -2661,6 +2685,7 @@
/* Set the minimum number of members (once you go above it you cannot go below it) */
conference->min = 2;
+ /* if the dialplan specified a pin, override the profile's value */
if (dpin) {
conference->pin = switch_core_strdup(conference->pool, dpin);
}
@@ -2672,19 +2697,19 @@
launch_conference_thread(conference);
} else {
- /* Figure out what conference to call. */
+ /* if the conference exists, get the pointer to it */
if ((conference = (conference_obj_t *) switch_core_hash_find(globals.conference_hash, conf_name))) {
freepool = pool;
+ /* couldn't find the conference, create one */
} else {
- /* Create the conference object. */
conference = conference_new(conf_name, profile, pool);
-
if (!conference) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
goto done;
}
+ /* if the dialplan specified a pin, override the profile's value */
if (dpin) {
conference->pin = switch_core_strdup(conference->pool, dpin);
}
@@ -2697,7 +2722,6 @@
/* Start the conference thread for this conference */
launch_conference_thread(conference);
-
}
if (conference->pin) {
@@ -2746,13 +2770,14 @@
cxml = NULL;
}
+ /* if we're using "bridge:" make an outbound call and bridge it in */
if (!switch_strlen_zero(bridgeto) && strcasecmp(bridgeto, "none")) {
if (conference_outcall(conference, session, bridgeto, 60, NULL, NULL, NULL) != SWITCH_STATUS_SUCCESS) {
goto done;
}
} else {
- // if we're not using "bridge:" set the conference answered flag
- // and this isn't an outbound channel, answer the call
+ /* if we're not using "bridge:" set the conference answered flag */
+ /* and this isn't an outbound channel, answer the call */
if (!switch_channel_test_flag(channel, CF_OUTBOUND))
switch_set_flag(conference, CFLAG_ANSWERED);
}
@@ -2765,9 +2790,7 @@
if (switch_core_codec_init(&member.read_codec,
"L16",
NULL,
- //conference->rate,
read_codec->implementation->samples_per_second,
- //conference->interval,
read_codec->implementation->microseconds_per_frame / 1000,
1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
@@ -2804,9 +2827,7 @@
"L16",
NULL,
conference->rate,
- //read_codec->implementation->samples_per_second,
conference->interval,
- //read_codec->implementation->microseconds_per_frame / 1000,
1,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
NULL,
@@ -3215,7 +3236,7 @@
uint32_t rate = 8000, interval = 20;
switch_status_t status;
- /* Conference Name */
+ /* Validate the conference name */
if (switch_strlen_zero(name)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Record! no name.\n");
return NULL;
@@ -3331,7 +3352,7 @@
return NULL;
}
- /* Initilize the object with some settings */
+ /* initialize the conference object with settings from the specified profile */
conference->pool = pool;
conference->timer_name = switch_core_strdup(conference->pool, timer_name);
conference->tts_engine = switch_core_strdup(conference->pool, tts_engine);
@@ -3421,6 +3442,7 @@
/* Connect my internal structure to the blank pointer passed to me */
*module_interface = &conference_module_interface;
+ /* create/register custom event message type */
if (switch_event_reserve_subclass(CONF_EVENT_MAINT) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", CONF_EVENT_MAINT);
return SWITCH_STATUS_TERM;
@@ -3448,7 +3470,9 @@
if (globals.running) {
+ /* signal all threads to shutdown */
globals.running = 0;
+ /* wait for all threads */
while (globals.threads) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for %d threads\n", globals.threads);
switch_yield(100000);
1
0
[commit] r3546 - freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference
by Freeswitch SVN 05 Dec '06
by Freeswitch SVN 05 Dec '06
05 Dec '06
Author: mikej
Date: Tue Dec 5 16:29:14 2006
New Revision: 3546
Modified:
freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
manually merge r3544-3545 from trunk
Modified: freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/branches/knhor/trunk/src/mod/applications/mod_conference/mod_conference.c Tue Dec 5 16:29:14 2006
@@ -252,7 +252,7 @@
static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *obj);
static void conference_loop_output(conference_member_t *member);
static uint32_t conference_stop_file(conference_obj_t *conference, file_stop_t stop);
-static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin);
+static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel);
static switch_status_t conference_say(conference_obj_t *conference, char *text, uint32_t leadin);
static void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim);
static switch_status_t conf_api_main(char *buf, switch_core_session_t *session, switch_stream_handle_t *stream);
@@ -448,11 +448,11 @@
if (conference->enter_sound) {
- conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN);
+ conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN, switch_core_session_get_channel(member->session));
}
if (conference->count == 1 && conference->alone_sound) {
- conference_play_file(conference, conference->alone_sound, 0);
+ conference_play_file(conference, conference->alone_sound, 0, switch_core_session_get_channel(member->session));
}
if (conference->min && conference->count >= conference->min) {
@@ -521,10 +521,10 @@
switch_set_flag(conference, CFLAG_DESTRUCT);
} else {
if (conference->exit_sound) {
- conference_play_file(conference, conference->exit_sound, 0);
+ conference_play_file(conference, conference->exit_sound, 0, switch_core_session_get_channel(member->session));
}
if (conference->count == 1 && conference->alone_sound) {
- conference_play_file(conference, conference->alone_sound, 0);
+ conference_play_file(conference, conference->alone_sound, 0, switch_core_session_get_channel(member->session));
}
}
@@ -1550,11 +1550,14 @@
}
/* Play a file in the conference room */
-static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin)
+static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel)
{
confernce_file_node_t *fnode, *nptr;
switch_memory_pool_t *pool;
uint32_t count;
+ char *expanded = NULL;
+ uint8_t frexp = 0;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_mutex_lock(conference->mutex);
switch_mutex_lock(conference->member_mutex);
@@ -1566,25 +1569,36 @@
return SWITCH_STATUS_FALSE;
}
+ if (channel) {
+ if ((expanded = switch_channel_expand_variables(channel, file)) != file) {
+ file = expanded;
+ frexp = 1;
+ }
+ }
+
+
#ifdef WIN32
if (*(file +1) != ':' && *file != '/') {
#else
if (*file != '/') {
#endif
- return conference_say(conference, file, leadin);
+ status = conference_say(conference, file, leadin);
+ goto done;
}
/* Setup a memory pool to use. */
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");
- return SWITCH_STATUS_MEMERR;
+ status = SWITCH_STATUS_MEMERR;
+ goto done;
}
/* Create a node object*/
if (!(fnode = switch_core_alloc(pool, sizeof(*fnode)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Alloc Failure\n");
switch_core_destroy_memory_pool(&pool);
- return SWITCH_STATUS_MEMERR;
+ status = SWITCH_STATUS_MEMERR;
+ goto done;
}
fnode->type = NODE_TYPE_FILE;
@@ -1596,7 +1610,8 @@
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
pool) != SWITCH_STATUS_SUCCESS) {
switch_core_destroy_memory_pool(&pool);
- return SWITCH_STATUS_NOTFOUND;
+ status = SWITCH_STATUS_NOTFOUND;
+ goto done;
}
fnode->pool = pool;
@@ -1612,7 +1627,13 @@
}
switch_mutex_unlock(conference->mutex);
- return SWITCH_STATUS_SUCCESS;
+ done:
+
+ if (frexp) {
+ switch_safe_free(expanded);
+ }
+
+ return status;
}
/* Play a file in the conference room to a member */
@@ -2166,7 +2187,7 @@
switch_event_t *event;
if (argc == 3) {
- if (conference_play_file(conference, argv[2], 0) == SWITCH_STATUS_SUCCESS) {
+ if (conference_play_file(conference, argv[2], 0, NULL) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "(play) Playing file %s\n", argv[2]);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", conference->name);
1
0
05 Dec '06
Author: anthm
Date: Tue Dec 5 16:26:26 2006
New Revision: 3545
Modified:
freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
feeling lucky part 2
Modified: freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c Tue Dec 5 16:26:26 2006
@@ -1252,10 +1252,7 @@
if (*file != '/') {
#endif
status = conference_say(conference, file, leadin);
- if (frexp) {
- switch_safe_free(expanded);
- }
- return status;
+ goto done;
}
/* Setup a memory pool to use. */
1
0
05 Dec '06
Author: anthm
Date: Tue Dec 5 16:10:33 2006
New Revision: 3544
Modified:
freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
Log:
feeling lucky
Modified: freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/trunk/src/mod/applications/mod_conference/mod_conference.c Tue Dec 5 16:10:33 2006
@@ -208,7 +208,7 @@
static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *obj);
static void conference_loop(conference_member_t *member);
static uint32_t conference_stop_file(conference_obj_t *conference, file_stop_t stop);
-static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin);
+static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel);
static switch_status_t conference_say(conference_obj_t *conference, char *text, uint32_t leadin);
static void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim);
static switch_status_t conf_function(char *buf, switch_core_session_t *session, switch_stream_handle_t *stream);
@@ -387,11 +387,11 @@
if (conference->enter_sound) {
- conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN);
+ conference_play_file(conference, conference->enter_sound, CONF_DEFAULT_LEADIN, switch_core_session_get_channel(member->session));
}
if (conference->count == 1 && conference->alone_sound) {
- conference_play_file(conference, conference->alone_sound, 0);
+ conference_play_file(conference, conference->alone_sound, 0, switch_core_session_get_channel(member->session));
}
if (conference->min && conference->count >= conference->min) {
@@ -460,10 +460,10 @@
switch_set_flag(conference, CFLAG_DESTRUCT);
} else {
if (conference->exit_sound) {
- conference_play_file(conference, conference->exit_sound, 0);
+ conference_play_file(conference, conference->exit_sound, 0, switch_core_session_get_channel(member->session));
}
if (conference->count == 1 && conference->alone_sound) {
- conference_play_file(conference, conference->alone_sound, 0);
+ conference_play_file(conference, conference->alone_sound, 0, switch_core_session_get_channel(member->session));
}
}
@@ -1219,11 +1219,14 @@
}
/* Play a file in the conference rooom */
-static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin)
+static switch_status_t conference_play_file(conference_obj_t *conference, char *file, uint32_t leadin, switch_channel_t *channel)
{
confernce_file_node_t *fnode, *nptr;
switch_memory_pool_t *pool;
uint32_t count;
+ char *expanded = NULL;
+ uint8_t frexp = 0;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_mutex_lock(conference->mutex);
switch_mutex_lock(conference->member_mutex);
@@ -1235,25 +1238,39 @@
return SWITCH_STATUS_FALSE;
}
+ if (channel) {
+ if ((expanded = switch_channel_expand_variables(channel, file)) != file) {
+ file = expanded;
+ frexp = 1;
+ }
+ }
+
+
#ifdef WIN32
if (*(file +1) != ':' && *file != '/') {
#else
if (*file != '/') {
#endif
- return conference_say(conference, file, leadin);
+ status = conference_say(conference, file, leadin);
+ if (frexp) {
+ switch_safe_free(expanded);
+ }
+ return status;
}
/* Setup a memory pool to use. */
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Pool Failure\n");
- return SWITCH_STATUS_MEMERR;
+ status = SWITCH_STATUS_MEMERR;
+ goto done;
}
/* Create a node object*/
if (!(fnode = switch_core_alloc(pool, sizeof(*fnode)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Alloc Failure\n");
switch_core_destroy_memory_pool(&pool);
- return SWITCH_STATUS_MEMERR;
+ status = SWITCH_STATUS_MEMERR;
+ goto done;
}
fnode->type = NODE_TYPE_FILE;
@@ -1265,7 +1282,8 @@
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
pool) != SWITCH_STATUS_SUCCESS) {
switch_core_destroy_memory_pool(&pool);
- return SWITCH_STATUS_NOTFOUND;
+ status = SWITCH_STATUS_NOTFOUND;
+ goto done;
}
fnode->pool = pool;
@@ -1281,7 +1299,13 @@
}
switch_mutex_unlock(conference->mutex);
- return SWITCH_STATUS_SUCCESS;
+ done:
+
+ if (frexp) {
+ switch_safe_free(expanded);
+ }
+
+ return status;
}
/* Play a file in the conference rooom to a member */
@@ -1902,7 +1926,7 @@
}
} else if (!strcasecmp(argv[1], "play")) {
if (argc == 3) {
- if (conference_play_file(conference, argv[2], 0) == SWITCH_STATUS_SUCCESS) {
+ if (conference_play_file(conference, argv[2], 0, NULL) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "(play) Playing file %s\n", argv[2]);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Conference-Name", conference->name);
1
0
05 Dec '06
Author: mikej
Date: Tue Dec 5 13:58:47 2006
New Revision: 3543
Modified:
freeswitch/trunk/src/mod/event_handlers/mod_cdr/README
Log:
comment this out in the sample to avoid support issues when people use the default config.
Modified: freeswitch/trunk/src/mod/event_handlers/mod_cdr/README
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_cdr/README (original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_cdr/README Tue Dec 5 13:58:47 2006
@@ -106,7 +106,7 @@
<param name="username" value="test"/>
<param name="password" value="test"/>
<param name="dbname" value="testing"/>
- <param name="chanvars_fixed" value="username=s,The_Kow=t"/>
+ <!-- <param name="chanvars_fixed" value="username=s,The_Kow=t"/> -->
<!-- This previous line logs username as a varchar, and The_Kow as a tiny -->
<param name="chanvars_supp" value="*"/>
<param name="chanvars_supp_repeat_fixed" value="0"/>
1
0
05 Dec '06
Author: igorneves
Date: Tue Dec 5 12:41:31 2006
New Revision: 3542
Added:
freeswitch/branches/igorneves/scripts/socket/fsconsole.c
Log:
_Vile version of C socket example
Added: freeswitch/branches/igorneves/scripts/socket/fsconsole.c
==============================================================================
--- (empty file)
+++ freeswitch/branches/igorneves/scripts/socket/fsconsole.c Tue Dec 5 12:41:31 2006
@@ -0,0 +1,306 @@
+/*
+ * FreeSWITCH Console
+ */
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#define buflen 38
+#define NUL '\0'
+
+char *app = "freeswitch";
+char *version = "0.1";
+char *hostname = "127.0.0.1";
+char *secret = "ClueCon";
+unsigned int port = 8021;
+
+char *intro = "Welcome to FreeSWITCH Console.\n\n";
+
+char buffer[buflen], *command;
+int sd, flag, prompt;
+
+char *trim(char *str);
+void print_tokens(char *line);
+int fs_switch_read();
+
+// Debug level
+int debug = 3;
+
+int main(int argc, char *argv[])
+{
+ if (argv[1] == "--help") {
+ fprintf(stderr,"usage %s hostname port\n", argv[0]);
+ exit(0);
+ }
+
+ /* Hostname and Port defined on command line */
+ if (argc > 1) {
+ strncpy(hostname, argv[1], sizeof(hostname));
+ hostname = argv[1];
+ port = atoi(argv[2]);
+ }
+
+ sd = socket(AF_INET, SOCK_STREAM, 0); /* init socket descriptor */
+ struct sockaddr_in sin;
+ struct hostent *host = gethostbyname(hostname);
+
+ //char buffer[buflen];
+ int len;
+ char *p;
+ char cmd[38];
+ int i, n, out;
+
+ /*** PLACE DATA IN sockaddr_in struct ***/
+ memcpy(&sin.sin_addr.s_addr, host->h_addr, host->h_length);
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(port);
+
+ /*** CONNECT SOCKET TO THE SERVICE DESCRIBED BY sockaddr_in struct ***/
+ if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
+ {
+ perror("connecting");
+ exit(1);
+ }
+
+ flag = fcntl(sd, F_GETFL, 0);
+ flag |= O_NONBLOCK;
+ fcntl(sd, F_SETFL, flag);
+
+ printf(intro);
+
+ /* Setup the prompt */
+ prompt = 1;
+
+ while(1)
+ {
+
+ /* Prompt */
+ if (prompt)
+ {
+ printf("%s %s> ", app, version);
+ prompt = 0;
+ }
+
+ memset(buffer, 0, sizeof(buffer));
+ memset(cmd, 0, sizeof(cmd));
+
+ /* Setup the first read */
+ fs_switch_read(sd, buffer);
+
+ flag = fcntl(0, F_GETFL, 0);
+ flag |= O_NONBLOCK;
+ fcntl(0, F_SETFL, flag);
+
+ fgets(cmd, 36, stdin);
+ cmd[strlen(cmd) - 1] = 0;
+
+ if (!strcmp(cmd, "exit")) {
+ printf("Exiting.. goodbye\n");
+ exit(0);
+ }
+
+ if (!strcmp(cmd, "version")) {
+ printf("Version %s\n", version);
+ prompt = 1;
+ }
+
+ if (!strcmp(cmd, "\n")) {
+ prompt = 1;
+ }
+
+ if (fs_switch_read() > 0) {
+ // Do nothing
+ } else {
+ // Sleep
+ sleep(1);
+ }
+ }
+
+ close(sd);
+}
+
+
+
+int fs_switch_read()
+ {
+
+ int len;
+ char buf[4096], reply[4096], tmp[255], contents[4096];
+
+ char content[32];
+ char content_type[32];
+ char content_following[32];
+ char content_after[32];
+ char junk[32];
+
+ len = atoi(tmp);
+ if (len <= 0) len += 255;
+ len = recv(sd, buffer, len, 0);
+
+ if (len > 0)
+ {
+ memset(contents, 0, sizeof(contents));
+ strncpy(contents, buffer, len);
+
+ // Print Incoming input to screen
+ if (debug > 0)
+ write(1,contents,len);
+
+ char whitespace[] = "\r";
+ char *token, *token_split, *subtoken_split;
+ char token_key[32], token_val[32], token_contents[4096], subtoken_contents[4096];
+ char subtoken_key[32], subtoken_val[32];
+
+ //print_tokens(contents);
+
+ for (token=strtok(contents,whitespace); token !=NULL; token=strtok(NULL,whitespace))
+ {
+
+ //printf("Next token is %s\n", token);
+
+ sprintf(token_contents, "%s", token);
+
+ token_split = strtok(token_contents, ":");
+ sprintf(token_key, "%s", token_split);
+ token_split = strtok(NULL, "\n");
+ sprintf(token_val, "%s", token_split);
+ token_split = strtok(NULL, "\n");
+
+ token = strtok(NULL, "\n\n");
+
+ trim(token_val);
+
+ if (debug > 1)
+ printf("\nkey: '%s', val: '%s'\n", token_key, token_val);
+
+
+ if (strcmp(token_key, "Content-Type") == 0)
+ {
+
+ if (strcmp(token_val, "auth/request") == 0)
+ {
+ printf("\nAuthenticating...\n");
+
+ command = "auth";
+ sprintf(buf, "auth %s\n\n", secret);
+ write(sd, buf, strlen(buf));
+
+ } else if (strcmp(token_val, "command/reply") == 0) {
+
+ /* Parse the reply */
+ sprintf(subtoken_contents, "%s", token_split);
+
+ subtoken_split = strtok(subtoken_contents, ":");
+ sprintf(subtoken_key, "%s", subtoken_split);
+ subtoken_split = strtok(NULL, "\n");
+ sprintf(subtoken_val, "%s", subtoken_split);
+ subtoken_split = strtok(NULL, "\n");
+
+ trim(subtoken_val);
+
+ if (debug > 1)
+ printf("subkey: '%s', subval: '%s'\n", subtoken_key, subtoken_val);
+
+ if (strcmp(subtoken_key, "Reply-Text") == 0)
+ {
+ if (strcmp(subtoken_val, "+OK accepted") == 0)
+ {
+ if (strcmp(command, "auth") == 0)
+ {
+ printf("\nAuthentication Successful\n");
+ command = "";
+ }
+ }
+ }
+
+ }
+ }
+
+
+ }
+ /* Set the prompt */
+ prompt = 1;
+
+ return 1;
+ } else {
+ return 0;
+ }
+
+}
+
+
+void print_tokens(char *line)
+{
+ char whitespace[] = "\n";
+ char *token;
+
+ for (token=strtok(line,whitespace); token !=NULL; token=strtok(NULL,whitespace))
+ {
+ printf("Next token is %s\n", token);
+ }
+}
+
+
+char *trim(char *str)
+{
+ char *ibuf = str, *obuf = str;
+ int i = 0, cnt = 0;
+
+ /*
+ ** Trap NULL
+ */
+
+ if (str)
+ {
+ /*
+ ** Remove leading spaces (from RMLEAD.C)
+ */
+
+ for (ibuf = str; *ibuf && isspace(*ibuf); ++ibuf)
+ ;
+ if (str != ibuf)
+ memmove(str, ibuf, ibuf - str);
+
+ /*
+ ** Collapse embedded spaces (from LV1WS.C)
+ */
+
+ while (*ibuf)
+ {
+ if (isspace(*ibuf) && cnt)
+ ibuf++;
+ else
+ {
+ if (!isspace(*ibuf))
+ cnt = 0;
+ else
+ {
+ *ibuf = ' ';
+ cnt = 1;
+ }
+ obuf[i++] = *ibuf++;
+ }
+ }
+ obuf[i] = NUL;
+
+ /*
+ ** Remove trailing spaces (from RMTRAIL.C)
+ */
+
+ while (--i >= 0)
+ {
+ if (!isspace(obuf[i]))
+ break;
+ }
+ obuf[++i] = NUL;
+ }
+ return str;
+}
+
+
1
0
[commit] r3541 - freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python
by Freeswitch SVN 05 Dec '06
by Freeswitch SVN 05 Dec '06
05 Dec '06
Author: jkr888
Date: Tue Dec 5 11:09:36 2006
New Revision: 3541
Modified:
freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/Makefile
freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/freeswitch_python.cpp
freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/freeswitch_python.h
Log:
Modified: freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/Makefile
==============================================================================
--- freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/Makefile (original)
+++ freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/Makefile Tue Dec 5 11:09:36 2006
@@ -4,13 +4,18 @@
LDFLAGS=-lpython2.4 -Xlinker -export-dynamic -L$(PREFIX)/lib/python2.4/config/ -lutil
SWIGCFILE=../../../switch_swig.c
SWIGIFILE=../../../switch_swig.i
+CPPCC = g++
+OBJS=freeswitch_python.o
#all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(PYMOD).$(DYNAMIC_LIB_EXTEN)
-all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN)
+all: depends $(MODNAME).$(DYNAMIC_LIB_EXTEN) $(OBJS)
depends:
MAKE=$(MAKE) PY_CFLAGS=-fPIC $(BASE)/build/buildlib.sh $(BASE) install Python-2.4.3.tgz --prefix=$(PREFIX) --enable-threads
+%.o: %.cpp
+ $(CPPCC) -Wall -Werror -fPIC $(CFLAGS) -c -o $@ $<
+
%.o: %.c
$(CC) $(LCFLAGS) $(CFLAGS) -c $< -o $@
@@ -18,8 +23,9 @@
$(CC) $(LCFLAGS) $(CFLAGS) -c mod_python.c -o mod_python.o
reswig:
- rm -f switch_swig_wrap.c config.m4 CREDITS *${PYMOD}*
- swig -o switch_swig_wrap.c -l$(SWIGIFILE) -ignoremissing -DMULTIPLICITY -python -module $(PYMOD) $(SWIGCFILE)
+ # rm -f switch_swig_wrap.c config.m4 CREDITS *${PYMOD}*
+ # swig -o switch_swig_wrap.c -l$(SWIGIFILE) -ignoremissing -DMULTIPLICITY -python -module $(PYMOD) $(SWIGCFILE)
+ swig -python -shadow -c++ mod_python.i
# patch -p0 -i fix.diff
switch_swig_wrap.o: switch_swig_wrap.c Makefile
Modified: freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/freeswitch_python.cpp
==============================================================================
--- freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/freeswitch_python.cpp (original)
+++ freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/freeswitch_python.cpp Tue Dec 5 11:09:36 2006
@@ -1,8 +1,12 @@
#include "freeswitch_python.h"
-SessionContainer::SessionContainer()
+SessionContainer::SessionContainer(char *nuuid)
{
-
+ uuid = nuuid;
+ if ((session = switch_core_session_locate(uuid))) {
+ switch_core_session_rwunlock(session);
+ channel = switch_core_session_get_channel(session);
+ }
}
SessionContainer::~SessionContainer()
@@ -10,4 +14,51 @@
}
+void SessionContainer::console_log(char *level_str, char *msg)
+{
+ switch_log_level_t level = SWITCH_LOG_DEBUG;
+ if (level_str) {
+ level = switch_log_str2level(level_str);
+ }
+ switch_log_printf(SWITCH_CHANNEL_LOG, level, msg);
+}
+
+void SessionContainer::console_clean_log(char *msg)
+{
+ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN,SWITCH_LOG_DEBUG, msg);
+}
+
+void SessionContainer::answer()
+{
+ switch_channel_answer(channel);
+}
+
+void SessionContainer::pre_answer()
+{
+ switch_channel_pre_answer(channel);
+}
+
+void SessionContainer::hangup(char *cause)
+{
+ switch_channel_hangup(channel, switch_channel_str2cause(cause));
+}
+
+void SessionContainer::set_variable(char *var, char *val)
+{
+ switch_channel_set_variable(channel, var, val);
+}
+
+void SessionContainer::get_variable(char *var, char *val)
+{
+ switch_channel_get_variable(channel, var);
+}
+
+void SessionContainer::set_state(char *state)
+{
+ switch_channel_state_t current_state = switch_channel_get_state(channel);
+
+ if ((current_state = switch_channel_name_state(state)) < CS_HANGUP) {
+ switch_channel_set_state(channel, current_state);
+ }
+}
Modified: freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/freeswitch_python.h
==============================================================================
--- freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/freeswitch_python.h (original)
+++ freeswitch/branches/jkr888/trunk/src/mod/languages/mod_python/freeswitch_python.h Tue Dec 5 11:09:36 2006
@@ -1,5 +1,5 @@
#ifdef __cplusplus
-exten "C" {
+extern "C" {
#endif
#include <switch.h>
@@ -10,11 +10,20 @@
switch_channel_t *channel;
char *uuid;
public:
- SessionContainer();
+ SessionContainer(char *uuid);
~SessionContainer();
+ void console_log(char *level_str, char *msg);
+ void console_clean_log(char *msg);
+ void answer();
+ void pre_answer();
+ void hangup(char *cause);
+ void set_variable(char *var, char *val);
+ void get_variable(char *var, char *val);
+ void set_state(char *state);
protected:
};
#ifdef __cplusplus
}
#endif
+
1
0