第 3 章 プロトコルアーキテクチャ

3.1 プロトコル階層

DTP 実装は以下の階層構造に従って組織しなければならない

+-----------------------------------------------+
|           アプリケーション層 (Application Layer) |
|   iFay / coFay / Personal Data Heap            |
|   端末アプリケーション                            |
+-----------------------------------------------+
|           DTP プロトコル層 (DTP Protocol Layer) |
|   DTP_Engine (DTP_Master / DTP_Slave)         |
|   - Agreement Manager                          |
|   - Frame Codec                                |
|   - DAG Manager                                |
|   - Encryption Module                          |
|   - Session Manager                            |
|   - Resume Manager                             |
+-----------------------------------------------+
|           アダプタ層 (Adapter Layer)            |
|   Transport_Adapter                            |
+-----------------------------------------------+
|           伝送層 (Transport Layer)              |
|   BLE / WebSocket / TCP / RTSP / ...           |
+-----------------------------------------------+

実装は層を跨いだ呼び出しを行ってはならない(例:アプリケーション層がアダプタ層のインタフェースを直接呼び出す等)。

3.2 コアコンポーネント

DTP_Engine は以下の 6 つのコアコンポーネントを含まなければならない

3.2.1 Agreement Manager(ネゴシエーションマネージャ)

Agreement Manager は以下の機能を提供しなければならない

  1. ネゴシエーションフロー管理:Request_Frame および Response_Frame の送受信を処理する。
  2. Agreement ライフサイクル管理:Agreement の negotiating から terminated までの状態遷移を維持する。
  3. 一意識別子の生成:合意に至った Agreement ごとに、RFC 4122 準拠の UUID v4 を Agreement_ID として生成する。
  4. 複数 Agreement 並行サポート:1 つのセッション内で複数のアクティブな Agreement を同時に維持することをサポートしなければならない

3.2.2 Frame Codec(フレームコーデック)

Frame Codec は以下の機能を提供しなければならない

  1. シリアライズ:LogicalFrame オブジェクトをバイナリバイト列にエンコードする。
  2. デシリアライズ:バイナリバイト列を LogicalFrame オブジェクトにデコードする。
  3. ラウンドトリップ整合性:任意の有効な LogicalFrame オブジェクトについて、シリアライズ後再度デシリアライズすると元のオブジェクトと等価な LogicalFrame を生成しなければならない
  4. 整形出力(Pretty Printer):LogicalFrame を人間可読なテキストに変換する機能を提供すべきであり、ヘッダー内のすべての主要フィールドを含むべきである

3.2.3 DAG Manager(DAG マネージャ)

DAG Manager は以下の機能を提供しなければならない

  1. 循環検出:Fragment が DAG に追加される前に循環を形成しないことを検証しなければならない。循環を検出した場合、その Fragment を拒否し DAG_CYCLE_DETECTED エラー(4001)を返さなければならない
  2. 依存解決:Fragment が宣言した依存対象がまだ到着していない場合、その Fragment を「依存解決待ち」状態としてマークし、キャッシュしなければならない
  3. 遅延解決:依存対象の Fragment が到着した後、以前にキャッシュされた Fragment を自動的に解決しなければならない
  4. 関係タイプサポートderived_fromannotatessupersedes の 3 種類の関係タイプをサポートしなければならない

3.2.4 Encryption Module(暗号化モジュール)

Encryption Module は以下の機能を提供しなければならない

  1. ペイロード暗号化:CAP で事前ネゴシエーションされた鍵を用いてペイロードを暗号化する。
  2. ペイロード復号:CAP で事前ネゴシエーションされた鍵を用いて受信したペイロードを復号する。
  3. 鍵レディチェック:暗号化操作の前に CAP が鍵交換を完了していることを検証しなければならない
  4. 暗号化メタデータ生成:暗号化メタデータ(アルゴリズム識別子と鍵バージョン番号)を平文の形式でフレームヘッダーに含まなければならない

3.2.5 Session Manager(セッションマネージャ)

Session Manager は以下の機能を提供しなければならない

  1. セッションライフサイクル管理:セッションの確立、維持、クローズ。
  2. 状態の永続化:下位接続が中断したとき、セッション状態を永続化しなければならない
  3. 状態の復元:接続が復旧し CAP が再検証を通過した後、以前のセッション状態を復元できるようにしなければならない
  4. タイムアウト検出:セッションのアイドルタイムアウト検出を実装しなければならない

3.2.6 Resume Manager(再開マネージャ)

Resume Manager は以下の機能を提供しなければならない

  1. シーケンス番号の割り当て:送信する各 Fragment に単調増加のシーケンス番号を割り当てる。
  2. 未確認キャッシュ:受信側からまだ確認応答を受け取っていない Fragment をローカルキャッシュする。
  3. 中断点の報告:接続復旧時に、対端へ受信に成功した最高シーケンス番号を報告する。
  4. キャッシュ管理:キャッシュ容量の上限検出を実装しなければならない。キャッシュが上限に達した場合、送信を一時停止し BUFFER_FULL エラー(6001)を返さなければならない

3.3 状態機械

DTP_Engine は以下の状態機械を実装しなければならない

                 [Idle]
                    |
                    | 接続要求を受信
                    v
             [WaitingForCAP]
                    |
                    | CAP 検証 + 鍵交換完了
                    v
             [SessionEstablished]
                    |
                    | Request_Frame を発行または受信
                    v
              [Negotiating]
                    |
                    | Agreement 成立
                    v
              [Transmitting]
                    |
                    | 接続中断
                    v
                [Suspended]
                    |
                    | 接続復旧 + CAP 再検証
                    v
                [Resuming]
                    |
                    | 再開ハンドシェイク完了
                    v
              [Transmitting]

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

現在の状態トリガイベント遷移先状態備考
Idle接続要求を受信WaitingForCAP
WaitingForCAPCAP 検証 + 鍵交換完了SessionEstablished
WaitingForCAPCAP 失敗またはタイムアウトIdle関連リソースを解放しなければならない
SessionEstablishedRequest_Frame を発行または受信Negotiating
SessionEstablishedセッションタイムアウトIdleセッションをクローズしなければならない
NegotiatingAgreement 成立Transmitting
Negotiatingネゴシエーション失敗または拒否SessionEstablished
TransmittingFragment の継続伝送Transmitting自己ループ
Transmittingadjustment タイプの Request_Frame を受信Negotiating
Transmitting下位接続が切断Suspendedセッション状態を永続化しなければならない
TransmittingAgreement 終了かつ他のアクティブ Agreement なしSessionEstablished
Suspended接続復旧かつ CAP 再検証通過Resuming
SuspendedセッションタイムアウトIdleリソースを解放しなければならない
Resuming再開ハンドシェイク完了Transmitting
Resuming復元失敗Idleセッションをクローズしなければならない

実装は上表に列挙されていない状態遷移を導入してはならない

3.4 Transport_Adapter インタフェース

Transport_Adapter は以下のインタフェースを提供しなければならない

interface Transport_Adapter {
  // 接続管理
  connect(endpoint: TransportEndpoint): Connection;
  disconnect(connectionId: ConnectionID): void;

  // データ伝送
  send(connectionId: ConnectionID, data: Uint8Array): void;
  onReceive(handler: (connectionId: ConnectionID, data: Uint8Array) => void): void;

  // 状態イベント
  onConnectionStateChange(handler: (connectionId: ConnectionID, state: ConnectionState) => void): void;
}

Transport_Adapter の具体的な実装は以下の規範的要件を満たさなければならない

  1. send() 操作はノンブロッキングでなければならない
  2. 下位接続の状態に変化が発生した場合、onConnectionStateChange コールバックを介して DTP_Engine に通知しなければならない
  3. サポートする各伝送プロトコル(BLE、WebSocket、TCP、RTSP)に対し、統一されたインタフェース実装を提供しなければならない
  4. DTP_Engine から渡されたバイナリデータを変更してはならない

3.5 マスター・スレーブインタラクションのシーケンス

完全な DTP インタラクションは以下の 5 段階に従わなければならない

段階 1:CAP 前処理

DTP_Engine は CAP が身元検証と鍵交換を完了するのを待たなければならない。この段階で、DTP はいかなるデータフレームも送信してはならない

段階 2:DTP セッション確立

CAP 完了後、DTP_Engine は一意な Session_ID(UUID v4)を生成し、SessionEstablished 状態に遷移しなければならない

段階 3:ネゴシエーション

段階 3a(データ収集ネゴシエーション):Master は requestType = collection の Request_Frame を送信してもよく、Slave は Response_Frame を介して acceptedrejected、または counter_proposal のいずれかで応答しなければならない

段階 3b(データ注入ネゴシエーション):Slave は requestType = injection の Request_Frame を送信してもよく、Master は Response_Frame で応答しなければならない

段階 4:データ伝送

Agreement 成立後、送信側はデータフレームを介して Fragment を送信しなければならず、各 Fragment はそれが属する Agreement_ID を携帯しなければならない(またはコンテキストを継承するため省略する。第 4.5 節を参照)。

段階 5:接続中断と復旧

下位接続が中断した際、DTP_Engine は Suspended 状態に遷移し、セッションを永続化しなければならない。接続復旧後、CAP を介して再検証しなければならず、その後 Resuming 状態に入って再開ハンドシェイクを完了する。