[asterisk-commits] file: branch file/bridge_unreal_optimizer r410469 - in /team/file/bridge_unre...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Mar 11 15:52:23 CDT 2014


Author: file
Date: Tue Mar 11 15:52:16 2014
New Revision: 410469

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=410469
Log:
Invoke the optimization callbacks when an optimization attempt occurs.

Modified:
    team/file/bridge_unreal_optimizer/bridges/bridge_unreal.c
    team/file/bridge_unreal_optimizer/include/asterisk/core_unreal.h
    team/file/bridge_unreal_optimizer/main/bridge.c
    team/file/bridge_unreal_optimizer/main/core_local.c

Modified: team/file/bridge_unreal_optimizer/bridges/bridge_unreal.c
URL: http://svnview.digium.com/svn/asterisk/team/file/bridge_unreal_optimizer/bridges/bridge_unreal.c?view=diff&rev=410469&r1=410468&r2=410469
==============================================================================
--- team/file/bridge_unreal_optimizer/bridges/bridge_unreal.c (original)
+++ team/file/bridge_unreal_optimizer/bridges/bridge_unreal.c Tue Mar 11 15:52:16 2014
@@ -90,6 +90,9 @@
 
 /*! \brief Taskprocessor which optimizes things */
 static struct ast_taskprocessor *taskprocessor;
+
+/*! \brief Integer which is incremented to produce a unique id for optimization attempts */
+static unsigned int optimization_id;
 
 /*! \brief Task structure which contains information for optimizing unreal bridges */
 struct optimize_task_data {
@@ -105,6 +108,8 @@
 	struct ast_channel *peer_owner;
 	/*! \brief Peer in the outbound channel bridge */
 	struct ast_channel *peer_chan;
+	/*! \brief Optional callback functions */
+	struct ast_unreal_pvt_callbacks *callbacks;
 };
 
 /*! \brief Destructor for optimize task data */
@@ -124,7 +129,8 @@
 static struct optimize_task_data *optimize_task_data_alloc(
 	struct ast_channel *owner, struct ast_channel *chan,
 	struct ast_bridge *bridge_owner, struct ast_bridge *bridge_chan,
-	struct ast_channel *peer_owner, struct ast_channel *peer_chan)
+	struct ast_channel *peer_owner, struct ast_channel *peer_chan,
+	struct ast_unreal_pvt_callbacks *callbacks)
 {
 	struct optimize_task_data *task_data = ao2_alloc(sizeof(*task_data),
 		optimize_task_data_destroy);
@@ -139,6 +145,7 @@
 	task_data->bridge_chan = ao2_bump(bridge_chan);
 	task_data->peer_owner = ast_channel_ref(peer_owner);
 	task_data->peer_chan = ast_channel_ref(peer_chan);
+	task_data->callbacks = callbacks;
 
 	return task_data;
 }
@@ -149,18 +156,44 @@
 	struct optimize_task_data *task_data = data;
 	enum ast_bridge_optimization optimization = ast_bridges_allow_optimization(task_data->bridge_chan,
 		task_data->bridge_owner);
+	unsigned int id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
+	struct ast_bridge *dst_bridge = NULL, *src_bridge = NULL;
+	struct ast_channel *chan = NULL, *swap = NULL;
+	int res = 0;
 
 	switch (optimization) {
 	case AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE:
-		ast_bridge_move(task_data->bridge_chan, task_data->bridge_owner, task_data->peer_owner,
-			task_data->chan, 1);
+		dst_bridge = task_data->bridge_chan;
+		src_bridge = task_data->bridge_owner;
+		chan = task_data->peer_owner;
+		swap = task_data->chan;
 		break;
 	case AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE:
-		ast_bridge_move(task_data->bridge_owner, task_data->bridge_chan, task_data->peer_chan,
-			task_data->owner, 1);
+		dst_bridge = task_data->bridge_owner;
+		src_bridge = task_data->bridge_chan;
+		chan = task_data->peer_chan;
+		swap = task_data->owner;
 		break;
 	default:
 		break;
+	}
+
+	/* If all required information is not present abort early */
+	if (!dst_bridge || !src_bridge || !chan || !swap) {
+		ao2_ref(task_data, -1);
+		return 0;
+	}
+
+	if (task_data->callbacks && task_data->callbacks->optimization_started) {
+		task_data->callbacks->optimization_started(task_data->owner, task_data->chan,
+			chan, (swap == task_data->owner) ? AST_UNREAL_OWNER : AST_UNREAL_CHAN, id);
+	}
+
+	res = ast_bridge_move(dst_bridge, src_bridge, chan, swap, 1);
+
+	if (task_data->callbacks && task_data->callbacks->optimization_finished) {
+		task_data->callbacks->optimization_finished(task_data->owner, task_data->chan,
+			!res ? 1 : 0, id);
 	}
 
 	ao2_ref(task_data, -1);
@@ -287,7 +320,7 @@
 	if (changed && pvt->bridge_owner && pvt->bridge_chan) {
 		struct optimize_task_data *task_data = optimize_task_data_alloc(pvt->owner,
 			pvt->chan, pvt->bridge_owner, pvt->bridge_chan, pvt->bridged_owner,
-			pvt->bridged_chan);
+			pvt->bridged_chan, pvt->callbacks);
 
 		ast_debug(1, "Queueing task to remove unreal channels between bridge '%s' and '%s'\n",
 			pvt->bridge_owner->uniqueid, pvt->bridge_chan->uniqueid);

Modified: team/file/bridge_unreal_optimizer/include/asterisk/core_unreal.h
URL: http://svnview.digium.com/svn/asterisk/team/file/bridge_unreal_optimizer/include/asterisk/core_unreal.h?view=diff&rev=410469&r1=410468&r2=410469
==============================================================================
--- team/file/bridge_unreal_optimizer/include/asterisk/core_unreal.h (original)
+++ team/file/bridge_unreal_optimizer/include/asterisk/core_unreal.h Tue Mar 11 15:52:16 2014
@@ -58,27 +58,28 @@
 struct ast_unreal_pvt_callbacks {
 	/*!
 	 * \brief Called when an optimization attempt has started
-	 * \note p is locked when this callback is called
-	 * \param p The \ref ast_unreal_pvt object
+	 * \param owner The owner channel
+	 * \param chan The outbound channel
 	 * \param source The channel that is optimizing into an unreal_pvt channel's bridge.
 	 * If NULL, the optimization is being accomplished via a bridge merge.
 	 * \param dest Indicator of which channel's bridge in the unreal_pvt will survive the
 	 * optimization
 	 * \param id Unique identifier for this optimization operation.
 	 */
-	void (* const optimization_started)(struct ast_unreal_pvt *p, struct ast_channel *source,
-			enum ast_unreal_channel_indicator dest, unsigned int id);
+	void (* const optimization_started)(struct ast_channel *owner, struct ast_channel *chan,
+		struct ast_channel *source, enum ast_unreal_channel_indicator dest, unsigned int id);
 
 	/*!
 	 * \brief Called when an optimization attempt completed successfully
-	 * \note p is locked when this callback is called
-	 * \param p The \ref ast_unreal_pvt object
+	 * \param owner The owner channel
+	 * \param chan The outbound channel
 	 * \param success Non-zero if the optimization succeeded, zero if the optimization
 	 * met with fatal and permanent error
 	 * \param id Unique identifier for this optimization. Same as the one from the optimization_started
 	 * call
 	 */
-	void (* const optimization_finished)(struct ast_unreal_pvt *p, int success, unsigned int id);
+	void (* const optimization_finished)(struct ast_channel *owner, struct ast_channel *chan,
+		int success, unsigned int id);
 };
 
 /*!

Modified: team/file/bridge_unreal_optimizer/main/bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/file/bridge_unreal_optimizer/main/bridge.c?view=diff&rev=410469&r1=410468&r2=410469
==============================================================================
--- team/file/bridge_unreal_optimizer/main/bridge.c (original)
+++ team/file/bridge_unreal_optimizer/main/bridge.c Tue Mar 11 15:52:16 2014
@@ -114,8 +114,6 @@
 
 static AST_RWLIST_HEAD_STATIC(bridge_technologies, ast_bridge_technology);
 
-static unsigned int optimization_id;
-
 /* Initial starting point for the bridge array of channels */
 #define BRIDGE_ARRAY_START 128
 
@@ -2323,107 +2321,6 @@
 
 /*!
  * \internal
- * \brief Lock the unreal channel stack for chan and prequalify it.
- * \since 12.0.0
- *
- * \param chan Unreal channel writing a frame into the channel driver.
- *
- * \note It is assumed that chan is already locked.
- *
- * \retval bridge on success with bridge and bridge_channel locked.
- * \retval NULL if cannot do optimization now.
- */
-static struct ast_bridge *optimize_lock_chan_stack(struct ast_channel *chan)
-{
-	struct ast_bridge *bridge;
-	struct ast_bridge_channel *bridge_channel;
-
-	if (!AST_LIST_EMPTY(ast_channel_readq(chan))) {
-		return NULL;
-	}
-	if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_EMULATE_DTMF)) {
-		return NULL;
-	}
-	if (ast_channel_has_audio_frame_or_monitor(chan)) {
-		/* Channel has an active monitor, audiohook, or framehook. */
-		return NULL;
-	}
-	bridge_channel = ast_channel_internal_bridge_channel(chan);
-	if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
-		return NULL;
-	}
-	bridge = bridge_channel->bridge;
-	if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_SIMPLE
-		|| bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
-		|| ast_bridge_trylock(bridge)) {
-		ast_bridge_channel_unlock(bridge_channel);
-		return NULL;
-	}
-	if (!bridge_channel_internal_allows_optimization(bridge_channel) ||
-			!bridge_allows_optimization(bridge)) {
-		ast_bridge_unlock(bridge);
-		ast_bridge_channel_unlock(bridge_channel);
-		return NULL;
-	}
-	return bridge;
-}
-
-/*!
- * \internal
- * \brief Lock the unreal channel stack for peer and prequalify it.
- * \since 12.0.0
- *
- * \param peer Other unreal channel in the pair.
- *
- * \retval bridge on success with bridge, bridge_channel, and peer locked.
- * \retval NULL if cannot do optimization now.
- */
-static struct ast_bridge *optimize_lock_peer_stack(struct ast_channel *peer)
-{
-	struct ast_bridge *bridge;
-	struct ast_bridge_channel *bridge_channel;
-
-	if (ast_channel_trylock(peer)) {
-		return NULL;
-	}
-	if (!AST_LIST_EMPTY(ast_channel_readq(peer))) {
-		ast_channel_unlock(peer);
-		return NULL;
-	}
-	if (ast_test_flag(ast_channel_flags(peer), AST_FLAG_EMULATE_DTMF)) {
-		ast_channel_unlock(peer);
-		return NULL;
-	}
-	if (ast_channel_has_audio_frame_or_monitor(peer)) {
-		/* Peer has an active monitor, audiohook, or framehook. */
-		ast_channel_unlock(peer);
-		return NULL;
-	}
-	bridge_channel = ast_channel_internal_bridge_channel(peer);
-	if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
-		ast_channel_unlock(peer);
-		return NULL;
-	}
-	bridge = bridge_channel->bridge;
-	if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_IDLE
-		|| bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
-		|| ast_bridge_trylock(bridge)) {
-		ast_bridge_channel_unlock(bridge_channel);
-		ast_channel_unlock(peer);
-		return NULL;
-	}
-	if (!bridge_allows_optimization(bridge) ||
-			!bridge_channel_internal_allows_optimization(bridge_channel)) {
-		ast_bridge_unlock(bridge);
-		ast_bridge_channel_unlock(bridge_channel);
-		ast_channel_unlock(peer);
-		return NULL;
-	}
-	return bridge;
-}
-
-/*!
- * \internal
  * \brief Indicates allowability of a swap optimization
  */
 enum bridge_allow_swap {
@@ -2485,84 +2382,6 @@
 
 /*!
  * \internal
- * \brief Check and attempt to swap optimize out the unreal channels.
- * \since 12.0.0
- *
- * \param chan_bridge
- * \param chan_bridge_channel
- * \param peer_bridge
- * \param peer_bridge_channel
- * \param pvt Unreal data containing callbacks to call if the optimization actually
- * happens
- *
- * \retval 1 if unreal channels failed to optimize out.
- * \retval 0 if unreal channels were not optimized out.
- * \retval -1 if unreal channels were optimized out.
- */
-static int try_swap_optimize_out(struct ast_bridge *chan_bridge,
-	struct ast_bridge_channel *chan_bridge_channel, struct ast_bridge *peer_bridge,
-	struct ast_bridge_channel *peer_bridge_channel,
-	struct ast_unreal_pvt *pvt)
-{
-	struct ast_bridge *dst_bridge;
-	struct ast_bridge_channel *dst_bridge_channel;
-	struct ast_bridge_channel *src_bridge_channel;
-	struct ast_bridge_channel *other;
-	int res = 1;
-
-	switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
-	case SWAP_TO_CHAN_BRIDGE:
-		dst_bridge = chan_bridge;
-		dst_bridge_channel = chan_bridge_channel;
-		src_bridge_channel = peer_bridge_channel;
-		break;
-	case SWAP_TO_PEER_BRIDGE:
-		dst_bridge = peer_bridge;
-		dst_bridge_channel = peer_bridge_channel;
-		src_bridge_channel = chan_bridge_channel;
-		break;
-	case SWAP_PROHIBITED:
-	default:
-		return 0;
-	}
-
-	other = ast_bridge_channel_peer(src_bridge_channel);
-	if (other && other->state == BRIDGE_CHANNEL_STATE_WAIT) {
-		unsigned int id;
-
-		if (ast_channel_trylock(other->chan)) {
-			return 1;
-		}
-
-		id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
-
-		ast_verb(3, "Move-swap optimizing %s <-- %s.\n",
-			ast_channel_name(dst_bridge_channel->chan),
-			ast_channel_name(other->chan));
-
-		if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
-				&& pvt->callbacks->optimization_started) {
-			pvt->callbacks->optimization_started(pvt, other->chan,
-					dst_bridge_channel->chan == pvt->owner ? AST_UNREAL_OWNER : AST_UNREAL_CHAN,
-					id);
-			ast_set_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN);
-		}
-		other->swap = dst_bridge_channel->chan;
-		if (!bridge_do_move(dst_bridge, other, 1, 1)) {
-			ast_bridge_channel_leave_bridge(src_bridge_channel,
-				BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, AST_CAUSE_NORMAL_CLEARING);
-			res = -1;
-		}
-		if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
-			pvt->callbacks->optimization_finished(pvt, res == 1, id);
-		}
-		ast_channel_unlock(other->chan);
-	}
-	return res;
-}
-
-/*!
- * \internal
  * \brief Indicates allowability of a merge optimization
  */
 enum bridge_allow_merge {
@@ -2606,112 +2425,6 @@
 	}
 
 	return MERGE_ALLOWED;
-}
-
-/*!
- * \internal
- * \brief Check and attempt to merge optimize out the unreal channels.
- * \since 12.0.0
- *
- * \param chan_bridge
- * \param chan_bridge_channel
- * \param peer_bridge
- * \param peer_bridge_channel
- * \param pvt Unreal data containing callbacks to call if the optimization actually
- * happens
- *
- * \retval 0 if unreal channels were not optimized out.
- * \retval -1 if unreal channels were optimized out.
- */
-static int try_merge_optimize_out(struct ast_bridge *chan_bridge,
-	struct ast_bridge_channel *chan_bridge_channel, struct ast_bridge *peer_bridge,
-	struct ast_bridge_channel *peer_bridge_channel,
-	struct ast_unreal_pvt *pvt)
-{
-	struct merge_direction merge;
-	struct ast_bridge_channel *kick_me[] = {
-		chan_bridge_channel,
-		peer_bridge_channel,
-	};
-	unsigned int id;
-
-	switch (bridges_allow_merge_optimization(chan_bridge, peer_bridge, ARRAY_LEN(kick_me), &merge)) {
-	case MERGE_ALLOWED:
-		break;
-	case MERGE_PROHIBITED:
-		return 0;
-	case MERGE_NOT_ENOUGH_CHANNELS:
-		ast_debug(4, "Can't optimize %s -- %s out, not enough channels in bridge %s.\n",
-			ast_channel_name(chan_bridge_channel->chan),
-			ast_channel_name(peer_bridge_channel->chan),
-			merge.src->uniqueid);
-		return 0;
-	case MERGE_NO_MULTIMIX:
-		ast_debug(4, "Can't optimize %s -- %s out, multimix is needed and it cannot be acquired.\n",
-			ast_channel_name(chan_bridge_channel->chan),
-			ast_channel_name(peer_bridge_channel->chan));
-		return 0;
-	}
-
-	ast_verb(3, "Merge optimizing %s -- %s out.\n",
-		ast_channel_name(chan_bridge_channel->chan),
-		ast_channel_name(peer_bridge_channel->chan));
-
-	id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
-
-	if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
-			&& pvt->callbacks->optimization_started) {
-		pvt->callbacks->optimization_started(pvt, NULL,
-				merge.dest == ast_channel_internal_bridge(pvt->owner) ? AST_UNREAL_OWNER : AST_UNREAL_CHAN,
-				id);
-		ast_set_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN);
-	}
-	bridge_do_merge(merge.dest, merge.src, kick_me, ARRAY_LEN(kick_me), 1);
-	if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
-		pvt->callbacks->optimization_finished(pvt, 1, id);
-	}
-
-	return -1;
-}
-
-int ast_bridge_unreal_optimize_out(struct ast_channel *chan, struct ast_channel *peer, struct ast_unreal_pvt *pvt)
-{
-	struct ast_bridge *chan_bridge;
-	struct ast_bridge *peer_bridge;
-	struct ast_bridge_channel *chan_bridge_channel;
-	struct ast_bridge_channel *peer_bridge_channel;
-	int res = 0;
-
-	chan_bridge = optimize_lock_chan_stack(chan);
-	if (!chan_bridge) {
-		return res;
-	}
-	chan_bridge_channel = ast_channel_internal_bridge_channel(chan);
-
-	peer_bridge = optimize_lock_peer_stack(peer);
-	if (peer_bridge) {
-		peer_bridge_channel = ast_channel_internal_bridge_channel(peer);
-
-		res = try_swap_optimize_out(chan_bridge, chan_bridge_channel,
-			peer_bridge, peer_bridge_channel, pvt);
-		if (!res) {
-			res = try_merge_optimize_out(chan_bridge, chan_bridge_channel,
-				peer_bridge, peer_bridge_channel, pvt);
-		} else if (0 < res) {
-			res = 0;
-		}
-
-		/* Release peer locks. */
-		ast_bridge_unlock(peer_bridge);
-		ast_bridge_channel_unlock(peer_bridge_channel);
-		ast_channel_unlock(peer);
-	}
-
-	/* Release chan locks. */
-	ast_bridge_unlock(chan_bridge);
-	ast_bridge_channel_unlock(chan_bridge_channel);
-
-	return res;
 }
 
 enum ast_bridge_optimization ast_bridges_allow_optimization(struct ast_bridge *chan_bridge,

Modified: team/file/bridge_unreal_optimizer/main/core_local.c
URL: http://svnview.digium.com/svn/asterisk/team/file/bridge_unreal_optimizer/main/core_local.c?view=diff&rev=410469&r1=410468&r2=410469
==============================================================================
--- team/file/bridge_unreal_optimizer/main/core_local.c (original)
+++ team/file/bridge_unreal_optimizer/main/core_local.c Tue Mar 11 15:52:16 2014
@@ -141,9 +141,10 @@
 static int local_call(struct ast_channel *ast, const char *dest, int timeout);
 static int local_hangup(struct ast_channel *ast);
 static int local_devicestate(const char *data);
-static void local_optimization_started_cb(struct ast_unreal_pvt *base, struct ast_channel *source,
-		enum ast_unreal_channel_indicator dest, unsigned int id);
-static void local_optimization_finished_cb(struct ast_unreal_pvt *base, int success, unsigned int id);
+static void local_optimization_started_cb(struct ast_channel *owner, struct ast_channel *chan,
+	struct ast_channel *source,	enum ast_unreal_channel_indicator dest, unsigned int id);
+static void local_optimization_finished_cb(struct ast_channel *owner, struct ast_channel *chan,
+	int success, unsigned int id);
 
 static struct ast_manager_event_blob *local_message_to_ami(struct stasis_message *msg);
 
@@ -321,19 +322,19 @@
 	return res;
 }
 
-static struct ast_multi_channel_blob *local_channel_optimization_blob(struct local_pvt *p,
-		struct ast_json *json_object)
+static struct ast_multi_channel_blob *local_channel_optimization_blob(
+	struct ast_channel *owner, struct ast_channel *chan, struct ast_json *json_object)
 {
 	struct ast_multi_channel_blob *payload;
 	RAII_VAR(struct ast_channel_snapshot *, local_one_snapshot, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_channel_snapshot *, local_two_snapshot, NULL, ao2_cleanup);
 
-	local_one_snapshot = ast_channel_snapshot_create(p->base.owner);
+	local_one_snapshot = ast_channel_snapshot_create(owner);
 	if (!local_one_snapshot) {
 		return NULL;
 	}
 
-	local_two_snapshot = ast_channel_snapshot_create(p->base.chan);
+	local_two_snapshot = ast_channel_snapshot_create(chan);
 	if (!local_two_snapshot) {
 		return NULL;
 	}
@@ -349,13 +350,12 @@
 }
 
 /*! \brief Callback for \ref ast_unreal_pvt_callbacks \ref optimization_started_cb */
-static void local_optimization_started_cb(struct ast_unreal_pvt *base, struct ast_channel *source,
-		enum ast_unreal_channel_indicator dest, unsigned int id)
+static void local_optimization_started_cb(struct ast_channel *owner, struct ast_channel *chan,
+	struct ast_channel *source, enum ast_unreal_channel_indicator dest, unsigned int id)
 {
 	RAII_VAR(struct ast_json *, json_object, ast_json_null(), ast_json_unref);
 	RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
-	struct local_pvt *p = (struct local_pvt *)base;
 
 	json_object = ast_json_pack("{s: i, s: i}",
 			"dest", dest, "id", id);
@@ -364,7 +364,7 @@
 		return;
 	}
 
-	payload = local_channel_optimization_blob(p, json_object);
+	payload = local_channel_optimization_blob(owner, chan, json_object);
 	if (!payload) {
 		return;
 	}
@@ -384,16 +384,16 @@
 		return;
 	}
 
-	stasis_publish(ast_channel_topic(p->base.owner), msg);
+	stasis_publish(ast_channel_topic(owner), msg);
 }
 
 /*! \brief Callback for \ref ast_unreal_pvt_callbacks \ref optimization_finished_cb */
-static void local_optimization_finished_cb(struct ast_unreal_pvt *base, int success, unsigned int id)
+static void local_optimization_finished_cb(struct ast_channel *owner, struct ast_channel *chan,
+	int success, unsigned int id)
 {
 	RAII_VAR(struct ast_json *, json_object, ast_json_null(), ast_json_unref);
 	RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
-	struct local_pvt *p = (struct local_pvt *)base;
 
 	json_object = ast_json_pack("{s: i, s: i}", "success", success, "id", id);
 
@@ -401,7 +401,7 @@
 		return;
 	}
 
-	payload = local_channel_optimization_blob(p, json_object);
+	payload = local_channel_optimization_blob(owner, chan, json_object);
 	if (!payload) {
 		return;
 	}
@@ -411,7 +411,7 @@
 		return;
 	}
 
-	stasis_publish(ast_channel_topic(p->base.owner), msg);
+	stasis_publish(ast_channel_topic(owner), msg);
 }
 
 static struct ast_manager_event_blob *local_message_to_ami(struct stasis_message *message)




More information about the asterisk-commits mailing list