1 /*- 2 * Copyright (c) 1985, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.proprietary.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)hys24.c 8.1 (Berkeley) 06/06/93"; 10 #endif /* not lint */ 11 12 #include "condevs.h" 13 14 /* 15 * hyspopn24(telno, flds, dev) connect to hayes smartmodem (pulse call) 16 * hystopn24(telno, flds, dev) connect to hayes smartmodem (tone call) 17 * 18 * return codes: >0 - file number - ok CF_DIAL,CF_DEVICE - failed 19 */ 20 21 #include <sys/file.h> 22 #include <sys/ioctl.h> 23 24 hyspopn24(telno, flds, dev) 25 char *telno, *flds[]; 26 struct Devices *dev; 27 { 28 return hysopn24(telno, flds, dev, 0); 29 } 30 31 hystopn24(telno, flds, dev) 32 char *telno, *flds[]; 33 struct Devices *dev; 34 { 35 return hysopn24(telno, flds, dev, 1); 36 } 37 38 /* ARGSUSED */ 39 hysopn24(telno, flds, dev, toneflag) 40 char *telno; 41 char *flds[]; 42 struct Devices *dev; 43 int toneflag; 44 { 45 int dh = -1; 46 int result, ix, speed; 47 char *ii; 48 extern errno; 49 char dcname[20]; 50 char resultbuf[16]; 51 52 sprintf(dcname, "/dev/%s", dev->D_line); 53 DEBUG(4, "dc - %s\n", dcname); 54 if (setjmp(Sjbuf)) { 55 logent(dcname, "TIMEOUT"); 56 if (dh >= 0) 57 hyscls24(dh, 0); 58 return CF_DIAL; 59 } 60 signal(SIGALRM, alarmtr); 61 getnextfd(); 62 alarm(10); 63 dh = open(dcname, 2); /* read/write */ 64 alarm(0); 65 66 for (ii = telno; *ii; ii++) 67 if (*ii == '=') 68 *ii = ','; 69 70 /* modem is open */ 71 next_fd = -1; 72 if (dh >= 0) { 73 ioctl(dh, TIOCHPCL, 0); 74 fixline(dh, dev->D_speed); 75 if (dochat(dev, flds, dh)) { 76 logent(dcname, "CHAT FAILED"); 77 hyscls24(dh, 0); 78 return CF_DIAL; 79 } 80 hyscls24(dh, 1);/* make sure the line is reset */ 81 write(dh, "AT&F&D3&C1E0M0X3QV0Y\r", 21); 82 if (expect("0\r", dh) != 0) { 83 logent(dcname, "HSM not responding OK"); 84 hyscls24(dh, 0); 85 return CF_DIAL; 86 } 87 if (toneflag) 88 write(dh, "\rATDT", 5); 89 else 90 write(dh, "\rATDP", 5); 91 write(dh, telno, strlen(telno)); 92 write(dh, "\r", 1); 93 94 if (setjmp(Sjbuf)) { 95 logent(dcname, "Modem Hung"); 96 if (dh >= 0) 97 hyscls24(dh, 0); 98 return CF_DIAL; 99 } 100 signal(SIGALRM, alarmtr); 101 alarm(120); 102 do { 103 for (ix = 0; ix < 16; ix++) { 104 read(dh, resultbuf + ix, 1); 105 DEBUG(6, "character read = 0x%X \n", resultbuf[ix]); 106 if ((0x7f & resultbuf[ix]) == 0xd) 107 break; 108 } 109 110 result = atol(resultbuf); 111 switch (result) { 112 case 0: 113 logent("HSM Spurious OK response", _FAILED); 114 speed = 0; 115 break; 116 case 1: 117 logent("HSM connected at 300 baud!", _FAILED); 118 speed = -1; 119 break; 120 case 2: 121 speed = 0; 122 DEBUG(4, "Ringing", 0); 123 break; 124 case 3: 125 logent("HSM No Carrier", _FAILED); 126 speed = -1; 127 break; 128 case 4: 129 logent("HSM Error", _FAILED); 130 speed = -1; 131 break; 132 case 5: 133 speed = 1200; 134 break; 135 case 6: 136 logent("HSM No dialtone", _FAILED); 137 speed = -1; 138 break; 139 case 7: 140 logent("HSM detected BUSY", _FAILED); 141 speed = -1; 142 break; 143 case 8: 144 logent("HSM No quiet answer", _FAILED); 145 speed = -1; 146 break; 147 case 10: 148 speed = 2400; 149 break; 150 default: 151 logent("HSM Unknown response", _FAILED); 152 speed = -1; 153 break; 154 } 155 156 } while (speed == 0); 157 158 alarm(0); 159 160 if (speed < 0) { 161 strcpy(devSel, dev->D_line); 162 hyscls24(dh, 0); 163 return CF_DIAL; 164 } else if (speed != dev->D_speed) { 165 DEBUG(4, "changing line speed to %d baud\n", speed); 166 fixline(dh, speed); 167 } 168 } 169 if (dh < 0) { 170 logent(dcname, "CAN'T OPEN"); 171 return dh; 172 } 173 DEBUG(4, "hayes ok\n", CNULL); 174 return dh; 175 } 176 177 hyscls24(fd, flag) 178 int fd, flag; 179 { 180 char dcname[20]; 181 int fff = 1; 182 183 if (fd > 0) { 184 sprintf(dcname, "/dev/%s", devSel); 185 if (flag) 186 DEBUG(4, "Resetting fd = %d\n", fd); 187 else 188 DEBUG(4, "Hanging up fd = %d\n", fd); 189 /* 190 * Since we have a getty sleeping on this line, when it wakes 191 * up it sends all kinds of garbage to the modem. 192 * Unfortunatly, the modem likes to execute the previous 193 * command when it sees the garbage. The previous command 194 * was to dial the phone, so let's make the last command 195 * reset the modem. 196 */ 197 if (!flag) 198 fixline(fd, 2400); 199 write(fd, "\r", 1); 200 sleep(2); 201 write(fd, "+++", 3); 202 sleep(3); 203 write(fd, "\rATH\rATZ\r", 9); 204 sleep(2); 205 ioctl(fd, TIOCFLUSH, &fff); 206 207 if (!flag) { 208 close(fd); 209 delock(devSel); 210 } 211 } 212 } 213