RTIO-based Remote LED Control

The author’s native language is Chinese. This document is translated using AI.

1. Introduction

In a production environment, RTIO services are typically deployed on cloud servers.

This article shares how to use a Windows PC (WSL2) as a server in a development environment to control connected devices. The model is shown below. Due to the length of this article, this demonstration will only show how to simulate mobile HTTP requests using the curl command. Future articles will showcase complete mobile-side device control.

+----------+          +--------------------+
|          |          |     WINDOWS11      |
| ESP32-C6 | -------> |                    |
|          |          |                    |
+----------+          | +----------------+ |
                      | |      WSL2      | |
+----------+          | |                | |
|          |          | | RTIO-Container | |
| Phone    | -------> | |                | |
|          |          | +----------------+ |
+----------+          +--------------------+

If the development environment is Linux (such as an Ubuntu PC), you can skip the WSL-related setup.

2. Hardware and Environment Setup

  • ESP32-C6-DevKitC-1 development board (official manual).
  • Windows with WSL2 installed.

Key information for the WSL experiment client is as follows:

$ hostnamectl
# ...
  Virtualization: wsl
Operating System: Ubuntu 22.04.3 LTS                       
          Kernel: Linux 5.15.167.4-microsoft-standard-WSL2
    Architecture: x86-64

This WSL Linux (hereinafter referred to as WSL) is mainly used for:

  • Compiling the demo source code for the ESP32-C6 side.
  • Deploying the RTIO server (running the RTIO Docker).
  • Sending HTTP requests using curl to simulate mobile device control.

The following setup is required:

3. Experiment Steps

3.1. Server Deployment

Pull the RTIO Docker image, run the RTIO service, and enable TLS device connection.

$ sudo docker pull registry.cn-guangzhou.aliyuncs.com/rtio/rtio:v0.8.0
# ...
Digest: sha256:...
$ sudo docker run -it --entrypoint ./rtio \
--rm  -p 17017:17017 -p 17917:17917 registry.cn-guangzhou.aliyuncs.com/rtio/rtio:v0.8.0  \
-disable.deviceverify -disable.hubconfiger \
-enable.hub.tls \
-hub.tls.certfile ./certificates/demo_server.crt \
-hub.tls.keyfile ./certificates/demo_server.key \
-log.level info
2024-12-26 09:13:41.998 INF rtio starting ...

To expose services externally using WSL, additional settings are required, such as configuring the firewall and port forwarding to WSL. Please refer to 4.1. WSL Network Configuration.

3.2. Device Side Compilation

First, download the rtio-device-sdk-c source code and switch to the demos-esp32/rtio/remote_switch directory.

git clone https://github.com/mkrainbow/rtio-device-sdk-c.git
cd rtio-device-sdk-c/demos-esp32/rtio/remote_switch

Second, set the target platform.

$ idf.py set-target esp32c6
-- Configuring done
-- Generating done
-- Build files have been written to: rtio-device-sdk-c/demos-esp32/rtio/remote_switch/build

$ idf.py menuconfig

Third, configure the WiFi SSID, WiFi password, and target server address.

$ idf.py menuconfig
    Serial flasher config  ---> 
    Partition Table  ---> 
    Example Configuration  ---> 
    ...

After running idf.py menuconfig, select Example Configuration ---> and configure the following options:

(myssid) WiFi SSID
(mypassword) WiFi Password
(demo.rtio.mkrainbow.com) RTIO Service HOST
(17017) RTIO Service PORT 

Fourth, compile the project, which should show a successful compilation message.

$ idf.py build
#...
Successfully created esp32c6 image.
#...
Project build complete. To flash, run:
 idf.py flash

Fifth, connect the development board’s USB port (type-c with “UART” marking) to the Windows host and begin flashing with the following command. Note that you need to map the board’s USB to WSL. For details, see 4.2. WSL Connect USB Devices.

$ idf.py flash

# ...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.0 seconds (effective 508.7 kbit/s)...
Hash of data verified.

If the flashing is successful, you can monitor the device logs. The following log indicates that both WiFi and RTIO server connections were successful.

I (7265) wifi station: got ip:192.168.xxx.xxx
I (7265) wifi station: connected to ap SSID: xxx password: xxx
# ...
[INFO] [RTIO] [7479] [core_rtio.c:481 connectRTIOServer] Device verification successful.

3.3. Sending Requests via curl to Switch LED

Base64 encode the “on” and “off” parameters.

$ echo -n "on" | base64
b24=
$ echo -n "off" | base64
b2Zm

Execute the following command in WSL to turn on the LED.

curl http://localhost:17917/cfa09baa-4913-4ad7-a936-3e26f9671b10 -d '{"method":"copost", "uri":"/switch","id":1234,"data":"b24="}'

Execute the following command to turn off the LED.

curl http://localhost:17917/cfa09baa-4913-4ad7-a936-3e26f9671b10 -d '{"method":"copost", "uri":"/switch","id":1234,"data":"b2Zm"}'

Observe the LED status on the development board (Appendix 3: Showcase). The key logs are as follows.

[INFO] [RTIO_SWITCH] [739574] [rtio_switch.c:51 uriSwitch] Handling the copost req with uri=/switch, pReqData=on.
[INFO] [RTIO_SWITCH] [746024] [rtio_switch.c:51 uriSwitch] Handling the copost req with uri=/switch, pReqData=off.

4.1. WSL Network Configuration

First, ensure that the Windows host network is set to “Private” instead of “Public”. If set to public, the Windows firewall will restrict LAN traffic.

Open Windows Settings, go to "Network and Internet" page, click on "Properties" at the top, and select "Private network".

Second, open port 17017 for RTIO service in the firewall. Open Windows PowerShell with administrator privileges and execute the following command.

netsh advfirewall firewall add rule name="17017 for RTIO" protocol=TCP localport=17017 dir=in action=allow

If you want to test the network with Ping, Windows may have “ICMP Echo” disabled by default. You can add the following rule.

netsh advfirewall firewall add rule name="ICMP for RTIO" protocol=ICMPV4 dir=in action=allow

Third, port forwarding. Forward the development board’s request to WSL. (WSL uses the default network model, but you can try other network modes such as Mirrored mode networking and skip the following steps.)

Get the WSL IP address.

> wsl --list --running
Ubuntu-22.04

> wsl -d Ubuntu-22.04  hostname -

I
172.22.3.95

Using “172.22.3.95” as an example, replace it with your own address. Run the following command for port forwarding.

netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=17017 connectaddress=172.22.3.95 connectport=17017

You can check the port forwarding with the following command.

netsh interface portproxy show all

4.2. WSL Connect USB Devices

For detailed information, refer to: Install the USBIPD-WIN project.

Install usbipd. Open Windows PowerShell with administrator privileges and run the following command.

winget install --interactive --exact dorssel.usbipd-win

Connect the development board and use usbipd to list devices.

> usbipd list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-10   0b05:1939  AURA LED Controller, USB Input Device                         Not shared
5-3    10c4:ea60  Silicon Labs CP210x USB to UART Bridge (COM5)                Not shared

Attach the device to WSL. The ESP32-C6-DevKitC-1 USB device is “Silicon Labs CP210x USB to UART Bridge”, and the BUSID is “5-3”.

> usbipd bind --busid 5-3

> usbipd list
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-10   0b05:1939  AURA LED Controller, USB Input Device                         Not shared
5-3    10c4:ea60  Silicon Labs CP210x USB to UART Bridge (COM5)                Shared

> usbipd attach --wsl --busid 5-3
usbipd: info: Using WSL distribution 'Ubuntu-22.04' to attach; the device will be available in all WSL 2 distributions.

The successful addition will be shown as above. In WSL, you can check for the device.

$ lsusb
Bus 001 Device 002: ID 10c4:ea60 Silicon Labs CP210x UART Bridge

$ ls /dev/ttyUSB0
/dev/ttyUSB0

/dev/ttyUSB0 can now be used for firmware flashing.

5. Appendix 2: End of Experiment (Optional)

5.1. Restore WSL Network Settings

Open Windows PowerShell with administrator privileges and run the following commands.

To close port forwarding.

netsh interface portproxy show all
netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=17017

Check the rules added for RTIO.

> netsh advfirewall firewall show rule name=all | Select-String "RTIO"
Rule Name:                             17017 for RTIO
Rule Name:                             ICMP for RTIO

Delete the related rules.

netsh advfirewall firewall delete rule name="17017 for RTIO"
netsh advfirewall firewall delete rule name="ICMP for RTIO"

5.2. Restore Network Properties

If it was set to “Public network” before the experiment, remember to change it back.

Open Windows Settings, go to "Network and Internet" page, click on "Properties" at the top, and select "Public network".

5.3. Unbind USB Devices

Open Windows PowerShell with administrator privileges and use the following commands to unbind, replacing BUSID with the target ID.

usbipd detach --busid BUSID
usbipd unbind --busid BUSID

6. Appendix 3: Showcase

alt text

As shown in the above picture, the data field in the message uses base64 encoding, which can be decoded as follows:

$ echo -n "b24=" | base64 -d
on
$ echo -n "b2Zm" | base64 -d
off
$ echo -n "b2s=" | base64 -d
ok

Conclusion: In the development environment (WSL2), using curl to send HTTP requests successfully turns the LED on or off, making it convenient for local testing. If RTIO is deployed in a cloud-based Linux environment, WSL-related operations can be skipped, and the deployment is simpler.