Need non-pfSense packages to run USB hardware
-
Apologies if this is in the wrong category, it seemed the most suitable as it deals with package installation on pfSense devices.
I bought a cheap USB relay device and want to be able to operate it from a shell (via ssh) on pfSense. I run a server (small android TV box) which works great but every couple weeks will just seize up. The only fix is to do a hard reset on the device (unplug/re-plug it from the wall). I have no other devices on my network, so being able to do a power cycle with the USB relay through the pfSense device would be a perfect solution.
In order to interface with the USB relay, there seems to be two different options:
https://github.com/darrylb123/usbrelay
https://github.com/pavel-a/usb-relay-hidBoth require a C/C++ compiler and autotools to be installed so that they can be compiled on the pfSense, but these packages are not available via the pfSense package repo. I edited some config files to be able to use the default freeBSD package repo, but haven't tried installing anything due to a possible issue with incompatible libraries/dependencies.
Looking for any advice on how I can get this working - is there a good chance on having issues if I go through with adding the packages? Is there a different way?
Thanks!
-
@tkgendro Not very elegant, but how about just putting a lamp timer on it and rebooting it daily? I'd be very hesitant to load a bunch of untested packages on my FW.
-
Check Amazon for a T319 timer. I have one and it will probably do the job for you.
Ted
-
S stephenw10 moved this topic from Problems Installing or Upgrading pfSense Software
-
Unclear if there is an hidapi driver in FreeBSD at all and it looks like both those are just front ends for an existing Linux driver.
What does pfSense show in the logs when you connect it?
-
@provels @tedquade Thanks for the suggestions; this is currently my back up plan if I can't get the USB relay working. I'd prefer something more 'on-demand' since it's happened before where the server seizes up within a few hours of a reboot, it seems completely random when it happens (and not just if its been running for a while).
-
@stephenw10 Thanks for the reply and moving the topic to where it belongs :).
I'm also not sure about the hidapi driver, but only one of the git projects seems to need it. As for the existing Linux driver, I was hoping a similar library would exist in FreeBSD and the code would still be compile-able with some effort (I'm a c++ dev). I haven't actually received the USB Relay yet, I'll update with the pfSense logs tomorrow/Friday.
Thanks!
-
@stephenw10 I got it working. In the end I had to install some non-pfSense packages but I don't think there's a conflict. Writing this up in case it helps someone.
In pfSense system logs the device shows up as:
Feb 6 17:23:44 kernel uhid0: <www.dcttech.com USBRelay2, class 0/0, rev 1.10/1.00, addr 3> on usbus0 Feb 6 17:23:44 kernel uhid0 on uhub1 Feb 6 17:23:44 kernel ugen0.3: <www.dcttech.com USBRelay2> at usbus0
I tried using the available usbhidctl command but couldn't get the USB Relay to operate. In the end, I had to install gcc13, hidapi, and update pkg itself. The total list of packages installed due to dependencies:
hidapi: 0.14.0 [pfSense] tiff: 4.4.0_2 [pfSense] abseil: 20240722.0 [FreeBSD] binutils: 2.43.1,1 [FreeBSD] brotli: 1.1.0,1 [FreeBSD] c-ares: 1.34.4 [FreeBSD] fontconfig: 2.15.0_3,1 [FreeBSD] freetype2: 2.13.3 [FreeBSD] fstrm: 0.6.1_1 [FreeBSD] gcc13: 13.3.0 [FreeBSD] gdbm: 1.24 [FreeBSD] giflib: 5.2.2 [FreeBSD] graphite2: 1.3.14 [FreeBSD] jbigkit: 2.1_3 [FreeBSD] jpeg-turbo: 3.1.0 [FreeBSD] jsoncpp: 1.9.6_1 [FreeBSD] libc6-shim: 20240512 [FreeBSD] libdaemon: 0.14_1 [FreeBSD] libdeflate: 1.22 [FreeBSD] libfontenc: 1.1.8 [FreeBSD] libpfctl: 0.15 [FreeBSD] libunwind: 20240221_1 [FreeBSD] libyaml: 0.2.5 [FreeBSD] mpc: 1.3.1_1 [FreeBSD] mpfr: 4.2.1,1 [FreeBSD] pixman: 0.44.2 [FreeBSD] png: 1.6.45 [FreeBSD] protobuf: 29.3,1 [FreeBSD] protobuf-c: 1.4.1_8 [FreeBSD] ruby: 3.2.6,1 [FreeBSD] tcl86: 8.6.16_2 [FreeBSD]
I then wrote a small program in C:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <hidapi/hidapi.h> #define VENDOR_ID 0x16c0 #define PRODUCT_ID 0x05df // Function to send HID report to the device int send_hid_report(hid_device *handle, unsigned char *report, size_t length) { int res = hid_write(handle, report, length); if (res < 0) { printf("Error writing HID report: %ls\n", hid_error(handle)); return -1; } return 0; } int main(int argc, char *argv[]) { // Initialize HIDAPI if (hid_init()) { printf("Failed to initialize HIDAPI\n"); return -1; } // Open the USB Relay device hid_device *handle = hid_open(VENDOR_ID, PRODUCT_ID, NULL); if (!handle) { printf("Unable to open HID device\n"); return -1; } printf("HID device opened successfully\n"); // Prepare the HID report to control the relay unsigned char report[9]; memset(report, 0, sizeof(report)); report[0] = 0x0; // Report ID report[1] = 0xFF; // Target state (e.g., 0x01 for ON, 0x00 for OFF) report[2] = 0x01; // Relay number (e.g., relay 1) report[3] = 0x00; report[4] = 0x00; report[5] = 0x00; report[6] = 0x00; report[7] = 0x00; report[8] = 0x00; // Check if the user passed the correct argument to turn on or off if (argc != 2) { printf("Usage: %s <on|off>\n", argv[0]); hid_close(handle); return -1; } // Turn relay on or off based on the argument if (strcmp(argv[1], "on") == 0) { report[1] = 0xFF; // Relay ON } else if (strcmp(argv[1], "off") == 0) { report[1] = 0xFD; // Relay OFF } else { printf("Invalid argument. Use 'on' or 'off'.\n"); hid_close(handle); return -1; } // Send the report to control the relay if (send_hid_report(handle, report, sizeof(report)) < 0) { hid_close(handle); return -1; } printf("Relay is now %s\n", argv[1]); // Close the device and cleanup hid_close(handle); hid_exit(); return 0; }
But before it would compile successfully I had to clone the FreeBSD source repo with
git clone https://git.FreeBSD.org/src.git
and copy a bunch of files fromsrc/sys/sys/
to/usr/include/sys/
as they're missing from the system - the exact files will be displayed when trying to compile the code and you can copy them over one by one. There's probably a better way to do this but it worked for me.Compiled with
gcc13 -o relay relay.c -lhidapi
, run with./relay off
and./relay on
.Lastly, I don't recommend doing any of this unless you're comfortable in Linux/Unix/FreeBSD systems and know what you're doing (or don't mind potentially having to reinstall pfSense). There's still a chance something will go wrong with my pfSense somewhere down the line. See this thread on how to configure pfSense to allow you to install all FreeBSD packages (like gcc and hidapi), and also why you shouldn't do it:
https://forum.netgate.com/topic/98082/2-3-how-to-install-other-freebsd-packages-repositories/10
. -
Nice!
I would always recommend compiling any code in a FreeBSD install and moving the binary into pfSense though. Something simple like that should be pretty version compatible across kernels etc.
-
@stephenw10 I had actually thought of doing a cross-compile from my ubuntu installation but it seemed too complicated to figure out how to compile it against FreeBSD headers and especially how to handle the hidapi library.
Had I thought of doing a FreeBSD install on a VM at the very beginning, then compiling the code on the VM before copying to the pfSense box, it probably would have been faster and easier overall.