Exemplo n.º 1
0
static struct ast_multi_channel_blob *local_channel_optimization_blob(struct local_pvt *p,
		struct ast_json *json_object)
{
	struct ast_multi_channel_blob *payload;
	RAII_VAR(struct ast_channel_snapshot *, local_one_snapshot, NULL, ao2_cleanup);
	RAII_VAR(struct ast_channel_snapshot *, local_two_snapshot, NULL, ao2_cleanup);

	local_one_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(p->base.owner));
	if (!local_one_snapshot) {
		return NULL;
	}

	local_two_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(p->base.chan));
	if (!local_two_snapshot) {
		return NULL;
	}

	payload = ast_multi_channel_blob_create(json_object);
	if (!payload) {
		return NULL;
	}
	ast_multi_channel_blob_add_channel(payload, "1", local_one_snapshot);
	ast_multi_channel_blob_add_channel(payload, "2", local_two_snapshot);

	return payload;
}
Exemplo n.º 2
0
/*!
 * \internal
 * \brief Post the \ref ast_local_bridge_type \ref stasis message
 * \since 12.0.0
 *
 * \param p local_pvt to raise the local bridge message
 *
 * \return Nothing
 */
static void publish_local_bridge_message(struct local_pvt *p)
{
	RAII_VAR(struct ast_multi_channel_blob *, multi_blob, NULL, ao2_cleanup);
	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
	RAII_VAR(struct ast_channel_snapshot *, one_snapshot, NULL, ao2_cleanup);
	RAII_VAR(struct ast_channel_snapshot *, two_snapshot, NULL, ao2_cleanup);
	struct ast_channel *owner;
	struct ast_channel *chan;

	if (!ast_local_bridge_type()) {
		return;
	}

	ast_unreal_lock_all(&p->base, &chan, &owner);

	blob = ast_json_pack("{s: s, s: s, s: b}",
		"context", p->context,
		"exten", p->exten,
		"can_optimize", !ast_test_flag(&p->base, AST_UNREAL_NO_OPTIMIZATION));
	if (!blob) {
		goto end;
	}

	multi_blob = ast_multi_channel_blob_create(blob);
	if (!multi_blob) {
		goto end;
	}

	one_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(owner));
	if (!one_snapshot) {
		goto end;
	}

	two_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
	if (!two_snapshot) {
		goto end;
	}

	ast_multi_channel_blob_add_channel(multi_blob, "1", one_snapshot);
	ast_multi_channel_blob_add_channel(multi_blob, "2", two_snapshot);

	msg = stasis_message_create(ast_local_bridge_type(), multi_blob);
	if (!msg) {
		goto end;
	}

	stasis_publish(ast_channel_topic(owner), msg);

end:
	ast_channel_unlock(owner);
	ast_channel_unref(owner);

	ast_channel_unlock(chan);
	ast_channel_unref(chan);

	ao2_unlock(&p->base);
}
Exemplo n.º 3
0
static int send_call_pickup_stasis_message(struct ast_channel *picking_up, struct ast_channel_snapshot *chan, struct ast_channel_snapshot *target)
{
	RAII_VAR(struct ast_multi_channel_blob *, pickup_payload, NULL, ao2_cleanup);
	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);

	if (!(pickup_payload = ast_multi_channel_blob_create(ast_json_null()))) {
		return -1;
	}

	ast_multi_channel_blob_add_channel(pickup_payload, "channel", chan);
	ast_multi_channel_blob_add_channel(pickup_payload, "target", target);

	if (!(msg = stasis_message_create(ast_call_pickup_type(), pickup_payload))) {
		return -1;
	}

	stasis_publish(ast_channel_topic(picking_up), msg);
	return 0;
}
Exemplo n.º 4
0
/*! \internal
 * \brief Publish the chanspy message over Stasis-Core
 * \param spyer The channel doing the spying
 * \param spyee Who is being spied upon
 * \start start If non-zero, the spying is starting. Otherwise, the spyer is
 * finishing
 */
static void publish_chanspy_message(struct ast_channel *spyer,
									struct ast_channel *spyee,
									int start)
{
	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
	RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);

	if (!spyer) {
		ast_log(AST_LOG_WARNING, "Attempt to publish ChanSpy message for NULL spyer channel\n");
		return;
	}
	blob = ast_json_null();
	if (!blob) {
		return;
	}

	payload = ast_multi_channel_blob_create(blob);
	if (!payload) {
		return;
	}

	if (pack_channel_into_message(spyer, "spyer_channel", payload)) {
		return;
	}

	if (spyee) {
		if (pack_channel_into_message(spyee, "spyee_channel", payload)) {
			return;
		}
	}

	message = stasis_message_create(
			start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type(),
					payload);
	if (!message) {
		return;
	}
	stasis_publish(ast_channel_topic(spyer), message);
}
Exemplo n.º 5
0
/*! \internal
 * \brief Publish the chanspy message over Stasis-Core
 * \param snoop The snoop structure
 * \start start If non-zero, the spying is starting. Otherwise, the spyer is
 * finishing
 */
static void publish_chanspy_message(struct stasis_app_snoop *snoop, int start)
{
	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
	RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
	RAII_VAR(struct ast_channel_snapshot *, snoop_snapshot, NULL, ao2_cleanup);
	RAII_VAR(struct ast_channel_snapshot *, spyee_snapshot, NULL, ao2_cleanup);
	struct stasis_message_type *type = start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type();

	blob = ast_json_null();
	if (!blob || !type) {
		return;
	}

	payload = ast_multi_channel_blob_create(blob);
	if (!payload) {
		return;
	}

	snoop_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(snoop->chan));
	if (!snoop_snapshot) {
		return;
	}
	ast_multi_channel_blob_add_channel(payload, "spyer_channel", snoop_snapshot);

	spyee_snapshot = ast_channel_snapshot_get_latest(snoop->uniqueid);
	if (spyee_snapshot) {
		ast_multi_channel_blob_add_channel(payload, "spyee_channel", spyee_snapshot);
	}

	message = stasis_message_create(type, payload);
	if (!message) {
		return;
	}

	stasis_publish(ast_channel_topic(snoop->chan), message);
}
Exemplo n.º 6
0
void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_channel *peer,
	struct ast_channel *forwarded, const char *dialstring, const char *dialstatus,
	const char *forward)
{
	RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
	RAII_VAR(struct ast_channel_snapshot *, caller_snapshot, NULL, ao2_cleanup);
	RAII_VAR(struct ast_channel_snapshot *, peer_snapshot, NULL, ao2_cleanup);
	RAII_VAR(struct ast_channel_snapshot *, forwarded_snapshot, NULL, ao2_cleanup);

	ast_assert(peer != NULL);
	blob = ast_json_pack("{s: s, s: s, s: s}",
			     "dialstatus", S_OR(dialstatus, ""),
			     "forward", S_OR(forward, ""),
			     "dialstring", S_OR(dialstring, ""));
	if (!blob) {
		return;
	}
	payload = ast_multi_channel_blob_create(blob);
	if (!payload) {
		return;
	}

	if (caller) {
		ast_channel_lock(caller);
		caller_snapshot = ast_channel_snapshot_create(caller);
		ast_channel_unlock(caller);
		if (!caller_snapshot) {
			return;
		}
		ast_multi_channel_blob_add_channel(payload, "caller", caller_snapshot);
	}

	ast_channel_lock(peer);
	peer_snapshot = ast_channel_snapshot_create(peer);
	ast_channel_unlock(peer);
	if (!peer_snapshot) {
		return;
	}
	ast_multi_channel_blob_add_channel(payload, "peer", peer_snapshot);

	if (forwarded) {
		ast_channel_lock(forwarded);
		forwarded_snapshot = ast_channel_snapshot_create(forwarded);
		ast_channel_unlock(forwarded);
		if (!forwarded_snapshot) {
			return;
		}
		ast_multi_channel_blob_add_channel(payload, "forwarded", forwarded_snapshot);
	}

	msg = stasis_message_create(ast_channel_dial_type(), payload);
	if (!msg) {
		return;
	}

	if (forwarded) {
		struct stasis_subscription *subscription = stasis_subscribe(ast_channel_topic(peer), dummy_event_cb, NULL);

		stasis_publish(ast_channel_topic(peer), msg);
		stasis_unsubscribe_and_join(subscription);
	} else {
		publish_message_for_channel_topics(msg, caller);
	}
}