root@uiucuxc.UUCP (09/18/84)
Here's a Hayes driver that was whipped together and works reliably (for us). I'd be interested in any changes that make it reliable for someone else. Paul Pomes UUCP: {ihnp4,pur-ee}!uiucdcs!uiucuxc!paul harpo!uiucuxc!paul ARPA: paul%uiucuxc%uiuc.csnet@csnet-relay.arpa CSNET: paul%uiucuxc@uiuc US Mail: Univ of Illinois, CSO, 1304 W Springfield Ave, Urbana, IL 61801 ----Cut Here----- #define DEBUG #include "tip.h" /* ** Hayes 1200 modem driver ** ** It's assumed the modem is set up with the following dip switch settings: ** ** SW 1: Up - Normal DTR action ** SW 2: Dn - Terse responses (numeric codes 0 to 5) ** SW 3: Dn - Enable modem response ** SW 4: Dn - Disable echo of command characters ** SW 5: Dn - Auto-answer disabled ** SW 6: Dn - Force CD and DSR ready ** SW 7: Up - Single line RJ11C/W jacks ** SW 8: Dn - Enable command mode ** ** Written 27 June 1984 by Paul Pomes, University of Illinois, CSO ** ** Copyright University of Illinois, 1984. Permission is granted for ** unlimited modification, use, and distribution, except that this ** software may not be sold for profit directly nor as part of any ** software package. This software is made available with no warranty ** of any kind, express or implied. */ /* modem commands ** ** INIT sets the escape code to meta-U, theoretically denying users the ** use of the escape code. However BREAK puts the modem into command mode ** anyway. *sigh* To cover up as much as possible, the guard time is set ** to five seconds on either side of the BREAK. */ #define INIT1 "ATS2=149\r" #define INIT2 "ATS12=255\r" #define SYNC "AT\r" /* sync the modem serial port to the ** tty speed */ /* result codes returned by modem in form "n\r" */ #define OK 0 #define CONNECT 1 #define RING 2 #define NO_CARRIER 3 #define ERROR 4 #define CONNECT_1200 5 static int sigALRM(); static int timeout = 0; static jmp_buf timeoutbuf; #ifdef DEBUG static char response[40], *r_pnt; #endif hayes_dialer(num) char *num; { register int connected = 0; char cbuf[40]; if (boolean(value(VERBOSE))) printf("\nstarting call..."); #ifdef DEBUG for (r_pnt = response; r_pnt < response+40; r_pnt++) *r_pnt = 0; #endif ioctl(FD, TIOCCDTR, 0); sleep(2); ioctl(FD, TIOCSDTR, 0); ioctl(FD, TIOCFLUSH, 0); sleep(1); /* ** Sync the modem to the tty port speed */ if (write(FD, SYNC, strlen(SYNC) != strlen(SYNC))) { printf("can't write first sync to hayes..."); exit(0); } if (write(FD, SYNC, strlen(SYNC) != strlen(SYNC))) { printf("can't write second sync to hayes..."); exit(0); } sleep(1); ioctl(FD, TIOCFLUSH, 0); if (cmd(SYNC) != '0') { printf("can't sync hayes to tty port speed..."); #ifdef DEBUG printf("Responses: "); for (r_pnt = response; *r_pnt; r_pnt++) printf("%d ", *r_pnt); putchar('\n'); #endif return (0); } /* * Configure; then dial. */ if (cmd(INIT1) != '0') { printf("can't INIT1 hayes..."); #ifdef DEBUG printf("Responses: "); for (r_pnt = response; *r_pnt; r_pnt++) printf("%d ", *r_pnt); putchar('\n'); #endif return (0); } sleep(1); if (cmd(INIT2) != '0') { printf("can't INIT2 hayes..."); #ifdef DEBUG printf("Responses: "); for (r_pnt = response; *r_pnt; r_pnt++) printf("%d ", *r_pnt); putchar('\n'); #endif return (0); } (void) sprintf(cbuf, "ATDT %s\r", num); if (write(FD, cbuf, strlen(cbuf)) != strlen(cbuf)) { printf("dial command write error to hayes..."); return(0); } connected = detect("1\r"); #ifdef ACULOG if (timeout) { char line[80]; sprintf(line, "%d second dial timeout", number(value(DIALTIMEOUT))); logent(value(HOST), num, "hayes", line); } #endif if (timeout) hayes_disconnect(); /* insurance */ return (connected); } hayes_disconnect() { if (FD > 0) ioctl(FD, TIOCCDTR, 0); close(FD); } hayes_abort() { char c = '\r'; if (FD > 0) { write(FD, &c, 1); ioctl(FD, TIOCCDTR, 0); } close(FD); } static int sigALRM() { timeout = 1; #ifdef DEBUG printf("Timeout: Responses: "); for (r_pnt = response; *r_pnt; r_pnt++) printf("%d ", *r_pnt); putchar('\n'); #endif longjmp(timeoutbuf, 1); } static int cmd(s) register char *s; { char c, cr; int (*f)(); write(FD, s, strlen(s)); f = signal(SIGALRM, sigALRM); if (setjmp(timeoutbuf)) { hayes_abort(); signal(SIGALRM, f); return (1); } alarm(number(value(DIALTIMEOUT))); read(FD, &c, 1); read(FD, &cr, 1); #ifdef DEBUG *r_pnt++ = c; *r_pnt++ = cr; #endif while (cr != '\r') { c = cr; read(FD, &cr, 1); cr &= 0177; #ifdef DEBUG *r_pnt++ = cr; #endif } alarm(0); signal(SIGALRM, f); c &= 0177; return ((int) c); } static int detect(s) register char *s; { char c; int (*f)(); f = signal(SIGALRM, sigALRM); timeout = 0; while (*s) { if (setjmp(timeoutbuf)) { hayes_abort(); break; } alarm(number(value(DIALTIMEOUT))); read(FD, &c, 1); #ifdef DEBUG *r_pnt++ = c; #endif alarm(0); c &= 0177; if (c != *s++) return (0); } signal(SIGALRM, f); return (timeout == 0); }