ModalAI Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Register
    • Login

    PX4 -> QGC connection through USB for VOXL2

    Ask your questions right here!
    8
    21
    935
    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.
    • B
      bendraper @Alex Kushleyev
      last edited by

      @Alex-Kushleyev I saw a post from @tom from a few years ago discussing how there should be the necessary drivers to support an RNDIS gadget so I assume that is my issue. Any insight on how to enable that?

      [Apr 1 19:15] configfs-gadget gadget: Wrong NDP SIGN
      [ +12.232553] usbpd usbpd0: Type-C Source (default) connected
      [  +0.019411] usbpd usbpd0: USB Type-C disconnect
      [  +0.004363] android_work: sent uevent USB_STATE=DISCONNECTED
      [  +0.001100] msm-dwc3 a600000.ssusb: DWC3 in low power mode
      [  +3.492478] usbpd usbpd0: Type-C Source (medium - 1.5A) connected
      [  +0.113740] msm-usb-ssphy-qmp 88e8000.ssphy: USB DP QMP PHY: Update TYPEC CTRL(3)
      [  +0.057403] msm-dwc3 a600000.ssusb: DWC3 exited from low power mode
      [  +0.068603] usbpd usbpd0: Type-C Source (high - 3.0A) connected
      [  +0.238255] android_work: sent uevent USB_STATE=CONNECTED
      [  +0.041534] configfs-gadget gadget: high-speed config #1: c
      [  +0.000644] android_work: sent uevent USB_STATE=CONFIGURED
      [  +0.195765] usbpd usbpd0: Type-C Source (medium - 1.5A) connected
      [  +0.021780] usbpd usbpd0: Type-C Source (high - 3.0A) connected
      [  +0.179818] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.000172] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.069075] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.002827] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.176097] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.001314] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.001331] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.250721] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.491456] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.000164] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.000446] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.067507] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.000984] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.012649] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.183993] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.001107] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.211788] configfs-gadget gadget: Wrong NDP SIGN
      [  +0.030077] configfs-gadget gadget: Wrong NDP SIGN
      
      Alex KushleyevA 1 Reply Last reply Reply Quote 0
      • Alex KushleyevA
        Alex Kushleyev ModalAI Team @bendraper
        last edited by

        @bendraper , If you see an ethernet connection to VOXL2 show up on your Windows host, then the usb gadget is properly configured on VOXL2. Perhaps something else is going on. Are you assigning a static ip on your host that is on the same subnet as VOXL2?

        You should try to repeat the same test on a linux machine (or virtual machine) to see if you can get a working connection.

        Alex

        B 1 Reply Last reply Reply Quote 0
        • B
          bendraper @Alex Kushleyev
          last edited by

          @Alex-Kushleyev Yea I can get a connection on a linux machine with no issue. I do need to get it working on a Windows machine for my purposes though. I definitely have the static IP setup correctly. I tried populating the gateway and also not populating it. I confirmed in powershell that there is indeed a route present for that traffic, but they do not want to communicate with each other. Some quick research seems to suggest Windows is very finicky with the CDC NCM protocol and it is more suited to work with an RNDIS interface. Were you able to ping/ssh to a voxl via an ethernet interface on the usb-c port to a windows machine using just the commands you listed above in this post?

          Alex KushleyevA 1 Reply Last reply Reply Quote 0
          • Alex KushleyevA
            Alex Kushleyev ModalAI Team @bendraper
            last edited by

            @bendraper , I just tried this on a Windows 11 VM and even though i was able to see a network device appear in the VM and i configured the IPv4 properties, I cannot ping or ssh. It seems consistent with what you are seeing.

            B 1 Reply Last reply Reply Quote 0
            • B
              bendraper @Alex Kushleyev
              last edited by

              @Alex-Kushleyev It looks like someone on the forums maybe had success setting up the interface as an RNDIS gadget. I'll try to mess with it some more but let me know if you find a solution. Thanks!

              Alex KushleyevA 1 Reply Last reply Reply Quote 0
              • Alex KushleyevA
                Alex Kushleyev ModalAI Team @bendraper
                last edited by

                @bendraper , I will ask around.

                B 1 Reply Last reply Reply Quote 0
                • B
                  bendraper @Alex Kushleyev
                  last edited by

                  @Alex-Kushleyev So I can see a gadget functionality called gsi.rndis (I'd expect something called rndis.0 or something but maybe that is irrelevant) but when I change the line in /sbin/usb/compositions/901D to use gsi.rndis instead of ncm.0, my network interface on windows disappears and I can no longer ADB. I'd imagine there's something at the kernal level that doesn't like that but I'm out of my wheelhouse there. Setting it back to ncm.0 returns to the previous state but still cannot ping. Wireshark doesn't even see anything happening over that interface

                  1 Reply Last reply Reply Quote 0
                  • Zachary Lowell 0Z
                    Zachary Lowell 0 ModalAI Team
                    last edited by

                    Hi All - gonna spend a bit of time looking into this today so I can get some context on the problem.

                    Zach

                    1 Reply Last reply Reply Quote 0
                    • Q
                      qt
                      last edited by qt

                      To enable the NCM gadget on drone (an ethernet over usb protocol), I created a systemclt service on the drone and on the PC.
                      That's not perfect, but in my case with my pc ubuntu it works. I can use the usb-c wire to communicate with the drone via NCM protocol. I did that to have a better data rate and it is the case since I have now 40 M Bytes/s.

                      I can't share files but here are the code blocks without any warranty. I hope it can help (sorry for the very long message :)) :

                      ./config-voxl-usb-ncm.sh

                      #!/usr/bin/env bash
                      set -euo pipefail
                      
                      # Minimal orchestrator for PC and Drone install/uninstall.
                      # - PC: installs systemd service, setup script, and NetworkManager drop-in
                      # - Drone: pushes files via adb and enables systemd service
                      # FLAGS:
                      #   --pc        Only operate on the PC
                      #   --drone     Only operate on the drone (via adb)
                      #   --uninstall Uninstall instead of install
                      #
                      # Defaults: if neither --pc nor --drone is provided, both are processed.
                      
                      ROOT_DIR="$(dirname "$(realpath "$0")")"
                      ON_PC_DIR="${ROOT_DIR}/on_pc"
                      ON_DRONE_DIR="${ROOT_DIR}/on_drone"
                      
                      SERVICE="voxl-usb-ncm.service"
                      SETUP="voxl-usb-ncm-setup.sh"
                      
                      
                      show_help() {
                          echo "Usage: $0 [OPTION]"
                          echo
                          echo "Minimal orchestrator for PC and Drone install/uninstall."
                          echo "- PC: installs systemd service, setup script, and NetworkManager drop-in"
                          echo "- Drone: pushes files via adb and enables systemd service"
                          echo
                          echo "Options:"
                          echo "  --pc           Install configuration on PC only"
                          echo "  --drone        Install configuration on Drone only (requires adb)"
                          echo "  --uninstall    Remove configuration from both PC and Drone"
                          echo "  --help         Show this help message"
                          echo
                          echo "Examples:"
                          echo "  $0             Install on both PC and Drone"
                          echo "  $0 --pc        Install only on PC"
                          echo "  $0 --uninstall Remove all configuration"
                      }
                      
                      do_pc_install() {
                        echo "[INFO][PC] Installing setup script..."
                        sudo install -m 0755 "${ON_PC_DIR}/${SETUP}" /usr/local/sbin/
                      
                        echo "[INFO][PC] Installing systemd service..."
                        sudo install -m 0644 "${ON_PC_DIR}/${SERVICE}" /etc/systemd/system/
                      
                        echo "[INFO][PC] Reloading systemd and enabling service..."
                        sudo systemctl daemon-reload
                        sudo systemctl enable --now "${SERVICE}"
                      
                        echo "[INFO][PC] Adding NetworkManager unmanaged config..."
                        sudo install -d -m 0755 /etc/NetworkManager/conf.d
                        sudo install -m 0644 "${ON_PC_DIR}/unmanaged.conf" /etc/NetworkManager/conf.d/
                      
                        echo "[INFO][PC] Restarting NetworkManager..."
                        sudo systemctl restart NetworkManager
                      
                        echo "[INFO][PC] Install complete."
                      }
                      
                      do_pc_uninstall() {
                        echo "[INFO][PC] Uninstalling..."
                        sudo systemctl disable --now "${SERVICE}" || true
                        sudo rm -f /etc/systemd/system/"${SERVICE}"
                        sudo rm -f /usr/local/sbin/${SETUP}
                        sudo rm -f /etc/NetworkManager/conf.d/unmanaged.conf
                        sudo systemctl daemon-reload
                        sudo systemctl restart NetworkManager
                        echo "[INFO][PC] Uninstall complete."
                      }
                      
                      do_drone_install() {
                        echo "[INFO][DRONE] Preparing adb (root + remount)..."
                        adb root
                        adb remount
                      
                        echo "[INFO][DRONE] Pushing setup script..."
                        adb push "${ON_DRONE_DIR}/${SETUP}" /data/local/tmp/${SETUP}
                        adb shell "mkdir -p /usr/local/sbin && cp /data/local/tmp/${SETUP} /usr/local/sbin/ && chmod 0755 /usr/local/sbin/${SETUP}"
                      
                        echo "[INFO][DRONE] Pushing systemd service..."
                        adb push "${ON_DRONE_DIR}/${SERVICE}" /data/local/tmp/${SERVICE}
                        adb shell "cp /data/local/tmp/${SERVICE} /etc/systemd/system/${SERVICE} && chmod 0644 /etc/systemd/system/${SERVICE}"
                      
                        echo "[INFO][DRONE] Enabling service..."
                        adb shell "systemctl daemon-reload && systemctl enable --now ${SERVICE}"
                      
                        echo "[INFO][DRONE] Install complete."
                      }
                      
                      do_drone_uninstall() {
                        echo "[INFO][DRONE] Uninstalling..."
                        adb root
                        adb remount
                        adb shell "systemctl disable --now ${SERVICE} || true"
                        adb shell "rm -f /etc/systemd/system/${SERVICE} /usr/local/sbin/${SETUP} || true"
                        adb shell "systemctl daemon-reload"
                        echo "[INFO][DRONE] Uninstall complete."
                      }
                      
                      
                      # Arg parsing
                      TARGET_PC=false
                      TARGET_DRONE=false
                      DO_UNINSTALL=false
                      
                      for arg in "$@"; do
                        case "$arg" in
                          --help) show_help; exit 0 ;;
                          --pc) TARGET_PC=true ;;
                          --drone) TARGET_DRONE=true ;;
                          --uninstall) DO_UNINSTALL=true ;;
                          *)
                            echo "[ERROR] Unknown argument: $arg";
                            show_help;
                            exit 1 ;;
                        esac
                      done
                      
                      # Default to both if none selected
                      if ! $TARGET_PC && ! $TARGET_DRONE; then
                        TARGET_PC=true
                        TARGET_DRONE=true
                      fi
                      
                      # Execute
                      if $DO_UNINSTALL; then
                        $TARGET_PC && do_pc_uninstall
                        $TARGET_DRONE && do_drone_uninstall
                      else
                        $TARGET_PC && do_pc_install
                        $TARGET_DRONE && do_drone_install
                      fi
                      
                      echo "[INFO] All done."
                      

                      ./on_drone/voxl-usb-ncm-setup.sh

                      #!/bin/bash
                      
                      # ──────────────────────────────────────────────────────────────────────────────
                      # Variables
                      # ──────────────────────────────────────────────────────────────────────────────
                      PTH_USB="/sys/kernel/config/usb_gadget/g1"
                      PTH_USB_CONF="$PTH_USB/configs/c.1"
                      PTH_USB_NCM="$PTH_USB/functions/ncm.0"
                      
                      # Network point-to-point USB NCM
                      DRONE_IP_CIDR="${DRONE_IP_CIDR:-10.55.0.1/30}" # IP/mask drone usb0
                      MTU="${MTU:-1500}"                             # After some tests, 1500 seems to be the maximum for NCM in USB2.1
                      
                      # ──────────────────────────────────────────────────────────────────────────────
                      log(){ echo "[voxl-usb-ncm] $*"; }
                      
                      for i in {1..20}; do
                        if [ -d "$PTH_USB" ] && [ -d "$PTH_USB_CONF" ]; then
                          break
                        fi
                        [ $i -eq 1 ] && log "Wait configfs/gadget…"
                        sleep 0.5
                      done
                      [ -d "$PTH_USB" ]  || { log "Don't find gadget $PTH_USB"; exit 1; }
                      [ -d "$PTH_USB_CONF" ] || { log "Don't find config $PTH_USB_CONF"; exit 1; }
                      
                      # Create NCM function if it doesn't exist
                      [ -d "$PTH_USB_NCM" ] || mkdir -p "$PTH_USB_NCM"
                      
                      # Link NCM function to USB gadget config if it's not already done
                      if [ ! -L "$PTH_USB_CONF/ncm" ]; then
                        log "Symlink NCM → config"
                        ln -s "$PTH_USB_NCM" "$PTH_USB_CONF/ncm"
                      fi
                      
                      # Update USB gadget to take into account the new NCM function
                      echo "" > "$PTH_USB/UDC"
                      
                      check_usb0="ip link show usb0 > /dev/null 2>&1"
                      if ! eval "$check_usb0"; then
                          sleep 0.5
                          if ! eval "$check_usb0"; then
                              log "usb0 doesn't exist after NCM setup"
                              exit 1
                          fi
                      fi
                      log "usb0 added successfully after NCM setup"
                      
                      # Config network usb0 (idempotente)
                      log "Configuration network usb0: $DRONE_IP_CIDR (mtu=$MTU)"
                      ip link set usb0 up || true
                      ip addr flush dev usb0 || true
                      ip addr add "$DRONE_IP_CIDR" dev usb0
                      ip link set usb0 mtu "$MTU" || true
                      
                      # Small TCP optimisations
                      [ -w /proc/sys/net/ipv4/tcp_mtu_probing ] && echo 1 > /proc/sys/net/ipv4/tcp_mtu_probing || true
                      [ -w /proc/sys/net/core/rmem_max ] && echo 16777216 > /proc/sys/net/core/rmem_max || true
                      [ -w /proc/sys/net/core/wmem_max ] && echo 16777216 > /proc/sys/net/core/wmem_max || true
                      
                      log "USB NCM configuration done !"
                      exit 0
                      

                      ./on_drone/voxl-usb-ncm.service

                      [Unit]
                      Description=VOXL USB NCM setup (add NCM function and bring up usb0)
                      After=multi-user.target sys-kernel-config.mount
                      Requires=sys-kernel-config.mount
                      
                      [Service]
                      Type=oneshot
                      RemainAfterExit=yes
                      ExecStart=/usr/local/sbin/voxl-usb-ncm-setup.sh
                      
                      [Install]
                      WantedBy=multi-user.target
                      

                      ./on_pc/unmanaged.conf

                      [keyfile]
                      unmanaged-devices=interface-name:enx*
                      

                      ./on_pc/voxl-usb-ncm-setup.sh

                      #!/bin/bash
                      
                      IP="10.55.0.2/30"
                      CONFIGURED_IFACE=""
                      LOGGER_TAG="[voxl-usb-ncm]"
                      
                      log() {
                        /usr/bin/logger -t "$LOGGER_TAG" "$1"
                      }
                      
                      log "Service started"
                      
                      while true; do
                        IFACE=$(ls /sys/class/net | grep '^enx' | head -n1)
                        if [ -n "$IFACE" ]; then
                          if [ "$IFACE" != "$CONFIGURED_IFACE" ]; then
                            log "Detected new interface: $IFACE"
                            /usr/sbin/ip addr flush dev "$IFACE" || log "Failed to flush IP addresses on $IFACE"
                            /usr/sbin/ip addr add "$IP" dev "$IFACE" || log "Failed to assign IP $IP to $IFACE"
                            /usr/sbin/ip link set "$IFACE" up || log "Failed to bring up $IFACE"
                            /usr/sbin/ip route del default dev "$IFACE" 2>/dev/null || log "No default route to delete for $IFACE"
                            log "Configured $IFACE with $IP"
                            CONFIGURED_IFACE="$IFACE"
                          fi
                        else
                          if [ -n "$CONFIGURED_IFACE" ]; then
                            log "Interface $CONFIGURED_IFACE disconnected"
                          fi
                          CONFIGURED_IFACE=""
                        fi
                        sleep 2
                      done
                      

                      ./on_pc/voxl-usb-ncm.service

                      [Unit]
                      Description=Watch for USB NCM interface and configure it
                      After=network.target
                      ConditionPathExists=/usr/local/sbin/voxl-usb-ncm-setup.sh
                      
                      [Service]
                      Type=simple
                      ExecStart=/usr/local/sbin/voxl-usb-ncm-setup.sh
                      Restart=always
                      RestartSec=2
                      
                      [Install]
                      WantedBy=multi-user.target
                      
                      Q 1 Reply Last reply Reply Quote 0
                      • Q
                        qt @qt
                        last edited by

                        The readme to help you use my scripts :

                        ./readme.md :

                        # VOXL USB NCM Setup for ModalAI Starling 2 Max
                        
                        ## Context & Objective
                        
                        > This repository provides scripts and configuration files to enable **USB NCM** (Network Control Model) networking between a **ModalAI Starling 2 Max** drone and a **Linux PC**.
                        The goal is to transfer files faster than **Wi-Fi** or **ADB**, using a direct USB Ethernet link. **USB NCM** creates a virtual Ethernet interface over USB, allowing high-speed IP communication for **SSH**, `rsync`, or other tools.
                        
                        ---
                        
                        ## Features
                        
                        Automatic configuration of USB NCM on both drone and PC.
                        Systemd services to persist configuration across reboots.
                        NetworkManager drop-in to prevent interference on the PC.
                        IP addressing and MTU tuning for optimal performance.
                        
                        ## Installation
                        
                        Run the orchestrator script from the root of this repository:
                        
                        ```bash
                        chmod +x config-voxl-usb-ncm.sh # Already executable normally
                        ./config-voxl-usb-ncm.sh
                        

                        Options

                        • --pc : Configure only the PC.
                        • --drone : Configure only the drone (requires adb).
                        • --uninstall : Stops and disables services, removes scripts, and cleans NetworkManager configuration.

                        Exemples

                        # Install on both PC and drone
                        ./config-voxl-usb-ncm.sh
                        
                        # Install only on PC
                        ./config-voxl-usb-ncm.sh --pc
                        
                        # Install only on drone
                        ./config-voxl-usb-ncm.sh --drone
                        
                        # Uninstall everything
                        ./config-voxl-usb-ncm.sh --uninstall
                        
                        # Uninstall only on PC
                        ./config-voxl-usb-ncm.sh --pc --uninstall
                        
                        # Uninstall only on drone
                        ./config-voxl-usb-ncm.sh --drone --uninstall
                        
                        

                        Configuration Details

                        • IP Addresses
                          • Drone: 10.55.0.1/30 on usb0
                          • PC: 10.55.0.2/30 on enx* (USB Ethernet interface)
                        • MTU
                          • Default: 1500 (After some tests, 1500 seems to be the maximum for NCM in USB2.1)
                        • Systemd Services
                          • Drone: voxl-usb-ncm.service (oneshot, sets up USB gadget and configures usb0)
                          • PC: voxl-usb-ncm.service (persistent, monitors enx* and configures IP)
                        • NetworkManager
                          • Adds /etc/NetworkManager/conf.d/unmanaged.conf which prevents NetworkManager from interfering with the USB interface.

                        How to Connect

                        Once installed and both devices are connected via USB:

                        # It will ask password
                        ssh root@10.55.0.1
                        
                        # We can put the password in parameter by using sshpass.
                        # By default, the password on the drone is oelinux123.
                        sshpass -p oelinux123 ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@10.55.0.1
                        

                        File Transfer with rsync

                        # Example to copy a folder from PC to drone:
                        rsync -ah --info=progress2 --partial --inplace /path/to/local/folder root@10.55.0.1:/path/on/drone/
                        
                        # Example to copy a folder from drone to pc:
                        rsync -ah --info=progress2 --partial --inplace root@10.55.0.1:/path/to/drone/folder /path/on/pc
                        

                        File Overview

                        • File : on_drone/voxl-usb-ncm-setup.sh
                          • Destination : /usr/local/sbin/ on drone
                          • Purpose : Creates USB gadget NCM function, configures usb0 with IP 10.55.0.1/30 and MTU
                        • File : on_drone/voxl-usb-ncm.service
                          • Destination : /etc/systemd/system/ on drone
                          • Purpose : Runs setup script at boot (oneshot)
                        • File : on_pc/voxl-usb-ncm-setup.sh
                          • Destination : /usr/local/sbin/ on PC
                          • Purpose : Monitors enx* interface, assigns IP 10.55.0.2/30
                        • File : on_pc/voxl-usb-ncm.service
                          • Destination : /etc/systemd/system/ on PC
                          • Purpose : Starts monitoring script at boot
                        • File : on_pc/unmanaged.conf
                          • Destination : /etc/NetworkManager/conf.d/
                          • Purpose : Marks enx* interfaces as unmanaged
                        • File : config-voxl-usb-ncm.sh
                          • Purpose : Orchestrates installation/uninstallation on PC and drone
                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post
                        Powered by NodeBB | Contributors