Review Board 1.7.16


Voicemail check cleanup

Review Request #525 - Created Feb. 23, 2010 and submitted

Tilghman Lesher
/trunk
15654, 16448
Reviewers
asterisk-dev
Asterisk
A few cleanups to fix a few bugs.

- Urgent voicemails were not attached, because the attachment code looked in the wrong folder.
- Urgent voicemails were sometimes counted twice when displaying the count of new messages.
- Backends were inconsistent as to which voicemails each API counted.
Unit test written, tested, and included.

Changes between revision 1 and 2

1 2 3
1 2 3

  1. /trunk/apps/app_voicemail.c: Loading...
  2. /trunk/include/asterisk/app.h: Loading...
  3. /trunk/res/res_agi.c: Loading...
/trunk/apps/app_voicemail.c
Diff Revision 1 Diff Revision 2
[20] 112 lines
[+20] [+] ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
113
#include "asterisk/stringfields.h"
113
#include "asterisk/stringfields.h"
114
#include "asterisk/smdi.h"
114
#include "asterisk/smdi.h"
115
#include "asterisk/astobj2.h"
115
#include "asterisk/astobj2.h"
116
#include "asterisk/event.h"
116
#include "asterisk/event.h"
117
#include "asterisk/taskprocessor.h"
117
#include "asterisk/taskprocessor.h"

    
   
118
#include "asterisk/test.h"
118

    
   
119

   
119
#ifdef ODBC_STORAGE
120
#ifdef ODBC_STORAGE
120
#include "asterisk/res_odbc.h"
121
#include "asterisk/res_odbc.h"
121
#endif
122
#endif
122

    
   
123

   
[+20] [20] 2126 lines
[+20] [+] static int inboxcount2(const char *mailbox_context, int *urgentmsgs, int *newmsgs, int *oldmsgs)
2249
static int has_voicemail(const char *mailbox, const char *folder)
2250
static int has_voicemail(const char *mailbox, const char *folder)
2250
{
2251
{
2251
	char tmp[256], *tmp2, *box, *context;
2252
	char tmp[256], *tmp2, *box, *context;
2252
	ast_copy_string(tmp, mailbox, sizeof(tmp));
2253
	ast_copy_string(tmp, mailbox, sizeof(tmp));
2253
	tmp2 = tmp;
2254
	tmp2 = tmp;
2254
	if (strchr(tmp2, ',')) {
2255
	if (strchr(tmp2, ',') || strchr(tmp2, '&')) {
2255
		while ((box = strsep(&tmp2, ",&"))) {
2256
		while ((box = strsep(&tmp2, ",&"))) {
2256
			if (!ast_strlen_zero(box)) {
2257
			if (!ast_strlen_zero(box)) {
2257
				if (has_voicemail(box, folder)) {
2258
				if (has_voicemail(box, folder)) {
2258
					return 1;
2259
					return 1;
2259
				}
2260
				}
[+20] [20] 2735 lines
[+20] [+] yuck:
4995
 */
4996
 */
4996
static int has_voicemail(const char *mailbox, const char *folder)
4997
static int has_voicemail(const char *mailbox, const char *folder)
4997
{
4998
{
4998
	char tmp[256], *tmp2 = tmp, *box, *context;
4999
	char tmp[256], *tmp2 = tmp, *box, *context;
4999
	ast_copy_string(tmp, mailbox, sizeof(tmp));
5000
	ast_copy_string(tmp, mailbox, sizeof(tmp));
5000
	while ((context = box = strsep(&tmp2, ","))) {
5001
	while ((context = box = strsep(&tmp2, ",&"))) {
5001
		strsep(&context, "@");
5002
		strsep(&context, "@");
5002
		if (ast_strlen_zero(context))
5003
		if (ast_strlen_zero(context))
5003
			context = "default";
5004
			context = "default";
5004
		if (messagecount(context, box, folder))
5005
		if (messagecount(context, box, folder))
5005
			return 1;
5006
			return 1;
[+20] [20] 68 lines
[+20] [+] static int copy_message(struct ast_channel *chan, struct ast_vm_user *vmu, int imbox, int msgnum, long duration, struct ast_vm_user *recip, char *fmt, char *dir, const char *flag)
5074
#endif
5075
#endif
5075
#if !(defined(IMAP_STORAGE) || defined(ODBC_STORAGE))
5076
#if !(defined(IMAP_STORAGE) || defined(ODBC_STORAGE))
5076

    
   
5077

   
5077
static int messagecount(const char *context, const char *mailbox, const char *folder)
5078
static int messagecount(const char *context, const char *mailbox, const char *folder)
5078
{
5079
{
5079
	return __has_voicemail(context, mailbox, folder, 0) + strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0);
5080
	return __has_voicemail(context, mailbox, folder, 0) + (strcmp(folder, "INBOX") ? 0 : __has_voicemail(context, mailbox, "Urgent", 0));
5080
}
5081
}
5081

    
   
5082

   
5082
static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
5083
static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
5083
{
5084
{
5084
	DIR *dir;
5085
	DIR *dir;
[+20] [20] 19 lines
[+20] static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
5104
		if (!strncasecmp(de->d_name, "msg", 3)) {
5105
		if (!strncasecmp(de->d_name, "msg", 3)) {
5105
			if (shortcircuit) {
5106
			if (shortcircuit) {
5106
				ret = 1;
5107
				ret = 1;
5107
				break;
5108
				break;
5108
			} else if (!strncasecmp(de->d_name + 8, "txt", 3)) {
5109
			} else if (!strncasecmp(de->d_name + 8, "txt", 3)) {
5109
				if (shortcircuit) return 1;

   
5110
				ret++;
5110
				ret++;
5111
			}
5111
			}
5112
		}
5112
		}
5113
	}
5113
	}
5114

    
   
5114

   
[+20] [20] 13 lines
[+20] static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
5128
 */
5128
 */
5129
static int has_voicemail(const char *mailbox, const char *folder)
5129
static int has_voicemail(const char *mailbox, const char *folder)
5130
{
5130
{
5131
	char tmp[256], *tmp2 = tmp, *box, *context;
5131
	char tmp[256], *tmp2 = tmp, *box, *context;
5132
	ast_copy_string(tmp, mailbox, sizeof(tmp));
5132
	ast_copy_string(tmp, mailbox, sizeof(tmp));
5133
	while ((box = strsep(&tmp2, ","))) {
5133
	while ((box = strsep(&tmp2, ",&"))) {
5134
		if ((context = strchr(box, '@')))
5134
		if ((context = strchr(box, '@')))
5135
			*context++ = '\0';
5135
			*context++ = '\0';
5136
		else
5136
		else
5137
			context = "default";
5137
			context = "default";
5138
		if (__has_voicemail(context, box, folder, 1))
5138
		if (__has_voicemail(context, box, folder, 1))
[+20] [20] 6447 lines
[+20] [+] static int write_password_to_file(const char *secretfn, const char *password) {
11586
		return -1;
11586
		return -1;
11587
	}
11587
	}
11588
	return 0;
11588
	return 0;
11589
}
11589
}
11590

    
   
11590

   

    
   
11591
AST_TEST_DEFINE(test_voicemail_msgcount)

    
   
11592
{

    
   
11593
	int i, j, res = AST_TEST_PASS;

    
   
11594
	struct ast_vm_user *vmu;

    
   
11595
	struct vm_state vms;

    
   
11596
	struct {

    
   
11597
		char dir[256];

    
   
11598
		char file[256];

    
   
11599
		char txtfile[256];

    
   
11600
	} tmp[3];

    
   
11601
	char syscmd[256];

    
   
11602
	const char origweasels[] = "tt-weasels";

    
   
11603
	const char testcontext[] = "test";

    
   
11604
	const char testmailbox[] = "00000000";

    
   
11605
	const char testspec[] = "00000000@test";

    
   
11606
	FILE *txt;

    
   
11607
	int new, old, urgent;

    
   
11608
	const char *folders[3] = { "Old", "Urgent", "INBOX" };

    
   
11609
	const int folder2mbox[3] = { 1, 11, 0 };

    
   
11610
	const int expected_results[3][12] = {

    
   
11611
		/* hasvm-old, hasvm-urgent, hasvm-new, ic-old, ic-urgent, ic-new, ic2-old, ic2-urgent, ic2-new, mc-old, mc-urgent, mc-new */

    
   
11612
		{          1,            0,         0,      1,         0,      0,       1,          0,       0,      1,         0,      0 },

    
   
11613
		{          1,            1,         1,      1,         0,      1,       1,          1,       0,      1,         1,      1 },

    
   
11614
		{          1,            1,         1,      1,         0,      2,       1,          1,       1,      1,         1,      2 },

    
   
11615
	};

    
   
11616

   

    
   
11617
	switch (cmd) {

    
   
11618
	case TEST_INIT:

    
   
11619
		info->name = "test_voicemail_msgcount";

    
   
11620
		info->category = "apps/app_voicemail/";

    
   
11621
		info->summary = "Test Voicemail status checks";

    
   
11622
		info->description =

    
   
11623
			"Verify that message counts are correct when retrieved through the public API";

    
   
11624
		return AST_TEST_NOT_RUN;

    
   
11625
	case TEST_EXECUTE:

    
   
11626
		break;

    
   
11627
	}

    
   
11628

   

    
   
11629
	/* Make sure the original path was completely empty */

    
   
11630
	create_dirpath(tmp[0].dir, sizeof(tmp[0].dir), testcontext, testmailbox, "");

    
   
11631
	snprintf(tmp[0].file, sizeof(tmp[0].file), "rm -rf %s", tmp[0].dir);

    
   
11632
	i = system(tmp[0].file);

    
   
11633

   

    
   
11634
	if (!(vmu = find_user(NULL, testcontext, testmailbox)) &&

    
   
11635
		!(vmu = find_or_create(testcontext, testmailbox))) {

    
   
11636
		ast_test_status_update(test, "Cannot create vmu structure\n");

    
   
11637
		return AST_TEST_NOT_RUN;

    
   
11638
	}

    
   
11639

   

    
   
11640
	populate_defaults(vmu);

    
   
11641
	memset(&vms, 0, sizeof(vms));

    
   
11642

   

    
   
11643
	/* Create temporary voicemail */

    
   
11644
	for (i = 0; i < 3; i++) {

    
   
11645
		create_dirpath(tmp[i].dir, sizeof(tmp[i].dir), testcontext, testmailbox, folders[i]);

    
   
11646
		make_file(tmp[i].file, sizeof(tmp[i].file), tmp[i].dir, 0);

    
   
11647
		snprintf(tmp[i].txtfile, sizeof(tmp[i].txtfile), "%s.txt", tmp[i].file);

    
   
11648

   

    
   
11649
		if (ast_fileexists(origweasels, "gsm", "en") > 0) {

    
   
11650
			snprintf(syscmd, sizeof(syscmd), "cp %s/sounds/en/%s.gsm %s/%s/%s/%s/msg0000.gsm", ast_config_AST_DATA_DIR, origweasels,

    
   
11651
				VM_SPOOL_DIR, testcontext, testmailbox, folders[i]);

    
   
11652
			j = system(syscmd);

    
   
11653
		}

    
   
11654

   

    
   
11655
		if ((txt = fopen(tmp[i].txtfile, "w+"))) {

    
   
11656
			fprintf(txt, "; just a stub\n[message]\nflag=%s\n", strcmp(folders[i], "Urgent") ? "" : "Urgent");

    
   
11657
			fclose(txt);

    
   
11658
		} else {

    
   
11659
			ast_test_status_update(test, "Unable to write message file '%s'\n", tmp[i].txtfile);

    
   
11660
			res = AST_TEST_FAIL;

    
   
11661
			break;

    
   
11662
		}

    
   
11663
		open_mailbox(&vms, vmu, folder2mbox[i]);

    
   
11664
		STORE(tmp[i].dir, testmailbox, testcontext, 0, NULL, vmu, "gsm", 600, &vms, strcmp(folders[i], "Urgent") ? "" : "Urgent");

    
   
11665

   

    
   
11666
		/* hasvm-old, hasvm-urgent, hasvm-new, ic-old, ic-urgent, ic-new, ic2-old, ic2-urgent, ic2-new, mc-old, mc-urgent, mc-new */

    
   
11667
		for (j = 0; j < 3; j++) {

    
   
11668
			if (ast_app_has_voicemail(testspec, folders[j]) != expected_results[i][0 + j]) {

    
   
11669
				ast_test_status_update(test, "has_voicemail(%s, %s) returned %d and we expected %d\n",

    
   
11670
					testspec, folders[j], ast_app_has_voicemail(testspec, folders[j]), expected_results[i][0 + j]);

    
   
11671
				res = AST_TEST_FAIL;

    
   
11672
			}

    
   
11673
		}

    
   
11674

   

    
   
11675
		new = old = urgent = 0;

    
   
11676
		if (ast_app_inboxcount(testspec, &new, &old)) {

    
   
11677
			ast_test_status_update(test, "inboxcount returned failure\n");

    
   
11678
			res = AST_TEST_FAIL;

    
   
11679
		} else if (old != expected_results[i][3 + 0] || new != expected_results[i][3 + 2]) {

    
   
11680
			ast_test_status_update(test, "inboxcount(%s) returned old=%d (expected %d) and new=%d (expected %d)\n",

    
   
11681
				testspec, old, expected_results[i][3 + 0], new, expected_results[i][3 + 2]);

    
   
11682
			res = AST_TEST_FAIL;

    
   
11683
		}

    
   
11684

   

    
   
11685
		new = old = urgent = 0;

    
   
11686
		if (ast_app_inboxcount2(testspec, &urgent, &new, &old)) {

    
   
11687
			ast_test_status_update(test, "inboxcount2 returned failure\n");

    
   
11688
			res = AST_TEST_FAIL;

    
   
11689
		} else if (old != expected_results[i][6 + 0] ||

    
   
11690
				urgent != expected_results[i][6 + 1] ||

    
   
11691
				   new != expected_results[i][6 + 2]    ) {

    
   
11692
			ast_test_status_update(test, "inboxcount2(%s) returned old=%d (expected %d), urgent=%d (expected %d), and new=%d (expected %d)\n",

    
   
11693
				testspec, old, expected_results[i][5 + 0], urgent, expected_results[i][5 + 1], new, expected_results[i][5 + 2]);

    
   
11694
			res = AST_TEST_FAIL;

    
   
11695
		}

    
   
11696

   

    
   
11697
		new = old = urgent = 0;

    
   
11698
		for (j = 0; j < 3; j++) {

    
   
11699
			if (ast_app_messagecount(testcontext, testmailbox, folders[j]) != expected_results[i][9 + j]) {

    
   
11700
				ast_test_status_update(test, "messagecount(%s, %s) returned %d and we expected %d\n",

    
   
11701
					testspec, folders[j], ast_app_messagecount(testcontext, testmailbox, folders[j]), expected_results[i][9 + j]);

    
   
11702
				res = AST_TEST_FAIL;

    
   
11703
			}

    
   
11704
		}

    
   
11705
	}

    
   
11706

   

    
   
11707
	if (vms.deleted) {

    
   
11708
		ast_free(vms.deleted);

    
   
11709
	}

    
   
11710
	if (vms.heard) {

    
   
11711
		ast_free(vms.heard);

    
   
11712
	}

    
   
11713

   

    
   
11714
	return res;

    
   
11715
}

    
   
11716

   
11591
static int reload(void)
11717
static int reload(void)
11592
{
11718
{
11593
	return load_config(1);
11719
	return load_config(1);
11594
}
11720
}
11595

    
   
11721

   
[+20] [20] 18 lines
[+20] [+] static int unload_module(void)
11614
	ast_unload_realtime("voicemail");
11740
	ast_unload_realtime("voicemail");
11615
	ast_unload_realtime("voicemail_data");
11741
	ast_unload_realtime("voicemail_data");
11616

    
   
11742

   
11617
	free_vm_users();
11743
	free_vm_users();
11618
	free_vm_zones();
11744
	free_vm_zones();

    
   
11745
	AST_TEST_UNREGISTER(test_voicemail_msgcount);
11619
	return res;
11746
	return res;
11620
}
11747
}
11621

    
   
11748

   
11622
static int load_module(void)
11749
static int load_module(void)
11623
{
11750
{
[+20] [20] 28 lines
[+20] static int load_module(void)
11652

    
   
11779

   
11653
	ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname);
11780
	ast_install_vm_functions(has_voicemail, inboxcount, inboxcount2, messagecount, sayname);
11654
	ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL);
11781
	ast_realtime_require_field("voicemail", "uniqueid", RQ_UINTEGER3, 11, "password", RQ_CHAR, 10, SENTINEL);
11655
	ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL);
11782
	ast_realtime_require_field("voicemail_data", "filename", RQ_CHAR, 30, "duration", RQ_UINTEGER3, 5, SENTINEL);
11656

    
   
11783

   

    
   
11784
	AST_TEST_REGISTER(test_voicemail_msgcount);

    
   
11785

   
11657
	return res;
11786
	return res;
11658
}
11787
}
11659

    
   
11788

   
11660
static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) 
11789
static int dialout(struct ast_channel *chan, struct ast_vm_user *vmu, char *num, char *outgoing_context) 
11661
{
11790
{
[+20] [20] 495 lines
/trunk/include/asterisk/app.h
Diff Revision 1 Diff Revision 2 - File Reverted
 
/trunk/res/res_agi.c
Diff Revision 1 Diff Revision 2 - File Reverted
 
  1. /trunk/apps/app_voicemail.c: Loading...
  2. /trunk/include/asterisk/app.h: Loading...
  3. /trunk/res/res_agi.c: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.