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; }
/*! * \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); }
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; }
/*! \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); }
/*! \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); }
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); } }