From 847f0bb157ae2f7afed398eeb8ba5837c983e091 Mon Sep 17 00:00:00 2001 From: Hermes Date: Sun, 27 Sep 2026 23:01:52 +0200 Subject: [PATCH] hilink: add read-only YAML-aware MSP VTX status --- .../overlay/etc/init.d/S97link-monitor | 1 + .../general/overlay/usr/bin/wifibroadcast | 2 +- .../0001-wifilink-mspvtx-read-only.patch | 155 ++++++++++++++++++ package/msposd/msposd.mk | 58 +++++++ 4 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 package/msposd/0001-wifilink-mspvtx-read-only.patch create mode 100644 package/msposd/msposd.mk diff --git a/devices/ssc338q_fpv_openipc-urllc-aio/general/overlay/etc/init.d/S97link-monitor b/devices/ssc338q_fpv_openipc-urllc-aio/general/overlay/etc/init.d/S97link-monitor index 0d47043..00f4707 100755 --- a/devices/ssc338q_fpv_openipc-urllc-aio/general/overlay/etc/init.d/S97link-monitor +++ b/devices/ssc338q_fpv_openipc-urllc-aio/general/overlay/etc/init.d/S97link-monitor @@ -15,6 +15,7 @@ case "$1" in -c 6 \ -p 500 \ -w 1000 \ + --mspvtx \ -r 20 \ -m /dev/ttyS2 \ -o 127.0.0.1:14551 \ diff --git a/devices/ssc338q_fpv_openipc-urllc-aio/general/overlay/usr/bin/wifibroadcast b/devices/ssc338q_fpv_openipc-urllc-aio/general/overlay/usr/bin/wifibroadcast index e0fa21f..92c5435 100755 --- a/devices/ssc338q_fpv_openipc-urllc-aio/general/overlay/usr/bin/wifibroadcast +++ b/devices/ssc338q_fpv_openipc-urllc-aio/general/overlay/usr/bin/wifibroadcast @@ -120,7 +120,7 @@ start_telemetry() { size=$(curl -s localhost/api/v1/config.json | jsonfilter -qe "@.video0.size") fi if ! pidof msposd >/dev/null; then - msposd -b 115200 -c 8 -c 6 -p 500 -w 1000 -r "$osd_fps" -m /dev/"$serial" \ + msposd -b 115200 -c 8 -c 6 -p 500 -w 1000 --mspvtx -r "$osd_fps" -m /dev/"$serial" \ -o 127.0.0.1:"$port_tx" -z "$size" > /dev/null & fi fi diff --git a/package/msposd/0001-wifilink-mspvtx-read-only.patch b/package/msposd/0001-wifilink-mspvtx-read-only.patch new file mode 100644 index 0000000..fe79aad --- /dev/null +++ b/package/msposd/0001-wifilink-mspvtx-read-only.patch @@ -0,0 +1,155 @@ +diff --git a/osd.c b/osd.c +index a8b756e..eefb4d6 100644 +--- a/osd.c ++++ b/osd.c +@@ -960,48 +960,16 @@ static void rx_msp_callback(msp_msg_t *msp_message) { + } + + case MSP_GET_VTX_CONFIG: { +- if (vtxInitDone) { ++ if (vtxInitDone && verbose) { + mspVtxConfigStruct *in_mspVtxConfigStruct = (mspVtxConfigStruct *)msp_message->payload; +- uint16_t frequency = ++ uint16_t requested_frequency = + (in_mspVtxConfigStruct->freqMSB << 8) | in_mspVtxConfigStruct->freqLSB; + +- double current_frequency = +- read_current_freq_from_interface(read_setting("/etc/wfb.conf", "wlan")); +- +- if (verbose) +- printf("mspVTX Band: %i, Channel: %i, wanted Frequency: %u, set " +- "Frequency: %.0f\n", +- in_mspVtxConfigStruct->band, in_mspVtxConfigStruct->channel, frequency, +- current_frequency); +- +- if (frequency != (uint16_t)current_frequency) { +- int channel = 0; +- for (int i = 0; i < MAX_ENTRIES; i++) { +- if (fc_list[i].frequency == frequency) +- channel = fc_list[i].channel; +- } +- if (channel > 0) { +- if (verbose) +- printf("mspVTX executing channel change to channel " +- "%d\n", +- channel); +- +- set_frequency(read_setting("/etc/wfb.conf", "wlan"), channel); +- +- // store new channel to wfb.conf +- char cha_str[32]; +- sprintf(cha_str, "%i", channel); +- write_setting("/etc/wfb.conf", "channel", cha_str); +- } else { +- printf("Never change to channel 0, we should not reach " +- "here, check " +- "vtx table in your fc\n"); +- } +- } +- } else { +- if (verbose) +- printf("vtxInitDone not finished, should never happen\n"); ++ printf("mspVTX read-only: FC requested %u MHz, configured WFB frequency %d MHz\n", ++ requested_frequency, read_wfb_frequency()); + } ++ // Channel changes are intentionally ignored. The active raw-radio link is ++ // controlled by link-mode/WFB profiles, not legacy iwconfig commands. + break; + } + +diff --git a/osd/msp/msp.c b/osd/msp/msp.c +index b1a538c..bdb443e 100644 +--- a/osd/msp/msp.c ++++ b/osd/msp/msp.c +@@ -144,22 +144,26 @@ void setVtxTablePowerLevel(int serial_fd, uint8_t idx) { + + void msp_set_vtx_config(int serial_fd) { + +- // mspVTX read current frequency setting +- query_interface_for_available_frequencies(); +- +- frequency = read_current_freq_from_interface(read_setting("/etc/wfb.conf", "wlan")); ++ // WiFiLink stores the configured WFB channel in YAML. Do not use ++ // iwconfig: on the RTL8812EU it can report stale management-mode data ++ // while raw WFB is active. ++ frequency = read_wfb_frequency(); ++ if (frequency < 0) { ++ fprintf(stderr, "mspVTX: cannot read /etc/wfb.yaml channel\n"); ++ return; ++ } + + int band = 6; + int channel = 3; + for (int index = 0; index < FREQ_TABLE_SIZE; index++) { + if (channelFreqTable[index] == frequency) { + // Determine band and channel using division and modulo +- band = index / 8 + 1; // Which band (integer division) +- channel = (index % 8) + 1; // Channel within the band (modulo) ++ band = index / 8 + 1; ++ channel = (index % 8) + 1; + + if (verbose) + printf("Frequency %d found in band %i, channel %d\n", frequency, band, channel); +- break; // Exit after finding the frequency ++ break; + } + } + +diff --git a/osd/util/interface.c b/osd/util/interface.c +index 089fdc2..49d60fc 100644 +--- a/osd/util/interface.c ++++ b/osd/util/interface.c +@@ -153,3 +153,41 @@ void set_frequency(char *interface, int channel) { + printf("Failed to set channel on %s\n", interface); + } + } ++ ++int read_wfb_frequency(void) { ++ FILE *fp = fopen("/etc/wfb.yaml", "r"); ++ char buffer[256]; ++ int in_wireless = 0; ++ int channel = -1; ++ ++ if (fp == NULL) { ++ return -1; ++ } ++ ++ while (fgets(buffer, sizeof(buffer), fp) != NULL) { ++ if (strncmp(buffer, "wireless:", 9) == 0) { ++ in_wireless = 1; ++ continue; ++ } ++ ++ if (in_wireless && buffer[0] != ' ' && buffer[0] != ' ' && ++ buffer[0] != '\n') { ++ break; ++ } ++ ++ if (in_wireless && sscanf(buffer, " channel: %d", &channel) == 1) { ++ break; ++ } ++ } ++ ++ fclose(fp); ++ ++ if (channel >= 1 && channel <= 14) { ++ return 2407 + channel * 5; ++ } ++ if (channel > 14 && channel <= 196) { ++ return 5000 + channel * 5; ++ } ++ ++ return -1; ++} +diff --git a/osd/util/interface.h b/osd/util/interface.h +index 983971d..134b0d5 100644 +--- a/osd/util/interface.h ++++ b/osd/util/interface.h +@@ -22,3 +22,7 @@ int query_interface_for_available_frequencies(); + void set_frequency(char *interface, int channel); + + int read_current_freq_from_interface(char *interface); ++ ++// Read WiFiLink/OpenIPC WFB channel from the YAML runtime configuration. ++// Returns the centre frequency in MHz, or -1 when no valid channel is present. ++int read_wfb_frequency(void); diff --git a/package/msposd/msposd.mk b/package/msposd/msposd.mk new file mode 100644 index 0000000..90493b0 --- /dev/null +++ b/package/msposd/msposd.mk @@ -0,0 +1,58 @@ +################################################################################ +# +# msposd — pinned upstream plus HiLink WiFiLink mspVTX compatibility patch +# +################################################################################ + +MSPOSD_SITE = $(call github,openipc,msposd,$(MSPOSD_VERSION)) +MSPOSD_VERSION = ad0175ce01c4e09b3eb4223fd683735f9df22715 +MSPOSD_DEPENDENCIES = libevent-openipc + +ifeq ($(OPENIPC_SOC_FAMILY),gk7205v200) + MSPOSD_FAMILY = goke + MSPOSD_OSDRV = $(GOKE_OSDRV_GK7205V200_PKGDIR) +else ifeq ($(OPENIPC_SOC_FAMILY),hi3516ev200) + MSPOSD_FAMILY = hisi + MSPOSD_OSDRV = $(HISILICON_OSDRV_HI3516EV200_PKGDIR) +else ifeq ($(OPENIPC_SOC_FAMILY),infinity6b0) + MSPOSD_FAMILY = star6b0 + MSPOSD_OSDRV = $(SIGMASTAR_OSDRV_INFINITY6B0_PKGDIR) +else ifeq ($(OPENIPC_SOC_FAMILY),infinity6c) + MSPOSD_FAMILY = star6c + MSPOSD_OSDRV = $(SIGMASTAR_OSDRV_INFINITY6C_PKGDIR) +else + MSPOSD_FAMILY = star6e + MSPOSD_OSDRV = $(SIGMASTAR_OSDRV_INFINITY6E_PKGDIR) +endif + +define MSPOSD_BUILD_CMDS + $(MAKE) CC=$(TARGET_CC) TOOLCHAIN=$(STAGING_DIR) DRV=$(MSPOSD_OSDRV)/files/lib $(MSPOSD_FAMILY) OUTPUT=$(@D)/msposd -C $(@D) +endef + +define MSPOSD_INSTALL_TARGET_CMDS + $(INSTALL) -m 755 -d $(TARGET_DIR)/usr/bin + $(INSTALL) -m 755 -t $(TARGET_DIR)/usr/bin $(@D)/msposd + $(INSTALL) -m 755 -t $(TARGET_DIR)/usr/bin $(@D)/safeboot.sh + + $(INSTALL) -m 755 -d $(TARGET_DIR)/usr/share/fonts + $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_inav.png + $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_inav_hd.png + $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_btfl.png + $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_btfl_hd.png + $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_ardu.png + $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_ardu_hd.png + $(INSTALL) -m 644 -t $(TARGET_DIR)/etc $(@D)/vtxmenu.ini +endef + +define MSPOSD_INSTALL_LIBRARIES + $(INSTALL) -m 755 -d $(TARGET_DIR)/usr/lib + $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib $(MSPOSD_OSDRV)/files/lib/libcam_os_wrapper.so + $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib $(MSPOSD_OSDRV)/files/lib/libmi_rgn.so + $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib $(MSPOSD_OSDRV)/files/lib/libmi_sys.so +endef + +ifeq ($(OPENIPC_SOC_VENDOR),sigmastar) +MSPOSD_POST_INSTALL_TARGET_HOOKS += MSPOSD_INSTALL_LIBRARIES +endif + +$(eval $(generic-package))