

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <conio.h>
#include <time.h>
#include <dos.h>  /* 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);
}


