static void consumer_exec(void *data, struct stasis_subscription *sub, struct stasis_message *message) { struct consumer *consumer = data; struct stasis_cache_update *cache_update = stasis_message_data(message); struct ast_device_state_message *device_state; if (!cache_update->new_snapshot) { return; } device_state = stasis_message_data(cache_update->new_snapshot); if (strcmp(device_state->device, UNIT_TEST_DEVICE_IDENTIFIER)) { /* not a device state we're interested in */ return; } { SCOPED_AO2LOCK(lock, consumer); ++consumer->event_count; if (device_state->eid) { consumer->state = device_state->state; if (consumer->sig_on_non_aggregate_state) { consumer->sig_on_non_aggregate_state = 0; consumer->already_out = 1; ast_cond_signal(&consumer->out); } } else { consumer->aggregate_state = device_state->state; consumer->already_out = 1; ast_cond_signal(&consumer->out); } } }
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); } }
static void confbridge_publish_manager_event( struct stasis_message *message, const char *event, struct ast_str *extra_text) { struct ast_bridge_blob *blob = stasis_message_data(message); const char *conference_name; RAII_VAR(struct ast_str *, bridge_text, NULL, ast_free); RAII_VAR(struct ast_str *, channel_text, NULL, ast_free); ast_assert(blob != NULL); ast_assert(event != NULL); bridge_text = ast_manager_build_bridge_state_string(blob->bridge); if (!bridge_text) { return; } conference_name = ast_json_string_get(ast_json_object_get(blob->blob, "conference")); ast_assert(conference_name != NULL); if (blob->channel) { channel_text = ast_manager_build_channel_state_string(blob->channel); } manager_event(EVENT_FLAG_CALL, event, "Conference: %s\r\n" "%s" "%s" "%s", conference_name, ast_str_buffer(bridge_text), S_COR(channel_text, ast_str_buffer(channel_text), ""), S_COR(extra_text, ast_str_buffer(extra_text), "")); }
static struct ast_manager_event_blob *system_registry_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); const char *channeltype; const char *username; const char *domain; const char *status; const char *cause; RAII_VAR(struct ast_str *, cause_string, ast_str_create(32), ast_free); if (!cause_string) { return NULL; } channeltype = ast_json_string_get(ast_json_object_get(payload->json, "channeltype")); username = ast_json_string_get(ast_json_object_get(payload->json, "username")); domain = ast_json_string_get(ast_json_object_get(payload->json, "domain")); status = ast_json_string_get(ast_json_object_get(payload->json, "status")); cause = ast_json_string_get(ast_json_object_get(payload->json, "cause")); if (!ast_strlen_zero(cause)) { ast_str_set(&cause_string, 0, "Cause: %s\r\n", cause); } return ast_manager_event_blob_create(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: %s\r\n" "Username: %s\r\n" "Domain: %s\r\n" "Status: %s\r\n" "%s", channeltype, username, domain, status, ast_str_buffer(cause_string)); }
static void cache_update_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) { struct stasis_cache_update *update = stasis_message_data(message); struct ast_endpoint_snapshot *old_snapshot; struct ast_endpoint_snapshot *new_snapshot; if (ast_endpoint_snapshot_type() != update->type) { return; } old_snapshot = stasis_message_data(update->old_snapshot); new_snapshot = stasis_message_data(update->new_snapshot); handle_endpoint_update(old_snapshot, new_snapshot); }
static void parking_event_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) { if (stasis_message_type(message) == ast_parked_call_type()) { struct ast_parked_call_payload *parked_call_message = stasis_message_data(message); parked_call_message_response(parked_call_message); } }
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); }
static void channel_enter_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) { static const char *swap_name = "SwapUniqueid: "; struct ast_bridge_blob *blob = stasis_message_data(message); RAII_VAR(struct ast_str *, bridge_text, NULL, ast_free); RAII_VAR(struct ast_str *, channel_text, NULL, ast_free); const char *swap_id; bridge_text = ast_manager_build_bridge_state_string(blob->bridge); channel_text = ast_manager_build_channel_state_string(blob->channel); if (!bridge_text || !channel_text) { return; } swap_id = ast_json_string_get(ast_json_object_get(blob->blob, "swap")); manager_event(EVENT_FLAG_CALL, "BridgeEnter", "%s" "%s" "%s%s%s", ast_str_buffer(bridge_text), ast_str_buffer(channel_text), swap_id ? swap_name : "", S_OR(swap_id, ""), swap_id ? "\r\n" : ""); }
static struct ast_manager_event_blob *call_pickup_to_ami(struct stasis_message *message) { struct ast_multi_channel_blob *contents = stasis_message_data(message); struct ast_channel_snapshot *chan; struct ast_channel_snapshot *target; struct ast_manager_event_blob *res; RAII_VAR(struct ast_str *, channel_str, NULL, ast_free); RAII_VAR(struct ast_str *, target_str, NULL, ast_free); chan = ast_multi_channel_blob_get_channel(contents, "channel"); target = ast_multi_channel_blob_get_channel(contents, "target"); ast_assert(chan != NULL && target != NULL); if (!(channel_str = ast_manager_build_channel_state_string(chan))) { return NULL; } if (!(target_str = ast_manager_build_channel_state_string_prefix(target, "Target"))) { return NULL; } res = ast_manager_event_blob_create(EVENT_FLAG_CALL, "Pickup", "%s" "%s", ast_str_buffer(channel_str), ast_str_buffer(target_str)); return res; }
void ast_ari_channels_get(struct ast_variable *headers, struct ast_ari_channels_get_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); struct stasis_cache *cache; struct ast_channel_snapshot *snapshot; cache = ast_channel_cache(); if (!cache) { ast_ari_response_error( response, 500, "Internal Server Error", "Message bus not initialized"); return; } msg = stasis_cache_get(cache, ast_channel_snapshot_type(), args->channel_id); if (!msg) { ast_ari_response_error( response, 404, "Not Found", "Channel not found"); return; } snapshot = stasis_message_data(msg); ast_assert(snapshot != NULL); ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL)); }
static int find_route( struct stasis_message_router *router, struct stasis_message *message, struct stasis_message_route *route_out) { struct stasis_message_route *route = NULL; struct stasis_message_type *type = stasis_message_type(message); SCOPED_AO2LOCK(lock, router); ast_assert(route_out != NULL); if (type == stasis_cache_update_type()) { /* Find a cache route */ struct stasis_cache_update *update = stasis_message_data(message); route = route_table_find(&router->cache_routes, update->type); } if (route == NULL) { /* Find a regular route */ route = route_table_find(&router->routes, type); } if (route == NULL && router->default_route.callback) { /* Maybe the default route, then? */ route = &router->default_route; } if (!route) { return -1; } *route_out = *route; return 0; }
int stasis_topic_wait(struct stasis_topic *topic) { RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); RAII_VAR(struct stasis_subscription *, sub, NULL, stasis_unsubscribe); struct caching_guarantee *guarantee; msg = caching_guarantee_create(); if (!msg) { return -1; } sub = stasis_subscribe(topic, guarantee_handler, msg); if (!sub) { return -1; } guarantee = stasis_message_data(msg); ast_mutex_lock(&guarantee->lock); stasis_publish(topic, msg); while (!guarantee->done) { ast_cond_wait(&guarantee->cond, &guarantee->lock); } ast_mutex_unlock(&guarantee->lock); return 0; }
static void mwi_update_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) { struct ast_mwi_state *mwi_state; RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free); if (ast_mwi_state_type() != stasis_message_type(message)) { return; } mwi_state = stasis_message_data(message); if (!mwi_state) { return; } if (mwi_state->snapshot) { channel_event_string = ast_manager_build_channel_state_string(mwi_state->snapshot); } /*** DOCUMENTATION <managerEventInstance> <synopsis>Raised when the state of messages in a voicemail mailbox has changed or when a channel has finished interacting with a mailbox.</synopsis> <syntax> <channel_snapshot/> <parameter name="Mailbox"> <para>The mailbox with the new message, specified as <literal>mailbox</literal>@<literal>context</literal></para> </parameter> <parameter name="Waiting"> <para>Whether or not the mailbox has messages waiting for it.</para> </parameter> <parameter name="New"> <para>The number of new messages.</para> </parameter> <parameter name="Old"> <para>The number of old messages.</para> </parameter> </syntax> <description> <note><para>The Channel related parameters are only present if a channel was involved in the manipulation of a mailbox. If no channel is involved, the parameters are not included with the event.</para> </note> </description> </managerEventInstance> ***/ manager_event(EVENT_FLAG_CALL, "MessageWaiting", "%s" "Mailbox: %s\r\n" "Waiting: %d\r\n" "New: %d\r\n" "Old: %d\r\n", AS_OR(channel_event_string, ""), mwi_state->uniqueid, ast_app_has_voicemail(mwi_state->uniqueid, NULL), mwi_state->new_msgs, mwi_state->old_msgs); }
static struct ast_manager_event_blob *varset_to_ami(struct stasis_message *msg) { RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free); struct ast_channel_blob *obj = stasis_message_data(msg); const char *variable = ast_json_string_get(ast_json_object_get(obj->blob, "variable")); const char *value = ast_json_string_get(ast_json_object_get(obj->blob, "value")); if (obj->snapshot) { channel_event_string = ast_manager_build_channel_state_string(obj->snapshot); } else { channel_event_string = ast_str_create(35); ast_str_set(&channel_event_string, 0, "Channel: none\r\n" "Uniqueid: none\r\n"); } if (!channel_event_string) { return NULL; } return ast_manager_event_blob_create(EVENT_FLAG_DIALPLAN, "VarSet", "%s" "Variable: %s\r\n" "Value: %s\r\n", ast_str_buffer(channel_event_string), variable, value); }
struct ast_endpoint_snapshot *ast_endpoint_latest_snapshot(const char *tech, const char *name) { RAII_VAR(char *, id, NULL, ast_free); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); struct ast_endpoint_snapshot *snapshot; if (ast_strlen_zero(name)) { ast_asprintf(&id, "%s", tech); } else { ast_asprintf(&id, "%s/%s", tech, name); } if (!id) { return NULL; } ast_tech_to_upper(id); msg = stasis_cache_get(ast_endpoint_cache(), ast_endpoint_snapshot_type(), id); if (!msg) { return NULL; } snapshot = stasis_message_data(msg); ast_assert(snapshot != NULL); ao2_ref(snapshot, +1); return snapshot; }
static int filter_bridge_type_cb(void *obj, void *arg, int flags) { char *bridge_type = arg; struct ast_bridge_snapshot *snapshot = stasis_message_data(obj); /* unlink all the snapshots that do not match the bridge type */ return strcmp(bridge_type, snapshot->technology) ? CMP_MATCH : 0; }
static struct ast_manager_event_blob *contactstatus_to_ami(struct stasis_message *msg) { struct ast_endpoint_blob *obj = stasis_message_data(msg); RAII_VAR(struct ast_str *, contactstatus_event_string, ast_str_create(64), ast_free); const char *value; if (!(value = ast_json_string_get(ast_json_object_get(obj->blob, "uri")))) { return NULL; } ast_str_append(&contactstatus_event_string, 0, "URI: %s\r\n", value); if (!(value = ast_json_string_get(ast_json_object_get(obj->blob, "contact_status")))) { return NULL; } ast_str_append(&contactstatus_event_string, 0, "ContactStatus: %s\r\n", value); if (!(value = ast_json_string_get(ast_json_object_get(obj->blob, "aor")))) { return NULL; } ast_str_append(&contactstatus_event_string, 0, "AOR: %s\r\n", value); if (!(value = ast_json_string_get(ast_json_object_get(obj->blob, "endpoint_name")))) { return NULL; } ast_str_append(&contactstatus_event_string, 0, "EndpointName: %s\r\n", value); if ((value = ast_json_string_get(ast_json_object_get(obj->blob, "roundtrip_usec")))) { ast_str_append(&contactstatus_event_string, 0, "RoundtripUsec: %s\r\n", value); } return ast_manager_event_blob_create(EVENT_FLAG_SYSTEM, "ContactStatus", "%s", ast_str_buffer(contactstatus_event_string)); }
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; }
static struct ast_manager_event_blob *peerstatus_to_ami(struct stasis_message *msg) { struct ast_endpoint_blob *obj = stasis_message_data(msg); RAII_VAR(struct ast_str *, peerstatus_event_string, ast_str_create(64), ast_free); const char *value; /* peer_status is the only *required* thing */ if (!(value = ast_json_string_get(ast_json_object_get(obj->blob, "peer_status")))) { return NULL; } ast_str_append(&peerstatus_event_string, 0, "PeerStatus: %s\r\n", value); if ((value = ast_json_string_get(ast_json_object_get(obj->blob, "cause")))) { ast_str_append(&peerstatus_event_string, 0, "Cause: %s\r\n", value); } if ((value = ast_json_string_get(ast_json_object_get(obj->blob, "address")))) { ast_str_append(&peerstatus_event_string, 0, "Address: %s\r\n", value); } if ((value = ast_json_string_get(ast_json_object_get(obj->blob, "port")))) { ast_str_append(&peerstatus_event_string, 0, "Port: %s\r\n", value); } if ((value = ast_json_string_get(ast_json_object_get(obj->blob, "time")))) { ast_str_append(&peerstatus_event_string, 0, "Time: %s\r\n", value); } return ast_manager_event_blob_create(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: %s\r\n" "Peer: %s/%s\r\n" "%s", obj->snapshot->tech, obj->snapshot->tech, obj->snapshot->resource, ast_str_buffer(peerstatus_event_string)); }
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; }
static int send_bridge_info_item_cb(void *obj, void *arg, void *data, int flags) { char *uniqueid = obj; struct mansession *s = arg; char *id_text = data; RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); struct ast_channel_snapshot *snapshot; RAII_VAR(struct ast_str *, channel_text, NULL, ast_free); msg = stasis_cache_get(ast_channel_cache(), ast_channel_snapshot_type(), uniqueid); if (!msg) { return 0; } snapshot = stasis_message_data(msg); if (snapshot->tech_properties & AST_CHAN_TP_INTERNAL) { return 0; } channel_text = ast_manager_build_channel_state_string(snapshot); if (!channel_text) { return 0; } astman_append(s, "Event: BridgeInfoChannel\r\n" "%s" "%s" "\r\n", ast_str_buffer(channel_text), id_text); return 0; }
static void appcdr_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message) { struct app_cdr_message_payload *payload; if (stasis_message_type(message) != appcdr_message_type()) { return; } payload = stasis_message_data(message); if (!payload) { return; } if (payload->disable) { if (ast_cdr_set_property(payload->channel_name, AST_CDR_FLAG_DISABLE_ALL)) { ast_log(AST_LOG_WARNING, "Failed to disable CDRs on channel %s\n", payload->channel_name); } } if (payload->reenable) { if (ast_cdr_clear_property(payload->channel_name, AST_CDR_FLAG_DISABLE_ALL)) { ast_log(AST_LOG_WARNING, "Failed to enable CDRs on channel %s\n", payload->channel_name); } } if (payload->reset) { if (ast_cdr_reset(payload->channel_name, payload->keep_variables)) { ast_log(AST_LOG_WARNING, "Failed to reset CDRs on channel %s\n", payload->channel_name); } } }
/*! \brief Generic MWI event callback used for one-off events from voicemail modules */ static void mwi_app_event_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) { struct ast_mwi_blob *payload = stasis_message_data(message); RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free); RAII_VAR(struct ast_str *, event_buffer, NULL, ast_free); struct ast_json *event_json = ast_json_object_get(payload->blob, "Event"); if (!event_json) { return; } if (payload->mwi_state && payload->mwi_state->snapshot) { channel_event_string = ast_manager_build_channel_state_string(payload->mwi_state->snapshot); } event_buffer = ast_manager_str_from_json_object(payload->blob, exclude_event_cb); if (!event_buffer) { ast_log(AST_LOG_WARNING, "Failed to create payload for event %s\n", ast_json_string_get(event_json)); return; } manager_event(EVENT_FLAG_CALL, ast_json_string_get(event_json), "Mailbox: %s\r\n" "%s" "%s", payload->mwi_state ? payload->mwi_state->uniqueid : "Unknown", ast_str_buffer(event_buffer), channel_event_string ? ast_str_buffer(channel_event_string) : ""); }
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); } }
static void bridge_merge_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message) { struct ast_bridge_merge_message *merge_msg = stasis_message_data(message); RAII_VAR(struct ast_str *, to_text, NULL, ast_free); RAII_VAR(struct ast_str *, from_text, NULL, ast_free); ast_assert(merge_msg->to != NULL); ast_assert(merge_msg->from != NULL); to_text = ast_manager_build_bridge_state_string_prefix(merge_msg->to, "To"); from_text = ast_manager_build_bridge_state_string_prefix(merge_msg->from, "From"); if (!to_text || !from_text) { return; } /*** DOCUMENTATION <managerEventInstance> <synopsis>Raised when two bridges are merged.</synopsis> <syntax> <bridge_snapshot prefix="To"/> <bridge_snapshot prefix="From"/> </syntax> </managerEventInstance> ***/ manager_event(EVENT_FLAG_CALL, "BridgeMerge", "%s" "%s", ast_str_buffer(to_text), ast_str_buffer(from_text)); }
static void caching_topic_exec(void *data, struct stasis_subscription *sub, struct stasis_message *message) { RAII_VAR(struct stasis_caching_topic *, caching_topic_needs_unref, NULL, ao2_cleanup); struct stasis_caching_topic *caching_topic = data; const char *id = NULL; ast_assert(caching_topic != NULL); ast_assert(caching_topic->topic != NULL); ast_assert(caching_topic->cache != NULL); ast_assert(caching_topic->cache->id_fn != NULL); if (stasis_subscription_final_message(sub, message)) { caching_topic_needs_unref = caching_topic; } /* Handle cache clear event */ if (stasis_cache_clear_type() == stasis_message_type(message)) { RAII_VAR(struct stasis_message *, old_snapshot, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, update, NULL, ao2_cleanup); struct stasis_message *clear_msg = stasis_message_data(message); const char *clear_id = caching_topic->cache->id_fn(clear_msg); struct stasis_message_type *clear_type = stasis_message_type(clear_msg); ast_assert(clear_type != NULL); if (clear_id) { old_snapshot = cache_put(caching_topic->cache, clear_type, clear_id, NULL); if (old_snapshot) { update = update_create(old_snapshot, NULL); stasis_publish(caching_topic->topic, update); return; } ast_log(LOG_ERROR, "Attempting to remove an item from the %s cache that isn't there: %s %s\n", stasis_topic_name(caching_topic->topic), stasis_message_type_name(clear_type), clear_id); return; } } id = caching_topic->cache->id_fn(message); if (id == NULL) { /* Object isn't cached; discard */ } else { /* Update the cache */ RAII_VAR(struct stasis_message *, old_snapshot, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, update, NULL, ao2_cleanup); old_snapshot = cache_put(caching_topic->cache, stasis_message_type(message), id, message); update = update_create(old_snapshot, message); if (update == NULL) { return; } stasis_publish(caching_topic->topic, update); } }
static int dump_cache_load(void *obj, void *arg, int flags) { struct stasis_message *msg = obj; struct ast_endpoint_snapshot *snapshot = stasis_message_data(msg); handle_endpoint_update(NULL, snapshot); return 0; }
static const char *channel_snapshot_get_name(struct stasis_message *message) { struct ast_channel_snapshot *snapshot; if (ast_channel_snapshot_type() != stasis_message_type(message)) { return NULL; } snapshot = stasis_message_data(message); return snapshot->name; }
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); } }
void ast_ari_channels_list(struct ast_variable *headers, struct ast_ari_channels_list_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup); RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); struct ao2_iterator i; void *obj; struct stasis_message_sanitizer *sanitize = stasis_app_get_sanitizer(); cache = ast_channel_cache(); if (!cache) { ast_ari_response_error( response, 500, "Internal Server Error", "Message bus not initialized"); return; } ao2_ref(cache, +1); snapshots = stasis_cache_dump(cache, ast_channel_snapshot_type()); if (!snapshots) { ast_ari_response_alloc_failed(response); return; } json = ast_json_array_create(); if (!json) { ast_ari_response_alloc_failed(response); return; } for (i = ao2_iterator_init(snapshots, 0); (obj = ao2_iterator_next(&i)); ao2_cleanup(obj)) { RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup); struct ast_channel_snapshot *snapshot = stasis_message_data(msg); int r; if (sanitize && sanitize->channel_snapshot && sanitize->channel_snapshot(snapshot)) { continue; } r = ast_json_array_append( json, ast_channel_snapshot_to_json(snapshot, NULL)); if (r != 0) { ast_ari_response_alloc_failed(response); ao2_cleanup(obj); ao2_iterator_destroy(&i); return; } } ao2_iterator_destroy(&i); ast_ari_response_ok(response, ast_json_ref(json)); }