コード例 #1
0
ファイル: app.c プロジェクト: roramirez/asterisk
/*! 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;
}
コード例 #2
0
ファイル: app.c プロジェクト: roramirez/asterisk
/*! Forward a bridge's topics to an app */
static struct app_forwards *forwards_create_bridge(struct stasis_app *app,
	struct ast_bridge *bridge)
{
	struct app_forwards *forwards;

	if (!app) {
		return NULL;
	}

	forwards = forwards_create(app, bridge ? bridge->uniqueid : BRIDGE_ALL);
	if (!forwards) {
		return NULL;
	}

	forwards->forward_type = FORWARD_BRIDGE;
	forwards->topic_forward = stasis_forward_all(ast_bridge_topic(bridge), app->topic);

	if (!forwards->topic_forward && bridge) {
		forwards_unsubscribe(forwards);
		ao2_ref(forwards, -1);
		return NULL;
	}

	return forwards;
}
コード例 #3
0
ファイル: app.c プロジェクト: lyx2014/Asterisk
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)
{
	RAII_VAR(struct app_forwards *, forwards, NULL, ao2_cleanup);
	SCOPED_AO2LOCK(lock, app->forwards);

	forwards = ao2_find(app->forwards, id, OBJ_SEARCH_KEY | OBJ_NOLOCK);
	if (!forwards) {
		ast_debug(3, "App '%s' not subscribed to %s '%s'\n", app->name, kind, id);
		return -1;
	}
	forwards->interested--;

	ast_debug(3, "%s '%s': is %d interested in %s\n", kind, id, forwards->interested, app->name);
	if (forwards->interested == 0 || terminate) {
		/* No one is interested any more; unsubscribe */
		ast_debug(3, "%s '%s' unsubscribed from %s\n", kind, id, app->name);
		forwards_unsubscribe(forwards);
		ao2_find(app->forwards, forwards,
			OBJ_POINTER | OBJ_NOLOCK | OBJ_UNLINK |
			OBJ_NODATA);

		if (!strcmp(kind, "endpoint")) {
			messaging_app_unsubscribe_endpoint(app->name, id);
		}
	}

	return 0;
}
コード例 #4
0
ファイル: app.c プロジェクト: litnimax/asterisk
/*! Forward a bridge's topics to an app */
static struct app_forwards *forwards_create_bridge(struct stasis_app *app,
	struct ast_bridge *bridge)
{
	struct app_forwards *forwards;

	if (!app) {
		return NULL;
	}

	forwards = forwards_create(app, bridge ? bridge->uniqueid : BRIDGE_ALL);
	if (!forwards) {
		return NULL;
	}

	forwards->forward_type = FORWARD_BRIDGE;
	if (bridge) {
		forwards->topic_forward = stasis_forward_all(ast_bridge_topic(bridge),
			app->topic);
	}
	forwards->topic_cached_forward = stasis_forward_all(
		bridge ? ast_bridge_topic_cached(bridge) : ast_bridge_topic_all_cached(),
		app->topic);

	if ((!forwards->topic_forward && bridge) || !forwards->topic_cached_forward) {
		/* Half-subscribed is a bad thing */
		forwards_unsubscribe(forwards);
		ao2_ref(forwards, -1);
		return NULL;
	}

	return forwards;
}
コード例 #5
0
ファイル: app.c プロジェクト: litnimax/asterisk
/*! Forward a channel's topics to an app */
static struct app_forwards *forwards_create_channel(struct stasis_app *app,
	struct ast_channel *chan)
{
	struct app_forwards *forwards;

	if (!app) {
		return NULL;
	}

	forwards = forwards_create(app, chan ? ast_channel_uniqueid(chan) : CHANNEL_ALL);
	if (!forwards) {
		return NULL;
	}

	forwards->forward_type = FORWARD_CHANNEL;
	if (chan) {
		forwards->topic_forward = stasis_forward_all(ast_channel_topic(chan),
			app->topic);
	}
	forwards->topic_cached_forward = stasis_forward_all(
		chan ? ast_channel_topic_cached(chan) : ast_channel_topic_all_cached(),
		app->topic);

	if ((!forwards->topic_forward && chan) || !forwards->topic_cached_forward) {
		/* Half-subscribed is a bad thing */
		forwards_unsubscribe(forwards);
		ao2_ref(forwards, -1);
		return NULL;
	}

	return forwards;
}
コード例 #6
0
ファイル: app.c プロジェクト: roramirez/asterisk
static int unsubscribe(struct stasis_app *app, const char *kind, const char *id, int terminate)
{
	struct app_forwards *forwards;

	if (!id) {
		if (!strcmp(kind, "bridge")) {
			id = BRIDGE_ALL;
		} else if (!strcmp(kind, "channel")) {
			id = CHANNEL_ALL;
		} else if (!strcmp(kind, "endpoint")) {
			id = ENDPOINT_ALL;
		} else {
			ast_log(LOG_WARNING, "Unknown subscription kind '%s'\n", kind);
			return -1;
		}
	}

	ao2_lock(app->forwards);
	forwards = ao2_find(app->forwards, id, OBJ_SEARCH_KEY | OBJ_NOLOCK);
	if (!forwards) {
		ao2_unlock(app->forwards);
		ast_debug(3, "App '%s' not subscribed to %s '%s'\n", app->name, kind, id);
		return -1;
	}
	forwards->interested--;

	ast_debug(3, "%s '%s': is %d interested in %s\n", kind, id, forwards->interested, app->name);
	if (forwards->interested == 0 || terminate) {
		/* No one is interested any more; unsubscribe */
		ast_debug(3, "%s '%s' unsubscribed from %s\n", kind, id, app->name);
		forwards_unsubscribe(forwards);
		ao2_find(app->forwards, forwards,
			OBJ_POINTER | OBJ_NOLOCK | OBJ_UNLINK |
			OBJ_NODATA);

		if (!strcmp(kind, "endpoint")) {
			messaging_app_unsubscribe_endpoint(app->name, id);
		}
	}
	ao2_unlock(app->forwards);
	ao2_ref(forwards, -1);

	return 0;
}