HermannSW
Posts: 717
Joined: Fri Jul 22, 2016 9:09 pm

Sending keystrokes to console process?

Sun May 27, 2018 8:17 am

I am using console a lot, but from ssh sessions (with latest Raspbian Stretch Lite):
  • for raspivid preview (raspivid -md 7 -w 640 -h 480 -p 706,20,640,480 -fps 180 -t 0)
  • with "fbi" command to display images (sudo fbi -T 1 test.png)
  • with "fbgrab" command to take screenshots
Recently I connected a small wireless keyboard and console worked like a charme.

I just found that after "sudo su" I can send characters to console, but they don't have any effect besides being displayed (echo -e "pi\npassword\n" > /dev/tty1).
Image

I found that remote controlling an application can be done via a FIFO:
https://stackoverflow.com/a/20323269/5674289

But the process I want to remote control (from ssh) is the console process, and that is already started.

Is it possible to "use" console (displayed on HDMI monitor) from ssh somehow "as if" a wireless keyboard is connected (some kind of console command processor input redirection)?
--> Raspberry camera / gstreamer / raspivid / raspiraw (bookmark list):
https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/fork-raspiraw      https://github.com/Hermann-SW/userland      https://twitter.com/HermannSW

HiassofT
Posts: 102
Joined: Fri Jun 30, 2017 10:07 pm

Re: Sending keystrokes to console process?

Sun May 27, 2018 4:06 pm

If you are running a text-mode application you could start it in "screen". screen sessions can be shared and you can then ssh in and attach to that screen session (see screen manpage for details).

Another possibility is to use /dev/uinput to inject input events - this can be mouse, keyboard, whatever you need. See the kernel docs for examples: https://www.kernel.org/doc/html/latest/ ... input.html

so long,

Hias

HermannSW
Posts: 717
Joined: Fri Jul 22, 2016 9:09 pm

Re: Sending keystrokes to console process?

Sun May 27, 2018 8:35 pm

Thanks, screen is no option since I want to "remote control" the console session seen on HDMI monitor.

"/dev/uinput" is definitely interesting and does that "remote control".
I compiled the keyboard event example (after adding missing includes for unistd.h, fcntl.h and string.h).
Executing the compiled program with sudo indeed outputs a space on console and moves cursor right

I looked up /usr/include/linux/input-event-codes.h and replaced both KEY_SPACE (for press and release) by KEY_P, compiled and executed again -- nothing happens. Not sure how to emit "p" for user pi login.

P.S:
There are 3 occurrences of KEY_SPACE, after I replaced all by KEY_P executing the program emits "p" to console.
Much code for emitting a single key. Anyway it should be possible to write a ssh_console_remote_control allowing to use the ssh session and do the same as a wireless keyboard would do -- nice!
--> Raspberry camera / gstreamer / raspivid / raspiraw (bookmark list):
https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/fork-raspiraw      https://github.com/Hermann-SW/userland      https://twitter.com/HermannSW

HiassofT
Posts: 102
Joined: Fri Jun 30, 2017 10:07 pm

Re: Sending keystrokes to console process?

Sun May 27, 2018 10:38 pm

You also need to add ioctl(fd, UI_SET_KEYBIT, KEY_P); at the beginning (after the KEY_SPACE UI_SET_KEYBIT ioctl). The UI_SET_KEYBIT ioctls set which keys are supported by your "virtual keyboard" and you have to call it for every key you are going to send out.

so long,

Hias

HermannSW
Posts: 717
Joined: Fri Jul 22, 2016 9:09 pm

Re: Sending keystrokes to console process?

Mon Jun 04, 2018 8:50 pm

I did a quick and dirty "line.c" console remote control program, can only do lower case letters, digits and some other ASCII characters. So this replaces the keyboard.

I found "telepi" project on Github, last updated 2014. That allows to view console even without monitor connected!
https://github.com/DougGore/telepi

I had to slow the .h264 transmission rate a bit, but then was able to "see" the console via cvlc.

These are the remote commands entered from ssh session:

Code: Select all

$ sudo ./line pi
$ sudo ./line raspberry
$ sudo ./line "uname -a"
$ sudo ./line "fbgrab tst.png"
$ 

And this is the result, successful login, and some commands:
Image


I think this is quite nice, use of Raspberry console with neither keyboard nor monitor!

Here is the (not nice) "line.c" for completeness:

Code: Select all

#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <linux/uinput.h>
#include <assert.h>

char map[128]={
0,0,0,0,0,0,0,0,0,0,0,0,0,KEY_ENTER,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
KEY_SPACE, 0, 0, 0, 0, 0, 0, KEY_APOSTROPHE, KEY_LEFTBRACE, KEY_RIGHTBRACE, KEY_KPASTERISK, KEY_KPPLUS, KEY_COMMA, KEY_MINUS, KEY_DOT, KEY_SLASH, KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, 0, KEY_SEMICOLON, 0, KEY_EQUAL, 0, 0 , 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0, KEY_BACKSLASH, 0, 0, 0,0, 0,
KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, KEY_K,
KEY_L, KEY_M, KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, KEY_U, KEY_V,
KEY_W, KEY_X, KEY_Y, KEY_Z, 0,0,0,0,0
};

void emit(int fd, int type, int code, int val)
{
   struct input_event ie;

   ie.type = type;
   ie.code = code;
   ie.value = val;
   /* timestamp values below are ignored */
   ie.time.tv_sec = 0;
   ie.time.tv_usec = 0;

   write(fd, &ie, sizeof(ie));
}

void EMIT(int fd,  int code)
{
   /* Key press, report the event, send key release, and report again */
   emit(fd, EV_KEY, code, 1);
   emit(fd, EV_SYN, SYN_REPORT, 0);
   emit(fd, EV_KEY, code, 0);
   emit(fd, EV_SYN, SYN_REPORT, 0);
}

int main(int argc, char *argv[])
{
   struct uinput_setup usetup;
   int i;

   int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);

   assert(argc=2);
   for(i=0; i<strlen(argv[1]); ++i)
     assert(map[(int)argv[1][i]]);

   ioctl(fd, UI_SET_EVBIT, EV_KEY);
   for (i=0; i < 256; i++) {
      ioctl(fd, UI_SET_KEYBIT, i);
   }

   memset(&usetup, 0, sizeof(usetup));
   usetup.id.bustype = BUS_USB;
   usetup.id.vendor = 0x1234; /* sample vendor */
   usetup.id.product = 0x5678; /* sample product */
   strcpy(usetup.name, "Example device");

   ioctl(fd, UI_DEV_SETUP, &usetup);
   ioctl(fd, UI_DEV_CREATE);

   sleep(1);

   for(i=0; i<strlen(argv[1]); ++i)
     EMIT(fd, map[(int)argv[1][i]]);

   EMIT(fd, KEY_ENTER);

   sleep(1);

   ioctl(fd, UI_DEV_DESTROY);
   close(fd);

   return 0;
}
Last edited by HermannSW on Tue Jun 05, 2018 8:33 am, edited 1 time in total.
--> Raspberry camera / gstreamer / raspivid / raspiraw (bookmark list):
https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/fork-raspiraw      https://github.com/Hermann-SW/userland      https://twitter.com/HermannSW

HermannSW
Posts: 717
Joined: Fri Jul 22, 2016 9:09 pm

Re: Sending keystrokes to console process?

Mon Jun 04, 2018 9:13 pm

Btw, telepi can handle raspivid preview screen as well(!).

This ssh remote control command:

Code: Select all

[email protected]:~ $ sudo ./line "raspivid -md 7 -w 640 -h 480 -p 30,30,320,240 -t 0 "
[email protected]:~ $

Resulted in this cvlc display of telepi .h264 transmission:
Image
--> Raspberry camera / gstreamer / raspivid / raspiraw (bookmark list):
https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/fork-raspiraw      https://github.com/Hermann-SW/userland      https://twitter.com/HermannSW

Return to “Raspbian”

Who is online

Users browsing this forum: No registered users and 32 guests