[svn-commits] brushtyler: branch brushtyler/voicemail_menu_branch r212428 - in /team/brusht...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Aug 17 10:33:39 CDT 2009


Author: brushtyler
Date: Mon Aug 17 10:33:35 2009
New Revision: 212428

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=212428
Log:
added urgent messages check and corrected some bugs

Modified:
    team/brushtyler/voicemail_menu_branch/apps/myvm/brief.txt
    team/brushtyler/voicemail_menu_branch/apps/myvm/voicemail_menu-actual.conf
    team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c

Modified: team/brushtyler/voicemail_menu_branch/apps/myvm/brief.txt
URL: http://svn.asterisk.org/svn-view/asterisk/team/brushtyler/voicemail_menu_branch/apps/myvm/brief.txt?view=diff&rev=212428&r1=212427&r2=212428
==============================================================================
--- team/brushtyler/voicemail_menu_branch/apps/myvm/brief.txt (original)
+++ team/brushtyler/voicemail_menu_branch/apps/myvm/brief.txt Mon Aug 17 10:33:35 2009
@@ -105,6 +105,13 @@
 are used to navigate throught menus, the function actions are the real actions 
 will be made by voicemail application.
 
+When is executing an action, an error can occurrs. 
+There are 2 types of errors: errors that affects only the current action and 
+errors that affects the entire voicemail application behaviour.
+The first error type results in the current action termination and in the
+successive execution of default action, an error of the second type instead 
+terminates the voicemail application.
+
 Jump Actions
 	call(<menu_name>)
         ; make a jump from a menu to another keeping trace of the caller menu. 
@@ -222,7 +229,7 @@
         ; folder name into store the message.
 
     msg_exists(...)
-        ; test if a message exists
+        ; test if a message exists: return 1 if exists, 0 otherwise
         ; Following the args use explaination
     msg_exists([<number>])
         ; test if the specified message number (relative number) exists in
@@ -236,5 +243,5 @@
         ; test if a message has been recorded but not stored
 
     mb_exists(<number>)
-        ; test if the specified mailbox exists
-
+        ; test if the specified mailbox exists: return 1 if exists, 0 otherwise
+

Modified: team/brushtyler/voicemail_menu_branch/apps/myvm/voicemail_menu-actual.conf
URL: http://svn.asterisk.org/svn-view/asterisk/team/brushtyler/voicemail_menu_branch/apps/myvm/voicemail_menu-actual.conf?view=diff&rev=212428&r1=212427&r2=212428
==============================================================================
--- team/brushtyler/voicemail_menu_branch/apps/myvm/voicemail_menu-actual.conf (original)
+++ team/brushtyler/voicemail_menu_branch/apps/myvm/voicemail_menu-actual.conf Mon Aug 17 10:33:35 2009
@@ -55,7 +55,8 @@
 ; VM_MB_NUMBER          called mailbox
 ; VM_MB_CONTEXT         called context
 ;
-; VM_MSG_IS_SELECTED	1 if a messege is selected, 0 otherwise
+; VM_MSG_SELECTED   	0 if no messeges are selected, the message number
+                        otherwise
 ; VM_MSG_IS_FIRST       NULL if no message is selected, 1 if the selected 
 ;                       message is not the first, 0 otherwise
 ; VM_MSG_IS_LAST        NULL if no message is selected, 1 if the selected 
@@ -89,27 +90,22 @@
           ; enabled when enter in the voicemail the first time
     init += SET(VM_MB=${VM_MB_NUMBER}@${VM_MB_CONTEXT}),
           ; VM_MB conteins number at context
-    init += SET(VM_NEW_MSGS=${VMCOUNT(${VM_MB},INBOX)}), 
-          ; VM_NEW_MSG conteins the number of new messages
-    init += SET(VM_OLD_MSGS=${VMCOUNT(${VM_MB},Old)}), 
-          ; VM_OLD_MSG conteins the number of old messages
-    init += SET(VM_FOLDER=${IF(${VM_NEW_MSGS}?INBOX:Old)}), 
-          ; if there are new messages, VM_FOLDER conteins new folder name
-          ; else conteins the old folder name
-    init += change_to(${VM_FOLDER}), 
-          ; set the previous selected folder as current
-    init += SET(VM_MSGS=${VMCOUNT(${VM_MB},${VM_FOLDER})}), 
-          ; VM_MSGS conteins the number of messages in the current folder
+    init += call(recount_messages), 
+          ; refresh the messages counter variables
+    init += SET(VM_FOLDER=${IF(${VM_URG_MSGS}?Urgent:${IF(${VM_NEW_MSGS}?INBOX:Old)})}), 
+          ; select the proper folder: VM_FOLDER conteins the urgent folder 
+          ; name if there are urgent messages, the new folder name if there 
+          ; are new messages else the old folder name
+    init += call(change_menu_exec), 
+          ; open the previous selected folder
     init += call(start_menu_intro)
-          ; play intro and instructions
+          ; and play intro and instructions
 
     default = call(start_menu_instruction)
             ; play instructions
 
-    1  = ${VM_MSG_IS_SELECTED} ? SET(VM_MENU_TYPE=play), 
-       ; if a message is selected, set the play as menu type
-    1 += set_msg(0, current), 
-       ; set as selected message the first in the folder
+    1  = ${VM_MSG_SELECTED} ? SET(VM_MENU_TYPE=play), 
+       ; if a message is selected, set play as menu type
     1 += jump(start_menu)
        ; and then go to Play Messages Menu
 
@@ -121,26 +117,36 @@
     3  = SET(VM_MENU_TYPE=init), call(adv_menu)
        ; go to Advanced Menu Options
 
-    4  = ${VM_MSG_IS_FIRST} ? play(vm-nomore)
+    4  = ${VM_MSG_IS_FIRST} ?
        ; if the selected message is the first, there are no previous messages
-
-    4  = ${VM_MSG_IS_SELECTED} ? SET(VM_MENU_TYPE=play), 
-       ; if a message is selected, set the play as menu type
-    4 += set_msg(-1), jump(start_menu)
-       ; and then play the previous message
-
-    5  = ${VM_MSG_IS_SELECTED} ? SET(VM_MENU_TYPE=play), 
-       ; if a message is selected, set the play as menu type
-    5 += jump(start_menu)
-       ; and then play current message
-
-    6  = ${VM_MSG_IS_LAST} ? play(vm-nomore)
+    4 += call(check_for_urgent_mess), 
+       ; so check for urgent messages
+    4 += ${IF($[${VM_FOLDER}=Urgent]?jump(play_menu_exec))},
+       ; and if there are any urgent messages play the first one
+    4 += play(vm-nomore)
+       ; else play the no more sound
+
+    4  = ${VM_MSG_SELECTED} ? 
+       ; if a message is selected and is not the first, 
+    4 += set_msg(-1), jump(play_menu_exec)
+       ; play the previous message
+
+    5  = ${VM_MSG_SELECTED} ? jump(play_menu_exec)
+       ; if a message is selected, play the current message
+
+    6  = ${VM_MSG_IS_LAST} ? 
        ; if the selected message is the last, there are no next messages
-
-    6  = ${VM_MSG_IS_SELECTED} ? SET(VM_MENU_TYPE=play), 
-       ; if a message is selected, set the play as menu type
-    6 += set_msg(+1), jump(start_menu)
-       ; and then play the next message
+    6 += call(check_for_urgent_mess), 
+       ; so check for urgent messages
+    6 += ${IF($[${VM_FOLDER}=Urgent]?jump(play_menu_exec))},
+       ; and if there are any urgent messages play the first one
+    6 += play(vm-nomore)
+       ; else play the no more sound
+
+    6  = ${VM_MSG_SELECTED} ? 
+       ; if a message is selected and is not the last, 
+    6 += set_msg(+1), jump(play_menu_exec)
+       ; play the next message
 
     7  = ${VM_MSG_IS_DELETED}=0 ? SET(VM_MENU_TYPE=play), 
        ; if the selected message are not already marked for deletion,
@@ -152,10 +158,10 @@
     7 += undelete_msg(), play(vm-undeleted)
        ; unmark it
 
-    8  = ${VM_MSG_IS_SELECTED} ? call(forward_menu)
+    8  = ${VM_MSG_SELECTED} ? call(forward_menu)
        ; if a message is selected, go to the Forward Menu to forward it
 
-    9  = ${VM_MSG_IS_SELECTED} ? 
+    9  = ${VM_MSG_SELECTED} ? 
        ; if a message is selected,
     9 += ${IF($[${VM_MENU_TYPE}=full]?SET(VM_MENU_TYPE=play))}, 
        ; if the menu type is full, set it to play type
@@ -215,22 +221,22 @@
     init  = ${VM_MENU_TYPE}=play ? jump(start_menu_play_instruction)
           ; if the play menu type is selected, play the right instruction
 
-    init  = ${IF(${VM_MSG_IS_SELECTED}?play(vm-onefor))}, 
-    init += ${IF(${VM_MSG_IS_SELECTED}?play(vm-${VM_FOLDER}))}, 
-    init += ${IF(${VM_MSG_IS_SELECTED}?play(vm-messages))}, 
+    init  = ${IF(${VM_MSG_SELECTED}?play(vm-onefor))}, 
+    init += ${IF(${VM_MSG_SELECTED}?play(vm-${VM_FOLDER}))}, 
+    init += ${IF(${VM_MSG_SELECTED}?play(vm-messages))}, 
     init += play(vm-opts), 
     init += play(vm-helpexit), 
     init += return(1)
 
 [start_menu_full_instruction]   ; play the start_menu instruction when the 
                                 ; full menu type is selected
-    init  = ${IF(${VM_MSG_IS_SELECTED}?play(vm-onefor))}, 
-    init += ${IF(${VM_MSG_IS_SELECTED}?play(vm-${VM_FOLDER}))}, 
-    init += ${IF(${VM_MSG_IS_SELECTED}?play(vm-messages))}, 
+    init  = ${IF(${VM_MSG_SELECTED}?play(vm-onefor))}, 
+    init += ${IF(${VM_MSG_SELECTED}?play(vm-${VM_FOLDER}))}, 
+    init += ${IF(${VM_MSG_SELECTED}?play(vm-messages))}, 
     init += play(vm-opts), 
-    init += ${IF(${VM_MSG_IS_SELECTED}?play(vm-onefor-full))}, 
-    init += ${IF(${VM_MSG_IS_SELECTED}?play(vm-${VM_FOLDER}))}, 
-    init += ${IF(${VM_MSG_IS_SELECTED}?play(vm-messages))}, 
+    init += ${IF(${VM_MSG_SELECTED}?play(vm-onefor-full))}, 
+    init += ${IF(${VM_MSG_SELECTED}?play(vm-${VM_FOLDER}))}, 
+    init += ${IF(${VM_MSG_SELECTED}?play(vm-messages))}, 
     init += play(vm-opts-full), 
     init += ${IF(${VM_MSG_IS_FIRST}?:play(vm-prev))}, 
     init += play(vm-repeat), 
@@ -257,6 +263,42 @@
 
 ;-----------------------------------------------------------;
 ;
+; Play Exec Menu
+
+[play_menu_exec]
+    init  = ${VM_MSG_SELECTED} ? SET(VM_MENU_TYPE=play), 
+          ; if a message is selected, set play as menu type
+    init += jump(start_menu)
+          ; and then play current message
+
+;-----------------------------------------------------------;
+;
+; Recount Messages Menu
+
+[recount_messages]
+    init  = SET(VM_URG_MSGS=${VMCOUNT(${VM_MB},Urgent)}), 
+          ; VM_URG_MSG conteins the number of urgent messages
+    init += SET(VM_NEW_MSGS=${VMCOUNT(${VM_MB},INBOX)}), 
+          ; VM_NEW_MSG conteins the number of new messages
+    init += SET(VM_OLD_MSGS=${VMCOUNT(${VM_MB},Old)}), 
+          ; VM_OLD_MSG conteins the number of old messages
+    init += return(1)
+
+;-----------------------------------------------------------;
+;
+; Check for Urgent Messages Menu
+
+[check_for_urgent_mess]
+    init  = call(recount_messages),
+          ; refresh the messages counter variables
+    init += ${IF(${VM_URG_MSGS}?SET(VM_FOLDER=Urgent):return(1))}, 
+          ; if there are urgent messages set VM_FOLDER to the urgent folder 
+    init += call(change_menu_exec), 
+          ; and open this folder
+    init += return(1)
+
+;-----------------------------------------------------------;
+;
 ; Advanced Menu Options
 ;
 ; Contains the message advanced operations o user operation 
@@ -267,11 +309,11 @@
     default = call(adv_menu_instruction)
             ; play instructions
 
-    1  = ${VM_MSG_IS_SELECTED} ? jump(reply_menu)
+    1  = ${VM_MSG_SELECTED} ? jump(reply_menu)
        ; go to Reply Menu to do a reply to the sender
     2  = ${VMU_CALLBACK} ? jump(callback_menu)
        ; if callback is permitted, go to Callback Menu
-    3  = ${VM_MSG_IS_SELECTED} ? play_envelope()
+    3  = ${VM_MSG_SELECTED} ? play_envelope()
        ; play additional message informations
     4  = ${VMU_DIALOUT} ? jump(dialout_menu)
        ; if permitted, make an external call
@@ -285,9 +327,9 @@
 
 
 [adv_menu_instruction]  ; play the adv_menu instructions
-    init  = ${IF(${VM_MSG_IS_SELECTED}?play(vm-toreply))}, 
+    init  = ${IF(${VM_MSG_SELECTED}?play(vm-toreply))}, 
     init += ${IF(${VMU_CALLBACK}?play(vm-tocallback))}, 
-    init += ${IF(${VM_MSG_IS_SELECTED}?play(vm-tohearenv))}, 
+    init += ${IF(${VM_MSG_SELECTED}?play(vm-tohearenv))}, 
     init += ${IF(${VMU_DIALOUT}?play(vm-tomakecall))}, 
     init += ${IF(${VMU_LEAVE_MSG}?play(vm-leavemsg))}, 
     init += play(vm-starmain), 
@@ -450,13 +492,15 @@
     default = call(save_menu_instruction)
             ; play instructions
 
-    0  = save_into(INBOX), return(1) 
-    1  = save_into(Old), return(1)
-    2  = save_into(Work), return(1)
-    3  = save_into(Family), return(1)
-    4  = save_into(Friends), return(1)
-       ; save the selected message into a folder and return
-    _# = exit()   ; exit
+    0  = SET(VM_FOLD=INBOX), jump(save_menu_exec) 
+    1  = SET(VM_FOLD=Old), jump(save_menu_exec)
+    2  = SET(VM_FOLD=Work), jump(save_menu_exec)
+    3  = SET(VM_FOLD=Family), jump(save_menu_exec)
+    4  = SET(VM_FOLD=Friends), jump(save_menu_exec)
+       ; save temporarely the selected folder and call the 
+       ; Save To Folder Menu Exec to store the selected 
+       ; message in that folder
+    _# = return(1)   ; return to Main Menu
 
 
 [save_menu_instruction] ; play the save_menu instruction
@@ -488,6 +532,22 @@
     init += play(vm-messages), 
     init += play(vm-tocancel), 
     init += return(1)
+
+;-----------------------------------------------------------;
+;
+; Save To Folder Exec Menu
+
+[save_menu_exec]
+    init  = save_into(${VM_FOLD}), 
+    init += play(vm-message), 
+    init += play_num(${VM_MSG_SELECTED}), 
+    init += play(vm-savedto), 
+    init += play(vm-${VM_FOLD}), 
+    init += return(1)
+
+    default = return(1)
+            ; this action is executed only when the save_into function 
+            ; in the init block return an error
 
 ;-----------------------------------------------------------;
 ;
@@ -550,11 +610,17 @@
 [change_menu_exec]
     init  = change_to(${VM_FOLDER}),
           ; set the VM_FOLDER as the current folder
+    init += set_msg(0, current),
+          ; set the first message in the folder as selected
     init += SET(VM_MSGS=${VMCOUNT(${VM_MB},${VM_FOLDER})}), 
           ; refresh the value of VM_MSGS, it conteins the number of
           ; messages in the current folder 
     init += return(1)
           ; and return
+
+    default = return(1)
+            ; this action is executed only when the change_to function 
+            ; in the init block return an error
 
 ;-----------------------------------------------------------;
 ;
@@ -656,6 +722,10 @@
     init += record_msg(), return(1)
           ; record the message and return
 
+    default = return(1)
+            ; this action is executed only when the record_msg function 
+            ; in the init block return an error
+
 ;-----------------------------------------------------------;
 ;
 ; Exit Menu

Modified: team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c?view=diff&rev=212428&r1=212427&r2=212428
==============================================================================
--- team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c (original)
+++ team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c Mon Aug 17 10:33:35 2009
@@ -217,16 +217,47 @@
 	char msg_format[512];
 };
 
-/* There is apparently support for a fixed number of folders */
-static int map_folder(const char *mbox_name)
-{
-	return 0;	/* XXX must be fixed */
+static int folder_int(const char *folder)
+{
+	/*assume a NULL folder means INBOX*/
+	if (!folder)
+		return 0;
+#ifdef IMAP_STORAGE
+	if (!strcasecmp(folder, imapfolder))
+#else
+	if (!strcasecmp(folder, "INBOX"))
+#endif
+		return 0;
+	else if (!strcasecmp(folder, "Old"))
+		return 1;
+	else if (!strcasecmp(folder, "Work"))
+		return 2;
+	else if (!strcasecmp(folder, "Family"))
+		return 3;
+	else if (!strcasecmp(folder, "Friends"))
+		return 4;
+	else if (!strcasecmp(folder, "Cust1"))
+		return 5;
+	else if (!strcasecmp(folder, "Cust2"))
+		return 6;
+	else if (!strcasecmp(folder, "Cust3"))
+		return 7;
+	else if (!strcasecmp(folder, "Cust4"))
+		return 8;
+	else if (!strcasecmp(folder, "Cust5"))
+		return 9;
+	else /*assume they meant INBOX if folder is not found otherwise*/
+		return 0;
 }
 
 static const char *mbox(int id)
 {
-	static const char *msgs[] = {
+	static const char * const msgs[] = {
+#ifdef IMAP_STORAGE
+		imapfolder,
+#else
 		"INBOX",
+#endif
 		"Old",
 		"Work",
 		"Family",
@@ -236,8 +267,10 @@
 		"Cust3",
 		"Cust4",
 		"Cust5",
+		"Deleted",
+		"Urgent"
 	};
-	return (id >= 0 && id < (sizeof(msgs)/sizeof(msgs[0]))) ? msgs[id] : "Unknown";
+	return (id >= 0 && id < ARRAY_LEN(msgs)) ? msgs[id] : "Unknown";
 }
 
 struct vmstate {
@@ -289,6 +322,7 @@
 	int *heard;
 	int curmsg;
 	int lastmsg;
+	int urgentmessages;
 	int newmessages;
 	int oldmessages;
 	int starting;
@@ -1436,7 +1470,7 @@
 
 	for (x = 0; x < vmu->maxmsg; x++) { 
 		if (!vms->deleted[x] && ((strcasecmp(vms->curbox, "INBOX") && strcasecmp(vms->curbox, "Urgent")) || !vms->heard[x] || (vms->heard[x] && !ast_test_flag(vmu, VM_MOVEHEARD)))) { 
-			/* Save this message.  It's not in INBOX or hasn't been heard */ 
+			/* Save this message. It's not in INBOX or hasn't been heard */ 
 			make_file(vms->fn, sizeof(vms->fn), vms->curdir, x); 
 			if (!EXISTS(vms->curdir, x, vms->fn, NULL)) 
 				break;
@@ -1766,9 +1800,6 @@
 	return 0;
 }
 
-static int dialout2(struct ast_channel *chan, struct ast_vm_user *vmu, const char *num,
-		    char *outgoing_context);
-
 static int advanced_options(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int msg, int option, signed char record_gain)
 {
 	int res = 0;
@@ -1918,10 +1949,7 @@
 static int do_menu(struct ast_channel *chan, struct ast_category * category, 
             const char * menu_name, int depth, struct vm_state* vms, 
             struct ast_vm_user *vmu, struct exec_main_var* vm_var);
-struct exec_result vm_exec_actions(struct ast_category * menu, const char * body,
-    		struct ast_channel *chan, int depth, struct vm_state* vms,
-	    	struct ast_vm_user *vmu, struct exec_main_var* vm_var);
-struct exec_result vm_exec_actions2(struct ast_category * menu, const char * body, 
+struct exec_result vm_exec_actions(struct ast_category * menu, const char * body, 
 	        struct ast_channel *chan, int depth, struct vm_state* vms, 
             struct ast_vm_user *vmu, struct exec_main_var* vm_var);
 
@@ -2007,7 +2035,8 @@
 	char *cid;
 	struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE, };
 
-    if (s_cid) *s_cid = NULL;
+    if (s_cid)
+        *s_cid = NULL;
 
     if (vms->curmsg < 0)
         return -1;
@@ -2041,7 +2070,9 @@
 		return -1;
     }
 
-    if (s_cid) *s_cid = ast_strdup(cid);
+    if (s_cid)
+        *s_cid = ast_strdup(cid);
+
 	ast_config_destroy(msg_cfg);
     return 0;
 }
@@ -2053,6 +2084,7 @@
 				struct ast_vm_user* vmu)
 {
     char *cid = NULL, *num = NULL, *name = NULL;
+    char curmsg[10];
 
 #if debug
 	if (vms->curmsg < 0)
@@ -2064,10 +2096,12 @@
     }
     ast_free((void *)cid);
 
+    /* convert the current message number in string */
+    snprintf(curmsg, sizeof(curmsg), "%d", vms->curmsg+1);
+	pbx_builtin_setvar_helper(chan, "VM_MSG_SELECTED", vms->curmsg >= 0 ? curmsg : "0");
 	pbx_builtin_setvar_helper(chan, "VM_MSG_IS_DELETED", vms->curmsg >= 0 ? (vms->deleted[vms->curmsg] ? "1" : "0") : "");
 	pbx_builtin_setvar_helper(chan, "VM_MSG_IS_LAST", vms->curmsg >= 0 ? (vms->curmsg < vms->lastmsg ? "0" : "1") : "");
 	pbx_builtin_setvar_helper(chan, "VM_MSG_IS_FIRST", vms->curmsg >= 0 ? (vms->curmsg == 0 ? "1" : "0") : "");
-	pbx_builtin_setvar_helper(chan, "VM_MSG_IS_SELECTED", vms->curmsg >= 0 ? "1" : "0");
 
    	pbx_builtin_setvar_helper(chan, "VM_MSG_SENDER", vms->curmsg >= 0 && num ? num : "");
 	/*DEBUG*/
@@ -2079,16 +2113,16 @@
 	const char * MSG_SELECTED;
 	const char * MSG_SENDER;
 
+	MSG_SELECTED = pbx_builtin_getvar_helper(chan, "VM_MSG_SELECTED");
 	DEL = pbx_builtin_getvar_helper(chan, "VM_MSG_IS_DELETED");
 	NOT_FIRST = pbx_builtin_getvar_helper(chan, "VM_MSG_IS_FIRST");
 	NOT_LAST = pbx_builtin_getvar_helper(chan, "VM_MSG_IS_LAST");
-	MSG_SELECTED = pbx_builtin_getvar_helper(chan, "VM_MSG_IS_SELECTED");
 	MSG_SENDER = pbx_builtin_getvar_helper(chan, "VM_MSG_SENDER");
 	ast_log(LOG_NOTICE, "++++++++++++++++++++++++++++++++++++++\n");
+	ast_log(LOG_NOTICE, "VM_MSG_SELECTED : '%s'\n",MSG_SELECTED);
 	ast_log(LOG_NOTICE, "VM_MSG_IS_DELETED: '%s'\n",DEL);
 	ast_log(LOG_NOTICE, "VM_MSG_IS_FIRST :'%s'\n",NOT_FIRST);
 	ast_log(LOG_NOTICE, "VM_MSG_IS_LAST : '%s'\n",NOT_LAST);
-	ast_log(LOG_NOTICE, "VM_MSG_IS_SELECTED : '%s'\n",MSG_SELECTED);
 	ast_log(LOG_NOTICE, "VM_MSG_SENDER : '%s'\n",MSG_SENDER);
 	ast_log(LOG_NOTICE, "++++++++++++++++++++++++++++++++++++++\n");
     }
@@ -2126,7 +2160,7 @@
 }
 
 static int parse_message_num(const char* args, struct ast_channel* chan, struct vm_state* vms, 
-        char *fold, int *num)
+        char **fold, int *num)
 {
 	int argc=0;
     char *params[30];
@@ -2139,9 +2173,9 @@
     if (num)
         *num = 0;
     if (fold)
-        fold[0] = '\0';
-
-	if (args == NULL)
+        *fold = NULL;
+
+	if (!args)
         return -1;
 
     action = ast_strdupa(args);
@@ -2171,16 +2205,17 @@
 
     if (fold) {
         if (!ast_strlen_zero(msgfold) && strcmp(msgfold, "current"))    /* not current folder */
-            ast_copy_string(fold, msgfold, sizeof(fold));
+            *fold = ast_strdup(msgfold);
         else
-            ast_copy_string(fold, vms->curbox, sizeof(fold));
+            *fold = ast_strdup(vms->curbox);
     }
     if (num) {
         if (ast_strlen_zero(msgfold))   /* msgnum is relative on the current message */
             *num = vms->curmsg + msgnum;
         else     /* msgnum is an absolute message number */
             *num = msgnum;
-    }    
+    }
+
     return 0;
 }
 
@@ -2189,7 +2224,7 @@
 {
     int res = 0;
 	int num;
-    char fold[80];
+    char *folder, *fold;
 
     if (result)
         *result = NULL;
@@ -2198,13 +2233,16 @@
         return 0;
 
     /* retrieve num and folder from the args */
-    if (parse_message_num(args, chan, vms, fold, &num) || ast_strlen_zero(fold))
+    if (parse_message_num(args, chan, vms, &fold, &num) || !fold)
         return 1;
 
+    folder = ast_strdupa(fold);
+    ast_free(fold);
+
     /* is not the current folder, change it */
-    if (strcmp(fold, vms->curbox)) {
-        if ((res = vmm_change_to(fold, chan, vms, vmu, vm_var, NULL))) {
-            ast_log(LOG_ERROR, "An error occurred when change to folder %s\n", fold);
+    if (strcmp(folder, vms->curbox)) {
+        if ((res = vmm_change_to(folder, chan, vms, vmu, vm_var, NULL))) {
+            ast_log(LOG_ERROR, "An error occurred when change to folder %s\n", folder);
             return res;
         }
     }
@@ -2251,7 +2289,7 @@
 	char tempfile[PATH_MAX] = "";
 
     int num;
-    char fold[80];
+    char *folder, *fold;
 
     if (result)
         *result = "0";
@@ -2261,22 +2299,87 @@
         snprintf(tempfile ,sizeof(tempfile), "%s%s/%s/%s", VM_SPOOL_DIR, vmu->context, vms->username, type);
         if (result)
             *result = ast_fileexists(tempfile, NULL, NULL) > 0 ? "1" : "0";
-    } else if (!parse_message_num(args, chan, vms, fold, &num) && !ast_strlen_zero(fold)) {
+    } else if (!parse_message_num(args, chan, vms, &fold, &num) && fold) {
+        folder = ast_strdupa(fold);
+        ast_free(folder);
+
         /* check the existence of the message by number and folder */
-        make_file(tempfile, sizeof(tempfile), fold, num);
+        make_file(tempfile, sizeof(tempfile), folder, num);
         if (result)
-            *result = EXISTS(num, fold, tempfile, NULL) ? "1" : "0";
+            *result = EXISTS(num, folder, tempfile, NULL) ? "1" : "0";
     }
     return 0;
 }
 
+static int exec_skipaftercmd(struct ast_channel* chan, struct vm_state* vms,
+            struct ast_vm_user* vmu, struct exec_main_var* vm_var)
+{
+    int res = 0;
+
+    if (ast_test_flag((&globalflags), VM_SKIPAFTERCMD)) {
+		if (vms->curmsg < vms->lastmsg) {
+			vms->curmsg++;
+			res = play_message(chan, vmu, vms);
+		} else if (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) {
+			vms->curmsg = 0;
+			res = play_message(chan, vmu, vms);
+		} else {
+			/* Check if we were listening to urgent
+			   messages.  If so, go to regular new messages
+			   instead of saying "no more messages"
+			*/
+			if (vm_var->in_urgent == 1) {
+				/* Check for new messages */
+				vm_var->in_urgent = 0;
+				res = close_mailbox(vms, vmu);
+				if (res == ERROR_LOCK_PATH)
+					return -1;
+				res = open_mailbox(vms, vmu, NEW_FOLDER);
+				if (res == ERROR_LOCK_PATH)
+					return -1;
+				ast_debug(1, "No more urgent messages, opened INBOX and got %d new messages\n", vms->lastmsg + 1);
+				vms->curmsg = -1;
+				if (vms->lastmsg < 0)
+					res = ast_play_and_wait(chan, "vm-nomore");
+			} else {
+				res = ast_play_and_wait(chan, "vm-nomore");
+			}
+		}
+	}
+    return res;
+}
+
 static int vmm_save_into(const char* args, struct ast_channel* chan, struct vm_state* vms,
             struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
 {
+    int res;
+    int fold = folder_int(args);
+
     if (result)
         *result = NULL;
 
-    return 1;   /* TODO */
+    if (fold == 0 && strcasecmp(args, "INBOX")) {
+        ast_log(AST_LOG_WARNING, "Folder '%s' doesn't exists\n", args);
+        return 1;
+    }
+
+    res = save_to_folder(vmu, vms, vms->curmsg, fold);
+    if (res == ERROR_LOCK_PATH) {
+        return 1;
+#ifndef IMAP_STORAGE
+	} else if (!res) {
+		vms->deleted[vms->curmsg] = 1;
+#endif
+	} else {
+		vms->deleted[vms->curmsg] = 0;
+		vms->heard[vms->curmsg] = 0;
+	}
+
+    if (res) {
+		res = ast_play_and_wait(chan, "vm-mailboxfull");
+	}
+
+    return exec_skipaftercmd(chan, vms, vmu, vm_var);
 }
 
 static int review_record_store_delete(struct ast_channel *chan, const char *args, int option, 
@@ -2318,10 +2421,10 @@
     if (result)
         *result = NULL;
 
-    if (!parse_message_type(args, &type)) 
-        return review_record_store_delete(chan, type, 3, vms, vmu, vm_var);
-
-    return 1;
+    if (parse_message_type(args, &type))
+        return 1;
+
+    return review_record_store_delete(chan, type, 3, vms, vmu, vm_var);
 }
 
 static int record_voicemail(struct ast_channel *chan, struct vm_state* vms,
@@ -2332,20 +2435,20 @@
 		    struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
 {
     char *type = NULL;
+    char *t = NULL;
 
     if (result)
         *result = NULL;
 
-    if (!parse_message_type(args, &type)) {
-        char *t = NULL;
-        parse_message_type("rec", &t);
-        if (strcmp(type, t))    /* record a greeting message */
-            return review_record_store_delete(chan, type, 2, vms, vmu, vm_var);
-
-        /* record a temporary message */
-        return record_voicemail(chan, vms, vmu, vm_var);
-    }
-    return 1;
+    if (parse_message_type(args, &type))
+        return 1;
+
+    parse_message_type("rec", &t);
+    if (strcmp(type, t))    /* record a greeting message */
+        return review_record_store_delete(chan, type, 2, vms, vmu, vm_var);
+
+    /* record a temporary message */
+    return record_voicemail(chan, vms, vmu, vm_var);
 }
 
 /* play an information message */
@@ -2543,11 +2646,10 @@
 	char *canceldtmf = "";
 
     char *t = NULL;
-
-    snprintf(tempfile ,sizeof(tempfile), "%s%s/%s/%s", VM_SPOOL_DIR, vmu->context, vmu->mailbox, type);
-
     parse_message_type("rec", &t);
-    if (!type || ast_strlen_zero(type) || !strcmp(type, t))
+    snprintf(tempfile, sizeof(tempfile), "%s%s/%s/%s", VM_SPOOL_DIR, vmu->context, vmu->mailbox, t);
+
+    if (!type || !ast_strlen_zero(type) || !strcmp(type, t))
         ast_copy_string(recordfile, tempfile, sizeof(recordfile));
     else
         snprintf(recordfile, sizeof(recordfile), "%s%s/%s/%s", VM_SPOOL_DIR, vmu->context, vms->username, type);
@@ -2672,9 +2774,191 @@
     return 0;
 }
 
+static int vmm_change_to(const char *args, struct ast_channel* chan, struct vm_state* vms,
+			 struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
+{
+	int res;
+
+    if (result)
+        *result = NULL;
+
+	res = close_mailbox(vms, vmu);
+	if (res == ERROR_LOCK_PATH)
+		return -1;
+
+	/* If folder is not urgent, set in_urgent to zero! */
+	if (strcasecmp(args, "Urgent")) 
+        vm_var->in_urgent = 0;
+	res = open_mailbox(vms, vmu, args);
+
+    if (vms->lastmsg < 0)
+        vms->curmsg = -1;
+    else
+        vms->curmsg = 0;
+
+    set_channelvar_full(chan, vms, vmu);
+
+	if (res == ERROR_LOCK_PATH)
+		return -1;
+
+	vm_var->play_folder = folder_int(args);
+
+    /* if (useadsi)
+    	adsi_status2(chan, &vms); */
+	return 0;
+}
+
+static int vmm_delete(const char* args, struct ast_channel* chan, struct vm_state* vms,
+		      struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
+{
+	int res = 0;
+    char *type = NULL;
+
+    if (result)
+        *result = NULL;
+
+    if (!ast_strlen_zero(args) && !parse_message_type(args, &type)) 
+        return review_record_store_delete(chan, type, 4, vms, vmu, vm_var);
+
+    if (vmm_set_msg(args, chan, vms, vmu, vm_var, NULL))
+        return -1;
+
+	if (vms->curmsg >= 0 && vms->curmsg <= vms->lastmsg) {
+		vms->deleted[vms->curmsg] = !vms->deleted[vms->curmsg];
+		/* if (useadsi)
+			adsi_delete(chan, &vms); */
+		if (vms->deleted[vms->curmsg]) {
+			if (vm_var->play_folder == 0) {
+				if (vm_var->in_urgent) {
+					vms->urgentmessages--;
+				} else {
+					vms->newmessages--;
+				}
+			}
+			else if (vm_var->play_folder == 1)
+				vms->oldmessages--;
+			/* res = ast_play_and_wait(chan, "vm-deleted"); */
+		} else {
+			if (vm_var->play_folder == 0) {
+				if (vm_var->in_urgent) {
+					vms->urgentmessages++;
+				} else {
+					vms->newmessages++;
+				}
+			}
+			else if (vm_var->play_folder == 1)
+				vms->oldmessages++;
+			/* res = ast_play_and_wait(chan, "vm-undeleted"); */
+	    }
+		if ((res = exec_skipaftercmd(chan, vms, vmu, vm_var)))
+            return res;
+	}
+#ifdef IMAP_STORAGE
+	deleted = 1;
+#endif
+	return 0;
+}
+
+static int vmm_forward_msg(const char* args, struct ast_channel* chan, struct vm_state* vms, 
+            struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
+{
+    int res = 0;
+	char *username;
+    char *ptype = NULL;
+
+	int argc=0;
+    char *params[2];
+	char *action = NULL;
+
+    if (result)
+        *result = NULL;
+
+	if (args == NULL || !strlen(args))
+        return 1;
+
+    action = ast_strdupa(args);
+	memset(params, 0, sizeof(params));
+	argc = ast_app_separate_args(action, ',', params, sizeof(params)/sizeof(params[0]));
+    
+    if (argc < 1)
+        return 1;
+
+    /* args conteins the recipient number */
+    action = ast_strdupa(params[0]);
+    ast_trim_blanks(action);
+    username = ast_skip_blanks(action);
+
+    if (argc >= 2) {    /* you want forward the recorded message */
+        char *type = NULL;
+        action = ast_strdupa(params[1]);
+        ast_trim_blanks(action);
+        action = ast_skip_blanks(action);
+        if (parse_message_type(action, &ptype))
+            return 1;   /* no keywords associated to the 2nd arg */
+
+        parse_message_type("rec", &type);   /* retrieve the "rec" keyword */
+        if (strcmp(ptype, type))
+            return 1;   /* no "rec" keyword as the 2nd arg */
+    }
+
+    if (ptype) {
+		res = forward_message(chan, vmu->context, vms, vmu, username, vmfmts, 1, vm_var->record_gain, vm_var->in_urgent);
+		if (res == ERROR_LOCK_PATH) {
+			return -1;
+		}
+    } else if (vms->lastmsg > -1) {
+		res = forward_message(chan, vmu->context, vms, vmu, username, vmfmts, 0, vm_var->record_gain, vm_var->in_urgent);
+		if (res == ERROR_LOCK_PATH) {
+			return -1;
+		}
+	}
+
+    return exec_skipaftercmd(chan, vms, vmu, vm_var);
+}
+
+static int vmm_envelope(const char* args, struct ast_channel* chan, struct vm_state* vms,
+			struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
+{
+    int res;
+
+    if (result)
+        *result = NULL;
+
+    if (vmm_set_msg(args, chan, vms, vmu, vm_var, NULL))
+        return -1;
+
+	res = advanced_options(chan, vmu, vms, vms->curmsg, 3, vm_var->record_gain);
+    if (res == '*')
+        res = 0;
+
+    return res;
+}
+
+
+static int vmm_dialout(const char* args, struct ast_channel* chan, struct vm_state* vms,
+		       struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
+{
+    if (result)
+        *result = NULL;
+	
+	if (ast_strlen_zero(args))
+        return 1;
+
+	if (args[strlen(args)-1] == '*')    /* user do a mistake and want to repeat number to call */
+		return 1;
+
+	if (option_verbose > 2)
+		ast_verbose( VERBOSE_PREFIX_3 "Placing outgoing call to extension '%s' in context '%s' from context '%s'\n", args, vmu->dialout, chan->context);
+
+	ast_copy_string(chan->exten, args, sizeof(chan->exten));
+	ast_copy_string(chan->context, vmu->dialout, sizeof(chan->context));
+	chan->priority = 0;
+	return 0;
+}
+
 /* exec a function by variables substitution and, if requireq, subfunctions parse and execution */
 static int exec_function(struct ast_channel *chan, struct vm_state* vms, struct ast_vm_user *vmu, 
-    struct exec_main_var* vm_var, int r_level, const char *function, char** result, int depth, struct exec_result* res)
+    struct exec_main_var* vm_var, int r_level, const char *function, char **result, int depth, struct exec_result* res)
 {
     int i, digit = 0;
 	char *action = ast_strdupa(function);
@@ -2828,7 +3112,7 @@
             digit = 0;
 
         /* during the execution of an action the user press a digit, then skip all play functions */
-        if (digit && !strncasecmp(my_f[i].name, "play", 4) && strcasecmp(my_f[i].name, "play_msg")) {
+        if (digit && !strncasecmp(my_f[i].name, "play", 4)) {
 #if debug
             ast_log(LOG_NOTICE, "SKIP Function: %s(%s)\n", my_f[i].name, buf);
 #endif
@@ -2847,7 +3131,9 @@
                 sprintf(res->digit, "%c", digit); 
     	}
 	} else if (r_level == 0) {
-        /* otherwise exec a dialplan function */
+        /* otherwise exec a dialplan function only if is at the top level, 
+         * because at the other levels this function is called by previous 
+         * level pbx_substitute_variables_helper */
         sprintf(app, "%s(%s)", name, buf);
         buf[0] = '\0';
 #if debug
@@ -2897,77 +3183,12 @@
     return digit;
 }
 
-#if 0
-/*! \brief determine if an entry is enabled.
- * look in the body for an if(...) statement at the beginning.
- * If not available, then return success (marked as -1)
- * If available, evaluate the body as a dialplan function and
- * return success(1) if the function returns != 0,
- * return failure(0) if the function returns 0
- */
-static int enabled(const char *entry, struct ast_channel *chan)
-{
-	int i, argc;
-	char *args[30]; /* at least 2 */
-	char *condition = ast_strdupa(entry); /* the body, if(...),x(), y(), ... */
-    char *s;
-
-	/*ast_log(LOG_NOTICE, "entry to be tested: '%s'\n", entry);*/
-	/* separate the first element of the body from the rest */
-	argc = ast_app_separate_args(condition, ',', args, 2 /* only care for first + rest */);
-//    ast_free(condition);
-	if (argc < 1)		/* no argument */
-		return -1;
-	s = ast_skip_blanks(args[0]);
-	if (strncmp(s, "IF", 2) != 0) /* no condition for this entry */
-		return -1;
-
-	/* the entry of the pattern matched is conditioned,
-	 * so we have to extract the body and evaluate it
-	 */
-	s = ast_skip_blanks(s + 2);	/* skip the 'if' part and subsequent blanks */
-	if (*s != '(') {		/* syntax error */
-		ast_log(LOG_WARNING, "syntax error in %s\n", entry);
-		return 0;
-	}
-	s++;			/* skip open parenthesis */
-	ast_trim_blanks(s);
-	i = strlen(s);
-	if (i && s[i-1] == ')' )	/* remove trailing parenthesis */
-		s[i-1] = '\0';
-	ast_log(LOG_WARNING, "testing: '%s'\n", s);
-	/* now extract the body, using '&' as a separator */
-	argc = ast_app_separate_args(s, '&', args, sizeof(args)/sizeof(args[0]));
-	for (i = 0; i < argc; i++) {
-		char s_eval[256];
-		/*ast_log(LOG_NOTICE, "*-*-*-*condizione '%d': '%s'*-*-*-*\n", argc, args[argc]);*/
-		memset(s_eval, 0, sizeof(s_eval));
-		/* substitution of channel variable with value */
-		pbx_substitute_variables_helper(chan, args[i], s_eval, sizeof(s_eval)-1);
-		ast_log(LOG_NOTICE, "s_eval: '%s'\n", s_eval);
-		/* check if is a dialplan function */
-		if ((strchr(s_eval, '(') != NULL) && (strchr(s_eval, ')') != NULL)) {
-			char result[256];
-			result[0] = '\0';
-			ast_func_read(chan, s_eval, result, sizeof(result));
-			ast_log(LOG_NOTICE, "result of condition %d: '%s'\n", argc, result);
-			if (atoi(result) == 0) 
-				return  0;
-		}
-		ast_log(LOG_WARNING, "result of verify of existence of channel variable: '%d'\n", (!strcmp(s_eval, "")) ? 0 : 1);
-		if (!strcmp(s_eval, ""))
-			return 0;
-	}
-	return 1;
-}
-#endif
-
 /*! \brief determine if an entry condition is enabled.
  * If no condition return -1
  * If the condition is verified return 1
  * If the condition is not verified (NULL, 0, empty string) return 0
  */
-static int enabled2(const char *condition, struct ast_channel *chan, struct vm_state* vms, 
+static int enabled(const char *condition, struct ast_channel *chan, struct vm_state* vms, 
             struct ast_vm_user *vmu, struct exec_main_var* vm_var)
 {
 	char *s = NULL, *result = NULL;
@@ -3023,7 +3244,7 @@
 {	
 	/*TODO: the following value must be getted from conf file */
 	int dtimeout = 1500;	/* timeout between digit */
-	int rtimeout = 5000;	/* timeout for the first digit */
+	int rtimeout = 6000;	/* timeout for the first digit */
     char *terminator = "#";
 
 	enum menu_state  { VMM_MS_DEFAULT, VMM_MS_INIT, VMM_MS_TIMEOUT, VMM_MS_WORKING} state = VMM_MS_INIT;
@@ -3073,9 +3294,9 @@
 		int j;
 		const char *matched;
 		char matched_dig[80];
+#if debug
 		ast_log(LOG_NOTICE, "---- menu: %s - level: %d - retries: %d - digits: %s ----\n", menu_name, depth, vms->retries, vms->str_dig);
 
-#if debug
 		ast_log(LOG_NOTICE, "valori ------> str_dig: '%s'\n", vms->str_dig);
 #endif
 		if (state == VMM_MS_WORKING) {
@@ -3089,8 +3310,9 @@
 
                 if (read_res == AST_GETDATA_EMPTY_END_TERMINATED)   /* terminator is the first and only digit, string empty */
                     strcat(vms->str_dig, terminator);
-
+#if debug
         		ast_log(LOG_WARNING, "Pressed digits: '%s'\n", vms->str_dig);
+#endif
             }
 		}
 
@@ -3127,12 +3349,12 @@
                 argc = ast_app_separate_args(action, '?', cond, 2 /* first + rest */);
                 if (argc > 1) {
                     /* have a condition, then evaluate it */
-                    /* enabled2() returns
+                    /* enabled() returns
                      * < 0 if there is no condition
                      * = 0 if the condition is not verified
                      * > 0 if the condition is verified
     				 */
-    				if (!enabled2(cond[0], chan, vms, vmu, vm_var))  
+    				if (!enabled(cond[0], chan, vms, vmu, vm_var))  
     					continue;
 
                     matched = cond[1];
@@ -3140,7 +3362,7 @@
                     /* no condition statement */
                     matched = cond[0];
                 else
-                    /* no actions defined */
+                    /* no actions to execute */
                     matched = "";
 #if debug
 				ast_log(LOG_NOTICE, "match found user: <%s> value <%s>\n", matched_dig, v->name);
@@ -3161,7 +3383,7 @@
 				vms->retries++;
     			vms->str_dig[0] = '\0';
 			} else {
-                /* init or default or timeout action */
+                /* a special pattern doesn't match */
 				ast_log(LOG_WARNING, "No %s action defined in conf file\n",
 					state == VMM_MS_INIT ? "init" : (state == VMM_MS_DEFAULT ? "default" : "timeout"));
 
@@ -3181,7 +3403,7 @@
   				state = VMM_MS_WORKING;
 			}
 			if (vms->retries == max_retries + 1) {
-				/* here the user have inserted an unexistent pattern for max_retries times */
+				/* here the user have inserted a not existent pattern for max_retries times */
 				ast_log(LOG_WARNING, "Max retries reached, try to exec 'timeout' action.\n");
 
                 vms->retries = 0;

[... 687 lines stripped ...]



More information about the svn-commits mailing list