17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
5*8d489c7aSmuffin
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate * Copyright (c) 1983 Regents of the University of California.
87c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement
97c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
107c478bd9Sstevel@tonic-gate */
11*8d489c7aSmuffin
12*8d489c7aSmuffin #pragma ident "%Z%%M% %I% %E% SMI"
137c478bd9Sstevel@tonic-gate
147c478bd9Sstevel@tonic-gate /*
157c478bd9Sstevel@tonic-gate * Routines for calling up on a Ventel Modem
167c478bd9Sstevel@tonic-gate * Define VENNOECHO if the Ventel is strapped for "no echo".
177c478bd9Sstevel@tonic-gate */
187c478bd9Sstevel@tonic-gate #include "tip.h"
197c478bd9Sstevel@tonic-gate
207c478bd9Sstevel@tonic-gate #define MAXRETRY 5
217c478bd9Sstevel@tonic-gate
22*8d489c7aSmuffin static int vensync(int);
23*8d489c7aSmuffin static int gobble(char);
24*8d489c7aSmuffin static void echo(char *);
25*8d489c7aSmuffin static void sigALRM(void);
267c478bd9Sstevel@tonic-gate static int timeout = 0;
277c478bd9Sstevel@tonic-gate static sigjmp_buf timeoutbuf;
287c478bd9Sstevel@tonic-gate
29*8d489c7aSmuffin void ven_disconnect(void);
30*8d489c7aSmuffin
31*8d489c7aSmuffin /* ARGSUSED */
32*8d489c7aSmuffin int
ven_dialer(char * num,char * acu)33*8d489c7aSmuffin ven_dialer(char *num, char *acu)
347c478bd9Sstevel@tonic-gate {
35*8d489c7aSmuffin char *cp;
36*8d489c7aSmuffin int connected = 0;
377c478bd9Sstevel@tonic-gate struct termios buf;
387c478bd9Sstevel@tonic-gate #ifdef ACULOG
397c478bd9Sstevel@tonic-gate char line[80];
407c478bd9Sstevel@tonic-gate #endif
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate * Get in synch with a couple of carriage returns
437c478bd9Sstevel@tonic-gate */
447c478bd9Sstevel@tonic-gate if (!vensync(FD)) {
45*8d489c7aSmuffin (void) printf("can't synchronize with ventel\n");
467c478bd9Sstevel@tonic-gate #ifdef ACULOG
477c478bd9Sstevel@tonic-gate logent(value(HOST), num, "ventel", "can't synch up");
487c478bd9Sstevel@tonic-gate #endif
497c478bd9Sstevel@tonic-gate return (0);
507c478bd9Sstevel@tonic-gate }
517c478bd9Sstevel@tonic-gate if (boolean(value(VERBOSE)))
52*8d489c7aSmuffin (void) printf("\ndialing...");
53*8d489c7aSmuffin (void) fflush(stdout);
54*8d489c7aSmuffin (void) ioctl(FD, TCGETS, &buf);
557c478bd9Sstevel@tonic-gate buf.c_cflag |= HUPCL;
56*8d489c7aSmuffin (void) ioctl(FD, TCSETSF, &buf);
577c478bd9Sstevel@tonic-gate #ifdef VENNOECHO
587c478bd9Sstevel@tonic-gate echo("#k$\r$\n$D$I$A$L$:$ ");
597c478bd9Sstevel@tonic-gate for (cp = num; *cp; cp++) {
60*8d489c7aSmuffin (void) sleep(1);
61*8d489c7aSmuffin (void) write(FD, cp, 1);
627c478bd9Sstevel@tonic-gate }
637c478bd9Sstevel@tonic-gate echo("\r$\n");
647c478bd9Sstevel@tonic-gate #else
657c478bd9Sstevel@tonic-gate echo("k$\r$\n$D$I$A$L$:$ <");
667c478bd9Sstevel@tonic-gate for (cp = num; *cp; cp++) {
677c478bd9Sstevel@tonic-gate char c;
687c478bd9Sstevel@tonic-gate
69*8d489c7aSmuffin (void) sleep(1);
70*8d489c7aSmuffin (void) write(FD, cp, 1);
71*8d489c7aSmuffin (void) read(FD, &c, 1);
727c478bd9Sstevel@tonic-gate }
737c478bd9Sstevel@tonic-gate echo(">\r$\n");
747c478bd9Sstevel@tonic-gate #endif
757c478bd9Sstevel@tonic-gate if (gobble('\n'))
767c478bd9Sstevel@tonic-gate connected = gobble('!');
77*8d489c7aSmuffin (void) ioctl(FD, TCFLSH, TCIOFLUSH);
787c478bd9Sstevel@tonic-gate #ifdef ACULOG
797c478bd9Sstevel@tonic-gate if (timeout) {
80*8d489c7aSmuffin (void) sprintf(line, "%d second dial timeout",
817c478bd9Sstevel@tonic-gate number(value(DIALTIMEOUT)));
827c478bd9Sstevel@tonic-gate logent(value(HOST), num, "ventel", line);
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate #endif
857c478bd9Sstevel@tonic-gate if (timeout)
867c478bd9Sstevel@tonic-gate ven_disconnect(); /* insurance */
877c478bd9Sstevel@tonic-gate return (connected);
887c478bd9Sstevel@tonic-gate }
897c478bd9Sstevel@tonic-gate
90*8d489c7aSmuffin void
ven_disconnect(void)91*8d489c7aSmuffin ven_disconnect(void)
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate
94*8d489c7aSmuffin (void) close(FD);
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate
97*8d489c7aSmuffin void
ven_abort(void)98*8d489c7aSmuffin ven_abort(void)
997c478bd9Sstevel@tonic-gate {
1007c478bd9Sstevel@tonic-gate
101*8d489c7aSmuffin (void) write(FD, "\03", 1);
102*8d489c7aSmuffin (void) close(FD);
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate
105*8d489c7aSmuffin static void
echo(char * s)106*8d489c7aSmuffin echo(char *s)
1077c478bd9Sstevel@tonic-gate {
1087c478bd9Sstevel@tonic-gate char c;
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate while (c = *s++) {
1117c478bd9Sstevel@tonic-gate switch (c) {
1127c478bd9Sstevel@tonic-gate case '$':
113*8d489c7aSmuffin (void) read(FD, &c, 1);
1147c478bd9Sstevel@tonic-gate s++;
1157c478bd9Sstevel@tonic-gate break;
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate case '#':
1187c478bd9Sstevel@tonic-gate c = *s++;
119*8d489c7aSmuffin (void) write(FD, &c, 1);
1207c478bd9Sstevel@tonic-gate break;
1217c478bd9Sstevel@tonic-gate
1227c478bd9Sstevel@tonic-gate default:
123*8d489c7aSmuffin (void) write(FD, &c, 1);
124*8d489c7aSmuffin (void) read(FD, &c, 1);
1257c478bd9Sstevel@tonic-gate }
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate static void
sigALRM(void)130*8d489c7aSmuffin sigALRM(void)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate
133*8d489c7aSmuffin (void) printf("\07timeout waiting for reply\n");
1347c478bd9Sstevel@tonic-gate timeout = 1;
1357c478bd9Sstevel@tonic-gate siglongjmp(timeoutbuf, 1);
1367c478bd9Sstevel@tonic-gate }
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate static int
gobble(char match)139*8d489c7aSmuffin gobble(char match)
1407c478bd9Sstevel@tonic-gate {
1417c478bd9Sstevel@tonic-gate char c;
1427c478bd9Sstevel@tonic-gate sig_handler_t f;
1437c478bd9Sstevel@tonic-gate
1447c478bd9Sstevel@tonic-gate f = signal(SIGALRM, (sig_handler_t)sigALRM);
1457c478bd9Sstevel@tonic-gate timeout = 0;
1467c478bd9Sstevel@tonic-gate do {
1477c478bd9Sstevel@tonic-gate if (sigsetjmp(timeoutbuf, 1)) {
148*8d489c7aSmuffin (void) signal(SIGALRM, f);
1497c478bd9Sstevel@tonic-gate return (0);
1507c478bd9Sstevel@tonic-gate }
151*8d489c7aSmuffin (void) alarm(number(value(DIALTIMEOUT)));
152*8d489c7aSmuffin (void) read(FD, &c, 1);
153*8d489c7aSmuffin (void) alarm(0);
1547c478bd9Sstevel@tonic-gate c &= 0177;
1557c478bd9Sstevel@tonic-gate #ifdef notdef
1567c478bd9Sstevel@tonic-gate if (boolean(value(VERBOSE)))
157*8d489c7aSmuffin (void) putchar(c);
1587c478bd9Sstevel@tonic-gate #endif
1597c478bd9Sstevel@tonic-gate } while (c != '\n' && c != match);
160*8d489c7aSmuffin (void) signal(SIGALRM, SIG_DFL);
1617c478bd9Sstevel@tonic-gate return (c == match);
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate
1647c478bd9Sstevel@tonic-gate #define min(a, b) (((a) > (b)) ? (b) : (a))
1657c478bd9Sstevel@tonic-gate /*
1667c478bd9Sstevel@tonic-gate * This convoluted piece of code attempts to get
1677c478bd9Sstevel@tonic-gate * the ventel in sync. If you don't have FIONREAD
1687c478bd9Sstevel@tonic-gate * there are gory ways to simulate this.
1697c478bd9Sstevel@tonic-gate */
1707c478bd9Sstevel@tonic-gate static int
vensync(int fd)171*8d489c7aSmuffin vensync(int fd)
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate int already = 0, nread;
1747c478bd9Sstevel@tonic-gate char buf[60];
1757c478bd9Sstevel@tonic-gate int dtr = TIOCM_DTR;
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate /*
1787c478bd9Sstevel@tonic-gate * Toggle DTR to force anyone off that might have left
1797c478bd9Sstevel@tonic-gate * the modem connected, and insure a consistent state
1807c478bd9Sstevel@tonic-gate * to start from.
1817c478bd9Sstevel@tonic-gate *
1827c478bd9Sstevel@tonic-gate * If you don't have the ioctl calls to diddle directly
1837c478bd9Sstevel@tonic-gate * with DTR, you can always try setting the baud rate to 0.
1847c478bd9Sstevel@tonic-gate */
185*8d489c7aSmuffin (void) ioctl(FD, TIOCMBIC, &dtr);
186*8d489c7aSmuffin (void) sleep(2);
187*8d489c7aSmuffin (void) ioctl(FD, TIOCMBIS, &dtr);
1887c478bd9Sstevel@tonic-gate while (already < MAXRETRY) {
1897c478bd9Sstevel@tonic-gate /*
1907c478bd9Sstevel@tonic-gate * After reseting the modem, send it two \r's to
1917c478bd9Sstevel@tonic-gate * autobaud on. Make sure to delay between them
1927c478bd9Sstevel@tonic-gate * so the modem can frame the incoming characters.
1937c478bd9Sstevel@tonic-gate */
194*8d489c7aSmuffin (void) write(fd, "\r", 1);
1957c478bd9Sstevel@tonic-gate #ifdef VMUNIX
1967c478bd9Sstevel@tonic-gate {
1977c478bd9Sstevel@tonic-gate #include <sys/time.h>
1987c478bd9Sstevel@tonic-gate struct timeval tv = {0, 500000};
1997c478bd9Sstevel@tonic-gate
200*8d489c7aSmuffin (void) select(0, 0, 0, 0, &tv);
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate #else
203*8d489c7aSmuffin (void) sleep(1);
2047c478bd9Sstevel@tonic-gate #endif
205*8d489c7aSmuffin (void) write(fd, "\r", 1);
206*8d489c7aSmuffin (void) sleep(3);
2077c478bd9Sstevel@tonic-gate if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
2087c478bd9Sstevel@tonic-gate perror("tip: ioctl");
2097c478bd9Sstevel@tonic-gate continue;
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate while (nread > 0) {
212*8d489c7aSmuffin (void) read(fd, buf, min(nread, 60));
2137c478bd9Sstevel@tonic-gate if ((buf[nread - 1] & 0177) == '$')
2147c478bd9Sstevel@tonic-gate return (1);
2157c478bd9Sstevel@tonic-gate nread -= min(nread, 60);
2167c478bd9Sstevel@tonic-gate }
217*8d489c7aSmuffin (void) sleep(1);
2187c478bd9Sstevel@tonic-gate already++;
2197c478bd9Sstevel@tonic-gate }
2207c478bd9Sstevel@tonic-gate return (0);
2217c478bd9Sstevel@tonic-gate }
222