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

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Aug 7 05:55:17 CDT 2009


Author: brushtyler
Date: Fri Aug  7 05:55:13 2009
New Revision: 210991

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=210991
Log:
Added "leave a message" functionality, corrected the actual menu conf file

Modified:
    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/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=210991&r1=210990&r2=210991
==============================================================================
--- team/brushtyler/voicemail_menu_branch/apps/myvm/voicemail_menu-actual.conf (original)
+++ team/brushtyler/voicemail_menu_branch/apps/myvm/voicemail_menu-actual.conf Fri Aug  7 05:55:13 2009
@@ -5,7 +5,9 @@
 ; This configuration file replicates the exact behaviour of
 ; the original app_voicemail.c with the following exceptions:
 ; 
-; 1. ... /* TODO */
+; 1. if you press any key when there is the play of the message envelope, 
+;       only it are skipped and not the play of the message.
+; 2. ... /* TODO */
 ;
 ; The voicemail is organized as a set of submenus, where the user
 ; can navigate through explicit input or via timeouts.
@@ -82,6 +84,7 @@
 [start_menu]
     init  = ${VM_MENU_TYPE} ? call(start_menu_intro)
           ; enabled if a type is setted, play intro and instructions
+
     init  = SET(VM_MENU_TYPE=init),
           ; enabled when enter in the voicemail the first time
     init += SET(VM_MB=${VM_MB_NUMBER}@${VM_MB_CONTEXT}),
@@ -103,45 +106,82 @@
     default = call(start_menu_instruction)
             ; play instructions
 
-    1  = ${VM_MSG_IS_SELECTED} ? SET(VM_MENU_TYPE=play), jump(start_menu)
-       ; if there are new messages, go to the new messages folder, 
-       ; else open the old messages folder and go to Play Messages Menu
-    2  = SET(VM_MENU_TYPE=init), call(change_to_folder_menu)
+    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 += jump(start_menu)
+       ; and then go to Play Messages Menu
+
+    2  = SET(VM_MENU_TYPE=init), call(change_to_folder_menu),
+       ; go to Change To Folder Menu
     2 += play(vm-${VM_FOLDER}), play(vm-messages)
-       ; go to Change Folder Menu
+       ; and then play the name of the selected folder
+
     3  = SET(VM_MENU_TYPE=init), call(adv_menu)
        ; go to Advanced Menu Options
+
     4  = ${VM_MSG_IS_FIRST} ? play(vm-nomore)
-    4  = SET(VM_MENU_TYPE=play), 
+       ; 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)
-       ; play previous message
-    5  = jump(start_menu)
-       ; play current message
+       ; 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)
-    6  = SET(VM_MENU_TYPE=play), 
+       ; 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)
-       ; play next message
+       ; and then play the next message
+
     7  = ${VM_MSG_IS_DELETED}=0 ? SET(VM_MENU_TYPE=play), 
-    7 += delete(), play(vm-deleted)
-       ; mark selected message for deletion
+       ; if the selected message are not already marked for deletion,
+    7 += delete_msg(), play(vm-deleted)
+       ; mark it
+
     7  = ${VM_MSG_IS_DELETED} ? SET(VM_MENU_TYPE=play), 
-    7 += undelete(), play(vm-undeleted)
-       ; unmark a previous marked message for deletion
-    8  = forward_message()
-       ; forward a message
-    9  = SET(VM_MENU_TYPE=init), call(save_to_folder_menu)
-       ; go to Save To Folder Menu
-    0  = SET(VM_MENU_TYPE=init), call(opts_menu)
-       ; go to Voicemail Menu Options
-    *  = ${VM_MENU_TYPE}=play ? SET(VM_MENU_TYPE=full)
-       ; help
+       ; if the selected message are marked for deletion,
+    7 += undelete_msg(), play(vm-undeleted)
+       ; unmark it
+
+    8  = ${VM_MSG_IS_SELECTED} ? call(forward_menu)
+       ; if a message is selected, go to the Forward Menu to forward it
+
+    9  = ${VM_MSG_IS_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
+    9 += call(save_to_folder_menu)
+       ; and go to Save Into Folder Menu
+
+    0  = ${IF($[${VM_MENU_TYPE}=full]?SET(VM_MENU_TYPE=play))}, 
+       ; if the menu type is full, set it to play type
+    0 += call(opts_menu)
+       ; and go to Voicemail Menu Options
+
+    *  = ${IF($[${VM_MENU_TYPE}=play]?SET(VM_MENU_TYPE=full))}
+       ; if the menu is in play type, change it to full type
+       ; and then play the instruction (default action)
+
     _# = exit()
        ; exit
 
+
 [start_menu_intro]  ; play the start_menu intro
     init  = ${VM_MENU_TYPE}=play ? jump(start_menu_play_intro)
+          ; if the play menu type is selected, play the right intro
+
     init  = ${VM_NEW_MSGS} & ${VM_OLD_MSGS} ? jump(start_menu_intro_newold)
           ; if there are both new and old messages, play the right intro
+
     init  = play(vm-youhave), 
     init += ${IF(${VM_MSGS}?play_num(${VM_MSGS}):play(vm-no))}, 
     init += ${IF(${VM_MSGS}?play(vm-${VM_FOLDER}))}, 
@@ -159,9 +199,22 @@
     init += ${IF($[${VM_OLD_MSGS}=1]?play(vm-message):play(vm-messages))}, 
     init += jump(start_menu_instruction)
 
+[start_menu_play_intro]  ; play the start_menu intro when the play menu type
+                         ; is selected
+    init  = play_envelope(), 
+          ; play additional message informations
+    init += play_msg(),
+          ; play the message
+    init += jump(start_menu_play_instruction)
+
+
 [start_menu_instruction]    ; play the start_menu instructions
     init  = ${VM_MENU_TYPE}=full ? jump(start_menu_full_instruction)
+          ; if the full menu type is selected, play the right instruction
+
     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))}, 
@@ -169,7 +222,8 @@
     init += play(vm-helpexit), 
     init += return(1)
 
-[start_menu_full_instruction]
+[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))}, 
@@ -188,14 +242,8 @@
     init += play(vm-helpexit), 
     init += return(1)
 
-[play_mess_menu_intro]  ; play the play_mess_menu intro
-    init  = play_envelope(), 
-          ; play additional message informations
-    init += play_msg(),
-          ; play the message
-    init += jump(play_mess_menu_instruction)
-
-[start_menu_play_instruction]   ; play the play_mess_menu instructions
+[start_menu_play_instruction]   ; play the start_menu instructions when the 
+                                ; play menu type is selected
     init  = play(vm-advopts), 
     init += ${IF(${VM_MSG_IS_FIRST}?:play(vm-prev))}, 
     init += play(vm-repeat), 
@@ -227,8 +275,11 @@
        ; play additional message informations
     4  = ${VMU_DIALOUT} ? jump(dialout_menu)
        ; if permitted, make an external call
-    5  = ${VMU_LEAVE_MSG} ? jump(leave_mess_menu)
-       ; if you can leave a message, go to Leave Message Menu
+    5  = ${VMU_LEAVE_MSG} ? SET(VM_RECIPIENT=),
+    5 += jump(leave_mess_menu)
+       ; if you can leave a message, make sure you don't have 
+       ; a recipient (look into called menu) 
+       ; and go to Leave Message Menu
 
     *  = return(1)  ; return to Main Menu
 
@@ -256,18 +307,6 @@
     init += forward_msg(${VM_NUMBER}), return(1)
           ; forward the current message and return
 
-[validate_forward_ext_menu]
-    init  = ${VM_NUMBER}=${VM_MB_NUMBER} ? play(pbx-invalid),
-          ; the recipient is also the sender, 
-    init += return(2)   ; return to Main Menu
-
-    init  = ${mb_exists(${VM_NUMBER})}=0 ? play(pbx-invalid),
-          ; the recipient mailbox doesn't exists, 
-    init += return(2)   ; return to Main Menu 
-
-    init  = return(1)   ; the recipient mailbox exists
-
-
 ;-----------------------------------------------------------;
 ;
 ; Ask For Extension Menu
@@ -286,6 +325,21 @@
 
 ;-----------------------------------------------------------;
 ;
+; Validate Forward Extension Menu
+
+[validate_forward_ext_menu]
+    init  = ${VM_NUMBER}=${VM_MB_NUMBER} ? play(pbx-invalid),
+          ; the recipient is also the sender, 
+    init += return(2)   ; return to Main Menu
+
+    init  = ${mb_exists(${VM_NUMBER})}=0 ? play(pbx-invalid),
+          ; the recipient mailbox doesn't exists, 
+    init += return(2)   ; return to Main Menu 
+
+    init  = return(1)   ; the recipient mailbox exists
+
+;-----------------------------------------------------------;
+;
 ; Reply Menu
 
 [reply_menu]
@@ -307,8 +361,9 @@
 [leave_mess_menu]
     init  = ${mb_exists(${VM_RECIPIENT})} ? 
           ; if recipient has a mailbox, 
-    init += play(vm-intro), play(beep), record_msg(), 
-          ; record a message,
+    init += SET(VM_REC_GREET=), call(record_exec_menu), 
+          ; make sure you don't record a greet (look into called menu)
+          ; and go to Record Exec Menu to record the message,
     init += forward_msg(${VM_RECIPIENT}, rec), 
           ; forward the recoded message to the mailbox
     init += delete_msg(rec),
@@ -318,8 +373,12 @@
     init  = ${VM_RECIPIENT} ? play(pbx-invalid), return(1)
           ; if recipient has no mailbox, return
 
-    init  = call(ask_for_extension_menu), SET(VM_RECIPIENT=${VM_NUMBER}),
-          ; if no recipient, ask to user for the extension
+    init  = call(ask_for_extension_menu), 
+          ; if no recipients, ask to user for the extension
+    init += ${IF(${ISNULL(${VM_NUMBER})}?return(1))},  
+          ; no number dialed, return 
+    init += SET(VM_RECIPIENT=${VM_NUMBER}), 
+          ; save the digited extension as recipient
     init += jump(leave_mess_menu)
           ; and then try again
 
@@ -450,9 +509,43 @@
     3  = SET(VM_FOLDER=Family), jump(change_menu_exec)
     4  = SET(VM_FOLDER=Friends), jump(change_menu_exec)
        ; select a folder and save it's name in VM_FOLDER, then 
-       ; go to Change Menu Exec to change the current folder
+       ; go to Change Folder Exec Menu to change the current folder
     _# = return(1)  ; return to Main Menu
 
+
+[change_menu_instruction]   ; play the change_menu instructions
+    init  = play(vm-changeto), 
+    init += play(vm-press), 
+    init += play(digits/0), 
+    init += play(vm-for), 
+    init += play(vm-INBOX), 
+    init += play(vm-messages), 
+    init += play(vm-press), 
+    init += play(digits/1), 
+    init += play(vm-for), 
+    init += play(vm-Old), 
+    init += play(vm-messages), 
+    init += play(vm-press), 
+    init += play(digits/2), 
+    init += play(vm-for), 
+    init += play(vm-Work), 
+    init += play(vm-messages), 
+    init += play(vm-press), 
+    init += play(digits/3), 
+    init += play(vm-for), 
+    init += play(vm-Family), 
+    init += play(vm-messages), 
+    init += play(vm-press), 
+    init += play(digits/4), 
+    init += play(vm-for), 
+    init += play(vm-Friends), 
+    init += play(vm-messages), 
+    init += play(vm-tocancel), 
+    init += return(1)
+
+;-----------------------------------------------------------;
+;
+; Change Folder Exec Menu
 
 [change_menu_exec]
     init  = change_to(${VM_FOLDER}),
@@ -462,37 +555,6 @@
           ; messages in the current folder 
     init += return(1)
           ; and return
-
-
-[change_menu_instruction]   ; play the change_menu instructions
-    init  = play(vm-changeto), 
-    init += play(vm-press), 
-    init += play(digits/0), 
-    init += play(vm-for), 
-    init += play(vm-INBOX), 
-    init += play(vm-messages), 
-    init += play(vm-press), 
-    init += play(digits/1), 
-    init += play(vm-for), 
-    init += play(vm-Old), 
-    init += play(vm-messages), 
-    init += play(vm-press), 
-    init += play(digits/2), 
-    init += play(vm-for), 
-    init += play(vm-Work), 
-    init += play(vm-messages), 
-    init += play(vm-press), 
-    init += play(digits/3), 
-    init += play(vm-for), 
-    init += play(vm-Family), 
-    init += play(vm-messages), 
-    init += play(vm-press), 
-    init += play(digits/4), 
-    init += play(vm-for), 
-    init += play(vm-Friends), 
-    init += play(vm-messages), 
-    init += play(vm-tocancel), 
-    init += return(1)
 
 ;-----------------------------------------------------------;
 ;
@@ -525,6 +587,9 @@
     init  = play(vm-options), 
     init += return(1)
 
+;-----------------------------------------------------------;
+;
+; Manage Temp Greeting Menu
 
 [manage_temp_menu]
     init    = ${msg_exists(temp)} ? play(vm-tempgreeting2)
@@ -537,14 +602,23 @@
     default = play(vm-tempgreeting)
             ; play instructions
 
-    1  = call(record_greetings_menu)
+    timeout = return(1)
+            ; return to Voicemail Menu Options
+
+    1  = call(record_menu)
        ; go to Record Menu to record a temporary greeting
-    2  = delete_msg(temp), play(vm-tempremoved)
+
+    2  = ${msg_exists(temp)} ? 
+       ; if exists,
+    2 += delete_msg(temp), play(vm-tempremoved)
        ; delete the temporary greeting
 
+;-----------------------------------------------------------;
+;
+; Record Menu
 
 [record_menu]
-    init    = call(record_exec_menu)
+    init    = call(record_exec_menu), play(vm-review)
             ; go to Record Exec Menu to record a message
 
     default = ${msg_exists(rec)} ? play(vm-review)
@@ -569,12 +643,16 @@
     3  = call(record_exec_menu)
        ; go to Record Exec Menu to record a message
 
+;-----------------------------------------------------------;
+;
+; Record Exec Menu
 
 [record_exec_menu]
-    init  = ${IF(${ISNULL(${VM_REC_GREET})}?:play(vm-rec-${VM_REC_GREET}))}, 
+    init  = ${IF(${ISNULL(${VM_REC_GREET})}?play(vm-intro):play(vm-rec-${VM_REC_GREET}))}, 
           ; if we want to record a greeting, play the right greeting sound,
+          ; otherwise play the intro sound
     init += play(beep),
-          ; then play a beep
+          ; then play a beep,
     init += record_msg(), return(1)
           ; record the message and return
 
@@ -585,7 +663,6 @@
 ; This menu are called when the voicemail app is ending, 
 ; by exit() function in another menu. 
 ; The exit() function in this menu terminate the voicemail.
-
 
 [exit_menu]
     init  = play(vm-goodbye), 

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=210991&r1=210990&r2=210991
==============================================================================
--- team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c (original)
+++ team/brushtyler/voicemail_menu_branch/apps/newvoicemail.c Fri Aug  7 05:55:13 2009
@@ -1,22 +1,15 @@
 /*
  * A new voicemail application where all policies are configurable
  * through a configuration file and not hardwired in the code.
- * At the moment the file is made of three parts:
- * header (the first 1200 lines), main body, footer. The main body can be included in the
- * original app_voicemail.c to replace some of its functions,
- * while header and footer are the glue to let the file compile by itself.
  */
 
 #ifdef MYVM_STANDALONE
-/*!-------------------------------------------------------------*/
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 86820 $")
 
 #include "asterisk/paths.h"
 #include <dirent.h>
-
-
 
 #include "asterisk/file.h"
 #include "asterisk/logger.h"
@@ -111,7 +104,6 @@
 #define DELETE(a,b,c,d) (vm_delete(c))
 #endif
 #endif
-/*! --- */
 
 /*
  * Config arguments, buffers and so on
@@ -161,22 +153,6 @@
 
 /* Check mail, control, etc */
 static char *app2 = "VoiceMailMain2";
-/*static char *synopsis_vmain = "Check Voicemail messages";
-static char *descrip_vmain =
-	"  VoiceMailMain([mailbox][@context][,options]): This application allows the\n"
-	"calling party to check voicemail messages. A specific mailbox, and optional\n"
-	"corresponding context, may be specified. If a mailbox is not provided, the\n"
-	"calling party will be prompted to enter one. If a context is not specified,\n"
-	"the 'default' context will be used.\n\n"
-	"  Options:\n"
-	"    p    - Consider the mailbox parameter as a prefix to the mailbox that\n"
-	"           is entered by the caller.\n"
-	"    g(#) - Use the specified amount of gain when recording a voicemail\n"
-	"           message. The units are whole-number decibels (dB).\n"
-	"    s    - Skip checking the passcode for the mailbox.\n"
-	"    a(#) - Skip folder prompt and go directly to folder specified.\n"
-	"           Defaults to INBOX\n";
-*/
 
 /*! Poll mailboxes for changes since there is something external to
  *  app_voicemail that may change them. */
@@ -199,7 +175,6 @@
 static unsigned char adsifdn[4] = "\x00\x00\x00\x0F";
 static unsigned char adsisec[4] = "\x9B\xDB\xF7\xAC";
 static int adsiver = 1;
-/*! --- */
 
 /*! STRUCTS */
 
@@ -231,14 +206,8 @@
 	AST_APP_OPTION_ARG('a', OPT_AUTOPLAY, OPT_ARG_PLAYFOLDER),
 });
 
-/*this structure contains value of some variables defined in this function
- * and needed to call voicemail function by the do_menu*/
-
-struct leave_vm_options {
-	unsigned int flags;
-	signed char record_gain;
-	char *exitcontext;
-};
+/* this structure contains value of some variables defined in this function
+ * and needed to call voicemail function by the do_menu */
 
 /*! Voicemail time zones */
 struct vm_zone {
@@ -301,13 +270,13 @@
 	char imapuser[80];               /*!< IMAP server login */
 	char imappassword[80];           /*!< IMAP server password if authpassword not defined */
 #endif
-	double volgain;		         /*!< Volume gain for voicemails sent via email */
+	double volgain;		             /*!< Volume gain for voicemails sent via email */
 	AST_LIST_ENTRY(ast_vm_user) list;
 };
 
 /*! Voicemail mailbox state */
 struct vm_state {
-	char str_dig[80];		/*!< Buffer representing pattern digited by user >*/
+	char str_dig[80];		/*!< Buffer representing pattern digited by user */
     int retries;
     int exiting;
 	char curbox[80];
@@ -347,22 +316,17 @@
 };
 
 /*!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+/*!+++++++++++++++++++++++++ HERE START CODE EXPORTED +++++++++++++++++++++++++++++++*/
 /*!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/*!++++++++++++++++++++++++++HERE START CODE EXPORTED++++++++++++++++++++++++++++++++*/
-/*!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/*!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-/*forward declarations*/
+
+/* DECLARATIONS */
 
 /* functions now in app_voicemail.c used from here */
 static int load_config(int);
-#if 0
-static int vmu_debug(struct ast_vm_user* vmu);
-static int vms_debug(struct vm_state* vms);
-#endif
 
 static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms);
 static int forward_message(struct ast_channel *chan, char *context, struct vm_state *vms, 
-                struct ast_vm_user *sender, char *username, char *fmt, int is_new_message, 
+                struct ast_vm_user *sender, char *username, char *fmt, int is_tmp_message, 
                 signed char record_gain, int urgent);
 /*static void adsi_folders(struct ast_channel *chan, int start, char *label);
 static int get_folder2(struct ast_channel *chan, char *fn, int start);
@@ -376,7 +340,7 @@
 #endif
 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);
 
-/*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/
+/* FUNCTIONS*/
 
 static void populate_defaults(struct ast_vm_user *vmu)
 {
@@ -515,7 +479,6 @@
 	} 
 }
 
-
 static char *vm_check_password_shell(char *command, char *buf, size_t len) 
 {
 	int fds[2], pid = 0;
@@ -625,24 +588,6 @@
 	}
 	return -1;
 }
-
-#if 0 /* unused */
-static int is_valid_dtmf(const char *key)
-{
-	int i;
-	char *local_key = ast_strdupa(key);
-
-	for(i = 0; i < strlen(key); ++i) {
-		if(!strchr(VALID_DTMF, *local_key)) {
-			ast_log(LOG_WARNING, "Invalid DTMF key \"%c\" used in voicemail configuration file\n", *local_key);
-			return 0;
-		}
-		local_key++;
-	}
-	return 1;
-}
-#endif
-
 
 static struct ast_vm_user *find_user_realtime(struct ast_vm_user *ivm, const char *context, const char *mailbox)
 {
@@ -674,7 +619,6 @@
 		fprintf(stderr, "User not found!!!\n");
 	return retval;
 }
-
 
 static struct ast_vm_user *find_user(struct ast_vm_user *ivm, const char *context, const char *mailbox)
 {
@@ -1051,6 +995,8 @@
 	return x - 1;
 }
 
+static int parse_message_type(const char *args, char **ret);
+
 #ifndef IMAP_STORAGE
 /*! 
  * \brief Copies a message from one mailbox to another.
@@ -1081,19 +1027,23 @@
 		create_dirpath(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
 	}
 	
-	if (!dir)
-		make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
-	else
-		ast_copy_string(fromdir, dir, sizeof(fromdir));
-
-	make_file(frompath, sizeof(frompath), fromdir, msgnum);
+    if (imbox >= 0) {   /* copy the message from imbox and msgnum */
+	    if (!dir) {
+	    	make_dir(fromdir, sizeof(fromdir), vmu->context, vmu->mailbox, frombox);
+        } else
+        	ast_copy_string(fromdir, dir, sizeof(fromdir));
+
+        make_file(frompath, sizeof(frompath), fromdir, msgnum);
+    } else {    /* use dir as path */
+        strcpy(frompath, dir);
+    }
 	make_dir(todir, sizeof(todir), recip->context, recip->mailbox, "INBOX");
 
 	if (vm_lock_path(todir))
 		return ERROR_LOCK_PATH;
 
 	recipmsgnum = last_message_index(recip, todir) + 1;
-ast_log(AST_LOG_NOTICE, "recipmsgnum: %d - recip->maxmsg: %d\n", recipmsgnum, recip->maxmsg);
+
 	if (recipmsgnum < recip->maxmsg) {
 		make_file(topath, sizeof(topath), todir, recipmsgnum);
 		if (EXISTS(fromdir, msgnum, frompath, chan->language)) {
@@ -1112,8 +1062,10 @@
 		ast_log(AST_LOG_ERROR, "Recipient mailbox %s@%s is full\n", recip->mailbox, recip->context);
 	}
 	ast_unlock_path(todir);
-//	notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag);
-	
+#if 0
+    /* XXX not implemented */
+	notify_new_message(chan, recip, NULL, recipmsgnum, duration, fmt, S_OR(chan->cid.cid_num, NULL), S_OR(chan->cid.cid_name, NULL), flag);
+#endif
 	return 0;
 }
 #endif
@@ -1189,10 +1141,10 @@
 }
 
 #if !(defined(IMAP_STORAGE) || defined(ODBC_STORAGE))
-/*static int messagecount(const char *context, const char *mailbox, const char *folder)
+static int messagecount(const char *context, const char *mailbox, const char *folder)
 {
 	return __has_voicemail(context, mailbox, folder, 0);
-}*/
+}
 
 
 static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit)
@@ -1421,7 +1373,7 @@
 }
 
 static int open_mailbox(struct vm_state *vms, struct ast_vm_user *vmu, const char *mbox_name)
-{	/*res = open_mailbox(&vms, vmu, OLD_FOLDER);*/
+{
 	int res = 0;
 	int count_msg, last_msg;
 	ast_copy_string(vms->curbox, mbox_name, sizeof(vms->curbox));
@@ -1435,15 +1387,15 @@
 	count_msg = count_messages(vmu, vms->curdir);
 	if (count_msg < 0)
 		return count_msg;
-	else
-		vms->lastmsg = count_msg - 1;
+
+	vms->lastmsg = count_msg - 1;
+
 	/*
 	The following test is needed in case sequencing gets messed up.
 	There appears to be more than one way to mess up sequence, so
 	we will not try to find all of the root causes--just fix it when
 	detected.
 	*/
-
 	if (vm_lock_path(vms->curdir)) {
 		ast_log(LOG_ERROR, "Could not open mailbox %s:  mailbox is locked\n", vms->curdir);
 		return -1;
@@ -1461,7 +1413,6 @@
 		if (res)
 			return res;
 	}
-
 	return 0;
 }
 
@@ -1875,7 +1826,7 @@
 }
 
 /*
- * XXX simply play a message.
+ * play the selected message.
  */
 static int play_message(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms)
 {
@@ -1899,15 +1850,6 @@
 	return res;
 }
 
-/*
- * XXX to be documented and implemented
- */
-/*static int forward_message(struct ast_channel *chan, char *context, struct vm_state *vms,
-			   struct ast_vm_user *sender, char *fmt, int flag,signed char record_gain)
-{
-	return 1;
-}*/
-
 #endif /* MYVM_STANDALONE */
 
 /*
@@ -1923,15 +1865,17 @@
 
 /* these are return codes for the function vm_exec_actions */
 enum exec_result_code{
- 	VMM_ERROR,	/* uninitialized, or some error occurred. */
-	VMM_JUMP,	/* jump to a specific menu */
+ 	VMM_ERROR,	    /* some error occurred. */
+	VMM_JUMP,	    /* jump to a specific menu */
 	VMM_CONTINUE,	/* stay in the current menu */
-	VMM_RETURN,	/* return from a submenu (up N steps in the stack) */
+	VMM_RETURN,	    /* return from a submenu (up N steps in the stack) */
 };
 
 struct exec_main_var {
 	char prefixstr[80];
 	char ext_context[256];
+    struct ast_category *endmenu_cat;
+    const char *endmenu_name;
 	int box;
 	int useadsi;
 	int skipuser;
@@ -2076,7 +2020,9 @@
 	msg_cfg = ast_config_load(filename, config_flags);
 	DISPOSE(vms->curdir, vms->curmsg);
 	if (!msg_cfg || msg_cfg == CONFIG_STATUS_FILEINVALID) {
+#if debug
 		ast_log(AST_LOG_WARNING, "No message attribute file?!! (%s)\n", filename);
+#endif
 		return -1;
 	}
 
@@ -2108,8 +2054,10 @@
 {
     char *cid = NULL, *num = NULL, *name = NULL;
 
+#if debug
 	if (vms->curmsg < 0)
 		ast_log(LOG_NOTICE, "No message selected\n");
+#endif
 
     if(!get_sender_cid(chan, vms, vmu, &cid)) {
     	ast_callerid_parse(cid, &name, &num);
@@ -2123,7 +2071,7 @@
 
    	pbx_builtin_setvar_helper(chan, "VM_MSG_SENDER", vms->curmsg >= 0 && num ? num : "");
 	/*DEBUG*/
-#if debug		
+#if debug
     {
 	const char * DEL;
 	const char * NOT_FIRST;
@@ -2177,24 +2125,24 @@
 	return 1;
 }
 
-static int vmm_set_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;
-
+static int parse_message_num(const char* args, struct ast_channel* chan, struct vm_state* vms, 
+        char *fold, int *num)
+{
 	int argc=0;
     char *params[30];
 	char *action = NULL;
     char buf[512];
 
-    if (result)
-        *result = NULL;
-
-	int msgnum = 0;
+    int msgnum = 0;
     char *msgfold = "";
 
-	if (args == NULL || !strlen(args))
-        return 0;
+    if (num)
+        *num = 0;
+    if (fold)
+        fold[0] = '\0';
+
+	if (args == NULL)
+        return -1;
 
     action = ast_strdupa(args);
 
@@ -2203,6 +2151,7 @@
 #if debug
     ast_log(LOG_NOTICE, "pbx_substitute_variables_helper - in: %s - out: %s\n", action, buf);
 #endif
+
 	memset(params, 0, sizeof(params));
 	argc = ast_app_separate_args(buf, ',', params, sizeof(params)/sizeof(params[0]));
     
@@ -2214,41 +2163,64 @@
         /* remove leading and trailing blanks */
     	ast_trim_blanks(action);
     	action = ast_skip_blanks(action);
-
         msgfold = ast_strdupa(action);
     }
 #if debug
     ast_log(LOG_NOTICE, "PASSED Folder: %s - Message: %d\n", msgfold, msgnum);
 #endif
-    /* if not current, change folder */
-    if (!ast_strlen_zero(msgfold) && strcmp(msgfold, "current") && 
-            strcasecmp(msgfold, vms->curbox)) {
-        if ((res = vmm_change_to(msgfold, chan, vms, vmu, vm_var, NULL))) {
-            ast_log(LOG_ERROR, "An error occurred when change to folder %s\n", msgfold);
+
+    if (fold) {
+        if (!ast_strlen_zero(msgfold) && strcmp(msgfold, "current"))    /* not current folder */
+            ast_copy_string(fold, msgfold, sizeof(fold));
+        else
+            ast_copy_string(fold, vms->curbox, sizeof(fold));
+    }
+    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;
+}
+
+static int vmm_set_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;
+	int num;
+    char fold[80];
+
+    if (result)
+        *result = NULL;
+
+	if (args == NULL)
+        return 0;
+
+    /* retrieve num and folder from the args */
+    if (parse_message_num(args, chan, vms, fold, &num) || ast_strlen_zero(fold))
+        return 1;
+
+    /* 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);
             return res;
         }
     }
-    if (!res) {
-        if (!strlen(msgfold)) {   /* msgnum is relative on the current message */
-            if ((vms->curmsg + msgnum >= 0) && (vms->curmsg + msgnum <= vms->lastmsg))
-                 vms->curmsg = vms->curmsg + msgnum;
-            else {
-    			ast_play_and_wait(chan, "vm-nomore");
-    			res = 1;
-            }
-        } else { /* msgnum is an absolute message number */
-            if ((msgnum >= 0) && (msgnum <= vms->lastmsg))
-                 vms->curmsg = msgnum;
-            else {
-    			ast_play_and_wait(chan, "vm-nomore");
-    			res = 1;
-            }
-        }
-        if (res)
-            ast_log(LOG_ERROR, "Message %d not found in %s folder - curmsg: %d, lastmsg: %d\n", msgnum, msgfold, vms->curmsg, vms->lastmsg);
-        else
-            set_channelvar(chan, vms, vmu);
-    }    
+
+    /* check if message exists in the folder */
+    if (num >= 0 && num <= vms->lastmsg)
+        vms->curmsg = num;
+    else {
+    	ast_play_and_wait(chan, "vm-nomore");
+        ast_log(LOG_ERROR, "Message %d not found in %s folder - curmsg: %d, lastmsg: %d\n", num, fold, vms->curmsg, vms->lastmsg);
+    	res = 1;
+    }
+
+    if (!res)
+        set_channelvar(chan, vms, vmu);
+
     return res;
 }
 
@@ -2256,27 +2228,46 @@
             struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
 {
     if (result)
-        *result = NULL;
+        *result = "0";
 
     if (!ast_strlen_zero(args)) {
+        /* args conteins the mailbox number, check if exists */
    		if (find_user(NULL, vmu->context, args)) {
-             *result = "1";
-   		} else {
-   			/* Sender has no mailbox */
+            if (result)
+                *result = "1";
+   		} else
+            /* the user has no mailboxes */
    			ast_verb(3, "No mailbox number '%s' in context '%s'\n", args, vmu->context);
-   		}
    	} else
         ast_verb(3, "No number passed as argument\n");
 
-    if (*result == NULL)
-        *result = "0";
     return 0;
 }
 
 static int vmm_msg_exists(const char* args, struct ast_channel* chan, struct vm_state* vms,
             struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
 {
-    return 1;
+    char *type = NULL;
+	char tempfile[PATH_MAX] = "";
+
+    int num;
+    char fold[80];
+
+    if (result)
+        *result = "0";
+
+    if (!ast_strlen_zero(args) && !parse_message_type(args, &type)) {
+        /* is a greeting message, construct its path and try if exists */
+        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)) {
+        /* check the existence of the message by number and folder */
+        make_file(tempfile, sizeof(tempfile), fold, num);
+        if (result)
+            *result = EXISTS(num, fold, tempfile, NULL) ? "1" : "0";
+    }
+    return 0;
 }
 
 static int vmm_save_into(const char* args, struct ast_channel* chan, struct vm_state* vms,
@@ -2318,6 +2309,7 @@
     return 0;
 }
 
+/* save the temporary (last recorded) message as greeting message */
 static int vmm_save_rec(const char* args, struct ast_channel* chan, struct vm_state* vms,
             struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
 {
@@ -2332,6 +2324,10 @@
     return 1;
 }
 
+static int record_voicemail(struct ast_channel *chan, struct vm_state* vms,
+		    struct ast_vm_user* vmu, struct exec_main_var* vm_var);
+
+/* record a message */
 static int vmm_record(const char* args, struct ast_channel* chan, struct vm_state* vms,
 		    struct ast_vm_user* vmu, struct exec_main_var* vm_var, char **result)
 {
@@ -2340,12 +2336,19 @@
     if (result)
         *result = NULL;
 
-    if (!parse_message_type(args, &type)) 
-        return review_record_store_delete(chan, "rec", 2, vms, vmu, vm_var);
-
+    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;
 }
 
+/* play an information message */
 int vmm_play(const char* args, struct ast_channel* chan, struct vm_state* vms, struct ast_vm_user *vmu,
 	 struct exec_main_var* vm_var, char **result)
 {
@@ -2355,6 +2358,7 @@
 	return ast_play_and_wait(chan, args);
 }
 
+/* play a number */
 int vmm_play_num(const char* args, struct ast_channel* chan, struct vm_state* vms, struct ast_vm_user *vmu,
 	 struct exec_main_var* vm_var, char **result)
 {
@@ -2366,6 +2370,7 @@
 	return say_and_wait(chan, num, chan->language);
 }
 
+/* play a message */
 static int vmm_play_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)
 {
@@ -2383,6 +2388,147 @@
 	return play_message(chan, vmu, vms);
 }
 
+/*!
+ * \brief Gets the current date and time, as formatted string.
+ * \param s The buffer to hold the output formatted date.
+ * \param len the length of the buffer. Used to prevent buffer overflow in ast_strftime.
+ * 
+ * The date format string used is "%a %b %e %r UTC %Y".
+ * 
+ * \return zero on success, -1 on error.
+ */
+static int get_date(char *s, int len)
+{
+	struct ast_tm tm;
+	struct timeval t = ast_tvnow();
+	
+	ast_localtime(&t, &tm, "UTC");
+
+	return ast_strftime(s, len, "%a %b %e %r UTC %Y", &tm);
+}
+
+/*!
+ * \brief Prompts the user and records a voicemail to a mailbox.
+ * \param chan
+ * \param ext
+ * \param options OPT_BUSY_GREETING, OPT_UNAVAIL_GREETING
+ * 
+ * 
+ * 
+ * \return zero on success, -1 on error.
+ */
+static int record_voicemail(struct ast_channel *chan, struct vm_state* vms,
+		    struct ast_vm_user* vmu, struct exec_main_var* vm_var)
+{
+	char callerid[256];
+	FILE *txt;
+	char date[256];
+	int res = 0;
+	int msgnum;
+	int duration = 0;
+	char priority[16];
+	char origtime[16];
+    char txtfile[PATH_MAX];
+	char tmpfile[PATH_MAX];
+	char tmpdur[16];
+	char fmt[80];
+	const char *category = NULL;
+	char flag[80];
+
+    ast_channel_lock(chan);
+	if ((category = pbx_builtin_getvar_helper(chan, "VM_CATEGORY"))) {
+		category = ast_strdupa(category);
+	}
+	ast_channel_unlock(chan);
+
+	ast_copy_string(fmt, vmfmts, sizeof(fmt));
+	if (!ast_strlen_zero(fmt)) {
+        char *type = NULL;
+		msgnum = 0;
+        parse_message_type("rec", &type);
+        snprintf(tmpfile ,sizeof(tmpfile), "%s%s/%s/%s", VM_SPOOL_DIR, vmu->context, vmu->mailbox, type);
+    	snprintf(txtfile, sizeof(txtfile), "%s.txt", tmpfile);
+
+		/* Store information in real-time storage */
+		if (ast_check_realtime("voicemail_data")) {
+			snprintf(priority, sizeof(priority), "%d", chan->priority);
+			snprintf(origtime, sizeof(origtime), "%ld", (long)time(NULL));
+			get_date(date, sizeof(date));
+			ast_store_realtime("voicemail_data", /*"origmailbox", vmu->mailbox,*/ "context", chan->context, "macrocontext", chan->macrocontext, "exten", chan->exten, "priority", priority, "callerchan", chan->name, "callerid", ast_callerid_merge(callerid, sizeof(callerid), chan->cid.cid_name, chan->cid.cid_num, "Unknown"), "origdate", date, "origtime", origtime, "category", S_OR(category,""), "filename", tmpfile, SENTINEL);
+		}
+
+		/* Store information */
+		txt = fopen(txtfile, "w+");
+		if (txt) {
+			get_date(date, sizeof(date));
+			fprintf(txt, 
+				";\n"
+				"; Message Information file\n"
+				";\n"
+				"[message]\n"
+/* now we're creating the message, the origmailbox information will be inserted in forward function */
+				/*"origmailbox=%s\n"*/
+				"context=%s\n"
+				"macrocontext=%s\n"
+				"exten=%s\n"
+				"priority=%d\n"
+				"callerchan=%s\n"
+				"callerid=%s\n"
+				"origdate=%s\n"
+				"origtime=%ld\n"
+				"category=%s\n",
+				/*vmu->mailbox,*/
+				chan->context,
+				chan->macrocontext, 
+				chan->exten,
+				chan->priority,
+				chan->name,
+				ast_callerid_merge(callerid, sizeof(callerid), S_OR(chan->cid.cid_name, NULL), S_OR(chan->cid.cid_num, NULL), "Unknown"),
+				date, (long)time(NULL),
+				category ? category : "");
+		} else
+			ast_log(AST_LOG_WARNING, "Error opening text file for output\n");
+
+		res = review_record_store_delete(chan, NULL, 2, vms, vmu, vm_var);
+
+		if (txt) {
+			fprintf(txt, "flag=%s\n", flag);
+			if (duration < vmminsecs) {
+				fclose(txt);
+				if (option_verbose > 2) 
+					ast_verbose(VERBOSE_PREFIX_3 "Recording was %d seconds long but needs to be at least %d - abandoning\n", duration, vmminsecs);
+				ast_filedelete(tmpfile, NULL);
+				unlink(tmpfile);
+				if (ast_check_realtime("voicemail_data")) {
+					ast_destroy_realtime("voicemail_data", "filename", tmpfile, SENTINEL);
+				}
+			} else {
+				fprintf(txt, "duration=%d\n", duration);
+				fclose(txt);
+				if (ast_fileexists(tmpfile, NULL, NULL) <= 0) {
+					ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n");
+					unlink(tmpfile);
+					if (ast_check_realtime("voicemail_data")) {
+						ast_destroy_realtime("voicemail_data", "filename", tmpfile, SENTINEL);
+					}
+				} else {
+					if (ast_check_realtime("voicemail_data")) {
+						snprintf(tmpdur, sizeof(tmpdur), "%d", duration);
+						ast_update_realtime("voicemail_data", "filename", tmpfile, "duration", tmpdur, SENTINEL);
+					}
+                }
+			}
+		}
+
+		if (!res && duration < vmminsecs)
+            res = 1;
+	} else
+		ast_log(AST_LOG_WARNING, "No format for saving voicemail?\n");
+
+	return res;
+}
+
+/* play, record, store and delete a greeting message or a temporary message */
 static int review_record_store_delete(struct ast_channel *chan, const char *type, int option, 
              struct vm_state* vms, struct ast_vm_user* vmu, struct exec_main_var* vm_var)
 {
@@ -2390,7 +2536,7 @@
     int duration = 0;
 	char recordfile[PATH_MAX] = "";

[... 1239 lines stripped ...]



More information about the svn-commits mailing list