On Thu, Oct 26, 2023 at 9:03 PM Theo de Raadt <dera...@openbsd.org> wrote:

>
> Crystal Kolipe <kolip...@exoticsilicon.com> wrote:
>
> > On Thu, Oct 26, 2023 at 12:20:08PM -0400, Morgan Aldridge wrote:
> > > Yes, your assumption was correct, every keypress acts as if I had
> pressed
> > > enter. Thanks for confirming!
> >
> > Getty re-displays the login prompt when it sees either 0x00 or 0x80 on
> the
> > serial line.  In fact, you can do it from the normal framebuffer console
> too,
> > just hit control-@ at the login prompt and it should repeat.
> >
> > (This is a historic behaviour which was once used for semi-automatic
> baud rate
> >  selection where you hit 'BREAK' a few times to get the remote end to
> cycle
> >  through all the speeds it supported until you, (hopefully), got a login
> >  prompt).
> >
> > So in your case, it seems that either the terminal is putting something
> on the
> > serial data lines that the USB serial adaptor is interpreting as nulls,
> or
> > possibly it's doing something with the handshaking lines that makes the
> > USB serial adaptor generate the equivalent internally.
> >
> > Any extra nulls added as padding bytes probably wouldn't show up in the
> > loopback test either, because the terminal would just happily ignore
> them.
>
> ktrace -di of the process will show what is going on
>

Thank you both!

Confirmed with `ktrace -di -g $(pgrep -f "getty std.9600 ttyU")` and
pressing a single character ('l'; a lower-case el... in hindsight, I should
have used a more recognizable character) on the connected terminal:

 14294 getty    CALL  read(0,0x78e711dd4246,0x1)
 14294 getty    GIO   fd 0 read 1 bytes
       "\0"
 14294 getty    RET   read 1

So, yeah, there's the null being received. The 'l' never is, but that jives
with what you've described regarding getty(8).

I disabled getty(8) on ttyU1, ran `cu -dr -l ttyU1 -s 9600`, then `ktrace
-di -g $(pgrep -f "cu -dr -l ttyU")`, and again pressed a single character
('l' again) on the connected terminal:

 62099 cu       CALL  read(3,0x2f26a7f400,0x2)
 62099 cu       GIO   fd 3 read 2 bytes
       "\0l"
 62099 cu       RET   read 2

Confirmed: there's the null being received before the 'l'. As you mentioned
was likely, cu(1) just ignores the null byte.

Performing the same cu(1) & ktrace(1) test with the TX/RX pins shorted and
pressing a single character ('l' again) in cu(1):

 72982 cu       CALL  write(3,0xbf9b0baf900,0x1)
 72982 cu       GIO   fd 3 wrote 1 bytes
       "l"
 72982 cu       RET   write 1
 72982 cu       CALL  kevent(4,0,0,0xbf9b0b8d000,64,0)
 72982 cu       STRU  struct kevent { ident=3, filter=EVFILT_READ,
flags=0x11<EV_ADD|EV_ONESHOT>, fflags=0<>, data=2, udata=0xbf9b0bb3c08 }
 72982 cu       RET   kevent 1
 72982 cu       CALL  ioctl(3,FIONREAD,0x74351e9ae74c)
 72982 cu       RET   ioctl 0
 72982 cu       CALL  read(3,0xbf9b0babd00,0x2)
 72982 cu       GIO   fd 3 read 2 bytes
       "\0l"
 72982 cu       RET   read 2

So, there it is, a single 'l' is written, but a null is read prior to the
'l'. So, it's the Keyspan/Tripp-Lite USA-19HS which is adding the null
byte. Again, I suspect the lack of flow-control implementation in ukspan(4)
is the culprit.

This weekend I'll do some more analysis with ktrace(1), especially loopback
tests with flow control lines shorted. I'll use my findings to work on
updating ukspan(4)'s ukspan_param() to handle flow control related c_cflag
masks such as CLOCAL, CCTS_OFLOW, CRTS_IFLOW, and MDMBUF, as described in
termios(4).

Morgan

Reply via email to