#include #include #include #include #include #include #include /* Dos-specific functions are used to get date/time. */ #include "common.h" /* Definitions/routines Al uses lots. */ #include "modem.h" /* Routines for accessing the modem. */ #include "voicemdm.h" /* Voicemodem routines. */ #define MAXIMUM_MESSAGE_NUMBER 100 FILE *message_file; int port_number; /* ...from the command line. */ int rings_to_answer_in=4,ring_count,next_message_number,call_beeper_flag=0; int ring_result; /* For saving the return code from the ring-detecting subroutine. */ int message_number,result; /*------------------------- Subroutines ------------------------------------- */ void serious_error(char *the_message) { fossil_close(port_number,0); printf("Serious error encountered; fossil port closed.\n"); fatal_error(the_message); } void owner_options(void) { int password_retry_count=0; while (1) /* Ask for password until ok or too many retries. */ { voicemdm_play_file(port_number,"PROMPTS\\ENTERPAS.MSG",0); voicemdm_play_beep(port_number); voicemdm_record_dtmf_string(port_number,15); /* Get password. */ if (!strcmp(voicemdm_dtmf_string,"1234")) /* Correct password? */ break; if (!strcmp(voicemdm_dtmf_string,"12345")) /* Get ready to receive update password? */ break; voicemdm_play_file(port_number,"PROMPTS\\INVALID.MSG",0); if (password_retry_count++ == 3) return; } if (!strcmp(voicemdm_dtmf_string,"12345")) /* Update password entered? */ { /* zzz This is where we could call a batch file to receive the file. */ /* It should probably also hang up, so that things don't goof up. */ return; } voicemdm_play_file(port_number,"PROMPTS\\GOODPASS.MSG",0); printf("Getting ready to play one beep for each message on file.\n"); message_number = 0; while (message_number < MAXIMUM_MESSAGE_NUMBER) { itoa(message_number,temp_string,10); strcat(temp_string,".MSG"); message_file = fopen(temp_string,"rb"); if (message_file == NULL) /* No message file with this number? */ { message_number++; continue; } fclose(message_file); printf(" Playing beep for message number %d now.\n",message_number); voicemdm_play_beep(port_number); /* One beep for each message we have. */ wait(0); /* Wait until end of second. */ message_number++; } rings_to_answer_in = 4; message_number = 0; while (message_number < MAXIMUM_MESSAGE_NUMBER) /* Play all messages. */ { itoa(message_number,temp_string,10); strcat(temp_string,".MSG"); message_file = fopen(temp_string,"rb"); if (message_file == NULL) /* No message file with this number? */ { message_number++; continue; } fclose(message_file); printf(" Playing message number %d (file %s).\n",message_number,temp_string); voicemdm_play_file(port_number,"PROMPTS\\PLAYINGM.MSG",0); voicemdm_play_file(port_number,temp_string,0); voicemdm_play_beep(port_number); voicemdm_play_file(port_number,"PROMPTS\\MENU1.MSG",0); result = voicemdm_dtmf_string[0]; if (!result) /* No selection made during outgoing message? */ { voicemdm_play_beep(port_number); result = voicemdm_record_dtmf_key(port_number,10); } if (result == 0) /* Timeout? */ { voicemdm_play_file(port_number,"PROMPTS\\INVALID.MSG",0); return; /* Just quit. */ } if (result == (int)'3') /* Delete? */ { voicemdm_play_file(port_number,"PROMPTS\\DELETING.MSG",0); printf("Deleting message file %s now....\n",temp_string); unlink(temp_string); message_number++; continue; } if (result == (int)'6') /* Next message? */ { voicemdm_play_file(port_number,"PROMPTS\\SKIPPING.MSG",0); printf("Skipping to next message.\n"); message_number++; continue; } if (result == (int)'7') /* Repeat message? */ { printf("Repeating message.\n"); continue; } /* Just leave the same message number, so it's processed again. */ voicemdm_play_file(port_number,"PROMPTS\\INVALID.MSG",0); printf("Staying on message %d because of invalid input.\n",message_number); } voicemdm_play_file(port_number,"PROMPTS\\NO_MORE.MSG",0); return; /* Indicate that no messages were saved during this call. */ } int process_call(void) { printf("Playing greeting message....\n"); voicemdm_play_file(port_number,"PROMPTS\\GREETING.MSG",0); if (voicemdm_dtmf_string[0] == '*') /* * pressed during greeting? */ { owner_options(); return(1); } voicemdm_play_beep(port_number); printf("Recording incoming message now....\n"); itoa(next_message_number,temp_string,10); strcat(temp_string,".MSG"); if (voicemdm_record_file(port_number,temp_string,0)) { printf("Message not saved due to dial or busy tone or the like during recording.\n"); return(1); } if (voicemdm_dtmf_string[0] == '*') /* * pressed while recording message? */ { owner_options(); return(1); } voicemdm_play_beep(port_number); call_beeper_flag = 1; rings_to_answer_in = 2; return(0); } void check_beeper_flag(void) { printf("Checking beeper flag to see if we should beep someone.\n"); if (!call_beeper_flag) return; printf(" Beeper flag set; calling Al's beeper now....\n"); wait(3); printf(" Setting modem parameters for dial-out.\n"); send_to_modem(port_number,"AT #BDR=16 #CLS=8 #VRA=55 #VRN=100"); send_to_modem(port_number,CR_string); if (waitfor(port_number,"OK",3,0)) { printf("Unable to set up modem for dial-out!%s\n",BELL_string); wait(1); return; } wait(1); printf(" Dialing beeper now.\n"); send_to_modem(port_number,"*70,,ATDT668-2675"); send_to_modem(port_number,CR_string); if (waitfor(port_number,"VCON",15,0)) { printf(" Quitting beeper dial-out; didn't get VCON for 15 seconds after dialing!%s\n",BELL_string); return; } if (ring_result == 1) /* Which phone number did this call arrive on? */ strcpy(voicemdm_dtmf_string,"3839853"); else strcpy(voicemdm_dtmf_string,"3161995"); if (!voicemdm_play_dtmf_string(port_number)) /* Everything ok? */ call_beeper_flag = 0; /* Reset flag. */ wait(1); send_to_modem(port_number,"ATH"); send_to_modem(port_number,CR_string); if (waitfor(port_number,"OK",5,0)) /* Some sort of trouble hanging up? */ { printf(" Trouble hanging up!%s\n",BELL_string); call_beeper_flag = 1; return; } wait(1); trash_modem_output(port_number,0); printf(" Done calling beeper.\n"); call_beeper_flag = 0; /* Get rid of flag now that we've called. */ } /*------------------------------- Main Program -------------------------------*/ int main(int argc, char *argv[]) { char input_char; if (argc <= 1) /* Our 1 required argument not specified? */ serious_error("Missing argument; supply the comm. port number."); port_number = atoi(argv[1]); if (fossil_init(port_number)) serious_error("Unable to initialize comm. port / fossil driver"); fossil_set_handshaking(port_number,2); fossil_set_dtr(port_number,1); while (1) /* This is the answering machine loop, from RING to hangup. */ { voicemdm_reset_modem(port_number); voicemdm_set_modem_parameters(port_number); /* This needs to be done for each call. */ ring_count = 0; printf("Searching for next unused message number.\n"); next_message_number = 0; while (1) { itoa(next_message_number,temp_string,10); strcat(temp_string,".MSG"); message_file = fopen(temp_string,"rb"); if (message_file == NULL) break; fclose(message_file); next_message_number++; } printf(" The next unused message number is %d.\n",next_message_number); if (next_message_number) /* 0.MSG on file? */ rings_to_answer_in = 2; printf(" The phone will be answered in %d rings this time.\n",rings_to_answer_in); if (call_beeper_flag) printf(" Beeper flag is set! We'll call beeper soon.\n"); else printf(" Beeper flag not set right now.\n"); printf("Waiting for a call; hit escape to end program....\n"); ring_result = voicemdm_wait_for_ring(port_number,rings_to_answer_in,180); if (ring_result == 0) /* Escape key pressed? */ break; /* Regular exit. */ if (ring_result == 3) /* We timed out? Check things. */ { if (next_message_number) /* Does the file 0.MSG exist, in effect? */ printf("There are messages on the answering machine!\n%s",BELL_string); check_beeper_flag(); continue; } if (ring_result == 4) /* Special key ('r') hit while waiting for ring? */ { printf("LOCAL RECORDING: Enter the name of the file to record: "); gets(temp_string); voicemdm_record_file(port_number,temp_string,1); continue; } if (ring_result == 5) /* Special key 'p' hi while waiting for ring? */ { printf("LOCAL PLAYING: Enter the name of the file to play: "); gets(temp_string); voicemdm_play_file(port_number,temp_string,1); continue; } printf("Answering call now....\n"); send_to_modem(port_number,"ATA"); /* Answer the call. */ send_to_modem(port_number,CR_string); if (waitfor(port_number,"VCON",7,0)) serious_error("Didn't get VCON after ATA command."); if (!ring_result) /* Regular old rings or double rings? */ { printf("This call came in on the primary telephone number (single rings detected).\n"); process_call(); } else { printf("This call came in on the second telephone number (double rings detected).\n"); process_call(); /* We got double-rings; we could put another routine here.*/ } printf("Hanging up now.\n"); voicemdm_play_file(port_number,"PROMPTS\\GOODBYE.MSG",0); send_to_modem(port_number,"ATH"); /* Hang up now. */ send_to_modem(port_number,CR_string); if (waitfor(port_number,"OK",5,0)) /* Did get get OK? */ serious_error("Couldn't hang up the darned modem!"); check_beeper_flag(); } printf("Resetting modem.\n"); send_to_modem(port_number,"ATZ"); send_to_modem(port_number,CR_string); if (waitfor(port_number,"OK",5,0)) serious_error("Didn't get OK after ATZ command to reset modem!"); printf("Closing modem port and dropping DTR.\n"); fossil_close(port_number,0); /* Close port, dropping DTR. */ printf("Successful exit!\n"); return(0); }