mirror of
https://github.com/daniviga/django-ram.git
synced 2026-03-21 07:42:30 +01:00
346 lines
8.3 KiB
Markdown
346 lines
8.3 KiB
Markdown
# DCC USB-to-Network Bridge Auto-Start Installation
|
|
|
|
This directory contains configuration files to automatically start the `dcc-usb-connector.service` when a specific USB device (CH340 USB-to-serial adapter, ID `1a86:7523`) is connected to `/dev/ttyUSB0`.
|
|
|
|
## Overview
|
|
|
|
The setup uses:
|
|
- **Udev rule** (`99-dcc-usb-connector.rules`) - Detects USB device connection/disconnection
|
|
- **Systemd user service** (`dcc-usb-connector.service`) - Bridges serial port to network port 2560
|
|
- **Installation script** (`install-udev-rule.sh`) - Automated installation helper
|
|
|
|
When the USB device is plugged in, the service automatically starts. When unplugged, it stops.
|
|
|
|
## Prerequisites
|
|
|
|
1. **Operating System**: Linux with systemd and udev
|
|
2. **Required packages**:
|
|
```bash
|
|
sudo dnf install nmap-ncat systemd udev
|
|
```
|
|
3. **User permissions**: Your user should be in the `dialout` group:
|
|
```bash
|
|
sudo usermod -a -G dialout $USER
|
|
# Log out and log back in for changes to take effect
|
|
```
|
|
|
|
## Quick Installation
|
|
|
|
Run the installation script:
|
|
|
|
```bash
|
|
./install-udev-rule.sh
|
|
```
|
|
|
|
This script will:
|
|
- Install the udev rule (requires sudo)
|
|
- Install the systemd user service to `~/.config/systemd/user/`
|
|
- Enable systemd lingering for your user
|
|
- Check for required tools and permissions
|
|
- Provide testing instructions
|
|
|
|
## Manual Installation
|
|
|
|
If you prefer to install manually:
|
|
|
|
### 1. Install the udev rule
|
|
|
|
```bash
|
|
sudo cp 99-dcc-usb-connector.rules /etc/udev/rules.d/
|
|
sudo udevadm control --reload-rules
|
|
sudo udevadm trigger --subsystem-match=tty
|
|
```
|
|
|
|
### 2. Install the systemd service
|
|
|
|
```bash
|
|
mkdir -p ~/.config/systemd/user/
|
|
cp dcc-usb-connector.service ~/.config/systemd/user/
|
|
systemctl --user daemon-reload
|
|
```
|
|
|
|
### 3. Enable lingering (optional but recommended)
|
|
|
|
This allows your user services to run even when you're not logged in:
|
|
|
|
```bash
|
|
sudo loginctl enable-linger $USER
|
|
```
|
|
|
|
## Verification
|
|
|
|
### Test the udev rule
|
|
|
|
```bash
|
|
# Monitor udev events (plug/unplug device while this runs)
|
|
udevadm monitor --property --subsystem-match=tty
|
|
|
|
# Test udev rule (when device is connected)
|
|
udevadm test /sys/class/tty/ttyUSB0
|
|
```
|
|
|
|
### Check service status
|
|
|
|
```bash
|
|
# Check if service is running
|
|
systemctl --user status dcc-usb-connector.service
|
|
|
|
# View service logs
|
|
journalctl --user -u dcc-usb-connector.service -f
|
|
```
|
|
|
|
### Test the network bridge
|
|
|
|
```bash
|
|
# Connect to the bridge
|
|
telnet localhost 2560
|
|
|
|
# Or using netcat
|
|
nc localhost 2560
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Automatic Operation
|
|
|
|
Once installed, the service will:
|
|
- **Start automatically** when USB device `1a86:7523` is connected to `/dev/ttyUSB0`
|
|
- **Stop automatically** when the device is disconnected
|
|
- Bridge serial communication to network port `2560`
|
|
|
|
### Manual Control
|
|
|
|
You can still manually control the service:
|
|
|
|
```bash
|
|
# Start the service
|
|
systemctl --user start dcc-usb-connector.service
|
|
|
|
# Stop the service
|
|
systemctl --user stop dcc-usb-connector.service
|
|
|
|
# Check status
|
|
systemctl --user status dcc-usb-connector.service
|
|
|
|
# View logs
|
|
journalctl --user -u dcc-usb-connector.service
|
|
```
|
|
|
|
## How It Works
|
|
|
|
### Component Interaction
|
|
|
|
```
|
|
USB Device Connected (1a86:7523 on /dev/ttyUSB0)
|
|
↓
|
|
Udev Rule Triggered
|
|
↓
|
|
Systemd User Service Started
|
|
↓
|
|
stty configures serial port (115200 baud)
|
|
↓
|
|
ncat bridges /dev/ttyUSB0 ↔ TCP port 2560
|
|
↓
|
|
Client apps connect to localhost:2560
|
|
```
|
|
|
|
### Udev Rule Details
|
|
|
|
The udev rule (`99-dcc-usb-connector.rules`) matches:
|
|
- **Subsystem**: `tty` (TTY/serial devices)
|
|
- **Vendor ID**: `1a86` (CH340 manufacturer)
|
|
- **Product ID**: `7523` (CH340 serial adapter)
|
|
- **Kernel device**: `ttyUSB0` (specific port)
|
|
|
|
When matched, it sets `ENV{SYSTEMD_USER_WANTS}="dcc-usb-connector.service"`, telling systemd to start the service.
|
|
|
|
### Service Configuration
|
|
|
|
The service (`dcc-usb-connector.service`):
|
|
1. Runs `stty -F /dev/ttyUSB0 -echo 115200` to configure the serial port
|
|
2. Executes `ncat -n -k -l 2560 </dev/ttyUSB0 >/dev/ttyUSB0` to bridge serial ↔ network
|
|
3. Uses `KillMode=mixed` for proper process cleanup
|
|
4. Terminates within 5 seconds when stopped
|
|
5. **Uses `StopWhenUnneeded=yes`** - This ensures the service stops when the device is removed
|
|
|
|
### Auto-Stop Mechanism
|
|
|
|
When the USB device is unplugged:
|
|
1. **Udev detects** the removal event
|
|
2. **Systemd removes** the device dependency from the service
|
|
3. **StopWhenUnneeded=yes** tells systemd to automatically stop the service when no longer needed
|
|
4. **Service terminates** gracefully within 5 seconds
|
|
|
|
This combination ensures clean automatic stop without requiring manual intervention or custom scripts.
|
|
|
|
## Troubleshooting
|
|
|
|
### Service doesn't start automatically
|
|
|
|
1. **Check udev rule is loaded**:
|
|
```bash
|
|
udevadm test /sys/class/tty/ttyUSB0 | grep SYSTEMD_USER_WANTS
|
|
```
|
|
Should show: `ENV{SYSTEMD_USER_WANTS}='dcc-usb-connector.service'`
|
|
|
|
2. **Check device is recognized**:
|
|
```bash
|
|
lsusb | grep 1a86:7523
|
|
ls -l /dev/ttyUSB0
|
|
```
|
|
|
|
3. **Verify systemd user instance is running**:
|
|
```bash
|
|
systemctl --user status
|
|
loginctl show-user $USER | grep Linger
|
|
```
|
|
|
|
### Permission denied on /dev/ttyUSB0
|
|
|
|
Add your user to the `dialout` group:
|
|
```bash
|
|
sudo usermod -a -G dialout $USER
|
|
# Log out and log back in
|
|
groups # Verify 'dialout' appears
|
|
```
|
|
|
|
### Device appears as /dev/ttyUSB1 instead of /dev/ttyUSB0
|
|
|
|
The udev rule specifically matches `ttyUSB0`. To make it flexible:
|
|
|
|
Edit `99-dcc-usb-connector.rules` and change:
|
|
```
|
|
KERNEL=="ttyUSB0"
|
|
```
|
|
to:
|
|
```
|
|
KERNEL=="ttyUSB[0-9]*"
|
|
```
|
|
|
|
Then reload:
|
|
```bash
|
|
sudo udevadm control --reload-rules
|
|
sudo udevadm trigger --subsystem-match=tty
|
|
```
|
|
|
|
### Service starts but ncat fails
|
|
|
|
1. **Check ncat is installed**:
|
|
```bash
|
|
which ncat
|
|
ncat --version
|
|
```
|
|
|
|
2. **Verify serial port works**:
|
|
```bash
|
|
stty -F /dev/ttyUSB0
|
|
cat /dev/ttyUSB0 # Should not error
|
|
```
|
|
|
|
3. **Check port 2560 is available**:
|
|
```bash
|
|
netstat -tuln | grep 2560
|
|
# Should be empty if nothing is listening
|
|
```
|
|
|
|
### View detailed logs
|
|
|
|
```bash
|
|
# Follow service logs in real-time
|
|
journalctl --user -u dcc-usb-connector.service -f
|
|
|
|
# View all logs for the service
|
|
journalctl --user -u dcc-usb-connector.service
|
|
|
|
# View with timestamps
|
|
journalctl --user -u dcc-usb-connector.service -o short-iso
|
|
```
|
|
|
|
## Uninstallation
|
|
|
|
To remove the auto-start feature:
|
|
|
|
```bash
|
|
# Remove udev rule
|
|
sudo rm /etc/udev/rules.d/99-dcc-usb-connector.rules
|
|
sudo udevadm control --reload-rules
|
|
sudo udevadm trigger --subsystem-match=tty
|
|
|
|
# Remove systemd service
|
|
systemctl --user stop dcc-usb-connector.service
|
|
rm ~/.config/systemd/user/dcc-usb-connector.service
|
|
systemctl --user daemon-reload
|
|
|
|
# (Optional) Disable lingering
|
|
sudo loginctl disable-linger $USER
|
|
```
|
|
|
|
## Advanced Configuration
|
|
|
|
### Customize for different USB device
|
|
|
|
Edit `99-dcc-usb-connector.rules` and change:
|
|
- `ATTRS{idVendor}=="1a86"` - USB vendor ID
|
|
- `ATTRS{idProduct}=="7523"` - USB product ID
|
|
|
|
Find your device IDs with:
|
|
```bash
|
|
lsusb
|
|
# Output: Bus 001 Device 003: ID 1a86:7523 QinHeng Electronics ...
|
|
# ^^^^:^^^^
|
|
# VID PID
|
|
```
|
|
|
|
### Change network port
|
|
|
|
Edit `dcc-usb-connector.service` and change:
|
|
```
|
|
ExecStart=/usr/bin/bash -c "/usr/bin/ncat -n -k -l 2560 ...
|
|
```
|
|
Replace `2560` with your desired port number.
|
|
|
|
### Enable auto-restart on failure
|
|
|
|
Edit `dcc-usb-connector.service` and add under `[Service]`:
|
|
```
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
```
|
|
|
|
Then reload:
|
|
```bash
|
|
systemctl --user daemon-reload
|
|
```
|
|
|
|
## Testing Without Physical Device
|
|
|
|
For development/testing without the actual USB device:
|
|
|
|
```bash
|
|
# Create a virtual serial port pair
|
|
socat -d -d pty,raw,echo=0 pty,raw,echo=0
|
|
|
|
# This creates two linked devices, e.g., /dev/pts/3 and /dev/pts/4
|
|
# Update the service to use one of these instead of /dev/ttyUSB0
|
|
```
|
|
|
|
## References
|
|
|
|
- [systemd user services](https://www.freedesktop.org/software/systemd/man/systemd.service.html)
|
|
- [udev rules writing](https://www.reactivated.net/writing_udev_rules.html)
|
|
- [ncat documentation](https://nmap.org/ncat/)
|
|
- [DCC++ EX](https://dcc-ex.com/) - The DCC command station software
|
|
|
|
## License
|
|
|
|
See the main project LICENSE file.
|
|
|
|
## Support
|
|
|
|
For issues specific to the auto-start feature:
|
|
1. Check the troubleshooting section above
|
|
2. Review logs: `journalctl --user -u dcc-usb-connector.service`
|
|
3. Test udev rules: `udevadm test /sys/class/tty/ttyUSB0`
|
|
|
|
For DCC++ EX or django-ram issues, see the main project documentation.
|