Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Need non-pfSense packages to run USB hardware

    Scheduled Pinned Locked Moved Hardware
    9 Posts 4 Posters 387 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T
      tkgendro
      last edited by

      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-hid

      Both 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!

      provelsP T 2 Replies Last reply Reply Quote 0
      • provelsP
        provels @tkgendro
        last edited by

        @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.

        Peder

        MAIN - pfSense+ 24.11-RELEASE - Adlink MXE-5401, i7, 16 GB RAM, 64 GB SSD. 500 GB HDD for SyslogNG
        BACKUP - pfSense+ 23.01-RELEASE - Hyper-V Virtual Machine, Gen 1, 2 v-CPUs, 3 GB RAM, 8GB VHDX (Dynamic)

        T 1 Reply Last reply Reply Quote 0
        • T
          tedquade @tkgendro
          last edited by

          Check Amazon for a T319 timer. I have one and it will probably do the job for you.

          Ted

          1 Reply Last reply Reply Quote 0
          • stephenw10S stephenw10 moved this topic from Problems Installing or Upgrading pfSense Software on
          • stephenw10S
            stephenw10 Netgate Administrator
            last edited by

            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?

            T 1 Reply Last reply Reply Quote 0
            • T
              tkgendro @provels
              last edited by

              @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).

              1 Reply Last reply Reply Quote 0
              • T
                tkgendro @stephenw10
                last edited by

                @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!

                T 1 Reply Last reply Reply Quote 1
                • T
                  tkgendro @tkgendro
                  last edited by

                  @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 from src/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.

                  1 Reply Last reply Reply Quote 1
                  • stephenw10S
                    stephenw10 Netgate Administrator
                    last edited by

                    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.

                    T 1 Reply Last reply Reply Quote 0
                    • T
                      tkgendro @stephenw10
                      last edited by

                      @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.

                      1 Reply Last reply Reply Quote 1
                      • First post
                        Last post
                      Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.