TALK_DETECT: A channel function that raises events when talking is detected

This patch adds a new channel function TALK_DETECT that, when set on a
channel, causes events indicating the start/stop of talking on a channel to be
emitted to both AMI and ARI clients. 

The function allows setting both the silence threshold (the length of silence
after which we decide no one is talking) as well as the talking threshold (the
amount of energy that counts as talking). Parameters can be updated on a channel
after talk detection has been enabled, and talk detection can be removed at
any time.

The events raised by the function use a nomenclature similar to existing AMI/ARI
events.
For AMI: ChannelTalkingStart/ChannelTalkingStop
For ARI: ChannelTalkingStarted/ChannelTalkingFinished

Review: https://reviewboard.asterisk.org/r/3563/

ASTERISK-23786 #close
Reported by: Matt Jordan



git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@414934 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Matthew Jordan
2014-05-30 12:39:36 +00:00
parent 1ff5e67a88
commit d0d19b1b90
8 changed files with 796 additions and 4 deletions

View File

@@ -85,6 +85,34 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
</see-also>
</managerEventInstance>
</managerEvent>
<managerEvent language="en_US" name="ChannelTalkingStart">
<managerEventInstance class="EVENT_FLAG_CLASS">
<synopsis>Raised when talking is detected on a channel.</synopsis>
<syntax>
<channel_snapshot/>
</syntax>
<see-also>
<ref type="function">TALK_DETECT</ref>
<ref type="managerEvent">ChannelTalkingStop</ref>
</see-also>
</managerEventInstance>
</managerEvent>
<managerEvent language="en_US" name="ChannelTalkingStop">
<managerEventInstance class="EVENT_FLAG_CLASS">
<synopsis>Raised when talking is no longer detected on a channel.</synopsis>
<syntax>
<channel_snapshot/>
<parameter name="Duration">
<para>The length in time, in milliseconds, that talking was
detected on the channel.</para>
</parameter>
</syntax>
<see-also>
<ref type="function">TALK_DETECT</ref>
<ref type="managerEvent">ChannelTalkingStart</ref>
</see-also>
</managerEventInstance>
</managerEvent>
***/
#define NUM_MULTI_CHANNEL_BLOB_BUCKETS 7
@@ -974,6 +1002,58 @@ static struct ast_json *dial_to_json(
return json;
}
static struct ast_manager_event_blob *talking_start_to_ami(struct stasis_message *msg)
{
struct ast_str *channel_string;
struct ast_channel_blob *obj = stasis_message_data(msg);
struct ast_manager_event_blob *blob;
channel_string = ast_manager_build_channel_state_string(obj->snapshot);
if (!channel_string) {
return NULL;
}
blob = ast_manager_event_blob_create(EVENT_FLAG_CALL, "ChannelTalkingStart",
"%s", ast_str_buffer(channel_string));
ast_free(channel_string);
return blob;
}
static struct ast_json *talking_start_to_json(struct stasis_message *message,
const struct stasis_message_sanitizer *sanitize)
{
return channel_blob_to_json(message, "ChannelTalkingStarted", sanitize);
}
static struct ast_manager_event_blob *talking_stop_to_ami(struct stasis_message *msg)
{
struct ast_str *channel_string;
struct ast_channel_blob *obj = stasis_message_data(msg);
int duration = ast_json_integer_get(ast_json_object_get(obj->blob, "duration"));
struct ast_manager_event_blob *blob;
channel_string = ast_manager_build_channel_state_string(obj->snapshot);
if (!channel_string) {
return NULL;
}
blob = ast_manager_event_blob_create(EVENT_FLAG_CALL, "ChannelTalkingStop",
"%s"
"Duration: %d\r\n",
ast_str_buffer(channel_string),
duration);
ast_free(channel_string);
return blob;
}
static struct ast_json *talking_stop_to_json(struct stasis_message *message,
const struct stasis_message_sanitizer *sanitize)
{
return channel_blob_to_json(message, "ChannelTalkingFinished", sanitize);
}
/*!
* @{ \brief Define channel message types.
*/
@@ -1008,6 +1088,14 @@ STASIS_MESSAGE_TYPE_DEFN(ast_channel_agent_login_type,
STASIS_MESSAGE_TYPE_DEFN(ast_channel_agent_logoff_type,
.to_ami = agent_logoff_to_ami,
);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_talking_start,
.to_ami = talking_start_to_ami,
.to_json = talking_start_to_json,
);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_talking_stop,
.to_ami = talking_stop_to_ami,
.to_json = talking_stop_to_json,
);
/*! @} */
@@ -1038,6 +1126,8 @@ static void stasis_channels_cleanup(void)
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_monitor_stop_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_agent_login_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_agent_logoff_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_talking_start);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_talking_stop);
}
int ast_stasis_channels_init(void)
@@ -1084,6 +1174,8 @@ int ast_stasis_channels_init(void)
res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_moh_stop_type);
res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_start_type);
res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_stop_type);
res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_talking_start);
res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_talking_stop);
return res;
}