Tru-facts about /etc/acucap generic dial support
George Robbins
grr at cbmvax.UUCP
Wed Feb 10 09:28:28 AEST 1988
XYZXYZ Warning: this may be Ultrix 1.2 specific XYZXYZ
I've been trying get my Telebit Trailblazer modems working reliably
with the Ultrix shared modem support at assorted speeds for both
dial-in and dial-out. Up till today, I've been trying to do this
with the "built-in" hayes support, but have encountered a fair
amount of frustration.
I've previously tried to use the "generic dialer" or acucap support,
but was greatly frustrated by my inability to get the software to
do anything consistently. Before trying again, I decided to try to
map out fairly precisely what the dialing code really does, where
error/status messages come out and what the general constraints are.
This is the result of a days debugging and analysis, combined with
some general notions about the way uucp works. There are bound to
be some minor and more stupid mistakes, but I think the gist of this
information will be useful. I don't have Ultrix sources, but I'd be
glad if someone that does could check this out. Of course it's also
possible that everything has been fixed and made rational in Ultrix
Release 2.x; perhaps Marc T. can comment...
Now, I guess that based on all this research, I am should be able to
construct functional and even reliable acucap entries! However, I'll
leave the results for another message.
Notes:
1) The acucap generic dialer facility is completely separate form the
normal unix dialers.
2) The strings defined in the termcap entries are *not* send/expect
strings in the uucp sense. Any escapes are translated by the termcap
type routines, and the dialer routines simply print the result with
some specified intra-character delay.
3) Not only does this mean you can't "program" in delays, breaks, parity
or similar stuff, you have very little control over the timing of
sending the strings.
4) You may not be able to combine a functional hayes style +++ sequence,
with other commands, depending on the definition your modem uses.
If 'guard' is the number of seconds of quiet required before and after
the +++, some modems also require less than 'guard' between the +'s.
You may find similar problems with too much delay between the A and T
of AT style command sequences.
5) Despite the documentation, the delay to wait for carrier to come on :fd:
is always in seconds. If you use the :lt: option and try to specify
a value in microseconds, your uucp will be hung up for a looooog time.
6) Not exactly mentioned in the documentation, but if you don't specify
a dial initialization string :di:, then the entire dialing step is
skipped.
7) The intra-character delay in the disconnect sequence is always 1,
either 1 second if you don't use :lt: or 1 microsecond if you do.
8) They way the response strings are processed is kind of goofy. If there
is a time limit on the response, then the program does a "sleep" for
that period. After the sleep, or if there was no limit, the input
routine checks for characters and tries to match them against the
desired response string. If there's not a match, it tries to get more
characters. Anyway, if no characters are received within one second
it times out and fails, otherwise keeps trying as long as characters
keep coming.
9) Operations in "shared" line mode require careful modem setup. The
modem should normally leave DSR off until in data mode, should not
deliver response messages on incoming calls and should not echo in
command mode. An ill-mannered modem will appear to be "active" to
getty and will not be available for sharing. It may also engage
in a prolonged conversation with getty/login, potentially wasting
cpu cycles or more dire evils.
10) Owners of DMF-32's will find that *no* incoming characters are
delivered unless the modem is asserting carrier detect. Due to (9)
above you can't leave "carrier detect on in command mode" set, or
the modem will not "share". This generally means that you will
have to use the :si: flag and dial "blind" and that you won't get
much in the way of meaningful diagnostic response codes.
11) An alternative, assuming that dropping DTR resets your modem's
options, is to include some modem command in the synchronization :ss:
string that turns on carrier in command mode, since no response codes
are looked at until after the :ss: string has been sent.
12) Since it cannot be guaranteed that the +++ style disconnect sequences
will work for a random hayes type modem, it is all but essential that
you use a cable/interface that supports modem control, and that modem
control be enabled for that line. For a shared line, this appears to
be controlled by the lines entry in the /etc/ttys's file, however it
would probably be a good idea not to have modem control disabled by
the interface flags in your systems config file.
General Flow:
This is intended only to show the sequence of operations, and indicate
where error messages and stuff are coming from....
debug implies a message controlled by uucico "-x" switch
ddebug implies a message controlled by the :db: termcap option
assert implies a message that is fatal - usually some inconsistently
log imples something that should show up in the /usr/spool/uucp/LOGFILE
genopn() is called from the general connect processing when your L-devices
file indicates you want some auto-dialer, and it isn't one of the built-ins,
and it was found in the /etc/acucap file.
genopn()
========
open device
log open errors
ioctl TIOCSINUSE - get shared modem
log shared modem error
debug "calling gen_setup"
ioctl TIOCNCAR - ignore software carrier
call routine to extract acucap fields
get process group
ioctl TIOCSPGRP - set device process group
call fixline() common setup processing
looks up speed in spds table
assert "BAD SPEED" - not in table
ioctl TIOCGETP - gtty
munge line parameters
ioctl TIOCSETP - stty
assert "RETURN FROM STTY" - no driver support
ioctl TIOCHPCL - hangup on close
ioctl TIOCEXCL - set exclusive use
calls gen_dialer
error analysis
debug "generic dialer error on %s"
set up message - one of:
"can't sync" "misdialed - try another" "no carrier"
log "generic dialer failed - acu = %s, cause = <message>"
flush input
return - either try new dialer or proceed with "login"
gencls() is called after the call is complete, or if things go sour.
note than more general clsacu does a ioctl TIOCNCAR to disable software
carrier detect before calling gencls.
gencls()
========
debug "close generic - Def = %d"
call gen_disconnect
log "close generic acu fd = %d"
sleep 5
return
gendialer() is the routine that actually handles the entire dialing sequence.
it really uses several more subroutines, but they'be been unrolled here.
gen_dialer()
============
ddebug - dump acucap parameters
ddebug - "gensync"
if :re:
ioctl TIOCCDTR - clear DTR
sleep 2
ioctl ITOCSDTR - set DTR
if :ss:
call output(:ss:,:sd:) - string, delay
if :sr:
call input(:sr:) -- note only 1 sec to respond!
if :hu:
ioctl TIOCHPCL - hangup on close - note already set by fixline!
if error
return can't sync
ddebug "gendial"
if :di: - skips dialing sequence if no :di: !!!
if :rs: - replace string
munge = and - in phone number to :rs:
concat :di: and number
if :dt:
concat :dt:
ddebug "dials = <concat>"
output(concat,:dd:) - output :di:phone:dt: at one crack, dial delay per :lt:
if :dr: - dial response
sleep(:da:) - :da: interpreted per :lt:
call input(:dr:)
if error
ddebug "gendial failed <dialer>"
else
ddebug "gendial success: respbuf = <response>"
if error
call gen_disconnect()
return mis-dialed
ioctl TIOCFLSH - flush buffers
setup alarm handler
when alarm
ddebug "online failed"
break
ioctl TIOCCAR - enable software carrier det.
if :cr: - wait for carrier
ddebug "waiting for carrier"
call alarm(:fd:) - note :fd: is always in seconds - no :lt: mediation
ioctl TIOCWONLINE - wait for carrier
call alarm(0) - unless timed out...
ddebug "carrier detected"
reset alarm handler
if :os: - online string
call input(:os:) - note :os: must start within one second of carrier!!!
if error
ddebug "online failed"
else
ddebug "online succeded"
if error
call gen_disconnect()
return no carrier
if :cs:
output(:cs:,:cd:) - completion string, completion delay per :lt:
if any errors
can gen_disconnect()
return error
else
return good
gen_disconnect() is called either at the end of a call, or by the gen_dialer
code when a call has been started, but hasn't been completed successfully.
gen_disconnect()
================
ddebug "gendisconnect"
if :ds: - disconnect string
call sleep(1) - one second
call output(:ds:,1) - disc string, one second or 1 microsec delay per :lt:
call sleep(1)
close device
More information about the Comp.unix.ultrix
mailing list