[asterisk-commits] mmichelson: branch mmichelson/queue_bugbug r394456 - /team/mmichelson/queue_b...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jul 16 11:55:21 CDT 2013
Author: mmichelson
Date: Tue Jul 16 11:55:19 2013
New Revision: 394456
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394456
Log:
Add initial naive hangup detection for queue calls.
This will need some major adjustments once local optimization
is taken into account, but for simple calls, this currently
works fine.
Modified:
team/mmichelson/queue_bugbug/apps/app_queue.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=394456&r1=394455&r2=394456
==============================================================================
--- team/mmichelson/queue_bugbug/apps/app_queue.c (original)
+++ team/mmichelson/queue_bugbug/apps/app_queue.c Tue Jul 16 11:55:19 2013
@@ -111,6 +111,7 @@
#include "asterisk/stasis_message_router.h"
#include "asterisk/bridging.h"
#include "asterisk/stasis_bridging.h"
+#include "asterisk/core_local.h"
/* Define, to debug reference counts on queues, without debugging reference counts on queue members */
/* #define REF_DEBUG_ONLY_QUEUES */
@@ -1936,15 +1937,13 @@
static void queue_publish_multi_channel_blob(struct ast_channel *caller, struct ast_channel *agent,
struct stasis_message_type *type, struct ast_json *blob)
{
- struct ast_channel_snapshot *caller_snapshot;
- struct ast_channel_snapshot *agent_snapshot;
+ RAII_VAR(struct ast_channel_snapshot *, caller_snapshot, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_channel_snapshot *, agent_snapshot, NULL, ao2_cleanup);
caller_snapshot = ast_channel_snapshot_create(caller);
agent_snapshot = ast_channel_snapshot_create(agent);
if (!caller_snapshot || !agent_snapshot) {
- ast_free(caller_snapshot);
- ast_free(agent_snapshot);
return;
}
@@ -5275,6 +5274,7 @@
time_t starttime;
int caller_pos;
int callcompletedinsl;
+ int hangup_detected;
};
static void queue_stasis_data_destructor(void *obj)
@@ -5329,8 +5329,8 @@
}
} else if (ast_blind_transfer_type() == stasis_message_type(msg)) {
struct ast_bridge_blob *blind_blob = stasis_message_data(msg);
- struct ast_channel_snapshot *caller;
- struct ast_channel_snapshot *agent;
+ RAII_VAR(struct ast_channel_snapshot *, caller, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_channel_snapshot *, agent, NULL, ao2_cleanup);
if (ast_strlen_zero(queue_data->bridge_uniqueid) ||
strcmp(queue_data->bridge_uniqueid, blind_blob->bridge->uniqueid)) {
@@ -5366,15 +5366,71 @@
}
}
+static void queue_channel_cb(void *userdata, struct stasis_subscription *sub,
+ struct stasis_topic *topic, struct stasis_message *msg)
+{
+ struct queue_stasis_data *queue_data = userdata;
+
+ if (stasis_subscription_final_message(sub, msg)) {
+ ao2_cleanup(queue_data);
+ } else if (ast_channel_hangup_request_type() == stasis_message_type(msg)) {
+ struct ast_channel_blob *channel_blob = stasis_message_data(msg);
+ RAII_VAR(struct ast_channel_snapshot *, caller, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_channel_snapshot *, agent, NULL, ao2_cleanup);
+ enum agent_complete_reason reason;
+
+ ao2_lock(queue_data);
+ if (queue_data->hangup_detected) {
+ ao2_unlock(queue_data);
+ return;
+ }
+ queue_data->hangup_detected = 1;
+ ao2_unlock(queue_data);
+
+ if (!strcmp(channel_blob->snapshot->uniqueid, queue_data->caller_uniqueid)) {
+ reason = CALLER;
+ } else if (!strcmp(channel_blob->snapshot->uniqueid, queue_data->agent_uniqueid)) {
+ reason = AGENT;
+ } else {
+ ast_log(LOG_WARNING, "Unexpected hangup request event received for channel %s\n",
+ channel_blob->snapshot->uniqueid);
+ return;
+ }
+
+ caller = ast_channel_snapshot_get_latest(queue_data->caller_uniqueid);
+ agent = ast_channel_snapshot_get_latest(queue_data->agent_uniqueid);
+
+ ast_queue_log(queue_data->queue, caller->uniqueid, queue_data->member->membername,
+ reason == CALLER ? "COMPLETECALLER" : "COMPLETEAGENT", "%ld|%ld|%d",
+ (long) (queue_data->starttime - queue_data->holdstart),
+ (long) (time(NULL) - queue_data->starttime), queue_data->caller_pos);
+ ast_log(LOG_NOTICE, "Detected hangup request on channel %s\n", channel_blob->snapshot->name);
+ send_agent_complete(queue_data->queue, caller, agent, queue_data->member,
+ queue_data->holdstart, queue_data->starttime, reason);
+ }
+}
+
static int setup_stasis_subs(struct queue_ent *qe, struct ast_channel *peer, struct member *mem,
time_t holdstart, time_t starttime, int callcompletedinsl)
{
struct queue_stasis_data *queue_data = queue_stasis_data_alloc(qe, peer, mem, holdstart, starttime, callcompletedinsl);
+ RAII_VAR(struct ast_channel *, local_caller, ast_local_get_peer(qe->chan), ast_channel_cleanup);
if (!queue_data) {
return -1;
}
stasis_subscribe(ast_bridge_topic_all(), queue_bridge_cb, queue_data);
+ ao2_ref(queue_data, +1);
+ stasis_subscribe(ast_channel_topic(qe->chan), queue_channel_cb, queue_data);
+ ao2_ref(queue_data, +1);
+ stasis_subscribe(ast_channel_topic(peer), queue_channel_cb, queue_data);
+ if (local_caller) {
+ /* Local optimization events are published on the ;1 channel topic, so if applicable,
+ * we need to subscribe to that channel's topic
+ */
+ ao2_ref(queue_data, +1);
+ stasis_subscribe(ast_channel_topic(local_caller), queue_channel_cb, queue_data);
+ }
return 0;
}
More information about the asterisk-commits
mailing list