[Asterisk-code-review] app voicemail: Add Mailbox Aliases (asterisk[13])
George Joseph
asteriskteam at digium.com
Tue Dec 11 14:07:15 CST 2018
George Joseph has uploaded this change for review. ( https://gerrit.asterisk.org/10799
Change subject: app_voicemail: Add Mailbox Aliases
......................................................................
app_voicemail: Add Mailbox Aliases
You can now define an "aliases" context in voicemail.conf
whose entries point to actual mailboxes. These can be used anywhere
the mailbox is specified.
Example:
[default]
1234 at default = yadayada
[aliases]
4321 at devices = 1234 at default
Now you can use 4321 at devices to refer to the 1234 at default mailbox.
Change-Id: I395b9205c91523a334fe971be0d1de4522067b04
---
M CHANGES
M apps/app_voicemail.c
M configs/samples/voicemail.conf.sample
M res/res_pjsip_mwi.c
4 files changed, 231 insertions(+), 44 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/99/10799/1
diff --git a/CHANGES b/CHANGES
index 6e87611..25f811e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,15 @@
==============================================================================
------------------------------------------------------------------------------
+--- Functionality changes from Asterisk 13.24.0 to Asterisk 13.25.0 ----------
+------------------------------------------------------------------------------
+
+app_voicemail
+------------------
+ * You can now specify a special context named "aliases" in voicemail.conf
+ which will allow you to create aliases for physical mailboxes.
+
+------------------------------------------------------------------------------
--- Functionality changes from Asterisk 13.23.0 to Asterisk 13.24.0 ----------
------------------------------------------------------------------------------
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 85e1c38..03b2320 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -1036,6 +1036,27 @@
static AST_RWLIST_HEAD_STATIC(mwi_subs, mwi_sub);
+struct alias_mailbox_mapping {
+ char *alias;
+ char *mailbox;
+ char buf[0];
+};
+
+struct mailbox_alias_mapping {
+ char *alias;
+ char *mailbox;
+ char buf[0];
+};
+
+#define MAPPING_BUCKETS 511
+static struct ao2_container *alias_mailbox_mappings;
+AO2_STRING_FIELD_HASH_FN(alias_mailbox_mapping, alias);
+AO2_STRING_FIELD_CMP_FN(alias_mailbox_mapping, alias);
+
+static struct ao2_container *mailbox_alias_mappings;
+AO2_STRING_FIELD_HASH_FN(mailbox_alias_mapping, mailbox);
+AO2_STRING_FIELD_CMP_FN(mailbox_alias_mapping, mailbox);
+
/* custom audio control prompts for voicemail playback */
static char listen_control_forward_key[12];
static char listen_control_reverse_key[12];
@@ -1748,9 +1769,31 @@
ast_set2_flag(vmu, !ivm, VM_ALLOCED);
AST_LIST_NEXT(vmu, list) = NULL;
}
- } else
- vmu = find_user_realtime(ivm, context, mailbox);
+ }
AST_LIST_UNLOCK(&users);
+ if (!vmu) {
+ vmu = find_user_realtime(ivm, context, mailbox);
+ }
+ if (!vmu) {
+ struct alias_mailbox_mapping *mapping;
+ size_t len = sizeof(vmu->mailbox) + sizeof(vmu->context) + sizeof('@') + 1;
+ char *search_string = ast_alloca(len);
+
+ len = snprintf(search_string, len, "%s%s%s",
+ mailbox,
+ ast_strlen_zero(context) ? "" : "@",
+ S_OR(context, ""));
+
+ mapping = ao2_find(alias_mailbox_mappings, search_string, OBJ_SEARCH_KEY);
+ if (mapping) {
+ char *search_mailbox;
+ char *search_context;
+
+ separate_mailbox(ast_strdupa(mapping->mailbox), &search_mailbox, &search_context);
+ vmu = find_user(ivm, search_mailbox, search_context);
+ }
+ }
+
return vmu;
}
@@ -6029,7 +6072,11 @@
DIR *dir;
struct dirent *de;
char fn[256];
+ char tmp[256];
int ret = 0;
+ struct alias_mailbox_mapping *mapping;
+ char *c;
+ char *m;
/* If no mailbox, return immediately */
if (ast_strlen_zero(mailbox))
@@ -6040,7 +6087,17 @@
if (ast_strlen_zero(context))
context = "default";
- snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, context, mailbox, folder);
+ snprintf(tmp, sizeof(tmp), "%s@%s", mailbox, context);
+ mapping = ao2_find(alias_mailbox_mappings, tmp, OBJ_SEARCH_KEY);
+ if (mapping) {
+ separate_mailbox(ast_strdupa(mapping->mailbox), &m, &c);
+ ao2_ref(mapping, -1);
+ } else {
+ c = (char *)context;
+ m = (char *)mailbox;
+ }
+
+ snprintf(fn, sizeof(fn), "%s%s/%s/%s", VM_SPOOL_DIR, c, m, folder);
if (!(dir = opendir(fn)))
return 0;
@@ -8046,12 +8103,26 @@
{
char *mailbox;
char *context;
+ struct ao2_iterator *aliases;
+ struct mailbox_alias_mapping *mapping;
if (separate_mailbox(ast_strdupa(box), &mailbox, &context)) {
return;
}
+ ast_debug(3, "Queueing event for mailbox %s\n", box);
ast_publish_mwi_state_channel(mailbox, context, new + urgent, old, channel_id);
+
+ aliases = ao2_find(mailbox_alias_mappings, box, OBJ_SEARCH_KEY | OBJ_MULTIPLE);
+ while ((mapping = ao2_iterator_next(aliases))) {
+ mailbox = NULL;
+ context = NULL;
+ ast_debug(3, "Found alias mapping: %s -> %s\n", mapping->alias, box);
+ separate_mailbox(ast_strdupa(mapping->alias), &mailbox, &context);
+ ast_publish_mwi_state_channel(mailbox, context, new + urgent, old, channel_id);
+ ao2_ref(mapping, -1);
+ }
+ ao2_iterator_destroy(aliases);
}
/*!
@@ -13261,7 +13332,6 @@
if (stasis_message_type(msg) != stasis_subscription_change_type()) {
return;
}
-
change = stasis_message_data(msg);
if (change->topic == ast_mwi_topic_all()) {
return;
@@ -13603,11 +13673,95 @@
}
#endif
+static struct alias_mailbox_mapping *alias_mailbox_mapping_create(const char *alias, const char *mailbox)
+{
+ struct alias_mailbox_mapping *mapping;
+ size_t from_len = strlen(alias) + 1;
+ size_t to_len = strlen(mailbox) + 1;
+
+ mapping = ao2_alloc(sizeof(*mapping) + from_len + to_len, NULL);
+ if (!mapping) {
+ return NULL;
+ }
+ mapping->alias = mapping->buf;
+ mapping->mailbox = mapping->buf + from_len;
+ strcpy(mapping->alias, alias); /* Safe */
+ strcpy(mapping->mailbox, mailbox); /* Safe */
+
+ return mapping;
+}
+
+static void load_aliases(struct ast_config *cfg)
+{
+ struct ast_variable *var;
+
+ var = ast_variable_browse(cfg, "aliases");
+ while (var) {
+ struct alias_mailbox_mapping *mapping = alias_mailbox_mapping_create(var->name, var->value);
+ if (mapping) {
+ ao2_link(alias_mailbox_mappings, mapping);
+ ao2_link(mailbox_alias_mappings, mapping);
+ ao2_ref(mapping, -1);
+ }
+ var = var->next;
+ }
+}
+
+static void load_zonemessages(struct ast_config *cfg)
+{
+ struct ast_variable *var;
+
+ var = ast_variable_browse(cfg, "zonemessages");
+ while (var) {
+ struct vm_zone *z;
+ char *msg_format, *tzone;
+
+ z = ast_malloc(sizeof(*z));
+ if (!z) {
+ return;
+ }
+
+ msg_format = ast_strdupa(var->value);
+ tzone = strsep(&msg_format, "|,");
+ if (msg_format) {
+ ast_copy_string(z->name, var->name, sizeof(z->name));
+ ast_copy_string(z->timezone, tzone, sizeof(z->timezone));
+ ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
+ AST_LIST_LOCK(&zones);
+ AST_LIST_INSERT_HEAD(&zones, z, list);
+ AST_LIST_UNLOCK(&zones);
+ } else {
+ ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
+ ast_free(z);
+ }
+ var = var->next;
+ }
+}
+
+static void load_users(struct ast_config *cfg)
+{
+ struct ast_variable *var;
+ char *cat = NULL;
+
+ while ((cat = ast_category_browse(cfg, cat))) {
+ if (strcasecmp(cat, "general") == 0
+ || strcasecmp(cat, "aliases") == 0
+ || strcasecmp(cat, "zonemessages") == 0) {
+ continue;
+ }
+
+ var = ast_variable_browse(cfg, cat);
+ while (var) {
+ append_mailbox(cat, var->name, var->value);
+ var = var->next;
+ }
+ }
+}
+
static int actual_load_config(int reload, struct ast_config *cfg, struct ast_config *ucfg)
{
struct ast_vm_user *current;
char *cat;
- struct ast_variable *var;
const char *val;
char *q, *stringp, *tmp;
int x;
@@ -13636,6 +13790,10 @@
/* Free all the zones structure */
free_vm_zones();
+ /* Remove all aliases */
+ ao2_callback(alias_mailbox_mappings, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
+ ao2_callback(mailbox_alias_mappings, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
+
AST_LIST_LOCK(&users);
memset(ext_pass_cmd, 0, sizeof(ext_pass_cmd));
@@ -14248,45 +14406,16 @@
}
/* load mailboxes from voicemail.conf */
- cat = ast_category_browse(cfg, NULL);
- while (cat) {
- if (strcasecmp(cat, "general")) {
- var = ast_variable_browse(cfg, cat);
- if (strcasecmp(cat, "zonemessages")) {
- /* Process mailboxes in this context */
- while (var) {
- append_mailbox(cat, var->name, var->value);
- var = var->next;
- }
- } else {
- /* Timezones in this context */
- while (var) {
- struct vm_zone *z;
- if ((z = ast_malloc(sizeof(*z)))) {
- char *msg_format, *tzone;
- msg_format = ast_strdupa(var->value);
- tzone = strsep(&msg_format, "|,");
- if (msg_format) {
- ast_copy_string(z->name, var->name, sizeof(z->name));
- ast_copy_string(z->timezone, tzone, sizeof(z->timezone));
- ast_copy_string(z->msg_format, msg_format, sizeof(z->msg_format));
- AST_LIST_LOCK(&zones);
- AST_LIST_INSERT_HEAD(&zones, z, list);
- AST_LIST_UNLOCK(&zones);
- } else {
- ast_log(AST_LOG_WARNING, "Invalid timezone definition at line %d\n", var->lineno);
- ast_free(z);
- }
- } else {
- AST_LIST_UNLOCK(&users);
- return -1;
- }
- var = var->next;
- }
- }
- }
- cat = ast_category_browse(cfg, cat);
- }
+
+ /*
+ * Aliases must be loaded before users or the aliases won't be notified
+ * if there's existing voicemail in the user mailbox.
+ */
+ load_aliases(cfg);
+
+ load_zonemessages(cfg);
+
+ load_users(cfg);
AST_LIST_UNLOCK(&users);
@@ -15037,6 +15166,16 @@
return res;
}
+static void print_mappings(void *v_obj, void *where, ao2_prnt_fn *prnt)
+{
+ struct alias_mailbox_mapping *mapping = v_obj;
+
+ if (!mapping) {
+ return;
+ }
+ prnt(where, "Alias: %s Mailbox: %s", mapping->alias, mapping->mailbox);
+}
+
/*!
* \brief Load the module
*
@@ -15063,6 +15202,38 @@
return AST_MODULE_LOAD_DECLINE;
}
+ alias_mailbox_mappings = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, MAPPING_BUCKETS,
+ alias_mailbox_mapping_hash_fn, NULL, alias_mailbox_mapping_cmp_fn);
+ if (!alias_mailbox_mappings) {
+ ast_log(LOG_ERROR, "Unable to create alias_mailbox_mappings container\n");
+ ao2_cleanup(inprocess_container);
+ return AST_MODULE_LOAD_DECLINE;
+ }
+ res = ao2_container_register("voicemail_alias_mailbox_mappings", alias_mailbox_mappings, print_mappings);
+ if (res) {
+ ast_log(LOG_ERROR, "Unable to register alias_mailbox_mappings container\n");
+ ao2_cleanup(inprocess_container);
+ ao2_cleanup(alias_mailbox_mappings);
+ return AST_MODULE_LOAD_DECLINE;
+ }
+
+ mailbox_alias_mappings = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, MAPPING_BUCKETS,
+ mailbox_alias_mapping_hash_fn, NULL, mailbox_alias_mapping_cmp_fn);
+ if (!mailbox_alias_mappings) {
+ ast_log(LOG_ERROR, "Unable to create mailbox_alias_mappings container\n");
+ ao2_cleanup(inprocess_container);
+ ao2_cleanup(alias_mailbox_mappings);
+ return AST_MODULE_LOAD_DECLINE;
+ }
+ res = ao2_container_register("voicemail_mailbox_alias_mappings", mailbox_alias_mappings, print_mappings);
+ if (res) {
+ ast_log(LOG_ERROR, "Unable to register mailbox_alias_mappings container\n");
+ ao2_cleanup(inprocess_container);
+ ao2_cleanup(alias_mailbox_mappings);
+ ao2_cleanup(mailbox_alias_mappings);
+ return AST_MODULE_LOAD_DECLINE;
+ }
+
/* compute the location of the voicemail spool directory */
snprintf(VM_SPOOL_DIR, sizeof(VM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR);
diff --git a/configs/samples/voicemail.conf.sample b/configs/samples/voicemail.conf.sample
index e4130d3..aae1eda 100644
--- a/configs/samples/voicemail.conf.sample
+++ b/configs/samples/voicemail.conf.sample
@@ -452,6 +452,11 @@
;4235 => 1234,Jim Holmes,jim at astricon.ips,,Tz=european
+; aliases allow alternate references to mailboxes.
+[aliases]
+1234 at devices => 1234 at default
+;6200 at devices => 4200 at default
+
;
; Mailboxes may be organized into multiple contexts for
; voicemail virtualhosting
diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c
index 5622515..3a43f96 100644
--- a/res/res_pjsip_mwi.c
+++ b/res/res_pjsip_mwi.c
@@ -436,6 +436,7 @@
struct ast_sip_message_accumulator *counter = arg;
struct ast_mwi_state *mwi_state;
+ ast_debug(2, "Searching for %s\n", mwi_stasis->mailbox);
msg = stasis_cache_get(ast_mwi_state_cache(), ast_mwi_state_type(), mwi_stasis->mailbox);
if (!msg) {
return 0;
@@ -444,6 +445,7 @@
mwi_state = stasis_message_data(msg);
counter->old_msgs += mwi_state->old_msgs;
counter->new_msgs += mwi_state->new_msgs;
+ ast_debug(2, "Found %s Old: %d New: %d\n", mwi_stasis->mailbox, counter->old_msgs, counter->new_msgs);
ao2_ref(msg, -1);
--
To view, visit https://gerrit.asterisk.org/10799
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-MessageType: newchange
Gerrit-Change-Id: I395b9205c91523a334fe971be0d1de4522067b04
Gerrit-Change-Number: 10799
Gerrit-PatchSet: 1
Gerrit-Owner: George Joseph <gjoseph at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20181211/78ec0872/attachment-0001.html>
More information about the asterisk-code-review
mailing list