# USB/IP Supervisor

A comprehensive USB/IP supervisor system for automatic device management between remote systems. Automatically monitors USB devices, handles hot-plugging, and maintains connections with automatic recovery.

## Features

- **Automatic Device Management**: Automatically bind/unbind USB devices based on physical presence
- **Hot-Plug Support**: Detects device connection/disconnection via udev monitoring
- **Network Recovery**: Automatic reconnection on network dropouts
- **Access Control**: Per-device client authorization on server
- **TUI Configuration**: Interactive terminal-based configuration wizard
- **systemd Integration**: Run as system services with automatic startup
- **Health Monitoring**: Periodic device state verification and recovery

## Requirements

- **Operating System**: Linux only
- **Runtime**: Bun >= 1.0
- **System Packages**: 
  - `usbip` (usbip-utils package)
  - Kernel modules: `vhci-hcd`, `usbip-core`
- **Permissions**: Root/sudo access for:
  - Installing udev rules
  - Running usbip commands
  - Installing systemd services

## Installation

### Install via npm

```bash
# Install globally
npm install -g @siwats/usbip-supervisor

# Or use with bunx (no installation needed)
bunx @siwats/usbip-supervisor --help
```

### Install usbip

```bash
# Ubuntu/Debian
sudo apt install linux-tools-generic usbip

# Fedora/RHEL
sudo dnf install usbip-utils

# Arch Linux
sudo pacman -S usbip
```

## Quick Start

### Server Setup

1. **Configure the server**:
```bash
bunx @siwats/usbip-supervisor server --configure
```

Follow the prompts to:
- Set listen address (default: 0.0.0.0)
- Set listen port (default: 3240)
- Add USB devices by vendor:product ID
- Specify allowed client IDs (optional)

2. **Start the server**:
```bash
bunx @siwats/usbip-supervisor server
```

3. **Install as systemd service** (optional):
```bash
sudo bunx @siwats/usbip-supervisor server --install-systemd
sudo systemctl start usbip-supervisor-server
```

### Client Setup

1. **Configure the client**:
```bash
bunx @siwats/usbip-supervisor client --configure
```

Follow the prompts to:
- Set client ID (unique identifier)
- Set server address and port
- Add USB devices to attach

2. **Start the client**:
```bash
bunx @siwats/usbip-supervisor client
```

3. **Install as systemd service** (optional):
```bash
sudo bunx @siwats/usbip-supervisor client --install-systemd
sudo systemctl start usbip-supervisor-client
```

## Configuration

Configuration files are stored in `~/.config/usbip-supervisor/`:
- `server.yaml` - Server configuration
- `client.yaml` - Client configuration

### Server Configuration Example

```yaml
listenAddress: 0.0.0.0
listenPort: 3240
logLevel: info
devices:
  - path: "pci-0000:00:14.0-usb-0:1:1.0"
    description: "USB Dongle on Port 1"
    allowedClients:
      - client1
      - client2
  - path: "pci-0000:00:14.0-usb-0:2:1.0"
    description: "USB Dongle on Port 2"
    allowedClients: []  # Allow all clients
```

### Client Configuration Example

```yaml
clientId: client1
serverAddress: 192.168.1.100
serverPort: 3240
logLevel: info
devices:
  - path: "pci-0000:00:14.0-usb-0:1:1.0"
    description: "USB Dongle from Server Port 1"
```

## Finding USB Device Paths

The supervisor uses USB by-path for device identification to uniquely identify each physical USB port. This allows you to use multiple identical USB devices.

### Method 1: Using the Configuration Wizard (Recommended)

The easiest way is to use the interactive configuration wizard, which automatically detects and displays available USB devices with their paths:

```bash
# Server
bunx @siwats/usbip-supervisor server --configure

# Client
bunx @siwats/usbip-supervisor client --configure
```

The wizard will show all connected USB devices with their paths and allow you to select them by index number.

### Method 2: Manual Discovery

You can manually find USB device paths using `udevadm`:

```bash
# List all USB devices with their paths
for dev in /dev/bus/usb/*/*; do
  echo "Device: $dev"
  udevadm info -q property $dev | grep -E "ID_PATH=|ID_VENDOR_ID=|ID_MODEL_ID=|ID_SERIAL="
  echo
done
```

Example output:
```
Device: /dev/bus/usb/001/002
ID_PATH=pci-0000:00:14.0-usb-0:1:1.0
ID_VENDOR_ID=1234
ID_MODEL_ID=5678
ID_SERIAL=ABC123
```

### Understanding USB By-Path

USB by-path follows the physical topology of your USB bus:
- Format: `pci-<PCI_address>-usb-<port_chain>`
- Example: `pci-0000:00:14.0-usb-0:1:1.0`
  - `pci-0000:00:14.0` = PCI address of the USB controller
  - `usb-0:1:1.0` = USB port chain (bus:port.subport...)

**Benefits**:
- Uniquely identifies each physical USB port
- Stays consistent across reboots
- Allows multiple identical devices to be distinguished
- More reliable than vendor/product ID alone

## Usage

### Server Commands

```bash
# Start server with default config
bunx @siwats/usbip-supervisor server

# Start with custom config file
bunx @siwats/usbip-supervisor server --config /path/to/config.yaml

# Run configuration wizard
bunx @siwats/usbip-supervisor server --configure

# Install systemd service
sudo bunx @siwats/usbip-supervisor server --install-systemd
```

### Client Commands

```bash
# Start client with default config
bunx @siwats/usbip-supervisor client

# Start with custom config file
bunx @siwats/usbip-supervisor client --config /path/to/config.yaml

# Run configuration wizard
bunx @siwats/usbip-supervisor client --configure

# Install systemd service
sudo bunx @siwats/usbip-supervisor client --install-systemd
```

## systemd Service Management

After installing the systemd service:

```bash
# Start service
sudo systemctl start usbip-supervisor-server  # or -client

# Stop service
sudo systemctl stop usbip-supervisor-server

# Check status
sudo systemctl status usbip-supervisor-server

# View logs
sudo journalctl -u usbip-supervisor-server -f

# Enable auto-start on boot
sudo systemctl enable usbip-supervisor-server
```

## How It Works

### Server

1. Monitors configured USB devices via udev
2. Automatically binds devices when they're plugged in
3. Accepts client connections via TCP
4. Notifies authorized clients when devices become available/unavailable
5. Periodically verifies device states

### Client

1. Connects to server via TCP
2. Receives notifications about device availability
3. Automatically attaches remote devices
4. Detects network dropouts and reconnects
5. Periodically verifies device states and recovers if needed

### Communication Protocol

- Length-prefixed JSON messages over TCP
- Automatic reconnection with exponential backoff
- Heartbeat mechanism to detect connection loss
- Message types:
  - `DEVICE_BIND` - Server tells client to attach device
  - `DEVICE_UNBIND` - Server tells client to detach device
  - `DEVICE_STATUS_QUERY` - Client queries device availability
  - `CONNECTION_STATUS_QUERY` - Client requests available devices list

## Troubleshooting

### "usbip is not installed"

Install the usbip-utils package for your distribution (see Installation section).

### "Failed to load USBIP modules"

Load the kernel modules manually:
```bash
sudo modprobe vhci-hcd
sudo modprobe usbip-core
```

### "Permission denied" errors

Some operations require root privileges. Either:
- Run with `sudo`
- Install the systemd service (runs as root)
- Add your user to appropriate groups

### Device not appearing on client

1. Check server logs: `sudo journalctl -u usbip-supervisor-server -f`
2. Verify device is bound on server: `usbip list -l`
3. Check client is authorized in server config
4. Verify network connectivity between client and server
5. Check client logs: `sudo journalctl -u usbip-supervisor-client -f`

### Connection keeps dropping

- Check network stability
- Verify firewall rules allow TCP traffic on configured port
- Check server logs for errors

## Development

### Build from source

```bash
git clone https://github.com/siwats/usbip-supervisor
cd usbip-supervisor
bun install
bun run dev
```

### Run tests

```bash
bun test
```

## License

MIT

## Author

Siwat
