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"
Go to the source code of this file.
Defines | |
#define | CONF_FILE "cdr_manager.conf" |
#define | CUSTOM_FIELDS_BUF_SIZE 1024 |
#define | DATE_FORMAT "%Y-%m-%d %T" |
Functions | |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Asterisk Manager Interface CDR Backend",.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CDR_DRIVER,) | |
AST_RWLOCK_DEFINE_STATIC (customfields_lock) | |
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_str * | customfields |
static int | enablecdr = 0 |
static const char | name [] = "cdr_manager" |
Asterisk Call Manager CDR records.
See also
Definition in file cdr_manager.c.
#define CONF_FILE "cdr_manager.conf" |
Definition at line 47 of file cdr_manager.c.
Referenced by load_config().
#define CUSTOM_FIELDS_BUF_SIZE 1024 |
Definition at line 48 of file cdr_manager.c.
Referenced by load_config(), and manager_log().
#define DATE_FORMAT "%Y-%m-%d %T" |
Definition at line 46 of file cdr_manager.c.
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_LOAD_ORDER | , | |||
"Asterisk Manager Interface CDR Backend" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload , |
|||
. | load_pri = AST_MODPRI_CDR_DRIVER | |||
) |
AST_RWLOCK_DEFINE_STATIC | ( | customfields_lock | ) |
static int load_config | ( | int | reload | ) | [static] |
Definition at line 59 of file cdr_manager.c.
References ast_category_browse(), ast_cdr_register(), ast_cdr_unregister(), 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, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_log(), ast_variable::name, ast_variable::next, and ast_variable::value.
Referenced by load_module(), and reload().
00060 { 00061 char *cat = NULL; 00062 struct ast_config *cfg; 00063 struct ast_variable *v; 00064 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 00065 int newenablecdr = 0; 00066 00067 cfg = ast_config_load(CONF_FILE, config_flags); 00068 if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 00069 return 0; 00070 } 00071 00072 if (cfg == CONFIG_STATUS_FILEINVALID) { 00073 ast_log(LOG_ERROR, "Config file '%s' could not be parsed\n", CONF_FILE); 00074 return -1; 00075 } 00076 00077 if (!cfg) { 00078 /* Standard configuration */ 00079 ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n"); 00080 if (enablecdr) 00081 ast_cdr_unregister(name); 00082 enablecdr = 0; 00083 return -1; 00084 } 00085 00086 if (reload) { 00087 ast_rwlock_wrlock(&customfields_lock); 00088 } 00089 00090 if (reload && customfields) { 00091 ast_free(customfields); 00092 customfields = NULL; 00093 } 00094 00095 while ( (cat = ast_category_browse(cfg, cat)) ) { 00096 if (!strcasecmp(cat, "general")) { 00097 v = ast_variable_browse(cfg, cat); 00098 while (v) { 00099 if (!strcasecmp(v->name, "enabled")) 00100 newenablecdr = ast_true(v->value); 00101 00102 v = v->next; 00103 } 00104 } else if (!strcasecmp(cat, "mappings")) { 00105 customfields = ast_str_create(CUSTOM_FIELDS_BUF_SIZE); 00106 v = ast_variable_browse(cfg, cat); 00107 while (v) { 00108 if (customfields && !ast_strlen_zero(v->name) && !ast_strlen_zero(v->value)) { 00109 if ((ast_str_strlen(customfields) + strlen(v->value) + strlen(v->name) + 14) < ast_str_size(customfields)) { 00110 ast_str_append(&customfields, -1, "%s: ${CDR(%s)}\r\n", v->value, v->name); 00111 ast_log(LOG_NOTICE, "Added mapping %s: ${CDR(%s)}\n", v->value, v->name); 00112 } else { 00113 ast_log(LOG_WARNING, "No more buffer space to add other custom fields\n"); 00114 break; 00115 } 00116 00117 } 00118 v = v->next; 00119 } 00120 } 00121 } 00122 00123 if (reload) { 00124 ast_rwlock_unlock(&customfields_lock); 00125 } 00126 00127 ast_config_destroy(cfg); 00128 00129 if (enablecdr && !newenablecdr) 00130 ast_cdr_unregister(name); 00131 else if (!enablecdr && newenablecdr) 00132 ast_cdr_register(name, "Asterisk Manager Interface CDR Backend", manager_log); 00133 enablecdr = newenablecdr; 00134 00135 return 0; 00136 }
static int load_module | ( | void | ) | [static] |
Definition at line 211 of file cdr_manager.c.
References AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, and load_config().
00212 { 00213 if (load_config(0)) { 00214 return AST_MODULE_LOAD_DECLINE; 00215 } 00216 00217 return AST_MODULE_LOAD_SUCCESS; 00218 }
static int manager_log | ( | struct ast_cdr * | cdr | ) | [static] |
Definition at line 138 of file cdr_manager.c.
References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, ast_cdr_disp2str(), ast_cdr_dup(), ast_cdr_flags2str(), 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, ast_channel::cdr, ast_cdr::channel, ast_cdr::clid, CUSTOM_FIELDS_BUF_SIZE, DATE_FORMAT, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, dummy(), ast_cdr::duration, ast_cdr::end, EVENT_FLAG_CDR, ast_cdr::lastapp, ast_cdr::lastdata, LOG_ERROR, manager_event, pbx_substitute_variables_helper(), ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.
Referenced by load_config().
00139 { 00140 struct ast_tm timeresult; 00141 char strStartTime[80] = ""; 00142 char strAnswerTime[80] = ""; 00143 char strEndTime[80] = ""; 00144 char buf[CUSTOM_FIELDS_BUF_SIZE]; 00145 00146 if (!enablecdr) 00147 return 0; 00148 00149 ast_localtime(&cdr->start, &timeresult, NULL); 00150 ast_strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult); 00151 00152 if (cdr->answer.tv_sec) { 00153 ast_localtime(&cdr->answer, &timeresult, NULL); 00154 ast_strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult); 00155 } 00156 00157 ast_localtime(&cdr->end, &timeresult, NULL); 00158 ast_strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult); 00159 00160 buf[0] = '\0'; 00161 ast_rwlock_rdlock(&customfields_lock); 00162 if (customfields && ast_str_strlen(customfields)) { 00163 struct ast_channel *dummy = ast_dummy_channel_alloc(); 00164 if (!dummy) { 00165 ast_log(LOG_ERROR, "Unable to allocate channel for variable substitution.\n"); 00166 return 0; 00167 } 00168 dummy->cdr = ast_cdr_dup(cdr); 00169 pbx_substitute_variables_helper(dummy, ast_str_buffer(customfields), buf, sizeof(buf) - 1); 00170 ast_channel_unref(dummy); 00171 } 00172 ast_rwlock_unlock(&customfields_lock); 00173 00174 manager_event(EVENT_FLAG_CDR, "Cdr", 00175 "AccountCode: %s\r\n" 00176 "Source: %s\r\n" 00177 "Destination: %s\r\n" 00178 "DestinationContext: %s\r\n" 00179 "CallerID: %s\r\n" 00180 "Channel: %s\r\n" 00181 "DestinationChannel: %s\r\n" 00182 "LastApplication: %s\r\n" 00183 "LastData: %s\r\n" 00184 "StartTime: %s\r\n" 00185 "AnswerTime: %s\r\n" 00186 "EndTime: %s\r\n" 00187 "Duration: %ld\r\n" 00188 "BillableSeconds: %ld\r\n" 00189 "Disposition: %s\r\n" 00190 "AMAFlags: %s\r\n" 00191 "UniqueID: %s\r\n" 00192 "UserField: %s\r\n" 00193 "%s", 00194 cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel, 00195 cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime, 00196 cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), 00197 ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield,buf); 00198 00199 return 0; 00200 }
static int reload | ( | void | ) | [static] |
Definition at line 220 of file cdr_manager.c.
References load_config().
00221 { 00222 return load_config(1); 00223 }
static int unload_module | ( | void | ) | [static] |
Definition at line 202 of file cdr_manager.c.
References ast_cdr_unregister(), and ast_free.
00203 { 00204 ast_cdr_unregister(name); 00205 if (customfields) 00206 ast_free(customfields); 00207 00208 return 0; 00209 }
struct ast_str* customfields [static] |
Definition at line 54 of file cdr_manager.c.
int enablecdr = 0 [static] |
Definition at line 52 of file cdr_manager.c.
const char name[] = "cdr_manager" [static] |
Definition at line 50 of file cdr_manager.c.