int manager_endpoints_init(void) { struct stasis_topic *endpoint_topic; int ret = 0; if (endpoint_router) { /* Already initialized */ return 0; } ast_register_atexit(manager_endpoints_shutdown); endpoint_topic = ast_endpoint_topic_all_cached(); if (!endpoint_topic) { return -1; } endpoint_router = stasis_message_router_create(endpoint_topic); if (!endpoint_router) { return -1; } ret |= stasis_message_router_add(endpoint_router, ast_endpoint_state_type(), endpoint_state_cb, NULL); /* If somehow we failed to add any routes, just shut down the whole * thing and fail it. */ if (ret) { manager_endpoints_shutdown(); return -1; } return 0; }
/*! 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; }