Add VM_INFO() dialplan function to gather information about a mailbox.

Deprecates MAILBOX_EXISTS. Provides count, email, exists, fullname,
language, locale, pager, password, tz.

(closes issue ASTERISK-18634)
Patch by: Kris Shaw
Review: https://reviewboard.asterisk.org/r/1568
Reviewed by: Walter Doekes


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@347192 65c4cc65-6c06-0410-ace0-fbb531ad65f3
certified/11.2
Walter Doekes 14 years ago
parent e14f572132
commit fd64bb66f9

@ -74,6 +74,13 @@ Core changes
affect the core console verbosity, 'remote set verbose' will now set a
separate level for each remote console without affecting any other console.
Dialplan functions
------------------
* Addition of the VM_INFO function that can be used to retrieve voicemail
user information, such as the email address and full name.
The MAILBOX_EXISTS dialplan function has been deprecated in favour of
VM_INFO.
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 1.8 to Asterisk 10 -------------------
------------------------------------------------------------------------------

@ -22,6 +22,10 @@
From 10 to 11:
Dialplan Functions:
- MAILBOX_EXISTS has been deprecated. Use VM_INFO with the 'exists' parameter
instead.
func_enum:
- ENUM query functions now return a count of -1 on lookup error to
differentiate between a failed query and a successful query with 0 results

@ -284,6 +284,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
</parameter>
</syntax>
<description>
<note><para>DEPRECATED. Use VM_INFO(mailbox[@context],exists) instead.</para></note>
<para>Check to see if the specified <replaceable>mailbox</replaceable> exists. If no voicemail
<replaceable>context</replaceable> is specified, the <literal>default</literal> context
will be used.</para>
@ -297,6 +298,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
</variable>
</variablelist>
</description>
<see-also>
<ref type="function">VM_INFO</ref>
</see-also>
</application>
<application name="VMAuthenticate" language="en_US">
<synopsis>
@ -354,10 +358,67 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<parameter name="context" />
</syntax>
<description>
<note><para>DEPRECATED. Use VM_INFO(mailbox[@context],exists) instead.</para></note>
<para>Returns a boolean of whether the corresponding <replaceable>mailbox</replaceable> exists.
If <replaceable>context</replaceable> is not specified, defaults to the <literal>default</literal>
context.</para>
</description>
<see-also>
<ref type="function">VM_INFO</ref>
</see-also>
</function>
<function name="VM_INFO" language="en_US">
<synopsis>
Returns the selected attribute from a mailbox.
</synopsis>
<syntax argsep=",">
<parameter name="mailbox" argsep="@" required="true">
<argument name="mailbox" required="true" />
<argument name="context" />
</parameter>
<parameter name="attribute" required="true">
<optionlist>
<option name="count">
<para>Count of messages in specified <replaceable>folder</replaceable>.
If <replaceable>folder</replaceable> is not specified, defaults to <literal>INBOX</literal>.</para>
</option>
<option name="email">
<para>E-mail address associated with the mailbox.</para>
</option>
<option name="exists">
<para>Returns a boolean of whether the corresponding <replaceable>mailbox</replaceable> exists.</para>
</option>
<option name="fullname">
<para>Full name associated with the mailbox.</para>
</option>
<option name="language">
<para>Mailbox language if overridden, otherwise the language of the channel.</para>
</option>
<option name="locale">
<para>Mailbox locale if overridden, otherwise global locale.</para>
</option>
<option name="pager">
<para>Pager e-mail address associated with the mailbox.</para>
</option>
<option name="password">
<para>Mailbox access password.</para>
</option>
<option name="tz">
<para>Mailbox timezone if overridden, otherwise global timezone</para>
</option>
</optionlist>
</parameter>
<parameter name="folder" required="false">
<para>If not specified, <literal>INBOX</literal> is assumed.</para>
</parameter>
</syntax>
<description>
<para>Returns the selected attribute from the specified <replaceable>mailbox</replaceable>.
If <replaceable>context</replaceable> is not specified, defaults to the <literal>default</literal>
context. Where the <replaceable>folder</replaceable> can be specified, common folders
include <literal>INBOX</literal>, <literal>Old</literal>, <literal>Work</literal>,
<literal>Family</literal> and <literal>Friends</literal>.</para>
</description>
</function>
<manager name="VoicemailUsersList" language="en_US">
<synopsis>
@ -5223,11 +5284,15 @@ static int messagecount(const char *context, const char *mailbox, const char *fo
char sql[PATH_MAX];
char rowdata[20];
struct generic_prepare_struct gps = { .sql = sql, .argc = 0 };
if (!folder)
folder = "INBOX";
/* If no mailbox, return immediately */
if (ast_strlen_zero(mailbox))
if (ast_strlen_zero(mailbox)) {
return 0;
}
if (ast_strlen_zero(folder)) {
folder = "INBOX";
}
obj = ast_odbc_request_obj(odbc_database, 0);
if (obj) {
@ -10975,7 +11040,7 @@ static int vm_box_exists(struct ast_channel *chan, const char *data)
if (!dep_warning) {
dep_warning = 1;
ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${MAILBOX_EXISTS(%s)} instead.\n", (char *) data);
ast_log(AST_LOG_WARNING, "MailboxExists is deprecated. Please use ${VM_INFO(%s,exists)} instead.\n", data);
}
box = ast_strdupa(data);
@ -11005,6 +11070,7 @@ static int acf_mailbox_exists(struct ast_channel *chan, const char *cmd, char *a
AST_APP_ARG(mbox);
AST_APP_ARG(context);
);
static int dep_warning = 0;
AST_NONSTANDARD_APP_ARGS(arg, args, '@');
@ -11013,15 +11079,99 @@ static int acf_mailbox_exists(struct ast_channel *chan, const char *cmd, char *a
return -1;
}
if (!dep_warning) {
dep_warning = 1;
ast_log(AST_LOG_WARNING, "MAILBOX_EXISTS is deprecated. Please use ${VM_INFO(%s,exists)} instead.\n", args);
}
ast_copy_string(buf, find_user(&svm, ast_strlen_zero(arg.context) ? "default" : arg.context, arg.mbox) ? "1" : "0", len);
return 0;
}
static int acf_vm_info(struct ast_channel *chan, const char *cmd, char *args, char *buf, size_t len)
{
struct ast_vm_user *vmu = NULL;
char *tmp, *mailbox, *context, *parse;
int res = 0;
AST_DECLARE_APP_ARGS(arg,
AST_APP_ARG(mailbox_context);
AST_APP_ARG(attribute);
AST_APP_ARG(folder);
);
buf[0] = '\0';
if (ast_strlen_zero(args)) {
ast_log(LOG_ERROR, "VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n");
return -1;
}
parse = ast_strdupa(args);
AST_STANDARD_APP_ARGS(arg, parse);
if (ast_strlen_zero(arg.mailbox_context) || ast_strlen_zero(arg.attribute)) {
ast_log(LOG_ERROR, "VM_INFO requires an argument (<mailbox>[@<context>],attribute[,folder])\n");
return -1;
}
tmp = ast_strdupa(arg.mailbox_context);
mailbox = strsep(&tmp, "@");
context = strsep(&tmp, "");
if (ast_strlen_zero(context)) {
context = "default";
}
vmu = find_user(NULL, context, mailbox);
if (!strncasecmp(arg.attribute, "exists", 5)) {
ast_copy_string(buf, vmu ? "1" : "0", len);
return 0;
}
if (vmu) {
if (!strncasecmp(arg.attribute, "password", 8)) {
ast_copy_string(buf, vmu->password, len);
} else if (!strncasecmp(arg.attribute, "fullname", 8)) {
ast_copy_string(buf, vmu->fullname, len);
} else if (!strncasecmp(arg.attribute, "email", 5)) {
ast_copy_string(buf, vmu->email, len);
} else if (!strncasecmp(arg.attribute, "pager", 5)) {
ast_copy_string(buf, vmu->pager, len);
} else if (!strncasecmp(arg.attribute, "language", 8)) {
ast_copy_string(buf, S_OR(vmu->language, chan->language), len);
} else if (!strncasecmp(arg.attribute, "locale", 6)) {
ast_copy_string(buf, vmu->locale, len);
} else if (!strncasecmp(arg.attribute, "tz", 2)) {
ast_copy_string(buf, vmu->zonetag, len);
} else if (!strncasecmp(arg.attribute, "count", 5)) {
/* If mbxfolder is empty messagecount will default to INBOX */
res = messagecount(context, mailbox, arg.folder);
if (res < 0) {
ast_log(LOG_ERROR, "Unable to retrieve message count for mailbox %s\n", arg.mailbox_context);
return -1;
}
snprintf(buf, len, "%d", res);
} else {
ast_log(LOG_ERROR, "Unknown attribute '%s' for VM_INFO\n", arg.attribute);
return -1;
}
}
return 0;
}
static struct ast_custom_function mailbox_exists_acf = {
.name = "MAILBOX_EXISTS",
.read = acf_mailbox_exists,
};
static struct ast_custom_function vm_info_acf = {
.name = "VM_INFO",
.read = acf_vm_info,
};
static int vmauthenticate(struct ast_channel *chan, const char *data)
{
char *s, *user = NULL, *context = NULL, mailbox[AST_MAX_EXTENSION] = "";
@ -13018,6 +13168,88 @@ cleanup:
return res;
}
AST_TEST_DEFINE(test_voicemail_vm_info)
{
struct ast_vm_user *vmu;
struct ast_channel *chan = NULL;
const char testcontext[] = "test";
const char testmailbox[] = "00000000";
const char vminfo_cmd[] = "VM_INFO";
char vminfo_buf[256], vminfo_args[256];
int res = AST_TEST_PASS;
int test_ret = 0;
int test_counter = 0;
struct {
char *vminfo_test_args;
char *vminfo_expected;
int vminfo_ret;
} test_items[] = {
{ "", "", -1 }, /* Missing argument */
{ "00000000@test,badparam", "", -1 }, /* Wrong argument */
{ "00000000@test", "", -1 }, /* Missing argument */
{ "00000000@test,exists", "1", 0 },
{ "11111111@test,exists", "0", 0 }, /* Invalid mailbox */
{ "00000000@test,email", "vm-info-test@example.net", 0 },
{ "11111111@test,email", "", 0 }, /* Invalid mailbox */
{ "00000000@test,fullname", "Test Framework Mailbox", 0 },
{ "00000000@test,pager", "vm-info-pager-test@example.net", 0 },
{ "00000000@test,locale", "en_US", 0 },
{ "00000000@test,tz", "central", 0 },
{ "00000000@test,language", "en", 0 },
{ "00000000@test,password", "9876", 0 },
};
switch (cmd) {
case TEST_INIT:
info->name = "test_voicemail_vm_info";
info->category = "/apps/app_voicemail/";
info->summary = "VM_INFO unit test";
info->description =
"This tests passing various parameters to VM_INFO";
return AST_TEST_NOT_RUN;
case TEST_EXECUTE:
break;
}
if (!(chan = ast_dummy_channel_alloc())) {
ast_test_status_update(test, "Unable to create dummy channel\n");
return AST_TEST_FAIL;
}
if (!(vmu = find_user(NULL, testcontext, testmailbox)) &&
!(vmu = find_or_create(testcontext, testmailbox))) {
ast_test_status_update(test, "Cannot create vmu structure\n");
chan = ast_channel_unref(chan);
return AST_TEST_FAIL;
}
populate_defaults(vmu);
ast_copy_string(vmu->email, "vm-info-test@example.net", sizeof(vmu->email));
ast_copy_string(vmu->fullname, "Test Framework Mailbox", sizeof(vmu->fullname));
ast_copy_string(vmu->pager, "vm-info-pager-test@example.net", sizeof(vmu->pager));
ast_copy_string(vmu->language, "en", sizeof(vmu->language));
ast_copy_string(vmu->zonetag, "central", sizeof(vmu->zonetag));
ast_copy_string(vmu->locale, "en_US", sizeof(vmu->zonetag));
ast_copy_string(vmu->password, "9876", sizeof(vmu->password));
for (test_counter = 0; test_counter < ARRAY_LEN(test_items); test_counter++) {
ast_copy_string(vminfo_args, test_items[test_counter].vminfo_test_args, sizeof(vminfo_args));
test_ret = acf_vm_info(chan, vminfo_cmd, vminfo_args, vminfo_buf, sizeof(vminfo_buf));
if (strcmp(vminfo_buf, test_items[test_counter].vminfo_expected)) {
ast_test_status_update(test, "VM_INFO respose was: '%s', but expected: '%s'\n", vminfo_buf, test_items[test_counter].vminfo_expected);
res = AST_TEST_FAIL;
}
if (!(test_ret == test_items[test_counter].vminfo_ret)) {
ast_test_status_update(test, "VM_INFO return code was: '%i', but expected '%i'\n", test_ret, test_items[test_counter].vminfo_ret);
res = AST_TEST_FAIL;
}
}
chan = ast_channel_unref(chan);
return res;
}
#endif /* defined(TEST_FRAMEWORK) */
static int reload(void)
@ -13035,6 +13267,7 @@ static int unload_module(void)
res |= ast_unregister_application(app4);
res |= ast_unregister_application(sayname_app);
res |= ast_custom_function_unregister(&mailbox_exists_acf);
res |= ast_custom_function_unregister(&vm_info_acf);
res |= ast_manager_unregister("VoicemailUsersList");
res |= ast_data_unregister(NULL);
#ifdef TEST_FRAMEWORK
@ -13043,6 +13276,7 @@ static int unload_module(void)
res |= AST_TEST_UNREGISTER(test_voicemail_vmuser);
res |= AST_TEST_UNREGISTER(test_voicemail_notify_endl);
res |= AST_TEST_UNREGISTER(test_voicemail_load_config);
res |= AST_TEST_UNREGISTER(test_voicemail_vm_info);
#endif
ast_cli_unregister_multiple(cli_voicemail, ARRAY_LEN(cli_voicemail));
ast_uninstall_vm_functions();
@ -13086,6 +13320,7 @@ static int load_module(void)
res |= ast_register_application_xml(app4, vmauthenticate);
res |= ast_register_application_xml(sayname_app, vmsayname_exec);
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);
#ifdef TEST_FRAMEWORK
res |= AST_TEST_REGISTER(test_voicemail_vmsayname);
@ -13093,6 +13328,7 @@ static int load_module(void)
res |= AST_TEST_REGISTER(test_voicemail_vmuser);
res |= AST_TEST_REGISTER(test_voicemail_notify_endl);
res |= AST_TEST_REGISTER(test_voicemail_load_config);
res |= AST_TEST_REGISTER(test_voicemail_vm_info);
#endif
if (res)

Loading…
Cancel
Save