第 5 章 ネゴシエーション機構

5.1 ネゴシエーションの原則

DTP 実装は以下のネゴシエーションの原則を強制 しなければならない

  1. ネゴシエーション優先:いかなる Fragment データ伝送の前にも、状態が active の Agreement が 必ず 存在 しなければならない
  2. 裸伝送の禁止:実装は Agreement に基づかないデータ伝送を許可 してはならない
  3. 双方向ネゴシエーション:Master はデータ収集ネゴシエーションを発起 してもよい。Slave はデータ注入ネゴシエーションを発起 してもよい
  4. 動的調整:双方は Agreement が active 状態のときにそのパラメータを調整 してもよい
  5. 明示的終了:双方は Agreement を明示的に終了 してもよい。終了後はその Agreement に基づくデータ伝送を直ちに停止 しなければならない

5.2 ネゴシエーションフレームタイプ

ネゴシエーションは Request_Frame と Response_Frame の 2 種類のフレームタイプを通じて完了 しなければならない

5.2.1 Request_Frame

Request_Frame は以下のフィールドを含 まなければならない

interface RequestFrame {
  frameType: "request";
  requestId: string;
  requestorRole: "master" | "slave";
  requestType: "collection" | "injection" | "adjustment" | "termination";
  targetAgreementId?: AgreementID;
  proposedParams: AgreementParams;
}
フィールド規範的要件
frameTypeリテラル "request"なければならない
requestIdリクエストの一意識別子で なければならない。UUID v4 を使用 すべきである
requestorRole"master" または "slave"なければならず、リクエスト発起側を識別する
requestType下表の 4 種類のいずれかで なければならない
targetAgreementIdrequestType"adjustment" または "termination" の場合、提供 しなければならない
proposedParams完全な AgreementParams を提供 しなければならない(第 5.4 節を参照)

5.2.2 RequestType

意味制約
"collection"データ収集リクエストrequestorRole = "master" により発起 されなければならない
"injection"データ注入申請requestorRole = "slave" により発起 されなければならない
"adjustment"既存 Agreement の調整targetAgreementId を提供 しなければならず、対象 Agreement は active 状態で なければならない
"termination"既存 Agreement の終了targetAgreementId を提供 しなければならない

実装は上記の制約を満たさないリクエストを拒否し、対応するエラーを返 さなければならない(第 9 章を参照)。

5.2.3 Response_Frame

Response_Frame は以下のフィールドを含 まなければならない

interface ResponseFrame {
  frameType: "response";
  requestId: string;
  result: NegotiationResult;
  agreedParams?: AgreementParams;
  agreementId?: AgreementID;
  rejectionReason?: string;
}
フィールド規範的要件
frameTypeリテラル "response"なければならない
requestId対応する Request_Frame の requestIdなければならない
resultNegotiationResult のいずれかで なければならない
agreedParamsresultaccepted または counter_proposal の場合、提供 しなければならない
agreementIdresultaccepted の場合、提供 しなければならず、新しく生成した UUID v4 で なければならない
rejectionReasonresultrejected の場合、提供 しなければならない

5.2.4 NegotiationResult

NegotiationResult は以下の 3 つの値のいずれかで なければならない

意味
"accepted"リクエストを受け入れる
"rejected"リクエストを拒否する
"counter_proposal"代替案を提示する

実装は列挙されていない結果値を返 してはならない

5.3 ネゴシエーションフロー

5.3.1 データ収集ネゴシエーション(Master 発起)

データ収集ネゴシエーションは以下のフローに従わ なければならない

  1. Master は Request_Frame を送信する。requestType = "collection"requestorRole = "master"
  2. Slave は Response_Frame で応答 しなければならず、以下の 3 つの結果のいずれかを含む:
    • "accepted"proposedParams に従って伝送することに同意する。Response_Frame には新しく生成された agreementId を含 まなければならない
    • "rejected":伝送を拒否する。rejectionReason でコンプライアンス制約(例:DLP ポリシー)を説明 しなければならない。コンプライアンス以外の理由で拒否 してはならない
    • "counter_proposal":代替パラメータを提示する。agreedParams で修正されたパラメータを提供 しなければならない
  3. Slave が counter_proposal で応答した場合、Master は新しい Request_Frame を送信して受け入れ、拒否、またはネゴシエーションを継続 してもよい
  4. Master は各データ収集リクエストに対する Slave の応答結果を永続的に記録 しなければならない

5.3.2 データ注入ネゴシエーション(Slave 発起)

データ注入ネゴシエーションは以下のフローに従わ なければならない

  1. Slave は Request_Frame を送信する。requestType = "injection"requestorRole = "slave"
  2. Master は Response_Frame で応答 しなければならず、以下の 3 つの結果のいずれかを含む:
    • "accepted":データ提供に同意する。agreedParams でフィルタリングされたデータ範囲(最小化データセット)を説明 しなければならない。Response_Frame には新しく生成された agreementId を含 まなければならない
    • "rejected":データ提供を拒否する。rejectionReason で理由を説明 すべきである
    • "counter_proposal":異なる範囲または形式のデータを提供する。agreedParams で代替案を説明 しなければならない
  3. Master はデータ注入の決定において完全な決定権を有 さなければならず、リクエストの受け入れを強制されては ならない

5.3.3 ネゴシエーションタイムアウト

実装は Request_Frame に対してタイムアウト閾値を設定 しなければならない。閾値内に対端の Response_Frame を受信できなかった場合:

  1. リクエスト側は Request_Frame を再送 すべきである。再試行回数は実装が設定する上限を超えて はならない
  2. 再試行上限に達した後、リクエスト側はネゴシエーションを終了し、上位アプリケーションに AGREEMENT_NEGOTIATION_FAILED エラー(3003)を通知 しなければならない

5.4 Agreement パラメータ(AgreementParams)

AgreementParams は以下のフィールドを含 まなければならない

interface AgreementParams {
  dataType: string;
  dataRange: string;
  transferMode: TransferMode;
  frequency: number | null;
  validityPeriod: number;
  priority: Priority;
}
フィールド規範的要件
dataTypestring空でなくて はならない。データタイプを識別する
dataRangestring空でなくて はならない。データ範囲を記述する
transferModeTransferMode下表の 3 つの値のいずれかで なければならない
frequencynumber | null単位は Hz。transferMode = "one_time" の場合は null で なければならず、その他のモードでは正の数で なければならない
validityPeriodnumber単位はミリ秒。正の整数で なければならない
priorityPriority下表の 4 つの値のいずれかで なければならない

5.4.1 TransferMode

意味
"one_time"一回限りの伝送。Agreement はデータ伝送完了後に自動的に終了 すべきである
"periodic"周期的伝送。frequency を設定 しなければならない
"streaming"ストリーミング伝送。frequency を設定 しなければならない

5.4.2 Priority

意味
"low"低優先度
"normal"通常優先度(デフォルト)
"high"高優先度
"critical"緊急優先度

実装は複数の Agreement がリソースを競合する場合、priority に従ってスケジューリング すべきである

5.5 Agreement のライフサイクル

5.5.1 状態の定義

AgreementStatus は以下の 4 つの値のいずれかで なければならない

状態意味
"negotiating"ネゴシエーション進行中
"active"Agreement が有効、データ伝送中
"suspended"接続中断、Agreement 一時停止中
"terminated"Agreement 終了

5.5.2 状態遷移

Agreement の状態は以下の遷移規則に従わ なければならない

現在の状態トリガイベント遷移先状態
(なし)Request_Frame 発行negotiating
negotiatingResponse_Frame で accepted を返却active
negotiatingResponse_Frame で rejected を返却(終了)
active下位接続が切断suspended
activetermination タイプの Request_Frame を受信terminated
activevalidityPeriod がタイムアウトterminated
suspended接続復旧かつ CAP 再検証通過active
suspended永続化タイムアウトterminated
terminated(終端状態)(なし)

5.5.3 一回限り Agreement の自動終了

transferMode = "one_time" かつデータ伝送が完了した場合:

  1. 送信側は最後の Fragment の後、requestType = "termination" の Request_Frame を介してその Agreement を終了 しなければならない
  2. 受信側は全 Fragment を受信し確認した後、Agreement の状態を terminated に設定 しなければならない

5.6 複数 Agreement の並行

DTP 実装は単一セッション内で active 状態の複数の Agreement を同時に維持することをサポート しなければならない

実装は以下を満たさ なければならない

  1. 各 Fragment は自身の Agreement_ID を介して具体的な Agreement に関連付けられる。
  2. 異なる Agreement の Fragment は伝送ストリーム内で交錯 してもよい
  3. 複数 Agreement の実際の伝送方式(直列または並列)は下位 Transport_Adapter の能力に 依存する
  4. 実装は単一セッション内のアクティブな Agreement の最大数を 16 未満に制限 してはならない。任意の数をサポート すべきである

5.7 Observer のネゴシエーション制限

Observer 役割は以下を満たさ なければならない

  1. Request_Frame を送信 してはならない。送信を試みた場合、DTP_Engine はその操作を拒否し OBSERVER_WRITE_DENIED エラー(8002)を返 さなければならない
  2. いかなる Response_Frame の決定権も受け取って はならない
  3. データフレームの読み取り専用コピーを受信 してもよい
  4. Observer として参加する際、Controller により明示的に認可 されなければならない