[comp.dcom.modems] Don't forget Ring Indicate

scl@virginia.acc.virginia.edu (Steve Losen) (01/27/88)

I would like to toss in my $0.02 on this dialin/out problem.  I
implemented this on a vax 780 running BSD4.2.  I followed the same
approach as outlined earlier with two logical devices for each physical
tty port.  However, we had a special problem that needs to be addressed
by anyone implementing any new tty drivers.

We have a lot of our hosts connected to an Ungermann/Bass LAN
(essentially a port switch).  We noticed that the UBLAN had the nasty
habit of raising CD whenever it saw DTR.  This completely defeated
my first attempt at solving the dialin/out problem because the
open(2) call raises DTR right away.  Getty would open the line for
dialin and start sending login: to the UBLAN (which was in command mode)
and we'd get a "babbling getty".

With a little more investigation I found that the UBLAN and most (if not all)
modems make use of ring indicate (RI pin 22).  If someone calls into
a modem and the host has DTR off, the modem raises RI instead of
answering the phone.  When the host sees RI, it raises DTR, the
modem answers the phone, and the modem raises CD, allowing the open(2)
on the tty to succeed.  Similarly, the UBLAN raises RI when it tries to
connect to a host that has DTR off.

Here is our solution as best as I can recall now:

DialOUT Open Algorithm:
	if (dialIN flag set) { /* someone has logged in on this line */
		set errno to EBUSY
		return with a failure.
	}
	Set dialout flag.
	Raise DTR.
	return with success.  /* no waiting for CD */

DialOUT Close Algorithm   /* note close only happens on LAST close */
	clear dialOUT flag
	if (HUPCL)
		drop DTR
	close.

DialIN Open Algorithm:
	/* DO NOT RAISE DTR */
	if (CD off) {
		do {
			wait for CD raise event  /* see interrupt handler below */
	 	} while dialOUT flag set.
	}
	set dialIN flag.
	return with success.

DialIN Close Algorithm
	clear dialIN flag.
	if (HUPCL)
		drop DTR

Interrupt Handler for changes in RI or CD
/* kernel jumps to this routine whenver RI or CD changes state */
	If (RI is up || CD is up)
		raise DTR
	if (CD is up)
		signal CD raise event
	if (CD is off)
		drop  DTR

You will also note that with this implementation you can connect two
hosts to each other with a single serial line (null modem) and allow
each host to have a getty.  Since Neither host raises DTR until it
tries to dialout to the other system, the two gettys don't babble
at each other.  Thus either host can initiate a call to the other
over that one line.

I was lucky that the VAX 780 dh tty hardware was able to detect changes
in RI.  I am currently hamstrung with systems that pay no attention
to RI (ATT 3B) and thus am forced to hassle with uugetty.
-- 
Steve Losen     scl@virginia.edu
University of Virginia Academic Computing Center

chris@mimsy.UUCP (Chris Torek) (01/29/88)

In article <571@virginia.acc.virginia.edu> scl@virginia.acc.virginia.edu (Steve Losen) writes:
>We have a lot of our hosts connected to an Ungermann/Bass LAN
>(essentially a port switch).  We noticed that the UBLAN had the nasty
>habit of raising CD whenever it saw DTR.

The U/B is doing it wrong, then.  Of course, that is no help for
those who have U/B equipment.  It is even arguably correct, since
the thing is in command mode, but they should have thought `modem',
not `weird network device', and at least made this configurable.

>With a little more investigation I found that the UBLAN and most
>(if not all) modems make use of ring indicate (RI pin 22).

Unfortunately, as you mention, most multiplexors (or at least those
for the Vax) pay no attention to RI.  You could wire a flip-flop
to be set by RI and cleared by ~DTR, and tie that to the multiplexor
board's CD, solving the U/B problem, but that would take extra hardware.

>If someone calls into a modem and the host has DTR off, the modem
>raises RI instead of answering the phone.  When the host sees RI,
>it raises DTR, the modem answers the phone, and the modem raises
>CD, allowing the open(2) on the tty to succeed.

In fact, when we were running 4.1BSD, we had two Vaxen connected
to each other by a hardwired line, and decided to use *it*
bidirectionally.  For this we came up with what we called `passive'
mode: open on the passive device would wait for CD without asserting
DTR, and would assert DTR only when it saw CD.  Opening the dial
device would assert DTR without waiting for CD.  The normal device
would raise DTR and wait for CD.  Hence a passive device would
speak to a dial device `properly', while two `normal' devices would
wage wearying war.  Summary:

	normal:	 raise DTR, then wait for CD.
	dial:	 raise DTR.
	passive: wait for CD, then raise DTR.

The interlocking required for dial/normal/passive is identical
to that for dial/normal, since one uses only one of normal/passive.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris