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