148651Sbostic /*-
2*62384Sbostic * Copyright (c) 1985, 1993
3*62384Sbostic * The Regents of the University of California. All rights reserved.
448651Sbostic *
548651Sbostic * %sccs.include.proprietary.c%
648651Sbostic */
748651Sbostic
825882Sbloom #ifndef lint
9*62384Sbostic static char sccsid[] = "@(#)hys24.c 8.1 (Berkeley) 06/06/93";
1048651Sbostic #endif /* not lint */
1125882Sbloom
1246875Sbostic #include "condevs.h"
1325882Sbloom
1425882Sbloom /*
1534193Srick * hyspopn24(telno, flds, dev) connect to hayes smartmodem (pulse call)
1634193Srick * hystopn24(telno, flds, dev) connect to hayes smartmodem (tone call)
1725882Sbloom *
1834193Srick * return codes: >0 - file number - ok CF_DIAL,CF_DEVICE - failed
1925882Sbloom */
2025882Sbloom
2134193Srick #include <sys/file.h>
2234193Srick #include <sys/ioctl.h>
2334193Srick
hyspopn24(telno,flds,dev)2425882Sbloom hyspopn24(telno, flds, dev)
2525882Sbloom char *telno, *flds[];
2625882Sbloom struct Devices *dev;
2725882Sbloom {
2825882Sbloom return hysopn24(telno, flds, dev, 0);
2925882Sbloom }
3025882Sbloom
hystopn24(telno,flds,dev)3125882Sbloom hystopn24(telno, flds, dev)
3225882Sbloom char *telno, *flds[];
3325882Sbloom struct Devices *dev;
3425882Sbloom {
3525882Sbloom return hysopn24(telno, flds, dev, 1);
3625882Sbloom }
3725882Sbloom
3825882Sbloom /* ARGSUSED */
hysopn24(telno,flds,dev,toneflag)3925882Sbloom hysopn24(telno, flds, dev, toneflag)
4025882Sbloom char *telno;
4125882Sbloom char *flds[];
4225882Sbloom struct Devices *dev;
4325882Sbloom int toneflag;
4425882Sbloom {
4534193Srick int dh = -1;
4634193Srick int result, ix, speed;
4725882Sbloom char *ii;
4825882Sbloom extern errno;
4925882Sbloom char dcname[20];
5034193Srick char resultbuf[16];
5125882Sbloom
5225882Sbloom sprintf(dcname, "/dev/%s", dev->D_line);
5325882Sbloom DEBUG(4, "dc - %s\n", dcname);
5425882Sbloom if (setjmp(Sjbuf)) {
5525882Sbloom logent(dcname, "TIMEOUT");
5625882Sbloom if (dh >= 0)
5734193Srick hyscls24(dh, 0);
5825882Sbloom return CF_DIAL;
5925882Sbloom }
6025882Sbloom signal(SIGALRM, alarmtr);
6125882Sbloom getnextfd();
6225882Sbloom alarm(10);
6334193Srick dh = open(dcname, 2); /* read/write */
6425882Sbloom alarm(0);
6525882Sbloom
6625882Sbloom for (ii = telno; *ii; ii++)
6725882Sbloom if (*ii == '=')
6834193Srick *ii = ',';
6925882Sbloom
7025882Sbloom /* modem is open */
7125882Sbloom next_fd = -1;
7225882Sbloom if (dh >= 0) {
7334193Srick ioctl(dh, TIOCHPCL, 0);
7425882Sbloom fixline(dh, dev->D_speed);
7525882Sbloom if (dochat(dev, flds, dh)) {
7625882Sbloom logent(dcname, "CHAT FAILED");
7734193Srick hyscls24(dh, 0);
7825882Sbloom return CF_DIAL;
7925882Sbloom }
8034193Srick hyscls24(dh, 1);/* make sure the line is reset */
8134193Srick write(dh, "AT&F&D3&C1E0M0X3QV0Y\r", 21);
8234193Srick if (expect("0\r", dh) != 0) {
8325882Sbloom logent(dcname, "HSM not responding OK");
8434193Srick hyscls24(dh, 0);
8525882Sbloom return CF_DIAL;
8625882Sbloom }
8725882Sbloom if (toneflag)
8825882Sbloom write(dh, "\rATDT", 5);
8925882Sbloom else
9025882Sbloom write(dh, "\rATDP", 5);
9125882Sbloom write(dh, telno, strlen(telno));
9225882Sbloom write(dh, "\r", 1);
9325882Sbloom
9434193Srick if (setjmp(Sjbuf)) {
9534193Srick logent(dcname, "Modem Hung");
9634193Srick if (dh >= 0)
9734193Srick hyscls24(dh, 0);
9834193Srick return CF_DIAL;
9934193Srick }
10034193Srick signal(SIGALRM, alarmtr);
10134193Srick alarm(120);
10234193Srick do {
10334193Srick for (ix = 0; ix < 16; ix++) {
10434193Srick read(dh, resultbuf + ix, 1);
10534193Srick DEBUG(6, "character read = 0x%X \n", resultbuf[ix]);
10634193Srick if ((0x7f & resultbuf[ix]) == 0xd)
10734193Srick break;
10834193Srick }
10934193Srick
11034193Srick result = atol(resultbuf);
11134193Srick switch (result) {
11234193Srick case 0:
11334193Srick logent("HSM Spurious OK response", _FAILED);
11434193Srick speed = 0;
11534193Srick break;
11634193Srick case 1:
11734193Srick logent("HSM connected at 300 baud!", _FAILED);
11834193Srick speed = -1;
11934193Srick break;
12034193Srick case 2:
12134193Srick speed = 0;
12234193Srick DEBUG(4, "Ringing", 0);
12334193Srick break;
12434193Srick case 3:
12534193Srick logent("HSM No Carrier", _FAILED);
12634193Srick speed = -1;
12734193Srick break;
12834193Srick case 4:
12934193Srick logent("HSM Error", _FAILED);
13034193Srick speed = -1;
13134193Srick break;
13234193Srick case 5:
13334193Srick speed = 1200;
13434193Srick break;
13534193Srick case 6:
13634193Srick logent("HSM No dialtone", _FAILED);
13734193Srick speed = -1;
13834193Srick break;
13934193Srick case 7:
14034193Srick logent("HSM detected BUSY", _FAILED);
14134193Srick speed = -1;
14234193Srick break;
14334193Srick case 8:
14434193Srick logent("HSM No quiet answer", _FAILED);
14534193Srick speed = -1;
14634193Srick break;
14734193Srick case 10:
14834193Srick speed = 2400;
14934193Srick break;
15034193Srick default:
15134193Srick logent("HSM Unknown response", _FAILED);
15234193Srick speed = -1;
15334193Srick break;
15434193Srick }
15534193Srick
15634193Srick } while (speed == 0);
15734193Srick
15834193Srick alarm(0);
15934193Srick
16034193Srick if (speed < 0) {
16125882Sbloom strcpy(devSel, dev->D_line);
16234193Srick hyscls24(dh, 0);
16325882Sbloom return CF_DIAL;
16434193Srick } else if (speed != dev->D_speed) {
16534193Srick DEBUG(4, "changing line speed to %d baud\n", speed);
16634193Srick fixline(dh, speed);
16725882Sbloom }
16825882Sbloom }
16925882Sbloom if (dh < 0) {
17025882Sbloom logent(dcname, "CAN'T OPEN");
17125882Sbloom return dh;
17225882Sbloom }
17325882Sbloom DEBUG(4, "hayes ok\n", CNULL);
17425882Sbloom return dh;
17525882Sbloom }
17625882Sbloom
hyscls24(fd,flag)17734193Srick hyscls24(fd, flag)
17834193Srick int fd, flag;
17925882Sbloom {
18025882Sbloom char dcname[20];
18144321Sbostic int fff = 1;
18225882Sbloom
18325882Sbloom if (fd > 0) {
18425882Sbloom sprintf(dcname, "/dev/%s", devSel);
18534193Srick if (flag)
18634193Srick DEBUG(4, "Resetting fd = %d\n", fd);
18734193Srick else
18834193Srick DEBUG(4, "Hanging up fd = %d\n", fd);
18934193Srick /*
19034193Srick * Since we have a getty sleeping on this line, when it wakes
19134193Srick * up it sends all kinds of garbage to the modem.
19234193Srick * Unfortunatly, the modem likes to execute the previous
19334193Srick * command when it sees the garbage. The previous command
19434193Srick * was to dial the phone, so let's make the last command
19534193Srick * reset the modem.
19634193Srick */
19734193Srick if (!flag)
19834193Srick fixline(fd, 2400);
19934193Srick write(fd, "\r", 1);
20025882Sbloom sleep(2);
20134193Srick write(fd, "+++", 3);
20234193Srick sleep(3);
20325882Sbloom write(fd, "\rATH\rATZ\r", 9);
20425882Sbloom sleep(2);
20534193Srick ioctl(fd, TIOCFLUSH, &fff);
20634193Srick
20734193Srick if (!flag) {
20834193Srick close(fd);
20934193Srick delock(devSel);
21034193Srick }
21125882Sbloom }
21225882Sbloom }
213