[asterisk-commits] mmichelson: branch mmichelson/queue_bugbug r394532 - in /team/mmichelson/queu...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 16 18:09:12 CDT 2013


Author: mmichelson
Date: Tue Jul 16 18:09:10 2013
New Revision: 394532

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394532
Log:
Add a bunch of new information to local optimization.

In order for a queue to track appropriate channels, it has to be
aware of when a local channel optimizes away so that it can then
start tracking a different channel instead. Therefore local channel
optimization publications now include more information

* An ID, so that you can match up a start and end message
* A source channel, so you know what channel to start tracking instead
* An indicator of which local channel's bridge is the "winner"


Modified:
    team/mmichelson/queue_bugbug/apps/app_queue.c
    team/mmichelson/queue_bugbug/include/asterisk/core_unreal.h
    team/mmichelson/queue_bugbug/main/bridging.c
    team/mmichelson/queue_bugbug/main/core_local.c

Modified: team/mmichelson/queue_bugbug/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/apps/app_queue.c?view=diff&rev=394532&r1=394531&r2=394532
==============================================================================
--- team/mmichelson/queue_bugbug/apps/app_queue.c (original)
+++ team/mmichelson/queue_bugbug/apps/app_queue.c Tue Jul 16 18:09:10 2013
@@ -5141,6 +5141,15 @@
 			queue_agent_complete_type(), blob);
 }
 
+struct local_optimization {
+	AST_DECLARE_STRING_FIELDS(
+		AST_STRING_FIELD(dest_bridge_uniqueid);
+		AST_STRING_FIELD(replacement_chan_uniqueid);
+		AST_STRING_FIELD(orig_chan_uniqueid);
+	);
+	int in_progress;
+};
+
 struct queue_stasis_data {
 	AST_DECLARE_STRING_FIELDS(
 		AST_STRING_FIELD(caller_uniqueid);
@@ -5159,6 +5168,8 @@
 	struct stasis_subscription *caller_sub;
 	struct stasis_subscription *local_caller_sub;
 	struct stasis_subscription *agent_sub;
+	struct local_optimization caller_optimize;
+	struct local_optimization agent_optimize;
 };
 
 static void queue_stasis_data_destructor(void *obj)
@@ -5271,6 +5282,9 @@
 			return;
 		}
 
+		/* BUGBUG Once atxfer_features is merged, we need to also return when
+		 * atxfer_msg->dest == AST_ATTENDED_TRANSFER_THREEWAY
+		 */
 		if (atxfer_msg->result == AST_BRIDGE_TRANSFER_FAIL) {
 			return;
 		}
@@ -5291,6 +5305,11 @@
 	}
 }
 
+static void handle_local_optimization(struct queue_stasis_data *queue_data, struct stasis_message *msg)
+{
+	/* XXX STUB */
+}
+
 static void queue_channel_cb(void *userdata, struct stasis_subscription *sub,
 		struct stasis_topic *topic, struct stasis_message *msg)
 {
@@ -5301,6 +5320,11 @@
 	}
 
 	if (queue_data->dying) {
+		return;
+	}
+
+	if (ast_local_optimization_begin_type() == stasis_message_type(msg)) {
+		handle_local_optimization(queue_data, msg);
 		return;
 	}
 	

Modified: team/mmichelson/queue_bugbug/include/asterisk/core_unreal.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/include/asterisk/core_unreal.h?view=diff&rev=394532&r1=394531&r2=394532
==============================================================================
--- team/mmichelson/queue_bugbug/include/asterisk/core_unreal.h (original)
+++ team/mmichelson/queue_bugbug/include/asterisk/core_unreal.h Tue Jul 16 18:09:10 2013
@@ -45,6 +45,11 @@
 
 struct ast_unreal_pvt;
 
+enum ast_unreal_channel_indicator {
+	AST_UNREAL_OWNER,
+	AST_UNREAL_CHAN,
+};
+
 /*!
  * \brief Callbacks that can be provided by concrete implementations of the unreal
  * channel driver that will be called when events occur in the unreal layer
@@ -54,8 +59,14 @@
 	 * \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 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);
+	void (* const optimization_started)(struct ast_unreal_pvt *p, struct ast_channel *source,
+			enum ast_unreal_channel_indicator dest, unsigned int id);
 
 	/*!
 	 * \brief Called when an optimization attempt completed successfully
@@ -63,8 +74,10 @@
 	 * \param p The \ref ast_unreal_pvt object
 	 * \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);
+	void (* const optimization_finished)(struct ast_unreal_pvt *p, int success, unsigned int id);
 };
 
 /*!

Modified: team/mmichelson/queue_bugbug/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/main/bridging.c?view=diff&rev=394532&r1=394531&r2=394532
==============================================================================
--- team/mmichelson/queue_bugbug/main/bridging.c (original)
+++ team/mmichelson/queue_bugbug/main/bridging.c Tue Jul 16 18:09:10 2013
@@ -68,6 +68,8 @@
 static struct ao2_container *bridges;
 
 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
@@ -4907,22 +4909,26 @@
  */
 	other = ast_bridge_channel_peer(src_bridge_channel);
 	if (other && other->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
+		unsigned int 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);
+			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_move_do(dst_bridge, other, 1, 1)) {
 			ast_bridge_change_state(src_bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
 			res = -1;
-			if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
-				pvt->callbacks->optimization_finished(pvt);
-			}
+		}
+		if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
+			pvt->callbacks->optimization_finished(pvt, res == 1, id);
 		}
 	}
 	return res;
@@ -5000,6 +5006,7 @@
 		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:
@@ -5024,14 +5031,18 @@
 		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);
+		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_merge_do(merge.dest, merge.src, kick_me, ARRAY_LEN(kick_me), 1);
 	if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
-		pvt->callbacks->optimization_finished(pvt);
+		pvt->callbacks->optimization_finished(pvt, 1, id);
 	}
 
 	return -1;

Modified: team/mmichelson/queue_bugbug/main/core_local.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/main/core_local.c?view=diff&rev=394532&r1=394531&r2=394532
==============================================================================
--- team/mmichelson/queue_bugbug/main/core_local.c (original)
+++ team/mmichelson/queue_bugbug/main/core_local.c Tue Jul 16 18:09:10 2013
@@ -201,8 +201,9 @@
 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);
-static void local_optimization_finished_cb(struct ast_unreal_pvt *base);
+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 struct ast_manager_event_blob *local_message_to_ami(struct stasis_message *msg);
 
@@ -380,58 +381,96 @@
 	return res;
 }
 
-static void publish_local_optimization(struct local_pvt *p, int complete)
-{
-	RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
-	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+static struct ast_multi_channel_blob *local_channel_optimization_blob(struct local_pvt *p,
+		struct ast_json *json_object)
+{
+	struct ast_multi_channel_blob *payload;
 	RAII_VAR(struct ast_json *, blob, ast_json_null(), ast_json_unref);
 	RAII_VAR(struct ast_channel_snapshot *, local_one_snapshot, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_channel_snapshot *, local_two_snapshot, NULL, ao2_cleanup);
 
 	if (!blob) {
-		return;
+		return NULL;
 	}
 
 	local_one_snapshot = ast_channel_snapshot_create(p->base.owner);
 	if (!local_one_snapshot) {
-		return;
+		return NULL;
 	}
 
 	local_two_snapshot = ast_channel_snapshot_create(p->base.chan);
 	if (!local_two_snapshot) {
-		return;
+		return NULL;
 	}
 
 	payload = ast_multi_channel_blob_create(blob);
 	if (!payload) {
-		return;
+		return NULL;
 	}
 	ast_multi_channel_blob_add_channel(payload, "1", local_one_snapshot);
 	ast_multi_channel_blob_add_channel(payload, "2", local_two_snapshot);
 
-	msg = stasis_message_create(
-			complete ? ast_local_optimization_end_type() : ast_local_optimization_begin_type(),
-			payload);
+	return payload;
+}
+
+/*! \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)
+{
+	RAII_VAR(struct ast_json *, json_object, 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);
+
+	if (!json_object) {
+		return;
+	}
+
+	payload = local_channel_optimization_blob(p, json_object);
+
+	if (source) {
+		RAII_VAR(struct ast_channel_snapshot *, source_snapshot, NULL, ao2_cleanup);
+		source_snapshot = ast_channel_snapshot_create(source);
+		if (!source_snapshot) {
+			return;
+		}
+
+		ast_multi_channel_blob_add_channel(payload, "source", source_snapshot);
+	}
+
+	msg = stasis_message_create(ast_local_optimization_begin_type(), payload);
 	if (!msg) {
 		return;
 	}
 
 	stasis_publish(ast_channel_topic(p->base.owner), msg);
-
-}
-
-/*! \brief Callback for \ref ast_unreal_pvt_callbacks \ref optimization_started_cb */
-static void local_optimization_started_cb(struct ast_unreal_pvt *base)
-{
+}
+
+/*! \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)
+{
+	RAII_VAR(struct ast_json *, json_object, 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;
-	publish_local_optimization(p, 0);
-}
-
-/*! \brief Callback for \ref ast_unreal_pvt_callbacks \ref optimization_finished_cb */
-static void local_optimization_finished_cb(struct ast_unreal_pvt *base)
-{
-	struct local_pvt *p = (struct local_pvt *)base;
-	publish_local_optimization(p, 1);
+
+	json_object = ast_json_pack("{s: i, s: i}", "success", success, "id", id);
+
+	if (!json_object) {
+		return;
+	}
+
+	payload = local_channel_optimization_blob(p, json_object);
+
+	msg = stasis_message_create(ast_local_optimization_end_type(), payload);
+	if (!msg) {
+		return;
+	}
+
+	stasis_publish(ast_channel_topic(p->base.owner), msg);
 }
 
 static struct ast_manager_event_blob *local_message_to_ami(struct stasis_message *message)
@@ -458,9 +497,28 @@
 	}
 
 	if (stasis_message_type(message) == ast_local_optimization_begin_type()) {
+		struct ast_channel_snapshot *source_snapshot;
+		RAII_VAR(struct ast_str *, source_str, NULL, ast_free);
+		const char *dest_uniqueid;
+
+		source_snapshot = ast_multi_channel_blob_get_channel(obj, "source");
+		if (source_snapshot) {
+			source_str = ast_manager_build_channel_state_string_prefix(source_snapshot, "Source");
+		}
+
+		dest_uniqueid = ast_json_object_get(blob, "dest") == AST_UNREAL_OWNER ?
+				local_snapshot_one->uniqueid : local_snapshot_two->uniqueid;
+
 		event = "LocalOptimizationBegin";
+		if (source_str) {
+			ast_str_append(&event_buffer, 0, "%s", ast_str_buffer(source_str));
+		}
+		ast_str_append(&event_buffer, 0, "DestUniqueId: %s\r\n", dest_uniqueid);
+		ast_str_append(&event_buffer, 0, "Id: %u\r\n", (unsigned int) ast_json_integer_get(ast_json_object_get(blob, "id")));
 	} else if (stasis_message_type(message) == ast_local_optimization_end_type()) {
 		event = "LocalOptimizationEnd";
+		ast_str_append(&event_buffer, 0, "Success: %s\r\n", ast_json_integer_get(ast_json_object_get(blob, "success")) ? "Yes" : "No");
+		ast_str_append(&event_buffer, 0, "Id: %u\r\n", (unsigned int) ast_json_integer_get(ast_json_object_get(blob, "id")));
 	} else if (stasis_message_type(message) == ast_local_bridge_type()) {
 		event = "LocalBridge";
 		ast_str_append(&event_buffer, 0, "Context: %s\r\n", ast_json_string_get(ast_json_object_get(blob, "context")));




More information about the asterisk-commits mailing list