179 #define DATE_FORMAT "%Y-%m-%d %T"
180 #define CONF_FILE "cdr_manager.conf"
181 #define CUSTOM_FIELDS_BUF_SIZE 1024
183 static const char name[] =
"cdr_manager";
185 static int enablecdr = 0;
187 static struct ast_str *customfields;
188 AST_RWLOCK_DEFINE_STATIC(customfields_lock);
190 static int manager_log(
struct ast_cdr *cdr);
192 static int load_config(
int reload)
198 int newenablecdr = 0;
201 if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
205 if (cfg == CONFIG_STATUS_FILEINVALID) {
206 ast_log(LOG_ERROR,
"Config file '%s' could not be parsed\n", CONF_FILE);
212 ast_log(LOG_WARNING,
"Failed to load configuration file. Module not activated.\n");
221 ast_rwlock_wrlock(&customfields_lock);
224 if (reload && customfields) {
225 ast_free(customfields);
230 if (!strcasecmp(cat,
"general")) {
231 v = ast_variable_browse(cfg, cat);
233 if (!strcasecmp(v->
name,
"enabled"))
238 }
else if (!strcasecmp(cat,
"mappings")) {
240 v = ast_variable_browse(cfg, cat);
242 if (customfields && !ast_strlen_zero(v->
name) && !ast_strlen_zero(v->
value)) {
245 ast_log(LOG_NOTICE,
"Added mapping %s: ${CDR(%s)}\n", v->
value, v->
name);
247 ast_log(LOG_WARNING,
"No more buffer space to add other custom fields\n");
258 ast_rwlock_unlock(&customfields_lock);
265 }
else if (newenablecdr) {
268 enablecdr = newenablecdr;
273 static int manager_log(
struct ast_cdr *cdr)
276 char strStartTime[80] =
"";
277 char strAnswerTime[80] =
"";
278 char strEndTime[80] =
"";
279 char buf[CUSTOM_FIELDS_BUF_SIZE];
285 ast_strftime(strStartTime,
sizeof(strStartTime), DATE_FORMAT, &timeresult);
287 if (cdr->answer.tv_sec) {
289 ast_strftime(strAnswerTime,
sizeof(strAnswerTime), DATE_FORMAT, &timeresult);
293 ast_strftime(strEndTime,
sizeof(strEndTime), DATE_FORMAT, &timeresult);
296 ast_rwlock_rdlock(&customfields_lock);
300 ast_log(LOG_ERROR,
"Unable to allocate channel for variable substitution.\n");
304 pbx_substitute_variables_helper(dummy,
ast_str_buffer(customfields), buf,
sizeof(buf) - 1);
307 ast_rwlock_unlock(&customfields_lock);
310 "AccountCode: %s\r\n"
312 "Destination: %s\r\n"
313 "DestinationContext: %s\r\n"
316 "DestinationChannel: %s\r\n"
317 "LastApplication: %s\r\n"
323 "BillableSeconds: %ld\r\n"
324 "Disposition: %s\r\n"
337 static int unload_module(
void)
344 ast_free(customfields);
349 static int load_module(
void)
355 if (load_config(0)) {
363 static int reload(
void)
365 return load_config(1);
368 AST_MODULE_INFO(
ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,
"Asterisk Manager Interface CDR Backend",
369 .support_level = AST_MODULE_SUPPORT_CORE,
371 .unload = unload_module,
struct ast_variable * next
int ast_cdr_backend_suspend(const char *name)
Suspend a CDR backend temporarily.
Main Channel structure associated with a channel.
char accountcode[AST_MAX_ACCOUNT_CODE]
Asterisk main include file. File version handling, generic pbx functions.
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
char dstchannel[AST_MAX_EXTENSION]
#define ast_channel_unref(c)
Decrease channel reference count.
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Time-related functions and macros.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
int ast_cdr_backend_unsuspend(const char *name)
Unsuspend a CDR backend.
char dcontext[AST_MAX_EXTENSION]
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Structure for variables, used for configurations and for channel variables.
struct ast_cdr * ast_cdr_dup(struct ast_cdr *cdr)
Duplicate a public CDR.
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
char lastdata[AST_MAX_EXTENSION]
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
General Asterisk PBX channel definitions.
#define ast_dummy_channel_alloc()
Create a fake channel structure.
char uniqueid[AST_MAX_UNIQUEID]
char dst[AST_MAX_EXTENSION]
Core PBX routines and definitions.
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
Responsible for call detail data.
char lastapp[AST_MAX_EXTENSION]
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Support for dynamic strings.
const ast_string_field name
Module has failed to load, may be in an inconsistent state.
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Structure used to handle boolean flags.
char src[AST_MAX_EXTENSION]
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
char clid[AST_MAX_EXTENSION]
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Asterisk module definitions.
char userfield[AST_MAX_USER_FIELD]
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.