バイナリ構造応答

「バイナリ構造応答」は、メッセージ構造定義で定義した構造体に基づき、フィールドの値で応答を出し分ける機能です。固定ヘッダ+ペイロードのようなバイナリプロトコルで、コマンド種別やアドレス値ごとに異なるバイナリ応答を返す場面で使います。

テキストや HEX バイト列の単純な条件マッチと応答(ExactContainsRegexHexPattern)については、「オートメーション」の「受信して返す」プリセットを使ってください(→ オートメーション)。

構造体ルールとは

構造体ルールは、受信したバイナリメッセージを構造体定義でパースし、フィールドの値が条件に一致したときに応答を返すルールです。

設定はセッション画面の「バイナリ構造応答」タブで行います。

前提:構造体定義の用意

構造体ルールを使う前に、メニューバーの 「プロジェクト」→「構造体定義…」 で対象プロトコルの構造体定義を作成しておく必要があります。構造体定義の作り方・フィールドの種類・フレーミング・エンディアン設定は メッセージ構造定義 を参照してください。

構造体ルールを作る

  1. 「自動応答」タブを開きます(②バイナリ構造応答)。
  2. 「追加」 をクリックすると、構造体ルール編集ダイアログが開きます。
  3. 各項目を設定して OK を押すと、一覧に追加されます。
  4. 既存ルールを変更するには行を選択して 「編集」、または行をダブルクリックします(「有効」チェック列の上を除く)。削除は 「削除」 です。
  5. 編集ウィンドウは開いたままセッション画面を操作できます。受信ログを見ながらフィールド条件や応答テンプレートを組み立てられます(ウィンドウの移動・サイズ変更もでき、大きさは次回も引き継がれます)。
  6. 一覧の 「有効」 チェックで個別に有効/無効を切り替えられます。
  7. 行を右クリックすると「編集」「削除」「有効/無効」のメニューが出ます(右クリックした行が操作対象になります)。

構造体ルール編集ダイアログの項目

基本

項目説明
名前ルールの識別名
優先度小さいほど先に評価。例: 10100 より優先
有効チェックで評価対象にする
参照する構造体定義受信パースに使う構造体定義を選択(プロジェクト内で定義済みのものが列挙される)
応答遅延(ms)応答を返すまでの待ち時間(0 で即時)

フィールド条件

フィールド条件を1つ以上設定します。すべての条件を満たしたときにマッチします(AND 条件)。

項目説明
フィールド名条件を評価するフィールドの名前(例: CommandHeader.FunctionCode
演算子等しい / 等しくない / より大きい / より小さい / 以上 / 以下(= > <
比較する値(10進、または 0x10 の 16 進表記)

フィールド名はフラットな表記(Command / Header.Command)を使います。構造体エディタの「フィールド名」列で確認できます。

応答テンプレート

受信した構造体のフィールド値や計算値をプレースホルダで埋め込んで応答バイト列を組み立てます。

プレースホルダ展開される値
{field:NAME}受信構造体のフィールド(NAME)の生バイト
{len:N}応答全体のバイト長を N バイトで埋める(プロジェクトのエンディアン)
{crc:KIND}それ以前のバイト列のチェックサム(Crc16Ccitt / Crc16Modbus / Sum8 / Sum16 / Xor8 など)
{echo:OFF:LEN}受信バイト列のオフセット OFF から LEN バイトをそのまま埋め込む

記述例:

AA {field:cmd} {len:2} {crc:Crc16Ccitt}

構文チェック」ボタンでテンプレートの妥当性を保存前に確認できます。

評価の仕組み

  • 構造体ルールは優先度の小さい順に評価されます。
  • 受信データに最初にマッチしたルールの応答が返されます(先勝ち)。
  • どのルールにもマッチしない場合は、応答しません。
  • 無効化されたルールは評価対象外です。

パケット一致トリガーのオートメーションが発動した受信データに対しては、バイナリ構造応答は評価されません(オートメーションが先勝ちします)。

リプレイ中はバイナリ構造応答が止まります

受信に応答を返す仕組みは「オートメーション+バイナリ構造応答」か「リプレイ」のどちらか片方だけが動きます。リプレイを再生している間は、フィールド条件にマッチしても構造体ルールは応答しません(二重応答を防ぐためです)。

再生中は「自動応答」タブのヘッダに「停止中」バッジが付き、タブを開くと案内バーが出ます。「ルールが有効なのに応答が返らない」ときは、まずここを確認し、必要ならバー内の「リプレイを停止」(またはヘッダの「リプレイを停止」)で通常動作へ戻してください。

手を動かして見る:複数ルールの優先度・重複・キャッチオールと、パケット一致オートメーションによる層間抑止を、同梱サンプルでひととおり観察できるチュートリアル → ルールの優先度・重複・層間競合

設定例

ケース 1: Modbus FC03/FC04 の出し分け

同梱サンプル samples/modbus-tcp/modbus-tcp.commsim(ポート 502)は、FC(ファンクションコード)フィールドの値で応答を切り替える構造体ルールの実例です。試し方は Modbus-TCP を参照してください。

設定のイメージ:

ルール 1(優先度 10)
  対象構造体定義 : ModbusTCPRequest
  フィールド条件 : FunctionCode = 0x03
  応答テンプレート: 00 01 00 00 00 05 01 03 02 {field:StartAddr} {crc:Crc16Modbus}

ルール 2(優先度 20)
  対象構造体定義 : ModbusTCPRequest
  フィールド条件 : FunctionCode = 0x04
  応答テンプレート: 00 01 00 00 00 05 01 04 02 FF FF {crc:Crc16Modbus}

ケース 2: コマンド値で応答を出し分け+受信フィールドをエコー

Command(u8)と Address(u16)を含む 4 バイト固定長メッセージを受信し、コマンド値によって異なる応答を返す例です。

前提の構造体定義(構造体名: CmdRequest):

フィールド名役割
Commandu8Discriminator
Addressu16None
Reservedu8None

ルール 1: コマンド 0x10(読み取り要求)→ アドレスをエコーして応答

項目設定値
名前ReadResponse
優先度10
参照する構造体定義CmdRequest
フィールド条件Command = 0x10
応答テンプレート90 {field:Address} 00 01 {len:1} {crc:Crc16Ccitt}
  • {field:Address} … 受信した Address フィールドの 2 バイトをそのままエコー
  • {len:1} … 応答全体の長さ(この例では len・crc 込みで 8 バイト)を 1 バイトで埋める
  • {crc:Crc16Ccitt} … 直前までの CRC-16/CCITT を付加

ルール 2: コマンド 0x20(書き込み要求)→ 固定の ACK を返す

項目設定値
名前WriteAck
優先度20
参照する構造体定義CmdRequest
フィールド条件Command = 0x20
応答テンプレートA0 00 00 {crc:Sum8}
  • {crc:Sum8} … 直前までの各バイトの合計の下位 1 バイトを付加

ケース 3: 範囲条件+受信データのエコーを組み合わせた応答

アドレスが 0x00000x00FF の範囲内なら応答し、それ以外は無応答(マッチなし)にする例です。

項目設定値
名前AddressRangeResponse
優先度30
参照する構造体定義CmdRequest
フィールド条件Address ≥ 0 かつ Address ≤ 255(≥ と ≤ の 2 条件を設定し AND で評価)
応答テンプレートB0 {echo:1:2} 01 {crc:Xor8}
  • {echo:1:2} … 受信バイト列のオフセット 1 から 2 バイト(Address 部分)をそのまま埋め込む
  • {crc:Xor8} … 直前までの XOR チェックサムを付加

複数のフィールド条件はすべて満たした場合(AND)にマッチします。範囲は「≥」と「≤」の 2 条件を組み合わせて表現します。

次に読む