Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 4
0
/*
* 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;
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
/*!
 * \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;
}
Ejemplo n.º 7
0
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);
	}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
0
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);
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
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, &timestr, 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);
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
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,
	};
	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;
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
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;
}
Ejemplo n.º 22
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;
}
Ejemplo n.º 23
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;
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
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;
}
Ejemplo n.º 27
0
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);
	
}
Ejemplo n.º 28
0
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;
}