Using socat for raw serial connection - linux

The goal is to connect to an embedded device using serial interface.
So far, I've used:
stty -F /dev/ttyS2 115200 cs8 ixoff
socat readline,history=/etc/socat.history /dev/ttyS2,raw,echo=0
And it works excellent, but then I discovered that there are some options during system boot that require you to press a single key without pressing enter, and readline fails there. So my idea was to bind the ttyS2 to cons0, but then I discovered multiple problems, such as inability to quit (ctr+c, ctr+q ctr+] and even esc doesn't work), backspace and delete do not work, letters are typed twice, etc. So after some trial and error, I came up with this:
socat /dev/cons0,raw,echo=0,crnl /dev/ttyS2,raw,echo=0,escape=0x03,crnl
raw on both sides allows a single key press to trigger a boot option
echo=0 on both sides prevents key press doubling
crnl on both sides prevent enter key press doubling
escape=0x03 allows me to quit the thing by pressing ctr+c
The problem is, when I quit, my cons0 is all f****d up, as if it somehow preserved the raw,echo=0,crnl settings. I know this problem is probably too specific for my scenario, but I just need a simple way to send keystrokes to serial as I would with putty (which is not available on my platform). I am using socat because it is extremely lightweight, does not require any aditional libraries, and because the shown commands are a part of the greater script that uses expect.
Any ideas and suggestions are greatly appreciated.

As Austin Phillips says, you can use stty sane to recover...
...but what is even better is that you can (probably) append it to your socat command as socat xxxxx ; stty sane and have the recovery be automatic when you quit with ctrl-c.

Thanks, that worked for me!
I just want to point out that the script should not rely on "static" console identification, because when expect spawns the script, it is going to have a completely different tty, therefor:
socat $(tty),raw,echo=0,escape=0x03 /dev/ttyS2,raw,echo=0,nonblock ; stty sane
edit: nonblock also solved the "enter" problem

Related

Why does cygwin mintty type 8~ (tilde) on its own?

CYGWIN_NT-6.3 x86_64
I open and use a terminal (mintty) and every so often an
8~
or simply
~
will appear on the commandline.
Why does this happen and how do I prevent this from happening.
Found the cause.
I run a utility to keep my windows machine from going to sleep. In the background it creates an event for key-up for F15.
This has been transparent until using cywin.
If the utility that is causing this input is Caffeine sending a F15 key up event, you can prevent it from happening in two ways:
Prevent F15 from being interpreted on the mintty side: Add the following line to your mintty config file (e.g. ~/.minttyrc). It tells mintty to ignore F15 by itself or with the Ctrl modifier, which does the trick for me (by itself, it produces ~, and with Ctrl, ;5~):
KeyFunctions=F15:void;C+F15:void
Prevent Caffeine from sending F15 by running it with the -useshift option.
I guess the first way is preferrable, because it keeps all the benefits of using the F15 key up event.

File list by ls are misaligned

I catted a binary file and hit Ctrl-Z to stop it. Now ls results are misaligned. What did it happen and how could I have them listed correctly again ?
Type reset to reset your terminal, and press Enter. Then maybe press Ctrl+L to clear the screen. You should be back to normal.
Oh and by the way, that binary cat you ran, when you pressed Ctrl-Z that just suspended it, it's probably still running. Run jobs to see the list of jobs, and if it's there, say job number 2, do kill %2 (or whichever job number).
When you catted the binary file, your terminal probably inadvertently interpreted some of its data as control sequences and tried to execute them, screwing its properties and state.
You can either kill the terminal altogether (quit it if you're in a GUI, or relog if you're on a tty), or use another control sequence to reset the terminal. echo -e \\033c should do the trick. Some systems also have a reset builtin/command, which accomplishes the same thing.

Write Text and command keys to a TTY on Linux

im working on a keyboard injection for a /dev/tty device.
The only thing i found out was using the TIOCSTI ioctl command to inject text into the buffer. As far as good, but i also need to submit the command i typed in. Is there a way to send command keys like strg, return, shift, etc to a /dev/tty?
Thanks in advance.
Made some mistake in the past. You can send any ascii char via TIOCSTI, so sending an '\n' or ASCII 27 you simulate a press on Return.

Need command-fedora-keyboard navigation key substitution in TCL script for a switch (CLI)

I have a switch (CLI based) that takes me to the present STP setting when you hit the alphabets (which iam able to automate with tcl) but when it comes to changing the STP setting say from RSTP to MSTP, manually, I have to hit the up arrow and down arrow keys( only option available).
I need help to give the up arrow and down arrow commands in tcl format to automate it.
I read about rlwrap but thats more of history/ file editing which may not be helpful for me.
I have tried the " ^[[A" and "[A" options and hexacodes with no success.
I have tried "\u001b[A" etc but the value STP does not change. The CLI is A XML CLI. This is my script .
spawn telnet $DUT1_IP expect "login:" send "$user\r" expect "Password:" send "$password\r" expect "sh-3.2#" #sleep 2 send "xml_cli\r" expect ">> " send "bridge_config_mode = STP"
If i have to change mode STP to MSTP i need to use up arrow key in my keyboard to change it to MSTP /RSTP . how to use in expect to handle the same . Please give your thoughts if we can use shell scripting for the same (or any other).
Thanks and Regards
Mo
Up is mapped by your system keyboard driver to a three-character sequence: ^[[A. The first character, rendered as ^[ here, is an Escape character that is not normally renderable on your screen, and you write a real one in a Tcl script with \u001b. Down is correspondingly ^[[B. (Strictly, it could be other character sequences — it depends on the terminal type after all — but virtually everything uses the same thing here, and thank goodness!)
Let's simplify things for you by putting those key sequences in variables (we also need a backslash before the real [ because it is a Tcl metasyntax character):
set up "\u001b\[A"
set down "\u001b\[B"
Now you can do this to send the characters to the remote side:
send $up
expect "...whatever..."
send $down
expect "...blah..."

Why vim doesn't work correctly into a telnet session?

I use vim (7.1) on OpenVMS V7.3-2.
I connect to VMS trough a telnet session with SmartTerm, a terminal emulator.
It works fine.
But when I start a telnet session from a VMS session (connected via SmartTerm) to another VMS session, some keys doesn't work properly.
|--------------| telnet |-------------| telnet |-----------------|
| Smartterm | ------> | VMS, Vim OK | ------> | VMS, Vim broken |
|--------------| |-------------| |-----------------|
Insert, Delete, Home, End, PageUp and PageDown are like ~ in normal mode ( upcase to lowercase or vice-versa )
Any idea ?
=============================================
Edit
I just realized that I didn't mention that the second telneted session is on the same VMS box.
I do that because I need to do something with rights from another user.
In addition to tweaking which terminal emulation is used, it's also a good idea to learn vim's keystrokes for the actions you're trying to perform. These are more reliable and don't depend on the terminal or the keyboard. For instance:
Insert: i
Home: ^ goes to first non-whitespace char, 0 goes to first column always
End: $
PageUp, PageDown: ctrl-u, ctrl-d move a half-page at a time
I've experienced similar issues while resurrecting a dusty old Solaris box. I was too lazy to search for how I should set my t_... variables correctly, so I remapped the faulty terminal escape sequences instead:
:map xxx 0 (press <C-v><Home> in place of xxx)
:map xxx <C-b> (press <C-v><PgUp> in place of xxx)
... etc
If you want setup this damned thing right, RTFMing might eat quite some nerve and time:
:h terminal-options
Usually this is because of the terminal emulation - so something isn't passing the right keys thru. It's been ages since I've done this, but look for stuff like VT-100 and the like. I doubt it's specific to vim, either :)
Sorry I can't be more help.
The first question to ask is simply: What are you sitting in front of? Are you really on the console of a VAX or Alpha running OpenVMS? My guess is the answer is no.
In the unlikely event that the answer is yes, simply enter:
$ SHOW TERMINAL
and make sure that the TERM variable on the remote UNIX host matches this exactly.
If my guess is correct and you're sitting in front of a PC or a Mac running some sort of terminal emulator like PuTTY or Terminal, then you need to explore your software's options to ensure that the terminal it's emulating is correctly reflected in both the VMS system's world view and that of the remote UNIX host.
Once you've figured out what kind of terminal you're emulating, use the VMS command above once again on the VMS system you're connected to to ensure that there is a match.
If not, simply correct the situation by typing:
$ SET TERMINAL/DEVICE=(your termainal name - e.g. vt100)
and then make sure that TERM on the remote unix host matches what the VMS system is set to.
Once you do all this, everything should work fine.
In addition to how to set env variables on terminal device compatibility, a tip on the telnet client itself might be useful:
Before usual Esc combination use Ctrl+[, e.g. to quit vim
Ctrl+[ Esc :q!

Resources