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;
}
Exemple #2
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;
}