Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unknown error 203 while reading from serial port on Debian (WSL) #687

Closed
alexxxz1977 opened this issue Dec 9, 2019 · 28 comments
Closed
Assignees
Labels
area-System.IO.Ports os-windows-wsl WSL (Windows Subsystem for Linux) OS - Linux binaries running on Windows
Milestone

Comments

@alexxxz1977
Copy link

Hello,

I am trying to write a simple console application to read data from USB device available through COM5. When I am trying to run the code under Windows 10 everything working fine. However I am getting some strange error when trying to run the code under Debian 10 (WSL). Here is a code:

            port.Open();
 	    var buf = new byte[5];
            var l = port.BaseStream.Read(buf, 0, 5);
            Console.WriteLine("Bytes read: ", l);
            Console.WriteLine("Content: ", BitConverter.ToString(buf).Replace("-",""));
            port.Close();

After running this code I am always see:

Unhandled exception. System.UnauthorizedAccessException: Access to the port '/dev/ttyS5' is denied.
---> System.IO.IOException: Unknown error 203
--- End of inner exception stack trace ---
at System.IO.Ports.SafeSerialDeviceHandle.Open(String portName)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
at hello_serialport.Program.Main(String[] args)

I've tried all possible combinations with permissions to COM port, added myself to dialout group, etc.... nothing is working. I am pretty sure that issue is not related with accessing the COM port through WSL, because have a python script which can read everything from the same port without any issues.

Any ideas why this might happens?

/Alexander

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added area-System.IO untriaged New issue has not been triaged by the area owner labels Dec 9, 2019
@davidsh
Copy link
Contributor

davidsh commented Dec 9, 2019

However I am getting some strange error when trying to run the code under Debian 10 (WSL).

WSL doesn't use a real Linux kernel. Many of the sys calls are not really implemented in WSL.

It will be interesting to see if this works with WSL2 on the latest Windows 10 Insider Preview builds. That uses a real Linux kernel.

@am11
Copy link
Member

am11 commented Dec 10, 2019

Seems like opposite is true, microsoft/WSL#4322; /dev/ttyS accessible in WSL is no longer in WSL2.

@alexxxz1977
Copy link
Author

As I said, I have a python script, which doing exactly the same (reading the values from com-port) which is working perfectly fine on WSL. As far I could see in the sources the problem occurs when native function is trying to set terminal into exclusive mode.

@wfurt
Copy link
Member

wfurt commented Dec 17, 2019

cc: @krwq @ManickaP

@ManickaP
Copy link
Member

ManickaP commented Dec 17, 2019

I'll check it out and report back.

So I was able to reproduce it on both WSL 1 and 2, using dotnet core 3.1 and Ubuntu 18.04.

@ManickaP ManickaP self-assigned this Dec 17, 2019
@krwq
Copy link
Member

krwq commented Dec 17, 2019

@ManickaP can you also reproduce python is working for you? What license is the python code, can we see what we do differently?

@ManickaP
Copy link
Member

ManickaP commented Dec 17, 2019

@alexxxz1977 Could you please post python repro?
And could you also share how you construct SerialPort instance?

@wfurt
Copy link
Member

wfurt commented Dec 17, 2019

I think key is to understand what 203 error is. I could not find any information about it. As minimum, we should also update mapping so it does not show as unknown.

@ManickaP
Copy link
Member

I've been digging around about this 203 error and couldn't find anything either. Also if I extract the C code called underneath and call it directly I get different errno.

@alexxxz1977 I need the full repro, including the instantiation of the SerialPort and the python repro you say is working.

@ManickaP ManickaP added needs more info os-windows-wsl WSL (Windows Subsystem for Linux) OS - Linux binaries running on Windows labels Dec 18, 2019
@alexxxz1977
Copy link
Author

Hello guys,

I did some research on this issue and found the following. The error happens in native code when calling ioctl function:

intptr_t SystemIoPortsNative_SerialPortOpen(const char * name)
{
    intptr_t fd;
    while ((fd = open(name, O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK)) < 0 && errno == EINTR);

    if (fd < 0)
    {
        return fd;
    }

    if (ioctl(fd, TIOCEXCL) != 0)
    {
        // We couldn't get exclusive access to the device file
        int oldErrno = errno;  */errno here is equal to 203
        close(fd);
        errno = oldErrno;
        return -1;
    }

    return fd;
}

I really don't know why it happens, I tried to play with permissions for COM port but nothing is working. The mentioned python script you can find here https://github.com/sameer/python-openzwave-sniffer. However it doesn't help you too much, since it requires Z-Wave USB stick and basically it uses openzwave library which is written on C and also open COM port using native functions. Instead of this I tired to play with other libraries for accessing COM port from .NET Core. I found two of them.

The first one called SerialPortStream(https://github.com/jcurl/SerialPortStream) and has its own native library to access COM port from Linux. Unfortunately I didn't find the sources for the second one which is called NetCoreSerial. Seems its only available as nuget package. However looking at the sample of usage in this repository (https://github.com/Ellerbach/serialapp) seems it just calling standard functions from Libc library.

BOTH are working fine on WSL/Debian 10. The sample of code I used for test is quite simple - just read and display incoming 5 bytes from COM port.

        static void Main(string[] args)
        {
            SerialPortStream port = new SerialPortStream("/dev/ttyS5", 115200);
            port.Open();
            var buf = new byte[5];
            var l = port.Read(buf, 0, 5);
            Console.WriteLine("Bytes read: {0}", l);
            Console.WriteLine("Content: {0}", BitConverter.ToString(buf).Replace("-", ","));
            port.Close();
        }

@ManickaP
Copy link
Member

ManickaP commented Dec 19, 2019

Not much found so far.
If I run port.Open(); within our testhost context (as a libraries test in runtime repo), I get errno 13 and nice "Permission Denied" description in the exception.
If I run the repro program against the locally built bits of master of runtime libraries, I still get 203. However, the native method SystemIoPortsNative_SerialPortOpen returns errno 13 after calling the open, which I confirmed by adding printf there.

I still don't know where the 203 comes from and why do I get in the repro program even if it runs with the same bits as the tests...

@alexxxz1977 Could you try to run the .NET Core repro under sudo? For me, it gets rid of the UnauthorizedAccessException but still fails later.

@ManickaP
Copy link
Member

ManickaP commented Dec 19, 2019

Also there seems to be only one significant difference between SerialPortStream and our implementation. And that is O_CLOEXEC flag passed to open.

Without the flag the error is the same.

@janvorli
Copy link
Member

I don't know about the error 203, but regarding the permissions issue, I've found the following page that has some details on how to fix that:
https://askubuntu.com/questions/210177/serial-port-terminal-cannot-open-dev-ttys0-permission-denied
It seems that the last message in the discussion should be the solution:

sudo usermod -a -G dialout <user>
sudo usermod -a -G tty <user>

@alexxxz1977
Copy link
Author

This does not work, tried several times

@krwq
Copy link
Member

krwq commented Dec 20, 2019

@alexxxz1977 not perfect but adding following udev rule (just save the file there):

/etc/udev/rules.d/50-myusb-rules.rules

SUBSYSTEM=="tty", KERNEL=="ttyUSB*", MODE="0777"
SUBSYSTEM=="tty", KERNEL=="ttyACM*", MODE="0777"

worked pretty well for me (you might need to adjust for other names like ttyS* etc if needed)

@alexxxz1977
Copy link
Author

No, this doesn't work. There are no ttyUSB or ttyACM devices on WSL at all. Every USB device is mapped by Windows to corresponding /dev/ttySX port where X is number of COM port on Windows. This is an article how it works:

https://blogs.msdn.microsoft.com/wsl/2017/04/14/serial-support-on-the-windows-subsystem-for-linux/

I am trying to run application under sudo and still have this freaking error number 203.

@ManickaP
Copy link
Member

ManickaP commented Dec 20, 2019

I am trying to run application under sudo and still have this freaking error number 203.

Interesting.
On the other hand, I am trying the SerialPortStream lib and I am getting the UnauthorizedAccess:

System.UnauthorizedAccessException: Can't open serial port (0; Permission denied)
   at RJCP.IO.Ports.Native.UnixNativeSerial.ThrowException() in /home/manicka/serialportstream/code/Native/UnixNativeSerial.cs:line 81
   at RJCP.IO.Ports.Native.UnixNativeSerial.Open() in /home/manicka/serialportstream/code/Native/UnixNativeSerial.cs:line 648
   at RJCP.IO.Ports.SerialPortStream.Open(Boolean setCommState) in /home/manicka/serialportstream/code/SerialPortStream.cs:line 246
   at RJCP.IO.Ports.SerialPortStream.Open() in /home/manicka/serialportstream/code/SerialPortStream.cs:line 216
   at issue_687.Program.Main(String[] args) in /home/manicka/issue_687/Program.cs:line 15

So I'm getting UnauthorizedAccessException with either lib on both WSL and native linux.
With sudo I'm able to open the port with either lib on native linux, but not on WSL.

Lastly, if I set the rights via sudo chmod 666 /dev/ttySX on native linux, the .NET Core SerialPort works without being run under sudo.

@alexxxz1977
Copy link
Author

Don't know what to say. Before playing with SerialPortStream I did a lot experiments with permissions for /dev/ttySX, so suddenly I did something that allowing the library to read serial stream. However on my RPi where I am deploying a ready solution the library is working fine without any manipulations with the permissions.

@ManickaP
Copy link
Member

ManickaP commented Dec 20, 2019

And have you tried System.IO.Ports on RasPI? Did it failed there as well as on WSL?

@ManickaP
Copy link
Member

You have WSL1, don't you? I just switched from WSL2 --> WSL1 and I'm getting the 203 even with sudo permissions.

@alexxxz1977
Copy link
Author

Yes, I am using WSL 1. I didn't try how System.IO.Ports is working on my RPi. I wanted to have quick solution allowing me to check how the build is working under Linux so I had to use SerialPortStream instead. I will try to install WSL 2 to see does System.IO.Ports is working well there.

@ManickaP
Copy link
Member

On WSL1 with SerialPortStream lib under sudo I'm getting:

System.IO.IOException: Can't open serial port (0; Input/output error)
   at RJCP.IO.Ports.Native.UnixNativeSerial.ThrowException() in /home/manicka/serialportstream/code/Native/UnixNativeSerial.cs:line 89
   at RJCP.IO.Ports.Native.UnixNativeSerial.Open() in /home/manicka/serialportstream/code/Native/UnixNativeSerial.cs:line 648
   at RJCP.IO.Ports.SerialPortStream.Open(Boolean setCommState) in /home/manicka/serialportstream/code/SerialPortStream.cs:line 246
   at RJCP.IO.Ports.SerialPortStream.Open() in /home/manicka/serialportstream/code/SerialPortStream.cs:line 216
   at issue_687.Program.Main(String[] args) in /home/manicka/issue_687/Program.cs:line 15

And I'm getting the same 'Input/output error' if I run stty. I'm no expert on this, but the toutorial you linked above instructs to map COM port in Win registry, which I didn't do.

Honestly, my best bet would be to use VS Code with remoting extension, SSH directly to RasPi and develop there. However, I'm not sure about how 'slow' this setup would be.

@alexxxz1977
Copy link
Author

I am using RPi at home and not always have access to it, since traveling my my laptop. I just wanted to have some kind of Linux testing environment, so decided that wsl would be a good idea

@ManickaP ManickaP mentioned this issue Mar 3, 2020
25 tasks
@JeremyKuhne
Copy link
Member

Triage: @ManickaP, what are the next steps for this issue?

@JeremyKuhne JeremyKuhne removed the untriaged New issue has not been triaged by the area owner label Mar 4, 2020
@JeremyKuhne JeremyKuhne added this to the Future milestone Mar 4, 2020
@ManickaP
Copy link
Member

ManickaP commented Mar 5, 2020

Hi @alexxxz1977, by any chance did you get to test this on WSL2? And does the scenario works for you on RasPi?

@ManickaP
Copy link
Member

ManickaP commented Mar 5, 2020

@JeremyKuhne Unfortunately I'm not equipped to fully repro this issue since I don't have the USB stick. Anyway, this might be unsupported feature of WSL (see microsoft/WSL#4322).
However, if the scenario'll work on RaspPi and the WSL2 officially does not support it yet 'In initial releases of WSL 2 hardware access support will be limited, e.g: you will be unable to access the GPU, serial or USB devices.', I'm inclined to close this and redirect people to vote for the feature in WSL repo.

@alexxxz1977
Copy link
Author

Hi @alexxxz1977, by any chance did you get to test this on WSL2? And does the scenario works for you on RasPi?

Hi, unfortunately I didn't have chance to test it neither RaspPI nor WSL2. You can close it since there is workaround with another library. I can reopen it anytime if find a time to provide additional info

@ManickaP
Copy link
Member

ManickaP commented Mar 5, 2020

@alexxxz1977 Thanks for the reply. Feel free to reopen the issue whenever you'd like to continue to investigate this.

@ManickaP ManickaP closed this as completed Mar 5, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 11, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.IO.Ports os-windows-wsl WSL (Windows Subsystem for Linux) OS - Linux binaries running on Windows
Projects
None yet
Development

No branches or pull requests

10 participants