[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