nerd@percival.UUCP (Michael Galassi) (02/22/88)
By popular request I'm re-posting this, I was going to mail the updated version but got enough requests within 24 hours of my original posting that I feel the nets cost as a whole will be lower if I post the whole darn thing again rather than mail out many copies to individuals. As I state in the comments at the start of tb.c (the dialer) the original structure of the routine came from the ucb distribution but has gone through so much that I don't think there are any problems with proprietary code being posted. If you find any problems with this and make any changes to this beyond tuning for your specific site I would very much apreciate getting diffs or a copy of the whole thing, god knows there are probably a dozen better ways of doing things than the way I have chosen. Last note, my comments are probably full of spelling errors, I don't realy care to know about it, they are your problem if you care to read them, you do have an alternative. -- Michael Galassi | If my opinions happen to be the same as ...!tektronix!tessi!percival!nerd | my employer's it is ONLY a coincidence, ...!uunet!littlei!percival!nerd | of cource coincidences DO happen. #--- cut this line and all the above out then feed to /bin/{k,}sh --- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # tb.c # This archive created: Sun Feb 21 12:42:22 1988 export PATH; PATH=/bin:$PATH echo shar: extracting "'tb.c'" '(7515 characters)' if test -f 'tb.c' then echo shar: will not over-write existing file "'tb.c'" else sed 's/^X//' << \SHAR_EOF > 'tb.c' X/* X * Telebit TrailBlazer dialer, two routines here get used X * by uucp: X * X * tbopn(telno, flds, dev) X * char *telno; X * char *flds[]; X * struct Devices *dev; X * X * action X * dials the number in telno on the TrailBlazer connected X * to port dev and sets the baud rate acordingly. X * returns X * file descriptor for /dev/ttyXX or CF_DIAL if dial was X * un-successfull. X * X * tbcls(fd) X * int fd; X * X * action X * hangs up the trailblazer by lowering dtr for a couple X * of seconds and in the process forces all the registers X * to their original state for things like dialin etc... X * also closes the device. X * returns X * nada, nothing, niente, rien (for bonus points, how many X * spelling errors are in those 4 words?) X * X * History X * drop dtr and flush tty often so I don't have to worry X * about autobauding and all that junk X * 02/14/88 -mng X * dumped almost everything, now using numeric codes instead X * of verbal result codes, much easier to do a switch on the X * values returned from the modems that way, also easier to X * fetch the result codes, just go as long as I get digits. X * 01/20/88 -mng X * stole the structure of the hayes dialer from ucb for this X * puppy, sort of works X * 01/10/88 -mng X * nerd@percival (..!tektronix!reed!percival!nerd) X * X * X * to run uucico with this dialer I set the Trailblazer's registers X * as follows (result of "atn?" command): X XE0 F1 M1 Q1 T V1 X1 Version BA4.00 XS00=001 S01=000 S02=255 S03=013 S04=010 S05=008 S06=002 S07=060 S08=002 S09=006 XS10=007 S11=070 S12=050 XS45=255 S47=004 S48=000 S49=000 XS50=000 S51=005 S52=002 S53=003 S54=001 S55=000 S56=017 S57=019 S58=003 S59=000 XS60=000 S61=000 S62=003 S63=001 S64=001 S65=000 S66=000 S67=000 S68=255 XS90=000 S91=000 S92=001 S95=002 XS100=000 S101=000 S102=000 S104=000 XS110=001 S111=255 S112=001 XS121=000 XN0: XN1: XN2: XN3: XN4: XN5: XN6: XN7: XN8: XN9: X X * X */ X X#include "../condevs.h" X X#ifdef TELEBIT X X#include <ctype.h> X#include <sys/ioctl.h> X X#define TBTMOUTHS 60 /* high speed timeout */ X#define TBTMOUTLS 30 /* low speed timeout */ X#define PEPBAUD 19200 /* interface speed for PEP connections */ X Xtbopn(telno, flds, dev) Xchar *telno; Xchar *flds[]; Xstruct Devices *dev; X{ X extern errno; X char dcname[20]; X char cbuf[MAXPH]; X register char *cp; X register int i; X int dh = -1, rings; X X sprintf(dcname, "/dev/%s", dev->D_line); X DEBUG(4, "dc - %s\n", dcname); X if (setjmp(Sjbuf)) { X logent(dcname, "TIMEOUT"); X if (dh >= 0) X tbcls(dh); X return (CF_DIAL); X } X signal(SIGALRM, alarmtr); X getnextfd(); X alarm(10); X dh = open(dcname, 2); /* read/write */ X alarm(0); X X /* modem is open */ X next_fd = -1; X if (dh < 0) { X logent(dcname, "CAN'T OPEN"); X return (CF_DIAL); X } X/* X * this forces the trailblazer to reset, guarantees me that X * it will be at 19.2 KBpS when I want it there and that all X * its buffers will be cleared. Probably don't need all the X * sleep calls here but who's in a hurry (did I tell you about X * the young and old bulls? :-) X */ X ioctl(dh, TIOCCDTR, 0); X sleep(1); X ioctl(dh, TIOCSDTR, 0); X sleep(1); X ioctl(dh, TIOCFLUSH, 0); X sleep(1); X/* X * do all conversation with the modem at high speed, saves me from X * a major headache and I can then use the result code from the modem X * to set the baud rate of the interface. X */ X fixline(dh, PEPBAUD); X X if (dochat(dev, flds, dh)) { X logent(dcname, "CHAT FAILED"); X tbcls(dh); X return (CF_DIAL); X } X/* X * sending "at\r" to the TrailBlazer should give us its undivided X * attention and insure there is no crud left in any of the buffers X * on the modem or in the serial driver. Given the default values X * of the modem there should be no result codes so I don't need the X * expect. X */ X write(dh, "at\r", 3); X sleep(1); X/* X * now set the modem up to dial, make sure we get the right result X * codes back (extended numeric) and all that. If we are going X * to try a PEP connection set the modem for this too. Also we X * have to set a longer timeout for PEP mode as most TrailBlazers X * are configured to put out the PEP mating call after several X * seconds of the normal tones. X */ X if (dev->D_speed == PEPBAUD) X write(dh, "atq6v0e0h0x1s7=60s50=255s51=5s54=4s111=30\r", 42); X else X write(dh, "atq6v0e0h0x1s7=30s50=0s51=5s54=4\r", 33); X X if (expect("0\r", dh) != 0) { X logent(dcname, "TrailBlazer seems dead"); X tbcls(dh); X return (CF_DIAL); X } X/* X * about time we got to dial X */ X write(dh, "atdt", 4); X write(dh, telno, strlen(telno)); X write(dh, "\r", 1); X X if (setjmp(Sjbuf)) { X logent(dcname, "TIMEOUT"); X strcpy(devSel, dev->D_line); X tbcls(dh); X return (CF_DIAL); X } X signal(SIGALRM, alarmtr); X/* X * set uucp to timeout about the same time the trailblazer will X * timeout if it can't connect X */ X if (dev->D_speed == PEPBAUD) X alarm(TBTMOUTHS); X else X alarm(TBTMOUTLS); X rings = 0; X do { X/* X * read any garbage characters in until a digit is found X */ X cp = cbuf; X while (read(dh, cp, 1) == 1) X if (isdigit(*cp)) X break; X ++cp; X/* X * now read characters in so long as they are numeric, this X * will hopefully be a connect or rring code X */ X while (read(dh, cp++, 1) == 1) X if (!isdigit(*cp)) X break; X *cp = '\0'; X i = atoi(cbuf); X/* X * do something with the sacred words of our holly modem X */ X switch (i) { X/* X * someone is trying to call us, damn X */ X case 2: X tbcls(dh); X strcpy(devSel, dev->D_line); X return (FLog("ring")); X/* X * modem gave up before we did X */ X case 3: X tbcls(dh); X strcpy(devSel, dev->D_line); X return (FLog("no carrier")); X/* X * error, probably something with the number in L.sys X */ X case 4: X tbcls(dh); X strcpy(devSel, dev->D_line); X return (FLog("error")); X/* X * something is wrong with the phone line X */ X case 6: X tbcls(dh); X strcpy(devSel, dev->D_line); X return (FLog("no dial tone")); X/* X * we'll just have to catch this one later X */ X case 7: X tbcls(dh); X strcpy(devSel, dev->D_line); X return (FLog("busy")); X/* X * the phone on the other end is ringing X */ X case 52: X DEBUG(4,"GOT: rring\n", CNULL); X } X } while ((i == 52) && (++rings < 6)); X alarm(0); X/* X * hopefully by the time we get here we will have a valid X * connect code and just have to set the baud rate acordingly X */ X switch (i) { X case 3: X i = 300; /* not on my system we don't! */ X break; X case 5: X i = 1200; X break; X case 10: X i = 2400; X break; X case 50: X i = PEPBAUD; X break; X/* X * rung too many times, assume no answer will come X */ X case 52: X tbcls(dh); X strcpy(devSel, dev->D_line); X return (FLog("no answer")); X/* X * probably don't need this but there is no overhead for it X */ X default: X tbcls(dh); X strcpy(devSel, dev->D_line); X return (FLog(cbuf)); X } X/* X * since we have been at high speed so far make sure we scale X * down if need-be X */ X if (i != PEPBAUD) { X fixline(dh, i); X DEBUG(4,"Baudrate reset to %d\n", i); X } X X DEBUG(4, "telebit connect at %d bps\n", i); X return (dh); X} X Xtbcls(fd) Xint fd; X{ X char dcname[20]; X X if (fd > 0) { X sprintf(dcname, "/dev/%s", devSel); X DEBUG(4, "Hanging up fd = %d\n", fd); X/* X * code to drop DTR forces hangup and modem reset X */ X ioctl(fd, TIOCCDTR, 0); X sleep(2); X ioctl(fd, TIOCSDTR, 0); X sleep(2); X ioctl(fd, TIOCFLUSH, 0); X close(fd); X/* X * remove any locks that may be on the device X */ X delock(devSel); X } X} X XFLog(str) Xchar *str; X{ X/* X * not much of a routine but we repeated this sequence so often X * I decided to move it out of site. X */ X DEBUG(4,"\nGOT: %s\n", str); X logent(str, _FAILED); X return (CF_DIAL); X} X#endif TELEBIT SHAR_EOF if test 7515 -ne "`wc -c < 'tb.c'`" then echo shar: error transmitting "'tb.c'" '(should have been 7515 characters)' fi fi # end of overwriting check # End of shell archive exit 0 -- Michael Galassi | If my opinions happen to be the same as ...!tektronix!tessi!percival!nerd | my employer's it is ONLY a coincidence, ...!uunet!littlei!percival!nerd | of cource coincidences DO happen.