ENDフレームはどこへ消えた — Semi Repeater Mode のターミネータ欠落と「ウォッチドッグ擬似終端」
本記事について(前提・検証条件)
本記事は、RADIODDITY DB40-D を用いて行った実験・観測の記録である。以下の前提・検証条件のもとで得られた結果であり、他機種・他ファームウェアでは挙動が異なる可能性がある点に留意されたい。
- 対象機種:RADIODDITY DB40-D
- 動作モード:Semi Repeater Mode(SFR On/Relay mode = RX and TX)
- 構成:RX/TX 同一周波数のシンプレックス(145.75000 MHz)/TS1・CC1
- ログ取得環境:MMDVM / OpenCCVoice(音声 ID 自動送出)
- 観測データ:2026年5〜6月に採取したログを比較
- 補足:症状のうち「ターミネータ欠落」の部分は観測結果からの推測であり、メーカーへ確認中である
再現環境:CPS 設定
本記事で扱う症状は、以下の CPS 設定(セミレピーターモード構成)で再現したものである。RX/TX を同一周波数のシンプレックスとし、SFR(Semi Repeater Mode)を On、Relay mode を RX and TX とした構成で、終端検出の不具合が現れる。
チャンネル設定(SFR-TS1)
| Zone / CH | Z-10 / 1 | RX Group | RX all |
| CH mode | Digital | Encryption | Off |
| CH Name | SFR-TS1 | Scan List | Off |
| RX Freq | 145.75000 | Contacts | Off |
| TX Freq | 145.75000 | EAS | Off |
| Power | High | Relay Monitor | On |
| RX Only | Off | Relay mode | RX and TX |
| Alarm | Off | SFR | On |
| Prompt | Off | PCT | Patcs |
| DMR Mode | Simplex | APRS | Off |
| RX TS | Slot 1 | Bandw | 25 |
| TX TS | Slot 1 | RX QT/DQT | Off |
| RX CC | 1 | TX QT/DQT | Off |
| TX CC | 1 | Msg Type | Unconfirme |
| TX Policy | Impolite |
DMR service 設定
| Remote monitor duration | 10S | DTMF Duration (On-time) | 50ms |
| Remote Monitor Decode | Off | DTMF Interval (Off time) | 50ms |
| Remote Kill Decode | Off | DTMF Volume (Local) | 5 |
| Radio Detection Decode | Off | DTMF ON/OFF | Off |
| Radio Revive Decode | On | GPS | On |
| Call Alert | Off | GPS Interval | 1Min |
| Group call hang time | 500ms | GPS Channel | Current Channel Select |
| Private call hang time | 500ms | ||
| Import Delay | 50ms |
※ 右側の Mandown 系・Scrambling frequency などの項目はグレーアウト(無効)のため割愛した。
症状:短い信号が、きれいに閉じない
ある中継機を Semi Repeater Mode で挟んだ瞬間から、短点送信(カーチャンク)の終端検出が壊れ始めた。通常のラグチューでは実害がないのに、0.8 秒級の短い信号だけが「正常終了」と判定されず、ウォッチドッグのタイムアウト待ちに落ちてしまう。
OpenCCVoice は DMR の交信状況を見て音声 ID を自動送出する仕組みで、その判定の根っこは「各送信の最初のフレームと最後のフレームを検出する」ことにある。最後のフレーム=終端が来なければ、システムは交信が終わったことを知ることができない。
背景:終端フレームの役割
DMR の音声送信は、ヘッダ → 音声バースト群 → ターミネータ(終端)という並びで構成される。MMDVM のログ上では、これがそれぞれ voice header と end of voice transmission として現れる。OpenCCVoice はこの 2 行をペアで掴み、開始と終了、そして継続時間を確定させている。
証拠:2 つのログを並べる
【A】正常終了(短点・クリーンな EOT)
M: 2026-05-21 21:25:13.384 DMR Slot 2, received network voice header from JI2TAB to TG 168
M: 2026-05-21 21:25:14.160 DMR Slot 2, received network end of voice transmission, 0.8 seconds, 0% packet loss, BER: 0.0%→ ヘッダの後に、ちゃんと終端が続く。パケットロス 0%、0.8 秒の短点も正しく処理される。
【B】Semi Repeater Mode での異常終了(ターミネータ欠落)
M: 2026-06-23 17:33:30.500 DMR Slot 2, received network voice header from JI2TAB to TG 168
M: 2026-06-23 17:33:32.800 DMR Slot 2, network watchdog has expired, 2.3 seconds, 63% packet loss→ ヘッダは届く。だが end of voice transmission が一度も来ない。代わりにリンクが時間切れ(watchdog has expired)になり、終端付近で高いパケットロスを記録する。
解釈(事実と推測を分けて)
確定している事実は、Semi Repeater Mode のときだけ end of voice transmission 行が出ず、ウォッチドッグ満了で送信が閉じることだ。全 TG で再現し、特定の TG に依存しない点も確認済み。
一方、「ターミネータのデータバーストそのものが転送されずに落ちている」というのは、ログ挙動から導いた推測である(この点はメーカー側へ問い合わせ中)。観測できているのはあくまで「終端行が欠落し、ウォッチドッグが満了する」という結果であり、欠落の正体は推定の段階にある。
自分側の手当て:ウォッチドッグ擬似終端
中継機側のファームは自分では直せない。ならばソフト側を頑丈にする。要は「ウォッチドッグ満了=擬似的な終端」として受け止め、通常 EOT とは別の時間上限で短点判定すればいい。
RX_DURATION_MAX_SEC = 2.0 # 通常EOT経路の短点上限(値は一例)
WATCHDOG_RX_MAX_SEC = 5.0 # ウォッチドッグ経路専用の上限(V1.70で追加)
if "end of voice transmission" in line: # 正常終端
duration, ceiling = parse_dur(line), RX_DURATION_MAX_SEC
elif "watchdog has expired" in line: # 擬似終端
duration, ceiling = parse_dur(line), WATCHDOG_RX_MAX_SEC
if duration <= ceiling:
trigger_voice_id() # カーチャンクとして応答※ 上記は構造を示すための簡略コード。
ポイントは、ウォッチドッグ満了の経過時間(実測2〜4秒)が通常経路の短点上限を超えてしまう点だ。ここを同じ閾値で裁くと、短点が「通常 QSO」へ誤分類される。経路ごとに天井を分けることで、これを防いだ。
なぜウォッチドッグの経過時間は長めに出るのか
ここで注意したいのは、ウォッチドッグ満了で記録される経過秒が、真のキーダウン時間そのものではない点である。この値には MMDVM 側のウォッチドッグタイムアウト(約 2 秒)が上乗せされるため、実際には短いカーチャンクであっても 2〜3 秒として記録される。したがって擬似終端経路の閾値は、通常 EOT 経路とは別の特性を前提に設計する必要がある。
「壊れた受信」を弾くパケットロスガード
ただし、ウォッチドッグ満了を一律に擬似終端として拾うと、実際には途切れて用をなさない受信まで応答対象になってしまう。そこで、ウォッチドッグ行に記録されるパケットロス率に上限を設け、それを超える受信は「壊れていて意味をなさない」とみなして救済しない、というガードを設けた。当初はロス 50% 以下のみを救済していたが、実ログのロスがおおむね 31〜75% に分布していたため、後に上限を 75% まで緩めて拾える範囲を広げている(値は運用しながら調整できる一例)。
途中参加(late entry)の救済
さらに、ヘッダを取りこぼした途中参加の送信(late entry)についても、開始イベントとして扱えるよう拡張した。これにより、それまで完全に捨てられていた頭欠けの送信も、後続の終端またはウォッチドッグ満了で判定に乗るようになった。ただし late entry は先頭が欠けているため、受信時間は実際のキーダウンより短めに算出される点に留意が必要である。
いつでも従来動作に戻せる
これらの擬似終端救済は、設定ひとつで一括して無効化できるようにしてある。無効にすれば、終端検出は通常の EOT のみに戻り、改修前と完全に同一の挙動になる。対症療法を入れつつ、必要ならすぐ元へ戻せる状態を保っている。
結果
Semi Repeater Mode 下でも、短点送信に対する音声 ID が再び正しく出るようになった。終端フレームが欠けても、ウォッチドッグの満了をもう一つの「終わりの合図」として扱えるからだ。
広げすぎることのトレードオフ
なお、救済範囲を広げるほど拾える短点は増えるが、その分だけ過剰応答のリスクも上がる。ロス率の高いブツ切れ受信や混信の断片にまで反応しうるため、実際の運用ログを見ながら、ロス上限や受信時間の下限を調整して落としどころを探る必要がある。擬似終端はあくまで、根治(ファーム側の修正)までの間口を広げる対症療法である。
教訓
直せないハードのバグは、ソフトの側で吸収できることがある。ただし吸収と並行して、上流(メーカー)への報告も忘れない——擬似終端はあくまで対症療法であり、根治はファーム側の修正だ。
次回予告
次回は、同じ Semi Repeater Mode で踏んだもう一つの罠、TG1 が別 TG へ書き換わる「TG リマップ問題」を取り上げる。
🏛 JJ2YYK あいちデジタルコミュニケーションハムクラブ