mirror of
https://github.com/daniviga/django-ram.git
synced 2026-03-20 23:32:30 +01:00
Manage dcc-usb-connector auto-stop on removal
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# Udev rule to auto-start dcc-usb-connector.service when USB device is connected
|
||||
# Udev rule to auto-start/stop dcc-usb-connector.service when USB device is connected/removed
|
||||
#
|
||||
# This rule detects when a CH340 USB-to-serial adapter (ID 1a86:7523)
|
||||
# is connected and assigned to /dev/ttyUSB0, then automatically starts
|
||||
# is connected/removed on /dev/ttyUSB0, then automatically starts/stops
|
||||
# the dcc-usb-connector.service (user systemd service).
|
||||
#
|
||||
# Installation:
|
||||
@@ -13,8 +13,10 @@
|
||||
# udevadm test /sys/class/tty/ttyUSB0
|
||||
# udevadm monitor --property --subsystem-match=tty
|
||||
#
|
||||
# The service will be started/stopped automatically when the device
|
||||
# is plugged in/unplugged.
|
||||
# The service will be started when the device is plugged in and stopped
|
||||
# when the device is unplugged.
|
||||
|
||||
# Match USB device 1a86:7523 on ttyUSB0 and trigger user systemd service
|
||||
# Match USB device 1a86:7523 on ttyUSB0
|
||||
# TAG+="systemd" tells systemd to track this device
|
||||
# ENV{SYSTEMD_USER_WANTS} starts the service on "add" and stops it on "remove"
|
||||
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", KERNEL=="ttyUSB0", TAG+="systemd", ENV{SYSTEMD_USER_WANTS}="dcc-usb-connector.service"
|
||||
|
||||
@@ -161,6 +161,17 @@ The service (`dcc-usb-connector.service`):
|
||||
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
|
||||
|
||||
|
||||
@@ -1,17 +1,53 @@
|
||||
# Use a container to implement a serial to net bridge
|
||||
# DCC Serial-to-Network Bridge
|
||||
|
||||
This uses `ncat` from [nmap](https://nmap.org/ncat/) to bridge a serial port to a network port. The serial port is passed to the Podman command (eg. `/dev/ttyACM0`) and the network port is `2560`.
|
||||
This directory provides two ways to bridge a serial port to a network port using `ncat` from [nmap](https://nmap.org/ncat/):
|
||||
|
||||
1. **Auto-Start with systemd + udev** (Recommended) - Automatically starts/stops when USB device is plugged/unplugged
|
||||
2. **Container-based** - Manual control using Podman/Docker
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Other variants of `nc` or `ncat` may not work as expected.
|
||||
|
||||
## Build and run the container
|
||||
## Option 1: Auto-Start with systemd + udev (Recommended)
|
||||
|
||||
Automatically start the bridge when USB device `1a86:7523` is connected to `/dev/ttyUSB0` and stop it when removed.
|
||||
|
||||
### Quick Install
|
||||
|
||||
```bash
|
||||
$ podman buil -t dcc/bridge .
|
||||
./install-udev-rule.sh
|
||||
```
|
||||
|
||||
### Features
|
||||
- ✅ Auto-start when device connected
|
||||
- ✅ Auto-stop when device removed
|
||||
- ✅ User-level service (no root needed)
|
||||
- ✅ Runs on boot (with lingering enabled)
|
||||
|
||||
See [INSTALL.md](INSTALL.md) for detailed documentation.
|
||||
|
||||
### Test
|
||||
|
||||
```bash
|
||||
# Run the test script
|
||||
./test-udev-autostart.sh
|
||||
|
||||
# Or manually check
|
||||
systemctl --user status dcc-usb-connector.service
|
||||
telnet localhost 2560
|
||||
```
|
||||
|
||||
## Option 2: Container-based (Manual)
|
||||
|
||||
### Build and run the container
|
||||
|
||||
```bash
|
||||
$ podman build -t dcc/bridge .
|
||||
$ podman run -d --group-add keep-groups --device=/dev/ttyACM0:/dev/arduino -p 2560:2560 --name dcc-bridge dcc/bridge
|
||||
```
|
||||
|
||||
### Test
|
||||
|
||||
It can be tested with `telnet`:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
[Unit]
|
||||
Description=DCC USB-to-Network Bridge Daemon
|
||||
After=network.target
|
||||
# Device will be available via udev rule, but add condition as safety check
|
||||
ConditionPathIsReadWrite=/dev/ttyUSB0
|
||||
# Stop this service when the device is no longer needed (removed)
|
||||
StopWhenUnneeded=yes
|
||||
|
||||
[Service]
|
||||
ExecStartPre=/usr/bin/stty -F /dev/ttyUSB0 -echo 115200
|
||||
|
||||
147
connector/test-udev-autostart.sh
Executable file
147
connector/test-udev-autostart.sh
Executable file
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Test script for DCC USB-to-Network Bridge auto-start/stop functionality
|
||||
#
|
||||
# This script helps verify that the service starts when the USB device
|
||||
# is connected and stops when it's removed.
|
||||
#
|
||||
# Usage:
|
||||
# ./test-udev-autostart.sh
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}=== DCC USB-to-Network Bridge Auto-Start/Stop Test ===${NC}"
|
||||
echo
|
||||
|
||||
# Check if udev rule is installed
|
||||
echo -e "${BLUE}1. Checking udev rule installation...${NC}"
|
||||
if [ -f /etc/udev/rules.d/99-dcc-usb-connector.rules ]; then
|
||||
echo -e "${GREEN}✓ Udev rule is installed${NC}"
|
||||
echo " Location: /etc/udev/rules.d/99-dcc-usb-connector.rules"
|
||||
else
|
||||
echo -e "${RED}✗ Udev rule is NOT installed${NC}"
|
||||
echo " Run: sudo cp 99-dcc-usb-connector.rules /etc/udev/rules.d/"
|
||||
exit 1
|
||||
fi
|
||||
echo
|
||||
|
||||
# Check if service is installed
|
||||
echo -e "${BLUE}2. Checking systemd service installation...${NC}"
|
||||
if [ -f ~/.config/systemd/user/dcc-usb-connector.service ]; then
|
||||
echo -e "${GREEN}✓ Systemd service is installed${NC}"
|
||||
echo " Location: ~/.config/systemd/user/dcc-usb-connector.service"
|
||||
else
|
||||
echo -e "${RED}✗ Systemd service is NOT installed${NC}"
|
||||
echo " Run: cp dcc-usb-connector.service ~/.config/systemd/user/"
|
||||
exit 1
|
||||
fi
|
||||
echo
|
||||
|
||||
# Check lingering
|
||||
echo -e "${BLUE}3. Checking systemd lingering...${NC}"
|
||||
if loginctl show-user "$USER" | grep -q "Linger=yes"; then
|
||||
echo -e "${GREEN}✓ Lingering is enabled${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ Lingering is NOT enabled${NC}"
|
||||
echo " Services may not start automatically when you're not logged in"
|
||||
echo " Run: sudo loginctl enable-linger $USER"
|
||||
fi
|
||||
echo
|
||||
|
||||
# Check if device is connected
|
||||
echo -e "${BLUE}4. Checking USB device...${NC}"
|
||||
if lsusb | grep -q "1a86:7523"; then
|
||||
echo -e "${GREEN}✓ USB device 1a86:7523 is connected${NC}"
|
||||
lsusb | grep "1a86:7523"
|
||||
|
||||
if [ -e /dev/ttyUSB0 ]; then
|
||||
echo -e "${GREEN}✓ /dev/ttyUSB0 exists${NC}"
|
||||
ls -l /dev/ttyUSB0
|
||||
else
|
||||
echo -e "${YELLOW}⚠ /dev/ttyUSB0 does NOT exist${NC}"
|
||||
echo " The device may be on a different port"
|
||||
echo " Available ttyUSB devices:"
|
||||
ls -l /dev/ttyUSB* 2>/dev/null || echo " (none found)"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}⚠ USB device 1a86:7523 is NOT connected${NC}"
|
||||
echo " Please plug in the device to test"
|
||||
fi
|
||||
echo
|
||||
|
||||
# Check service status
|
||||
echo -e "${BLUE}5. Checking service status...${NC}"
|
||||
if systemctl --user is-active --quiet dcc-usb-connector.service; then
|
||||
echo -e "${GREEN}✓ Service is RUNNING${NC}"
|
||||
systemctl --user status dcc-usb-connector.service --no-pager -l
|
||||
else
|
||||
echo -e "${YELLOW}⚠ Service is NOT running${NC}"
|
||||
echo " Status:"
|
||||
systemctl --user status dcc-usb-connector.service --no-pager -l || true
|
||||
fi
|
||||
echo
|
||||
|
||||
# Test udev rule
|
||||
echo -e "${BLUE}6. Testing udev rule (if device is connected)...${NC}"
|
||||
if [ -e /dev/ttyUSB0 ]; then
|
||||
echo " Running: udevadm test /sys/class/tty/ttyUSB0"
|
||||
echo " Looking for SYSTEMD_USER_WANTS..."
|
||||
if udevadm test /sys/class/tty/ttyUSB0 2>&1 | grep -q "SYSTEMD_USER_WANTS"; then
|
||||
echo -e "${GREEN}✓ Udev rule is triggering systemd${NC}"
|
||||
udevadm test /sys/class/tty/ttyUSB0 2>&1 | grep "SYSTEMD_USER_WANTS"
|
||||
else
|
||||
echo -e "${RED}✗ Udev rule is NOT triggering systemd${NC}"
|
||||
echo " The rule may not be matching correctly"
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}⚠ Cannot test udev rule - device not connected${NC}"
|
||||
fi
|
||||
echo
|
||||
|
||||
# Check network port
|
||||
echo -e "${BLUE}7. Checking network port 2560...${NC}"
|
||||
if netstat -tuln 2>/dev/null | grep -q ":2560" || ss -tuln 2>/dev/null | grep -q ":2560"; then
|
||||
echo -e "${GREEN}✓ Port 2560 is listening${NC}"
|
||||
netstat -tuln 2>/dev/null | grep ":2560" || ss -tuln 2>/dev/null | grep ":2560"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ Port 2560 is NOT listening${NC}"
|
||||
echo " Service may not be running or ncat failed to start"
|
||||
fi
|
||||
echo
|
||||
|
||||
# Summary and instructions
|
||||
echo -e "${BLUE}=== Test Summary ===${NC}"
|
||||
echo
|
||||
echo "To test auto-start/stop behavior:"
|
||||
echo
|
||||
echo "1. ${YELLOW}Monitor the service in one terminal:${NC}"
|
||||
echo " watch -n 1 'systemctl --user status dcc-usb-connector.service'"
|
||||
echo
|
||||
echo "2. ${YELLOW}Monitor udev events in another terminal:${NC}"
|
||||
echo " udevadm monitor --property --subsystem-match=tty"
|
||||
echo
|
||||
echo "3. ${YELLOW}Plug in the USB device${NC} and watch:"
|
||||
echo " - Udev should detect the device"
|
||||
echo " - Service should automatically start"
|
||||
echo " - Port 2560 should become available"
|
||||
echo
|
||||
echo "4. ${YELLOW}Unplug the USB device${NC} and watch:"
|
||||
echo " - Udev should detect device removal"
|
||||
echo " - Service should automatically stop (thanks to StopWhenUnneeded=yes)"
|
||||
echo " - Port 2560 should close"
|
||||
echo
|
||||
echo "5. ${YELLOW}Check logs:${NC}"
|
||||
echo " journalctl --user -u dcc-usb-connector.service -f"
|
||||
echo
|
||||
echo "Expected behavior:"
|
||||
echo " • Device connected → Service starts → Port 2560 opens"
|
||||
echo " • Device removed → Service stops → Port 2560 closes"
|
||||
echo
|
||||
Reference in New Issue
Block a user