Пример #1
0
static struct ast_json *peerstatus_to_json(struct stasis_message *msg, const struct stasis_message_sanitizer *sanitize)
{
	struct ast_endpoint_blob *obj = stasis_message_data(msg);
	struct ast_json *json_endpoint;
	struct ast_json *json_peer;
	struct ast_json *json_final;
	const struct timeval *tv = stasis_message_timestamp(msg);

	json_endpoint = ast_endpoint_snapshot_to_json(obj->snapshot, NULL);
	if (!json_endpoint) {
		return NULL;
	}

	json_peer = ast_json_object_create();
	if (!json_peer) {
		ast_json_unref(json_endpoint);
		return NULL;
	}

	/* Copy all fields from the blob */
	ast_json_object_update(json_peer, obj->blob);

	json_final = ast_json_pack("{s: s, s: o, s: o, s: o }",
		"type", "PeerStatusChange",
		"timestamp", ast_json_timeval(*tv, NULL),
		"endpoint", json_endpoint,
		"peer", json_peer);
	if (!json_final) {
		ast_json_unref(json_endpoint);
		ast_json_unref(json_peer);
	}

	return json_final;
}
Пример #2
0
static void sub_bridge_update_handler(void *data,
	struct stasis_subscription *sub,
	struct stasis_message *message)
{
	struct ast_json *json = NULL;
	struct stasis_app *app = data;
	struct ast_bridge_snapshot_update *update;
	const struct timeval *tv;

	update = stasis_message_data(message);

	tv = stasis_message_timestamp(message);

	if (!update->new_snapshot) {
		json = simple_bridge_event("BridgeDestroyed", update->old_snapshot, tv);
	} else if (!update->old_snapshot) {
		json = simple_bridge_event("BridgeCreated", update->new_snapshot, tv);
	} else if (update->new_snapshot && update->old_snapshot
		&& strcmp(update->new_snapshot->video_source_id, update->old_snapshot->video_source_id)) {
		json = simple_bridge_event("BridgeVideoSourceChanged", update->new_snapshot, tv);
		if (json && !ast_strlen_zero(update->old_snapshot->video_source_id)) {
			ast_json_object_set(json, "old_video_source_id",
				ast_json_string_create(update->old_snapshot->video_source_id));
		}
	}

	if (json) {
		app_send(app, json);
		ast_json_unref(json);
	}

	if (!update->new_snapshot && update->old_snapshot) {
		unsubscribe(app, "bridge", update->old_snapshot->uniqueid, 1);
	}
}
Пример #3
0
static struct ast_json *contactstatus_to_json(struct stasis_message *msg, const struct stasis_message_sanitizer *sanitize)
{
	struct ast_endpoint_blob *obj = stasis_message_data(msg);
	struct ast_json *json_endpoint;
	struct ast_json *json_final;
	const struct timeval *tv = stasis_message_timestamp(msg);

	json_endpoint = ast_endpoint_snapshot_to_json(obj->snapshot, NULL);
	if (!json_endpoint) {
		return NULL;
	}

	json_final = ast_json_pack("{s: s, s: o, s: o, s: { s: s, s: s, s: s, s: s } } ",
		"type", "ContactStatusChange",
		"timestamp", ast_json_timeval(*tv, NULL),
		"endpoint", json_endpoint,
		"contact_info",
		"uri", ast_json_string_get(ast_json_object_get(obj->blob, "uri")),
		"contact_status", ast_json_string_get(ast_json_object_get(obj->blob, "contact_status")),
		"aor", ast_json_string_get(ast_json_object_get(obj->blob, "aor")),
		"roundtrip_usec", ast_json_string_get(ast_json_object_get(obj->blob, "roundtrip_usec")));
	if (!json_final) {
		ast_json_unref(json_endpoint);
	}

	return json_final;
}
Пример #4
0
static struct ast_json *dtmf_end_to_json(
	struct stasis_message *message,
	const struct stasis_message_sanitizer *sanitize)
{
	struct ast_channel_blob *channel_blob = stasis_message_data(message);
	struct ast_json *blob = channel_blob->blob;
	struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
	const char *direction =
		ast_json_string_get(ast_json_object_get(blob, "direction"));
	const struct timeval *tv = stasis_message_timestamp(message);
	struct ast_json *json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);

	/* Only present received DTMF end events as JSON */
	if (strcasecmp("Received", direction) != 0) {
		return NULL;
	}

	if (!json_channel) {
		return NULL;
	}

	return ast_json_pack("{s: s, s: o, s: O, s: O, s: o}",
		"type", "ChannelDtmfReceived",
		"timestamp", ast_json_timeval(*tv, NULL),
		"digit", ast_json_object_get(blob, "digit"),
		"duration_ms", ast_json_object_get(blob, "duration_ms"),
		"channel", json_channel);
}
Пример #5
0
static void sub_endpoint_update_handler(void *data,
	struct stasis_subscription *sub,
	struct stasis_message *message)
{
	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
	struct stasis_app *app = data;
	struct stasis_cache_update *update;
	struct ast_endpoint_snapshot *new_snapshot;
	struct ast_endpoint_snapshot *old_snapshot;
	const struct timeval *tv;

	ast_assert(stasis_message_type(message) == stasis_cache_update_type());

	update = stasis_message_data(message);

	ast_assert(update->type == ast_endpoint_snapshot_type());

	new_snapshot = stasis_message_data(update->new_snapshot);
	old_snapshot = stasis_message_data(update->old_snapshot);

	if (new_snapshot) {
		tv = stasis_message_timestamp(update->new_snapshot);

		json = simple_endpoint_event("EndpointStateChange", new_snapshot, tv);
		if (!json) {
			return;
		}

		app_send(app, json);
	}

	if (!new_snapshot && old_snapshot) {
		unsubscribe(app, "endpoint", old_snapshot->id, 1);
	}
}
Пример #6
0
static void sub_bridge_update_handler(void *data,
	struct stasis_subscription *sub,
	struct stasis_message *message)
{
	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
	struct stasis_app *app = data;
	struct stasis_cache_update *update;
	struct ast_bridge_snapshot *new_snapshot;
	struct ast_bridge_snapshot *old_snapshot;
	const struct timeval *tv;

	ast_assert(stasis_message_type(message) == stasis_cache_update_type());

	update = stasis_message_data(message);

	ast_assert(update->type == ast_bridge_snapshot_type());

	new_snapshot = stasis_message_data(update->new_snapshot);
	old_snapshot = stasis_message_data(update->old_snapshot);
	tv = update->new_snapshot ?
		stasis_message_timestamp(update->new_snapshot) :
		stasis_message_timestamp(message);

	if (!new_snapshot) {
		json = simple_bridge_event("BridgeDestroyed", old_snapshot, tv);
	} else if (!old_snapshot) {
		json = simple_bridge_event("BridgeCreated", new_snapshot, tv);
	} else if (new_snapshot && old_snapshot
		&& strcmp(new_snapshot->video_source_id, old_snapshot->video_source_id)) {
		json = simple_bridge_event("BridgeVideoSourceChanged", new_snapshot, tv);
		if (json && !ast_strlen_zero(old_snapshot->video_source_id)) {
			ast_json_object_set(json, "old_video_source_id",
				ast_json_string_create(old_snapshot->video_source_id));
		}
	}

	if (json) {
		app_send(app, json);
	}

	if (!new_snapshot && old_snapshot) {
		unsubscribe(app, "bridge", old_snapshot->uniqueid, 1);
	}
}
Пример #7
0
static void sub_channel_update_handler(void *data,
	struct stasis_subscription *sub,
	struct stasis_message *message)
{
	struct stasis_app *app = data;
	struct stasis_cache_update *update;
	struct ast_channel_snapshot *new_snapshot;
	struct ast_channel_snapshot *old_snapshot;
	const struct timeval *tv;
	int i;

	ast_assert(stasis_message_type(message) == stasis_cache_update_type());

	update = stasis_message_data(message);

	ast_assert(update->type == ast_channel_snapshot_type());

	new_snapshot = stasis_message_data(update->new_snapshot);
	old_snapshot = stasis_message_data(update->old_snapshot);

	/* Pull timestamp from the new snapshot, or from the update message
	 * when there isn't one. */
	tv = update->new_snapshot ?
		stasis_message_timestamp(update->new_snapshot) :
		stasis_message_timestamp(message);

	for (i = 0; i < ARRAY_LEN(channel_monitors); ++i) {
		RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref);

		msg = channel_monitors[i](old_snapshot, new_snapshot, tv);
		if (msg) {
			app_send(app, msg);
		}
	}

	if (!new_snapshot && old_snapshot) {
		unsubscribe(app, "channel", old_snapshot->uniqueid, 1);
	}
}
Пример #8
0
/*! \internal \brief convert multi object blob to ari json */
static struct ast_json *multi_user_event_to_json(
	struct stasis_message *message,
	const struct stasis_message_sanitizer *sanitize)
{
	RAII_VAR(struct ast_json *, out, NULL, ast_json_unref);
	struct ast_multi_object_blob *multi = stasis_message_data(message);
	struct ast_json *blob = multi->blob;
	const struct timeval *tv = stasis_message_timestamp(message);
	enum stasis_user_multi_object_snapshot_type type;
	int i;

	out = ast_json_object_create();
	if (!out) {
		return NULL;
	}

	ast_json_object_set(out, "type", ast_json_string_create("ChannelUserevent"));
	ast_json_object_set(out, "timestamp", ast_json_timeval(*tv, NULL));
	ast_json_object_set(out, "eventname", ast_json_string_create(ast_json_string_get((ast_json_object_get(blob, "eventname")))));
	ast_json_object_set(out, "userevent", ast_json_deep_copy(blob));

	for (type = 0; type < STASIS_UMOS_MAX; ++type) {
		for (i = 0; i < AST_VECTOR_SIZE(&multi->snapshots[type]); ++i) {
			struct ast_json *json_object = NULL;
			char *name = NULL;
			void *snapshot = AST_VECTOR_GET(&multi->snapshots[type], i);

			switch (type) {
			case STASIS_UMOS_CHANNEL:
				json_object = ast_channel_snapshot_to_json(snapshot, sanitize);
				name = "channel";
				break;
			case STASIS_UMOS_BRIDGE:
				json_object = ast_bridge_snapshot_to_json(snapshot, sanitize);
				name = "bridge";
				break;
			case STASIS_UMOS_ENDPOINT:
				json_object = ast_endpoint_snapshot_to_json(snapshot, sanitize);
				name = "endpoint";
				break;
			}
			if (json_object) {
				ast_json_object_set(out, name, json_object);
			}
		}
	}
	return ast_json_ref(out);
}
Пример #9
0
static struct ast_json *channel_blob_to_json(
	struct stasis_message *message,
	const char *type,
	const struct stasis_message_sanitizer *sanitize)
{
	RAII_VAR(struct ast_json *, out, NULL, ast_json_unref);
	struct ast_channel_blob *channel_blob = stasis_message_data(message);
	struct ast_json *blob = channel_blob->blob;
	struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
	const struct timeval *tv = stasis_message_timestamp(message);
	int res = 0;

	if (blob == NULL || ast_json_is_null(blob)) {
		out = ast_json_object_create();
	} else {
		/* blobs are immutable, so shallow copies are fine */
		out = ast_json_copy(blob);
	}

	if (!out) {
		return NULL;
	}

	res |= ast_json_object_set(out, "type", ast_json_string_create(type));
	res |= ast_json_object_set(out, "timestamp",
		ast_json_timeval(*tv, NULL));

	/* For global channel messages, the snapshot is optional */
	if (snapshot) {
		struct ast_json *json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);

		if (!json_channel) {
			return NULL;
		}

		res |= ast_json_object_set(out, "channel", json_channel);
	}

	if (res != 0) {
		return NULL;
	}

	return ast_json_ref(out);
}
Пример #10
0
static struct ast_json *dial_to_json(
	struct stasis_message *message,
	const struct stasis_message_sanitizer *sanitize)
{
	struct ast_multi_channel_blob *payload = stasis_message_data(message);
	struct ast_json *blob = ast_multi_channel_blob_get_json(payload);
	struct ast_json *caller_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "caller"), sanitize);
	struct ast_json *peer_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "peer"), sanitize);
	struct ast_json *forwarded_json = ast_channel_snapshot_to_json(ast_multi_channel_blob_get_channel(payload, "forwarded"), sanitize);
	struct ast_json *json;
	const struct timeval *tv = stasis_message_timestamp(message);
	int res = 0;

	json = ast_json_pack("{s: s, s: o, s: O, s: O, s: O}",
		"type", "Dial",
		"timestamp", ast_json_timeval(*tv, NULL),
		"dialstatus", ast_json_object_get(blob, "dialstatus"),
		"forward", ast_json_object_get(blob, "forward"),
		"dialstring", ast_json_object_get(blob, "dialstring"));
	if (!json) {
		ast_json_unref(caller_json);
		ast_json_unref(peer_json);
		ast_json_unref(forwarded_json);
		return NULL;
	}

	if (caller_json) {
		res |= ast_json_object_set(json, "caller", caller_json);
	}
	if (peer_json) {
		res |= ast_json_object_set(json, "peer", peer_json);
	}
	if (forwarded_json) {
		res |= ast_json_object_set(json, "forwarded", forwarded_json);
	}

	if (res) {
		ast_json_unref(json);
		return NULL;
	}

	return json;
}
Пример #11
0
static struct ast_json *user_event_to_json(
	struct stasis_message *message,
	const struct stasis_message_sanitizer *sanitize)
{
	struct ast_channel_blob *channel_blob = stasis_message_data(message);
	struct ast_json *blob = channel_blob->blob;
	struct ast_channel_snapshot *snapshot = channel_blob->snapshot;
	const struct timeval *tv = stasis_message_timestamp(message);
	struct ast_json *json_channel = ast_channel_snapshot_to_json(snapshot, sanitize);

	if (!json_channel) {
		return NULL;
	}

	return ast_json_pack("{s: s, s: o, s: O, s: O, s: o}",
		"type", "ChannelUserevent",
		"timestamp", ast_json_timeval(*tv, NULL),
		"eventname", ast_json_object_get(blob, "eventname"),
		"userevent", blob,
		"channel", json_channel);
}
Пример #12
0
/*!
 * \brief Router callback for \ref stasis_cache_update messages.
 * \param data Data pointer given when added to router.
 * \param sub This subscription.
 * \param topic The topic the message was posted to. This is not necessarily the
 *              topic you subscribed to, since messages may be forwarded between
 *              topics.
 * \param message The message itself.
 */
static void updates(void *data, struct stasis_subscription *sub,
	struct stasis_message *message)
{
	/* Since this came from a message router, we know the type of the
	 * message. We can cast the data without checking its type.
	 */
	struct stasis_cache_update *update = stasis_message_data(message);

	/* We're only interested in channel snapshots, so check the type
	 * of the underlying message.
	 */
	if (ast_channel_snapshot_type() != update->type) {
		return;
	}

	/* There are three types of cache updates.
	 * !old && new -> Initial cache entry
	 * old && new -> Updated cache entry
	 * old && !new -> Cache entry removed.
	 */

	if (!update->old_snapshot && update->new_snapshot) {
		/* Initial cache entry; count a channel creation */
		ast_statsd_log("channels.count", AST_STATSD_COUNTER, 1);
	} else if (update->old_snapshot && !update->new_snapshot) {
		/* Cache entry removed. Compute the age of the channel and post
		 * that, as well as decrementing the channel count.
		 */
		struct ast_channel_snapshot *last;
		int64_t age;

		last = stasis_message_data(update->old_snapshot);
		age = ast_tvdiff_ms(*stasis_message_timestamp(message),
			last->creationtime);
		ast_statsd_log("channels.calltime", AST_STATSD_TIMER, age);

		/* And decrement the channel count */
		ast_statsd_log("channels.count", AST_STATSD_COUNTER, -1);
	}
}
Пример #13
0
static void sub_channel_update_handler(void *data,
	struct stasis_subscription *sub,
	struct stasis_message *message)
{
	struct stasis_app *app = data;
	struct ast_channel_snapshot_update *update = stasis_message_data(message);
	int i;

	for (i = 0; i < ARRAY_LEN(channel_monitors); ++i) {
		struct ast_json *msg;

		msg = channel_monitors[i](update->old_snapshot, update->new_snapshot,
			stasis_message_timestamp(message));
		if (msg) {
			app_send(app, msg);
			ast_json_unref(msg);
		}
	}

	if (ast_test_flag(&update->new_snapshot->flags, AST_FLAG_DEAD)) {
		unsubscribe(app, "channel", update->new_snapshot->base->uniqueid, 1);
	}
}