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; }
static int load_module(void) { struct ao2_container *endpoints; router = stasis_message_router_create(ast_endpoint_topic_all_cached()); if (!router) { return AST_MODULE_LOAD_FAILURE; } stasis_message_router_add(router, stasis_cache_update_type(), cache_update_cb, NULL); endpoints = stasis_cache_dump(ast_endpoint_cache(), ast_endpoint_snapshot_type()); if (endpoints) { ao2_callback(endpoints, OBJ_MULTIPLE | OBJ_NODATA | OBJ_NOLOCK, dump_cache_load, NULL); ao2_ref(endpoints, -1); } return AST_MODULE_LOAD_SUCCESS; }