/*! Forward a endpoint's topics to an app */ static struct app_forwards *forwards_create_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint) { RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup); if (!app || !endpoint) { return NULL; } forwards = forwards_create(app, ast_endpoint_get_id(endpoint)); if (!forwards) { return NULL; } forwards->forward_type = FORWARD_ENDPOINT; forwards->topic_forward = stasis_forward_all(ast_endpoint_topic(endpoint), app->topic); if (!forwards->topic_forward) { return NULL; } forwards->topic_cached_forward = stasis_forward_all( ast_endpoint_topic_cached(endpoint), app->topic); if (!forwards->topic_cached_forward) { /* Half-subscribed is a bad thing */ stasis_forward_cancel(forwards->topic_forward); forwards->topic_forward = NULL; return NULL; } ao2_ref(forwards, +1); return forwards; }
/*! Forward a endpoint's topics to an app */ static struct app_forwards *forwards_create_endpoint(struct stasis_app *app, struct ast_endpoint *endpoint) { struct app_forwards *forwards; int ret = 0; if (!app) { return NULL; } forwards = forwards_create(app, endpoint ? ast_endpoint_get_id(endpoint) : ENDPOINT_ALL); if (!forwards) { return NULL; } forwards->forward_type = FORWARD_ENDPOINT; if (endpoint) { forwards->topic_forward = stasis_forward_all(ast_endpoint_topic(endpoint), app->topic); forwards->topic_cached_forward = stasis_forward_all( ast_endpoint_topic_cached(endpoint), app->topic); if (!forwards->topic_forward || !forwards->topic_cached_forward) { /* Half-subscribed is a bad thing */ forwards_unsubscribe(forwards); ao2_ref(forwards, -1); return NULL; } } else { /* Since endpoint subscriptions also subscribe to channels, in the case * of all endpoint subscriptions, we only want messages for the endpoints. * As such, we route those particular messages and then re-publish them * on the app's topic. */ ast_assert(app->endpoint_router == NULL); app->endpoint_router = stasis_message_router_create(ast_endpoint_topic_all_cached()); if (!app->endpoint_router) { forwards_unsubscribe(forwards); ao2_ref(forwards, -1); return NULL; } ret |= stasis_message_router_add(app->endpoint_router, ast_endpoint_state_type(), endpoint_state_cb, app); ret |= stasis_message_router_add(app->endpoint_router, ast_endpoint_contact_state_type(), endpoint_state_cb, app); if (ret) { ao2_ref(app->endpoint_router, -1); app->endpoint_router = NULL; ao2_ref(forwards, -1); return NULL; } } return forwards; }
void ast_endpoint_blob_publish(struct ast_endpoint *endpoint, struct stasis_message_type *type, struct ast_json *blob) { RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); if (blob) { message = ast_endpoint_blob_create(endpoint, type, blob); } if (message) { stasis_publish(ast_endpoint_topic(endpoint), message); } }
int ast_channel_forward_endpoint(struct ast_channel *chan, struct ast_endpoint *endpoint) { ast_assert(chan != NULL); ast_assert(endpoint != NULL); chan->endpoint_forward = stasis_forward_all(ast_channel_topic(chan), ast_endpoint_topic(endpoint)); if (chan->endpoint_forward == NULL) { return -1; } return 0; }