char *dialv = "Dialing functions CTOS Version-2.00, May 92"; /* C K D I A L -- Dialing program for connection to remote system */ /* Author: Herm Fischer, Litton Data Systems, Van Nuys CA (HFISCHER@USC-ECLB) */ /* modified for CTOS C2.0 by Joel Dunn, UNC-CH, October 1986 */ /* * modified to add support for RACAL modem by Doug Drury - ITT-FSC, May 1991 * modified to remove forced tone dialing from hayes modem December 1991 */ #include "ctermi.h" #include "ctcmd.h" extern int local, speed, flow, mdmtyp, techo; extern char ttname[], sesfil[]; #define HAYES 1 /* for mdmtyp settings */ #define VENTEL 2 #define HAYESNV 3 /* internal use, non-verbal V0 setting */ #define RACAL 4 struct keytab mdmtab[] = { /* Modem types for command parsing */ "direct", 0, 0, "hayes", HAYES, 0, "ventel", VENTEL, 0, "racal", RACAL, 0 }; int nmdm = (sizeof(mdmtab) / sizeof(struct keytab)); #define DIALING 4 /* for ttvt parameter */ #define CONNECT 5 #define CONNECTED 1 /* for completion status */ #define FAILED 2 #define BUSY 3 static int tries = 0; #define LBUFL 100 static char lbuf[LBUFL]; static char *lbp; static stripp(s) char *s; { /* parity stripper aid */ for ( ; *s ; *s++ &= 0177 ); } /* D I A L -- Dial up the remote system */ dial(telnbr) char *telnbr; { char c; char *i; int waitct, status; char errmsg[50], *erp; int augMdm; /* mdmtyp with switch settings added */ int mdmEcho = 0; /* assume modem does not echo */ int n,m; if (!mdmtyp) { printf("Sorry, you must 'set modem' first\n"); return(-2); } augMdm = mdmtyp; /* internal use, to add dialer switches info*/ if (!local) { printf("Sorry, you must 'set line' first\n"); return(-2); } if (speed < 0) { printf("Sorry, you must 'set speed' first\n"); return(-2); } if (ttopen(ttname,local,mdmtyp) < 0) {/* Open, no wait for carrier */ erp = errmsg; sprintf(erp,"Sorry, can't open %s",ttname); perror(errmsg); return(-2); } /* cont'd... */ /* interdigit waits for tone dial */ /* ...dial, cont'd */ waitct = 1*strlen(telnbr) ; /* compute time to dial worst case */ switch (augMdm) { case HAYES: case HAYESNV: waitct += 35; /* dial tone + carrier waits + slop */ for (i=telnbr; *i; i++) if (*i == ',') waitct += 2; break; case VENTEL: waitct += 10; /* guess actual time for dialtones */ waitct += 10; /* ventel's apparent patience for carrier */ for (i=telnbr; *i; i++) if (*i == '%') waitct += 5; break; case RACAL: waitct += 35; break; } if (techo) { printf("Dialing thru %s, speed %d, number %s.\r\n",ttname,speed,telnbr); printf("The timeout for completing the call is %d seconds.\r\n",waitct); } /* Condition console terminal and communication line */ /* place line into "clocal" dialing state */ if ( ttpkt(speed,flow) < 0 ) { printf("Sorry, Can't condition communication line\n"); return(-2); } /* Put modem into command state */ ttflui(); /* flush input buffer if any */ #define OKAY 1 /* modem attention attempt status */ #define IGNORE 2 #define GOT_O -2 #define GOT_A -3 switch (augMdm) { case HAYES: case HAYESNV: while(tries++ < 4) { ttol("AT\r",3); /* signal for attention, look for response */ delay(10); /* give modem a chance to echo */ status = 0; while ( status <= 0 ) { switch (ttinc(0) & 0177) { case 'A': /* echoing, ignore */ status = GOT_A; break; case 'T': if (status == GOT_A) { mdmEcho = 1; /* expect echoing later */ status = 0; break; } status = IGNORE; break; case '\n': case '\r': status = 0; break; case '0': /* numeric result code */ augMdm = HAYESNV; /* nonverbal result codes */ status = OKAY; break; case 'O': /* maybe English result code*/ status = GOT_O; break; case 'K': if (status == GOT_O) { augMdm = HAYES; status = OKAY; break; } /* else its default anyway */ default: status = IGNORE; break; } } if (status == OKAY) break; if (status == IGNORE) ttflui(); delay(10); /* wait before retrying */ } if (status == OKAY) break; printf("Sorry, can't initialize modem\n"); ttpkt(speed,flow); /* cancel dialing state ioctl */ return(-2); /* cont'd... */ /* interdigit waits for tone dial */ /* ...dial, cont'd */ case VENTEL: ttoc('\r'); /* Put Ventel into command mode */ delay(10); ttoc('\r'); delay(10); ttoc('\r'); while( (ttinc(0) & 0177) != '$'); break; case RACAL: for (n=0; n < LBUFL; n++) lbuf[n] = '\0'; lbuf[0] = 0005; lbuf[1] = '\r'; ttol(lbuf,2); /* Get 's attention */ for (n=0; n < LBUFL; n++) lbuf[n] = '\0'; n = ttinl(lbuf,LBUFL,waitct,'*'); /* look for prompt */ if (n < 0) { printf("Sorry, can't initialize modem\n"); status = FAILED; ttpkt(speed,flow); return(-2); } break; /* Got modems attention! */ default: exit(0); /* should never get here */ } delay(10); /* give things settling time */ /* Dial the number */ switch (augMdm) { case HAYES: case HAYESNV: sprintf(lbuf,"AT D %s\r",telnbr); break; case VENTEL: sprintf(lbuf,"",telnbr); break; case RACAL: sprintf(lbuf,"D\r"); /* just send dial command modem will */ break; /* prompt for number */ } ttflui(); /* clear out stuff from waking modem up */ ttol(lbuf,strlen(lbuf)); /* send dialing string */ ttflui(); /* clear out stuff from dialing */ /* cont'd... */ /* interdigit waits for tone dial */ /* ...dial, cont'd */ /* Check for connection */ status = 0; while (status == 0) { switch (augMdm) { case HAYES: for (n = 0; n < LBUFL; n++) lbuf[n] = '\0'; n = ttinl(lbuf,LBUFL,waitct,'\n'); if (n > 2) { lbp = lbuf; while ((*lbp == '\r') || (*lbp == '\n')) lbp++; stripp(lbp); if (strncmp(lbp,"CONNECT",7) == 0) status = CONNECTED; else if (strncmp(lbp,"BUSY",4) == 0) status = BUSY; else if (strncmp(lbp,"NO ",3) == 0) status = FAILED; } else if (n < 0) status = FAILED; break; case HAYESNV: c = ttinc(0) & 0177; if (mdmEcho) { /* sponge up dialing string */ mdmEcho = c!='\r'; /* until return is echoed */ break; } if (c == '1') status = CONNECTED; else if (c == '5') status = CONNECTED; else if (c == '9') status = CONNECTED; else if (c == '7') status = BUSY; else if (c == '3') status = FAILED; else if (c == '4') status = FAILED; else if (c == '6') status = FAILED; else if (c == '8') status = FAILED; break; case VENTEL: delay(waitct*10); /* time to allow for connecting */ if ( (ttinc(0) & 0177) == '!') status = CONNECTED; break; case RACAL: printf("\n"); for (n=0; n < LBUFL; n++) lbuf[n] = '\0'; n = ttinl(lbuf,LBUFL,waitct,'?'); /* look for NUMBER? prompt */ for (n = 0; n < LBUFL; n++) { if (lbuf[n] == 'N') break; } for (m=0; lbuf[n] != '\0'; n++) { lbuf[m] = lbuf[n]; m++; } lbp=lbuf; stripp(lbp); if (strncmp(lbp,"NUMBER?",7) != 0) { status = FAILED; /* didn't get the NUMBER? prompt */ break; } sprintf(lbuf, "%s\r", telnbr); ttflui(); ttol(lbuf,strlen(lbuf)); /* now DIAL */ ttflui(); for (n=0; n < LBUFL; n++) lbuf[n] = '\0'; n = ttinl(lbuf,LBUFL,waitct,'!'); /* look for ON LINE! */ for (n = 0; n < LBUFL; n++) { if (lbuf[n] == '!') break; } for (m=0, n=n-7; m < 8; m++) { lbuf[m] = lbuf[n]; n++; } lbp = lbuf; stripp(lbp); if (!strncmp(lbp, "ON LINE!", 8)) status = CONNECTED; else status = FAILED; break; } } /* Place line into modem-control (non-clocal) state */ if (status == 0) printf("Sorry, Can't get response from modem\r\n"); else if (status == CONNECTED) printf("Connected!\n"); else if (status == FAILED) printf("Sorry, No Carrier\r\n"); else if (status == BUSY) printf("Sorry, Line Busy\r\n"); else printf("Failed to complete call\r\n"); ttpkt(speed,flow); /* cancel dialing state ioctl */ return((status==CONNECTED) ? 0 : -2); }