Keyboard as stdin for asp net core application

I need a support for

Console.ReadKey();

in ASP.NET Core application deployed to container app on host balenaFin v1.1 (CM3). I have a keyboard plugged to headless device(no monitor, no xserver, console app) and need to provide some pin code. When I run application on localhost, it detects what I entered.

docker-compose.yml

version: '2.1'
services:
  web:
    environment:
      - 'DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket'
      - 'ASPNETCORE_ENVIRONMENT=Development'
    labels:
      io.balena.features.dbus: '1'
    ports:
      - "80:3000"
    privileged: true
    stdin_open: true
    tty: true

Dockerfile

FROM balenalib/armv7hf-debian-dotnet:3.1-aspnet AS base
WORKDIR /app
EXPOSE 3000
ENV ASPNETCORE_URLS=http://+:3000
ENV UDEV=on

FROM balenalib/armv7hf-debian-dotnet:3.1-sdk-stretch AS build
WORKDIR /src
COPY . .
RUN dotnet restore "./Device/Device.csproj"
WORKDIR "/src/Device"
RUN dotnet build "Device.csproj" -c Release -o /app

FROM build AS publish
WORKDIR "/src/Device"
RUN dotnet publish "Device.csproj" -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Device.dll", "--server.urls", "http://0.0.0.0:3000"]

I use logger provider to display logs on balena dashboard logs. For example:

this.logger.LogInformation("KeyboardListener is started");
while(true)
{
    if (Console.KeyAvailable)
    {
        ConsoleKeyInfo key = Console.ReadKey(true);
        if (key.Key == ConsoleKey.Backspace)
        {
              this.logger.LogInformation("Backspace was pressed");
              this.inputCharacters.Clear();
        }
    }
}

displays “KeyboardListener is started” and “Backspace was pressed” everytime I press Backspace button. Application on balena just displays “KeyboardListener” like it does not detect when key is pressed.

When i run

cat /proc/bus/input/devices

it displays same on HOST OS and application container(web)

I: Bus=0003 Vendor=c0f4 Product=01e0 Version=0110
N: Name="USB usb keyboard"
P: Phys=usb-3f980000.usb-1.4/input0
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.0/0003:C0F4:01E0.0003/input/input3
U: Uniq=
H: Handlers=sysrq kbd leds event0 
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff800000 7ff febeffdf f3cfffff ffffffff fffffffe
B: MSC=10
B: LED=7

I: Bus=0003 Vendor=c0f4 Product=01e0 Version=0110
N: Name="USB usb keyboard Consumer Control"
P: Phys=usb-3f980000.usb-1.4/input1
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.1/0003:C0F4:01E0.0004/input/input4
U: Uniq=
H: Handlers=kbd event1 
B: PROP=0
B: EV=1f
B: KEY=300ff 0 0 0 0 483ffff 17aff32d bf544446 0 0 1 130c73 b17c000 267bfa d9415fed 9e1680 4400 0 10000002
B: REL=40
B: ABS=1 0
B: MSC=10

I: Bus=0003 Vendor=c0f4 Product=01e0 Version=0110
N: Name="USB usb keyboard System Control"
P: Phys=usb-3f980000.usb-1.4/input1
S: Sysfs=/devices/platform/soc/3f980000.usb/usb1/1-1/1-1.4/1-1.4:1.1/0003:C0F4:01E0.0004/input/input5
U: Uniq=
H: Handlers=kbd event2 
B: PROP=0
B: EV=13
B: KEY=c000 100000 0 0 0
B: MSC=10

In /dev/input i have

Host OS

root@3b903ed:~# ls /dev/input
by-id  by-path  event0  event1  event2  mice

Container

root@9f039c289005:/app# ls /dev/input
event0  event1  event2  mice

When I run on container’s terminal

cat /dev/input/event0

some characters are shown everytime I pressed keyboard’s buttons. (Example for multiple time pressed ESC button below)

root@640a96c20ee0:/dev/input# cat event0
�<�`��)�<�`���<�`���<�`(
                        )�<�`(
                              �<�`(
                                   �<�`�:
                                         )�<�`�:
                                                �<�`�:
                                                      �<�`J1)�<�`J1�<�`J1�<�`�i)�<�`�i�<�`�i�<�`c1)�<�`c1�<�`c1�<�`c�)�<�`c��<�`c��<�`�X
                                                                                                                                        )�<�`�X
                                                                                                                                               �<�`�X
                                                                                                                                                     �<�`�)�<�`��<�`�^C
1 Like

Hi and welcome to the forums.

What you are describing assumes the pty device, that the keyboard is attached to, is connected to the container’s stdin. This is unfortunately not true and there is no supported way to achieve this. That said it is unlikely we can make Console.ReadKey(); work as you expect.

You are going the right direction though - in order to read input from the keyboard within a container you need to listen to the events from the /dev/input/event* file and parse them in your application. This is usually done using libinput or evdev but as I understand none of those has bindings for .NET. A quick search led me to the following article: Linux & Dotnet – Read from a device file – HoNoSoFt which suggests a HidSharp library could do the trick. From a high-level perspective there should be little difference between looping over pressed console keys and looping over input events, though there may be .NET technicalities I am not aware of.

2 Likes

Thank you for support. I have used HidSharp library and application detects keyboard’s inputs (not so easy like Console.ReadKey() but still not so hard to use).

Good to hear that works for you. Do not hesistate to contact us in case you have more questions.