/*
* gkacct.h
*
* Accounting modules for GNU Gatekeeper. Provides generic
* support for accounting to the gatekeeper.
*
* Copyright (c) 2003, Quarcom FHU, Michal Zygmuntowicz
*
* This work is published under the GNU Public License (GPL)
* see file COPYING for details.
* We also explicitely grant the right to link this code
* with the OpenH323 library.
*
* $Log: gkacct.h,v $
* Revision 1.19 2006/04/14 13:56:19 willamowius
* call failover code merged
*
* Revision 1.1.1.1 2005/11/21 20:19:57 willamowius
*
*
* Revision 1.4 2005/11/15 19:52:56 jan
* Michal v1 (works, but on in routed, not proxy mode)
*
* Revision 1.18 2005/04/24 16:39:44 zvision
* MSVC6.0 compatibility fixed
*
* Revision 1.17 2005/01/17 08:42:25 zvision
* Compilation error fixed (missing std:: prefix before map)
*
* Revision 1.16 2005/01/16 22:37:15 zvision
* Redundant config reload mutex removed
*
* Revision 1.15 2005/01/10 23:49:06 willamowius
* provide mechanism for accounting modules to escape the parameters
*
* Revision 1.14 2005/01/05 15:42:40 willamowius
* new accounting event 'connect', parameter substitution unified in parent class
*
* Revision 1.13 2004/11/15 23:57:41 zvision
* Ability to choose between the original and the rewritten dialed number
*
* Revision 1.12 2004/11/10 18:30:41 zvision
* Ability to customize timestamp strings
*
* Revision 1.11 2004/06/25 13:33:18 zvision
* Better Username, Calling-Station-Id and Called-Station-Id handling.
* New SetupUnreg option in Gatekeeper::Auth section.
*
* Revision 1.10 2004/05/22 12:17:12 zvision
* Parametrized FileAcct CDR format
*
* Revision 1.9 2004/05/12 11:49:08 zvision
* New flexible CDR file rotation
*
* Revision 1.8 2004/04/17 11:43:42 zvision
* Auth/acct API changes.
* Header file usage more consistent.
*
* Revision 1.7 2003/10/31 00:01:23 zvision
* Improved accounting modules stacking control, optimized radacct/radauth a bit
*
* Revision 1.6 2003/10/08 12:40:48 zvision
* Realtime accounting updates added
*
* Revision 1.5 2003/09/29 16:11:44 zvision
* Added cvs Id keyword to header #define macro
*
* Revision 1.4 2003/09/16 11:25:10 zvision
* Optimization for configurations without accounting enabled
*
* Revision 1.3 2003/09/14 21:09:29 zvision
* Added new FileAcct logger from Tamas Jalsovszky. Thanks!
* Fixed module stacking. Redesigned API.
*
* Revision 1.2 2003/09/12 16:31:16 zvision
* Accounting initially added to the 2.2 branch
*
* Revision 1.1.2.1 2003/06/19 15:36:04 zvision
* Initial generic accounting support for GNU GK.
*
*/
#ifndef __GKACCT_H
#define __GKACCT_H "@(#) $Id: gkacct.h,v 1.19 2006/04/14 13:56:19 willamowius Exp $"
#include <list>
#include "name.h"
#include "factory.h"
#include "RasTbl.h"
/** Module for logging accounting events
generated by the gatekeeper.
*/
class GkAcctLogger : public NamedObject
{
public:
/// Processing type for this module
enum Control
{
/// if cannot log an accounting event
/// silently ignore the module and process remaining acct modules
Optional,
/// if cannot log an accounting event do not allow futher
/// call processing (e.g. call should not be connected, etc.)
/// always process remaining acct modules
Required,
/// if cannot log an accounting event do not allow futher
/// call processing (e.g. call should not be connected, etc.)
/// - always process remaining acct modules,
/// if the event has been logged, do not process remaining acct modules
/// and allow further call processing
Sufficient,
/// if cannot log an accounting event ignore the module
/// and process remaining acct modules,
/// if the event has been logged, do not process remaining acct modules
/// and allow further call processing
Alternative
};
/// status of the acct event processing
enum Status
{
Ok = 1, /// acct event has been logged
Fail = -1, /// acct event has not been logged (failure)
Next = 0 /// acct event has not been logged because the event type
/// is not supported/not configured for this module
};
/// accounting event types
enum AcctEvent
{
AcctStart = 0x0001, /// log call start
AcctStop = 0x0002, /// log call stop (disconnect)
AcctUpdate = 0x0004, /// /// call progress update
AcctOn = 0x0008, /// accounting enabled (GK start)
AcctOff = 0x0010, /// accounting disabled (GK stop)
AcctConnect = 0x0020, /// call connected
AcctAll = -1,
AcctNone = 0
};
/// Construct new accounting logger object.
GkAcctLogger(
/// module name (should be unique among different module types)
const char* moduleName,
/// name for a config section with logger settings
/// pass NULL to use the moduleName as the section name
const char* cfgSecName = NULL
);
virtual ~GkAcctLogger();
/** @return
Control flag determining processing behaviour for this module
(optional,sufficient,required).
*/
Control GetControlFlag() const { return m_controlFlag; }
/** @return
Flags signalling which accounting events (see #AcctEvent enum#)
should be logged. The flags are ORed.
*/
int GetEnabledEvents() const { return m_enabledEvents; }
/** @return
All events supported by the module ORed together.
*/
int GetSupportedEvents() const { return m_supportedEvents; }
/** Log an accounting event with this logger.
@return
Status of this logging operation (see #Status enum#)
*/
virtual Status Log(
AcctEvent evt, /// accounting event to log
const callptr& call /// a call associated with the event (if any)
);
protected:
/** @return
A pointer to configuration settings for this logger.
*/
PConfig* GetConfig() const { return m_config; }
/** @return
A name of the config file section with settings for the logger module.
*/
const PString& GetConfigSectionName() const { return m_configSectionName; }
/** Set which accounting events should be processed by this module.
It is important to call this from derived module constructor
to set which accounting events are recognized by this module.
*/
void SetSupportedEvents(
const int events
) { m_supportedEvents = events; }
/** Fill the map with accounting parameters (name => value associations).
*/
virtual void SetupAcctParams(
/// accounting parameters (name => value) associations
std::map<PString, PString>& params,
/// call (if any) associated with an accounting event being logged
const callptr& call,
/// timestamp formatting string
const PString& timestampFormat
) const;
/** Replace accounting parameters placeholders (%a, %{Name}, ...) with
actual values.
@return
New string with all parameters replaced.
*/
PString ReplaceAcctParams(
/// parametrized accounting string
const PString& cdrStr,
/// parameter values
const std::map<PString, PString>& params
) const;
/** Escape accounting parameters; called for each value before inserting.
Subclass this for all accounting modules that need escaping.
Default implementation doesn't modify the parameter.
@return
escaped string
*/
virtual PString EscapeAcctParam(const PString& param) const;
/** Read a list of events to be logged (ORed #AccEvent enum# constants)
from the passed tokens. Override this method if new event types
are being introduced in derived loggers, then invokde it from constructor.
@return
Resulting event mask.
*/
int GetEvents(
const PStringArray& tokens /// event names (start from index 1)
) const;
/** @return
A string that can be used to identify an account name
associated with the call.
*/
virtual PString GetUsername(
/// call (if any) associated with the RAS message
const callptr& call
) const;
/** @return
A string that can be used to identify a calling number.
*/
virtual PString GetCallingStationId(
/// call associated with the accounting event
const callptr& call
) const;
/** @return
A string that can be used to identify a calling number.
*/
virtual PString GetCalledStationId(
/// call associated with the accounting event
const callptr& call
) const;
/// @return A number actually dialed by the user (before rewrite)
virtual PString GetDialedNumber(
/// call associated with the accounting event
const callptr& call
) const;
private:
GkAcctLogger();
GkAcctLogger(const GkAcctLogger&);
GkAcctLogger & operator=(const GkAcctLogger&);
private:
/// processing behaviour (see #Control enum#)
Control m_controlFlag;
/// status for "default" logger - accept (Ok) or reject (Fail)
Status m_defaultStatus;
/// ORed #AcctEvent enum# constants - define which events are logged
int m_enabledEvents;
/// all supported (recongized) event types ORed together
int m_supportedEvents;
/// module settings
PConfig* m_config;
/// name for the config section with logger settings
PString m_configSectionName;
};
/**
Plain text file accounting module for GNU Gatekeeper.
Based on source source code from Tamas Jalsovszky
Copyright (c) 2003, eWorld Com, Tamas Jalsovszky
*/
class GkTimer;
class FileAcct : public GkAcctLogger
{
public:
enum Constants {
/// events recognized by this module
FileAcctEvents = AcctStop
};
enum RotationIntervals {
Hourly,
Daily,
Weekly,
Monthly,
RotationIntervalMax
};
/// Create GkAcctLogger for plain text file accounting
FileAcct(
/// name from Gatekeeper::Acct section
const char* moduleName,
/// name for a config section with logger settings
/// pass NULL to use the moduleName as the section name
const char* cfgSecName = NULL
);
/// Destroy the accounting logger
virtual ~FileAcct();
/// override from GkAcctLogger
virtual Status Log(
AcctEvent evt,
const callptr& call
);
/** Rotate the detail file, saving old file contents to a different
file and starting with a new one. This is a callback function
called when the rotation timer expires.
*/
void RotateOnTimer(
GkTimer* timer /// timer object that triggered rotation
);
protected:
/** Called to get CDR text to be stored in the CDR file.
Can be overriden to provide custom CDR text.
@return
true if the text is available, false otherwise
*/
virtual bool GetCDRText(
PString& cdrString, /// PString for the resulting CDR line
AcctEvent evt, /// accounting event being processed
const callptr& call /// call associated with this request (if any)
);
/** @return
True if the CDR file should be rotated.
*/
virtual bool IsRotationNeeded();
/** @return
Pointer to the opened file or NULL, if the operation failed.
*/
virtual PTextFile* OpenCDRFile(
const PFilePath& fn /// name of the file to open
);
/** Rotate the detail file, saving old file contents to a different
file and starting with a new one.
*/
void Rotate();
private:
/// parse rotation interval from the config
void GetRotateInterval(
PConfig& cfg, /// the config
const PString& section /// name of the config section to check
);
/* No default constructor allowed */
FileAcct();
/* No copy constructor allowed */
FileAcct(const FileAcct&);
/* No operator= allowed */
FileAcct& operator=(const FileAcct&);
private:
/// Plain text file name
PString m_cdrFilename;
/// File object
PTextFile* m_cdrFile;
/// for mutual file access
PMutex m_cdrFileMutex;
/// rotate file after the specified amount of lines is reached (if > 0)
long m_rotateLines;
/// rotate file after the specified fize size is reached (if > 0)
long m_rotateSize;
/// rotate file after the specified period of time (if >= 0)
int m_rotateInterval;
/// a minute when the interval based rotation should occur
int m_rotateMinute;
/// an hour when the interval based rotation should occur
int m_rotateHour;
/// day of the month (or of the week) for the interval based rotation
int m_rotateDay;
/// timer for rotation events
GkTimer* m_rotateTimer;
/// number of CDRs written (if rotation per number of lines is enabled)
long m_cdrLines;
/// if true, ignore CDR string and write CDRs in a standard format
bool m_standardCDRFormat;
/// parametrized CDR string
PString m_cdrString;
/// timestamp formatting string
PString m_timestampFormat;
/// human readable names for rotation intervals
static const char* const m_intervalNames[];
};
/// Factory for instances of GkAcctLogger-derived classes
template<class Acct>
struct GkAcctLoggerCreator : public Factory<GkAcctLogger>::Creator0 {
GkAcctLoggerCreator(const char* moduleName) : Factory<GkAcctLogger>::Creator0(moduleName) {}
virtual GkAcctLogger* operator()() const { return new Acct(m_id); }
};
class GkAcctLoggerList
{
public:
/** Construct an empty list of accounting loggers.
*/
GkAcctLoggerList();
/** Destroy the list of accounting loggers.
*/
~GkAcctLoggerList();
/** Apply configuration changes to the list of accounting loggers.
Usually it means destroying the old list and creating a new one.
*/
void OnReload();
/** Log accounting event with all active accounting loggers.
@return
true if the event has been successfully logged, false otherwise.
*/
bool LogAcctEvent(
GkAcctLogger::AcctEvent evt, /// the accounting event to be logged
const callptr& call, /// a call associated with the event (if any)
time_t now = 0 /// "now" timestamp for accounting update events
);
private:
GkAcctLoggerList(const GkAcctLogger&);
GkAcctLoggerList& operator=(const GkAcctLoggerList&);
private:
/// head of the accounting loggers list
std::list<GkAcctLogger*> m_loggers;
/// interval (seconds) between subsequent accounting updates for calls
long m_acctUpdateInterval;
};
#endif /* __GKACCT_H */
syntax highlighted by Code2HTML, v. 0.9.1