Talker Alias 表示引きずりの謎 ─ 送信は正しいのに表示が違う
カテゴリ: ハマりどころ / OpenCCVoice / DVSwitch タグ: DMR, Talker Alias, Analog_Bridge, MMDVMHost, 埋め込みLC
音質と MD-619 のハング問題は解決しました。次に浮上したのは、無線機の表示に関する謎です。
症状
JJ2ZAR が カーチャンクして、OCV が応答すると、無線機の表示が JJ2YYK ではなく JJ2ZAR のまま。
しかし Pi-Star のダッシュボードでは、OCV の応答は正しく JJ2YYK として記録されています。ロス 0%、BER 0.0%、ID も 4402396。数値上は完璧です。
だが RF で受信している側の無線機表示が、直前に カーチャンクした局のコールサインを引きずってしまう。しかも複数の受信機・複数の経路で同じ症状が出ます。
仮説X:Analog_Bridge がメタデータを保持している
最初の仮説は「Analog_Bridge が『最後に聞いた局』のコールサインをメタデータとして保持し、次の送信の Talker Alias(TA、ストリーム埋め込みの文字列)に埋め込んでいる」というものでした。DVSwitch は元々「最後に聞いた人が次に話す」というシンプルな会話モデルで設計されているので、こういう挙動があってもおかしくありません。
V1.90 で対策として、自局アイデンティティを 三重に主張するように変更しました。
- 起動時に SET_INFO
- 他局の受信が終わるたびに SET_INFO
- 送信直前に SET_INFO(V1.83 から継続)
これで AB の「最後に聞いた局」状態を毎回上書きできる、はず。しかし Analog_Bridge のログを確認すると、驚く事実が。
I: USRP packet type: USRP_TYPE_TEXT (JJ2YYK) -> 4402396
AB は SET_INFO を確かに受理していた。 V1.83 の実装は届いていました。それでも表示は引きずる。仮説X では説明できません。
Talker Alias を直接デコードする
判決を下すには、ストリームに実際に埋め込まれた Talker Alias を直接読むしかありません。DMR の埋め込み LC は 4フレームにわたって断片が送られ、デインタリーブ → Hamming(16,11,4) FEC → 5bit CRC の処理で 128bit のデータを組み立てる複雑な構造です。
MMDVMHost(DMR ゲートウェイのオープン実装)の該当コード(DMREmbeddedData.cpp、Hamming.cpp、CRC.cpp)を Python に移植し、emblc.py として作成しました。前回紹介した dmrd_analyze.py に統合します。
検証として、実キャプチャの断片で「dst=44833 src=4402519」(既知の JJ2ZAR ストリーム)を復元できることを確認しました。実装は正しく動いています。
そして OCV のストリームを解析すると。
埋め込みLC/TA デコード:
GroupLC dst=44833 src=4402396 x23
TA_Header data=764a4a3259594b x6
TA_Block1 data=20416963686950 x6
TA_Block2 data=726566204a6170 x6
TA_Block3 data=616e204d4d4456 x5
★ Talker Alias = 'JJ2YYK AichiPref Japan MMDV' (format=ISO8859-1, len=27)
OCV のストリームは、Talker Alias まで完全に正しい JJ2YYK です。 しかも中身は MMDVM_Bridge.ini の Callsign + Location + Description そのもの。TA は MMDVM_Bridge が自分の ini から生成しています。
仮説Y:受信機側の途中参加処理
仮説X は完全棄却です。では何が原因か。
新しい仮説:TGIF がヘッダを食うため、無線機は「途中参加」で受信を始めます。途中参加時に発信者表示を更新しない機種は、直前の表示(= カーチャンクした JJ2ZAR)を保持し続ける。
これで説明がつきます。ストリームには埋め込み LC で正しい src と TA が繰り返し流れているのに、無線機がそれを「新しい発信者情報」として反映しない。特にディスプレイなし機や、古いファームの機種で顕著と思われます。
同じストリームでも、途中参加をきちんと処理する新しい機種なら、数秒後に表示は JJ2YYK に更新されるはずです。逆に、旧いファームや廉価機は「途中から入った信号は前の情報のまま」で走ってしまう。
結論と対応
ボット側に修正すべきものはありません。 送出内容は電波レベルで正しいことが証明されました。
Talker Alias 表示引きずりは「見た目だけの問題」で、ダッシュボード、Last Heard、ログはすべて正しく JJ2YYK として記録されます。実運用上の実害はありません。
V1.90 で実装した「自局アイデンティティの三重主張」は、結果的には「無害だが不要」と判明しました。ただし将来 Analog_Bridge の実装が変わったときの保険として、そのまま残しています。
教訓
症状の原因が「送信側」か「受信側」かを確定するには、実際のパケットまで降りる必要があります。 ダッシュボード表示は途中で加工されているので、判断材料にできない。RF で流れているビット列そのものを見るしかありません。
MMDVMHost のコードを Python に移植した Talker Alias デコーダは、この判決のためだけに実装しました。1回きりの分析ツールでしたが、これがなければ「Analog_Bridge を疑い続けて時間を無駄にする」という結果になっていたはずです。
曖昧な仮説を数時間追うより、確実に判定するツールを1時間で作った方が早い、という判断でした。オープン実装のありがたみをしみじみと感じました。MMDVMHost のコードが公開されていなければ、この移植はできませんでした。
副産物
この過程で作った emblc.py は、汎用の Talker Alias デコーダとして再利用可能です。DMR のストリーム内容を確認したい他のプロジェクトでも、そのまま使えます。
将来、DMR 系のトラブルシューティングで「送信は正しいのに受信側の表示が変」という状況に遭遇したら、まず埋め込み LC をデコードして「送信内容が本当に正しいか」を確定させてください。そこで正しいと確認できたら、それ以降は受信機側の問題として扱う判断ができます。
続きは最終回、並行制御の落とし穴について。
🏛 JJ2YYK あいちデジタルコミュニケーションハムクラブ
お疲れ様です。
AnalogBridgeの怪挙動を興味深く拝読しました。
さて、OpenGD77(MD9600,RT3S)のAPRSパケットはTalkerAliasで送出されてます。
TGIFでは記事の様に無理ですが、XLXdにDVSwitchを収容すれば、XLXDMRからAPRS網にパケット送出されるだろうなぁと思いました。
引き続き、宜しくお願いします。