Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hidws - WebSocket/USB HID gateway

hidws is a lightweight C daemon that bridges WebSocket clients to USB HID devices, letting web apps talk to HID devices remotely over the network without direct USB access.

It also ships hid-list, a small diagnostic tool that lists all USB HID devices and probes the reports they support.

Both programs link against the hidapi libusb backend and do not require kernel HID support (/dev/hidraw*), so they work even on systems without a HID/INPUT kernel subsystem.

Prerequisites (Ubuntu/Debian)

sudo apt install libhidapi-dev libwebsockets-dev

The programs link with -lhidapi-libusb at build time. libhidapi-dev must ship the precompiled libhidapi-libusb.so backend (usbfs, libusb).

USB device permissions

To read/write HID devices as a regular user:

1. Add user to plugdev group

sudo usermod -aG plugdev $USER

Log out and back in for the change to take effect.

2. Udev rules

Create /etc/udev/rules.d/99-hid.rules:

# Permissions for HID and USB devices (covers both hidraw and libusb backends)
SUBSYSTEM=="hidraw", MODE="0666"
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0664", GROUP="plugdev"

Then reload:

sudo udevadm control --reload-rules && sudo udevadm trigger

Build & Install

make
sudo make install          # PREFIX=/usr/local

This builds both hidws and hid-list.

MIPS/uClibc note: on the Freetz-EVO MIPS toolchain (GCC 13.4.0, uClibc-ng, -march=34kc -msoft-float), compiling hidws with -O1 or higher miscompiles the reader thread and crashes with a NULL deref inside hid_read_timeout (only -O0 is stable there). On other platforms the default flags are fine. If you hit a Segmentation fault right after [hid] Reader thread started, rebuild with -O0.

Usage

hidws - WebSocket/HID bridge

./hidws [port] [--cert FILE] [--key FILE]

Default port is 9001. Point your WebSocket client to ws://<host>:9001. The HID device is released automatically when the client disconnects.

TLS / WSS support (same port as WS)

By default (./hidws [port]) hidws serves both plain ws:// and encrypted wss:// on the same port, using a temporary self-signed certificate kept only in memory (no file, no disk writes, regenerated on every start). A warning is printed to the log and shown on the diagnostic page.

./hidws 9001                      # ws:// + wss://, temporary in-memory cert
./hidws 9001 --no-ssl             # ws:// only (no TLS at all)
./hidws 9001 --cert server.crt --key server.key   # persistent cert
  • --cert FILE [--key FILE]: use a persistent certificate. If the cert file does not exist yet and hidws was built with SSL support, a self-signed certificate/key pair is generated automatically at first start (RSA-2048, valid 10 years, CN/SAN fritz.box). --key is optional: if omitted, it is derived from the cert path by replacing the extension with .key (server.crt -> server.key).
  • --no-ssl: force plain ws:// only (no TLS). Useful to keep an explicit "no TLS" mode, e.g. from an init script.
  • Both schemes are served by the same listening socket, so ws://192.168.178.1:9001 and wss://192.168.178.1:9001 work side by side. This is handy on HTTPS-hosted web apps (e.g. GitHub Pages) which block plain ws:// connections: the app can fall back to wss://.

Note: the self-signed certificate is not trusted by clients, so browsers must be told to accept it (a one-time warning) or the app must be configured to allow self-signed certificates. With a temporary in-memory cert the exception is re-asked on every service restart; with a persistent cert (--cert) the exception stays valid across restarts.

Diagnostic page (http/https on the same port)

Opening http://<host>:<port>/ or https://<host>:<port>/ in a browser serves a small diagnostic page that confirms the daemon is reachable and shows version, port and the available WebSocket endpoints, plus "Test ws://" / "Test wss://" buttons that open a real WebSocket to the server and report success/failure. When a temporary in-memory certificate is in use, the page shows a warning banner about it.

This is the convenient way to confirm access and (for wss://) to accept the browser's one-time security exception for the self-signed certificate: visit https://192.168.178.1:9001/, accept the warning, then reload the page and press "Test wss://".

hid-list - enumerate HID devices

./hid-list

Prints every USB HID device (path, VID/PID, manufacturer, product, serial) and probes its feature and input reports.

Wire Protocol

All messages are JSON over WebSocket.

Client -> Server

Command Payload
list {"cmd":"list"}
open {"cmd":"open","vendorId":<int>,"productId":<int>}
send_report {"cmd":"send_report","reportId":<int>,"data":[<bytes>]}
send_feature_report {"cmd":"send_feature_report","reportId":<int>,"data":[<bytes>]}
close {"cmd":"close"}

Server -> Client

Type Payload
device_list {"type":"device_list","devices":[{"vendorId":...,"productId":...,"productName":"..."}]}
opened {"type":"opened","vendorId":...,"productId":...,"productName":"...","usagePage":...,"usage":...,"interfaceNumber":...,"busType":...,"releaseNumber":...,"serialNumber":"...","reportDescriptor":[...]}
input_report {"type":"input_report","reportId":<int>,"data":[<bytes>]}
ok {"type":"ok"}
error {"type":"error","message":"..."}
closed {"type":"closed"}

opened also carries the hidapi device info (usagePage, usage, interfaceNumber, busType, releaseNumber, serialNumber) and the raw HID report descriptor as a byte array (reportDescriptor), so clients can render the same report collections (input/output/feature with report IDs and items) as a local WebHID connection.

Notes

  • The KT02H20 family (FiiO JA11 etc.) uses OUTPUT reports; frontends must send data with send_report (report ID 0x02), not feature reports.
  • input_report data received over WebSocket includes the report-ID byte as the first element for numbered input reports; WebHID strips it, so remote frontends must strip it to match.

License

European Union Public Licence 1.2 (EUPL-1.2). See LICENSE.

About

WebSocket - HID bridge

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages