home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
nisttime.carsoncity.k12.mi.us
/
nisttime.carsoncity.k12.mi.us.tar
/
nisttime.carsoncity.k12.mi.us
/
pub
/
lockclock
/
dial_l.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-18
|
8KB
|
239 lines
int dial(int alt_num)
{
/*
this subroutine dials a hayes modem connected
to the com port using calls to wrtbuf and rdbuf.
if the first character in the dialing sequence (after
the ATD) is M (or m), then "manual" dialing is assumed.
in that case, just return and wait for received message.
the manual dialing capability is retained for compatibility
with the ACTS version and will not normally be used.
if echo is set to zero by the configuration file, then
echoes are not expected from the modem. if echo is not zero
then echoes are expected and a fatal error exists if
echoes are not received within the time out period.
this version of the program (7 jan. 92) uses time-out values
that are specified in units of clock ticks. this method
eliminates the need for time-out values that are scaled by
the CPU speed and is intended to be better suited to the
faster 386 and 486 configurations where cpuspd sometimes does
not give the correct relative speed value so that the
time-outs are wrong (usually too short).
this version is slightly different from the version that is
used with ACTS. The ACTS version prints a message on the
terminal in case of a problem; this version does not
do any output but simply returns a status value. the
status values are +1 for connection, 0 for no answer and
negative values for various modem problems and time-outs.
(version of 11 March 1996). If the primary ACTS telephone
number does not work and if the problem appears to be in
the ACTS service (rather than the modem itself), then the
program will try again with the alternate telephone number.
if input parameter alt_num is not zero then the alternate
ACTS number is tried immediately.
*/
#include "getdif.h"
#include <stdio.h>
#ifdef IBMPC
#include <dos.h>
#endif
void wrtbuf(),wait1s();
void hangup();
int rdbuf();
void putmsg(char *); /*writes message to error file */
char msgbuf[80]; /*holds message for putmsg */
char *ptr;
char ans[400],cc;
char ie1 = 'K';
char ie2 = '\n';
char ie3 = '\r';
char ie4 = 'Y'; /* response is BUSY */
char ie5 = 'T'; /* response is CONNECT */
char ie6 = 'R'; /* response is NO ANSWER or NO CARRIER */
char ie7 = -120;
int j,k,kk,stat;
#ifdef IBMPC
int tmo = -200; /* time-out limit, roughly 10 seconds */
int ttmo = -900; /* wait up to 50 sec for number to be dialed */
#endif
#ifdef SUN
int tmo = -10;
int ttmo= -200; /* this is a LONG time-out. */
#endif
again: /*try to dial the number from the start */
/*
send string ATZ, expect response of OK unless echo == 0
*/
ptr="ATZ\r";
wrtbuf(ptr);
if( (rdbuf(ans,ie1,ie7,ie7,tmo) == 0) && (echo != 0) )
{
if(retry-- == 0) return(-1);
hangup();
goto tryit; /*wait a bit and try again*/
}
/*
look for <cr><lf> following the OK
*/
if( (rdbuf(ans,ie2,ie7,ie7,tmo) == 0) && (echo != 0) )
{
if(retry-- == 0) return(-2);
hangup();
goto tryit;
}
wait1s();
/*
set: echo on, full duplex, speaker off, basic word responses on
expect echo of OK <cr>
*/
ptr="AT E1 M1 Q0 V1\r";
wrtbuf(ptr);
if( (rdbuf(ans,ie1,ie7,ie7,tmo) == 0) && (echo !=0) ) return(-3);
wait1s();
/*
now send the dialing string. switch to the alternate number
when there are only three re-tries left. Since the default
value for retry is 6, this results in 3 tries with the primary
number followed by three with the alternate one. Try the
alternate number immediately if input parameter alt_num
is non zero.
*/
if( (retry > 3) && (alt_num == 0) ) wrtbuf(number);
else wrtbuf(alt_number);
if( (rdbuf(ans,ie3,ie7,ie7,tmo) == 0) && (echo !=0) ) return(-4);
/*
now wait for response from modem. there are several
possibilities as follows:
1. modem does not response at all. this is almost
certainly an error -- flag immediately if echo
mode enabled. otherwise parse response.
2. read terminates on R from RINGING -- only some modems
can do this -- go back and read some more. do not
reset buffer pointer here since response is only
partial.
3. read terminates on R from NO ANSWER or NO CARRIER --
that's all folks. Same thing if read terminates on Y
from BUSY.
4. read terminates on T from CONNECT -- the kind of
stuff we like to see.
5. read terminates on T from AT or ATDT -- throw
it away and read some more. this should only
happen on SUN machines where the reads are buffered
on IBMPC where the input port is not buffered the
ATDT string should have been overwritten by the
digits of the number.
the variable stat is 0 until we are finished and is
1 when the final modem status has been received
kk points to the origin of the buffer for the current
read. it is zero unless a partial answer has been
received (NO CAR for example).
*/
stat=0;
kk=0;
do
{
/*
read some stuff, abort if timeout and no response
(modem should have given status of call).
when rdbuf returns, k points to terminator relative to
origin which is kk.
*/
if( (k=rdbuf(&ans[kk],ie4,ie5,ie6,ttmo)) == 0 ) return(-5);
/*
if we read more than one character, and
if end of message is ER, we have final modem status.
answer is either NO ANSWER or NO CARRIER. bad news
either way but we are finished.
likewise if the message ends in SY, then the call
status is BUSY. Also bad news, but we are finished
*/
if( (k > 1) && (ans[kk+k-1] == 'R') && (ans[kk+k-2] == 'E'))
stat=1;
if( (k > 1) && (ans[kk+k-1] == 'Y') && (ans[kk+k-2] == 'S'))
stat=1;
/*
if we read more than one character and
if end of message is CT we have final modem status.
answer is CONNECT (possibly CONNECT 1200).
*/
if( (k > 1) && (ans[kk+k-1] == 'T') && (ans[kk+k-2] == 'C') )
stat=1;
/*
if we terminated on an R and it is the first character, then
it is the R of RINGING. if we read more than one character
and we ended with an R and the previous character was not E,
then we are in the midst of NO CARRIER -- keep on reading.
*/
if( (kk+k > 1) && (ans[kk+k-1] == 'R') && (ans[kk+k-2] != 'E') )
kk += k;
if( (kk+k == 1) && (ans[0] == 'R') )
kk += k;
/*
if we have read 200 characters and still not found a
terminator of some sort then something is wrong. there
is probably lots of line noise. in any case, we will
abandon this call and try again.
*/
if( (stat == 0) && (kk > 200) )
{
sprintf(ans,"NO CARRIER");
stat = 1; /*get out of the loop*/
}
} while (stat == 0);
/*
since modem response was set to words, skip leading
extraneous stuff including remnants of number and possible
leading newline. first loop ends when a letter is found,
and j points to it.
*/
for(j=0; ( (j < k+kk) && (ans[j] < 'A')) ; j++) ;
for(k=j; (cc=ans[k]) != 0; k++)
{
if(cc == 'T')
{
if(retry > 3) return(1); /*connect on default number!*/
return(11); /*connect on alternate number*/
}
}
/*
if this attempt did not work and retries are either
exhausted or disabled then too bad. Return to caller
with a failure status
else if manual retries have been requested, then prompt
operator and either retry or exit depending on response.
else if automatic retries were selected try again. Decrement
retry to keep track of how many times we have done this.
Eventually there will be no more left and then
we will return to caller with a failure status
*/
if(retry == 0) return(0);
/*
if we are here then retry > 0 and automatic retries are
selected and available. So decrement the count and then
go around again. This loop will either eventually connect
or retry will go to 0 and we will return a failed status
above.
*/
retry--;
tryit: /* wait a few seconds and then try it again */
sprintf(msgbuf,"\nfailed in dial, retry=%d\n",retry);
putmsg(msgbuf);
putmsg(ans);
wait1s();
wait1s();
goto again;
}