117775Sralph #ifndef lint 2*46875Sbostic static char sccsid[] = "@(#)hysq.c 4.3 (Berkeley) 03/02/91"; 317775Sralph #endif 417775Sralph 5*46875Sbostic #include "condevs.h" 617775Sralph 717775Sralph /* 817775Sralph * New dialout routine to work with Hayes' SMART MODEM 917775Sralph * 13-JUL-82, Mike Mitchell 1017775Sralph * Modified 23-MAR-83 to work with Tom Truscott's (rti!trt) 1117775Sralph * version of UUCP (ncsu!mcm) 1217775Sralph * 1317775Sralph * The modem should be set to NOT send any result codes to 1417775Sralph * the system (switch 3 up, 4 down). This end will figure out 1517775Sralph * what is wrong. 1617775Sralph * 1717775Sralph * I had lots of problems with the modem sending 1817775Sralph * result codes since I am using the same modem for both incomming and 1917775Sralph * outgoing calls. I'd occasionally miss the result code (getty would 2017775Sralph * grab it), and the connect would fail. Worse yet, the getty would 2117775Sralph * think the result code was a user name, and send garbage to it while 2217775Sralph * it was in the command state. I turned off ALL result codes, and hope 2317775Sralph * for the best. 99% of the time the modem is in the correct state. 2417775Sralph * Occassionally it doesn't connect, or the phone was busy, etc., and 2517775Sralph * uucico sits there trying to log in. It eventually times out, calling 2617775Sralph * clsacu() in the process, so it resets itself for the next attempt. 2717775Sralph */ 2817775Sralph 2917775Sralph /* 3017775Sralph * NOTE: this version is not for the faint-hearted. 3117775Sralph * Someday it would be nice to have a single version of hayes dialer 3217775Sralph * with a way to specify the switch settings that are on the dialer 3317775Sralph * as well as tone/pulse. 3417775Sralph * In the meantime, using HAYES rather than HAYESQ is probably best. 3517775Sralph */ 3617775Sralph 3717775Sralph hysqpopn(telno, flds, dev) 3817775Sralph char *telno, *flds[]; 3917775Sralph struct Devices *dev; 4017775Sralph { 4117775Sralph return hysqopn(telno, flds, dev, 0); 4217775Sralph } 4317775Sralph 4417775Sralph hysqtopn(telno, flds, dev) 4517775Sralph char *telno, *flds[]; 4617775Sralph struct Devices *dev; 4717775Sralph { 4817775Sralph return hysqopn(telno, flds, dev, 1); 4917775Sralph } 5017775Sralph 5117775Sralph hysqopn(telno, flds, dev, toneflag) 5217775Sralph char *telno, *flds[]; 5317775Sralph struct Devices *dev; 5417775Sralph int toneflag; 5517775Sralph { 5617775Sralph char dcname[20], phone[MAXPH+10], c = 0; 5717775Sralph #ifdef USG 5817775Sralph struct termio ttbuf; 5917775Sralph #endif USG 6017775Sralph int status, dnf; 6117775Sralph unsigned timelim; 6217775Sralph 6317775Sralph signal(SIGALRM, alarmtr); 6417775Sralph sprintf(dcname, "/dev/%s", dev->D_line); 6517775Sralph 6617775Sralph getnextfd(); 6717775Sralph if (setjmp(Sjbuf)) { 6817775Sralph logent("DEVICE", "NO"); 6917775Sralph DEBUG(4, "Open timed out %s", dcname); 7017775Sralph return CF_NODEV; 7117775Sralph } 7217775Sralph alarm(10); 7317775Sralph 7417775Sralph if ((dnf = open(dcname, 2)) <= 0) { 7517775Sralph logent("DEVICE", "NO"); 7617775Sralph DEBUG(4, "Can't open %s", dcname); 7717775Sralph return CF_NODEV; 7817775Sralph } 7917775Sralph 8017775Sralph alarm(0); 8117775Sralph next_fd = -1; 8217775Sralph fixline(dnf, dev->D_speed); 8317775Sralph DEBUG(4, "Hayes port - %s, ", dcname); 8417775Sralph 8517775Sralph if (toneflag) 8617775Sralph sprintf(phone, "\rATDT%s\r", telno); 8717775Sralph else 8817775Sralph sprintf(phone, "\rATDP%s\r", telno); 8917775Sralph 9017775Sralph write(dnf, phone, strlen(phone)); 9117775Sralph 9217775Sralph /* calculate delay time for the other system to answer the phone. 9317775Sralph * Default is 15 seconds, add 2 seconds for each comma in the phone 9417775Sralph * number. 9517775Sralph */ 9617775Sralph timelim = 150; 9717775Sralph while(*telno) { 9817775Sralph c = *telno++; 9917775Sralph if (c == ',') 10017775Sralph timelim += 20; 10117775Sralph else if (toneflag) 10217775Sralph timelim += 2; /* .2 seconds per tone */ 10317775Sralph else { 10417775Sralph if (c == '0') timelim += 10; /* .1 sec per digit */ 10517775Sralph else if (c > '0' && c <= '9') 10617775Sralph timelim += (c - '0'); 10717775Sralph } 10817775Sralph } 10917775Sralph alarm(timelim/10 + 1); 11017775Sralph if (setjmp(Sjbuf) == 0) { 11117775Sralph read(dnf, &c, 1); 11217775Sralph alarm(0); 11317775Sralph } 11417775Sralph 11517775Sralph return dnf; 11617775Sralph } 11717775Sralph 11817775Sralph hysqcls(fd) 11917775Sralph int fd; 12017775Sralph { 12117775Sralph char dcname[20]; 12217775Sralph struct sgttyb hup, sav; 12317775Sralph 12417775Sralph if (fd > 0) { 12517775Sralph sprintf(dcname, "/dev/%s", devSel); 12617775Sralph DEBUG(4, "Hanging up fd = %d\n", fd); 12717775Sralph /* 12817775Sralph * code to drop DTR -- change to 0 baud then back to default. 12917775Sralph */ 13017775Sralph gtty(fd, &hup); 13117775Sralph gtty(fd, &sav); 13217775Sralph hup.sg_ispeed = B0; 13317775Sralph hup.sg_ospeed = B0; 13417775Sralph stty(fd, &hup); 13517775Sralph sleep(2); 13617775Sralph stty(fd, &sav); 13717775Sralph /* 13817775Sralph * now raise DTR -- close the device & open it again. 13917775Sralph */ 14017775Sralph sleep(2); 14117775Sralph close(fd); 14217775Sralph sleep(2); 14317775Sralph fd = open(dcname, 2); 14417775Sralph /* 14517775Sralph * Since we have a getty sleeping on this line, when it wakes up it sends 14617775Sralph * all kinds of garbage to the modem. Unfortunatly, the modem likes to 14717775Sralph * execute the previous command when it sees the garbage. The previous 14817775Sralph * command was to dial the phone, so let's make the last command reset 14917775Sralph * the modem. 15017775Sralph */ 15117775Sralph sleep(2); 15217775Sralph write(fd, "\rATZ\r", 5); 15317775Sralph close(fd); 15417775Sralph delock(devSel); 15517775Sralph } 15617775Sralph } 157