#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include "asterisk.h"
#include "asterisk/channel.h"
#include "asterisk/cdr.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/utils.h"
Go to the source code of this file.
Defines | |
#define | CSV_LOG_DIR "/cdr-csv" |
#define | CSV_MASTER "/Master.csv" |
#define | DATE_FORMAT "%Y-%m-%d %T" |
Functions | |
static int | append_date (char *buf, struct timeval tv, size_t bufsize) |
static int | append_int (char *buf, int s, size_t bufsize) |
static int | append_string (char *buf, char *s, size_t bufsize) |
static int | build_csv_record (char *buf, size_t bufsize, struct ast_cdr *cdr) |
static int | csv_log (struct ast_cdr *cdr) |
char * | description (void) |
Provides a description of the module. | |
char * | key () |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
int | reload (void) |
Reload stuff. | |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
static int | writefile (char *s, char *acc) |
Variables | |
static char * | desc = "Comma Separated Values CDR Backend" |
static FILE * | mf = NULL |
static char * | name = "csv" |
Definition in file cdr_csv.c.
|
Definition at line 48 of file cdr_csv.c. Referenced by csv_log(), and writefile(). |
|
Definition at line 49 of file cdr_csv.c. Referenced by csv_log(). |
|
Definition at line 51 of file cdr_csv.c. Referenced by append_date(), get_date(), manager_log(), odbc_log(), pgsql_log(), and sqlite_log(). |
|
Definition at line 129 of file cdr_csv.c. References append_string(), DATE_FORMAT, and t. 00130 { 00131 char tmp[80] = ""; 00132 struct tm tm; 00133 time_t t; 00134 t = tv.tv_sec; 00135 if (strlen(buf) > bufsize - 3) 00136 return -1; 00137 if (ast_tvzero(tv)) { 00138 strncat(buf, ",", bufsize - strlen(buf) - 1); 00139 return 0; 00140 } 00141 localtime_r(&t,&tm); 00142 strftime(tmp, sizeof(tmp), DATE_FORMAT, &tm); 00143 return append_string(buf, tmp, bufsize); 00144 }
|
|
Definition at line 115 of file cdr_csv.c. Referenced by build_csv_record(). 00116 { 00117 char tmp[32]; 00118 int pos = strlen(buf); 00119 snprintf(tmp, sizeof(tmp), "%d", s); 00120 if (pos + strlen(tmp) > bufsize - 3) 00121 return -1; 00122 strncat(buf, tmp, bufsize - strlen(buf) - 1); 00123 pos = strlen(buf); 00124 buf[pos++] = ','; 00125 buf[pos++] = '\0'; 00126 return 0; 00127 }
|
|
Definition at line 90 of file cdr_csv.c. References error(). Referenced by append_date(), and build_csv_record(). 00091 { 00092 int pos = strlen(buf); 00093 int spos = 0; 00094 int error = 0; 00095 if (pos >= bufsize - 4) 00096 return -1; 00097 buf[pos++] = '\"'; 00098 error = -1; 00099 while(pos < bufsize - 3) { 00100 if (!s[spos]) { 00101 error = 0; 00102 break; 00103 } 00104 if (s[spos] == '\"') 00105 buf[pos++] = '\"'; 00106 buf[pos++] = s[spos]; 00107 spos++; 00108 } 00109 buf[pos++] = '\"'; 00110 buf[pos++] = ','; 00111 buf[pos++] = '\0'; 00112 return error; 00113 }
|
|
Definition at line 146 of file cdr_csv.c. References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, append_date(), append_int(), append_string(), ast_cdr_disp2str(), ast_cdr_flags2str(), ast_cdr::billsec, ast_cdr::channel, ast_cdr::clid, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield. Referenced by csv_log(). 00147 { 00148 00149 buf[0] = '\0'; 00150 /* Account code */ 00151 append_string(buf, cdr->accountcode, bufsize); 00152 /* Source */ 00153 append_string(buf, cdr->src, bufsize); 00154 /* Destination */ 00155 append_string(buf, cdr->dst, bufsize); 00156 /* Destination context */ 00157 append_string(buf, cdr->dcontext, bufsize); 00158 /* Caller*ID */ 00159 append_string(buf, cdr->clid, bufsize); 00160 /* Channel */ 00161 append_string(buf, cdr->channel, bufsize); 00162 /* Destination Channel */ 00163 append_string(buf, cdr->dstchannel, bufsize); 00164 /* Last Application */ 00165 append_string(buf, cdr->lastapp, bufsize); 00166 /* Last Data */ 00167 append_string(buf, cdr->lastdata, bufsize); 00168 /* Start Time */ 00169 append_date(buf, cdr->start, bufsize); 00170 /* Answer Time */ 00171 append_date(buf, cdr->answer, bufsize); 00172 /* End Time */ 00173 append_date(buf, cdr->end, bufsize); 00174 /* Duration */ 00175 append_int(buf, cdr->duration, bufsize); 00176 /* Billable seconds */ 00177 append_int(buf, cdr->billsec, bufsize); 00178 /* Disposition */ 00179 append_string(buf, ast_cdr_disp2str(cdr->disposition), bufsize); 00180 /* AMA Flags */ 00181 append_string(buf, ast_cdr_flags2str(cdr->amaflags), bufsize); 00182 00183 #ifdef CSV_LOGUNIQUEID 00184 /* Unique ID */ 00185 append_string(buf, cdr->uniqueid, bufsize); 00186 #endif 00187 #ifdef CSV_LOGUSERFIELD 00188 /* append the user field */ 00189 append_string(buf, cdr->userfield,bufsize); 00190 #endif 00191 /* If we hit the end of our buffer, log an error */ 00192 if (strlen(buf) < bufsize - 5) { 00193 /* Trim off trailing comma */ 00194 buf[strlen(buf) - 1] = '\0'; 00195 strncat(buf, "\n", bufsize - strlen(buf) - 1); 00196 return 0; 00197 } 00198 return -1; 00199 }
|
|
Definition at line 220 of file cdr_csv.c. References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr_disp2str(), ast_cdr_flags2str(), ast_config_AST_LOG_DIR, AST_CONFIG_MAX_PATH, ast_log(), ast_strlen_zero(), ast_cdr::billsec, build_csv_record(), ast_cdr::channel, CSV_LOG_DIR, CSV_MASTER, ast_cdr::disposition, ast_cdr::dst, ast_cdr::duration, LOG_ERROR, LOG_WARNING, ast_cdr::src, and writefile(). Referenced by load_module(). 00221 { 00222 /* Make sure we have a big enough buf */ 00223 char buf[1024]; 00224 char csvmaster[AST_CONFIG_MAX_PATH]; 00225 snprintf(csvmaster, sizeof(csvmaster),"%s/%s/%s", ast_config_AST_LOG_DIR, CSV_LOG_DIR, CSV_MASTER); 00226 #if 0 00227 printf("[CDR] %s ('%s' -> '%s') Dur: %ds Bill: %ds Disp: %s Flags: %s Account: [%s]\n", cdr->channel, cdr->src, cdr->dst, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), cdr->accountcode); 00228 #endif 00229 if (build_csv_record(buf, sizeof(buf), cdr)) { 00230 ast_log(LOG_WARNING, "Unable to create CSV record in %d bytes. CDR not recorded!\n", (int)sizeof(buf)); 00231 } else { 00232 /* because of the absolutely unconditional need for the 00233 highest reliability possible in writing billing records, 00234 we open write and close the log file each time */ 00235 mf = fopen(csvmaster, "a"); 00236 if (!mf) { 00237 ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", csvmaster, strerror(errno)); 00238 } 00239 if (mf) { 00240 fputs(buf, mf); 00241 fflush(mf); /* be particularly anal here */ 00242 fclose(mf); 00243 mf = NULL; 00244 } 00245 if (!ast_strlen_zero(cdr->accountcode)) { 00246 if (writefile(buf, cdr->accountcode)) 00247 ast_log(LOG_WARNING, "Unable to write CSV record to account file '%s' : %s\n", cdr->accountcode, strerror(errno)); 00248 } 00249 } 00250 return 0; 00251 }
|
|
Provides a description of the module.
Definition at line 253 of file cdr_csv.c. 00254 { 00255 return desc; 00256 }
|
|
Returns the ASTERISK_GPL_KEY. This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 289 of file cdr_csv.c. References ASTERISK_GPL_KEY. 00290 { 00291 return ASTERISK_GPL_KEY; 00292 }
|
|
Initialize the module. Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 266 of file cdr_csv.c. References ast_cdr_register(), ast_log(), csv_log(), and LOG_ERROR. 00267 { 00268 int res; 00269 00270 res = ast_cdr_register(name, desc, csv_log); 00271 if (res) { 00272 ast_log(LOG_ERROR, "Unable to register CSV CDR handling\n"); 00273 if (mf) 00274 fclose(mf); 00275 } 00276 return res; 00277 }
|
|
Reload stuff. This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.
Definition at line 279 of file cdr_csv.c.
|
|
Cleanup all module structures, sockets, etc. This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 258 of file cdr_csv.c. References ast_cdr_unregister(). 00259 { 00260 if (mf) 00261 fclose(mf); 00262 ast_cdr_unregister(name); 00263 return 0; 00264 }
|
|
Provides a usecount. This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 284 of file cdr_csv.c.
|
|
Definition at line 201 of file cdr_csv.c. References ast_config_AST_LOG_DIR, AST_CONFIG_MAX_PATH, ast_log(), CSV_LOG_DIR, and LOG_WARNING. Referenced by csv_log(). 00202 { 00203 char tmp[AST_CONFIG_MAX_PATH]; 00204 FILE *f; 00205 if (strchr(acc, '/') || (acc[0] == '.')) { 00206 ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc); 00207 return -1; 00208 } 00209 snprintf(tmp, sizeof(tmp), "%s/%s/%s.csv", (char *)ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc); 00210 f = fopen(tmp, "a"); 00211 if (!f) 00212 return -1; 00213 fputs(s, f); 00214 fflush(f); 00215 fclose(f); 00216 return 0; 00217 }
|
|
|
|
Definition at line 88 of file cdr_csv.c. Referenced by ast_say_number_full_de(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_he(), and ast_say_number_full_pt(). |
|
|