示例#1
0
/*! \brief Frame hook that is called to intercept hold/unhold */
static struct ast_frame *native_rtp_framehook(struct ast_channel *chan, struct ast_frame *f, enum ast_framehook_event event, void *data)
{
	RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
	struct native_rtp_bridge_data *native_data = data;

	if (!f || (event != AST_FRAMEHOOK_EVENT_WRITE)) {
		return f;
	}

	bridge = ast_channel_get_bridge(chan);

	if (bridge) {
		/* native_rtp_bridge_start/stop are not being called from bridging
		   core so we need to lock the bridge prior to calling these functions
		   Unfortunately that means unlocking the channel, but as it
		   should not be modified this should be okay... hopefully...
		   unless this channel is being moved around right now and is in
		   the process of having this framehook removed (which is fine). To
		   ensure we then don't stop or start when we shouldn't we consult
		   the data provided. If this framehook has been detached then the
		   detached variable will be set. This is safe to check as it is only
		   manipulated with the bridge lock held. */
		ast_channel_unlock(chan);
		ast_bridge_lock(bridge);
		if (!native_data->detached) {
			if (f->subclass.integer == AST_CONTROL_HOLD) {
				native_rtp_bridge_stop(bridge, chan);
			} else if ((f->subclass.integer == AST_CONTROL_UNHOLD) ||
				(f->subclass.integer == AST_CONTROL_UPDATE_RTP_PEER)) {
				native_rtp_bridge_start(bridge, chan);
			}
		}
		ast_bridge_unlock(bridge);
		ast_channel_lock(chan);

	}

	return f;
}
示例#2
0
static void native_rtp_bridge_leave(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
{
	native_rtp_bridge_framehook_detach(bridge_channel);
	native_rtp_bridge_stop(bridge, NULL);
}