What to do if there is no driver in the smartphone. We continue experiments with “Aurora”
Hello reader!
Previously, I bought a phone with the Aurora OS and became a member of the beta testing program. This made it possible to develop software for mobile devices using Qt. But suddenly I faced a problem: it is not possible to connect to the smartphone through the old USB-good. As it turned out, the device “out of the box” does not have the necessary drivers. If you’re wondering how I solved this problem and connected via phone, I’m sorry!
Use the navigation if you don’t want to read the entire text:
→ Problems
→ Analysis
→ Implementation
→ Program example
→ Conclusion
Problems
When getting acquainted with Debian at school and in the first years of university, I encountered an interesting case: it was necessary to assemble a module from the weekend and sign it. The task is simple and was solved in most cases by obtaining the necessary makefile. However, there is no need for such manipulations now.
When connecting the gadget via the USB connector, you don’t have to think about installing the driver. Various input and storage devices, as well as communication interfaces, can work with the underlying driver of the operating system. There are extremely rare situations when it is necessary to download and install something to work with the device.
Surprisingly, deja vu happened in 2024. In the Aurora core, by default, there are only a few modules for peripherals. And those that implement the tty interface for CDC are completely absent. A couple of evenings were spent trying to assemble and sign the module. The lack of mokutil seemed to slow me down. However, later and with the help of keytool in keyring, it was not possible to add the necessary files to the system. Here it is – the maximum security of the Russian fork of the Finnish OS.
I did not know the solution to the problem and decided to contact the support of “Aurora” at the beginning of July. The answer did not help:
Therefore, there is no possibility to implement this connection. But there is a desire – let’s turn to the work of USB CDC and libusb.
During the preparation of the article, I posted the source code of the library on GitHub and shared the link in the Aurora developers’ chat. Because of the war, I received valuable feedback on managing the interface from the application and assigning application rights and accesses. With this knowledge, I plan to finalize the usability improvement library. Also, thanks to participation in the beta testing program, it was possible to contact the development team and request early access to the descriptors being created.
Analysis
I installed the usbutils package from the standard Aurora repository while testing the device’s USB connectivity. When I enter the lsusb command, I get output that shows which devices are on and some additional information about them.
[defaultuser@R570E ~]$ devel-su
Password:
[root@R570E defaultuser]# lsusb -v | grep "idVendor\|idProduct\|bEndpointAddress"
idVendor 0x1a86 QinHeng Electronics
idProduct 0x7523 HL-340 USB-Serial adapter
bEndpointAddress 0x82 EP 2 IN
bEndpointAddress 0x02 EP 2 OUT
bEndpointAddress 0x81 EP 1 IN
The last line is the connected device, which contains a usb-uart converter based on CH340. This device is an instance of USB CDC, that is, it implements data transfer interfaces. From the detailed conclusion, we are interested in endpoints X and Y.
After a short search, I found a couple of interesting and convenient repositories on GitHub: cdc example and ch340x. They are an example of how the libusb1.0 standard library can be used. There is also a great article on Habra to dive into USB work.
On the basis of the above repositories, I made my own small project for connecting to various usb-uart microcircuits and put it in open access. If only the dynamic library is needed, it can be downloaded from the latest release. To include the repository in the project and change it, execute the following commands in the src folder of the project:
git clone [email protected]:VORyabchevsky/experimental_1.git lib
curl -o lib/libusb.h https://raw.githubusercontent.com/tenderlove/libusb/refs/heads/master/libusb/libusb.h
Realization
The source code for the library is available in the CDCConnector repository on GitHub. The current version of the compiled library for the Aurora OS can be found on the release page.
First of all, I prepared a makefile that allows you to assemble a dynamic library. This must be done under the target system. If the library needs to be updated, for example, by increasing performance or adding new functionality, it is enough to call make all in the folder with the project.
Now let’s go directly to the implementation. To connect to devices via libusb, we need to select vid and pid devices, and to exchange information – data exchange endpoints. For this, he prepared the CDCDEV structure, which contains the minimum necessary information for work and reference fields.
If you need to add your chip with known endpoints, it is enough to declare a variable of type CDCDEV, for example:
CDCDEV PL2303 = {.vid=0x067b,
.pid=0x2303,
.devName="PL2303",
.desc="Prolific Technology, Inc. USB-Serial Controller",
.bulkReadEndpoint=0x83,
.bulkWriteEndpoint=0x02} ;
The devName and desc fields are only needed to display information later. In variants.h prepared several variants for popular microcircuits.
For ease of operation and debugging, I have prepared static functions:
- lsUSB — scans and receives a pool of connected USB devices, their vid and pid in the CDCDEV vector;
- lsCDC – scans and receives a pool of connected USB CDC devices, also stores in the CDCDEV vector.
Since it is planned to connect no more than one device to the phone, I additionally made the firstCDC function, which returns the CDCDEV of the first found device to which variants.h endpoints are connected.
Next, you need to set the message exchange rate, bit parity, and packet size. Most often, the last two fields are left as they are, but it is better to predict their change. The default mode is 115,200 baud, 8n1. If necessary, you can change this by calling the setBaudrate function. It easily recalculates the speed into a sequence of bytes to transfer them to the endpoint using libusb_control_transfer:
if (!(110>8;
}
return 0;
After performing preliminary settings of the communication interface, you can start opening the port and exchanging information. Here’s an example of connecting to a device for gcc:
…
CDCDEV variant;
int res = CDCConnector::firstCDC(&variant);
if (res!=1) {
std::cout 0){
buf[len] = 0;
fprintf(stdout, "Received: \"%s\"\n", buf);
std::cout
Example program
This program is compiled using public key pairs. After the development is completed, I plan to order a separate pair of keys for the possibility of publishing programs in the store.
I developed a simple Aurora IDE example using the dynamic library mentioned above. The program detects the presence of a connected USB-COM converter and establishes a connection for data exchange.
Screenshot of the program screens.
When developing and debugging a library on a device, it’s convenient to add an extra step to the application’s build pipeline.
What needs to be done
- Go to Projects.
- Select a tab Drafting.
- In the field Drafting add stage select “Special processing stage”.
- Raise the created stage to the second place (after checking the Building Engine) and write the parameters according to your IDE parameters.
For clarity, I showed the pipeline in the image:
Step-by-step automation of the process.
Next, in order for the program to use the compiled library, it is necessary to connect it in the *.pro file:
LIBS += -L$$PWD/lib/ -lcdcc -lusb-1.0
I+=libusb/libusb/
Then you need to connect the header file in the code:
#include
#include
To check the functionality after the first power-on using the QDebug module, let’s output information to the phone console or the PC console:
When calling the function in debugging, we can see that devices with VID and PID have been determined.
Next, you need to manually allow work with the USB device, otherwise you will receive an access denied error. To do this, in the console in administrator mode, recursively raise the level of privileges to everything in the /dev/bus/usb folder:
devel-su
chmod 777 /dev/bus/usb/001/*
After that, you can start testing the work and using the application itself.
Conclusion
The implemented library allows you to connect and configure interaction with a wide range of devices implementing USB CDC: from industrial controllers and switches to independent Arduino-based devices. I plan to collect some old pet-projects for a mobile operating system, making them more compact and practical.
Such a library can be used not only for existing CDC chips, but also for other devices with endpoints for reading and writing information. I will improve this library by adding polling and setting DTR, RTS, etc. signals.
There is great potential for the use of such libraries in Aurora. The system can be applied to the development of interfaces of embedded equipment. For example, a smart home control screen or an input panel for a CNC machine. Functionality is limited only by the imagination of the author!