/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application Call Detail Recorder module
*
* Copyright 2006, Author: Yossi Neiman, president of Cartis Solutions, Inc. 
* <freeswitch AT cartissolutions.com>
*
* Description: We don't need any documentation, do we?
*
* Version: MPL 1.1
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License
*
* The Core API is the FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application by
* Anthony Minnesale II <anthmct@yahoo.com>
*
* README
*
*/

mod_cdr has been written in C++ using class inheritence and virtual methods, and registers all classes that
have been built in at load time.  It then calls up the connect() method on each particular object and if successful at initializing the object, it adds it to a data structure that contains 1 instance of every sucessfully configured and connected object.  This means that at any time after loading, it will only try to create objects that are functional, skipping any that are built in but are not desired for use at the current time.

In order to use mod_cdr, you must uncomment this line in the freeswitch.xml configuration file located in the conf directory:  <load module="mod_cdr"/> in the <modules> section.  Then below this section, you need to uncomment this section <configuration name="mod_cdr.conf" description="CDR Configuration"> and input the per class configurations.  All class specific configurations go within this parent section as a subsection.

There are currently the following types of loggers:

Class: 		CsvCDR, located in csvcdr.h and csvcdr.cpp
Description:	This is the standard CSV output class.  It has a default list of CDR elements that it always
		logs, and the user can specify channel variables to be logged in a fixed order (chanvars_fixed) starting after the last default value to be logged.  Additionally, the user can specify additional channel variables to be logged after the fixed order channel variables as key=value pairs.
Configuration:	Section name: <csvcdr>
		<param name="path" value=""/>  value is the location to put the files (required)         <param name="size_limit" value=""/> value is the size limit of the output file, default value of 10MB (optional)
		<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.
		
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
		containing all the information.  It does not distinguish between fixed and supplemental channel variables.  If you are running freeswitch in a high volume environment, it is important to note that these individual files are small,  often times between 750 and 1500 bytes.  It is therefore recommended to use a partition with small cluster sizes or (on systems supporting) on reiserfs or reiser4 filesystems which are both excellent handlers of large numbers of small files.
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)

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.
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_supp" value=""/> value is a comma separated list of supplemental channel variables to log.  Can be a wildcard (*) (optional)
		<param name="chanvars_supp_repeat_fixed" value=""/> value is 0 for no, 1 for yes, and determines whether or not to repeat any of the fixed channel variables as key / value pairs in the chanvars table.

FAQ:

Q: Why C++?
A: Why not?  It works well in this design.

Q: Why is there a distinction between fixed and supplemental channel variables?
A: There is a distinction so that a level of uniformity can be maintain on those loggers that require uniformity.  For example, if you expect that channel variable FOO will always been at a specific location on a CSV row, then it is required that it be a fixed channel variable.  The fixed means that it is a fixed position, and needs to be logged even if it is blank.  Supplemental channel variables, on the other hand, are more dynamic, and will only log those channel variables that actually exist on that given leg of the call.  That means that if you supply a wildcard, it will simply iterate all the channel variables.  If you do not want to repeat the fixed channel variables in the supplemental channel variables, it will then remove the fixed channel variables from the data structure holding the supplemental channel variables even before the process_record() method is called up.

Q: What would an example configuration look like?
A: Here is an excerpt from the freeswitch XML configuration file:

	<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="*"/>
		</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"/>
		</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 -->
			<param name="chanvars_supp" value="*"/>
			<param name="chanvars_supp_repeat_fixed" value="0"/>
		</mysqlcdr>
	</configuration>
