One 9 is enough. I tried it twice at the gate, and it worked like a charm both times. So I'm going to declare victory. Thanks very much to everyone for your help. If I decide to follow up on the MCU version of this, I'll be back. I'm probably the last one in the country that would set up the gate to call their land line, but I'll post the code in case anyone ever needs it. It will be obvious that I'm not fluent in C. By the way, in addition to being Jenny's number, 8675309 is a also prime number. This may mean that Jenny was prime.
/*
This program runs under XP on a Toshiba L35-S2171 laptop with an Agere
software modem built in. It monitors Caller ID for the gate's phone
number in a gated community. If there's a match, it goes offhook,
then dials 9, then hangs up. This is supposed to prevent the situation
where the visitor calls from the gate, but the call goes to voicemail,
so the visitor is stuck. The LCC compiler was used. It's a console app.
*/
#include <stdio.h>
#include <conio.h>
char phonenum[] = "8008675309"; //the gate's calling number
char comport[] = "\\\\.\\COM3"; //COM port of modem
char AT1[] = "AT+VCID=1 E0 V1 Q0\r\n"; //enable Caller ID
char *pAT1 = &AT1;
char AT2[] = "ATS11=255 S93=5 X3 DT9;\r\n"; //answer and dial 9
char *pAT2 = &AT2;
char AT3[] = "ATH\r\n"; //hang up
char *pAT3 = &AT3;
char AT4[] = "ATZ\r\n"; //reset modem
char *pAT4 = &AT4;
char *ret;
int Outwrote = 0;
int *pOutwrote = &Outwrote;
char Inbyte = 0;
char *pInbyte = &Inbyte;
int Fetched = 0;
int *pFetched = &Fetched;
int i;
int j;
char buf[250]; //buffer for Caller ID message
char *pbuf = &buf;
int main(){
Entry:
for (i = 0; i < 250; i++) { //clear buffer
buf[i] = 0;
}
HANDLE Port = CreateFile(comport, //open COM port
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if (Port == INVALID_HANDLE_VALUE) {
int err = GetLastError();
printf("Error opening port \r\n");
return err;
}
else {
printf("COM port Opened \r\n");
}
PurgeComm(Port, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
COMMTIMEOUTS timeouts = {0}; //set timeouts
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutConstant = 100;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 100;
timeouts.WriteTotalTimeoutMultiplier = 0;
SetCommTimeouts(Port, &timeouts);
DCB dcbMasterInitState; //save state of COM port
GetCommState(Port, &dcbMasterInitState);
DCB dcbMaster = dcbMasterInitState; //make changes
dcbMaster.BaudRate = 115200;
dcbMaster.Parity = NOPARITY;
dcbMaster.ByteSize = 8;
dcbMaster.StopBits = ONESTOPBIT;
SetCommState(Port, &dcbMaster);
WriteFile(Port,pAT1,strlen(AT1),pOutwrote,NULL); //enable Caller ID
Sleep(1000);
do {
ReadFile(Port,pInbyte,1,pFetched,NULL); //read and dump any response
}
while (Fetched > 0);
do { //look for "RING" message to begin
Sleep(500);
ReadFile(Port,pInbyte,1,pFetched,NULL);
printf(".");
}
while (Fetched == 0);
Sleep(1000); //allow time for Caller ID to complete
ReadFile(Port,pbuf,250,pFetched,NULL); //read in Caller ID message
Sleep(100);
ret = strstr(buf,phonenum); //does message contain the right number?
if(ret) {
printf("Gate Call\r\n"); //yes - dial 9 then hang up
WriteFile(Port,pAT2,strlen(AT2),pOutwrote,NULL);
Sleep(5000); //minimum 3 sec delay to dial after off-hook
WriteFile(Port,pAT3,strlen(AT3),pOutwrote,NULL);
Sleep(500);
}
else printf("Not Gate\r\n"); //no
WriteFile(Port,pAT4,strlen(AT4),pOutwrote,NULL); //reset everything and close COM port
Sleep(10000);
SetCommState(Port, &dcbMasterInitState);
sleep(60);
CloseHandle(Port);
Port = INVALID_HANDLE_VALUE;
goto Entry; //start over
}