1*48651Sbostic /*- 2*48651Sbostic * Copyright (c) 1985 The Regents of the University of California. 3*48651Sbostic * All rights reserved. 4*48651Sbostic * 5*48651Sbostic * %sccs.include.proprietary.c% 6*48651Sbostic */ 7*48651Sbostic 825882Sbloom #ifndef lint 9*48651Sbostic static char sccsid[] = "@(#)hys24.c 1.8 (Berkeley) 04/24/91"; 10*48651Sbostic #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 2425882Sbloom hyspopn24(telno, flds, dev) 2525882Sbloom char *telno, *flds[]; 2625882Sbloom struct Devices *dev; 2725882Sbloom { 2825882Sbloom return hysopn24(telno, flds, dev, 0); 2925882Sbloom } 3025882Sbloom 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 */ 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 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