#!/bin/sh # # set_bitrate.sh # # Usage: # set_bitrate.sh [max_mcs] [--cap ] [--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: # ::: # # 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 system’s 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 [max_mcs] [--cap ] [--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: ::: 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."