static int manager_log(struct ast_cdr *cdr) { time_t t; struct tm timeresult; char strStartTime[80] = ""; char strAnswerTime[80] = ""; char strEndTime[80] = ""; if (!enablecdr) return 0; t = cdr->start.tv_sec; ast_localtime(&t, &timeresult, NULL); strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult); if (cdr->answer.tv_sec) { t = cdr->answer.tv_sec; ast_localtime(&t, &timeresult, NULL); strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult); } t = cdr->end.tv_sec; ast_localtime(&t, &timeresult, NULL); strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult); manager_event(EVENT_FLAG_CALL, "Cdr", "AccountCode: %s\r\n" "Source: %s\r\n" "Destination: %s\r\n" "DestinationContext: %s\r\n" "CallerID: %s\r\n" "Channel: %s\r\n" "DestinationChannel: %s\r\n" "LastApplication: %s\r\n" "LastData: %s\r\n" "StartTime: %s\r\n" "AnswerTime: %s\r\n" "EndTime: %s\r\n" "Duration: %ld\r\n" "BillableSeconds: %ld\r\n" "Disposition: %s\r\n" "AMAFlags: %s\r\n" "UniqueID: %s\r\n" "UserField: %s\r\n", cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield); return 0; }
static void format_date(char *buffer, size_t length, struct timeval *when) { struct ast_tm tm; ast_localtime(when, &tm, NULL); ast_strftime(buffer, length, DATE_FORMAT, &tm); }
static int write_metadata( FILE *logfile, char *signalling_type, struct ast_channel *chan) { int res = 0; time_t t; struct tm now; char *cl,*cn; char workstring[80]; char timestamp[80]; /* Extract the caller ID location */ if (chan->cid.cid_num) ast_copy_string(workstring, chan->cid.cid_num, sizeof(workstring)); workstring[sizeof(workstring) - 1] = '\0'; ast_callerid_parse(workstring, &cn, &cl); if (cl) ast_shrink_phone_number(cl); /* Get the current time */ time(&t); ast_localtime(&t, &now, NULL); /* Format the time */ strftime(timestamp, sizeof(timestamp), time_stamp_format, &now); res = fprintf(logfile, "\n\n[metadata]\n\n"); if(res >= 0) res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type); if(res >= 0) res = fprintf(logfile, "CALLINGFROM=%s\n", (!cl) ? "<unknown>" : cl); if(res >- 0) res = fprintf(logfile, "CALLERNAME=%s\n", (!cn) ? "<unknown>" : cn); if(res >= 0) res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp); if(res >= 0) res = fprintf(logfile, "[events]\n\n"); if(res < 0){ ast_verbose(VERBOSE_PREFIX_4 "AlarmReceiver: can't write metadata\n"); ast_log(LOG_DEBUG,"AlarmReceiver: can't write metadata\n"); } else res = 0; return res; }
/* * Write the metadata to the log file */ static int write_metadata( FILE *logfile, char *signalling_type, struct ast_channel *chan) { int res = 0; struct timeval t; struct ast_tm now; char *cl; char *cn; char workstring[80]; char timestamp[80]; /* Extract the caller ID location */ ast_copy_string(workstring, S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""), sizeof(workstring)); ast_shrink_phone_number(workstring); if (ast_strlen_zero(workstring)) { cl = "<unknown>"; } else { cl = workstring; } cn = S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "<unknown>"); /* Get the current time */ t = ast_tvnow(); ast_localtime(&t, &now, NULL); /* Format the time */ ast_strftime(timestamp, sizeof(timestamp), time_stamp_format, &now); res = fprintf(logfile, "\n\n[metadata]\n\n"); if (res >= 0) { res = fprintf(logfile, "PROTOCOL=%s\n", signalling_type); } if (res >= 0) { res = fprintf(logfile, "CALLINGFROM=%s\n", cl); } if (res >= 0) { res = fprintf(logfile, "CALLERNAME=%s\n", cn); } if (res >= 0) { res = fprintf(logfile, "TIMESTAMP=%s\n\n", timestamp); } if (res >= 0) { res = fprintf(logfile, "[events]\n\n"); } if (res < 0) { ast_verb(3, "AlarmReceiver: can't write metadata\n"); ast_debug(1,"AlarmReceiver: can't write metadata\n"); } else { res = 0; } return res; }
struct ast_json *ast_json_timeval(const struct timeval tv, const char *zone) { char buf[AST_ISO8601_LEN]; struct ast_tm tm = {}; ast_localtime(&tv, &tm, zone); ast_strftime(buf, sizeof(buf),AST_ISO8601_FORMAT, &tm); return ast_json_string_create(buf); }
/*! * \brief Write metadata to log file * * \param logfile Log File Pointer * \param signalling_type Signaling Type * \param chan Asterisk Channel * \param no_checksum Expecting messages without checksum * * \retval 0 success * \retval -1 failure */ static int write_metadata(FILE *logfile, char *signalling_type, struct ast_channel *chan, int no_checksum) { struct timeval t; struct ast_tm now; char *cl; char *cn; char workstring[80]; char timestamp[80]; /* Extract the caller ID location */ ast_copy_string(workstring, S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""), sizeof(workstring)); ast_shrink_phone_number(workstring); if (ast_strlen_zero(workstring)) { cl = "<unknown>"; } else { cl = workstring; } cn = S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, "<unknown>"); /* Get the current time */ t = ast_tvnow(); ast_localtime(&t, &now, NULL); /* Format the time */ ast_strftime(timestamp, sizeof(timestamp), time_stamp_format, &now); if (no_group_meta && fprintf(logfile, "PROTOCOL=%s\n" "CHECKSUM=%s\n" "CALLINGFROM=%s\n" "CALLERNAME=%s\n" "TIMESTAMP=%s\n\n", signalling_type, (!no_checksum) ? "yes" : "no", cl, cn, timestamp) > -1) { return 0; } else if (fprintf(logfile, "\n\n[metadata]\n\n" "PROTOCOL=%s\n" "CHECKSUM=%s\n" "CALLINGFROM=%s\n" "CALLERNAME=%s\n" "TIMESTAMP=%s\n\n" "[events]\n\n", signalling_type, (!no_checksum) ? "yes" : "no", cl, cn, timestamp) > -1) { return 0; } ast_verb(3, "AlarmReceiver: can't write metadata\n"); ast_debug(1, "AlarmReceiver: can't write metadata\n"); return -1; }
static void custom_log(struct ast_event *event) { CURL *curl; CURLcode res; struct ast_tm timeresult; struct curl_slist *headers = NULL; char start_time[80] = ""; struct ast_cel_event_record record = { .version = AST_CEL_EVENT_RECORD_VERSION, }; if (ast_cel_fill_record(event, &record)) { return; } ast_localtime(&record.event_time, &timeresult, NULL); ast_strftime(start_time, sizeof(start_time), DATE_FORMAT, &timeresult); curl = curl_easy_init(); if (curl) { headers = curl_slist_append(headers, "Content-Type: application/json"); curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.5:9200/asterisk/cel/"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); char *post_fields = malloc(sizeof(char) * 6048); sprintf(post_fields, "{\"EventName\": \"%s\", \"AccountCode\": \"%s\", \ \"CallerIDnum\": \"%s\", \"CallerIDname\": \"%s\", \ \"CallerIDani\": \"%s\", \"CallerIDrdnis\": \"%s\", \ \"CAllerIDdnid\": \"%s\", \"Exten\": \"%s\", \ \"Context\": \"%s\", \"Channel\": \"%s\", \ \"Application\": \"%s\", \"AppData\": \"%s\", \ \"EventTime\": \"%s\", \"AMAFlags\": \"%s\", \ \"UniqueID\": \"%s\", \"LinkedID\": \"%s\", \ \"Userfield\": \"%s\", \"Peer\": \"%s\", \ \"Peeraccount\": \"%s\", \"Extra\": \"%s\" }", record.event_name, record.account_code, record.caller_id_num, record.caller_id_name, record.caller_id_ani, record.caller_id_rdnis, record.caller_id_dnid, record.extension, record.context, record.channel_name, record.application_name, record.application_data, start_time, ast_channel_amaflags2string(record.amaflag), record.unique_id, record.linked_id, record.user_field, record.peer, record.peer_account, record.extra); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_fields); curl_easy_perform(curl); curl_slist_free_all(headers); curl_easy_cleanup(curl); free(post_fields); }
int main(int argc, char **argv) { struct timeval tv; struct tm tm; char *zone[5] = { NULL, "America/New_York", "America/Chicago", "America/Denver", "America/Los_Angeles" }; int i; gettimeofday(&tv,NULL); for (i=0;i<5;i++) { ast_localtime(&tv.tv_sec,&tm,zone[i]); printf("Localtime at %s is %04d/%02d/%02d %02d:%02d:%02d\n",(zone[i] == NULL ? "NULL" : zone[i]),tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); } return 0; }
static void manager_log(const struct ast_event *event, void *userdata) { struct ast_tm timeresult; char start_time[80] = ""; struct ast_cel_event_record record = { .version = AST_CEL_EVENT_RECORD_VERSION, }; if (ast_cel_fill_record(event, &record)) { return; } if (!enablecel) { return; } ast_localtime(&record.event_time, &timeresult, NULL); ast_strftime(start_time, sizeof(start_time), DATE_FORMAT, &timeresult); manager_event(EVENT_FLAG_CALL, "CEL", "EventName: %s\r\n" "AccountCode: %s\r\n" "CallerIDnum: %s\r\n" "CallerIDname: %s\r\n" "CallerIDani: %s\r\n" "CallerIDrdnis: %s\r\n" "CallerIDdnid: %s\r\n" "Exten: %s\r\n" "Context: %s\r\n" "Channel: %s\r\n" "Application: %s\r\n" "AppData: %s\r\n" "EventTime: %s\r\n" "AMAFlags: %s\r\n" "UniqueID: %s\r\n" "LinkedID: %s\r\n" "Userfield: %s\r\n" "Peer: %s\r\n", record.event_name, record.account_code, record.caller_id_num, record.caller_id_name, record.caller_id_ani, record.caller_id_rdnis, record.caller_id_dnid, record.extension, record.context, record.channel_name, record.application_name, record.application_data, start_time, ast_cel_get_ama_flag_name(record.amaflag), record.unique_id, record.linked_id, record.user_field, record.peer); }
static int append_date(char *buf, struct timeval when, size_t bufsize) { char tmp[80] = ""; struct ast_tm tm; if (strlen(buf) > bufsize - 3) return -1; if (ast_tvzero(when)) { strncat(buf, ",", bufsize - strlen(buf) - 1); return 0; } ast_localtime(&when, &tm, usegmtime ? "GMT" : NULL); ast_strftime(tmp, sizeof(tmp), DATE_FORMAT, &tm); return append_string(buf, tmp, bufsize); }
static char *cli_time(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct timeval date_tv; struct ast_tm tm = { 0, }; const char *zone = NULL; const char *format = "%Y-%m-%d %H:%M:%S.%q"; char buf[64]; switch (cmd) { case CLI_INIT: e->command = "lab time"; e->usage = "lab time <timezone> <format>\n"; return NULL; case CLI_GENERATE: return NULL; } if (a->argc >= 3) { zone = a->argv[2]; } if (a->argc >= 4) { format = a->argv[3]; } if (a->argc >= 5) { return CLI_SHOWUSAGE; } date_tv = ast_tvnow(); ast_localtime(&date_tv, &tm, zone); tm.tm_usec = 123; ast_strftime(buf, sizeof(buf), format, &tm); ast_cli(a->fd, "%s\nus: %d\n", buf, tm.tm_usec); return CLI_SUCCESS; }
static int say_date_generic(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *timezone, const char *prefix) { char buf[128]; struct tm tm; say_args_t a = { chan, ints, lang, -1, -1 }; if (format == NULL) format = ""; ast_localtime(&t, &tm, NULL); snprintf(buf, sizeof(buf), "%s:%s:%04d%02d%02d%02d%02d.%02d-%d-%3d", prefix, format, tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday, tm.tm_yday); return do_say(&a, buf, NULL, 0); }
static int odbc_log(struct ast_cdr *cdr) { int ODBC_res; char sqlcmd[2048] = "", timestr[128]; int res = 0; struct tm tm; if (usegmtime) gmtime_r(&cdr->start.tv_sec,&tm); else ast_localtime(&cdr->start.tv_sec, &tm, NULL); ast_mutex_lock(&odbc_lock); strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm); memset(sqlcmd,0,2048); if (loguniqueid) { snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s " "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp," "lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table); } else { snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s " "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata," "duration,billsec,disposition,amaflags,accountcode) " "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table); } if (!connected) { res = odbc_init(); if (res < 0) { odbc_disconnect(); ast_mutex_unlock(&odbc_lock); return 0; } } ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, ODBC_con, &ODBC_stmt); if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) { if (option_verbose > 10) ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Failure in AllocStatement %d\n", ODBC_res); SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt); odbc_disconnect(); ast_mutex_unlock(&odbc_lock); return 0; } /* We really should only have to do this once. But for some strange reason if I don't it blows holes in memory like like a shotgun. So we just do this so its safe. */ ODBC_res = SQLPrepare(ODBC_stmt, (unsigned char *)sqlcmd, SQL_NTS); if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) { if (option_verbose > 10) ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error in PREPARE %d\n", ODBC_res); SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt); odbc_disconnect(); ast_mutex_unlock(&odbc_lock); return 0; } SQLBindParameter(ODBC_stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(timestr), 0, ×tr, 0, NULL); SQLBindParameter(ODBC_stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->clid), 0, cdr->clid, 0, NULL); SQLBindParameter(ODBC_stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->src), 0, cdr->src, 0, NULL); SQLBindParameter(ODBC_stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dst), 0, cdr->dst, 0, NULL); SQLBindParameter(ODBC_stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dcontext), 0, cdr->dcontext, 0, NULL); SQLBindParameter(ODBC_stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->channel), 0, cdr->channel, 0, NULL); SQLBindParameter(ODBC_stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dstchannel), 0, cdr->dstchannel, 0, NULL); SQLBindParameter(ODBC_stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastapp), 0, cdr->lastapp, 0, NULL); SQLBindParameter(ODBC_stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastdata), 0, cdr->lastdata, 0, NULL); SQLBindParameter(ODBC_stmt, 10, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->duration, 0, NULL); SQLBindParameter(ODBC_stmt, 11, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->billsec, 0, NULL); if (dispositionstring) SQLBindParameter(ODBC_stmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(ast_cdr_disp2str(cdr->disposition)) + 1, 0, ast_cdr_disp2str(cdr->disposition), 0, NULL); else SQLBindParameter(ODBC_stmt, 12, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->disposition, 0, NULL); SQLBindParameter(ODBC_stmt, 13, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->amaflags, 0, NULL); SQLBindParameter(ODBC_stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->accountcode), 0, cdr->accountcode, 0, NULL); if (loguniqueid) { SQLBindParameter(ODBC_stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->uniqueid), 0, cdr->uniqueid, 0, NULL); SQLBindParameter(ODBC_stmt, 16, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->userfield), 0, cdr->userfield, 0, NULL); } if (connected) { res = odbc_do_query(); if (res < 0) { if (option_verbose > 10) ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n"); if (option_verbose > 10) ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Reconnecting to dsn %s\n", dsn); SQLDisconnect(ODBC_con); res = odbc_init(); if (res < 0) { if (option_verbose > 10) ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: %s has gone away!\n", dsn); odbc_disconnect(); } else { if (option_verbose > 10) ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Trying Query again!\n"); res = odbc_do_query(); if (res < 0) { if (option_verbose > 10) ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n"); } } } } else { if (option_verbose > 10) ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n"); } SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt); ast_mutex_unlock(&odbc_lock); return 0; }
static void manager_log(const struct ast_event *event, void *userdata) { struct ast_tm timeresult; char start_time[80] = ""; char user_defined_header[160]; const char *event_name; struct ast_cel_event_record record = { .version = AST_CEL_EVENT_RECORD_VERSION, }; if (!enablecel) { return; } if (ast_cel_fill_record(event, &record)) { return; } ast_localtime(&record.event_time, &timeresult, NULL); ast_strftime(start_time, sizeof(start_time), DATE_FORMAT, &timeresult); event_name = record.event_name; user_defined_header[0] = '\0'; if (record.event_type == AST_CEL_USER_DEFINED) { if (cel_show_user_def) { snprintf(user_defined_header, sizeof(user_defined_header), "UserDefType: %s\r\n", record.user_defined_name); } else { event_name = record.user_defined_name; } } manager_event(EVENT_FLAG_CALL, "CEL", "EventName: %s\r\n" "AccountCode: %s\r\n" "CallerIDnum: %s\r\n" "CallerIDname: %s\r\n" "CallerIDani: %s\r\n" "CallerIDrdnis: %s\r\n" "CallerIDdnid: %s\r\n" "Exten: %s\r\n" "Context: %s\r\n" "Channel: %s\r\n" "Application: %s\r\n" "AppData: %s\r\n" "EventTime: %s\r\n" "AMAFlags: %s\r\n" "UniqueID: %s\r\n" "LinkedID: %s\r\n" "Userfield: %s\r\n" "Peer: %s\r\n" "PeerAccount: %s\r\n" "%s" "Extra: %s\r\n", event_name, record.account_code, record.caller_id_num, record.caller_id_name, record.caller_id_ani, record.caller_id_rdnis, record.caller_id_dnid, record.extension, record.context, record.channel_name, record.application_name, record.application_data, start_time, ast_cel_get_ama_flag_name(record.amaflag), record.unique_id, record.linked_id, record.user_field, record.peer, record.peer_account, user_defined_header, record.extra); }
static char *cli_show_tasks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ao2_iterator i; struct ast_sip_sched_task *schtd; const char *log_format = ast_logger_get_dateformat(); struct ast_tm tm; char queued[32]; char last_start[32]; char last_end[32]; int datelen; struct timeval now = ast_tvnow(); const char *separator = "======================================"; switch (cmd) { case CLI_INIT: e->command = "pjsip show scheduled_tasks"; e->usage = "Usage: pjsip show scheduled_tasks\n" " Show all scheduled tasks\n"; return NULL; case CLI_GENERATE: return NULL; } if (a->argc != 3) { return CLI_SHOWUSAGE; } ast_localtime(&now, &tm, NULL); datelen = ast_strftime(queued, sizeof(queued), log_format, &tm); ast_cli(a->fd, "PJSIP Scheduled Tasks:\n\n"); ast_cli(a->fd, " %1$-24s %2$-8s %3$-9s %4$-7s %6$-*5$s %7$-*5$s %8$-*5$s\n", "Task Name", "Interval", "Times Run", "State", datelen, "Queued", "Last Started", "Last Ended"); ast_cli(a->fd, " %1$-24.24s %2$-8.8s %3$-9.9s %4$-7.7s %6$-*5$.*5$s %7$-*5$.*5$s %8$-*5$.*5$s\n", separator, separator, separator, separator, datelen, separator, separator, separator); ao2_ref(tasks, +1); ao2_rdlock(tasks); i = ao2_iterator_init(tasks, 0); while ((schtd = ao2_iterator_next(&i))) { ast_localtime(&schtd->when_queued, &tm, NULL); ast_strftime(queued, sizeof(queued), log_format, &tm); if (ast_tvzero(schtd->last_start)) { strcpy(last_start, "not yet started"); } else { ast_localtime(&schtd->last_start, &tm, NULL); ast_strftime(last_start, sizeof(last_start), log_format, &tm); } if (ast_tvzero(schtd->last_end)) { if (ast_tvzero(schtd->last_start)) { strcpy(last_end, "not yet started"); } else { strcpy(last_end, "running"); } } else { ast_localtime(&schtd->last_end, &tm, NULL); ast_strftime(last_end, sizeof(last_end), log_format, &tm); } ast_cli(a->fd, " %1$-24.24s %2$-8.3f %3$-9d %4$-7s %6$-*5$s %7$-*5$s %8$-*5$s\n", schtd->name, schtd->interval / 1000.0, schtd->run_count, schtd->is_running ? "running" : "waiting", datelen, queued, last_start, last_end); ao2_cleanup(schtd); } ao2_iterator_destroy(&i); ao2_unlock(tasks); ao2_ref(tasks, -1); ast_cli(a->fd, "\n"); return CLI_SUCCESS; }
struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event *event) { struct varshead *headp; struct ast_var_t *newvariable; const char *mixed_name; char timebuf[30]; struct ast_channel *tchan; struct ast_cel_event_record record = { .version = AST_CEL_EVENT_RECORD_VERSION, }; struct ast_datastore *datastore; char *app_data; /* do not call ast_channel_alloc because this is not really a real channel */ if (!(tchan = ast_dummy_channel_alloc())) { return NULL; } headp = ast_channel_varshead(tchan); /* first, get the variables from the event */ if (ast_cel_fill_record(event, &record)) { ast_channel_unref(tchan); return NULL; } /* next, fill the channel with their data */ mixed_name = (record.event_type == AST_CEL_USER_DEFINED) ? record.user_defined_name : record.event_name; if ((newvariable = ast_var_assign("eventtype", mixed_name))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } if (ast_strlen_zero(cel_dateformat)) { snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec, (long) record.event_time.tv_usec); } else { struct ast_tm tm; ast_localtime(&record.event_time, &tm, NULL); ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm); } if ((newvariable = ast_var_assign("eventtime", timebuf))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } if ((newvariable = ast_var_assign("eventenum", record.event_name))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } if ((newvariable = ast_var_assign("eventextra", record.extra))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } ast_channel_caller(tchan)->id.name.valid = 1; ast_channel_caller(tchan)->id.name.str = ast_strdup(record.caller_id_name); ast_channel_caller(tchan)->id.number.valid = 1; ast_channel_caller(tchan)->id.number.str = ast_strdup(record.caller_id_num); ast_channel_caller(tchan)->ani.number.valid = 1; ast_channel_caller(tchan)->ani.number.str = ast_strdup(record.caller_id_ani); ast_channel_redirecting(tchan)->from.number.valid = 1; ast_channel_redirecting(tchan)->from.number.str = ast_strdup(record.caller_id_rdnis); ast_channel_dialed(tchan)->number.str = ast_strdup(record.caller_id_dnid); ast_channel_exten_set(tchan, record.extension); ast_channel_context_set(tchan, record.context); ast_channel_name_set(tchan, record.channel_name); ast_channel_uniqueid_set(tchan, record.unique_id); ast_channel_linkedid_set(tchan, record.linked_id); ast_channel_accountcode_set(tchan, record.account_code); ast_channel_peeraccount_set(tchan, record.peer_account); ast_channel_userfield_set(tchan, record.user_field); if ((newvariable = ast_var_assign("BRIDGEPEER", record.peer))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } ast_channel_amaflags_set(tchan, record.amaflag); /* We need to store an 'application name' and 'application * data' on the channel for logging purposes, but the channel * structure only provides a place to store pointers, and it * expects these pointers to be pointing to data that does not * need to be freed. This means that the channel's destructor * does not attempt to free any storage that these pointers * point to. However, we can't provide data in that form directly for * these structure members. In order to ensure that these data * elements have a lifetime that matches the channel's * lifetime, we'll put them in a datastore attached to the * channel, and set's the channel's pointers to point into the * datastore. The datastore will then be automatically destroyed * when the channel is destroyed. */ if (!(datastore = ast_datastore_alloc(&fabricated_channel_datastore, NULL))) { ast_channel_unref(tchan); return NULL; } if (!(app_data = ast_malloc(strlen(record.application_name) + strlen(record.application_data) + 2))) { ast_datastore_free(datastore); ast_channel_unref(tchan); return NULL; } ast_channel_appl_set(tchan, strcpy(app_data, record.application_name)); ast_channel_data_set(tchan, strcpy(app_data + strlen(record.application_name) + 1, record.application_data)); datastore->data = app_data; ast_channel_datastore_add(tchan, datastore); return tchan; }
static int manager_log(struct ast_cdr *cdr) { struct ast_tm timeresult; char strStartTime[80] = ""; char strAnswerTime[80] = ""; char strEndTime[80] = ""; char buf[CUSTOM_FIELDS_BUF_SIZE]; if (!enablecdr) return 0; ast_localtime(&cdr->start, &timeresult, NULL); ast_strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult); if (cdr->answer.tv_sec) { ast_localtime(&cdr->answer, &timeresult, NULL); ast_strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult); } ast_localtime(&cdr->end, &timeresult, NULL); ast_strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult); buf[0] = '\0'; ast_rwlock_rdlock(&customfields_lock); if (customfields && ast_str_strlen(customfields)) { struct ast_channel *dummy = ast_dummy_channel_alloc(); if (!dummy) { ast_log(LOG_ERROR, "Unable to allocate channel for variable substitution.\n"); return 0; } dummy->cdr = ast_cdr_dup(cdr); pbx_substitute_variables_helper(dummy, ast_str_buffer(customfields), buf, sizeof(buf) - 1); ast_channel_unref(dummy); } ast_rwlock_unlock(&customfields_lock); manager_event(EVENT_FLAG_CDR, "Cdr", "AccountCode: %s\r\n" "Source: %s\r\n" "Destination: %s\r\n" "DestinationContext: %s\r\n" "CallerID: %s\r\n" "Channel: %s\r\n" "DestinationChannel: %s\r\n" "LastApplication: %s\r\n" "LastData: %s\r\n" "StartTime: %s\r\n" "AnswerTime: %s\r\n" "EndTime: %s\r\n" "Duration: %ld\r\n" "BillableSeconds: %ld\r\n" "Disposition: %s\r\n" "AMAFlags: %s\r\n" "UniqueID: %s\r\n" "UserField: %s\r\n" "%s", cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield,buf); return 0; }
struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event *event) { struct varshead *headp; struct ast_var_t *newvariable; char timebuf[30]; struct ast_channel *tchan; struct ast_cel_event_record record = { .version = AST_CEL_EVENT_RECORD_VERSION, }; /* do not call ast_channel_alloc because this is not really a real channel */ if (!(tchan = ast_dummy_channel_alloc())) { return NULL; } headp = &tchan->varshead; /* first, get the variables from the event */ if (ast_cel_fill_record(event, &record)) { ast_channel_release(tchan); return NULL; } /* next, fill the channel with their data */ if ((newvariable = ast_var_assign("eventtype", record.event_name))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } if (ast_strlen_zero(cel_dateformat)) { snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec, (long) record.event_time.tv_usec); } else { struct ast_tm tm; ast_localtime(&record.event_time, &tm, NULL); ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm); } if ((newvariable = ast_var_assign("eventtime", timebuf))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } if ((newvariable = ast_var_assign("eventextra", record.extra))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } tchan->caller.id.name.valid = 1; tchan->caller.id.name.str = ast_strdup(record.caller_id_name); tchan->caller.id.number.valid = 1; tchan->caller.id.number.str = ast_strdup(record.caller_id_num); tchan->caller.ani.number.valid = 1; tchan->caller.ani.number.str = ast_strdup(record.caller_id_ani); tchan->redirecting.from.number.valid = 1; tchan->redirecting.from.number.str = ast_strdup(record.caller_id_rdnis); tchan->dialed.number.str = ast_strdup(record.caller_id_dnid); ast_copy_string(tchan->exten, record.extension, sizeof(tchan->exten)); ast_copy_string(tchan->context, record.context, sizeof(tchan->context)); ast_string_field_set(tchan, name, record.channel_name); ast_string_field_set(tchan, uniqueid, record.unique_id); ast_string_field_set(tchan, linkedid, record.linked_id); ast_string_field_set(tchan, accountcode, record.account_code); ast_string_field_set(tchan, peeraccount, record.peer_account); ast_string_field_set(tchan, userfield, record.user_field); pbx_builtin_setvar_helper(tchan, "BRIDGEPEER", record.peer); tchan->appl = ast_strdup(record.application_name); tchan->data = ast_strdup(record.application_data); tchan->amaflags = record.amaflag; return tchan; }
static int sqlite_log(struct ast_cdr *cdr) { int res = 0; char *zErr = 0; struct tm tm; time_t t; char startstr[80]; char answerstr[80]; char endstr[80]; char *dispositionstr = NULL; int count; ast_mutex_lock(&sqlite_lock); t = cdr->start.tv_sec; ast_localtime(&t, &tm, NULL); strftime(startstr, sizeof(startstr), DATE_FORMAT, &tm); t = cdr->answer.tv_sec; ast_localtime(&t, &tm, NULL); strftime(answerstr, sizeof(answerstr), DATE_FORMAT, &tm); t = cdr->end.tv_sec; ast_localtime(&t, &tm, NULL); strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm); dispositionstr = ast_cdr_disp2str(cdr->disposition); for(count=0; count<5; count++) { res = sqlite_exec_printf(db, "INSERT INTO cdr (" "clid," "src," "dst," "dcontext," "channel," "dstchannel," "lastapp," "lastdata," "start," "answer," "end," "duration," "billsec," "disposition," "amaflags," "accountcode," "uniqueid," "userfield" ") VALUES (" "'%q', " // clid "'%q', " // src "'%q', " // dst "'%q', " // dcontext "'%q', " // channel "'%q', " // dstchannel "'%q', " // lastapp "'%q', " // lastdata "'%q', " // start "'%q', " // answer "'%q', " // end "%d, " // duration "%d, " // billsec "'%q', " // disposition "%d, " // amaflags "'%q', " // accountcode "'%q', " // uniqueiq "'%q' " // userfield ")", NULL, NULL, &zErr, cdr->clid, cdr->src, cdr->dst, cdr->dcontext, cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata, startstr, answerstr, endstr, cdr->duration, cdr->billsec, dispositionstr, cdr->amaflags, cdr->accountcode, cdr->uniqueid, cdr->userfield ); if (res != SQLITE_BUSY && res != SQLITE_LOCKED) break; usleep(200); } if (zErr) { ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr); free(zErr); } ast_mutex_unlock(&sqlite_lock); return res; }
static int http_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers) { char file_name[64] = "/tmp/test-media-cache-XXXXXX"; struct ast_str *http_header = ast_str_create(128); struct ast_str *cache_control = ast_str_create(128); int fd = -1; int unmodified = 0; int send_file = options.send_file && method == AST_HTTP_GET; if (!http_header) { goto error; } if (send_file) { char buf[1024]; fd = mkstemp(file_name); if (fd == -1) { ast_log(LOG_ERROR, "Unable to open temp file for testing: %s (%d)", strerror(errno), errno); goto error; } memset(buf, 1, sizeof(buf)); if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { ast_log(LOG_ERROR, "Failed to write expected number of bytes to pipe\n"); close(fd); goto error; } close(fd); fd = open(file_name, 0); if (fd == -1) { ast_log(LOG_ERROR, "Unable to open temp file for testing: %s (%d)", strerror(errno), errno); goto error; } } if (options.cache_control.maxage) { SET_OR_APPEND_CACHE_CONTROL(cache_control); ast_str_append(&cache_control, 0, "max-age=%d", options.cache_control.maxage); } if (options.cache_control.s_maxage) { SET_OR_APPEND_CACHE_CONTROL(cache_control); ast_str_append(&cache_control, 0, "s-maxage=%d", options.cache_control.s_maxage); } if (options.cache_control.no_cache) { SET_OR_APPEND_CACHE_CONTROL(cache_control); ast_str_append(&cache_control, 0, "%s", "no-cache"); } if (options.cache_control.must_revalidate) { SET_OR_APPEND_CACHE_CONTROL(cache_control); ast_str_append(&cache_control, 0, "%s", "must-revalidate"); } if (ast_str_strlen(cache_control)) { ast_str_append(&http_header, 0, "%s\r\n", ast_str_buffer(cache_control)); } if (options.expires.tv_sec) { struct ast_tm now_time; char tmbuf[64]; ast_localtime(&options.expires, &now_time, NULL); ast_strftime(tmbuf, sizeof(tmbuf), "%a, %d %b %Y %T %z", &now_time); ast_str_append(&http_header, 0, "Expires: %s\r\n", tmbuf); } if (!ast_strlen_zero(options.etag)) { struct ast_variable *v; ast_str_append(&http_header, 0, "ETag: %s\r\n", options.etag); for (v = headers; v; v = v->next) { if (!strcasecmp(v->name, "If-None-Match") && !strcasecmp(v->value, options.etag)) { unmodified = 1; break; } } } if (!unmodified) { ast_http_send(ser, method, options.status_code, options.status_text, http_header, NULL, send_file ? fd : 0, 1); } else { ast_http_send(ser, method, 304, "Not Modified", http_header, NULL, 0, 1); } if (send_file) { close(fd); unlink(file_name); } ast_free(cache_control); return 0; error: ast_free(http_header); ast_free(cache_control); ast_http_request_close_on_completion(ser); ast_http_error(ser, 418, "I'm a Teapot", "Please don't ask me to brew coffee."); return 0; }
static int beanstalk_put(struct ast_cdr *cdr) { struct ast_tm timeresult; char strAnswerTime[80] = ""; char strStartTime[80]; char strEndTime[80]; char *cdr_buffer; int bs_id; int bs_socket; struct ast_json *t_cdr_json; if (!enablecdr) { return 0; } ast_rwlock_rdlock(&config_lock); bs_socket = bs_connect(bs_host, bs_port); if (bs_use(bs_socket, bs_tube) != BS_STATUS_OK) { ast_log(LOG_ERROR, "Connection to Beanstalk tube %s @ %s:%d had failed", bs_tube, bs_host, bs_port); ast_rwlock_unlock(&config_lock); return 0; } ast_localtime(&cdr->start, &timeresult, NULL); ast_strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult); if (cdr->answer.tv_sec) { ast_localtime(&cdr->answer, &timeresult, NULL); ast_strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult); } ast_localtime(&cdr->end, &timeresult, NULL); ast_strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult); ast_rwlock_unlock(&config_lock); t_cdr_json = ast_json_pack("{s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:s, s:i, s:i, s:s, s:s, s:s, s:s}", "AccountCode", S_OR(cdr->accountcode, ""), "Source", S_OR(cdr->src, ""), "Destination", S_OR(cdr->dst, ""), "DestinationContext", S_OR(cdr->dcontext, ""), "CallerID", S_OR(cdr->clid, ""), "Channel", S_OR(cdr->channel, ""), "DestinationChannel", S_OR(cdr->dstchannel, ""), "LastApplication", S_OR(cdr->lastapp, ""), "LastData", S_OR(cdr->lastdata, ""), "StartTime", S_OR(strStartTime, ""), "AnswerTime", S_OR(strAnswerTime, ""), "EndTime", S_OR(strEndTime, ""), "Duration", cdr->duration, "Billsec", cdr->billsec, "Disposition", S_OR(ast_cdr_disp2str(cdr->disposition), ""), "AMAFlags", S_OR(ast_channel_amaflags2string(cdr->amaflags), ""), "UniqueID", S_OR(cdr->uniqueid, ""), "UserField", S_OR(cdr->userfield, "")); cdr_buffer = ast_json_dump_string(t_cdr_json); ast_json_unref(t_cdr_json); bs_id = bs_put(bs_socket, priority, BEANSTALK_JOB_DELAY, BEANSTALK_JOB_TTR, cdr_buffer, strlen(cdr_buffer)); if (bs_id > 0) { ast_log(LOG_DEBUG, "Successfully created job %d with %s\n", bs_id, cdr_buffer); } else { ast_log(LOG_ERROR, "CDR job creation failed for %s\n", cdr_buffer); } bs_disconnect(bs_socket); ast_json_free(cdr_buffer); return 0; }
static int timeout_write(struct ast_channel *chan, const char *cmd, char *data, const char *value) { double x = 0.0; long sec = 0L; char timestr[64]; struct ast_tm myt; struct timeval when = {0,}; int res; if (!chan) return -1; if (!data) { ast_log(LOG_ERROR, "Must specify type of timeout to set.\n"); return -1; } if (!value) return -1; res = sscanf(value, "%30ld%30lf", &sec, &x); if (res == 0 || sec < 0) { when.tv_sec = 0; when.tv_usec = 0; } else if (res == 1) { when.tv_sec = sec; } else if (res == 2) { when.tv_sec = sec; when.tv_usec = x * 1000000; } switch (*data) { case 'a': case 'A': ast_channel_lock(chan); ast_channel_setwhentohangup_tv(chan, when); ast_channel_unlock(chan); if (VERBOSITY_ATLEAST(3)) { if (!ast_tvzero(*ast_channel_whentohangup(chan))) { when = ast_tvadd(when, ast_tvnow()); ast_strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S.%3q %Z", ast_localtime(&when, &myt, NULL)); ast_verb(3, "Channel will hangup at %s.\n", timestr); } else { ast_verb(3, "Channel hangup cancelled.\n"); } } break; case 'r': case 'R': if (ast_channel_pbx(chan)) { ast_channel_pbx(chan)->rtimeoutms = when.tv_sec * 1000 + when.tv_usec / 1000; ast_verb(3, "Response timeout set to %.3f\n", ast_channel_pbx(chan)->rtimeoutms / 1000.0); } break; case 'd': case 'D': if (ast_channel_pbx(chan)) { ast_channel_pbx(chan)->dtimeoutms = when.tv_sec * 1000 + when.tv_usec / 1000; ast_verb(3, "Digit timeout set to %.3f\n", ast_channel_pbx(chan)->dtimeoutms / 1000.0); } break; default: ast_log(LOG_ERROR, "Unknown timeout type specified.\n"); break; } return 0; }
static SQLHSTMT execute_cb(struct odbc_obj *obj, void *data) { struct ast_cdr *cdr = data; SQLRETURN ODBC_res; char sqlcmd[2048] = "", timestr[128]; struct ast_tm tm; SQLHSTMT stmt; ast_localtime(&cdr->start, &tm, ast_test_flag(&config, CONFIG_USEGMTIME) ? "GMT" : NULL); ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm); if (ast_test_flag(&config, CONFIG_LOGUNIQUEID)) { snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s " "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp," "lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) " "VALUES ({ts '%s'},?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table, timestr); } else { snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s " "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata," "duration,billsec,disposition,amaflags,accountcode) " "VALUES ({ts '%s'},?,?,?,?,?,?,?,?,?,?,?,?,?)", table, timestr); } ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, obj->con, &stmt); if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) { ast_verb(11, "cdr_odbc: Failure in AllocStatement %d\n", ODBC_res); SQLFreeHandle(SQL_HANDLE_STMT, stmt); return NULL; } SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->clid), 0, cdr->clid, 0, NULL); SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->src), 0, cdr->src, 0, NULL); SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dst), 0, cdr->dst, 0, NULL); SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dcontext), 0, cdr->dcontext, 0, NULL); SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->channel), 0, cdr->channel, 0, NULL); SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dstchannel), 0, cdr->dstchannel, 0, NULL); SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastapp), 0, cdr->lastapp, 0, NULL); SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastdata), 0, cdr->lastdata, 0, NULL); if (ast_test_flag(&config, CONFIG_HRTIME)) { double hrbillsec = 0.0; double hrduration; if (!ast_tvzero(cdr->answer)) { hrbillsec = (double) ast_tvdiff_us(cdr->end, cdr->answer) / 1000000.0; } hrduration = (double) ast_tvdiff_us(cdr->end, cdr->start) / 1000000.0; SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_FLOAT, 0, 0, &hrduration, 0, NULL); SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_FLOAT, 0, 0, &hrbillsec, 0, NULL); } else { SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->duration, 0, NULL); SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->billsec, 0, NULL); } if (ast_test_flag(&config, CONFIG_DISPOSITIONSTRING)) SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(ast_cdr_disp2str(cdr->disposition)) + 1, 0, ast_cdr_disp2str(cdr->disposition), 0, NULL); else SQLBindParameter(stmt, 11, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->disposition, 0, NULL); SQLBindParameter(stmt, 12, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->amaflags, 0, NULL); SQLBindParameter(stmt, 13, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->accountcode), 0, cdr->accountcode, 0, NULL); if (ast_test_flag(&config, CONFIG_LOGUNIQUEID)) { SQLBindParameter(stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->uniqueid), 0, cdr->uniqueid, 0, NULL); SQLBindParameter(stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->userfield), 0, cdr->userfield, 0, NULL); } ODBC_res = SQLExecDirect(stmt, (unsigned char *)sqlcmd, SQL_NTS); if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) { ast_verb(11, "cdr_odbc: Error in ExecDirect: %d\n", ODBC_res); SQLFreeHandle(SQL_HANDLE_STMT, stmt); return NULL; } return stmt; }
static int build_radius_record(VALUE_PAIR **tosend, struct ast_cdr *cdr) { int recordtype = PW_STATUS_STOP; struct ast_tm tm; char timestr[128]; char *tmp; if (!rc_avpair_add(rh, tosend, PW_ACCT_STATUS_TYPE, &recordtype, 0, 0)) return -1; /* Account code */ if (!rc_avpair_add(rh, tosend, PW_AST_ACCT_CODE, &cdr->accountcode, strlen(cdr->accountcode), VENDOR_CODE)) return -1; /* Source */ if (!rc_avpair_add(rh, tosend, PW_AST_SRC, &cdr->src, strlen(cdr->src), VENDOR_CODE)) return -1; /* Destination */ if (!rc_avpair_add(rh, tosend, PW_AST_DST, &cdr->dst, strlen(cdr->dst), VENDOR_CODE)) return -1; /* Destination context */ if (!rc_avpair_add(rh, tosend, PW_AST_DST_CTX, &cdr->dcontext, strlen(cdr->dcontext), VENDOR_CODE)) return -1; /* Caller ID */ if (!rc_avpair_add(rh, tosend, PW_AST_CLID, &cdr->clid, strlen(cdr->clid), VENDOR_CODE)) return -1; /* Channel */ if (!rc_avpair_add(rh, tosend, PW_AST_CHAN, &cdr->channel, strlen(cdr->channel), VENDOR_CODE)) return -1; /* Destination Channel */ if (!rc_avpair_add(rh, tosend, PW_AST_DST_CHAN, &cdr->dstchannel, strlen(cdr->dstchannel), VENDOR_CODE)) return -1; /* Last Application */ if (!rc_avpair_add(rh, tosend, PW_AST_LAST_APP, &cdr->lastapp, strlen(cdr->lastapp), VENDOR_CODE)) return -1; /* Last Data */ if (!rc_avpair_add(rh, tosend, PW_AST_LAST_DATA, &cdr->lastdata, strlen(cdr->lastdata), VENDOR_CODE)) return -1; /* Start Time */ ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, ast_localtime(&cdr->start, &tm, ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL)); if (!rc_avpair_add(rh, tosend, PW_AST_START_TIME, timestr, strlen(timestr), VENDOR_CODE)) return -1; /* Answer Time */ ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, ast_localtime(&cdr->answer, &tm, ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL)); if (!rc_avpair_add(rh, tosend, PW_AST_ANSWER_TIME, timestr, strlen(timestr), VENDOR_CODE)) return -1; /* End Time */ ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, ast_localtime(&cdr->end, &tm, ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL)); if (!rc_avpair_add(rh, tosend, PW_AST_END_TIME, timestr, strlen(timestr), VENDOR_CODE)) return -1; /* Duration */ if (!rc_avpair_add(rh, tosend, PW_AST_DURATION, &cdr->duration, 0, VENDOR_CODE)) return -1; /* Billable seconds */ if (!rc_avpair_add(rh, tosend, PW_AST_BILL_SEC, &cdr->billsec, 0, VENDOR_CODE)) return -1; /* Disposition */ tmp = ast_cdr_disp2str(cdr->disposition); if (!rc_avpair_add(rh, tosend, PW_AST_DISPOSITION, tmp, strlen(tmp), VENDOR_CODE)) return -1; /* AMA Flags */ tmp = ast_cdr_flags2str(cdr->amaflags); if (!rc_avpair_add(rh, tosend, PW_AST_AMA_FLAGS, tmp, strlen(tmp), VENDOR_CODE)) return -1; if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUNIQUEID)) { /* Unique ID */ if (!rc_avpair_add(rh, tosend, PW_AST_UNIQUE_ID, &cdr->uniqueid, strlen(cdr->uniqueid), VENDOR_CODE)) return -1; } if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUSERFIELD)) { /* append the user field */ if (!rc_avpair_add(rh, tosend, PW_AST_USER_FIELD, &cdr->userfield, strlen(cdr->userfield), VENDOR_CODE)) return -1; } /* Setting Acct-Session-Id & User-Name attributes for proper generation of Acct-Unique-Session-Id on server side */ /* Channel */ if (!rc_avpair_add(rh, tosend, PW_USER_NAME, &cdr->channel, strlen(cdr->channel), 0)) return -1; /* Unique ID */ if (!rc_avpair_add(rh, tosend, PW_ACCT_SESSION_ID, &cdr->uniqueid, strlen(cdr->uniqueid), 0)) return -1; return 0; }
static int build_radius_record(VALUE_PAIR **send, struct ast_cel_event_record *record) { int recordtype = PW_STATUS_STOP; struct ast_tm tm; char timestr[128]; char *amaflags; int left_len; char *left_value; int send_len; if (!rc_avpair_add(rh, send, PW_ACCT_STATUS_TYPE, &recordtype, 0, 0)) { return -1; } /* Account code */ if (!ADD_VENDOR_CODE(PW_AST_ACCT_CODE, record->account_code)) { return -1; } /* Source */ if (!ADD_VENDOR_CODE(PW_AST_CIDNUM, record->caller_id_num)) { return -1; } /* Destination */ if (!ADD_VENDOR_CODE(PW_AST_EXTEN, record->extension)) { return -1; } /* Destination context */ if (!ADD_VENDOR_CODE(PW_AST_CONTEXT, record->context)) { return -1; } /* Caller ID */ if (!ADD_VENDOR_CODE(PW_AST_CIDNAME, record->caller_id_name)) { return -1; } /* Caller ID ani */ if (!ADD_VENDOR_CODE(PW_AST_CIDANI, record->caller_id_ani)) { return -1; } /* Caller ID rdnis */ if (!ADD_VENDOR_CODE(PW_AST_CIDRDNIS, record->caller_id_rdnis)) { return -1; } /* Caller ID dnid */ if (!ADD_VENDOR_CODE(PW_AST_CIDDNID, record->caller_id_dnid)) { return -1; } /* Channel */ if (!ADD_VENDOR_CODE(PW_AST_CHANNAME, record->channel_name)) { return -1; } /* Last Application */ if (!ADD_VENDOR_CODE(PW_AST_APPNAME, record->application_name)) { return -1; } /* Last Data */ if (!ADD_VENDOR_CODE(PW_AST_APPDATA, record->application_data)) { return -1; } /* Extra */ left_len = strlen(record->extra); left_value = (char *)record->extra; while(left_len > 0){ if(left_len > 240){ send_len = 240; }else{ send_len = left_len; } if(!rc_avpair_add(rh, send, PW_AST_EXTRA, left_value, send_len, VENDOR_CODE )) { return -1; } left_len-=send_len; left_value+=send_len; } /* Event Time */ ast_localtime(&record->event_time, &tm, ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME) ? "GMT" : NULL); ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm); if (!rc_avpair_add(rh, send, PW_AST_EVENT_TIME, timestr, strlen(timestr), VENDOR_CODE)) { return -1; } /* AMA Flags */ amaflags = ast_strdupa(ast_channel_amaflags2string(record->amaflag)); if (!rc_avpair_add(rh, send, PW_AST_AMA_FLAGS, amaflags, strlen(amaflags), VENDOR_CODE)) { return -1; } if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUNIQUEID)) { /* Unique ID */ if (!ADD_VENDOR_CODE(PW_AST_UNIQUE_ID, record->unique_id)) { return -1; } } /* LinkedID */ if (!ADD_VENDOR_CODE(PW_AST_LINKED_ID, record->linked_id)) { return -1; } /* Setting Acct-Session-Id & User-Name attributes for proper generation of Acct-Unique-Session-Id on server side */ /* Channel */ if (!rc_avpair_add(rh, send, PW_USER_NAME, (void *)record->channel_name, strlen(record->channel_name), 0)) { return -1; } return 0; }
struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event *event) { struct varshead *headp; struct ast_var_t *newvariable; const char *mixed_name; char timebuf[30]; struct ast_channel *tchan; struct ast_cel_event_record record = { .version = AST_CEL_EVENT_RECORD_VERSION, }; /* do not call ast_channel_alloc because this is not really a real channel */ if (!(tchan = ast_dummy_channel_alloc())) { return NULL; } headp = ast_channel_varshead(tchan); /* first, get the variables from the event */ if (ast_cel_fill_record(event, &record)) { ast_channel_unref(tchan); return NULL; } /* next, fill the channel with their data */ mixed_name = (record.event_type == AST_CEL_USER_DEFINED) ? record.user_defined_name : record.event_name; if ((newvariable = ast_var_assign("eventtype", mixed_name))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } if (ast_strlen_zero(cel_dateformat)) { snprintf(timebuf, sizeof(timebuf), "%ld.%06ld", (long) record.event_time.tv_sec, (long) record.event_time.tv_usec); } else { struct ast_tm tm; ast_localtime(&record.event_time, &tm, NULL); ast_strftime(timebuf, sizeof(timebuf), cel_dateformat, &tm); } if ((newvariable = ast_var_assign("eventtime", timebuf))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } if ((newvariable = ast_var_assign("eventenum", record.event_name))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } if ((newvariable = ast_var_assign("userdeftype", record.user_defined_name))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } if ((newvariable = ast_var_assign("eventextra", record.extra))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } ast_channel_caller(tchan)->id.name.valid = 1; ast_channel_caller(tchan)->id.name.str = ast_strdup(record.caller_id_name); ast_channel_caller(tchan)->id.number.valid = 1; ast_channel_caller(tchan)->id.number.str = ast_strdup(record.caller_id_num); ast_channel_caller(tchan)->ani.number.valid = 1; ast_channel_caller(tchan)->ani.number.str = ast_strdup(record.caller_id_ani); ast_channel_redirecting(tchan)->from.number.valid = 1; ast_channel_redirecting(tchan)->from.number.str = ast_strdup(record.caller_id_rdnis); ast_channel_dialed(tchan)->number.str = ast_strdup(record.caller_id_dnid); ast_channel_exten_set(tchan, record.extension); ast_channel_context_set(tchan, record.context); ast_channel_name_set(tchan, record.channel_name); ast_channel_uniqueid_set(tchan, record.unique_id); ast_channel_linkedid_set(tchan, record.linked_id); ast_channel_accountcode_set(tchan, record.account_code); ast_channel_peeraccount_set(tchan, record.peer_account); ast_channel_userfield_set(tchan, record.user_field); if ((newvariable = ast_var_assign("BRIDGEPEER", record.peer))) { AST_LIST_INSERT_HEAD(headp, newvariable, entries); } ast_channel_appl_set(tchan, ast_strdup(record.application_name)); ast_channel_data_set(tchan, ast_strdup(record.application_data)); ast_channel_amaflags_set(tchan, record.amaflag); return tchan; }
static int callerid_genmsg(char *msg, int size, const char *number, const char *name, int flags) { struct timeval now = ast_tvnow(); struct ast_tm tm; char *ptr; int res; int i, x; /* Get the time */ ast_localtime(&now, &tm, NULL); ptr = msg; /* Format time and message header */ res = snprintf(ptr, size, "\001\010%02d%02d%02d%02d", tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min); size -= res; ptr += res; if (ast_strlen_zero(number) || (flags & CID_UNKNOWN_NUMBER)) { /* Indicate number not known */ res = snprintf(ptr, size, "\004\001O"); size -= res; ptr += res; } else if (flags & CID_PRIVATE_NUMBER) { /* Indicate number is private */ res = snprintf(ptr, size, "\004\001P"); size -= res; ptr += res; } else { /* Send up to 16 digits of number MAX */ i = strlen(number); if (i > 16) i = 16; res = snprintf(ptr, size, "\002%c", i); size -= res; ptr += res; for (x = 0; x < i; x++) ptr[x] = number[x]; ptr[i] = '\0'; ptr += i; size -= i; } if (ast_strlen_zero(name) || (flags & CID_UNKNOWN_NAME)) { /* Indicate name not known */ res = snprintf(ptr, size, "\010\001O"); size -= res; ptr += res; } else if (flags & CID_PRIVATE_NAME) { /* Indicate name is private */ res = snprintf(ptr, size, "\010\001P"); size -= res; ptr += res; } else { /* Send up to 16 digits of name MAX */ i = strlen(name); if (i > 16) i = 16; res = snprintf(ptr, size, "\007%c", i); size -= res; ptr += res; for (x = 0; x < i; x++) ptr[x] = name[x]; ptr[i] = '\0'; ptr += i; size -= i; } return (ptr - msg); }
static int pgsql_log(struct ast_cdr *cdr) { struct tm tm; time_t t = cdr->start.tv_sec; char sqlcmd[2048] = "", timestr[128]; char *pgerror; PGresult *result; ast_mutex_lock(&pgsql_lock); ast_localtime(&t, &tm, NULL); strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm); if ((!connected) && pghostname && pgdbuser && pgpassword && pgdbname) { conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword); if (PQstatus(conn) != CONNECTION_BAD) { connected = 1; } else { pgerror = PQerrorMessage(conn); ast_log(LOG_ERROR, "cdr_pgsql: Unable to connect to database server %s. Calls will not be logged!\n", pghostname); ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror); PQfinish(conn); conn = NULL; } } if (connected) { char *clid=NULL, *dcontext=NULL, *channel=NULL, *dstchannel=NULL, *lastapp=NULL, *lastdata=NULL; char *src=NULL, *dst=NULL, *uniqueid=NULL, *userfield=NULL; int pgerr; /* Maximum space needed would be if all characters needed to be escaped, plus a trailing NULL */ if ((clid = alloca(strlen(cdr->clid) * 2 + 1)) != NULL) PQescapeStringConn(conn, clid, cdr->clid, strlen(cdr->clid), &pgerr); if ((dcontext = alloca(strlen(cdr->dcontext) * 2 + 1)) != NULL) PQescapeStringConn(conn, dcontext, cdr->dcontext, strlen(cdr->dcontext), &pgerr); if ((channel = alloca(strlen(cdr->channel) * 2 + 1)) != NULL) PQescapeStringConn(conn, channel, cdr->channel, strlen(cdr->channel), &pgerr); if ((dstchannel = alloca(strlen(cdr->dstchannel) * 2 + 1)) != NULL) PQescapeStringConn(conn, dstchannel, cdr->dstchannel, strlen(cdr->dstchannel), &pgerr); if ((lastapp = alloca(strlen(cdr->lastapp) * 2 + 1)) != NULL) PQescapeStringConn(conn, lastapp, cdr->lastapp, strlen(cdr->lastapp), &pgerr); if ((lastdata = alloca(strlen(cdr->lastdata) * 2 + 1)) != NULL) PQescapeStringConn(conn, lastdata, cdr->lastdata, strlen(cdr->lastdata), &pgerr); if ((uniqueid = alloca(strlen(cdr->uniqueid) * 2 + 1)) != NULL) PQescapeStringConn(conn, uniqueid, cdr->uniqueid, strlen(cdr->uniqueid), &pgerr); if ((userfield = alloca(strlen(cdr->userfield) * 2 + 1)) != NULL) PQescapeStringConn(conn, userfield, cdr->userfield, strlen(cdr->userfield), &pgerr); if ((src = alloca(strlen(cdr->src) * 2 + 1)) != NULL) PQescapeStringConn(conn, src, cdr->src, strlen(cdr->src), &pgerr); if ((dst = alloca(strlen(cdr->dst) * 2 + 1)) != NULL) PQescapeStringConn(conn, dst, cdr->dst, strlen(cdr->dst), &pgerr); /* Check for all alloca failures above at once */ if ((!clid) || (!dcontext) || (!channel) || (!dstchannel) || (!lastapp) || (!lastdata) || (!uniqueid) || (!userfield) || (!src) || (!dst)) { ast_log(LOG_ERROR, "cdr_pgsql: Out of memory error (insert fails)\n"); ast_mutex_unlock(&pgsql_lock); return -1; } if (option_debug > 1) ast_log(LOG_DEBUG, "cdr_pgsql: inserting a CDR record.\n"); snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s (calldate,clid,src,dst,dcontext,channel,dstchannel," "lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) VALUES" " ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%ld,%ld,'%s',%ld,'%s','%s','%s')", table, timestr, clid, src, dst, dcontext, channel, dstchannel, lastapp, lastdata, cdr->duration,cdr->billsec,ast_cdr_disp2str(cdr->disposition),cdr->amaflags, cdr->accountcode, uniqueid, userfield); if (option_debug > 2) ast_log(LOG_DEBUG, "cdr_pgsql: SQL command executed: %s\n",sqlcmd); /* Test to be sure we're still connected... */ /* If we're connected, and connection is working, good. */ /* Otherwise, attempt reconnect. If it fails... sorry... */ if (PQstatus(conn) == CONNECTION_OK) { connected = 1; } else { ast_log(LOG_ERROR, "cdr_pgsql: Connection was lost... attempting to reconnect.\n"); PQreset(conn); if (PQstatus(conn) == CONNECTION_OK) { ast_log(LOG_ERROR, "cdr_pgsql: Connection reestablished.\n"); connected = 1; } else { pgerror = PQerrorMessage(conn); ast_log(LOG_ERROR, "cdr_pgsql: Unable to reconnect to database server %s. Calls will not be logged!\n", pghostname); ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror); PQfinish(conn); conn = NULL; connected = 0; ast_mutex_unlock(&pgsql_lock); return -1; } } result = PQexec(conn, sqlcmd); if (PQresultStatus(result) != PGRES_COMMAND_OK) { pgerror = PQresultErrorMessage(result); ast_log(LOG_ERROR,"cdr_pgsql: Failed to insert call detail record into database!\n"); ast_log(LOG_ERROR,"cdr_pgsql: Reason: %s\n", pgerror); ast_log(LOG_ERROR,"cdr_pgsql: Connection may have been lost... attempting to reconnect.\n"); PQreset(conn); if (PQstatus(conn) == CONNECTION_OK) { ast_log(LOG_ERROR, "cdr_pgsql: Connection reestablished.\n"); connected = 1; PQclear(result); result = PQexec(conn, sqlcmd); if (PQresultStatus(result) != PGRES_COMMAND_OK) { pgerror = PQresultErrorMessage(result); ast_log(LOG_ERROR,"cdr_pgsql: HARD ERROR! Attempted reconnection failed. DROPPING CALL RECORD!\n"); ast_log(LOG_ERROR,"cdr_pgsql: Reason: %s\n", pgerror); } } ast_mutex_unlock(&pgsql_lock); PQclear(result); return -1; } PQclear(result); } ast_mutex_unlock(&pgsql_lock); return 0; }