Реверс прошивки модуля FM100B: архитектура + что такое вокодер
docs/fm100b-firmware-re.md: образ = ARM(старт)+Thumb-2/FPU, 1.5МБ, без символов, база RAM ~0x0360xxxx. Карта регионов. КЛЮЧЕВОЕ: «Vocoder» в прошивке = WebRTC audio (шумодав NSX + AGC, открытый код), а НЕ AMBE. Сам AMBE — вне ARM-образа (DSP/ROM A6), в прошивке только интерфейс ATVoiceEnc/Dec + RecvAmbedata. Найдены open-source либы: EasyFlash (NV/калибровка), WebRTC (аудио). Честная оценка: свой вокодер для эфирного DMR невозможен (нет AMBE-совместимости); реально моддить — WebRTC-параметры, кодек-гейны, NV-калибровку, логику DMR. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NikMGoqQWWk9wy2ww2vJAr
Этот коммит содержится в:
@@ -24,7 +24,10 @@ CMDS = {
|
||||
"CmdEnd": "34 52 05 ee 79",
|
||||
}
|
||||
|
||||
def hx(name): return bytes.fromhex(CMDS[name].replace(" ", ""))
|
||||
def hx(name):
|
||||
if name.startswith("hex:"):
|
||||
return bytes.fromhex(name[4:].replace(" ", ""))
|
||||
return bytes.fromhex(CMDS[name].replace(" ", ""))
|
||||
|
||||
# powershell: open port, run a sequence of (write, wait) steps, capture each response
|
||||
PS = r'''
|
||||
@@ -47,7 +50,7 @@ foreach ($s in $steps) {{
|
||||
if ($buf.Count -gt 0 -and ($sw.ElapsedMilliseconds-$last) -gt {idle}) {{ break }}
|
||||
}}
|
||||
$hex = ($buf | ForEach-Object {{ "{{0:x2}}" -f $_ }}) -join ""
|
||||
Write-Output ("RSP:"+$name+":"+$hex)
|
||||
Write-Output ("RSP|"+$name+"|"+$hex)
|
||||
}}
|
||||
$p.Close()
|
||||
Write-Output "DONE"
|
||||
@@ -72,8 +75,8 @@ def run(port, seq, dwell=120, tmo=700, idle=200):
|
||||
res=[]
|
||||
for line in out.split("\n"):
|
||||
if line.startswith("ERR:"): sys.exit(line)
|
||||
if line.startswith("RSP:"):
|
||||
_,name,hexs=line.split(":",2)
|
||||
if line.startswith("RSP|"):
|
||||
_,name,hexs=line.split("|",2)
|
||||
res.append((name, bytes.fromhex(hexs) if hexs else b""))
|
||||
return res
|
||||
|
||||
@@ -107,7 +110,7 @@ def main():
|
||||
print("Нет ответов от рации (powershell не вернул RSP). Порт/режим?")
|
||||
return
|
||||
for name,rx in res:
|
||||
tag=f" {name:12s} TX={CMDS[name]}"
|
||||
tag=f" {name:14s} TX={CMDS.get(name, name[4:] if name.startswith('hex:') else name)}"
|
||||
if not rx:
|
||||
print(tag+" RX=(нет ответа)")
|
||||
else:
|
||||
|
||||
Ссылка в новой задаче
Block a user