static switch_status_t my_on_reporting(switch_core_session_t *session)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	const char *template_str = NULL;
	char *expanded_vars = NULL, *sql = NULL;

	if (globals.shutdown) {
		return SWITCH_STATUS_SUCCESS;
	}

	if (!((globals.legs & CDR_LEG_A) && (globals.legs & CDR_LEG_B))) {
		if ((globals.legs & CDR_LEG_A)) {
			if (switch_channel_get_originator_caller_profile(channel)) {
				return SWITCH_STATUS_SUCCESS;
			}
		} else {
			if (switch_channel_get_originatee_caller_profile(channel)) {
				return SWITCH_STATUS_SUCCESS;
			}
		}
	}

	if (globals.debug) {
		switch_event_t *event;
		if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
			char *buf;
			switch_channel_event_set_data(channel, event);
			switch_event_serialize(event, &buf, SWITCH_FALSE);
			switch_assert(buf);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "CHANNEL_DATA:\n%s\n", buf);
			switch_event_destroy(&event);
			switch_safe_free(buf);
		}
	}

	template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template);

	if (!template_str) {
		template_str = default_template;
	}

	expanded_vars = switch_channel_expand_variables(channel, template_str);

	if (!expanded_vars) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error expanding CDR variables.\n");
		return SWITCH_STATUS_FALSE;
	}

	sql = switch_mprintf("INSERT INTO %s VALUES (%s)", globals.db_table, expanded_vars);
	assert(sql);
	write_cdr(sql);
	switch_safe_free(sql);

	if (expanded_vars != template_str) {
		switch_safe_free(expanded_vars);
	}

	return status;
}
static switch_status_t my_on_reporting(switch_core_session_t *session)
{
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	const char *log_dir = NULL, *accountcode = NULL, *a_template_str = NULL, *g_template_str = NULL;
	char *log_line, *path = NULL;

	if (globals.shutdown) {
		return SWITCH_STATUS_SUCCESS;
	}

	if (!((globals.legs & CDR_LEG_A) && (globals.legs & CDR_LEG_B))) {
		if ((globals.legs & CDR_LEG_A)) {
			if (switch_channel_get_originator_caller_profile(channel)) {
				return SWITCH_STATUS_SUCCESS;
			}
		} else {
			if (switch_channel_get_originatee_caller_profile(channel)) {
				return SWITCH_STATUS_SUCCESS;
			}
		}
	}

	if (!(log_dir = switch_channel_get_variable(channel, "cdr_csv_base"))) {
		log_dir = globals.log_dir;
	}

	if (switch_dir_make_recursive(log_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", log_dir);
		return SWITCH_STATUS_FALSE;
	}

	if (globals.debug) {
		switch_event_t *event;
		if (switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS) {
			char *buf;
			switch_channel_event_set_data(channel, event);
			switch_event_serialize(event, &buf, SWITCH_FALSE);
			switch_assert(buf);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "CHANNEL_DATA:\n%s\n", buf);
			switch_event_destroy(&event);
			free(buf);
		}
	}

	g_template_str = (const char *) switch_core_hash_find(globals.template_hash, globals.default_template);

	if ((accountcode = switch_channel_get_variable(channel, "ACCOUNTCODE"))) {
		a_template_str = (const char *) switch_core_hash_find(globals.template_hash, accountcode);
	}

	if (!g_template_str) {
		g_template_str =
			"\"${accountcode}\",\"${caller_id_number}\",\"${destination_number}\",\"${context}\",\"${caller_id}\",\"${channel_name}\",\"${bridge_channel}\",\"${last_app}\",\"${last_arg}\",\"${start_stamp}\",\"${answer_stamp}\",\"${end_stamp}\",\"${duration}\",\"${billsec}\",\"${hangup_cause}\",\"${amaflags}\",\"${uuid}\",\"${userfield}\";";
	}

	if (!a_template_str) {
		a_template_str = g_template_str;
	}

	log_line = switch_channel_expand_variables(channel, a_template_str);

	if ((accountcode) && (!globals.masterfileonly)) {
		path = switch_mprintf("%s%s%s.csv", log_dir, SWITCH_PATH_SEPARATOR, accountcode);
		assert(path);
		write_cdr(path, log_line);
		free(path);
	}

	if (g_template_str != a_template_str) {
		if (log_line != a_template_str) {
			switch_safe_free(log_line);
		}
		log_line = switch_channel_expand_variables(channel, g_template_str);
	}

	if (!log_line) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating cdr\n");
		return SWITCH_STATUS_FALSE;
	}

	path = switch_mprintf("%s%sMaster.csv", log_dir, SWITCH_PATH_SEPARATOR);
	assert(path);
	write_cdr(path, log_line);
	free(path);


	if (log_line != g_template_str) {
		free(log_line);
	}

	return status;
}
void conference_event_call_setup_handler(switch_event_t *event)
{
	switch_status_t status = SWITCH_STATUS_FALSE;
	conference_obj_t *conference = NULL;
	char *conf = switch_event_get_header(event, "Target-Component");
	char *domain = switch_event_get_header(event, "Target-Domain");
	char *dial_str = switch_event_get_header(event, "Request-Target");
	char *dial_uri = switch_event_get_header(event, "Request-Target-URI");
	char *action = switch_event_get_header(event, "Request-Action");
	char *ext = switch_event_get_header(event, "Request-Target-Extension");
	char *ext_domain = switch_event_get_header(event, "Request-Target-Domain");
	char *full_url = switch_event_get_header(event, "full_url");
	char *call_id = switch_event_get_header(event, "Request-Call-ID");

	if (!ext) ext = dial_str;

	if (!zstr(conf) && !zstr(dial_str) && !zstr(action) && (conference = conference_find(conf, domain))) {
		switch_event_t *var_event;
		switch_event_header_t *hp;

		if (conference_utils_test_flag(conference, CFLAG_RFC4579)) {
			char *key = switch_mprintf("conference_%s_%s_%s_%s", conference->name, conference->domain, ext, ext_domain);
			char *expanded = NULL, *ostr = dial_str;;

			if (!strcasecmp(action, "call")) {
				if((conference->max_members > 0) && (conference->count >= conference->max_members)) {
					// Conference member limit has been reached; do not proceed with setup request
					status = SWITCH_STATUS_FALSE;
				} else {
					if (switch_event_create_plain(&var_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) {
						abort();
					}

					for(hp = event->headers; hp; hp = hp->next) {
						if (!strncasecmp(hp->name, "var_", 4)) {
							switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, hp->name + 4, hp->value);
						}
					}

					switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_call_key", key);
					switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_destination_number", ext);

					switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_invite_uri", dial_uri);

					switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_status", "true");
					switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "conference_track_call_id", call_id);
					switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_invite_domain", domain);
					switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_invite_contact_params", "~isfocus");

					if (!strncasecmp(ostr, "url+", 4)) {
						ostr += 4;
					} else if (!switch_true(full_url) && conference->outcall_templ) {
						if ((expanded = switch_event_expand_headers(var_event, conference->outcall_templ))) {
							ostr = expanded;
						}
					}

					status = conference_outcall_bg(conference, NULL, NULL, ostr, 60, NULL, NULL, NULL, NULL, NULL, NULL, &var_event);

					if (expanded && expanded != conference->outcall_templ) {
						switch_safe_free(expanded);
					}
				}

			} else if (!strcasecmp(action, "end")) {
				if (switch_core_session_hupall_matching_var("conference_call_key", key, SWITCH_CAUSE_NORMAL_CLEARING)) {
					conference_send_notify(conference, "SIP/2.0 200 OK\r\n", call_id, SWITCH_TRUE);
				} else {
					conference_send_notify(conference, "SIP/2.0 481 Failure\r\n", call_id, SWITCH_TRUE);
				}
				status = SWITCH_STATUS_SUCCESS;
			}

			switch_safe_free(key);
		} else { // Conference found but doesn't support referral.
			status = SWITCH_STATUS_FALSE;
		}


		switch_thread_rwlock_unlock(conference->rwlock);
	} else { // Couldn't find associated conference.  Indicate failure on refer subscription
		status = SWITCH_STATUS_FALSE;
	}

	if(status != SWITCH_STATUS_SUCCESS) {
		// Unable to setup call, need to generate final NOTIFY
		if (switch_event_create(&event, SWITCH_EVENT_CONFERENCE_DATA) == SWITCH_STATUS_SUCCESS) {
			event->flags |= EF_UNIQ_HEADERS;

			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-name", conf);
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-domain", domain);
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "conference-event", "refer");
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call_id", call_id);
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "final", "true");
			switch_event_add_body(event, "%s", "SIP/2.0 481 Failure\r\n");
			switch_event_fire(&event);
		}
	}

}
Beispiel #4
0
static switch_bool_t fsk_detect_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
	switch_fsk_detect_t *pvt = (switch_fsk_detect_t *) user_data;
	//switch_frame_t *frame = NULL;
	switch_channel_t *channel = switch_core_session_get_channel(pvt->session);

	switch (type) {
	case SWITCH_ABC_TYPE_INIT: {
		switch_codec_implementation_t read_impl = { 0 };
		switch_core_session_get_read_impl(pvt->session, &read_impl);
		
		if (fsk_demod_init(&pvt->fsk_data, read_impl.actual_samples_per_second, pvt->fbuf, sizeof(pvt->fbuf))) {
			return SWITCH_FALSE;
		}
		
		break;
	}
	case SWITCH_ABC_TYPE_CLOSE:
		{
			fsk_demod_destroy(&pvt->fsk_data);
		}
		break;

	case SWITCH_ABC_TYPE_WRITE_REPLACE:
	case SWITCH_ABC_TYPE_READ_REPLACE:
		{
			switch_frame_t *rframe;

			if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
				rframe = switch_core_media_bug_get_read_replace_frame(bug);
			} else {
				rframe = switch_core_media_bug_get_write_replace_frame(bug);
			}

			if (!pvt->skip && fsk_demod_feed(&pvt->fsk_data, rframe->data, rframe->datalen / 2) != SWITCH_STATUS_SUCCESS) {
				char str[1024] = "";
				size_t type, mlen;
				char *sp;
				switch_event_t *event;
				const char *app_var;
				int total = 0;

				switch_event_create_plain(&event, SWITCH_EVENT_CHANNEL_DATA);
				
				while(fsk_data_parse(&pvt->fsk_data, &type, &sp, &mlen) == SWITCH_STATUS_SUCCESS) {
					char *varname = NULL, *val, *p;
					
					switch_copy_string(str, sp, mlen+1);
					*(str+mlen) = '\0';
					switch_clean_string(str);
					//printf("TYPE %u LEN %u VAL [%s]\n", (unsigned)type, (unsigned)mlen, str);

					val = str;

					switch(type) {
					case MDMF_DATETIME:
						varname = "fsk_datetime";
						break;
					case MDMF_PHONE_NAME:
						varname = "fsk_phone_name";
						break;
					case MDMF_PHONE_NUM:
						varname = "fsk_phone_num";
						break;
					case MDMF_NAME_VALUE:
						varname = switch_core_session_sprintf(pvt->session, "fsk_%s", val);
						if ((p = strchr(varname, ':'))) {
							*p++ = '\0';
							val = p;
						}
						break;
					default:
						break;
					}

					if (varname && val) {
						total++;
						switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s setting FSK var [%s][%s]\n", 
										  switch_channel_get_name(channel), varname, val);
						switch_channel_set_variable(channel, varname, val);
						if (event) {
							switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, varname, val);
						}
					}
				}

				if (event) {
					if (switch_core_session_queue_event(pvt->session, &event) != SWITCH_STATUS_SUCCESS) {
						switch_event_destroy(&event);
					}
				}
				
				if (total && (app_var = switch_channel_get_variable(channel, "execute_on_fsk"))) {
					char *app_arg;

					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(pvt->session), SWITCH_LOG_DEBUG, "%s processing execute_on_fsk [%s]\n", 
									  switch_channel_get_name(channel), app_var);
					if ((app_arg = strchr(app_var, ' '))) {
						*app_arg++ = '\0';
					}
					switch_core_session_execute_application(pvt->session, app_var, app_arg);
				}
				
				pvt->skip = 10;
			}
			
			memset(rframe->data, 255, rframe->datalen);

			if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
				switch_core_media_bug_set_read_replace_frame(bug, rframe);
			} else {
				switch_core_media_bug_set_write_replace_frame(bug, rframe);
			}

			if (pvt->skip && !--pvt->skip) {
				return SWITCH_FALSE;
			}

		}
		break;
	case SWITCH_ABC_TYPE_WRITE:
	default:
		break;
	}

	return SWITCH_TRUE;
}
Beispiel #5
0
/**
 * Encode log as GELF
 */
static char *to_gelf(const switch_log_node_t *node, switch_log_level_t log_level)
{
	char *gelf_text = NULL;
	cJSON *gelf = cJSON_CreateObject();
	char *hostname;
	char timestamp[32];
	char *full_message = node->content;
	char short_message[151];
	char *short_message_end = NULL;
	char *parsed_full_message = NULL;
	char *field_name = NULL;
	switch_event_t *log_fields = NULL;
	switch_core_session_t *session = NULL;

	cJSON_AddItemToObject(gelf, "version", cJSON_CreateString("1.1"));
	if ((hostname = switch_core_get_variable("hostname")) && !zstr(hostname)) {
		cJSON_AddItemToObject(gelf, "host", cJSON_CreateString(hostname));
	} else if ((hostname = switch_core_get_variable("local_ip_v4")) && !zstr(hostname)) {
		cJSON_AddItemToObject(gelf, "host", cJSON_CreateString(hostname));
	}
	switch_snprintf(timestamp, 32, "%"SWITCH_UINT64_T_FMT".%d", (uint64_t)(node->timestamp / 1000000), (node->timestamp % 1000000) / 1000);
	cJSON_AddItemToObject(gelf, "timestamp", cJSON_CreateString(timestamp));
	cJSON_AddItemToObject(gelf, "_microtimestamp", cJSON_CreateNumber(node->timestamp));
	cJSON_AddItemToObject(gelf, "level", cJSON_CreateNumber(to_graylog2_level(log_level)));
	cJSON_AddItemToObject(gelf, "_ident", cJSON_CreateString("freeswitch"));
	cJSON_AddItemToObject(gelf, "_pid", cJSON_CreateNumber((int)getpid()));
	if (!zstr(node->userdata)) {
		cJSON_AddItemToObject(gelf, "_uuid", cJSON_CreateString(node->userdata));
	}
	if (!zstr_buf(node->file)) {
		cJSON_AddItemToObject(gelf, "_file", cJSON_CreateString(node->file));
		cJSON_AddItemToObject(gelf, "_line", cJSON_CreateNumber(node->line));
	}
	if (!zstr_buf(node->func)) {
		cJSON_AddItemToObject(gelf, "_function", cJSON_CreateString(node->func));
	}

	/* skip initial space and new line */
	if (*full_message == ' ') {
		full_message++;
	}
	if (*full_message == '\n') {
		full_message++;
	}

	/* get fields from channel data, if configured */
	if (!zstr(node->userdata) && (session = switch_core_session_locate(node->userdata))) {
		switch_channel_t *channel = switch_core_session_get_channel(session);
		switch_event_header_t *hp;
		/* session_fields name mapped to variable name */
		for (hp = globals.session_fields->headers; hp; hp = hp->next) {
			if (!zstr(hp->name) && !zstr(hp->value)) {
				const char *val = switch_channel_get_variable(channel, hp->value);
				if (!zstr(val)) {
					if (!log_fields) {
						switch_event_create_plain(&log_fields, SWITCH_EVENT_CHANNEL_DATA);
					}
					switch_event_add_header_string(log_fields, SWITCH_STACK_BOTTOM, hp->name, val);
				}
			}
		}
		switch_core_session_rwunlock(session);
	}

	/* parse list of fields from message text, if any */
	if (strncmp(full_message, "LOG_FIELDS", 10) == 0) {
		switch_event_create_brackets(full_message+10, '[', ']', ',', &log_fields, &parsed_full_message, SWITCH_TRUE);
		full_message = parsed_full_message;
	}

	/* add additional fields */
	if (log_fields) {
		switch_event_header_t *hp;
		for (hp = log_fields->headers; hp; hp = hp->next) {
			if (!zstr(hp->name) && !zstr(hp->value)) {
				if (strncmp(hp->name, "@#", 2) == 0) {
					field_name = switch_mprintf("_%s", hp->name + 2);
					cJSON_AddItemToObject(gelf, field_name, cJSON_CreateNumber(strtod(hp->value, NULL)));
				} else {
					field_name = switch_mprintf("_%s", hp->name);
					cJSON_AddItemToObject(gelf, field_name, cJSON_CreateString(hp->value));
				}
				free(field_name);
			}
		}
		switch_event_destroy(&log_fields);
	}

	cJSON_AddItemToObject(gelf, "full_message", cJSON_CreateString(full_message));

	switch_snprintf(short_message, sizeof(short_message) - 1, "%s", full_message);
	if ((short_message_end = strchr(short_message, '\n'))) {
		*short_message_end = '\0';
	}
	cJSON_AddItemToObject(gelf, "short_message", cJSON_CreateString(short_message));

	gelf_text = cJSON_PrintUnformatted(gelf);
	cJSON_Delete(gelf);
	
	switch_safe_free(parsed_full_message);
	
	return gelf_text;
}