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.