Asterisk - The Open Source Telephony Project GIT-master-a358458
manager_mwi.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2013, Digium, Inc.
5 *
6 * Matt Jordan <mjordan@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*! \file
20 *
21 * \brief The Asterisk Management Interface - AMI (MWI event handling)
22 *
23 * \author Matt Jordan <mjordan@digium.com>
24 */
25
26#include "asterisk.h"
27
28#include "asterisk/manager.h"
29#include "asterisk/app.h"
30#include "asterisk/mwi.h"
31#include "asterisk/channel.h"
33#include "asterisk/stasis.h"
34
36
37/*** DOCUMENTATION
38 ***/
39
40/*! \brief The \ref stasis subscription returned by the forwarding of the MWI topic
41 * to the manager topic
42 */
44
45/*! \brief Callback function used by \ref mwi_app_event_cb to weed out "Event" keys */
46static int exclude_event_cb(const char *key)
47{
48 if (!strcmp(key, "Event")) {
49 return -1;
50 }
51 return 0;
52}
53
54/*! \brief Generic MWI event callback used for one-off events from voicemail modules */
55static void mwi_app_event_cb(void *data, struct stasis_subscription *sub,
56 struct stasis_message *message)
57{
58 struct ast_mwi_blob *payload = stasis_message_data(message);
59 RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
60 RAII_VAR(struct ast_str *, event_buffer, NULL, ast_free);
61 struct ast_json *event_json = ast_json_object_get(payload->blob, "Event");
62
63 if (!event_json) {
64 return;
65 }
66
67 if (payload->mwi_state && payload->mwi_state->snapshot) {
68 channel_event_string = ast_manager_build_channel_state_string(payload->mwi_state->snapshot);
69 }
70
72 if (!event_buffer) {
73 ast_log(AST_LOG_WARNING, "Failed to create payload for event %s\n", ast_json_string_get(event_json));
74 return;
75 }
76
78 "Mailbox: %s\r\n"
79 "%s"
80 "%s",
81 payload->mwi_state ? payload->mwi_state->uniqueid : "Unknown",
82 ast_str_buffer(event_buffer),
83 channel_event_string ? ast_str_buffer(channel_event_string) : "");
84}
85
86static void mwi_update_cb(void *data, struct stasis_subscription *sub,
87 struct stasis_message *message)
88{
89 struct ast_mwi_state *mwi_state;
90 RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
91
93 return;
94 }
95
96 mwi_state = stasis_message_data(message);
97 if (!mwi_state) {
98 return;
99 }
100
101 if (mwi_state->snapshot) {
102 channel_event_string = ast_manager_build_channel_state_string(mwi_state->snapshot);
103 }
104
105 /*** DOCUMENTATION
106 <managerEvent language="en_US" name="MessageWaiting">
107 <managerEventInstance class="EVENT_FLAG_CALL">
108 <synopsis>Raised when the state of messages in a voicemail mailbox
109 has changed or when a channel has finished interacting with a
110 mailbox.</synopsis>
111 <syntax>
112 <channel_snapshot/>
113 <parameter name="Mailbox">
114 <para>The mailbox with the new message, specified as <literal>mailbox</literal>@<literal>context</literal></para>
115 </parameter>
116 <parameter name="Waiting">
117 <para>Whether or not the mailbox has messages waiting for it.</para>
118 </parameter>
119 <parameter name="New">
120 <para>The number of new messages.</para>
121 </parameter>
122 <parameter name="Old">
123 <para>The number of old messages.</para>
124 </parameter>
125 </syntax>
126 <description>
127 <note><para>The Channel related parameters are only present if a
128 channel was involved in the manipulation of a mailbox. If no
129 channel is involved, the parameters are not included with the
130 event.</para>
131 </note>
132 </description>
133 </managerEventInstance>
134 </managerEvent>
135 ***/
136 manager_event(EVENT_FLAG_CALL, "MessageWaiting",
137 "%s"
138 "Mailbox: %s\r\n"
139 "Waiting: %d\r\n"
140 "New: %d\r\n"
141 "Old: %d\r\n",
142 AS_OR(channel_event_string, ""),
143 mwi_state->uniqueid,
145 mwi_state->new_msgs,
146 mwi_state->old_msgs);
147}
148
149static void manager_mwi_shutdown(void)
150{
153}
154
156{
157 int ret = 0;
159 struct stasis_topic *mwi_topic;
160 struct stasis_message_router *message_router;
161
163 if (!manager_topic) {
164 return -1;
165 }
166 message_router = ast_manager_get_message_router();
167 if (!message_router) {
168 return -1;
169 }
170 mwi_topic = ast_mwi_topic_all();
171 if (!mwi_topic) {
172 return -1;
173 }
174
176 if (!topic_forwarder) {
177 return -1;
178 }
179
181
182 ret |= stasis_message_router_add(message_router,
185 NULL);
186
187 ret |= stasis_message_router_add(message_router,
190 NULL);
191
192 /* If somehow we failed to add any routes, just shut down the whole
193 * thing and fail it.
194 */
195 if (ret) {
197 return -1;
198 }
199
200 return 0;
201}
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_free(a)
Definition: astmm.h:180
#define ast_log
Definition: astobj2.c:42
General Asterisk PBX channel definitions.
struct stasis_message_router * ast_manager_get_message_router(void)
Get the stasis_message_router for AMI.
Definition: manager.c:1877
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
Definition: manager.c:1872
struct ast_str * ast_manager_str_from_json_object(struct ast_json *blob, key_exclusion_cb exclusion_cb)
Convert a JSON object into an AMI compatible string.
Definition: manager.c:1973
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:1636
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
int ast_app_has_voicemail(const char *mailboxes, const char *folder)
Determine if a given mailbox has any voicemail If folder is NULL, defaults to "INBOX"....
Definition: main/app.c:582
#define AST_LOG_WARNING
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:253
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
#define EVENT_FLAG_CALL
Definition: manager.h:76
static void mwi_update_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Definition: manager_mwi.c:86
struct stasis_message_router * mwi_state_router
Definition: manager_mwi.c:35
int manager_mwi_init(void)
Initialize support for AMI MWI events.
Definition: manager_mwi.c:155
static void mwi_app_event_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
Generic MWI event callback used for one-off events from voicemail modules.
Definition: manager_mwi.c:55
static void manager_mwi_shutdown(void)
Definition: manager_mwi.c:149
static struct stasis_forward * topic_forwarder
The Stasis Message Bus API subscription returned by the forwarding of the MWI topic to the manager to...
Definition: manager_mwi.c:43
static int exclude_event_cb(const char *key)
Callback function used by mwi_app_event_cb to weed out "Event" keys.
Definition: manager_mwi.c:46
Asterisk MWI API.
struct stasis_message_type * ast_mwi_state_type(void)
Get the Stasis Message Bus API message type for MWI messages.
struct stasis_message_type * ast_mwi_vm_app_type(void)
Get the Stasis Message Bus API message type for voicemail application specific messages.
struct stasis_topic * ast_mwi_topic_all(void)
Get the Stasis Message Bus API topic for MWI messages.
Definition: mwi.c:89
struct stasis_forward * sub
Definition: res_corosync.c:240
#define NULL
Definition: resample.c:96
Stasis Message Bus API. See Stasis Message Bus API for detailed documentation.
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
Definition: stasis.c:1548
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
Definition: stasis.c:1578
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define AS_OR(a, b)
Definition: strings.h:49
Abstract JSON element (object, array, string, int, ...).
Object that represents an MWI update with some additional application defined data.
Definition: mwi.h:471
struct ast_mwi_state * mwi_state
Definition: mwi.h:472
struct ast_json * blob
Definition: mwi.h:473
The structure that contains MWI state.
Definition: mwi.h:455
struct ast_channel_snapshot * snapshot
Definition: mwi.h:462
int old_msgs
Definition: mwi.h:460
int new_msgs
Definition: mwi.h:459
const ast_string_field uniqueid
Definition: mwi.h:458
Support for dynamic strings.
Definition: strings.h:623
Forwarding information.
Definition: stasis.c:1531
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941