Add files via upload

pull/1724/head
snokvist 2025-02-23 11:24:05 +01:00 committed by GitHub
parent 9e46a2e5a8
commit 3836844638
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 1813 additions and 0 deletions

View File

@ -0,0 +1,326 @@
#!/bin/sh
#
# bitrate_calculator.sh
#
# This script supports two modes:
#
# 1. Normal (default) mode:
# Usage:
# bitrate_calculator.sh <target_bitrate_in_kbps> [fec_ratio] [max_mcs (0-7)] [--cap <cap>] [--gi <guard>] [--max_bw <20|40>]
#
# If fec_ratio is not provided, it defaults to "8/12".
# The script searches (in fixed order: 20 MHz long, 20 MHz short, then 40 MHz long, 40 MHz short)
# for the lowest MCS (0..max_mcs, default max_mcs=7) whose computed forward rate is ≥ target.
# If the optional "--gi" is provided, only that guard interval is used.
# If the optional "--max_bw" is provided, it limits the search to that maximum bandwidth.
#
# The computed rate is given by:
#
# final = ( base_rate * 3 * fec_n + (4*fec_k)/2 ) / (4*fec_k)
#
# where base_rate (in kbps) is looked up from hardcoded tables.
# The computed rate is capped at a maximum value (default cap is 20000 kbps,
# overrideable via --cap).
#
# Output is a single line in the format:
# <mcs>:<bw>:<gi>:<fec>
#
# 2. Backwards mode:
# Usage:
# bitrate_calculator.sh --backwards <bw (20|40)> <mcs (0-7)> <guard (long|short)> <fec ratio (x/y)> [--cap <cap>]
#
# It computes (and outputs) the forward rate (capped) for the given parameters.
#
# -------------------------
# Parse optional global arguments
# -------------------------
# Default cap is 20000 kbps.
CAP=20000
backwards_mode=0
locked_gi=""
MAX_BW=40 # new: default maximum bandwidth for candidate search is 40MHz (i.e. search both 20 & 40)
other_args=""
while [ "$#" -gt 0 ]; do
case "$1" in
--cap)
shift
if [ "$#" -eq 0 ]; then
echo "Error: --cap requires a value"
exit 1
fi
CAP="$1"
shift
;;
--backwards)
backwards_mode=1
shift
;;
--gi)
shift
if [ "$#" -eq 0 ]; then
echo "Error: --gi requires a value (long or short)"
exit 1
fi
locked_gi="$1"
case "$locked_gi" in
long|short) ;;
*) echo "Error: --gi must be 'long' or 'short'." ; exit 1 ;;
esac
shift
;;
--max_bw)
shift
if [ "$#" -eq 0 ]; then
echo "Error: --max_bw requires a value (20 or 40)"
exit 1
fi
if [ "$1" != "20" ] && [ "$1" != "40" ]; then
echo "Error: --max_bw must be either 20 or 40"
exit 1
fi
MAX_BW="$1"
shift
;;
*)
other_args="$other_args $1"
shift
;;
esac
done
set -- $other_args
# -------------------------
# Function: compute_final
# -------------------------
# Given:
# bw : Bandwidth (20 or 40)
# gi : Guard interval ("long" or "short")
# mcs : MCS index (0-7)
# fec_n : FEC numerator
# fec_k : FEC denominator
#
# Looks up the base_rate (in kbps) from hardcoded tables:
#
# 20 MHz:
# Long GI: 6500, 13000, 19500, 26000, 39000, 52000, 58500, 65000
# Short GI: 7200, 14400, 21700, 28900, 43300, 57800, 65000, 72200
#
# 40 MHz:
# Long GI: (20% reduced) 10800, 21600, 32400, 43200, 64800, 86400, 97200, 108000
# Short GI: (20% reduced) 12000, 24000, 36000, 48000, 72000, 96000, 108000, 120000
#
# Then computes:
#
# final = ( base_rate * 3 * fec_n + (4*fec_k)/2 ) / (4*fec_k)
#
# If final > CAP, it is set to CAP.
compute_final() {
bw="$1"
gi="$2"
mcs="$3"
fec_n="$4"
fec_k="$5"
if [ "$bw" -eq 20 ]; then
if [ "$gi" = "long" ]; then
case "$mcs" in
0) base=6500 ;;
1) base=12000 ;;
2) base=15500 ;;
3) base=20000 ;;
4) base=25000 ;;
5) base=42000 ;;
6) base=47500 ;;
7) base=55000 ;;
esac
else
case "$mcs" in
0) base=7200 ;;
1) base=13400 ;;
2) base=18700 ;;
3) base=21900 ;;
4) base=28300 ;;
5) base=43800 ;;
6) base=50000 ;;
7) base=55200 ;;
esac
fi
elif [ "$bw" -eq 40 ]; then
if [ "$gi" = "long" ]; then
case "$mcs" in
0) base=9800 ;;
1) base=18600 ;;
2) base=30400 ;;
3) base=40200 ;;
4) base=55800 ;;
5) base=80400 ;;
6) base=90200 ;;
7) base=97000 ;;
esac
else
case "$mcs" in
0) base=12000 ;;
1) base=24000 ;;
2) base=36000 ;;
3) base=48000 ;;
4) base=60000 ;;
5) base=91000 ;;
6) base=980000 ;;
7) base=100000 ;;
esac
fi
else
echo "Error: unsupported bandwidth $bw" >&2
exit 1
fi
denom=$(( 3 * fec_k ))
half_denom=$(( denom / 2 ))
num=$(( base * 2 * fec_n ))
final=$(( (num + half_denom) / denom ))
if [ "$final" -gt "$CAP" ]; then
final="$CAP"
fi
echo "$final"
}
# -------------------------
# Mode Selection
# -------------------------
if [ "$backwards_mode" -eq 1 ]; then
# Backwards mode: Expect exactly 4 arguments: bw, mcs, guard, fec.
if [ "$#" -ne 4 ]; then
echo "Usage: $0 --backwards <bw (20|40)> <mcs (0-7)> <guard (long|short)> <fec ratio (x/y)> [--cap <cap>]"
exit 1
fi
bw="$1"
mcs="$2"
guard="$3"
fec="$4"
if [ "$bw" -ne 20 ] && [ "$bw" -ne 40 ]; then
echo "Error: bandwidth must be 20 or 40."
exit 1
fi
case "$mcs" in
[0-7]) ;;
*) echo "Error: mcs must be between 0 and 7." ; exit 1 ;;
esac
if [ "$guard" != "long" ] && [ "$guard" != "short" ]; then
echo "Error: guard must be 'long' or 'short'."
exit 1
fi
fec_n=$(echo "$fec" | cut -d'/' -f1)
fec_k=$(echo "$fec" | cut -d'/' -f2)
if [ -z "$fec_n" ] || [ -z "$fec_k" ]; then
echo "Error: fec ratio must be in the form x/y."
exit 1
fi
final=$(compute_final "$bw" "$guard" "$mcs" "$fec_n" "$fec_k")
echo "$final"
exit 0
fi
# -------------------------
# Normal Mode (Forward Search)
# -------------------------
# Usage:
# bitrate_calculator.sh <target_bitrate_in_kbps> [fec_ratio] [max_mcs (0-7)] [--cap <cap>] [--gi <guard>]
#
# If fec_ratio is not provided, default is "8/12". If max_mcs is not provided, default is 7.
if [ "$#" -lt 1 ] || [ "$#" -gt 3 ]; then
echo "Usage: $0 <target_bitrate_in_kbps> [fec_ratio] [max_mcs (0-7)] [--cap <cap>] [--gi <guard>] [--max_bw <20|40>]"
exit 1
fi
target="$1"
shift
case "$target" in
''|*[!0-9]*)
echo "Error: target must be a positive integer." >&2
exit 1
;;
esac
if [ "$#" -ge 1 ]; then
case "$1" in
*/*) fec="$1"; shift;;
*) fec="8/12" ;;
esac
else
fec="8/12"
fi
fec_n=$(echo "$fec" | cut -d'/' -f1)
fec_k=$(echo "$fec" | cut -d'/' -f2)
if [ -z "$fec_n" ] || [ -z "$fec_k" ]; then
echo "Error: fec ratio must be in the form x/y." >&2
exit 1
fi
if [ "$#" -ge 1 ]; then
max_mcs="$1"
shift
case "$max_mcs" in
[0-7]) ;;
*) echo "Error: max_mcs must be between 0 and 7." >&2; exit 1 ;;
esac
else
max_mcs=7
fi
# Define which bandwidth values to search based on the --max_bw option.
if [ "$MAX_BW" -eq 20 ]; then
BW_VALUES="20"
else
BW_VALUES="20 40"
fi
candidate_found=0
if [ -n "$locked_gi" ]; then
for bw in $BW_VALUES; do
for mcs in $(seq 0 $max_mcs); do
final=$(compute_final "$bw" "$locked_gi" "$mcs" "$fec_n" "$fec_k")
if [ "$final" -ge "$target" ]; then
candidate_mcs="$mcs"
candidate_bw="$bw"
candidate_gi="$locked_gi"
candidate_fec="$fec"
candidate_found=1
break 2
fi
done
done
else
for bw in $BW_VALUES; do
for gi in long short; do
for mcs in $(seq 0 $max_mcs); do
final=$(compute_final "$bw" "$gi" "$mcs" "$fec_n" "$fec_k")
if [ "$final" -ge "$target" ]; then
candidate_mcs="$mcs"
candidate_bw="$bw"
candidate_gi="$gi"
candidate_fec="$fec"
candidate_found=1
break 3
fi
done
done
done
fi
if [ "$candidate_found" -eq 1 ]; then
echo "${candidate_mcs}:${candidate_bw}:${candidate_gi}:${candidate_fec}"
else
echo "No combination found." >&2
exit 1
fi

View File

@ -0,0 +1,22 @@
#!/bin/sh
if [ "$1" -eq 5 ]; then
echo "Channel5 change."
# Retrieve the telemetry setting from the YAML file
tx_on_arm=$(yaml-cli -i /etc/wfb.yaml -g .telemetry.tx_on_arm)
# Only run the TX ON ARM code if the setting is "enabled"
if [ "$tx_on_arm" = "enabled" ]; then
##TX ON ARM BEGIN
if [ "$2" -lt 1200 ]; then
echo "Disarm detected, setting low power"
set_alink_tx_pwr.sh 1
elif [ "$2" -gt 1800 ]; then
echo "ARM detected, setting high power"
set_alink_tx_pwr.sh 9
fi
##TX ON ARM END
fi
fi
exit 0

View File

@ -0,0 +1,5 @@
#!/bin/sh
echo "8 12"
exit 0

View File

@ -0,0 +1,3 @@
#!/bin/sh
firstboot

View File

@ -0,0 +1,116 @@
#!/bin/sh
#
# Script: generate_backup.sh
# Purpose: Read one or more file/directory paths (from a file list or a single argument),
# copy them into a staging area preserving their relative paths,
# remove unwanted subdirectories (specifically /overlay/root/root if backing up /overlay/root),
# and then generate a SHA1 checksum file where the filenames are shown relative to the staging root.
#
# Usage:
# ./generate_backup.sh file_list.txt
# - Reads absolute paths (files or directories) from file_list.txt.
#
# ./generate_backup.sh /some/path
# - Backs up the specified path recursively.
#
# ./generate_backup.sh
# - Defaults to backing up /overlay/root.
#
# --- Determine Input Mode ---
found_overlay_root=0
if [ $# -lt 1 ]; then
mode="single"
single_path="/overlay/root"
elif [ -f "$1" ]; then
mode="list"
list_file="$1"
elif [ -d "$1" ]; then
mode="single"
single_path="$1"
else
echo "Error: Provided argument is neither a file list nor a directory."
exit 1
fi
# --- Directories and File Names ---
BACKUP_STAGING_DIR="/tmp/backup/staging"
FINAL_BACKUP_DIR="/tmp/backup"
TAR_FILE="$FINAL_BACKUP_DIR/backup.tar"
TAR_GZ_FILE="$FINAL_BACKUP_DIR/backup.tar.gz"
CHECKSUM_FILE="$BACKUP_STAGING_DIR/checksum.txt"
# --- Prepare Staging Area ---
rm -rf "$BACKUP_STAGING_DIR" 2>/dev/null
mkdir -p "$BACKUP_STAGING_DIR" || { echo "Error: Could not create staging directory '$BACKUP_STAGING_DIR'."; exit 1; }
# --- Function: process_path ---
# Copies a file or directory into the staging area preserving its relative path.
process_path() {
filepath="$1"
[ -z "$filepath" ] && return
# Remove trailing slashes (unless the path is just "/")
if [ "$filepath" != "/" ]; then
filepath=$(echo "$filepath" | sed 's:/*$::')
fi
# Mark if the backup source is exactly /overlay/root
if [ "$filepath" = "/overlay/root" ]; then
found_overlay_root=1
fi
if [ -f "$filepath" ]; then
REL_PATH=$(echo "$filepath" | sed 's|^/||')
DEST_DIR="$BACKUP_STAGING_DIR/$(dirname "$REL_PATH")"
mkdir -p "$DEST_DIR" || { echo "Error: Could not create subdirectory for '$REL_PATH' in staging."; exit 1; }
cp "$filepath" "$DEST_DIR" || { echo "Error: Could not copy '$filepath' to staging area."; exit 1; }
elif [ -d "$filepath" ]; then
REL_PATH=$(echo "$filepath" | sed 's|^/||')
DEST_PARENT="$BACKUP_STAGING_DIR/$(dirname "$REL_PATH")"
mkdir -p "$DEST_PARENT" || { echo "Error: Could not create parent directory '$DEST_PARENT'."; exit 1; }
cp -r "$filepath" "$DEST_PARENT" || { echo "Error: Could not copy directory '$filepath' to staging area."; exit 1; }
else
echo "Error: File or directory '$filepath' does not exist."
exit 1
fi
}
# --- Process Input ---
if [ "$mode" = "list" ]; then
while IFS= read -r line; do
process_path "$line"
done < "$list_file"
elif [ "$mode" = "single" ]; then
process_path "$single_path"
fi
# --- Remove Unwanted Subfolder ---
# If /overlay/root was among the sources, then in the staging area the files are under "overlay/root".
# Remove the extra "root" folder (i.e. /tmp/backup/staging/overlay/root/root) if it exists.
if [ $found_overlay_root -eq 1 ]; then
unwanted_dir="$BACKUP_STAGING_DIR/overlay/root/root"
if [ -d "$unwanted_dir" ]; then
rm -rf "$unwanted_dir" || { echo "Error: Could not remove unwanted folder '$unwanted_dir' from staging area."; exit 1; }
fi
fi
# --- Generate Checksum File with Relative Paths ---
# We walk the staging directory and, for each file, remove the staging prefix.
# (This sed substitution technique is a common method for converting absolute paths to relative ones :contentReference[oaicite:0]{index=0}.)
> "$CHECKSUM_FILE" || { echo "Error: Cannot write to checksum file '$CHECKSUM_FILE'."; exit 1; }
find "$BACKUP_STAGING_DIR" -type f ! -name "$(basename "$CHECKSUM_FILE")" | while IFS= read -r file; do
# Remove the staging prefix to get the relative path.
rel=$(echo "$file" | sed "s|^$BACKUP_STAGING_DIR/||")
checksum=$(sha1sum "$file" | awk '{print $1}')
echo "$checksum $rel"
done > "$CHECKSUM_FILE" || { echo "Error: Failed to generate checksums."; exit 1; }
# --- Create Tar Archive and Compress ---
mkdir -p "$FINAL_BACKUP_DIR" || { echo "Error: Could not create final backup directory '$FINAL_BACKUP_DIR'."; exit 1; }
tar -C "$BACKUP_STAGING_DIR" -cvf "$TAR_FILE" . || { echo "Error: Failed to create tar file from staging directory."; exit 1; }
gzip -f "$TAR_FILE" || { echo "Error: Failed to compress tar file."; exit 1; }
echo "Backup archive successfully created at: $TAR_GZ_FILE"
exit 0

View File

@ -0,0 +1,235 @@
#!/bin/sh
#
# build_vtx_info.sh Build the /etc/vtx_info.yaml configuration file
#
# This script gathers system values, reads WiFi parameters (bw, ldpc,
# stbc, and TX power settings) from /etc/wifi_profiles.yaml based on wifi_profile,
# and determines the WiFi adapter (raw driver name) solely by scanning lsusb.
#
# If the wifi_profile is not found in /etc/wifi_profiles.yaml, it falls back
# to the "default" profile.
#
# It then uses the external tool "yaml-cli" (which supports -i, -s, -g, -d)
# to set keys in /etc/vtx_info.yaml.
#
# Path to the YAML file to be built.
YAML_FILE="/etc/vtx_info.yaml"
# Create the file if it does not exist.
[ ! -f "$YAML_FILE" ] && touch "$YAML_FILE"
########################################
# Fetch dynamic values from the system #
########################################
# 1. vtx_id: use the output of ipcinfo -i; default to "UNKNOWN"
vtx_id=$(ipcinfo -i 2>/dev/null)
[ -z "$vtx_id" ] && vtx_id="UNKNOWN"
# 2. soc: read fw_printenv soc and extract the value; default to "ssc338q"
soc=$(fw_printenv soc 2>/dev/null | awk -F '=' '{print $2}')
[ -z "$soc" ] && soc="ssc338q"
# 3. sensor: read fw_printenv sensor; default to "imx335"
sensor=$(fw_printenv sensor 2>/dev/null | awk -F '=' '{print $2}')
[ -z "$sensor" ] && sensor="imx335"
# 4. build_option: extract from /etc/os-release; default "fpv"
build_option=$(grep "^BUILD_OPTION=" /etc/os-release 2>/dev/null | cut -d'=' -f2 | tr -d '"')
[ -z "$build_option" ] && build_option="fpv"
# 5. wifi_profile: use fw_printenv wifi_profile; if not defined, set default.
wifi_profile_raw=$(fw_printenv wifi_profile 2>&1)
if echo "$wifi_profile_raw" | grep -qi "not defined"; then
wifi_profile="default"
else
wifi_profile=$(echo "$wifi_profile_raw" | awk -F '=' '{print $2}')
fi
# 5. vtx_name: use fw_printenv vtx_name:; if not defined, set default.
vtx_name_raw=$(fw_printenv vtx_name 2>&1)
if echo "$vtx_name_raw" | grep -qi "not defined"; then
vtx_name="default"
else
vtx_name=$(echo "$vtx_name_raw" | awk -F '=' '{print $2}')
fi
# 6. master_groundstation: use fw_printenv master_groundstation:; if not defined, set default.
master_groundstation_raw=$(fw_printenv master_groundstation 2>&1)
if echo "$master_groundstation_raw" | grep -qi "not defined"; then
master_groundstation="none"
else
master_groundstation=$(echo "$master_groundstation_raw" | awk -F '=' '{print $2}')
fi
########################################
# Validate or set default wifi_profile #
########################################
# If no wifi_profile was provided OR if the profile is not found in /etc/wifi_profiles.yaml,
# then use the "default" profile.
if [ -f /etc/wifi_profiles.yaml ]; then
# Try to query a key (e.g. bw) from the given profile.
test_profile=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".bw 2>/dev/null)
if [ -z "$wifi_profile" ] || [ "$test_profile" = "Node not found." ] || [ -z "$test_profile" ]; then
echo "Profile '$wifi_profile' not found in /etc/wifi_profiles.yaml, falling back to default." >&2
wifi_profile="default"
fi
else
echo "/etc/wifi_profiles.yaml not found; proceeding without profile parameters." >&2
fi
########################################
# Determine WiFi adapter via lsusb #
########################################
# Use lsusb to extract the raw driver name.
# The loop goes over unique USB IDs (field 6 from lsusb output) and
# sets wifi_adapter based on known card IDs.
wifi_adapter="none"
for card in $(lsusb | awk '{print $6}' | sort -u); do
case "$card" in
"0bda:8812" | "0bda:881a" | "0b05:17d2" | "2357:0101" | "2604:0012")
wifi_adapter="88XXau"
break
;;
"0bda:a81a")
wifi_adapter="8812eu"
break
;;
"0bda:f72b" | "0bda:b733")
wifi_adapter="8733bu"
break
;;
esac
done
########################################
# Read WiFi parameters from profiles #
########################################
# Read bandwidth (bw), LDPC, and STBC from /etc/wifi_profiles.yaml using wifi_profile.
if [ -n "$wifi_profile" ] && [ -f /etc/wifi_profiles.yaml ]; then
wifi_bw=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".bw 2>/dev/null)
wifi_ldpc_rx=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".ldpc_rx 2>/dev/null)
wifi_ldpc_tx=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".ldpc_tx 2>/dev/null)
wifi_stbc=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".stbc 2>/dev/null)
fi
# Fallback defaults if any parameter is missing.
[ -z "$wifi_bw" ] && wifi_bw="[20]"
[ -z "$wifi_ldpc_rx" ] && wifi_ldpc_rx="[0]"
[ -z "$wifi_ldpc_tx" ] && wifi_ldpc_tx="[0]"
[ -z "$wifi_stbc" ] && wifi_stbc="[0]"
########################################
# TX Power Settings from profiles #
########################################
# For a given wifi_profile, read TX power lists.
if [ -n "$wifi_profile" ] && [ -f /etc/wifi_profiles.yaml ]; then
tx_mcs0=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".tx_power.mcs0 2>/dev/null)
tx_mcs1=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".tx_power.mcs1 2>/dev/null)
tx_mcs2=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".tx_power.mcs2 2>/dev/null)
tx_mcs3=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".tx_power.mcs3 2>/dev/null)
tx_mcs4=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".tx_power.mcs4 2>/dev/null)
tx_mcs5=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".tx_power.mcs5 2>/dev/null)
tx_mcs6=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".tx_power.mcs6 2>/dev/null)
tx_mcs7=$(yaml-cli -i /etc/wifi_profiles.yaml -g profiles."$wifi_profile".tx_power.mcs7 2>/dev/null)
fi
# Fallback TX power defaults if any list is empty.
[ -z "$tx_mcs0" ] && tx_mcs0="[1,5,10,10,10,10,10,10,10,10,10]"
[ -z "$tx_mcs1" ] && tx_mcs1="[1,5,10,10,10,10,10,10,10,10,10]"
[ -z "$tx_mcs2" ] && tx_mcs2="[1,5,10,10,10,10,10,10,10,10,10]"
[ -z "$tx_mcs3" ] && tx_mcs3="[1,5,10,10,10,10,10,10,10,10,10]"
[ -z "$tx_mcs4" ] && tx_mcs4="[1,5,10,10,10,10,10,10,10,10,10]"
[ -z "$tx_mcs5" ] && tx_mcs5="[1,5,10,10,10,10,10,10,10,10,10]"
[ -z "$tx_mcs6" ] && tx_mcs6="[1,5,10,10,10,10,10,10,10,10,10]"
[ -z "$tx_mcs7" ] && tx_mcs7="[1,5,10,10,10,10,10,10,10,10,10]"
########################################
# Video Modes (Static Tables) #
########################################
if [ "$sensor" = "imx415" ]; then
mode_30fps="[3840x2160,2880x1620,1920x1080,1440x810,1280x720]"
mode_60fps="[2720x1528,1920x1080,1440x810,1360x764,1280x720]"
mode_90fps="[1920x1080,1600x900,1440x810,1280x720,960x540]"
mode_120fps="[1920x1080,1440x810,1280x720,1104x612,736x408]"
else
# Default to imx335 video modes.
mode_59fps="[1440x1080]"
mode_60fps="[2560x1440,1920x1080,1600x900,1440x810,1280x720]"
mode_90fps="[2208x1248,1920x1080,1440x810,1280x720,1104x624]"
mode_120fps="[1920x1080,1600x900,1440x810,1280x720,960x540]"
fi
########################################
# Bitrate List (Based on soc) #
########################################
if [ "$soc" = "ssc338q" ]; then
bitrate="[4096,6144,8192,10240,12288,14336,16384]"
elif [ "$soc" = "ssc30kq" ]; then
bitrate="[4096,6144,8192,10240,12288]"
else
bitrate="[4096,6144,8192,10240]"
fi
########################################
# IMU Sensor detection #
########################################
if i2cdetect -y -r 1 2>/dev/null | grep -q "68"; then
imu_sensor="BMI270"
else
imu_sensor="none"
fi
########################################
# Build the YAML file using yaml-cli #
########################################
# Top-level keys.
yaml-cli -i "$YAML_FILE" -s vtx_id "$vtx_id"
yaml-cli -i "$YAML_FILE" -s vtx_name $vtx_name
yaml-cli -i "$YAML_FILE" -s build_option "$build_option"
yaml-cli -i "$YAML_FILE" -s soc "$soc"
yaml-cli -i "$YAML_FILE" -s master_groundstation "$master_groundstation"
# WiFi section.
yaml-cli -i "$YAML_FILE" -s wifi.wifi_adapter "$wifi_adapter"
yaml-cli -i "$YAML_FILE" -s wifi.wifi_profile "$wifi_profile"
yaml-cli -i "$YAML_FILE" -s wifi.bw "$wifi_bw"
yaml-cli -i "$YAML_FILE" -s wifi.ldpc_rx "$wifi_ldpc_rx"
yaml-cli -i "$YAML_FILE" -s wifi.ldpc_tx "$wifi_ldpc_tx"
yaml-cli -i "$YAML_FILE" -s wifi.stbc "$wifi_stbc"
# TX power settings (nested mapping).
yaml-cli -i "$YAML_FILE" -s wifi.tx_power.mcs0 "$tx_mcs0"
yaml-cli -i "$YAML_FILE" -s wifi.tx_power.mcs1 "$tx_mcs1"
yaml-cli -i "$YAML_FILE" -s wifi.tx_power.mcs2 "$tx_mcs2"
yaml-cli -i "$YAML_FILE" -s wifi.tx_power.mcs3 "$tx_mcs3"
yaml-cli -i "$YAML_FILE" -s wifi.tx_power.mcs4 "$tx_mcs4"
yaml-cli -i "$YAML_FILE" -s wifi.tx_power.mcs5 "$tx_mcs5"
yaml-cli -i "$YAML_FILE" -s wifi.tx_power.mcs6 "$tx_mcs6"
yaml-cli -i "$YAML_FILE" -s wifi.tx_power.mcs7 "$tx_mcs7"
# Video section.
yaml-cli -i "$YAML_FILE" -s video.alink "[disabled,simple_alink,greg_alink]"
yaml-cli -i "$YAML_FILE" -s video.sensor "$sensor"
yaml-cli -i "$YAML_FILE" -s video.bitrate "$bitrate"
yaml-cli -i "$YAML_FILE" -s video.imu_sensor "$imu_sensor"
if [ "$sensor" = "imx415" ]; then
yaml-cli -i "$YAML_FILE" -s video.modes."30fps" "$mode_30fps"
fi
yaml-cli -i "$YAML_FILE" -s video.modes."60fps" "$mode_60fps"
yaml-cli -i "$YAML_FILE" -s video.modes."90fps" "$mode_90fps"
yaml-cli -i "$YAML_FILE" -s video.modes."120fps" "$mode_120fps"
# Finished.
exit 0

View File

@ -0,0 +1,6 @@
#!/bin/sh
##Add code to print out temp etc for the web interface.
#soc temp, wifi temp, current wfb settings, current wifi tx_pwr
ipcinfo -t >> /tmp/vtx.log
ipcinfo -t > /tmp/www_info

View File

@ -0,0 +1,62 @@
#!/bin/sh
# ----------------------------------------------------------
# Exit code definitions (for readability/reference)
# ----------------------------------------------------------
# #define EXIT_ERR 1 # (Fatal errors)
# #define EXIT_BIND 2 # (File received/bind operation)
# ----------------------------------------------------------
# Cleanup function
# ----------------------------------------------------------
cleanup() {
echo "[CLEANUP] Stopping wifibroadcast, wfb_rx, wfb_tx, wfb_tun."
wifibroadcast stop
killall -q wfb_rx
killall -q wfb_tx
killall -q wfb_tun
sleep 1
wifibroadcast start
}
# ----------------------------------------------------------
# Trap signals
# ----------------------------------------------------------
# - INT covers Ctrl+C
# - EXIT covers *any* exit (normal or error)
trap cleanup INT EXIT
# ----------------------------------------------------------
# (Optional) Initial cleanup to stop anything already running
# ----------------------------------------------------------
wifibroadcast stop
killall -q wfb_rx
killall -q wfb_tx
killall -q wfb_tun
sleep 1
# ----------------------------------------------------------
# Setup commands
# ----------------------------------------------------------
iw wlan0 set monitor none
iw wlan0 set channel 165 HT20
iw reg set US
sleep 1
echo "- Starting bind process..."
if ! [ -f /etc/bind.key ]
then
echo "OoLVgEYyFofg9zdhfYPks8/L8fqWaF9Jk8aEnynFPsXNqhSpRCMbVKBFP4fCEOv5DGcbXmUHV5eSykAbFB70ew==" \
| base64 -d > /etc/bind.key
fi
echo "- Starting wfb_rx, wfb_tx, wfb_tun"
wfb_rx -p 255 -u 5800 -K /etc/bind.key -i 10531917 wlan0 &> /dev/null &
wfb_tx -p 127 -u 5801 -K /etc/bind.key -M 1 -S 0 -L 0 \
-k 1 -n 2 -i 10531917 wlan0 &> /dev/null &
wfb_tun -a 10.5.99.2/24 &
# Sleep needed for wfb_tun to initialize
sleep 8

View File

@ -0,0 +1,171 @@
#!/bin/sh
#
# Enhanced script that:
# - Runs drone_provisioner in an infinite loop
# - Traps Ctrl+C (SIGINT) and other signals
# - Acts based on exit codes from drone_provisioner, including 5 for BACKUP
# - Always runs cleanup steps on exit
# ----------------------------------------------------------
# Cleanup function (called on exit or signal)
# ----------------------------------------------------------
cleanup() {
echo "[CLEANUP] Removing temporary directories..."
rm -rf /tmp/flash
rm -rf /tmp/bind
rm -rf /tmp/backup
}
# ----------------------------------------------------------
# Trap signals for graceful shutdown
# ----------------------------------------------------------
trap "echo 'Received SIGINT (Ctrl+C). Exiting gracefully...'; exit 130" INT
trap "echo 'Received SIGTERM. Exiting gracefully...'; exit 143" TERM
# You can add more traps for other signals if desired:
# trap "echo 'Received SIGHUP. Exiting gracefully...'; exit 129" HUP
# This trap ensures cleanup is *always* done upon exit (any exit).
trap cleanup EXIT
# ----------------------------------------------------------
# Main loop
# ----------------------------------------------------------
while true; do
# --------------------------------------------------------
# Run drone_provisioner and capture its exit code
# --------------------------------------------------------
drone_provisioner --ip 0.0.0.0 --listen-duration 99999
EXIT_CODE=$?
echo "drone_provisioner exited with code $EXIT_CODE."
# --------------------------------------------------------
# Handle exit codes
# --------------------------------------------------------
case $EXIT_CODE in
0)
echo "Listen period ended. Exiting with code 0."
exit 0
;;
1)
echo "Fatal errors. Exiting with code 1."
exit 1
;;
2)
echo "File received and saved successfully (BIND). Continuing execution..."
cd /tmp/bind || exit 2
# Decompress the .tar.gz
gunzip bind.tar.gz
# Optional: validate that bind.tar now exists
if [ ! -f bind.tar ]; then
echo "ERR: bind.tar not found after gunzip."
exit 2
fi
# Extract the tar
tar x -f bind.tar
# Detect the top-level directory name (assuming exactly one)
extracted_dir="$(tar -tf bind.tar | head -n1 | cut -d/ -f1)"
# Check that the directory exists
if [ -n "$extracted_dir" ] && [ -d "$extracted_dir" ]; then
cd "$extracted_dir" || exit 2
echo "Changed directory to: $extracted_dir"
else
echo "ERR: Could not identify a single top-level directory from bind.tar"
exit 2
fi
# Validate checksums
if ! [ -f checksum.txt ] || ! sha1sum -c checksum.txt
then
echo "ERR: Checksum failed."
exit 2
fi
# -----------------------------------------------------
# Copy system files, as needed
# -----------------------------------------------------
if [ -d overlay/ ]; then
cp -r overlay/root/* /
echo "Overlay files copied to root."
fi
if [ -f etc/wfb.yaml ]; then
cp etc/wfb.yaml /etc/wfb.yaml
echo "Copy success: /etc/wfb.yaml"
fi
if [ -d etc/sensors/ ]; then
cp etc/sensors/* /etc/sensors/
echo "Copy success: Sensor bins"
fi
if [ -f etc/majestic.yaml ]; then
cp etc/majestic.yaml /etc/majestic.yaml
/etc/init.d/S95majestic restart
echo "Copy & restart success: /etc/majestic.yaml"
fi
if [ -f lib/modules/4.9.84/sigmastar/sensor_imx335_mipi.ko ]; then
cp lib/modules/4.9.84/sigmastar/sensor_imx335_mipi.ko \
/lib/modules/4.9.84/sigmastar/sensor_imx335_mipi.ko
echo "Copy success (restart required): sensor_imx335_mipi.ko"
fi
#Set various settings
wifi_profile_name=$(yaml-cli -i /etc/wfb.yaml -g .wireless.wifi_module)
fw_setenv wifi_profile ${wifi_profile_name:-default}
vtx_name=$(yaml-cli -i /etc/wfb.yaml -g .wireless.vtx_name)
fw_setenv vtx_name ${vtx_name:-default}
#Usage: /usr/bin/set_bitrate.sh <target_bitrate_in_kbps> [max_mcs] [--cap <cap_value>] [--max_bw <20|40>]
set_bitrate.sh $(yaml-cli -i /etc/majestic.yaml -g .video0.bitrate) 5 --max_bw $(yaml-cli -i /etc/wfb.yaml -g .wireless.max_bw)
#if passphrase is set, generate /etc/drone.key
pass="$(yaml-cli -i /etc/wfb.conf -g .wireless.passhrase)" && [ -n "$pass" ] && keygen "$pass"
if [ -f ./custom_script.sh ]; then
chmod +x ./custom_script.sh
./custom_script.sh
echo "Copy success and executed: custom_script.sh"
fi
# Cleanup BIND dir before continuing the loop
rm -rf /tmp/bind
continue
;;
3)
echo "UNBIND command received. Executing firstboot..."
firstboot
exit 3
;;
4)
echo "FLASH command received. Exiting with code 4."
# (Insert your FLASH code here, currently not implemented)
exit 4
;;
5)
echo "Backup completed. Continuing execution..."
continue
;;
*)
echo "Unexpected error occurred. Exiting with code $EXIT_CODE."
exit "$EXIT_CODE"
;;
esac
done

View File

@ -0,0 +1,4 @@
#!/bin/sh
echo "Set benchtest parameters"
#Decrease TX power to lowest allowed
set_alink_tx_pwr.sh 0

View File

@ -0,0 +1,192 @@
#!/bin/sh
#
# set_bitrate.sh
#
# Usage:
# set_bitrate.sh <target_bitrate_in_kbps> [max_mcs] [--cap <cap_value>] [--max_bw <20|40>]
#
# This script reads FEC settings from /etc/wfb.yaml and allowed bandwidths
# from /etc/vtx_info.yaml, then calls bitrate_calculator.sh (with the given
# target, FEC ratio, max_mcs, and maximum bandwidth limit) to compute the best
# settings (MCS, BW, GI).
#
# The FEC ratio is constructed by swapping the YAML values so that a file with:
#
# broadcast:
# fec_n: 12
# fec_k: 8
#
# produces a ratio "8/12" as expected by bitrate_calculator.sh.
#
# The output from bitrate_calculator.sh is expected in the format:
# <mcs>:<bw>:<gi>:<fec>
#
# Then the script updates the YAML configuration files and sets the radio
# settings in the running session.
#
# Note: If the candidate BW is 40, and the systems allowed maximum bandwidth
# (read from /etc/vtx_info.yaml) is 40, then wireless.mode is forced to "HT40+".
#
# --- Parse arguments ---
if [ "$#" -lt 1 ]; then
echo "Usage: $0 <target_bitrate_in_kbps> [max_mcs] [--cap <cap_value>] [--max_bw <20|40>]"
exit 1
fi
TARGET="$1"
shift
# Default max_mcs is 5.
max_mcs=5
if [ "$#" -gt 0 ]; then
case "$1" in
--*) ;; # if next arg starts with --
*) max_mcs="$1"; shift;;
esac
fi
# Default cap is 20000 kbps unless overridden.
CAP=20000
# Default max_bw for candidate search is 40 (both 20 and 40 will be searched).
MAX_BW=40
while [ "$#" -gt 0 ]; do
case "$1" in
--cap)
shift
if [ -z "$1" ]; then
echo "Error: --cap requires a value."
exit 1
fi
CAP="$1"
shift
;;
--max_bw)
shift
if [ -z "$1" ]; then
echo "Error: --max_bw requires a value (20 or 40)."
exit 1
fi
if [ "$1" != "20" ] && [ "$1" != "40" ]; then
echo "Error: --max_bw must be either 20 or 40."
exit 1
fi
MAX_BW="$1"
shift
;;
*)
echo "Unknown argument: $1"
exit 1
;;
esac
done
# --- Read FEC settings from /etc/wfb.yaml ---
# Example YAML:
# broadcast:
# fec_n: 12
# fec_k: 8
fec_n=$(yaml-cli -i /etc/wfb.yaml -g .broadcast.fec_n)
fec_k=$(yaml-cli -i /etc/wfb.yaml -g .broadcast.fec_k)
if [ -z "$fec_n" ] || [ -z "$fec_k" ]; then
echo "Error: Could not read FEC settings from /etc/wfb.yaml."
exit 1
fi
# Swap the order so that a YAML with fec_n:12 and fec_k:8 produces "8/12".
fec_ratio="${fec_k}/${fec_n}"
# --- Read allowed bandwidths from /etc/vtx_info.yaml ---
# Expected format: [5,10,20,40]
bw_array=$(yaml-cli -i /etc/vtx_info.yaml -g .wifi.bw)
max_bw_allowed=$(echo "$bw_array" | sed 's/[][]//g' | awk -F, '{print $NF}' | tr -d ' ')
if [ -z "$max_bw_allowed" ]; then
echo "Error: Could not read allowed bandwidths from /etc/vtx_info.yaml."
exit 1
fi
# Our bitrate_calculator.sh supports 20 and 40 MHz.
if [ "$max_bw_allowed" -ge 40 ]; then
ALLOWED_BW="40"
else
ALLOWED_BW="20"
fi
# --- Call bitrate_calculator.sh ---
# We now pass the optional --max_bw parameter.
RESULT=$(bitrate_calculator.sh "$TARGET" "$fec_ratio" "$max_mcs" --cap "$CAP" --gi long --max_bw "$MAX_BW")
#echo ""$TARGET" "$fec_ratio" "$max_mcs" --cap "$CAP" --gi long --max_bw "$MAX_BW" and exit code $?"
if [ $? -ne 0 ]; then
echo "Error: bitrate_calculator.sh failed. Setting fallback, please retry with a lower bitrate."
#Fallback
set_bitrate.sh 2800 0 --max_bw 20
exit 1
fi
# RESULT is expected in the format: <mcs>:<bw>:<gi>:<fec>
candidate_mcs=$(echo "$RESULT" | cut -d: -f1)
candidate_bw=$(echo "$RESULT" | cut -d: -f2)
candidate_gi=$(echo "$RESULT" | cut -d: -f3)
candidate_fec=$(echo "$RESULT" | cut -d: -f4)
# --- Adjust candidate if its bandwidth exceeds allowed maximum ---
if [ "$candidate_bw" -gt "$max_bw_allowed" ]; then
echo "Warning: Candidate BW ${candidate_bw} MHz exceeds allowed maximum (${max_bw_allowed} MHz)."
candidate_bw="$max_bw_allowed"
fi
echo "Setting new configuration:"
echo " Target bitrate: ${TARGET} kbps"
echo " Selected settings: MCS=${candidate_mcs}, BW=${candidate_bw} MHz, GI=${candidate_gi}, FEC=${candidate_fec}"
echo " Bitrate cap: ${CAP} kbps"
echo " Allowed max BW: ${max_bw_allowed} MHz"
# --- Update YAML configuration ---
# Update /etc/wfb.yaml:
yaml-cli -i /etc/wfb.yaml -s .broadcast.mcs_index "$candidate_mcs" > /dev/null
yaml-cli -i /etc/wfb.yaml -s .broadcast.fec_k "$fec_k" > /dev/null
yaml-cli -i /etc/wfb.yaml -s .broadcast.fec_n "$fec_n" > /dev/null
yaml-cli -i /etc/wfb.yaml -s .broadcast.guard_interval "$candidate_gi" > /dev/null
# Determine wireless mode:
# If the allowed maximum BW is 40, then force mode "HT40+"
if [ "$max_bw_allowed" -eq 40 ]; then
mode="HT40+"
else
mode="HT${candidate_bw}"
fi
yaml-cli -i /etc/wfb.yaml -s .wireless.mode "$mode" > /dev/null
yaml-cli -i /etc/wfb.yaml -s .broadcast.bw "$candidate_bw" > /dev/null
yaml-cli -i /etc/majestic.yaml -s .video0.bitrate "$TARGET" > /dev/null
set +e
/etc/init.d/S98wifibroadcast stop
ret=$?
if [ $ret -ne 0 ]; then
echo "wifibroadcast stop failed (exit code $ret), sleeping 5 seconds before retrying..."
sleep 5
/etc/init.d/S98wifibroadcast stop
fi
set -e
curl -s localhost/api/v1/set?video0.bitrate=$TARGET 2> /dev/null
if ! pgrep -f majestic >/dev/null 2>&1; then
echo "Majestic is not running. Starting majestic..."
/etc/init.d/S95majestic start
else
echo "Majestic is running."
fi
set +e
/etc/init.d/S98wifibroadcast start
ret=$?
if [ $ret -ne 0 ]; then
echo "wifibroadcast start failed (exit code $ret), sleeping 5 seconds before retrying..."
sleep 5
/etc/init.d/S98wifibroadcast start
fi
set -e
echo "Bitrate settings applied successfully."

View File

@ -0,0 +1,186 @@
#!/bin/sh
#
# set_bitrate.sh
#
# Usage:
# set_bitrate.sh <target_bitrate_in_kbps> [max_mcs] [--cap <cap_value>] [--max_bw <20|40>] [--direction <initial|increased|decreased|unchanged>] [--tx_pwr <tx_power_value>]
#
# (Additional usage info…)
#
# --- Parse arguments ---
if [ "$#" -lt 1 ]; then
echo "Usage: $0 <target_bitrate_in_kbps> [max_mcs] [--cap <cap_value>] [--max_bw <20|40>] [--direction <initial|increased|decreased|unchanged>] [--tx_pwr <tx_power_value>]"
exit 1
fi
TARGET="$1"
shift
# Default max_mcs is 5.
max_mcs=5
if [ "$#" -gt 0 ]; then
case "$1" in
--*) ;; # if next arg starts with --
*) max_mcs="$1"; shift;;
esac
fi
# Default cap is 20000 kbps unless overridden.
CAP=20000
# Default max_bw for candidate search is 40 (both 20 and 40 will be searched).
MAX_BW=40
# Default direction. If not provided, we assume "initial"
DIRECTION="initial"
# Default TX_PWR is set to 5 unless overridden.
TX_PWR=5
while [ "$#" -gt 0 ]; do
case "$1" in
--cap)
shift
if [ -z "$1" ]; then
echo "Error: --cap requires a value."
exit 1
fi
CAP="$1"
shift
;;
--max_bw)
shift
if [ -z "$1" ]; then
echo "Error: --max_bw requires a value (20 or 40)."
exit 1
fi
if [ "$1" != "20" ] && [ "$1" != "40" ]; then
echo "Error: --max_bw must be either 20 or 40."
exit 1
fi
MAX_BW="$1"
shift
;;
--direction)
shift
if [ -z "$1" ]; then
echo "Error: --direction requires a value (initial, increased, decreased, or unchanged)."
exit 1
fi
case "$1" in
initial|increased|decreased|unchanged)
DIRECTION="$1"
;;
*)
echo "Error: Unknown direction: $1. Valid options are: initial, increased, decreased, or unchanged."
exit 1
;;
esac
shift
;;
--tx_pwr)
shift
if [ -z "$1" ]; then
echo "Error: --tx_pwr requires a value."
exit 1
fi
TX_PWR="$1"
shift
;;
*)
echo "Unknown argument: $1"
exit 1
;;
esac
done
# --- Read FEC settings from /etc/wfb.yaml ---
fec_n=$(yaml-cli -i /etc/wfb.yaml -g .broadcast.fec_n)
fec_k=$(yaml-cli -i /etc/wfb.yaml -g .broadcast.fec_k)
if [ -z "$fec_n" ] || [ -z "$fec_k" ]; then
echo "Error: Could not read FEC settings from /etc/wfb.yaml."
exit 1
fi
fec_ratio="${fec_k}/${fec_n}"
# --- Read allowed bandwidths from /etc/vtx_info.yaml ---
bw_array=$(yaml-cli -i /etc/vtx_info.yaml -g .wifi.bw)
max_bw_allowed=$(echo "$bw_array" | sed 's/[][]//g' | awk -F, '{print $NF}' | tr -d ' ')
if [ -z "$max_bw_allowed" ]; then
echo "Error: Could not read allowed bandwidths from /etc/vtx_info.yaml."
exit 1
fi
if [ "$max_bw_allowed" -ge 40 ]; then
ALLOWED_BW="40"
else
ALLOWED_BW="20"
fi
# --- Call bitrate_calculator.sh ---
RESULT=$(bitrate_calculator.sh "$TARGET" "$fec_ratio" "$max_mcs" --cap "$CAP" --gi long --max_bw "$MAX_BW")
if [ $? -ne 0 ]; then
echo "Error: bitrate_calculator.sh failed. Setting fallback, please retry with a lower bitrate."
set_bitrate.sh 3000 0 --max_bw 20
exit 1
fi
# RESULT is expected in the format: <mcs>:<bw>:<gi>:<fec>
candidate_mcs=$(echo "$RESULT" | cut -d: -f1)
candidate_bw=$(echo "$RESULT" | cut -d: -f2)
candidate_gi=$(echo "$RESULT" | cut -d: -f3)
candidate_fec=$(echo "$RESULT" | cut -d: -f4)
# --- Adjust candidate if its bandwidth exceeds allowed maximum ---
if [ "$candidate_bw" -gt "$max_bw_allowed" ]; then
echo "Warning: Candidate BW ${candidate_bw} MHz exceeds allowed maximum (${max_bw_allowed} MHz)."
candidate_bw="$max_bw_allowed"
fi
echo "Setting new configuration:"
echo " Target bitrate: ${TARGET} kbps"
echo " Selected settings: MCS=${candidate_mcs}, BW=${candidate_bw} MHz, GI=${candidate_gi}, FEC=${candidate_fec}"
echo " Bitrate cap: ${CAP} kbps"
echo " Allowed max BW: ${max_bw_allowed} MHz"
echo " Update direction: ${DIRECTION}"
echo " Transmitter Power: ${TX_PWR}"
# --- Execute update blocks based on --direction ---
if [ "$DIRECTION" = "decreased" ]; then
# If "decreased", update Majestic Online first
## --- Update Majestic Online ---
curl -s localhost/api/v1/set?video0.bitrate=$TARGET 2> /dev/null
sleep 1
# Then update WFB_NG Online
# --- Update WFB_NG Online ---
wfb_tx_cmd 8000 set_radio -B ${candidate_bw} -G ${candidate_gi} \
-S $(yaml-cli -i /etc/wfb.yaml -g .broadcast.stbc) \
-L $(yaml-cli -i /etc/wfb.yaml -g .broadcast.ldpc_tx) \
-M ${candidate_mcs}
wfb_tx_cmd 8000 set_fec -k ${fec_k} -n ${fec_n}
# --- Set transmitter power ---
echo "Setting transmitter power to ${TX_PWR}."
set_alink_tx_pwr.sh "$TX_PWR" --mcs $candidate_mcs
else
# --- Set transmitter power ---
echo "Setting transmitter power to ${TX_PWR}."
set_alink_tx_pwr.sh "$TX_PWR" --mcs $candidate_mcs
# Otherwise, update WFB_NG Online first
# --- Update WFB_NG Online ---
wfb_tx_cmd 8000 set_radio -B ${candidate_bw} -G ${candidate_gi} \
-S $(yaml-cli -i /etc/wfb.yaml -g .broadcast.stbc) \
-L $(yaml-cli -i /etc/wfb.yaml -g .broadcast.ldpc_tx) \
-M ${candidate_mcs}
wfb_tx_cmd 8000 set_fec -k ${fec_k} -n ${fec_n}
sleep 0.2
## --- Update Majestic Online ---
curl -s localhost/api/v1/set?video0.bitrate=$TARGET 2> /dev/null
fi
echo "Bitrate settings applied successfully."

View File

@ -0,0 +1,130 @@
#!/bin/sh
#
# Usage: set_tx_power.sh <value 0-10> [direction] [--mcs <0-7>]
#
# This script:
# 1. Checks if TX power throttling is enabled.
# 2. Retrieves the current mcs_index from wfb_tx_cmd (or uses provided --mcs value).
# 3. Uses yaml-cli to get the TX power table for that mcs_index.
# 4. Interpolates the provided value (010) to select one of the table entries.
# 5. Checks the wifi adapter type and, if it is "88XXau", prepends a negative sign to the TX power.
# 6. Sets the TX power via iw.
#
# --- Argument Parsing ---
TX_INPUT=""
DIRECTION=""
MCS_OVERRIDE=""
while [ "$#" -gt 0 ]; do
case "$1" in
--mcs)
shift
if [ "$#" -gt 0 ]; then
MCS_OVERRIDE="$1"
else
echo "Error: --mcs requires a value."
exit 1
fi
;;
*)
if [ -z "$TX_INPUT" ]; then
TX_INPUT="$1"
elif [ -z "$DIRECTION" ]; then
DIRECTION="$1"
else
echo "Unknown argument: $1"
exit 1
fi
;;
esac
shift
done
if [ -z "$TX_INPUT" ]; then
echo "Usage: $0 <value 0-10> [direction] [--mcs <0-7>]"
exit 1
fi
if [ -z "$DIRECTION" ]; then
DIRECTION="initiated"
fi
# --- Throttling Check ---
# For now, throttling is set to "disabled". (Update this logic as needed.)
TEMP_THROTTLE="disabled"
if [ "$TEMP_THROTTLE" = "enabled" ]; then
echo "TX power throttling is enabled. Aborting TX power change."
exit 0
fi
# --- Determine mcs_index ---
if [ -n "$MCS_OVERRIDE" ]; then
# Sanity check: ensure MCS_OVERRIDE is between 0 and 7, else default to 7.
if [ "$MCS_OVERRIDE" -ge 0 ] 2>/dev/null && [ "$MCS_OVERRIDE" -le 7 ] 2>/dev/null; then
MCS_INDEX="$MCS_OVERRIDE"
else
MCS_INDEX=7
fi
else
# --- Get current mcs_index from wfb_tx_cmd ---
MCS_INDEX=$(wfb_tx_cmd 8000 get_radio | grep '^mcs_index=' | cut -d '=' -f2)
if [ -z "$MCS_INDEX" ]; then
echo "Error: Unable to retrieve mcs_index."
exit 1
fi
fi
# --- Retrieve TX power table from YAML ---
# Expected output: e.g., mcs1: [1,5,10,15,20,25,30,35,40,45,50]
TABLE_OUTPUT=$(yaml-cli -i /etc/vtx_info.yaml -g ".wifi.tx_power.mcs${MCS_INDEX}")
# Remove the "mcsX:" prefix and the surrounding brackets.
POWER_LIST=$(echo "$TABLE_OUTPUT" | sed -e "s/^mcs${MCS_INDEX}:[[:space:]]*//" -e 's/[][]//g')
# --- Parse list into individual values ---
OLD_IFS="$IFS"
IFS=,
set -- $POWER_LIST
IFS="$OLD_IFS"
NUM_VALUES=$#
# --- Interpolate to select TX power ---
# Map TX_INPUT (010) to an index in the list.
DESIRED_INDEX=$(awk -v inVal="$TX_INPUT" -v n="$NUM_VALUES" 'BEGIN { print int(inVal/10*(n-1)+0.5) }')
ARRAY_INDEX=$((DESIRED_INDEX + 1))
# Retrieve the selected TX power value.
eval "MCS_TX_PWR=\${$ARRAY_INDEX}"
if [ -z "$MCS_TX_PWR" ]; then
echo "Error: Could not determine TX power from table."
exit 1
fi
# --- Parameters for TX power multiplier ---
DEFAULT_MULT=50 # Used for non-88XXau adapters
ALT_MULT=100 # Used for 88XXau adapter (TX power will be negative)
# --- Check wifi adapter type ---
WIFI_ADAPTER=$(yaml-cli -i /etc/vtx_info.yaml -g .wifi.wifi_adapter)
if [ "$WIFI_ADAPTER" = "88XXau" ]; then
MULTIPLIER=$ALT_MULT
# Force MCS_TX_PWR to be negative if not already.
case "$MCS_TX_PWR" in
-*)
# Already negative.
;;
*)
MCS_TX_PWR="-${MCS_TX_PWR}"
;;
esac
else
MULTIPLIER=$DEFAULT_MULT
fi
# --- Set the TX power ---
# Multiplication in shell arithmetic handles negatives correctly.
TXPOWER=$(( MCS_TX_PWR * MULTIPLIER ))
echo "Setting TX power to $MCS_TX_PWR ($TXPOWER) (mcs${MCS_INDEX}, adapter: $WIFI_ADAPTER, direction: $DIRECTION)"
iw wlan0 set txpower fixed "$TXPOWER"
exit 0

View File

@ -0,0 +1,148 @@
#!/bin/sh
# Threshold definitions:
WARNING1_THRESHOLD=80 # First warning threshold
WARNING2_THRESHOLD=90 # Second warning threshold (warning: VTX will soon throttle)
THROTTLE_THRESHOLD=100 # Throttle Level 1 threshold (100104°C)
THROTTLE2_THRESHOLD=105 # Throttle Level 2 threshold (105109°C)
REBOOT_THRESHOLD=110 # Reboot threshold (>=110°C)
# Define persistent state flag:
# 0 = Normal (<80°C)
# 1 = Warning level 1 (8089°C)
# 2 = Warning level 2 (9099°C)
# 3 = Throttle Level 1 (100104°C)
# 4 = Throttle Level 2 (105109°C)
# 5 = Reboot (>=110°C)
current_state=0
# Record the timestamp when the current state started
state_start_time=$(date +%s)
while true; do
# --- Get VTX Temperature ---
# Example output from ipcinfo --temp: "39.00"
vtx_temp=$(ipcinfo --temp)
vtx_int=$(echo "$vtx_temp" | cut -d. -f1)
# --- Get Adapter Temperature ---
wifi_adapter=$(yaml-cli -i /etc/vtx_info.yaml -g .wifi.wifi_adapter)
adapter_temp=0
if [ "$wifi_adapter" = "8733bu" ]; then
# Expected file format: "rf_path: 0, thermal_value: 37, offset: 45, temperature: 20"
adapter_temp=$(grep -o 'temperature: [0-9]*' /proc/net/rtl8733bu/wlan0/thermal_state | awk '{print $2}')
elif [ "$wifi_adapter" = "88XXau" ]; then
echo "Adapter 88XXau temperature extraction not implemented yet."
adapter_temp=0
elif [ "$wifi_adapter" = "8812eu" ]; then
echo "Adapter 8812eu temperature extraction not implemented yet."
adapter_temp=0
else
echo "Unknown adapter type: $wifi_adapter"
fi
# Fallback if adapter_temp is empty
if [ -z "$adapter_temp" ]; then
adapter_temp=0
fi
echo "VTX temperature: ${vtx_temp}°C, Adapter temperature: ${adapter_temp}°C"
# --- Determine the Highest Temperature ---
max_temp=$vtx_int
if [ "$adapter_temp" -gt "$max_temp" ]; then
max_temp=$adapter_temp
fi
# --- Map max_temp to a state ---
if [ "$max_temp" -lt "$WARNING1_THRESHOLD" ]; then
new_state=0
elif [ "$max_temp" -lt "$WARNING2_THRESHOLD" ]; then
new_state=1
elif [ "$max_temp" -lt "$THROTTLE_THRESHOLD" ]; then
new_state=2
elif [ "$max_temp" -lt "$THROTTLE2_THRESHOLD" ]; then
new_state=3
elif [ "$max_temp" -lt "$REBOOT_THRESHOLD" ]; then
new_state=4
else
new_state=5
fi
# --- Check for state change and take actions accordingly ---
if [ "$new_state" -ne "$current_state" ]; then
# Save previous state before updating
old_state=$current_state
current_state=$new_state
state_start_time=$(date +%s)
if [ "$current_state" -eq 0 ]; then
# Recovery: only run if coming from a throttling state (3 or 4)
if [ "$old_state" -eq 3 ] || [ "$old_state" -eq 4 ]; then
echo "Recovered from throttling state. Running recovery commands..."
/etc/init.d/S95majestic stop
wifibroadcast stop
wifibroadcast start
/etc/init.d/S95majestic start
fi
echo "Normal: VTX Temp:&T WifiTemp:&W"
elif [ "$current_state" -eq 1 ]; then
echo "Warning: High temperature detected. VTX Temp:&T WifiTemp:&W" > /tmp/msposd.msg
elif [ "$current_state" -eq 2 ]; then
echo "Warning: High temperature detected. VTX will soon thermal throttle...VTX Temp:&T WifiTemp:&W" > /tmp/msposd.msg
elif [ "$current_state" -eq 3 ]; then
# Throttle Level 1 commands only if moving upward (old_state < new_state)
if [ "$current_state" -gt "$old_state" ]; then
if [ "$wifi_adapter" = "88XXau" ]; then
txpower_value="-500"
else
txpower_value="500"
fi
iw dev wlan0 set txpower fixed $txpower_value
echo setfps 0 30 > /proc/mi_modules/mi_sensor/mi_sensor0
fi
echo "Throttling VTX (level 1). Reboot imminent, return to home..VTX Temp:&T WifiTemp:&W" > /tmp/msposd.msg
elif [ "$current_state" -eq 4 ]; then
# Throttle Level 2 commands only if moving upward (old_state < new_state)
if [ "$current_state" -gt "$old_state" ]; then
echo "Severe throttling VTX (level 2). Video will stop in 10sec, return to home..VTX Temp:&T WifiTemp:&W" > /tmp/msposd.msg
sleep 10
/etc/init.d/S95majestic stop
fi
elif [ "$current_state" -eq 5 ]; then
echo "VTX will reboot due to thermal state...VTX Temp:&T WifiTemp:&W. Rebooting in 5 seconds..."
sleep 5
reboot
fi
else
# State remains the same; update the message with elapsed time.
elapsed=$(($(date +%s) - state_start_time))
case $current_state in
0)
echo "Normal: VTX Temp:&T WifiTemp:&W (State for ${elapsed} seconds)" > /tmp/msposd.msg
;;
1)
echo "Warning: High temperature detected. VTX Temp:&T WifiTemp:&W (State for ${elapsed} seconds)" > /tmp/msposd.msg
;;
2)
echo "Warning: High temperature detected. VTX will soon thermal throttle...VTX Temp:&T WifiTemp:&W (State for ${elapsed} seconds)" > /tmp/msposd.msg
;;
3)
echo "Throttling VTX (level 1). Reboot imminent, return to home..VTX Temp:&T WifiTemp:&W (State for ${elapsed} seconds)" > /tmp/msposd.msg
;;
4)
echo "Severe throttling VTX (level 2). Reboot imminent, return to home..VTX Temp:&T WifiTemp:&W (State for ${elapsed} seconds)" > /tmp/msposd.msg
;;
5)
# Reboot state should not linger.
;;
esac
fi
sleep 5
done

View File

@ -0,0 +1,207 @@
#!/bin/sh
wfb_key=/etc/drone.key
wfb_dev=wlan0
wfb_yaml() {
if [ -e "$1" ]; then
local CONFIG_FILE="$1"
wireless_keys="txpower channel wifi_mode passphrase video_key tunnel_key bind_key link_id"
for key in $wireless_keys; do
val="$(yaml-cli -i "$CONFIG_FILE" -g ".wireless.$key" 2>/dev/null)"
if [ -n "$val" ]; then
varname="WIRELESS_$(echo "$key" | tr '[:lower:]' '[:upper:]')"
eval "$varname='$val'"
# echo "$varname=$val"
fi
done
broadcast_keys="mcs_index fec_k fec_n force_vht ldpc stbc guard_interval bw"
for key in $broadcast_keys; do
val="$(yaml-cli -i "$CONFIG_FILE" -g ".broadcast.$key" 2>/dev/null)"
if [ -n "$val" ]; then
varname="BROADCAST_$(echo "$key" | tr '[:lower:]' '[:upper:]')"
eval "$varname='$val'"
# echo "$varname=$val"
fi
done
# Check for broadcast redundancy setting.
# If .wireless.broadcast_redundancy returns "auto", then run detect_redundancy.sh.
# Its output should be two numbers (e.g. "8 12"). If either number is empty, default to 8 and 12.
redundancy_val="$(yaml-cli -i "$CONFIG_FILE" -g .wireless.broadcast_redundancy 2>/dev/null)"
if [ "$redundancy_val" = "auto" ]; then
result="$(detect_redundancy.sh)"
fec_k=$(echo "$result" | awk '{print $1}')
fec_n=$(echo "$result" | awk '{print $2}')
[ -z "$fec_k" ] && fec_k=8
[ -z "$fec_n" ] && fec_n=12
BROADCAST_FEC_K="$fec_k"
BROADCAST_FEC_N="$fec_n"
fi
tunnel_keys="mcs_index fec_k fec_n force_vht ldpc stbc"
for key in $tunnel_keys; do
val="$(yaml-cli -i "$CONFIG_FILE" -g ".tunnel.$key" 2>/dev/null)"
if [ -n "$val" ]; then
varname="TUNNEL_$(echo "$key" | tr '[:lower:]' '[:upper:]')"
eval "$varname='$val'"
# echo "$varname=$val"
fi
done
telemetry_keys="router serial osd_fps channels"
for key in $telemetry_keys; do
val="$(yaml-cli -i "$CONFIG_FILE" -g ".telemetry.$key" 2>/dev/null)"
if [ -n "$val" ]; then
varname="TELEMETRY_$(echo "$key" | tr '[:lower:]' '[:upper:]')"
eval "$varname='$val'"
# echo "$varname=$val"
fi
done
fi
}
load_config() {
wfb_yaml /etc/wfb.yaml
if [ ! -e "$wfb_key" ]; then
wfb_key="/rom/etc/drone.key"
fi
}
load_modules() {
for card in $(lsusb | awk '{print $6}' | sort | uniq); do
case "$card" in
"0bda:8812" | "0bda:881a" | "0b05:17d2" | "2357:0101" | "2604:0012")
driver=88XXau
modprobe "$driver"
;;
"0bda:a81a")
driver=8812eu
modprobe "$driver" rtw_regd_src=1 rtw_tx_pwr_by_rate=0 rtw_tx_pwr_lmt_enable=0
;;
"0bda:f72b" | "0bda:b733")
driver=8733bu
modprobe "$driver" rtw_regd_src=1 rtw_tx_pwr_by_rate=0 rtw_tx_pwr_lmt_enable=0
;;
esac
done
if [ -z "$driver" ]; then
echo "- Wireless module not detected!"
exit 1
else
echo "- Detected driver: $driver"
fi
if ! ifconfig "$wfb_dev" up; then
echo "- Wireless driver not found!"
exit 1
fi
}
load_interface() {
iw "$wfb_dev" set monitor none
iw "$wfb_dev" set channel "$WIRELESS_CHANNEL" "$WIRELESS_WIFI_MODE"
iw reg set 00
if [ "$driver" = "88XXau" ]; then
iw "$wfb_dev" set txpower fixed "$((WIRELESS_TXPOWER * -100))"
else
iw "$wfb_dev" set txpower fixed "$((WIRELESS_TXPOWER * 50))"
fi
}
start_broadcast() {
echo "- Starting wfb_tx"
wfb_tx -K "$WIRELESS_VIDEO_KEY" -M "$BROADCAST_MCS_INDEX" -G "$BROADCAST_GUARD_INTERVAL" -B "$BROADCAST_BW" -C 8000 \
-k "$BROADCAST_FEC_K" -n "$BROADCAST_FEC_N" -i "$WIRELESS_LINK_ID" "$wfb_dev" &> /dev/null &
}
start_tunnel() {
echo "- Starting wfb_tun"
wfb_rx -p 160 -u 5800 -K "$WIRELESS_TUNNEL_KEY" -i "$WIRELESS_LINK_ID" "$wfb_dev" &> /dev/null &
wfb_tx -p 32 -u 5801 -K "$WIRELESS_TUNNEL_KEY" -M "$TUNNEL_MCS_INDEX" \
-k "$TUNNEL_FEC_K" -n "$TUNNEL_FEC_N" -i "$WIRELESS_LINK_ID" "$wfb_dev" &> /dev/null &
wfb_tun -a 10.5.0.10/24 > /dev/null &
}
start_telemetry() {
if [ "$(ipcinfo -c)" = "ssc33x" ]; then
devmem 0x1F207890 16 0x8
fi
if [ "$TELEMETRY_ROUTER" = "msposd" ]; then
echo "- Starting $TELEMETRY_ROUTER"
size=$(yaml-cli -i /etc/majestic.yaml -g .video0.size)
msposd --baudrate 115200 --channels 8 --ahi 0 -osd -r "$TELEMETRY_OSD_FPS" \
--master "$TELEMETRY_SERIAL" --out 10.5.0.1:14551 --size "${size:-1280x720}" > /dev/null &
elif [ "$TELEMETRY_ROUTER" = "mavfwd" ]; then
echo "- Starting $TELEMETRY_ROUTER"
mavfwd --baudrate 115200 --channels $TELEMETRY_CHANNELS -p 100 -a 15 -t \
--master "$TELEMETRY_SERIAL" --in 0.0.0.0:14550 --out 10.5.0.1:14551 > /dev/null &
fi
}
video_settings() {
if [ "$(ipcinfo -s)" = "imx415" ]; then
cli -s .isp.sensorConfig /etc/sensors/imx415_fpv.bin
fi
cli -s .isp.exposure 5
cli -s .video0.fps 60
cli -s .video0.codec h265
cli -s .video0.rcMode cbr
cli -s .outgoing.enabled true
cli -s .outgoing.server udp://0.0.0.0:5600
}
start() {
load_config
load_modules
load_interface
if [ ! -e /etc/system.ok ]; then
sleep 1
video_settings
touch /etc/system.ok
killall -1 majestic
fi
stop
start_broadcast
start_tunnel
start_telemetry
}
bind() {
provision_bind.sh
}
stop() {
for process in wfb_rx wfb_tx wfb_tun msposd mavfwd; do
if [ -n "$(pidof $process)" ]; then
echo "- Stopping $process"
killall -q "$process"
fi
done
}
case "$1" in
start|stop)
$1
;;
bind)
provision_bind.sh
;;
reset)
cp -f /rom/etc/majestic.yaml /etc/majestic.yaml
cp -f /rom/etc/wfb.yaml /etc/wfb.yaml
video_settings
;;
*)
echo "Usage: $0 {start|stop|reset|bind}"
exit 1
;;
esac