1fa92e883SRuslan Ermilov /* $OpenBSD: ventel.c,v 1.12 2006/03/17 19:17:13 moritz Exp $ */
20f3bdf5dSMark Murray /* $NetBSD: ventel.c,v 1.6 1997/02/11 09:24:21 mrg Exp $ */
30f3bdf5dSMark Murray
4*8a16b7a1SPedro F. Giffuni /*-
5*8a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause
6*8a16b7a1SPedro F. Giffuni *
718cc36fbSJordan K. Hubbard * Copyright (c) 1983, 1993
818cc36fbSJordan K. Hubbard * The Regents of the University of California. All rights reserved.
918cc36fbSJordan K. Hubbard *
1018cc36fbSJordan K. Hubbard * Redistribution and use in source and binary forms, with or without
1118cc36fbSJordan K. Hubbard * modification, are permitted provided that the following conditions
1218cc36fbSJordan K. Hubbard * are met:
1318cc36fbSJordan K. Hubbard * 1. Redistributions of source code must retain the above copyright
1418cc36fbSJordan K. Hubbard * notice, this list of conditions and the following disclaimer.
1518cc36fbSJordan K. Hubbard * 2. Redistributions in binary form must reproduce the above copyright
1618cc36fbSJordan K. Hubbard * notice, this list of conditions and the following disclaimer in the
1718cc36fbSJordan K. Hubbard * documentation and/or other materials provided with the distribution.
18fa92e883SRuslan Ermilov * 3. Neither the name of the University nor the names of its contributors
1918cc36fbSJordan K. Hubbard * may be used to endorse or promote products derived from this software
2018cc36fbSJordan K. Hubbard * without specific prior written permission.
2118cc36fbSJordan K. Hubbard *
2218cc36fbSJordan K. Hubbard * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2318cc36fbSJordan K. Hubbard * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2418cc36fbSJordan K. Hubbard * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2518cc36fbSJordan K. Hubbard * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2618cc36fbSJordan K. Hubbard * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2718cc36fbSJordan K. Hubbard * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2818cc36fbSJordan K. Hubbard * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2918cc36fbSJordan K. Hubbard * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3018cc36fbSJordan K. Hubbard * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3118cc36fbSJordan K. Hubbard * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3218cc36fbSJordan K. Hubbard * SUCH DAMAGE.
3318cc36fbSJordan K. Hubbard */
3418cc36fbSJordan K. Hubbard
3518cc36fbSJordan K. Hubbard /*
3618cc36fbSJordan K. Hubbard * Routines for calling up on a Ventel Modem
3718cc36fbSJordan K. Hubbard * The Ventel is expected to be strapped for local echo (just like uucp)
3818cc36fbSJordan K. Hubbard */
3918cc36fbSJordan K. Hubbard #include "tip.h"
400f3bdf5dSMark Murray #include <termios.h>
410f3bdf5dSMark Murray #include <sys/ioctl.h>
4218cc36fbSJordan K. Hubbard
4318cc36fbSJordan K. Hubbard #define MAXRETRY 5
4418cc36fbSJordan K. Hubbard
45fa92e883SRuslan Ermilov static int dialtimeout = 0;
4618cc36fbSJordan K. Hubbard static jmp_buf timeoutbuf;
4718cc36fbSJordan K. Hubbard
48fa92e883SRuslan Ermilov static void echo(char *);
49fa92e883SRuslan Ermilov static void sigALRM(int);
50fa92e883SRuslan Ermilov static int gobble(char, char *);
51fa92e883SRuslan Ermilov static int vensync(int);
520f3bdf5dSMark Murray
5318cc36fbSJordan K. Hubbard /*
5418cc36fbSJordan K. Hubbard * some sleep calls have been replaced by this macro
5518cc36fbSJordan K. Hubbard * because some ventel modems require two <cr>s in less than
5618cc36fbSJordan K. Hubbard * a second in order to 'wake up'... yes, it is dirty...
5718cc36fbSJordan K. Hubbard */
5818cc36fbSJordan K. Hubbard #define delay(num,denom) busyloop(CPUSPEED*num/denom)
5918cc36fbSJordan K. Hubbard #define CPUSPEED 1000000 /* VAX 780 is 1MIPS */
600f3bdf5dSMark Murray #define DELAY(n) do { long N = (n); while (--N > 0); } while (0)
610f3bdf5dSMark Murray #define busyloop(n) do { DELAY(n); } while (0)
6218cc36fbSJordan K. Hubbard
630f3bdf5dSMark Murray int
ven_dialer(char * num,char * acu)64fa92e883SRuslan Ermilov ven_dialer(char *num, char *acu)
6518cc36fbSJordan K. Hubbard {
660f3bdf5dSMark Murray char *cp;
670f3bdf5dSMark Murray int connected = 0;
680f3bdf5dSMark Murray char *msg, line[80];
690f3bdf5dSMark Murray struct termios cntrl;
7018cc36fbSJordan K. Hubbard
7118cc36fbSJordan K. Hubbard /*
7218cc36fbSJordan K. Hubbard * Get in synch with a couple of carriage returns
7318cc36fbSJordan K. Hubbard */
7418cc36fbSJordan K. Hubbard if (!vensync(FD)) {
7518cc36fbSJordan K. Hubbard printf("can't synchronize with ventel\n");
760f3bdf5dSMark Murray #ifdef ACULOG
7718cc36fbSJordan K. Hubbard logent(value(HOST), num, "ventel", "can't synch up");
7818cc36fbSJordan K. Hubbard #endif
7918cc36fbSJordan K. Hubbard return (0);
8018cc36fbSJordan K. Hubbard }
8118cc36fbSJordan K. Hubbard if (boolean(value(VERBOSE)))
8218cc36fbSJordan K. Hubbard printf("\ndialing...");
8318cc36fbSJordan K. Hubbard fflush(stdout);
840f3bdf5dSMark Murray tcgetattr(FD, &cntrl);
850f3bdf5dSMark Murray cntrl.c_cflag |= HUPCL;
860f3bdf5dSMark Murray tcsetattr(FD, TCSANOW, &cntrl);
8718cc36fbSJordan K. Hubbard echo("#k$\r$\n$D$I$A$L$:$ ");
8818cc36fbSJordan K. Hubbard for (cp = num; *cp; cp++) {
8918cc36fbSJordan K. Hubbard delay(1, 10);
9018cc36fbSJordan K. Hubbard write(FD, cp, 1);
9118cc36fbSJordan K. Hubbard }
9218cc36fbSJordan K. Hubbard delay(1, 10);
9318cc36fbSJordan K. Hubbard write(FD, "\r", 1);
9418cc36fbSJordan K. Hubbard gobble('\n', line);
9518cc36fbSJordan K. Hubbard if (gobble('\n', line))
9618cc36fbSJordan K. Hubbard connected = gobble('!', line);
970f3bdf5dSMark Murray tcflush(FD, TCIOFLUSH);
980f3bdf5dSMark Murray #ifdef ACULOG
99fa92e883SRuslan Ermilov if (dialtimeout) {
100fa92e883SRuslan Ermilov (void)snprintf(line, sizeof line, "%ld second dial timeout",
10118cc36fbSJordan K. Hubbard number(value(DIALTIMEOUT)));
10218cc36fbSJordan K. Hubbard logent(value(HOST), num, "ventel", line);
10318cc36fbSJordan K. Hubbard }
10418cc36fbSJordan K. Hubbard #endif
105fa92e883SRuslan Ermilov if (dialtimeout)
10618cc36fbSJordan K. Hubbard ven_disconnect(); /* insurance */
107fa92e883SRuslan Ermilov if (connected || dialtimeout || !boolean(value(VERBOSE)))
10818cc36fbSJordan K. Hubbard return (connected);
10918cc36fbSJordan K. Hubbard /* call failed, parse response for user */
1100f3bdf5dSMark Murray cp = strchr(line, '\r');
11118cc36fbSJordan K. Hubbard if (cp)
11218cc36fbSJordan K. Hubbard *cp = '\0';
113fa92e883SRuslan Ermilov for (cp = line; (cp = strchr(cp, ' ')) != NULL; cp++)
11418cc36fbSJordan K. Hubbard if (cp[1] == ' ')
11518cc36fbSJordan K. Hubbard break;
11618cc36fbSJordan K. Hubbard if (cp) {
11718cc36fbSJordan K. Hubbard while (*cp == ' ')
11818cc36fbSJordan K. Hubbard cp++;
11918cc36fbSJordan K. Hubbard msg = cp;
12018cc36fbSJordan K. Hubbard while (*cp) {
12118cc36fbSJordan K. Hubbard if (isupper(*cp))
12218cc36fbSJordan K. Hubbard *cp = tolower(*cp);
12318cc36fbSJordan K. Hubbard cp++;
12418cc36fbSJordan K. Hubbard }
12518cc36fbSJordan K. Hubbard printf("%s...", msg);
12618cc36fbSJordan K. Hubbard }
12718cc36fbSJordan K. Hubbard return (connected);
12818cc36fbSJordan K. Hubbard }
12918cc36fbSJordan K. Hubbard
1300f3bdf5dSMark Murray void
ven_disconnect(void)131fa92e883SRuslan Ermilov ven_disconnect(void)
13218cc36fbSJordan K. Hubbard {
13318cc36fbSJordan K. Hubbard close(FD);
13418cc36fbSJordan K. Hubbard }
13518cc36fbSJordan K. Hubbard
1360f3bdf5dSMark Murray void
ven_abort(void)137fa92e883SRuslan Ermilov ven_abort(void)
13818cc36fbSJordan K. Hubbard {
13918cc36fbSJordan K. Hubbard write(FD, "\03", 1);
14018cc36fbSJordan K. Hubbard close(FD);
14118cc36fbSJordan K. Hubbard }
14218cc36fbSJordan K. Hubbard
14318cc36fbSJordan K. Hubbard static void
echo(char * s)144fa92e883SRuslan Ermilov echo(char *s)
14518cc36fbSJordan K. Hubbard {
14618cc36fbSJordan K. Hubbard char c;
14718cc36fbSJordan K. Hubbard
148fa92e883SRuslan Ermilov while ((c = *s++) != '\0')
149fa92e883SRuslan Ermilov switch (c) {
15018cc36fbSJordan K. Hubbard case '$':
15118cc36fbSJordan K. Hubbard read(FD, &c, 1);
15218cc36fbSJordan K. Hubbard s++;
15318cc36fbSJordan K. Hubbard break;
15418cc36fbSJordan K. Hubbard
15518cc36fbSJordan K. Hubbard case '#':
15618cc36fbSJordan K. Hubbard c = *s++;
15718cc36fbSJordan K. Hubbard write(FD, &c, 1);
15818cc36fbSJordan K. Hubbard break;
15918cc36fbSJordan K. Hubbard
16018cc36fbSJordan K. Hubbard default:
16118cc36fbSJordan K. Hubbard write(FD, &c, 1);
16218cc36fbSJordan K. Hubbard read(FD, &c, 1);
16318cc36fbSJordan K. Hubbard }
16418cc36fbSJordan K. Hubbard }
16518cc36fbSJordan K. Hubbard
166fa92e883SRuslan Ermilov /*ARGSUSED*/
16718cc36fbSJordan K. Hubbard static void
sigALRM(int signo)168fa92e883SRuslan Ermilov sigALRM(int signo)
16918cc36fbSJordan K. Hubbard {
17018cc36fbSJordan K. Hubbard printf("\07timeout waiting for reply\n");
171fa92e883SRuslan Ermilov dialtimeout = 1;
17218cc36fbSJordan K. Hubbard longjmp(timeoutbuf, 1);
17318cc36fbSJordan K. Hubbard }
17418cc36fbSJordan K. Hubbard
17518cc36fbSJordan K. Hubbard static int
gobble(char match,char response[])176fa92e883SRuslan Ermilov gobble(char match, char response[])
17718cc36fbSJordan K. Hubbard {
1780f3bdf5dSMark Murray char *cp = response;
17918cc36fbSJordan K. Hubbard sig_t f;
18018cc36fbSJordan K. Hubbard char c;
18118cc36fbSJordan K. Hubbard
18218cc36fbSJordan K. Hubbard f = signal(SIGALRM, sigALRM);
183fa92e883SRuslan Ermilov dialtimeout = 0;
18418cc36fbSJordan K. Hubbard do {
18518cc36fbSJordan K. Hubbard if (setjmp(timeoutbuf)) {
18618cc36fbSJordan K. Hubbard signal(SIGALRM, f);
18718cc36fbSJordan K. Hubbard *cp = '\0';
18818cc36fbSJordan K. Hubbard return (0);
18918cc36fbSJordan K. Hubbard }
19018cc36fbSJordan K. Hubbard alarm(number(value(DIALTIMEOUT)));
19118cc36fbSJordan K. Hubbard read(FD, cp, 1);
19218cc36fbSJordan K. Hubbard alarm(0);
19318cc36fbSJordan K. Hubbard c = (*cp++ &= 0177);
19418cc36fbSJordan K. Hubbard #ifdef notdef
19518cc36fbSJordan K. Hubbard if (boolean(value(VERBOSE)))
19618cc36fbSJordan K. Hubbard putchar(c);
19718cc36fbSJordan K. Hubbard #endif
19818cc36fbSJordan K. Hubbard } while (c != '\n' && c != match);
19918cc36fbSJordan K. Hubbard signal(SIGALRM, SIG_DFL);
20018cc36fbSJordan K. Hubbard *cp = '\0';
20118cc36fbSJordan K. Hubbard return (c == match);
20218cc36fbSJordan K. Hubbard }
20318cc36fbSJordan K. Hubbard
20418cc36fbSJordan K. Hubbard #define min(a,b) ((a)>(b)?(b):(a))
20518cc36fbSJordan K. Hubbard /*
20618cc36fbSJordan K. Hubbard * This convoluted piece of code attempts to get
20718cc36fbSJordan K. Hubbard * the ventel in sync. If you don't have FIONREAD
20818cc36fbSJordan K. Hubbard * there are gory ways to simulate this.
20918cc36fbSJordan K. Hubbard */
21018cc36fbSJordan K. Hubbard static int
vensync(int fd)211fa92e883SRuslan Ermilov vensync(int fd)
21218cc36fbSJordan K. Hubbard {
21318cc36fbSJordan K. Hubbard int already = 0, nread;
21418cc36fbSJordan K. Hubbard char buf[60];
21518cc36fbSJordan K. Hubbard
21618cc36fbSJordan K. Hubbard /*
21718cc36fbSJordan K. Hubbard * Toggle DTR to force anyone off that might have left
21818cc36fbSJordan K. Hubbard * the modem connected, and insure a consistent state
21918cc36fbSJordan K. Hubbard * to start from.
22018cc36fbSJordan K. Hubbard *
22118cc36fbSJordan K. Hubbard * If you don't have the ioctl calls to diddle directly
22218cc36fbSJordan K. Hubbard * with DTR, you can always try setting the baud rate to 0.
22318cc36fbSJordan K. Hubbard */
22418cc36fbSJordan K. Hubbard ioctl(FD, TIOCCDTR, 0);
22518cc36fbSJordan K. Hubbard sleep(1);
22618cc36fbSJordan K. Hubbard ioctl(FD, TIOCSDTR, 0);
22718cc36fbSJordan K. Hubbard while (already < MAXRETRY) {
22818cc36fbSJordan K. Hubbard /*
22918cc36fbSJordan K. Hubbard * After reseting the modem, send it two \r's to
23018cc36fbSJordan K. Hubbard * autobaud on. Make sure to delay between them
23118cc36fbSJordan K. Hubbard * so the modem can frame the incoming characters.
23218cc36fbSJordan K. Hubbard */
23318cc36fbSJordan K. Hubbard write(fd, "\r", 1);
23418cc36fbSJordan K. Hubbard delay(1,10);
23518cc36fbSJordan K. Hubbard write(fd, "\r", 1);
23618cc36fbSJordan K. Hubbard sleep(2);
23718cc36fbSJordan K. Hubbard if (ioctl(fd, FIONREAD, (caddr_t)&nread) < 0) {
2380f3bdf5dSMark Murray perror("tip: ioctl");
23918cc36fbSJordan K. Hubbard continue;
24018cc36fbSJordan K. Hubbard }
24118cc36fbSJordan K. Hubbard while (nread > 0) {
24218cc36fbSJordan K. Hubbard read(fd, buf, min(nread, 60));
24318cc36fbSJordan K. Hubbard if ((buf[nread - 1] & 0177) == '$')
24418cc36fbSJordan K. Hubbard return (1);
24518cc36fbSJordan K. Hubbard nread -= min(nread, 60);
24618cc36fbSJordan K. Hubbard }
24718cc36fbSJordan K. Hubbard sleep(1);
24818cc36fbSJordan K. Hubbard already++;
24918cc36fbSJordan K. Hubbard }
25018cc36fbSJordan K. Hubbard return (0);
25118cc36fbSJordan K. Hubbard }
252