2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2013, Digium, Inc.
6 * Richard Mudgett <rmudgett@digium.com>
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.
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.
21 * \brief AMI wrapper for external MWI.
23 * \author Richard Mudgett <rmudgett@digium.com>
26 * \arg \ref AstCREDITS
30 <depend>res_mwi_external</depend>
31 <support_level>core</support_level>
36 <manager name="MWIGet" language="en_US">
38 Get selected mailboxes with message counts.
41 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
42 <parameter name="Mailbox" required="true">
43 <para>Mailbox ID in the form of
44 /<replaceable>regex</replaceable>/ for all mailboxes matching the regular
45 expression. Otherwise it is for a specific mailbox.</para>
49 <para>Get a list of mailboxes with their message counts.</para>
52 <managerEvent language="en_US" name="MWIGet">
53 <managerEventInstance class="EVENT_FLAG_REPORTING">
55 Raised in response to a MWIGet command.
58 <parameter name="ActionID" required="false"/>
59 <parameter name="Mailbox">
60 <para>Specific mailbox ID.</para>
62 <parameter name="OldMessages">
63 <para>The number of old messages in the mailbox.</para>
65 <parameter name="NewMessages">
66 <para>The number of new messages in the mailbox.</para>
70 <ref type="manager">MWIGet</ref>
72 </managerEventInstance>
74 <managerEvent language="en_US" name="MWIGetComplete">
75 <managerEventInstance class="EVENT_FLAG_REPORTING">
77 Raised in response to a MWIGet command.
80 <parameter name="ActionID" required="false"/>
81 <parameter name="EventList" />
82 <parameter name="ListItems">
83 <para>The number of mailboxes reported.</para>
87 <ref type="manager">MWIGet</ref>
89 </managerEventInstance>
91 <manager name="MWIDelete" language="en_US">
93 Delete selected mailboxes.
96 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
97 <xi:include xpointer="xpointer(/docs/manager[@name='MWIGet']/syntax/parameter[@name='Mailbox'])" />
100 <para>Delete the specified mailboxes.</para>
103 <manager name="MWIUpdate" language="en_US">
105 Update the mailbox message counts.
108 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
109 <parameter name="Mailbox" required="true">
110 <para>Specific mailbox ID.</para>
112 <parameter name="OldMessages">
113 <para>The number of old messages in the mailbox. Defaults
114 to zero if missing.</para>
116 <parameter name="NewMessages">
117 <para>The number of new messages in the mailbox. Defaults
118 to zero if missing.</para>
122 <para>Update the mailbox message counts.</para>
128 #include "asterisk.h"
130 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
132 #include "asterisk/module.h"
133 #include "asterisk/res_mwi_external.h"
134 #include "asterisk/manager.h"
136 /* ------------------------------------------------------------------- */
140 * \brief Get the requested mailboxes.
143 * \param s AMI session.
144 * \param m AMI message.
146 * \retval 0 to keep AMI connection.
147 * \retval -1 to disconnect AMI connection.
149 static int mwi_mailbox_get(struct mansession *s, const struct message *m)
153 const char *mailbox_id = astman_get_header(m, "Mailbox");
154 const struct ast_mwi_mailbox_object *mailbox;
155 struct ao2_container *mailboxes;
157 struct ao2_iterator iter;
159 if (ast_strlen_zero(mailbox_id)) {
160 astman_send_error(s, m, "Missing mailbox parameter in request");
164 if (*mailbox_id == '/') {
165 struct ast_str *regex_string;
167 regex_string = ast_str_create(strlen(mailbox_id) + 1);
169 astman_send_error(s, m, "Memory Allocation Failure");
173 /* Make "/regex/" into "regex" */
174 if (ast_regex_string_to_regex_pattern(mailbox_id, ®ex_string) != 0) {
175 astman_send_error_va(s, m, "Mailbox regex format invalid in: %s", mailbox_id);
176 ast_free(regex_string);
180 mailboxes = ast_mwi_mailbox_get_by_regex(ast_str_buffer(regex_string));
181 ast_free(regex_string);
183 mailboxes = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL, NULL);
185 mailbox = ast_mwi_mailbox_get(mailbox_id);
187 if (!ao2_link(mailboxes, (void *) mailbox)) {
188 ao2_ref(mailboxes, -1);
191 ast_mwi_mailbox_unref(mailbox);
196 astman_send_error(s, m, "Mailbox container creation failure");
200 astman_send_listack(s, m, "Mailboxes will follow", "start");
202 id = astman_get_header(m, "ActionID");
203 if (!ast_strlen_zero(id)) {
204 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
209 /* Output mailbox list. */
211 iter = ao2_iterator_init(mailboxes, AO2_ITERATOR_UNLINK);
212 for (; (mailbox = ao2_iterator_next(&iter)); ast_mwi_mailbox_unref(mailbox)) {
217 "OldMessages: %u\r\n"
218 "NewMessages: %u\r\n"
221 ast_mwi_mailbox_get_id(mailbox),
222 ast_mwi_mailbox_get_msgs_old(mailbox),
223 ast_mwi_mailbox_get_msgs_new(mailbox),
226 ao2_iterator_destroy(&iter);
227 ao2_ref(mailboxes, -1);
229 astman_send_list_complete_start(s, m, "MWIGetComplete", count);
230 astman_send_list_complete_end(s);
237 * \brief Delete the requested mailboxes.
240 * \param s AMI session.
241 * \param m AMI message.
243 * \retval 0 to keep AMI connection.
244 * \retval -1 to disconnect AMI connection.
246 static int mwi_mailbox_delete(struct mansession *s, const struct message *m)
248 const char *mailbox_id = astman_get_header(m, "Mailbox");
250 if (ast_strlen_zero(mailbox_id)) {
251 astman_send_error(s, m, "Missing mailbox parameter in request");
255 if (*mailbox_id == '/') {
256 struct ast_str *regex_string;
258 regex_string = ast_str_create(strlen(mailbox_id) + 1);
260 astman_send_error(s, m, "Memory Allocation Failure");
264 /* Make "/regex/" into "regex" */
265 if (ast_regex_string_to_regex_pattern(mailbox_id, ®ex_string) != 0) {
266 astman_send_error_va(s, m, "Mailbox regex format invalid in: %s", mailbox_id);
267 ast_free(regex_string);
271 ast_mwi_mailbox_delete_by_regex(ast_str_buffer(regex_string));
272 ast_free(regex_string);
274 ast_mwi_mailbox_delete(mailbox_id);
277 astman_send_ack(s, m, NULL);
283 * \brief Update the specified mailbox.
286 * \param s AMI session.
287 * \param m AMI message.
289 * \retval 0 to keep AMI connection.
290 * \retval -1 to disconnect AMI connection.
292 static int mwi_mailbox_update(struct mansession *s, const struct message *m)
294 const char *mailbox_id = astman_get_header(m, "Mailbox");
295 const char *msgs_old = astman_get_header(m, "OldMessages");
296 const char *msgs_new = astman_get_header(m, "NewMessages");
297 struct ast_mwi_mailbox_object *mailbox;
298 unsigned int num_old;
299 unsigned int num_new;
301 if (ast_strlen_zero(mailbox_id)) {
302 astman_send_error(s, m, "Missing mailbox parameter in request");
307 if (!ast_strlen_zero(msgs_old)) {
308 if (sscanf(msgs_old, "%u", &num_old) != 1) {
309 astman_send_error_va(s, m, "Invalid OldMessages: %s", msgs_old);
315 if (!ast_strlen_zero(msgs_new)) {
316 if (sscanf(msgs_new, "%u", &num_new) != 1) {
317 astman_send_error_va(s, m, "Invalid NewMessages: %s", msgs_new);
322 mailbox = ast_mwi_mailbox_alloc(mailbox_id);
324 astman_send_error(s, m, "Mailbox object creation failure");
328 /* Update external mailbox. */
329 ast_mwi_mailbox_set_msgs_old(mailbox, num_old);
330 ast_mwi_mailbox_set_msgs_new(mailbox, num_new);
331 if (ast_mwi_mailbox_update(mailbox)) {
332 astman_send_error(s, m, "Update attempt failed");
334 astman_send_ack(s, m, NULL);
336 ast_mwi_mailbox_unref(mailbox);
341 static int unload_module(void)
343 ast_manager_unregister("MWIGet");
344 ast_manager_unregister("MWIDelete");
345 ast_manager_unregister("MWIUpdate");
347 /* Must be done last */
348 ast_mwi_external_unref();
352 static int load_module(void)
356 /* Must be done first */
357 ast_mwi_external_ref();
360 res |= ast_manager_register_xml_core("MWIGet", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, mwi_mailbox_get);
361 res |= ast_manager_register_xml_core("MWIDelete", EVENT_FLAG_CALL, mwi_mailbox_delete);
362 res |= ast_manager_register_xml_core("MWIUpdate", EVENT_FLAG_CALL, mwi_mailbox_update);
365 return AST_MODULE_LOAD_DECLINE;
368 return AST_MODULE_LOAD_SUCCESS;
371 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "AMI support for external MWI",
372 .support_level = AST_MODULE_SUPPORT_CORE,
374 .unload = unload_module,