Search code examples
c++linuxunity-game-engineserial-portflatpak

How to read and write on serial ports on Unity Linux through C++ library?


  1. Introduction to the problem

I am developing a library in C++ that allows me to communicate with a device connected by USB reading and writing using serial ports, in Windows it works perfectly, but in Linux to be able to communicate with the devices I needed to read and write in the "/dev/tty*" files corresponding to each of them, for this task I use the "open" function to open the corresponding file as shown below:

int fileId = open(fileAddress, O_RDWR);

But this function returned -1 unless I included the main user in the dialout group using the following command:

sudo adduser $USER dialout
  1. Problem in Unity

With this I verified that everything worked perfectly in my C++ tests, but when I tried to include the library in the Unity project I realized that it failed again as it didn't have access to the serial ports

Since I am interested in the communication with the serial port being done through C++, as it is a cross-platform library, I cannot carry out the communication directly to C#

  1. Solution attemps

I was also looking for some possible solutions to said problem like in this case, but after trying for a while I couldn't get flatpak to find UnityHub since when calling this command:

/usr/bin/flatpak run --branch=stable --arch=x86_64 --device=all --command=start-unityhub com.unity.UnityHub

it threw me the following error:

error: app/com.unity.UnityHub/x86_64/stable is not installed

Even though I installed it following the official Unity installation guide for Ubuntu

I have also tried adding unity to remote flatpak repositories to see if that was the problem using the following command:

flatpak remote-add UnityHub https://hub.unity3d.com/linux/repos/deb

But it threw the following error:

error: GPG verification enabled, but no summary found (check that the configured URL in remote config is correct)
  1. Final question

In summary, my main question would be, what exactly should I do to be able to enable read and write permissions for serial ports in Unity and/or what would be the best way to solve this problem?

EDIT:

As I said in the comments, I already tried to add the user to dialout but apparently Unity was still unable to access the serial ports with said configuration as mentioned in response to this post, a workaround I did was to apply chmod on the specific tty files, the problem is that I have to manually do this and it is not practical when making an Unity build and that any user running the application has to manually find the corresponding tty file and apply chmod to it, if there isn't any other way to do it then, is there at least some way to apply chmod automatically or to solve this problem?


Solution

  • I'm not really sure where the problem lies, but I'll do my best to help.

    The official Unity installation guide for Ubuntu that you have linked to does not install Unity as a flatpak.

    That explains why flatpak tells you that it is not installed.

    The issue you're linking to is describing how flatpak's sandboxing affects Unity when accessing serial ports.

    Unless you followed a different tutorial than what you linked, this should not apply to you.

    I think your problem is that permissions on Ubuntu are not set up for serial port access by default. There is no "automatic" way to fix this, because it requires root permissions to change. What you could do, is bundle in an "installer" shell script with your program, and run that whenever you need the permissions to be changed.

    Command line version

    #!/bin/sh
    sudo usermod -a -G dialout "$USER"
    

    Graphical version (popup asking for password)

    #!/bin/sh
    pkexec usermod -a -G dialout "$USER"
    

    This isn't 100% portable, because not all Linux distributions use the dialout group, (for example, Arch Linux uses uucp) but it's probably good enough for your purposes on Ubuntu.