Exemplo n.º 1
0
static int write_to_ast_str(const char *buffer, size_t size, void *data)
{
	struct ast_str **dst = data;
	size_t str_size = ast_str_size(*dst);
	size_t remaining = str_size - ast_str_strlen(*dst);
	int ret;

	/* While ast_str_append will grow the ast_str, it won't report
	 * allocation errors. Fortunately, it's not that hard.
	 */

	/* Remaining needs to be big enough for buffer, plus null char */
	while (remaining < size + 1) {
		/* doubling the size of the buffer gives us 'amortized
		 * constant' time.
		 * See http://stackoverflow.com/a/249695/115478 for info.
		 */
		str_size *= 2;
		remaining = str_size - ast_str_strlen(*dst);
	}

	ret = ast_str_make_space(dst, str_size);
	if (ret == -1) {
		/* Could not alloc; fail */
		return -1;
	}

	ast_str_append_substr(dst, -1, buffer, size);
	return 0;
}
static int blacklist_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **str, ssize_t len)
{
	/* 2 bytes is a single integer, plus terminating null */
	if (ast_str_size(*str) - ast_str_strlen(*str) < 2) {
		if (len > ast_str_size(*str) || len == 0) {
			ast_str_make_space(str, len ? len : ast_str_strlen(*str) + 2);
		}
	}
	if (ast_str_size(*str) - ast_str_strlen(*str) >= 2) {
		int res = blacklist_read(chan, cmd, data, ast_str_buffer(*str) + ast_str_strlen(*str), 2);
		ast_str_update(*str);
		return res;
	}
	return -1;
}
Exemplo n.º 3
0
static int system_exec_helper(struct ast_channel *chan, const char *data, int failmode)
{
	int res = 0;
	struct ast_str *buf = ast_str_thread_get(&buf_buf, 16);
	char *cbuf;

	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "System requires an argument(command)\n");
		pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
		return failmode;
	}

	ast_autoservice_start(chan);

	/* Do our thing here */
	ast_str_get_encoded_str(&buf, 0, (char *) data);
	cbuf = ast_str_buffer(buf);

	if (strchr("\"'", cbuf[0]) && cbuf[ast_str_strlen(buf) - 1] == cbuf[0]) {
		cbuf[ast_str_strlen(buf) - 1] = '\0';
		cbuf++;
		ast_log(LOG_NOTICE, "It is not necessary to quote the argument to the System application.\n");
	}

	res = ast_safe_system(cbuf);

	if ((res < 0) && (errno != ECHILD)) {
		ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
		pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
		res = failmode;
	} else if (res == 127) {
		ast_log(LOG_WARNING, "Unable to execute '%s'\n", (char *)data);
		pbx_builtin_setvar_helper(chan, chanvar, "FAILURE");
		res = failmode;
	} else {
		if (res < 0) 
			res = 0;
		if (res != 0)
			pbx_builtin_setvar_helper(chan, chanvar, "APPERROR");
		else
			pbx_builtin_setvar_helper(chan, chanvar, "SUCCESS");
		res = 0;
	} 

	ast_autoservice_stop(chan);

	return res;
}
Exemplo n.º 4
0
/*!
 * \internal
 * \brief Build the NOTIFY request adding content or header info.
 */
static void build_notify(pjsip_tx_data *tdata, const char *name, const char *value,
			 struct ast_str **content_type, struct ast_str **content)
{
	if (not_allowed(name)) {
		ast_log(LOG_WARNING, "Cannot specify %s header, "
			"ignoring\n", name);
		return;
	}

	if (!strcasecmp(name, "Content-type")) {
		if (!(*content_type)) {
			*content_type = ast_str_create(CONTENT_TYPE_SIZE);
		}
		ast_str_set(content_type, 0,"%s", value);
	} else if (!strcasecmp(name, "Content")) {
		if (!(*content)) {
			*content = ast_str_create(CONTENT_SIZE);
		}

		if (ast_str_strlen(*content)) {
			ast_str_append(content, 0, "\r\n");
		}
		ast_str_append(content, 0, "%s", value);
	} else {
		ast_sip_add_header(tdata, name, value);
	}
}
Exemplo n.º 5
0
static int collect_names_cb(void *obj, void *arg, int flags) {
	struct ast_control_pvt_cause_code *cause_code = obj;
	struct ast_str **str = arg;

	ast_str_append(str, 0, "%s%s", (ast_str_strlen(*str) ? "," : ""), cause_code->chan_name);

	return 0;
}
Exemplo n.º 6
0
static int base64_helper(struct ast_channel *chan, const char *cmd, char *data,
			 char *buf, struct ast_str **str, ssize_t len)
{
	if (ast_strlen_zero(data)) {
		ast_log(LOG_WARNING, "Syntax: %s(<data>) - missing argument!\n", cmd);
		return -1;
	}

	if (cmd[7] == 'E') {
		if (buf) {
			ast_base64encode(buf, (unsigned char *) data, strlen(data), len);
		} else {
			if (len >= 0) {
				ast_str_make_space(str, len ? len : ast_str_strlen(*str) + strlen(data) * 4 / 3 + 2);
			}
			ast_base64encode(ast_str_buffer(*str) + ast_str_strlen(*str), (unsigned char *) data, strlen(data), ast_str_size(*str) - ast_str_strlen(*str));
			ast_str_update(*str);
		}
	} else {
		int decoded_len;
		if (buf) {
			decoded_len = ast_base64decode((unsigned char *) buf, data, len);
			/* add a terminating null at the end of buf, or at the
			 * end of our decoded string, which ever is less */
			buf[decoded_len <= (len - 1) ? decoded_len : len - 1] = '\0';
		} else {
			if (len >= 0) {
				ast_str_make_space(str, len ? len : ast_str_strlen(*str) + strlen(data) * 3 / 4 + 2);
			}
			decoded_len = ast_base64decode((unsigned char *) ast_str_buffer(*str) + ast_str_strlen(*str), data, ast_str_size(*str) - ast_str_strlen(*str));
			if (len)
				/* add a terminating null at the end of our
				 * buffer, or at the end of our decoded string,
				 * which ever is less */
				ast_str_buffer(*str)[decoded_len <= (len - 1) ? decoded_len : len - 1] = '\0';
			else
				/* space for the null is allocated above */
				ast_str_buffer(*str)[decoded_len] = '\0';

			ast_str_update(*str);
		}
	}

	return 0;
}
Exemplo n.º 7
0
static pjmedia_sdp_attr* generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
{
	struct ast_str *fmtp0 = ast_str_alloca(256);
	pj_str_t fmtp1;
	pjmedia_sdp_attr *attr = NULL;
	char *tmp;

	ast_format_generate_sdp_fmtp(format, rtp_code, &fmtp0);
	if (ast_str_strlen(fmtp0)) {
		tmp = ast_str_buffer(fmtp0) + ast_str_strlen(fmtp0) - 1;
		/* remove any carriage return line feeds */
		while (*tmp == '\r' || *tmp == '\n') --tmp;
		*++tmp = '\0';
		/* ast...generate gives us everything, just need value */
		tmp = strchr(ast_str_buffer(fmtp0), ':');
		if (tmp && tmp + 1) {
			fmtp1 = pj_str(tmp + 1);
		} else {
			fmtp1 = pj_str(ast_str_buffer(fmtp0));
		}
		attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1);
	}
	return attr;
}
Exemplo n.º 8
0
static int load_column_config(const char *tmp)
{
	char *col = NULL;
	char *cols = NULL, *save = NULL;
	char *escaped = NULL;
	struct ast_str *column_string = NULL;

	if (ast_strlen_zero(tmp)) {
		ast_log(LOG_WARNING, "Column names not specified. Module not loaded.\n");
		return -1;
	}
	if (!(column_string = ast_str_create(1024))) {
		ast_log(LOG_ERROR, "Out of memory creating temporary buffer for column list for table '%s.'\n", table);
		return -1;
	}
	if (!(save = cols = ast_strdup(tmp))) {
		ast_log(LOG_ERROR, "Out of memory creating temporary buffer for column list for table '%s.'\n", table);
		ast_free(column_string);
		return -1;
	}
	while ((col = strsep(&cols, ","))) {
		col = ast_strip(col);
		escaped = sqlite3_mprintf("%q", col);
		if (!escaped) {
			ast_log(LOG_ERROR, "Out of memory creating entry for column '%s' in table '%s.'\n", col, table);
			ast_free(column_string);
			ast_free(save);
			return -1;
		}
		ast_str_append(&column_string, 0, "%s%s", ast_str_strlen(column_string) ? "," : "", escaped);
		sqlite3_free(escaped);
	}
	if (!(columns = ast_strdup(ast_str_buffer(column_string)))) {
		ast_log(LOG_ERROR, "Out of memory copying columns string for table '%s.'\n", table);
		ast_free(column_string);
		ast_free(save);
		return -1;
	}
	ast_free(column_string);
	ast_free(save);

	return 0;
}
Exemplo n.º 9
0
static char *handle_cli_cdr_mongodb_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
	switch (cmd) {
	case CLI_INIT:
		e->command = "cdr mongodb status";
		e->usage =
			"Usage: cdr mongodb status\n"
			"       Shows current connection status for cdr_mongodb\n";
		return NULL;
	case CLI_GENERATE:
		return NULL;
	}

	if (a->argc != 3) {
		return CLI_SHOWUSAGE;
	}

	if (connected) {
		char status[256], status2[100] = "";
		if (dbport) {
			snprintf(status, sizeof(status), "Connected to %s@%s, port %d", ast_str_buffer(dbname), ast_str_buffer(hostname), dbport);
		} else {
			snprintf(status, sizeof(status), "Connected to %s@%s", ast_str_buffer(dbname), ast_str_buffer(hostname));
		}

		if (ast_str_strlen(dbcollection)) {
			snprintf(status2, sizeof(status2), " using collection %s", ast_str_buffer(dbcollection));
		}

		if (records == totalrecords) {
			ast_cli(a->fd, "  Wrote %d records since last restart.\n", totalrecords);
		} else {
			ast_cli(a->fd, "  Wrote %d records since last restart and %d records since last reconnect.\n", totalrecords, records);
		}
	} else {
		ast_cli(a->fd, "Not currently connected to a MongoDB server.\n");
	}

	return CLI_SUCCESS;
}
Exemplo n.º 10
0
static u_char *ast_var_channels_table(struct variable *vp, oid *name, size_t *length,
									int exact, size_t *var_len, WriteMethod **write_method)
{
	static unsigned long long_ret;
	static u_char bits_ret[2];
	static char string_ret[256];
	struct ast_channel *chan, *bridge;
	struct timeval tval;
	u_char *ret = NULL;
	int i, bit;
	struct ast_str *out = ast_str_alloca(2048);
	struct ast_channel_iterator *iter;

	if (header_simple_table(vp, name, length, exact, var_len, write_method, ast_active_channels()))
		return NULL;

	i = name[*length - 1] - 1;

	if (!(iter = ast_channel_iterator_all_new())) {
		return NULL;
	}

	while ((chan = ast_channel_iterator_next(iter)) && i) {
		ast_channel_unref(chan);
		i--;
	}

	iter = ast_channel_iterator_destroy(iter);

	if (chan == NULL) {
		return NULL;
	}

	*var_len = sizeof(long_ret);

	ast_channel_lock(chan);

	switch (vp->magic) {
	case ASTCHANINDEX:
		long_ret = name[*length - 1];
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANNAME:
		if (!ast_strlen_zero(ast_channel_name(chan))) {
			ast_copy_string(string_ret, ast_channel_name(chan), sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANLANGUAGE:
		if (!ast_strlen_zero(ast_channel_language(chan))) {
			ast_copy_string(string_ret, ast_channel_language(chan), sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANTYPE:
		ast_copy_string(string_ret, ast_channel_tech(chan)->type, sizeof(string_ret));
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANMUSICCLASS:
		if (!ast_strlen_zero(ast_channel_musicclass(chan))) {
			ast_copy_string(string_ret, ast_channel_musicclass(chan), sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANBRIDGE:
		if ((bridge = ast_bridged_channel(chan)) != NULL) {
			ast_copy_string(string_ret, ast_channel_name(bridge), sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANMASQ:
		if (ast_channel_masq(chan) && !ast_strlen_zero(ast_channel_name(ast_channel_masq(chan)))) {
			ast_copy_string(string_ret, ast_channel_name(ast_channel_masq(chan)), sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANMASQR:
		if (ast_channel_masqr(chan) && !ast_strlen_zero(ast_channel_name(ast_channel_masqr(chan)))) {
			ast_copy_string(string_ret, ast_channel_name(ast_channel_masqr(chan)), sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANWHENHANGUP:
		if (!ast_tvzero(*ast_channel_whentohangup(chan))) {
			gettimeofday(&tval, NULL);
			long_ret = difftime(ast_channel_whentohangup(chan)->tv_sec, tval.tv_sec) * 100 - tval.tv_usec / 10000;
			ret= (u_char *)&long_ret;
		}
		break;
	case ASTCHANAPP:
		if (ast_channel_appl(chan)) {
			ast_copy_string(string_ret, ast_channel_appl(chan), sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANDATA:
		if (ast_channel_data(chan)) {
			ast_copy_string(string_ret, ast_channel_data(chan), sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCONTEXT:
		ast_copy_string(string_ret, ast_channel_context(chan), sizeof(string_ret));
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANMACROCONTEXT:
		ast_copy_string(string_ret, ast_channel_macrocontext(chan), sizeof(string_ret));
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANMACROEXTEN:
		ast_copy_string(string_ret, ast_channel_macroexten(chan), sizeof(string_ret));
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANMACROPRI:
		long_ret = ast_channel_macropriority(chan);
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANEXTEN:
		ast_copy_string(string_ret, ast_channel_exten(chan), sizeof(string_ret));
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANPRI:
		long_ret = ast_channel_priority(chan);
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANACCOUNTCODE:
		if (!ast_strlen_zero(ast_channel_accountcode(chan))) {
			ast_copy_string(string_ret, ast_channel_accountcode(chan), sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANFORWARDTO:
		if (!ast_strlen_zero(ast_channel_call_forward(chan))) {
			ast_copy_string(string_ret, ast_channel_call_forward(chan), sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANUNIQUEID:
		ast_copy_string(string_ret, ast_channel_uniqueid(chan), sizeof(string_ret));
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANCALLGROUP:
		long_ret = ast_channel_callgroup(chan);
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANPICKUPGROUP:
		long_ret = ast_channel_pickupgroup(chan);
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANSTATE:
		long_ret = ast_channel_state(chan) & 0xffff;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANMUTED:
		long_ret = ast_channel_state(chan) & AST_STATE_MUTE ? 1 : 2;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANRINGS:
		long_ret = ast_channel_rings(chan);
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANCIDDNID:
		if (ast_channel_dialed(chan)->number.str) {
			ast_copy_string(string_ret, ast_channel_dialed(chan)->number.str, sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCIDNUM:
		if (ast_channel_caller(chan)->id.number.valid && ast_channel_caller(chan)->id.number.str) {
			ast_copy_string(string_ret, ast_channel_caller(chan)->id.number.str, sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCIDNAME:
		if (ast_channel_caller(chan)->id.name.valid && ast_channel_caller(chan)->id.name.str) {
			ast_copy_string(string_ret, ast_channel_caller(chan)->id.name.str, sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCIDANI:
		if (ast_channel_caller(chan)->ani.number.valid && ast_channel_caller(chan)->ani.number.str) {
			ast_copy_string(string_ret, ast_channel_caller(chan)->ani.number.str, sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCIDRDNIS:
		if (ast_channel_redirecting(chan)->from.number.valid && ast_channel_redirecting(chan)->from.number.str) {
			ast_copy_string(string_ret, ast_channel_redirecting(chan)->from.number.str, sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCIDPRES:
		long_ret = ast_party_id_presentation(&ast_channel_caller(chan)->id);
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANCIDANI2:
		long_ret = ast_channel_caller(chan)->ani2;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANCIDTON:
		long_ret = ast_channel_caller(chan)->id.number.plan;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANCIDTNS:
		long_ret = ast_channel_dialed(chan)->transit_network_select;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANAMAFLAGS:
		long_ret = ast_channel_amaflags(chan);
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANADSI:
		long_ret = ast_channel_adsicpe(chan);
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANTONEZONE:
		if (ast_channel_zone(chan)) {
			ast_copy_string(string_ret, ast_channel_zone(chan)->country, sizeof(string_ret));
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANHANGUPCAUSE:
		long_ret = ast_channel_hangupcause(chan);
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANVARIABLES:
		if (pbx_builtin_serialize_variables(chan, &out)) {
			*var_len = ast_str_strlen(out);
			ret = (u_char *)ast_str_buffer(out);
		}
		break;
	case ASTCHANFLAGS:
		bits_ret[0] = 0;
		for (bit = 0; bit < 8; bit++)
			bits_ret[0] |= ((ast_channel_flags(chan)->flags & (1 << bit)) >> bit) << (7 - bit);
		bits_ret[1] = 0;
		for (bit = 0; bit < 8; bit++)
			bits_ret[1] |= (((ast_channel_flags(chan)->flags >> 8) & (1 << bit)) >> bit) << (7 - bit);
		*var_len = 2;
		ret = bits_ret;
		break;
	case ASTCHANTRANSFERCAP:
		long_ret = ast_channel_transfercapability(chan);
		ret = (u_char *)&long_ret;
	default:
		break;
	}

	ast_channel_unlock(chan);
	chan = ast_channel_unref(chan);

	return ret;
}
Exemplo n.º 11
0
static int mongodb_log(struct ast_cdr *cdr)
{
	const char * ns;
	mongo conn[1];

	ast_debug(1, "mongodb: Starting mongodb_log.\n");

	mongo_init( &conn );
	if (mongo_connect( &conn , ast_str_buffer(hostname), dbport ) != MONGO_OK){
		mongo_destroy( &conn );
		ast_log(LOG_ERROR, "Method: mongodb_log, MongoDB failed to connect.\n");
		connected = 0;
		records = 0;
		return -1;
	}

	if (ast_str_strlen(dbuser) != 0 && (mongo_cmd_authenticate(&conn, ast_str_buffer(dbname), ast_str_buffer(dbuser), ast_str_buffer(password)) != MONGO_OK)) {
		mongo_destroy( &conn );
		ast_log(LOG_ERROR, "Method: mongodb_log, MongoDB failed to authenticate to do %s with username %s!\n", ast_str_buffer(dbname), ast_str_buffer(dbuser));
		connected = 0;
		records = 0;
		return -1;
	}

	ast_debug(1, "mongodb: Locking mongodb_lock.\n");
	ast_mutex_lock(&mongodb_lock);

	ast_debug(1, "mongodb: Got connection, Preparing record.\n");

	bson b[1];

	ast_debug(1, "mongodb: Init bson.\n");
	bson_init( &b );
	bson_append_new_oid( &b, "_id" );
	
	ast_debug(1, "mongodb: accountcode.\n");
	bson_append_string( &b , "accountcode",  cdr->accountcode);

	ast_debug(1, "mongodb: src.\n");
	bson_append_string( &b , "src",  cdr->src);

	ast_debug(1, "mongodb: dst.\n");
	bson_append_string( &b, "dst" , cdr->dst );

	ast_debug(1, "mongodb: dcontext.\n");
	bson_append_string( &b, "dcontext" , cdr->dcontext );

	ast_debug(1, "mongodb: clid.\n");
	bson_append_string( &b, "clid" , cdr->clid );

	ast_debug(1, "mongodb: channel.\n");
	bson_append_string( &b, "channel" , cdr->channel );

	ast_debug(1, "mongodb: dstchannel.\n");
	bson_append_string( &b, "dstchannel" , cdr->dstchannel );

	ast_debug(1, "mongodb: lastapp.\n");
	bson_append_string( &b, "lastapp" , cdr->lastapp );

	ast_debug(1, "mongodb: lastdata.\n");
	bson_append_string( &b, "lastdata" , cdr->lastdata );

	ast_debug(1, "mongodb: start.\n");
	bson_append_date( &b, "start", (bson_date_t)cdr->start.tv_sec*1000);

	ast_debug(1, "mongodb: answer.\n");
	bson_append_date( &b, "answer", (bson_date_t)cdr->answer.tv_sec*1000);

	ast_debug(1, "mongodb: end.\n");
	bson_append_date( &b, "end" , (bson_date_t)cdr->end.tv_sec*1000);

	ast_debug(1, "mongodb: duration.\n");
	bson_append_int( &b, "duration" , cdr->duration );

	ast_debug(1, "mongodb: billsec.\n");
	bson_append_int( &b, "billsec" , cdr->billsec );

	ast_debug(1, "mongodb: disposition.\n");
	bson_append_string( &b, "disposition" , ast_cdr_disp2str(cdr->disposition) );

	ast_debug(1, "mongodb: amaflags.\n");
	bson_append_string( &b, "amaflags" , ast_cdr_flags2str(cdr->amaflags) );

	ast_debug(1, "mongodb: uniqueid.\n");
	bson_append_string( &b, "uniqueid" , cdr->uniqueid );

	ast_debug(1, "mongodb: userfield.\n");
	bson_append_string( &b, "userfield" , cdr->userfield );

	bson_finish(&b);

	ast_debug(1, "mongodb: Inserting a CDR record.\n");
	mongo_insert( &conn , ast_str_buffer(dbnamespace) , &b );
	bson_destroy(&b);
	mongo_destroy( &conn );

	connected = 1;
	records++;
	totalrecords++;

	ast_debug(1, "Unlocking mongodb_lock.\n");
	ast_mutex_unlock(&mongodb_lock);
	return 0;
}
Exemplo n.º 12
0
static int _load_module(int reload)
{
    int res;
	struct ast_config *cfg;
	struct ast_variable *var;
	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };

	mongo conn[1];
	bson b[1];

	ast_debug(1, "Starting mongodb module load.\n");
	ast_debug(1, "Loading mongodb Config.\n");

	if (!(cfg = ast_config_load(config, config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
		ast_log(LOG_WARNING, "Unable to load config for mongodb CDR's: %s\n", config);
		return AST_MODULE_LOAD_SUCCESS;
	} else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
		return AST_MODULE_LOAD_SUCCESS;
	}


	if (reload) {
		_unload_module(1);
	}

	ast_debug(1, "Browsing mongodb Global.\n");
	var = ast_variable_browse(cfg, "global");
	if (!var) {
		return AST_MODULE_LOAD_SUCCESS;
	}

	res = 0;

	res |= load_config_string(cfg, "global", "hostname", &hostname, "localhost");
	res |= load_config_string(cfg, "global", "dbname", &dbname, "astriskcdrdb");
	res |= load_config_string(cfg, "global", "collection", &dbcollection, "cdr");
	res |= load_config_number(cfg, "global", "port", &dbport, 27017);
	res |= load_config_string(cfg, "global", "username", &dbuser, "");
	res |= load_config_string(cfg, "global", "password", &password, "");

	if (res < 0) {
		return AST_MODULE_LOAD_FAILURE;
	}

	ast_debug(1, "Got hostname of %s\n", ast_str_buffer(hostname));
	ast_debug(1, "Got port of %d\n", dbport);
	ast_debug(1, "Got dbname of %s\n", ast_str_buffer(dbname));
	ast_debug(1, "Got dbcollection of %s\n", ast_str_buffer(dbcollection));
	ast_debug(1, "Got user of %s\n", ast_str_buffer(dbuser));
	ast_debug(1, "Got password of %s\n", ast_str_buffer(password));
	
	
	dbnamespace = ast_str_create(255);
	ast_str_set(&dbnamespace, 0, "%s.%s", ast_str_buffer(dbname), ast_str_buffer(dbcollection));

	if (mongo_connect(&conn , ast_str_buffer(hostname), dbport) != MONGO_OK) {
		ast_log(LOG_ERROR, "Method: _load_module, MongoDB failed to connect to %s:%d!\n", ast_str_buffer(hostname), dbport);
		res = -1;
	} else {
		if (ast_str_strlen(dbuser) != 0 && (mongo_cmd_authenticate(&conn, ast_str_buffer(dbname), ast_str_buffer(dbuser), ast_str_buffer(password)) != MONGO_OK)) {
			ast_log(LOG_ERROR, "Method: _load_module, MongoDB failed to authenticate to do %s with username %s!\n", ast_str_buffer(dbname), ast_str_buffer(dbuser));
			res = -1;
		} else {
			connected = 1;
		}
		
		mongo_destroy(&conn);
	}

	ast_config_destroy(cfg);

	res = ast_cdr_register(name, desc, mongodb_log);
	if (res) {
		ast_log(LOG_ERROR, "Unable to register MongoDB CDR handling\n");
	} else {
		res = ast_cli_register_multiple(cdr_mongodb_status_cli, sizeof(cdr_mongodb_status_cli) / sizeof(struct ast_cli_entry));
	}

	return res;
}
Exemplo n.º 13
0
static int load_config(int reload)
{
	char *cat = NULL;
	struct ast_config *cfg;
	struct ast_variable *v;
	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
	int newenablecdr = 0;

	cfg = ast_config_load(CONF_FILE, config_flags);
	if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
		return 0;
	}

	if (cfg == CONFIG_STATUS_FILEINVALID) {
		ast_log(LOG_ERROR, "Config file '%s' could not be parsed\n", CONF_FILE);
		return -1;
	}

	if (!cfg) {
		/* Standard configuration */
		ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
		if (enablecdr)
			ast_cdr_unregister(name);
		enablecdr = 0;
		return -1;
	}

	if (reload) {
		ast_rwlock_wrlock(&customfields_lock);
	}

	if (reload && customfields) {
		ast_free(customfields);
		customfields = NULL;
	}

	while ( (cat = ast_category_browse(cfg, cat)) ) {
		if (!strcasecmp(cat, "general")) {
			v = ast_variable_browse(cfg, cat);
			while (v) {
				if (!strcasecmp(v->name, "enabled"))
					newenablecdr = ast_true(v->value);

				v = v->next;
			}
		} else if (!strcasecmp(cat, "mappings")) {
			customfields = ast_str_create(CUSTOM_FIELDS_BUF_SIZE);
			v = ast_variable_browse(cfg, cat);
			while (v) {
				if (customfields && !ast_strlen_zero(v->name) && !ast_strlen_zero(v->value)) {
					if ((ast_str_strlen(customfields) + strlen(v->value) + strlen(v->name) + 14) < ast_str_size(customfields)) {
						ast_str_append(&customfields, -1, "%s: ${CDR(%s)}\r\n", v->value, v->name);
						ast_log(LOG_NOTICE, "Added mapping %s: ${CDR(%s)}\n", v->value, v->name);
					} else {
						ast_log(LOG_WARNING, "No more buffer space to add other custom fields\n");
						break;
					}

				}
				v = v->next;
			}
		}
	}

	if (reload) {
		ast_rwlock_unlock(&customfields_lock);
	}

	ast_config_destroy(cfg);

	if (enablecdr && !newenablecdr)
		ast_cdr_unregister(name);
	else if (!enablecdr && newenablecdr)
		ast_cdr_register(name, "Asterisk Manager Interface CDR Backend", manager_log);
	enablecdr = newenablecdr;

	return 0;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
static u_char *ast_var_channels_table(struct variable *vp, oid *name, size_t *length,
									int exact, size_t *var_len, WriteMethod **write_method)
{
	static unsigned long long_ret;
	static u_char bits_ret[2];
	static char string_ret[256];
	struct ast_channel *chan, *bridge;
	struct timeval tval;
	u_char *ret = NULL;
	int i, bit;
	struct ast_str *out = ast_str_alloca(2048);

	if (header_simple_table(vp, name, length, exact, var_len, write_method, ast_active_channels()))
		return NULL;

	i = name[*length - 1] - 1;
	for (chan = ast_channel_walk_locked(NULL);
		 chan && i;
		 chan = ast_channel_walk_locked(chan), i--)
		ast_channel_unlock(chan);
	if (chan == NULL)
		return NULL;
	*var_len = sizeof(long_ret);

	switch (vp->magic) {
	case ASTCHANINDEX:
		long_ret = name[*length - 1];
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANNAME:
		if (!ast_strlen_zero(chan->name)) {
			strncpy(string_ret, chan->name, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANLANGUAGE:
		if (!ast_strlen_zero(chan->language)) {
			strncpy(string_ret, chan->language, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANTYPE:
		strncpy(string_ret, chan->tech->type, sizeof(string_ret));
		string_ret[sizeof(string_ret) - 1] = '\0';
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANMUSICCLASS:
		if (!ast_strlen_zero(chan->musicclass)) {
			strncpy(string_ret, chan->musicclass, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANBRIDGE:
		if ((bridge = ast_bridged_channel(chan)) != NULL) {
			strncpy(string_ret, bridge->name, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANMASQ:
		if (chan->masq && !ast_strlen_zero(chan->masq->name)) {
			strncpy(string_ret, chan->masq->name, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANMASQR:
		if (chan->masqr && !ast_strlen_zero(chan->masqr->name)) {
			strncpy(string_ret, chan->masqr->name, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANWHENHANGUP:
		if (!ast_tvzero(chan->whentohangup)) {
			gettimeofday(&tval, NULL);
			long_ret = difftime(chan->whentohangup.tv_sec, tval.tv_sec) * 100 - tval.tv_usec / 10000;
			ret= (u_char *)&long_ret;
		}
		break;
	case ASTCHANAPP:
		if (chan->appl) {
			strncpy(string_ret, chan->appl, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANDATA:
		if (chan->data) {
			strncpy(string_ret, chan->data, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCONTEXT:
		strncpy(string_ret, chan->context, sizeof(string_ret));
		string_ret[sizeof(string_ret) - 1] = '\0';
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANMACROCONTEXT:
		strncpy(string_ret, chan->macrocontext, sizeof(string_ret));
		string_ret[sizeof(string_ret) - 1] = '\0';
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANMACROEXTEN:
		strncpy(string_ret, chan->macroexten, sizeof(string_ret));
		string_ret[sizeof(string_ret) - 1] = '\0';
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANMACROPRI:
		long_ret = chan->macropriority;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANEXTEN:
		strncpy(string_ret, chan->exten, sizeof(string_ret));
		string_ret[sizeof(string_ret) - 1] = '\0';
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANPRI:
		long_ret = chan->priority;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANACCOUNTCODE:
		if (!ast_strlen_zero(chan->accountcode)) {
			strncpy(string_ret, chan->accountcode, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANFORWARDTO:
		if (!ast_strlen_zero(chan->call_forward)) {
			strncpy(string_ret, chan->call_forward, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANUNIQUEID:
		strncpy(string_ret, chan->uniqueid, sizeof(string_ret));
		string_ret[sizeof(string_ret) - 1] = '\0';
		*var_len = strlen(string_ret);
		ret = (u_char *)string_ret;
		break;
	case ASTCHANCALLGROUP:
		long_ret = chan->callgroup;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANPICKUPGROUP:
		long_ret = chan->pickupgroup;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANSTATE:
		long_ret = chan->_state & 0xffff;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANMUTED:
		long_ret = chan->_state & AST_STATE_MUTE ? 1 : 2;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANRINGS:
		long_ret = chan->rings;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANCIDDNID:
		if (chan->cid.cid_dnid) {
			strncpy(string_ret, chan->cid.cid_dnid, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCIDNUM:
		if (chan->cid.cid_num) {
			strncpy(string_ret, chan->cid.cid_num, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCIDNAME:
		if (chan->cid.cid_name) {
			strncpy(string_ret, chan->cid.cid_name, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCIDANI:
		if (chan->cid.cid_ani) {
			strncpy(string_ret, chan->cid.cid_ani, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCIDRDNIS:
		if (chan->cid.cid_rdnis) {
			strncpy(string_ret, chan->cid.cid_rdnis, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANCIDPRES:
		long_ret = chan->cid.cid_pres;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANCIDANI2:
		long_ret = chan->cid.cid_ani2;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANCIDTON:
		long_ret = chan->cid.cid_ton;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANCIDTNS:
		long_ret = chan->cid.cid_tns;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANAMAFLAGS:
		long_ret = chan->amaflags;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANADSI:
		long_ret = chan->adsicpe;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANTONEZONE:
		if (chan->zone) {
			strncpy(string_ret, chan->zone->country, sizeof(string_ret));
			string_ret[sizeof(string_ret) - 1] = '\0';
			*var_len = strlen(string_ret);
			ret = (u_char *)string_ret;
		}
		break;
	case ASTCHANHANGUPCAUSE:
		long_ret = chan->hangupcause;
		ret = (u_char *)&long_ret;
		break;
	case ASTCHANVARIABLES:
		if (pbx_builtin_serialize_variables(chan, &out)) {
			*var_len = ast_str_strlen(out);
			ret = (u_char *)ast_str_buffer(out);
		}
		break;
	case ASTCHANFLAGS:
		bits_ret[0] = 0;
		for (bit = 0; bit < 8; bit++)
			bits_ret[0] |= ((chan->flags & (1 << bit)) >> bit) << (7 - bit);
		bits_ret[1] = 0;
		for (bit = 0; bit < 8; bit++)
			bits_ret[1] |= (((chan->flags >> 8) & (1 << bit)) >> bit) << (7 - bit);
		*var_len = 2;
		ret = bits_ret;
		break;
	case ASTCHANTRANSFERCAP:
		long_ret = chan->transfercapability;
		ret = (u_char *)&long_ret;
	default:
		break;
	}
	ast_channel_unlock(chan);
	return ret;
}