static void set_json_chan_vars(struct json_object *json, switch_channel_t *channel)
{
	struct json_object *variable = NULL;
	switch_event_header_t *hi = switch_channel_variable_first(channel);

	if (!hi)
		return;

	for (; hi; hi = hi->next) {
		if (!zstr(hi->name) && !zstr(hi->value)) {
			char *data = hi->value;
			if (globals.encode_values == ENCODING_DEFAULT) {
				switch_size_t dlen = strlen(hi->value) * 3;

				if ((data = malloc(dlen))) {
					memset(data, 0, dlen);
					switch_url_encode(hi->value, data, dlen);
				}
			}

			variable = json_object_safe_new_string(data);			
			if (!is_error(variable)) {
				json_object_object_add(json, hi->name, variable);
			}

			if (data != hi->value) {
				switch_safe_free(data);
			}
		}
	}
	switch_channel_variable_last(channel);
}
Example #2
0
SWITCH_DECLARE(void) set_json_chan_vars(struct json_object *json, switch_channel_t *channel)
{
	struct json_object *variable = NULL;
	switch_event_header_t *hi = switch_channel_variable_first(channel);

	if (!hi)
		return;

	for (; hi; hi = hi->next) {
		if (!zstr(hi->name) && !zstr(hi->value)) {
			char *data;
			switch_size_t dlen = strlen(hi->value) * 3;

			if ((data = malloc(dlen))) {
				memset(data, 0, dlen);
				switch_url_encode(hi->value, data, dlen);

				variable = json_object_new_string(data);
				if (!is_error(variable)) {
					json_object_object_add(json, hi->name, variable);
				}
				free(data);
			}
		}
	}
	switch_channel_variable_last(channel);

	return;
}
Example #3
0
char *sofia_media_get_multipart(switch_core_session_t *session, const char *prefix, const char *sdp, char **mp_type)
{
	char *extra_headers = NULL;
	switch_stream_handle_t stream = { 0 };
	switch_event_header_t *hi = NULL;
	int x = 0;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	const char *boundary = switch_core_session_get_uuid(session);

	SWITCH_STANDARD_STREAM(stream);
	if ((hi = switch_channel_variable_first(channel))) {
		for (; hi; hi = hi->next) {
			const char *name = (char *) hi->name;
			char *value = (char *) hi->value;

			if (!strncasecmp(name, prefix, strlen(prefix))) {
				const char *hname = name + strlen(prefix);
				if (*value == '~') {
					stream.write_function(&stream, "--%s\nContent-Type: %s\nContent-Length: %d\n%s\n", boundary, hname, strlen(value), value + 1);
				} else {
					stream.write_function(&stream, "--%s\nContent-Type: %s\nContent-Length: %d\n\n%s\n", boundary, hname, strlen(value) + 1, value);
				}
				x++;
			}
		}
		switch_channel_variable_last(channel);
	}

	if (x) {
		*mp_type = switch_core_session_sprintf(session, "multipart/mixed; boundary=%s", boundary);
		if (sdp) {
			stream.write_function(&stream, "--%s\nContent-Type: application/sdp\nContent-Length: %d\n\n%s\n", boundary, strlen(sdp) + 1, sdp);
		}
		stream.write_function(&stream, "--%s--\n", boundary);
	}

	if (!zstr((char *) stream.data)) {
		extra_headers = stream.data;
	} else {
		switch_safe_free(stream.data);
	}

	return extra_headers;
}
Example #4
0
static void save_extra_headers(switch_event_t *extra_headers, switch_channel_t *channel)
{
	switch_event_header_t *ei = NULL;
	for (ei = switch_channel_variable_first(channel);
	     ei;
	     ei = ei->next) {
		const char *name = ei->name;
		char *value = ei->value;
		if (!strncasecmp(name, SIP_OREKA_HEADER_PREFIX, SIP_OREKA_HEADER_PREFIX_LEN)) {
			switch_event_add_header_string(extra_headers, SWITCH_STACK_BOTTOM, name, value);
		}
	}
	switch_channel_variable_last(channel);

	/* Remove the custom header variables that were saved */
	for (ei = extra_headers->headers;
	     ei;
	     ei = ei->next) {
		char *varname = ei->name;
		switch_channel_set_variable(channel, varname, NULL);
	}
}
Example #5
0
static switch_status_t my_on_reporting(switch_core_session_t *session)
{
	switch_status_t status = SWITCH_STATUS_SUCCESS;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	switch_event_header_t *hi;
	switch_caller_profile_t *caller_profile;
	switch_app_log_t *app_log;
	bson cdr;
	int is_b;
	char *tmp;

	if (globals.shutdown) {
		return SWITCH_STATUS_SUCCESS;
	}

	is_b = channel && switch_channel_get_originator_caller_profile(channel);
	if (!globals.log_b && is_b) {
		const char *force_cdr = switch_channel_get_variable(channel, SWITCH_FORCE_PROCESS_CDR_VARIABLE);
		if (!switch_true(force_cdr)) {
			return SWITCH_STATUS_SUCCESS;
		}
	}

	bson_init(&cdr);

	/* Channel data */
	bson_append_start_object(&cdr, "channel_data");
	bson_append_string(&cdr, "state", switch_channel_state_name(switch_channel_get_state(channel)));
	bson_append_string(&cdr, "direction", switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
	bson_append_int(&cdr, "state_number", switch_channel_get_state(channel));

	if ((tmp = switch_channel_get_flag_string(channel))) {
		bson_append_string(&cdr, "flags", tmp);
		free(tmp);
	}

	if ((tmp = switch_channel_get_cap_string(channel))) {
		bson_append_string(&cdr, "caps", tmp);
		free(tmp);
	}
	bson_append_finish_object(&cdr);				/* channel_data */


	/* Channel variables */
	bson_append_start_object(&cdr, "variables");

	if ((hi = switch_channel_variable_first(channel))) {
		for (; hi; hi = hi->next) {
			if (!zstr(hi->name) && !zstr(hi->value)) {
				bson_append_string(&cdr, hi->name, hi->value);
			}
		}
		switch_channel_variable_last(channel);
	}

	bson_append_finish_object(&cdr);				/* variables */


	/* App log */
	if ((app_log = switch_core_session_get_app_log(session))) {
		switch_app_log_t *ap;

		bson_append_start_object(&cdr, "app_log");
		for (ap = app_log; ap; ap = ap->next) {
			bson_append_start_object(&cdr, "application");
			bson_append_string(&cdr, "app_name", ap->app);
			bson_append_string(&cdr, "app_data", ap->arg);
			bson_append_long(&cdr, "app_stamp", ap->stamp);
			bson_append_finish_object(&cdr);		/* application */
		}

		bson_append_finish_object(&cdr);			/* app_log */
	}


	/* Callflow */
	caller_profile = switch_channel_get_caller_profile(channel);

	while (caller_profile) {
		bson_append_start_object(&cdr, "callflow");

		if (!zstr(caller_profile->dialplan)) {
			bson_append_string(&cdr, "dialplan", caller_profile->dialplan);
		}

		if (!zstr(caller_profile->profile_index)) {
			bson_append_string(&cdr, "profile_index", caller_profile->profile_index);
		}

		if (caller_profile->caller_extension) {
			switch_caller_application_t *ap;

			bson_append_start_object(&cdr, "extension");

			bson_append_string(&cdr, "name", caller_profile->caller_extension->extension_name);
			bson_append_string(&cdr, "number", caller_profile->caller_extension->extension_number);

			if (caller_profile->caller_extension->current_application) {
				bson_append_string(&cdr, "current_app", caller_profile->caller_extension->current_application->application_name);
			}

			for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) {
				bson_append_start_object(&cdr, "application");
				if (ap == caller_profile->caller_extension->current_application) {
					bson_append_bool(&cdr, "last_executed", 1);
				}
				bson_append_string(&cdr, "app_name", ap->application_name);
				bson_append_string(&cdr, "app_data", ap->application_data);
				bson_append_finish_object(&cdr);
			}

			if (caller_profile->caller_extension->children) {
				switch_caller_profile_t *cp = NULL;

				for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) {

					if (!cp->caller_extension) {
						continue;
					}

					bson_append_start_object(&cdr, "sub_extensions");
					bson_append_start_object(&cdr, "extension");

					bson_append_string(&cdr, "name", cp->caller_extension->extension_name);
					bson_append_string(&cdr, "number", cp->caller_extension->extension_number);
					bson_append_string(&cdr, "dialplan", cp->dialplan);
					if (cp->caller_extension->current_application) {
						bson_append_string(&cdr, "current_app", cp->caller_extension->current_application->application_name);
					}

					for (ap = cp->caller_extension->applications; ap; ap = ap->next) {
						bson_append_start_object(&cdr, "application");
						if (ap == cp->caller_extension->current_application) {
							bson_append_bool(&cdr, "last_executed", 1);
						}
						bson_append_string(&cdr, "app_name", ap->application_name);
						bson_append_string(&cdr, "app_data", ap->application_data);
						bson_append_finish_object(&cdr);
					}

					bson_append_finish_object(&cdr);	/* extension */
					bson_append_finish_object(&cdr);	/* sub_extensions */
				}
			}

			bson_append_finish_object(&cdr);			/* extension */
		}

		bson_append_start_object(&cdr, "caller_profile");
		set_bson_profile_data(&cdr, caller_profile);

		if (caller_profile->origination_caller_profile) {
			switch_caller_profile_t *cp = NULL;

			bson_append_start_object(&cdr, "origination");
			for (cp = caller_profile->origination_caller_profile; cp; cp = cp->next) {
				bson_append_start_object(&cdr, "origination_caller_profile");
				set_bson_profile_data(&cdr, cp);
				bson_append_finish_object(&cdr);
			}
			bson_append_finish_object(&cdr);			/* origination */
		}

		if (caller_profile->originator_caller_profile) {
			switch_caller_profile_t *cp = NULL;

			bson_append_start_object(&cdr, "originator");
			for (cp = caller_profile->originator_caller_profile; cp; cp = cp->next) {
				bson_append_start_object(&cdr, "originator_caller_profile");
				set_bson_profile_data(&cdr, cp);
				bson_append_finish_object(&cdr);
			}
			bson_append_finish_object(&cdr);			/* originator */
		}

		if (caller_profile->originatee_caller_profile) {
			switch_caller_profile_t *cp = NULL;

			bson_append_start_object(&cdr, "originatee");
			for (cp = caller_profile->originatee_caller_profile; cp; cp = cp->next) {
				bson_append_start_object(&cdr, "originatee_caller_profile");
				set_bson_profile_data(&cdr, cp);
				bson_append_finish_object(&cdr);
			}
			bson_append_finish_object(&cdr);			/* originatee */
		}

		bson_append_finish_object(&cdr);				/* caller_profile */

		/* Timestamps */
		if (caller_profile->times) {
			bson_append_start_object(&cdr, "times");

			/* Insert timestamps as long ints (microseconds) to preserve accuracy */
			bson_append_long(&cdr, "created_time", caller_profile->times->created);
			bson_append_long(&cdr, "profile_created_time", caller_profile->times->profile_created);
			bson_append_long(&cdr, "progress_time", caller_profile->times->progress);
			bson_append_long(&cdr, "progress_media_time", caller_profile->times->progress_media);
			bson_append_long(&cdr, "answered_time", caller_profile->times->answered);
			bson_append_long(&cdr, "bridged_time", caller_profile->times->bridged);
			bson_append_long(&cdr, "last_hold_time", caller_profile->times->last_hold);
			bson_append_long(&cdr, "hold_accum_time", caller_profile->times->hold_accum);
			bson_append_long(&cdr, "hangup_time", caller_profile->times->hungup);
			bson_append_long(&cdr, "resurrect_time", caller_profile->times->resurrected);
			bson_append_long(&cdr, "transfer_time", caller_profile->times->transferred);
			bson_append_finish_object(&cdr);			/* times */
		}

		bson_append_finish_object(&cdr);				/* callflow */
		caller_profile = caller_profile->next;
	}

	bson_finish(&cdr);

	switch_mutex_lock(globals.mongo_mutex);

	if (mongo_insert(globals.mongo_conn, globals.mongo_namespace, &cdr) != MONGO_OK) {
		if (globals.mongo_conn->err == MONGO_IO_ERROR) {
			mongo_error_t db_status;
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "MongoDB connection failed; attempting reconnect...\n");
			db_status = mongo_reconnect(globals.mongo_conn);

			if (db_status != MONGO_OK) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MongoDB reconnect failed with error code %d\n", db_status);
				status = SWITCH_STATUS_FALSE;
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "MongoDB connection re-established.\n");
				if (mongo_insert(globals.mongo_conn, globals.mongo_namespace, &cdr) != MONGO_OK) {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_insert: error code %d\n", globals.mongo_conn->err);
					status = SWITCH_STATUS_FALSE;
				}
			}

		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mongo_insert: error code %d\n", globals.mongo_conn->err);
			status = SWITCH_STATUS_FALSE;
		}
	}

	switch_mutex_unlock(globals.mongo_mutex);
	bson_destroy(&cdr);

	return status;
}