Восстановлено из транскрипта сессии после потери рабочего дерева на сервере сборки. Что внутри: - четыре новых модуля прошивки (приём, сборка исходящего, меню Messages); - правки существующих файлов в виде скриптов, с порядком применения; - инструменты стенда: снятие экрана рации по USB, дамп кадров, эталонная сборка пакета; - NOTES.md: что проверено в эфире, что не доделано, где грабли. Работало в эфире в августе 2026: данные ходят в обе стороны в режиме хотспота, рация принимает SMS и показывает на экране. Отправка собрана и сверена с эталоном сервера побайтово, но в эфире не проверялась. Claude-Session: https://claude.ai/code/session_01GJtvG5WwqYNe1b7s9LLtgy
45 строки
2.0 KiB
Python
45 строки
2.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Stop the radio from dropping out of hotspot (modem) mode when the host goes quiet.
|
|
|
|
Stock behaviour: if the USB host does not talk to the radio for MMDVMHOST_TIMEOUT
|
|
(20 s), the firmware calls hotspotExit() and leaves modem mode by itself. That is a
|
|
safety net for a crashed host, but it makes the radio unusable as a permanently
|
|
attached modem - which is exactly how it is used here.
|
|
|
|
With the timeout set to 0 the inactivity check is disabled; leaving modem mode is
|
|
then only done deliberately (by the user from the radio, or by the host asking the
|
|
modem to go idle).
|
|
"""
|
|
W = "/home/viktor/ogd77rel/uv_src/OpenGD77_MDUV380_DM1701_20260130/MDUV380_firmware/application"
|
|
p = W + "/source/functions/hotspot.c"
|
|
s = open(p).read()
|
|
|
|
if "MMDVMHOST_TIMEOUT_DISABLED" in s:
|
|
print("already patched")
|
|
raise SystemExit(0)
|
|
|
|
old_const = "static const uint32_t MMDVMHOST_TIMEOUT = 20000; // 20s timeout (MMDVMHost mode only, there is no timeout for BlueDV)\n"
|
|
assert old_const in s, "timeout constant not found"
|
|
|
|
new_const = (
|
|
"// 0 disables the host-inactivity timeout, so the radio stays in modem mode until it is\n"
|
|
"// told to leave. Set this back to 20000 to restore the stock 20 second auto-exit.\n"
|
|
"#define MMDVMHOST_TIMEOUT_DISABLED 0\n"
|
|
"static const uint32_t MMDVMHOST_TIMEOUT = MMDVMHOST_TIMEOUT_DISABLED;\n"
|
|
)
|
|
s = s.replace(old_const, new_const, 1)
|
|
|
|
# Guard both inactivity checks so a zero timeout means "never time out".
|
|
old_check = """ if ((nonVolatileSettings.hotspotType == HOTSPOT_TYPE_MMDVM) &&
|
|
((ticksGetMillis() - mmdvmHostLastActiveTime) > MMDVMHOST_TIMEOUT))
|
|
"""
|
|
new_check = """ if ((MMDVMHOST_TIMEOUT != 0) && (nonVolatileSettings.hotspotType == HOTSPOT_TYPE_MMDVM) &&
|
|
((ticksGetMillis() - mmdvmHostLastActiveTime) > MMDVMHOST_TIMEOUT))
|
|
"""
|
|
count = s.count(old_check)
|
|
assert count == 2, "expected 2 inactivity checks, found %d" % count
|
|
s = s.replace(old_check, new_check)
|
|
|
|
open(p, "w").write(s)
|
|
print("hotspot.c: host-inactivity auto-exit disabled (%d checks guarded)" % count)
|