バイナリ構造応答
「バイナリ構造応答」は、メッセージ構造定義で定義した構造体に基づき、フィールドの値で応答を出し分ける機能です。固定ヘッダ+ペイロードのようなバイナリプロトコルで、コマンド種別やアドレス値ごとに異なるバイナリ応答を返す場面で使います。
テキストや HEX バイト列の単純な条件マッチと応答(Exact・Contains・Regex・HexPattern)については、「オートメーション」の「受信して返す」プリセットを使ってください(→ オートメーション)。
構造体ルールとは
構造体ルールは、受信したバイナリメッセージを構造体定義でパースし、フィールドの値が条件に一致したときに応答を返すルールです。
設定はセッション画面の「バイナリ構造応答」タブで行います。
前提:構造体定義の用意
構造体ルールを使う前に、メニューバーの 「プロジェクト」→「構造体定義…」 で対象プロトコルの構造体定義を作成しておく必要があります。構造体定義の作り方・フィールドの種類・フレーミング・エンディアン設定は メッセージ構造定義 を参照してください。
構造体ルールを作る
- 「自動応答」タブを開きます(②バイナリ構造応答)。
- 「追加」 をクリックすると、構造体ルール編集ダイアログが開きます。
- 各項目を設定して OK を押すと、一覧に追加されます。
- 既存ルールを変更するには行を選択して 「編集」、または行をダブルクリックします(「有効」チェック列の上を除く)。削除は 「削除」 です。
- 編集ウィンドウは開いたままセッション画面を操作できます。受信ログを見ながらフィールド条件や応答テンプレートを組み立てられます(ウィンドウの移動・サイズ変更もでき、大きさは次回も引き継がれます)。
- 一覧の 「有効」 チェックで個別に有効/無効を切り替えられます。
- 行を右クリックすると「編集」「削除」「有効/無効」のメニューが出ます(右クリックした行が操作対象になります)。
構造体ルール編集ダイアログの項目
基本
| 項目 | 説明 |
|---|---|
| 名前 | ルールの識別名 |
| 優先度 | 小さいほど先に評価。例: 10 は 100 より優先 |
| 有効 | チェックで評価対象にする |
| 参照する構造体定義 | 受信パースに使う構造体定義を選択(プロジェクト内で定義済みのものが列挙される) |
| 応答遅延(ms) | 応答を返すまでの待ち時間(0 で即時) |
フィールド条件
フィールド条件を1つ以上設定します。すべての条件を満たしたときにマッチします(AND 条件)。
| 項目 | 説明 |
|---|---|
| フィールド名 | 条件を評価するフィールドの名前(例: Command、Header.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):
| フィールド名 | 型 | 役割 |
|---|---|---|
| Command | u8 | Discriminator |
| Address | u16 | None |
| Reserved | u8 | None |
ルール 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: 範囲条件+受信データのエコーを組み合わせた応答
アドレスが 0x0000〜0x00FF の範囲内なら応答し、それ以外は無応答(マッチなし)にする例です。
| 項目 | 設定値 |
|---|---|
| 名前 | 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 条件を組み合わせて表現します。
次に読む
- 構造体定義の作り方 → メッセージ構造定義
- テキスト/HEX の条件応答 → オートメーション
- 中継と記録 → 中継とキャプチャ
- 優先度・重複・層間競合を実際に動かして確認 → ルールの優先度・重複・層間競合(チュートリアル)