From 5bde2dbc34abee5c149de9534acd2cc3a5b39697 Mon Sep 17 00:00:00 2001 From: Kinsey Moore Date: Thu, 27 Sep 2012 17:02:13 +0000 Subject: Add VoicemailRefresh AMI Action Currently, if there are modifications to mailboxes that Asterisk is not aware of, the user needs to add "pollmailboxes" to their mailbox configuration, which repeatedly polls the subscribed mailboxes for changes. This results in a lot of extra work for the CPU. This patch introduces the AMI command VoicemailRefresh which permits external applications to trigger the refresh themselves. The refresh can apply to a specified mailbox only, an entire context, or all configured mailboxes. Even a refresh performed on every mailbox would not consume as much CPU as the pollmailboxes option, given that pollmailboxes runs continuously and this only runs on demand. (closes issue ASTERISK-17206) (closes issue ASTERISK-19908) Reported-by: Jeff Hutchins Reported-by: Tilghman Lesher Patch-by: Tilghman Lesher git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@373913 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CHANGES | 3 +++ apps/app_voicemail.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) 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$") + + + Tell Asterisk to poll mailboxes for a change + + + + + + + + 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 + pollmailboxes 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. + If Context is not specified, all + mailboxes on the system will be polled for changes. If + Context is specified, but + Mailbox is omitted, then all mailboxes + within Context will be polled. + Otherwise, only a single mailbox will be polled for changes. + + ***/ #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); -- cgit v1.2.3