mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-14 08:31:02 +00:00
app_meetme: Refactor manager events to use stasis
(closes issue ASTERISK-21467) Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/2564/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@390848 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -73,6 +73,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
#include "asterisk/paths.h"
|
||||
#include "asterisk/data.h"
|
||||
#include "asterisk/test.h"
|
||||
#include "asterisk/stasis.h"
|
||||
#include "asterisk/stasis_channels.h"
|
||||
#include "asterisk/stasis_message_router.h"
|
||||
#include "asterisk/json.h"
|
||||
|
||||
#include "enter.h"
|
||||
#include "leave.h"
|
||||
@@ -553,6 +557,88 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
MeetmeListRoomsComplete.</para>
|
||||
</description>
|
||||
</manager>
|
||||
<managerEvent language="en_US" name="MeetmeJoin">
|
||||
<managerEventInstance class="EVENT_FLAG_CALL">
|
||||
<synopsis>Raised when a user joins a MeetMe conference.</synopsis>
|
||||
<syntax>
|
||||
<parameter name="Meetme">
|
||||
<para>The identifier for the MeetMe conference.</para>
|
||||
</parameter>
|
||||
<parameter name="Usernum">
|
||||
<para>The identifier of the MeetMe user who joined.</para>
|
||||
</parameter>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
|
||||
</syntax>
|
||||
<see-also>
|
||||
<ref type="managerEvent">MeetmeLeave</ref>
|
||||
<ref type="application">MeetMe</ref>
|
||||
</see-also>
|
||||
</managerEventInstance>
|
||||
</managerEvent>
|
||||
<managerEvent language="en_US" name="MeetmeLeave">
|
||||
<managerEventInstance class="EVENT_FLAG_CALL">
|
||||
<synopsis>Raised when a user leaves a MeetMe conference.</synopsis>
|
||||
<syntax>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter)" />
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
|
||||
<parameter name="Duration">
|
||||
<para>The length of time in seconds that the Meetme user was in the conference.</para>
|
||||
</parameter>
|
||||
</syntax>
|
||||
<see-also>
|
||||
<ref type="managerEvent">MeetmeJoin</ref>
|
||||
</see-also>
|
||||
</managerEventInstance>
|
||||
</managerEvent>
|
||||
<managerEvent language="en_US" name="MeetmeEnd">
|
||||
<managerEventInstance class="EVENT_FLAG_CALL">
|
||||
<synopsis>Raised when a MeetMe conference ends.</synopsis>
|
||||
<syntax>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
|
||||
</syntax>
|
||||
<see-also>
|
||||
<ref type="managerEvent">MeetmeJoin</ref>
|
||||
</see-also>
|
||||
</managerEventInstance>
|
||||
</managerEvent>
|
||||
<managerEvent language="en_US" name="MeetmeTalkRequest">
|
||||
<managerEventInstance class="EVENT_FLAG_CALL">
|
||||
<synopsis>Raised when a MeetMe user has started talking.</synopsis>
|
||||
<syntax>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter)" />
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
|
||||
<parameter name="Duration">
|
||||
<para>The length of time in seconds that the Meetme user has been in the conference at the time of this event.</para>
|
||||
</parameter>
|
||||
<parameter name="Status">
|
||||
<enumlist>
|
||||
<enum name="on"/>
|
||||
<enum name="off"/>
|
||||
</enumlist>
|
||||
</parameter>
|
||||
</syntax>
|
||||
</managerEventInstance>
|
||||
</managerEvent>
|
||||
<managerEvent language="en_US" name="MeetmeTalking">
|
||||
<managerEventInstance class="EVENT_FLAG_CALL">
|
||||
<synopsis>Raised when a MeetMe user begins or ends talking.</synopsis>
|
||||
<syntax>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter)" />
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeTalkRequest']/managerEventInstance/syntax/parameter)" />
|
||||
</syntax>
|
||||
</managerEventInstance>
|
||||
</managerEvent>
|
||||
<managerEvent language="en_US" name="MeetmeMute">
|
||||
<managerEventInstance class="EVENT_FLAG_CALL">
|
||||
<synopsis>Raised when a MeetMe user is muted or unmuted.</synopsis>
|
||||
<syntax>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter)" />
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeTalkRequest']/managerEventInstance/syntax/parameter)" />
|
||||
</syntax>
|
||||
</managerEventInstance>
|
||||
</managerEvent>
|
||||
***/
|
||||
|
||||
#define CONFIG_FILE_NAME "meetme.conf"
|
||||
@@ -1031,6 +1117,330 @@ static const char gain_map[] = {
|
||||
15,
|
||||
};
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief accessor for join message type
|
||||
* \since 12.0.0
|
||||
*
|
||||
* \retval pointer to the stasis message type
|
||||
* \retval NULL if not initialized
|
||||
*/
|
||||
static struct stasis_message_type *meetme_join_type(void);
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief accessor for leave message type
|
||||
* \since 12.0.0
|
||||
*
|
||||
* \retval pointer to the stasis message type
|
||||
* \retval NULL if not initialized
|
||||
*/
|
||||
static struct stasis_message_type *meetme_leave_type(void);
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief accessor for end message type
|
||||
* \since 12.0.0
|
||||
*
|
||||
* \retval pointer to the stasis message type
|
||||
* \retval NULL if not initialized
|
||||
*/
|
||||
static struct stasis_message_type *meetme_end_type(void);
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief accessor for mute message type
|
||||
* \since 12.0.0
|
||||
*
|
||||
* \retval pointer to the stasis message type
|
||||
* \retval NULL if not initialized
|
||||
*/
|
||||
static struct stasis_message_type *meetme_mute_type(void);
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief accessor for talking message type
|
||||
* \since 12.0.0
|
||||
*
|
||||
* \retval pointer to the stasis message type
|
||||
* \retval NULL if not initialized
|
||||
*/
|
||||
static struct stasis_message_type *meetme_talking_type(void);
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief accessor for talk request message type
|
||||
* \since 12.0.0
|
||||
*
|
||||
* \retval pointer to the stasis message type
|
||||
* \retval NULL if not initialized
|
||||
*/
|
||||
static struct stasis_message_type *meetme_talk_request_type(void);
|
||||
|
||||
/* Routes the various meetme message types to the meetme stasis callback function to turn them into events */
|
||||
static struct stasis_message_router *meetme_event_message_router;
|
||||
|
||||
STASIS_MESSAGE_TYPE_DEFN(meetme_join_type);
|
||||
STASIS_MESSAGE_TYPE_DEFN(meetme_leave_type);
|
||||
STASIS_MESSAGE_TYPE_DEFN(meetme_end_type);
|
||||
STASIS_MESSAGE_TYPE_DEFN(meetme_mute_type);
|
||||
STASIS_MESSAGE_TYPE_DEFN(meetme_talking_type);
|
||||
STASIS_MESSAGE_TYPE_DEFN(meetme_talk_request_type);
|
||||
|
||||
static void meetme_stasis_cb(void *data, struct stasis_subscription *sub,
|
||||
struct stasis_topic *topic, struct stasis_message *message);
|
||||
|
||||
static void meetme_stasis_cleanup(void)
|
||||
{
|
||||
if (meetme_event_message_router) {
|
||||
stasis_message_router_unsubscribe(meetme_event_message_router);
|
||||
meetme_event_message_router = NULL;
|
||||
}
|
||||
|
||||
STASIS_MESSAGE_TYPE_CLEANUP(meetme_join_type);
|
||||
STASIS_MESSAGE_TYPE_CLEANUP(meetme_leave_type);
|
||||
STASIS_MESSAGE_TYPE_CLEANUP(meetme_end_type);
|
||||
STASIS_MESSAGE_TYPE_CLEANUP(meetme_mute_type);
|
||||
STASIS_MESSAGE_TYPE_CLEANUP(meetme_talking_type);
|
||||
STASIS_MESSAGE_TYPE_CLEANUP(meetme_talk_request_type);
|
||||
}
|
||||
|
||||
static int meetme_stasis_init(void)
|
||||
{
|
||||
|
||||
STASIS_MESSAGE_TYPE_INIT(meetme_join_type);
|
||||
STASIS_MESSAGE_TYPE_INIT(meetme_leave_type);
|
||||
STASIS_MESSAGE_TYPE_INIT(meetme_end_type);
|
||||
STASIS_MESSAGE_TYPE_INIT(meetme_mute_type);
|
||||
STASIS_MESSAGE_TYPE_INIT(meetme_talking_type);
|
||||
STASIS_MESSAGE_TYPE_INIT(meetme_talk_request_type);
|
||||
|
||||
meetme_event_message_router = stasis_message_router_create(
|
||||
stasis_caching_get_topic(ast_channel_topic_all_cached()));
|
||||
|
||||
if (!meetme_event_message_router) {
|
||||
meetme_stasis_cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stasis_message_router_add(meetme_event_message_router,
|
||||
meetme_join_type(),
|
||||
meetme_stasis_cb,
|
||||
NULL)) {
|
||||
meetme_stasis_cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stasis_message_router_add(meetme_event_message_router,
|
||||
meetme_leave_type(),
|
||||
meetme_stasis_cb,
|
||||
NULL)) {
|
||||
meetme_stasis_cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stasis_message_router_add(meetme_event_message_router,
|
||||
meetme_end_type(),
|
||||
meetme_stasis_cb,
|
||||
NULL)) {
|
||||
meetme_stasis_cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stasis_message_router_add(meetme_event_message_router,
|
||||
meetme_mute_type(),
|
||||
meetme_stasis_cb,
|
||||
NULL)) {
|
||||
meetme_stasis_cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stasis_message_router_add(meetme_event_message_router,
|
||||
meetme_talking_type(),
|
||||
meetme_stasis_cb,
|
||||
NULL)) {
|
||||
meetme_stasis_cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (stasis_message_router_add(meetme_event_message_router,
|
||||
meetme_talk_request_type(),
|
||||
meetme_stasis_cb,
|
||||
NULL)) {
|
||||
meetme_stasis_cleanup();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void meetme_stasis_cb(void *data, struct stasis_subscription *sub,
|
||||
struct stasis_topic *topic, struct stasis_message *message)
|
||||
{
|
||||
struct ast_channel_blob *channel_blob = stasis_message_data(message);
|
||||
struct stasis_message_type *message_type;
|
||||
const char *event;
|
||||
const char *conference_num;
|
||||
const char *status;
|
||||
struct ast_json *json_cur;
|
||||
RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
|
||||
RAII_VAR(struct ast_str *, extra_text, NULL, ast_free);
|
||||
|
||||
if (!channel_blob) {
|
||||
ast_assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
message_type = stasis_message_type(message);
|
||||
|
||||
if (!message_type) {
|
||||
ast_assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (message_type == meetme_join_type()) {
|
||||
event = "MeetmeJoin";
|
||||
} else if (message_type == meetme_leave_type()) {
|
||||
event = "MeetmeLeave";
|
||||
} else if (message_type == meetme_end_type()) {
|
||||
event = "MeetmeEnd";
|
||||
} else if (message_type == meetme_mute_type()) {
|
||||
event = "MeetmeMute";
|
||||
} else if (message_type == meetme_talking_type()) {
|
||||
event = "MeetmeTalking";
|
||||
} else if (message_type == meetme_talk_request_type()) {
|
||||
event = "MeetmeTalkRequest";
|
||||
} else {
|
||||
ast_assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!event) {
|
||||
ast_assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
conference_num = ast_json_string_get(ast_json_object_get(channel_blob->blob, "Meetme"));
|
||||
if (!conference_num) {
|
||||
ast_assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
status = ast_json_string_get(ast_json_object_get(channel_blob->blob, "status"));
|
||||
if (status) {
|
||||
ast_str_append_event_header(&extra_text, "Status", status);
|
||||
}
|
||||
|
||||
if (channel_blob->snapshot) {
|
||||
channel_text = ast_manager_build_channel_state_string(channel_blob->snapshot);
|
||||
}
|
||||
|
||||
if ((json_cur = ast_json_object_get(channel_blob->blob, "user"))) {
|
||||
int user_number = ast_json_integer_get(json_cur);
|
||||
RAII_VAR(struct ast_str *, user_prop_str, ast_str_create(32), ast_free);
|
||||
if (!user_prop_str) {
|
||||
return;
|
||||
}
|
||||
|
||||
ast_str_set(&user_prop_str, 0, "%d", user_number);
|
||||
ast_str_append_event_header(&extra_text, "User", ast_str_buffer(user_prop_str));
|
||||
|
||||
if ((json_cur = ast_json_object_get(channel_blob->blob, "duration"))) {
|
||||
int duration = ast_json_integer_get(json_cur);
|
||||
ast_str_set(&user_prop_str, 0, "%d", duration);
|
||||
ast_str_append_event_header(&extra_text, "Duration", ast_str_buffer(user_prop_str));
|
||||
}
|
||||
|
||||
json_cur = NULL;
|
||||
}
|
||||
|
||||
manager_event(EVENT_FLAG_CALL, event,
|
||||
"Meetme: %s\r\n"
|
||||
"%s"
|
||||
"%s",
|
||||
conference_num,
|
||||
channel_text ? ast_str_buffer(channel_text) : "",
|
||||
extra_text ? ast_str_buffer(extra_text) : "");
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Build a json object from a status value for inclusion in json extras for meetme_stasis_generate_msg
|
||||
* \since 12.0.0
|
||||
*
|
||||
* \param on if true, then status is on. Otherwise status is off
|
||||
* \retval NULL on failure to allocate the JSON blob.
|
||||
* \retval pointer to the JSON blob if successful.
|
||||
*/
|
||||
static struct ast_json *status_to_json(int on)
|
||||
{
|
||||
struct ast_json *json_object = ast_json_pack("{s: s}",
|
||||
"status", on ? "on" : "off");
|
||||
|
||||
return json_object;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \brief Generate a stasis message associated with a meetme event
|
||||
* \since 12.0.0
|
||||
*
|
||||
* \param meetme_confere The conference responsible for generating this message
|
||||
* \param chan The channel involved in the message (NULL allowed)
|
||||
* \param user The conference user involved in the message (NULL allowed)
|
||||
* \param message_type the type the stasis message being generated
|
||||
* \param extras Additional json fields desired for inclusion
|
||||
*/
|
||||
static void meetme_stasis_generate_msg(struct ast_conference *meetme_conference, struct ast_channel *chan,
|
||||
struct ast_conf_user *user, struct stasis_message_type *message_type, struct ast_json *extras)
|
||||
{
|
||||
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
|
||||
|
||||
json_object = ast_json_pack("{s: s}",
|
||||
"Meetme", meetme_conference->confno);
|
||||
|
||||
if (!json_object) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (extras) {
|
||||
ast_json_object_update(json_object, extras);
|
||||
}
|
||||
|
||||
if (user) {
|
||||
struct timeval now = ast_tvnow();
|
||||
long duration = (long)(now.tv_sec - user->jointime);
|
||||
RAII_VAR(struct ast_json *, json_user, ast_json_integer_create(user->user_no), ast_json_unref);
|
||||
RAII_VAR(struct ast_json *, json_user_duration, NULL, ast_json_unref);
|
||||
|
||||
if (ast_json_object_set(json_object, "user", json_user)) {
|
||||
return;
|
||||
}
|
||||
json_user = NULL;
|
||||
|
||||
if (duration > 0) {
|
||||
json_user_duration = ast_json_integer_create(duration);
|
||||
|
||||
if (!json_user_duration) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ast_json_object_set(json_object, "duration", json_user_duration)) {
|
||||
return;
|
||||
}
|
||||
json_user_duration = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
msg = ast_channel_blob_create(chan, message_type, json_object);
|
||||
|
||||
if (!msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
stasis_publish(ast_channel_topic(chan), msg);
|
||||
}
|
||||
|
||||
static int admin_exec(struct ast_channel *chan, const char *data);
|
||||
static void *recordthread(void *args);
|
||||
@@ -1953,18 +2363,8 @@ static int conf_free(struct ast_conference *conf)
|
||||
struct announce_listitem *item;
|
||||
|
||||
AST_LIST_REMOVE(&confs, conf, list);
|
||||
/*** DOCUMENTATION
|
||||
<managerEventInstance>
|
||||
<synopsis>Raised when a MeetMe conference ends.</synopsis>
|
||||
<syntax>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
|
||||
</syntax>
|
||||
<see-also>
|
||||
<ref type="managerEvent">MeetmeJoin</ref>
|
||||
</see-also>
|
||||
</managerEventInstance>
|
||||
***/
|
||||
manager_event(EVENT_FLAG_CALL, "MeetmeEnd", "Meetme: %s\r\n", conf->confno);
|
||||
|
||||
meetme_stasis_generate_msg(conf, NULL, NULL, meetme_end_type(), NULL);
|
||||
|
||||
if (conf->recording == MEETME_RECORD_ACTIVE) {
|
||||
conf->recording = MEETME_RECORD_TERMINATE;
|
||||
@@ -2298,30 +2698,8 @@ static int can_write(struct ast_channel *chan, struct ast_flags64 *confflags)
|
||||
|
||||
static void send_talking_event(struct ast_channel *chan, struct ast_conference *conf, struct ast_conf_user *user, int talking)
|
||||
{
|
||||
/*** DOCUMENTATION
|
||||
<managerEventInstance>
|
||||
<synopsis>Raised when a MeetMe user begins or ends talking.</synopsis>
|
||||
<syntax>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Usernum'])" />
|
||||
<parameter name="Status">
|
||||
<enumlist>
|
||||
<enum name="on"/>
|
||||
<enum name="off"/>
|
||||
</enumlist>
|
||||
</parameter>
|
||||
</syntax>
|
||||
</managerEventInstance>
|
||||
***/
|
||||
ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalking",
|
||||
"Channel: %s\r\n"
|
||||
"Uniqueid: %s\r\n"
|
||||
"Meetme: %s\r\n"
|
||||
"Usernum: %d\r\n"
|
||||
"Status: %s\r\n",
|
||||
ast_channel_name(chan), ast_channel_uniqueid(chan),
|
||||
conf->confno,
|
||||
user->user_no, talking ? "on" : "off");
|
||||
RAII_VAR(struct ast_json *, status_blob, status_to_json(talking), ast_json_unref);
|
||||
meetme_stasis_generate_msg(conf, chan, user, meetme_talking_type(), status_blob);
|
||||
}
|
||||
|
||||
static void set_user_talking(struct ast_channel *chan, struct ast_conference *conf, struct ast_conf_user *user, int talking, int monitor)
|
||||
@@ -3335,39 +3713,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
|
||||
ast_debug(1, "Placed channel %s in DAHDI conf %d\n", ast_channel_name(chan), conf->dahdiconf);
|
||||
|
||||
if (!sent_event) {
|
||||
/*** DOCUMENTATION
|
||||
<managerEventInstance>
|
||||
<synopsis>Raised when a user joins a MeetMe conference.</synopsis>
|
||||
<syntax>
|
||||
<parameter name="Meetme">
|
||||
<para>The identifier for the MeetMe conference.</para>
|
||||
</parameter>
|
||||
<parameter name="Usernum">
|
||||
<para>The identifier of the MeetMe user who joined.</para>
|
||||
</parameter>
|
||||
</syntax>
|
||||
<see-also>
|
||||
<ref type="managerEvent">MeetmeLeave</ref>
|
||||
<ref type="application">MeetMe</ref>
|
||||
</see-also>
|
||||
</managerEventInstance>
|
||||
***/
|
||||
ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeJoin",
|
||||
"Channel: %s\r\n"
|
||||
"Uniqueid: %s\r\n"
|
||||
"Meetme: %s\r\n"
|
||||
"Usernum: %d\r\n"
|
||||
"CallerIDnum: %s\r\n"
|
||||
"CallerIDname: %s\r\n"
|
||||
"ConnectedLineNum: %s\r\n"
|
||||
"ConnectedLineName: %s\r\n",
|
||||
ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno,
|
||||
user->user_no,
|
||||
S_COR(ast_channel_caller(user->chan)->id.number.valid, ast_channel_caller(user->chan)->id.number.str, "<unknown>"),
|
||||
S_COR(ast_channel_caller(user->chan)->id.name.valid, ast_channel_caller(user->chan)->id.name.str, "<unknown>"),
|
||||
S_COR(ast_channel_connected(user->chan)->id.number.valid, ast_channel_connected(user->chan)->id.number.str, "<unknown>"),
|
||||
S_COR(ast_channel_connected(user->chan)->id.name.valid, ast_channel_connected(user->chan)->id.name.str, "<unknown>")
|
||||
);
|
||||
meetme_stasis_generate_msg(conf, chan, user, meetme_join_type(), NULL);
|
||||
sent_event = 1;
|
||||
}
|
||||
|
||||
@@ -3716,6 +4062,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
|
||||
|
||||
/* If I should be muted but am still talker, mute me */
|
||||
if ((user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && (dahdic.confmode & DAHDI_CONF_TALKER)) {
|
||||
RAII_VAR(struct ast_json *, status_blob, status_to_json(1), ast_json_unref);
|
||||
dahdic.confmode ^= DAHDI_CONF_TALKER;
|
||||
if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
|
||||
ast_log(LOG_WARNING, "Error setting conference - Un/Mute \n");
|
||||
@@ -3727,95 +4074,34 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
|
||||
if (ast_test_flag64(confflags, (CONFFLAG_MONITORTALKER | CONFFLAG_OPTIMIZETALKER))) {
|
||||
set_user_talking(chan, conf, user, -1, ast_test_flag64(confflags, CONFFLAG_MONITORTALKER));
|
||||
}
|
||||
/*** DOCUMENTATION
|
||||
<managerEventInstance>
|
||||
<synopsis>Raised when a MeetMe user is muted.</synopsis>
|
||||
<syntax>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Usernum'])" />
|
||||
<parameter name="Status">
|
||||
<enumlist>
|
||||
<enum name="on"/>
|
||||
<enum name="off"/>
|
||||
</enumlist>
|
||||
</parameter>
|
||||
</syntax>
|
||||
</managerEventInstance>
|
||||
***/
|
||||
ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeMute",
|
||||
"Channel: %s\r\n"
|
||||
"Uniqueid: %s\r\n"
|
||||
"Meetme: %s\r\n"
|
||||
"Usernum: %d\r\n"
|
||||
"Status: on\r\n",
|
||||
ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno, user->user_no);
|
||||
meetme_stasis_generate_msg(conf, chan, user, meetme_mute_type(), status_blob);
|
||||
}
|
||||
|
||||
/* If I should be un-muted but am not talker, un-mute me */
|
||||
if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) && !ast_test_flag64(confflags, CONFFLAG_MONITOR) && !(dahdic.confmode & DAHDI_CONF_TALKER)) {
|
||||
RAII_VAR(struct ast_json *, status_blob, status_to_json(0), ast_json_unref);
|
||||
dahdic.confmode |= DAHDI_CONF_TALKER;
|
||||
if (ioctl(fd, DAHDI_SETCONF, &dahdic)) {
|
||||
ast_log(LOG_WARNING, "Error setting conference - Un/Mute \n");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
/*** DOCUMENTATION
|
||||
<managerEventInstance>
|
||||
<synopsis>Raised when a MeetMe user is unmuted.</synopsis>
|
||||
</managerEventInstance>
|
||||
***/
|
||||
ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeMute",
|
||||
"Channel: %s\r\n"
|
||||
"Uniqueid: %s\r\n"
|
||||
"Meetme: %s\r\n"
|
||||
"Usernum: %d\r\n"
|
||||
"Status: off\r\n",
|
||||
ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno, user->user_no);
|
||||
meetme_stasis_generate_msg(conf, chan, user, meetme_mute_type(), status_blob);
|
||||
}
|
||||
|
||||
if ((user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) &&
|
||||
(user->adminflags & ADMINFLAG_T_REQUEST) && !(talkreq_manager)) {
|
||||
talkreq_manager = 1;
|
||||
|
||||
/*** DOCUMENTATION
|
||||
<managerEventInstance>
|
||||
<synopsis>Raised when a MeetMe user has started talking.</synopsis>
|
||||
<syntax>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Usernum'])" />
|
||||
<parameter name="Status">
|
||||
<enumlist>
|
||||
<enum name="on"/>
|
||||
<enum name="off"/>
|
||||
</enumlist>
|
||||
</parameter>
|
||||
</syntax>
|
||||
</managerEventInstance>
|
||||
***/
|
||||
ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalkRequest",
|
||||
"Channel: %s\r\n"
|
||||
"Uniqueid: %s\r\n"
|
||||
"Meetme: %s\r\n"
|
||||
"Usernum: %d\r\n"
|
||||
"Status: on\r\n",
|
||||
ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno, user->user_no);
|
||||
RAII_VAR(struct ast_json *, status_blob, status_to_json(1), ast_json_unref);
|
||||
talkreq_manager = 1;
|
||||
meetme_stasis_generate_msg(conf, chan, user, meetme_talk_request_type(), status_blob);
|
||||
}
|
||||
|
||||
if (!(user->adminflags & (ADMINFLAG_MUTED | ADMINFLAG_SELFMUTED)) &&
|
||||
!(user->adminflags & ADMINFLAG_T_REQUEST) && (talkreq_manager)) {
|
||||
RAII_VAR(struct ast_json *, status_blob, status_to_json(0), ast_json_unref);
|
||||
talkreq_manager = 0;
|
||||
/*** DOCUMENTATION
|
||||
<managerEventInstance>
|
||||
<synopsis>Raised when a MeetMe user has finished talking.</synopsis>
|
||||
</managerEventInstance>
|
||||
***/
|
||||
ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeTalkRequest",
|
||||
"Channel: %s\r\n"
|
||||
"Uniqueid: %s\r\n"
|
||||
"Meetme: %s\r\n"
|
||||
"Usernum: %d\r\n"
|
||||
"Status: off\r\n",
|
||||
ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno, user->user_no);
|
||||
meetme_stasis_generate_msg(conf, chan, user, meetme_talk_request_type(), status_blob);
|
||||
}
|
||||
|
||||
/* If user have been hung up, exit the conference */
|
||||
@@ -4169,38 +4455,7 @@ bailoutandtrynormal:
|
||||
now = ast_tvnow();
|
||||
|
||||
if (sent_event) {
|
||||
/*** DOCUMENTATION
|
||||
<managerEventInstance>
|
||||
<synopsis>Raised when a user leaves a MeetMe conference.</synopsis>
|
||||
<syntax>
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Meetme'])" />
|
||||
<xi:include xpointer="xpointer(/docs/managerEvent[@name='MeetmeJoin']/managerEventInstance/syntax/parameter[@name='Usernum'])" />
|
||||
<parameter name="Duration">
|
||||
<para>The length of time in seconds that the Meetme user was in the conference.</para>
|
||||
</parameter>
|
||||
</syntax>
|
||||
<see-also>
|
||||
<ref type="managerEvent">MeetmeJoin</ref>
|
||||
</see-also>
|
||||
</managerEventInstance>
|
||||
***/
|
||||
ast_manager_event(chan, EVENT_FLAG_CALL, "MeetmeLeave",
|
||||
"Channel: %s\r\n"
|
||||
"Uniqueid: %s\r\n"
|
||||
"Meetme: %s\r\n"
|
||||
"Usernum: %d\r\n"
|
||||
"CallerIDNum: %s\r\n"
|
||||
"CallerIDName: %s\r\n"
|
||||
"ConnectedLineNum: %s\r\n"
|
||||
"ConnectedLineName: %s\r\n"
|
||||
"Duration: %ld\r\n",
|
||||
ast_channel_name(chan), ast_channel_uniqueid(chan), conf->confno,
|
||||
user->user_no,
|
||||
S_COR(ast_channel_caller(user->chan)->id.number.valid, ast_channel_caller(user->chan)->id.number.str, "<unknown>"),
|
||||
S_COR(ast_channel_caller(user->chan)->id.name.valid, ast_channel_caller(user->chan)->id.name.str, "<unknown>"),
|
||||
S_COR(ast_channel_connected(user->chan)->id.number.valid, ast_channel_connected(user->chan)->id.number.str, "<unknown>"),
|
||||
S_COR(ast_channel_connected(user->chan)->id.name.valid, ast_channel_connected(user->chan)->id.name.str, "<unknown>"),
|
||||
(long)(now.tv_sec - user->jointime));
|
||||
meetme_stasis_generate_msg(conf, chan, user, meetme_leave_type(), NULL);
|
||||
}
|
||||
|
||||
if (setusercount) {
|
||||
@@ -7739,6 +7994,8 @@ static int unload_module(void)
|
||||
res |= ast_custom_function_unregister(&meetme_info_acf);
|
||||
ast_unload_realtime("meetme");
|
||||
|
||||
meetme_stasis_cleanup();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -7758,6 +8015,8 @@ static int load_module(void)
|
||||
|
||||
res |= load_config(0);
|
||||
|
||||
res |= meetme_stasis_init();
|
||||
|
||||
ast_cli_register_multiple(cli_meetme, ARRAY_LEN(cli_meetme));
|
||||
res |= ast_manager_register_xml("MeetmeMute", EVENT_FLAG_CALL, action_meetmemute);
|
||||
res |= ast_manager_register_xml("MeetmeUnmute", EVENT_FLAG_CALL, action_meetmeunmute);
|
||||
|
@@ -188,24 +188,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
static struct stasis_message_router *bridge_state_router;
|
||||
static struct stasis_message_router *channel_state_router;
|
||||
|
||||
static void append_event_header(struct ast_str **fields_string,
|
||||
const char *header, const char *value)
|
||||
{
|
||||
struct ast_str *working_str = *fields_string;
|
||||
|
||||
if (!working_str) {
|
||||
working_str = ast_str_create(128);
|
||||
if (!working_str) {
|
||||
return;
|
||||
}
|
||||
*fields_string = working_str;
|
||||
}
|
||||
|
||||
ast_str_append(&working_str, 0,
|
||||
"%s: %s\r\n",
|
||||
header, value);
|
||||
}
|
||||
|
||||
static void confbridge_publish_manager_event(
|
||||
struct stasis_message *message,
|
||||
const char *event,
|
||||
@@ -306,7 +288,7 @@ static void confbridge_talking_cb(void *data, struct stasis_subscription *sub,
|
||||
return;
|
||||
}
|
||||
|
||||
append_event_header(&extra_text, "TalkingStatus", talking_status);
|
||||
ast_str_append_event_header(&extra_text, "TalkingStatus", talking_status);
|
||||
if (!extra_text) {
|
||||
return;
|
||||
}
|
||||
|
@@ -316,6 +316,21 @@ int astman_datastore_remove(struct mansession *s, struct ast_datastore *datastor
|
||||
*/
|
||||
struct ast_datastore *astman_datastore_find(struct mansession *s, const struct ast_datastore_info *info, const char *uid);
|
||||
|
||||
/*!
|
||||
* \brief append an event header to an ast string
|
||||
* \since 12
|
||||
*
|
||||
* \param fields_string pointer to an ast_string pointer. It may be a pointer to a
|
||||
* NULL ast_str pointer, in which case the ast_str will be initialized.
|
||||
* \param header The header being applied
|
||||
* \param value the value of the header
|
||||
*
|
||||
* \retval 0 if successful
|
||||
* \retval non-zero on failure
|
||||
*/
|
||||
int ast_str_append_event_header(struct ast_str **fields_string,
|
||||
const char *header, const char *value);
|
||||
|
||||
/*! \brief Struct representing a snapshot of channel state */
|
||||
struct ast_channel_snapshot;
|
||||
|
||||
|
@@ -89,6 +89,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
||||
#include "asterisk/security_events.h"
|
||||
#include "asterisk/event.h"
|
||||
#include "asterisk/aoc.h"
|
||||
#include "asterisk/strings.h"
|
||||
#include "asterisk/stringfields.h"
|
||||
#include "asterisk/presencestate.h"
|
||||
#include "asterisk/stasis.h"
|
||||
@@ -8242,6 +8243,26 @@ struct ast_datastore *astman_datastore_find(struct mansession *s, const struct a
|
||||
return datastore;
|
||||
}
|
||||
|
||||
int ast_str_append_event_header(struct ast_str **fields_string,
|
||||
const char *header, const char *value)
|
||||
{
|
||||
struct ast_str *working_str = *fields_string;
|
||||
|
||||
if (!working_str) {
|
||||
working_str = ast_str_create(128);
|
||||
if (!working_str) {
|
||||
return -1;
|
||||
}
|
||||
*fields_string = working_str;
|
||||
}
|
||||
|
||||
ast_str_append(&working_str, 0,
|
||||
"%s: %s\r\n",
|
||||
header, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void manager_event_blob_dtor(void *obj)
|
||||
{
|
||||
struct ast_manager_event_blob *ev = obj;
|
||||
|
Reference in New Issue
Block a user