summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES3
-rw-r--r--apps/app_voicemail.c65
2 files changed, 68 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index e2fea7bc8..83728500e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -17,6 +17,9 @@ AMI (Asterisk Manager Interface)
that the request is against a known peer. It also issues a new event,
'SIPqualifypeerdone', once the qualify action has been completed.
+ * Added VoicemailRefresh action to allow an external entity to trigger mailbox
+ updates when changes occur instead of requiring the use of pollmailboxes.
+
Logging
-------------------
* When performing queue pause/unpause on an interface without specifying an
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 4ee9e4354..5e8b4e86f 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -455,6 +455,33 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<description>
</description>
</manager>
+ <manager name="VoicemailRefresh" language="en_US">
+ <synopsis>
+ Tell Asterisk to poll mailboxes for a change
+ </synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
+ <parameter name="Context" />
+ <parameter name="Mailbox" />
+ </syntax>
+ <description>
+ <para>Normally, MWI indicators are only sent when Asterisk itself
+ changes a mailbox. With external programs that modify the content
+ of a mailbox from outside the application, an option exists called
+ <literal>pollmailboxes</literal> that will cause voicemail to
+ continually scan all mailboxes on a system for changes. This can
+ cause a large amount of load on a system. This command allows
+ external applications to signal when a particular mailbox has
+ changed, thus permitting external applications to modify mailboxes
+ and MWI to work without introducing considerable CPU load.</para>
+ <para>If <replaceable>Context</replaceable> is not specified, all
+ mailboxes on the system will be polled for changes. If
+ <replaceable>Context</replaceable> is specified, but
+ <replaceable>Mailbox</replaceable> is omitted, then all mailboxes
+ within <replaceable>Context</replaceable> will be polled.
+ Otherwise, only a single mailbox will be polled for changes.</para>
+ </description>
+ </manager>
***/
#ifdef IMAP_STORAGE
@@ -12646,6 +12673,42 @@ static void stop_poll_thread(void)
poll_thread = AST_PTHREADT_NULL;
}
+static int manager_voicemail_refresh(struct mansession *s, const struct message *m)
+{
+ const char *context = astman_get_header(m, "Context");
+ const char *mailbox = astman_get_header(m, "Mailbox");
+ struct mwi_sub *mwi_sub;
+ const char *at;
+
+ AST_RWLIST_RDLOCK(&mwi_subs);
+ AST_RWLIST_TRAVERSE(&mwi_subs, mwi_sub, entry) {
+ if (!ast_strlen_zero(mwi_sub->mailbox)) {
+ if (
+ /* First case: everything matches */
+ (ast_strlen_zero(context) && ast_strlen_zero(mailbox)) ||
+ /* Second case: match the mailbox only */
+ (ast_strlen_zero(context) && !ast_strlen_zero(mailbox) &&
+ (at = strchr(mwi_sub->mailbox, '@')) &&
+ strncmp(mailbox, mwi_sub->mailbox, at - mwi_sub->mailbox) == 0) ||
+ /* Third case: match the context only */
+ (!ast_strlen_zero(context) && ast_strlen_zero(mailbox) &&
+ (at = strchr(mwi_sub->mailbox, '@')) &&
+ strcmp(context, at + 1) == 0) ||
+ /* Final case: match an exact specified mailbox */
+ (!ast_strlen_zero(context) && !ast_strlen_zero(mailbox) &&
+ (at = strchr(mwi_sub->mailbox, '@')) &&
+ strncmp(mailbox, mwi_sub->mailbox, at - mwi_sub->mailbox) == 0 &&
+ strcmp(context, at + 1) == 0)
+ ) {
+ poll_subscribed_mailbox(mwi_sub);
+ }
+ }
+ }
+ AST_RWLIST_UNLOCK(&mwi_subs);
+ astman_send_ack(s, m, "Refresh sent");
+ return RESULT_SUCCESS;
+}
+
/*! \brief Manager list voicemail users command */
static int manager_list_voicemail_users(struct mansession *s, const struct message *m)
{
@@ -14185,6 +14248,7 @@ static int unload_module(void)
res |= ast_custom_function_unregister(&mailbox_exists_acf);
res |= ast_custom_function_unregister(&vm_info_acf);
res |= ast_manager_unregister("VoicemailUsersList");
+ res |= ast_manager_unregister("VoicemailRefresh");
res |= ast_data_unregister(NULL);
#ifdef TEST_FRAMEWORK
res |= AST_TEST_UNREGISTER(test_voicemail_vmsayname);
@@ -14242,6 +14306,7 @@ static int load_module(void)
res |= ast_custom_function_register(&mailbox_exists_acf);
res |= ast_custom_function_register(&vm_info_acf);
res |= ast_manager_register_xml("VoicemailUsersList", EVENT_FLAG_CALL | EVENT_FLAG_REPORTING, manager_list_voicemail_users);
+ res |= ast_manager_register_xml("VoicemailRefresh", EVENT_FLAG_USER, manager_voicemail_refresh);
#ifdef TEST_FRAMEWORK
res |= AST_TEST_REGISTER(test_voicemail_vmsayname);
res |= AST_TEST_REGISTER(test_voicemail_msgcount);