Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
cdr_manager.c File Reference

Asterisk Call Manager CDR records. More...

#include "asterisk.h"
#include <time.h>
#include "asterisk/channel.h"
#include "asterisk/cdr.h"
#include "asterisk/module.h"
#include "asterisk/utils.h"
#include "asterisk/manager.h"
#include "asterisk/config.h"
#include "asterisk/pbx.h"
Include dependency graph for cdr_manager.c:

Go to the source code of this file.

Macros

#define CONF_FILE   "cdr_manager.conf"
 
#define CUSTOM_FIELDS_BUF_SIZE   1024
 
#define DATE_FORMAT   "%Y-%m-%d %T"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int load_config (int reload)
 
static int load_module (void)
 
static int manager_log (struct ast_cdr *cdr)
 
static int reload (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Manager Interface CDR Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, .requires = "cdr", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_strcustomfields
 
static ast_rwlock_t customfields_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
 
static int enablecdr = 0
 
static const char name [] = "cdr_manager"
 

Detailed Description

Asterisk Call Manager CDR records.

See also

Definition in file cdr_manager.c.

Macro Definition Documentation

◆ CONF_FILE

#define CONF_FILE   "cdr_manager.conf"

Definition at line 180 of file cdr_manager.c.

Referenced by load_config().

◆ CUSTOM_FIELDS_BUF_SIZE

#define CUSTOM_FIELDS_BUF_SIZE   1024

Definition at line 181 of file cdr_manager.c.

Referenced by load_config(), and manager_log().

◆ DATE_FORMAT

#define DATE_FORMAT   "%Y-%m-%d %T"

Definition at line 179 of file cdr_manager.c.

Referenced by manager_log().

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 375 of file cdr_manager.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 375 of file cdr_manager.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 375 of file cdr_manager.c.

◆ load_config()

static int load_config ( int  reload)
static

Definition at line 192 of file cdr_manager.c.

References ast_category_browse(), ast_cdr_backend_suspend(), ast_cdr_backend_unsuspend(), ast_config_destroy(), ast_config_load, ast_free, ast_log, ast_rwlock_unlock, ast_rwlock_wrlock, ast_str_append(), ast_str_create, ast_str_size(), ast_str_strlen(), ast_strlen_zero, ast_true(), ast_variable_browse(), CONF_FILE, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, CUSTOM_FIELDS_BUF_SIZE, customfields_lock, enablecdr, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, name, ast_variable::next, NULL, and ast_variable::value.

Referenced by load_module(), and reload().

193 {
194  char *cat = NULL;
195  struct ast_config *cfg;
196  struct ast_variable *v;
197  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
198  int newenablecdr = 0;
199 
200  cfg = ast_config_load(CONF_FILE, config_flags);
201  if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
202  return 0;
203  }
204 
205  if (cfg == CONFIG_STATUS_FILEINVALID) {
206  ast_log(LOG_ERROR, "Config file '%s' could not be parsed\n", CONF_FILE);
207  return -1;
208  }
209 
210  if (!cfg) {
211  /* Standard configuration */
212  ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
213  if (enablecdr) {
215  }
216  enablecdr = 0;
217  return -1;
218  }
219 
220  if (reload) {
222  }
223 
224  if (reload && customfields) {
226  customfields = NULL;
227  }
228 
229  while ( (cat = ast_category_browse(cfg, cat)) ) {
230  if (!strcasecmp(cat, "general")) {
231  v = ast_variable_browse(cfg, cat);
232  while (v) {
233  if (!strcasecmp(v->name, "enabled"))
234  newenablecdr = ast_true(v->value);
235 
236  v = v->next;
237  }
238  } else if (!strcasecmp(cat, "mappings")) {
240  v = ast_variable_browse(cfg, cat);
241  while (v) {
242  if (customfields && !ast_strlen_zero(v->name) && !ast_strlen_zero(v->value)) {
243  if ((ast_str_strlen(customfields) + strlen(v->value) + strlen(v->name) + 14) < ast_str_size(customfields)) {
244  ast_str_append(&customfields, -1, "%s: ${CDR(%s)}\r\n", v->value, v->name);
245  ast_log(LOG_NOTICE, "Added mapping %s: ${CDR(%s)}\n", v->value, v->name);
246  } else {
247  ast_log(LOG_WARNING, "No more buffer space to add other custom fields\n");
248  break;
249  }
250 
251  }
252  v = v->next;
253  }
254  }
255  }
256 
257  if (reload) {
259  }
260 
261  ast_config_destroy(cfg);
262 
263  if (!newenablecdr) {
265  } else if (newenablecdr) {
267  }
268  enablecdr = newenablecdr;
269 
270  return 0;
271 }
struct ast_variable * next
int ast_cdr_backend_suspend(const char *name)
Suspend a CDR backend temporarily.
Definition: cdr.c:2866
static int enablecdr
Definition: cdr_manager.c:185
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1216
static struct ast_str * customfields
Definition: cdr_manager.c:187
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:699
#define LOG_WARNING
Definition: logger.h:274
static int reload(void)
Definition: cdr_manager.c:363
#define CUSTOM_FIELDS_BUF_SIZE
Definition: cdr_manager.c:181
int ast_cdr_backend_unsuspend(const char *name)
Unsuspend a CDR backend.
Definition: cdr.c:2884
#define CONFIG_STATUS_FILEINVALID
Structure for variables, used for configurations and for channel variables.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
Definition: extconf.c:3328
#define NULL
Definition: resample.c:96
#define ast_rwlock_unlock(a)
Definition: lock.h:232
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
#define ast_config_load(filename, flags)
Load a config file.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: extconf.c:1290
#define CONF_FILE
Definition: cdr_manager.c:180
#define CONFIG_STATUS_FILEUNCHANGED
#define LOG_ERROR
Definition: logger.h:285
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".
Definition: main/utils.c:1951
static const char name[]
Definition: cdr_manager.c:183
#define LOG_NOTICE
Definition: logger.h:263
#define ast_free(a)
Definition: astmm.h:182
Structure used to handle boolean flags.
Definition: utils.h:199
#define ast_rwlock_wrlock(a)
Definition: lock.h:234
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
static ast_rwlock_t customfields_lock
Definition: cdr_manager.c:188
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620

◆ load_module()

static int load_module ( void  )
static

Definition at line 349 of file cdr_manager.c.

References ast_cdr_register(), ast_cdr_unregister(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, load_config(), manager_log(), and name.

Referenced by reload().

350 {
351  if (ast_cdr_register(name, "Asterisk Manager Interface CDR Backend", manager_log)) {
353  }
354 
355  if (load_config(0)) {
358  }
359 
361 }
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
Definition: cdr.c:2988
static int load_config(int reload)
Definition: cdr_manager.c:192
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
Definition: cdr.c:2943
static const char name[]
Definition: cdr_manager.c:183
static int manager_log(struct ast_cdr *cdr)
Definition: cdr_manager.c:273
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78

◆ manager_log()

static int manager_log ( struct ast_cdr cdr)
static

Definition at line 273 of file cdr_manager.c.

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_cdr_dup(), ast_channel_amaflags2string(), ast_channel_cdr_set(), ast_channel_unref, ast_dummy_channel_alloc, ast_localtime(), ast_log, ast_rwlock_rdlock, ast_rwlock_unlock, ast_str_buffer(), ast_str_strlen(), ast_strftime(), ast_cdr::billsec, buf, ast_cdr::channel, ast_cdr::clid, CUSTOM_FIELDS_BUF_SIZE, customfields_lock, DATE_FORMAT, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, dummy(), ast_cdr::duration, enablecdr, ast_cdr::end, EVENT_FLAG_CDR, ast_cdr::lastapp, ast_cdr::lastdata, LOG_ERROR, manager_event, NULL, pbx_substitute_variables_helper(), ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.

Referenced by load_module().

274 {
275  struct ast_tm timeresult;
276  char strStartTime[80] = "";
277  char strAnswerTime[80] = "";
278  char strEndTime[80] = "";
280 
281  if (!enablecdr)
282  return 0;
283 
284  ast_localtime(&cdr->start, &timeresult, NULL);
285  ast_strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult);
286 
287  if (cdr->answer.tv_sec) {
288  ast_localtime(&cdr->answer, &timeresult, NULL);
289  ast_strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult);
290  }
291 
292  ast_localtime(&cdr->end, &timeresult, NULL);
293  ast_strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult);
294 
295  buf[0] = '\0';
299  if (!dummy) {
300  ast_log(LOG_ERROR, "Unable to allocate channel for variable substitution.\n");
301  return 0;
302  }
303  ast_channel_cdr_set(dummy, ast_cdr_dup(cdr));
304  pbx_substitute_variables_helper(dummy, ast_str_buffer(customfields), buf, sizeof(buf) - 1);
305  ast_channel_unref(dummy);
306  }
308 
310  "AccountCode: %s\r\n"
311  "Source: %s\r\n"
312  "Destination: %s\r\n"
313  "DestinationContext: %s\r\n"
314  "CallerID: %s\r\n"
315  "Channel: %s\r\n"
316  "DestinationChannel: %s\r\n"
317  "LastApplication: %s\r\n"
318  "LastData: %s\r\n"
319  "StartTime: %s\r\n"
320  "AnswerTime: %s\r\n"
321  "EndTime: %s\r\n"
322  "Duration: %ld\r\n"
323  "BillableSeconds: %ld\r\n"
324  "Disposition: %s\r\n"
325  "AMAFlags: %s\r\n"
326  "UniqueID: %s\r\n"
327  "UserField: %s\r\n"
328  "%s",
329  cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel,
330  cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime,
331  cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition),
333 
334  return 0;
335 }
#define ast_rwlock_rdlock(a)
Definition: lock.h:233
#define EVENT_FLAG_CDR
Definition: manager.h:81
Main Channel structure associated with a channel.
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:308
static int enablecdr
Definition: cdr_manager.c:185
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:288
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
static struct ast_str * customfields
Definition: cdr_manager.c:187
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
long int billsec
Definition: cdr.h:302
#define CUSTOM_FIELDS_BUF_SIZE
Definition: cdr_manager.c:181
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static void dummy(char *unused,...)
Definition: chan_unistim.c:220
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:284
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition: localtime.c:1739
struct ast_cdr * ast_cdr_dup(struct ast_cdr *cdr)
Duplicate a public CDR.
Definition: cdr.c:2998
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition: channel.c:4418
#define NULL
Definition: resample.c:96
#define ast_rwlock_unlock(a)
Definition: lock.h:232
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:292
long int amaflags
Definition: cdr.h:306
#define ast_log
Definition: astobj2.c:42
void ast_channel_cdr_set(struct ast_channel *chan, struct ast_cdr *value)
#define ast_dummy_channel_alloc()
Create a fake channel structure.
Definition: channel.h:1283
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:314
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:282
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:286
struct timeval answer
Definition: cdr.h:296
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:290
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:3430
#define LOG_ERROR
Definition: logger.h:285
struct timeval start
Definition: cdr.h:294
long int duration
Definition: cdr.h:300
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...
Definition: localtime.c:2524
char src[AST_MAX_EXTENSION]
Definition: cdr.h:280
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:688
struct timeval end
Definition: cdr.h:298
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: ael_main.c:211
long int disposition
Definition: cdr.h:304
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:278
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:248
static ast_rwlock_t customfields_lock
Definition: cdr_manager.c:188
#define DATE_FORMAT
Definition: cdr_manager.c:179
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:318

◆ reload()

static int reload ( void  )
static

Definition at line 363 of file cdr_manager.c.

References AST_MODFLAG_LOAD_ORDER, AST_MODPRI_CDR_DRIVER, AST_MODULE_INFO(), AST_MODULE_SUPPORT_CORE, ASTERISK_GPL_KEY, load_config(), load_module(), and unload_module().

364 {
365  return load_config(1);
366 }
static int load_config(int reload)
Definition: cdr_manager.c:192

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 337 of file cdr_manager.c.

References ast_cdr_unregister(), ast_free, and name.

Referenced by reload().

338 {
339  if (ast_cdr_unregister(name)) {
340  return -1;
341  }
342 
343  if (customfields)
345 
346  return 0;
347 }
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
Definition: cdr.c:2988
static struct ast_str * customfields
Definition: cdr_manager.c:187
static const char name[]
Definition: cdr_manager.c:183
#define ast_free(a)
Definition: astmm.h:182

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Asterisk Manager Interface CDR Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "30ef0c93b36035ec78c9cfd712d36d9b" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, .requires = "cdr", }
static

Definition at line 375 of file cdr_manager.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 375 of file cdr_manager.c.

◆ customfields

struct ast_str* customfields
static

Definition at line 187 of file cdr_manager.c.

◆ customfields_lock

ast_rwlock_t customfields_lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} }
static

Definition at line 188 of file cdr_manager.c.

Referenced by load_config(), and manager_log().

◆ enablecdr

int enablecdr = 0
static

Definition at line 185 of file cdr_manager.c.

Referenced by load_config(), and manager_log().

◆ name

const char name[] = "cdr_manager"
static

Definition at line 183 of file cdr_manager.c.

Referenced by load_config(), load_module(), and unload_module().