@kubohiroya/turbowarp-webrtc-qrcode-pairing 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.ja.md +122 -0
- package/README.md +414 -0
- package/dist/extension-manifest.json +318 -0
- package/dist/webrtc-qrcode-pairing.js +4064 -0
- package/docs/architecture.ja.md +57 -0
- package/docs/architecture.md +65 -0
- package/docs/design/qr-pairing/README.md +16 -0
- package/docs/design/qr-pairing/architecture.md +191 -0
- package/docs/design/qr-pairing/block-api.md +123 -0
- package/docs/design/qr-pairing/dataflow.md +202 -0
- package/docs/design/qr-pairing/extraction-plan.md +134 -0
- package/docs/design/qr-pairing/interfaces.ts +473 -0
- package/docs/design/qr-pairing/requirements.md +152 -0
- package/docs/design/qr-pairing/test-plan.md +126 -0
- package/docs/index.html +34 -0
- package/docs/initialization-issue.ja.md +34 -0
- package/docs/integration-guide.ja.md +245 -0
- package/docs/integration-guide.md +258 -0
- package/docs/migration.ja.md +110 -0
- package/docs/migration.md +115 -0
- package/package.json +90 -0
- package/schemas/extension-manifest.schema.json +49 -0
- package/src/block-definitions.json +264 -0
- package/src/clock.ts +18 -0
- package/src/config/feature-flags.ts +18 -0
- package/src/config/qr-config.ts +22 -0
- package/src/config.ts +12 -0
- package/src/errors.ts +51 -0
- package/src/extension-manifest.ts +149 -0
- package/src/extension.ts +281 -0
- package/src/globals.d.ts +54 -0
- package/src/index.ts +8 -0
- package/src/pairing/controller.ts +836 -0
- package/src/pairing/limits.ts +12 -0
- package/src/pairing/types.ts +96 -0
- package/src/ports/display.ts +136 -0
- package/src/ports/qr-scan.ts +151 -0
- package/src/ports/webrtc.ts +61 -0
- package/src/qr/courier.ts +267 -0
- package/src/qr/envelope.ts +0 -0
- package/src/qr/hash.ts +13 -0
- package/src/qr/limits.ts +44 -0
- package/src/qr/svg.ts +34 -0
- package/templates/README.ja.md +183 -0
- package/templates/README.md +198 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# 要求仕様の把握(Issue #1)
|
|
2
|
+
|
|
3
|
+
出典: [Issue #1](https://github.com/kubohiroya/turbowarp-webrtc-qrcode-pairing/issues/1)。
|
|
4
|
+
本書はIssue本文を設計入力として再構成したもので、新しい要求の追加はしない。
|
|
5
|
+
|
|
6
|
+
信頼性の凡例: 🟢 Issue本文に明記 / 🟡 Issue本文+既存実装からの妥当な導出 / 🔴 Issue本文にない設計上の追加判断。
|
|
7
|
+
|
|
8
|
+
## 1. 目的とスコープ
|
|
9
|
+
|
|
10
|
+
🟢 QRコードの光学的搬送でWebRTCのOffer/AnswerをやりとりするTurboWarp拡張。時刻同期・空間校正・モーションキャプチャに依存せず、複数アプリから再利用できる「接続準備」機能に限定する。
|
|
11
|
+
|
|
12
|
+
🟢 スコープ外: 光学的な時刻対応推定、レンズ校正、カメラ配置校正、姿勢推定、映像転送の独自実装。シグナリングサーバ。ICE/STUN/TURNの設計そのもの。
|
|
13
|
+
|
|
14
|
+
🟢 現状: テンプレート0.4.0由来の初期構成のみ。実行可能なのは`hello [NAME]`のみで、ペアリング実装は存在しない。
|
|
15
|
+
|
|
16
|
+
## 2. 役割と用語
|
|
17
|
+
|
|
18
|
+
| 用語 | 定義 | 由来 |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| 統合側端末 (hub) | Offerを生成・投影し、Answerを読み取る側 | 🟢 |
|
|
21
|
+
| カメラ側端末 (camera) | Offerを読み取り、Answerを表示する側 | 🟢 |
|
|
22
|
+
| 搬送担当者 | Answer QRをスマートフォンで撮影して統合側へ運ぶ人 | 🟢 |
|
|
23
|
+
| exchange(交換) | 1回のOffer→Answer往復。取消・再試行で新しいexchangeになる | 🟡 |
|
|
24
|
+
| part | 1枚のQRに収まる分割片 | 🟢 |
|
|
25
|
+
| courier envelope | partに載せる搬送用メタデータ+payload | 🟢 |
|
|
26
|
+
|
|
27
|
+
## 3. 標準操作(正常系)
|
|
28
|
+
|
|
29
|
+
🟢 Issue「利用場面と標準操作」の7手順。
|
|
30
|
+
|
|
31
|
+
1. hubが対象cameraとのペアリングを開始しOfferを生成する。
|
|
32
|
+
2. hubがプロジェクタでOffer QRを表示する。
|
|
33
|
+
3. cameraがカメラでQRを読み取り、全partを取得してOfferを受理する。
|
|
34
|
+
4. cameraがAnswerを生成し、そのQRを画面に表示する。
|
|
35
|
+
5. 担当者がスマートフォンでAnswer QRを(複数partならすべて)撮影し、hubまで運ぶ。
|
|
36
|
+
6. 担当者がスマートフォン画面をhubのカメラにかざす。hubは全partを再構成しAnswerを受理する。
|
|
37
|
+
7. WebRTC接続の成立を確認し、結果を利用アプリへ提供する。
|
|
38
|
+
|
|
39
|
+
🟢 制約: スマートフォンに専用アプリ・ネットワークを要求しない(撮影画像の表示だけで搬送できる)。操作案内・端末配置・投影レイアウトは利用アプリの責務。
|
|
40
|
+
|
|
41
|
+
## 4. 責務分担
|
|
42
|
+
|
|
43
|
+
| 対象 | 責務 |
|
|
44
|
+
|---|---|
|
|
45
|
+
| 本拡張 | QR搬送形式、QR生成・分割・表示、再構成・検証、Offer/Answer交換の進行と結果提供 |
|
|
46
|
+
| `turbowarp-webrtc` | Offer/Answer生成・受理、ICE、接続状態、接続とデータ通信 |
|
|
47
|
+
| `turbowarp-jsqr` | カメラフレームからのQRデコード |
|
|
48
|
+
| `turbowarp-camera-source` | カメラの取得・選択とフレームへのアクセス |
|
|
49
|
+
| 利用アプリ | 役割選択、操作案内、投影・表示レイアウト、接続後の処理 |
|
|
50
|
+
|
|
51
|
+
🟢 すべてIssue本文の表のとおり。
|
|
52
|
+
|
|
53
|
+
## 5. 機能要求(FR)
|
|
54
|
+
|
|
55
|
+
### FR-1 Offer/Answerの対称な搬送
|
|
56
|
+
|
|
57
|
+
| ID | 要求 | 受け入れ観点 |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| FR-1.1 | hub側のOffer生成・表示・Answer受理と、camera側のOffer受理・Answer生成・表示を両方実装する 🟢 | 両ロールのブロックが存在する |
|
|
60
|
+
| FR-1.2 | 再構成した接続情報は、正しい役割・対象のWebRTC能力に一度だけ渡す 🟢 | 二重受理が起きない |
|
|
61
|
+
| FR-1.3 | 送信側peer識別子と受信側ローカルpeer識別子の対応を定義し、両端で同じ識別子設定を暗黙に要求しない 🟢 | 非対称な命名で接続できる |
|
|
62
|
+
| FR-1.4 | AnswerがどのOffer交換への応答かを追跡し、別ペアリングへ誤適用しない 🟢 | 別exchangeのAnswerを拒否する |
|
|
63
|
+
|
|
64
|
+
### FR-2 QR搬送形式と再構成
|
|
65
|
+
|
|
66
|
+
| ID | 要求 |
|
|
67
|
+
|---|---|
|
|
68
|
+
| FR-2.1 | protocol version, session ID, peer対応情報, Offer/Answer種別, message ID, part index/count, message length, hash, payload を扱う 🟢 |
|
|
69
|
+
| FR-2.2 | QR容量と誤り訂正レベルに応じて分割し、単一QR/複数QRの両方に対応する 🟢 |
|
|
70
|
+
| FR-2.3 | partの順不同・重複読取りに対応し、取得済み数・必要数・未取得partを取得できる 🟢 |
|
|
71
|
+
| FR-2.4 | 全partが揃い、長さとhashを検証した後にのみWebRTCへ渡す 🟢 |
|
|
72
|
+
| FR-2.5 | 不正形式/非対応version/範囲外index/過大入力/異なるsession・messageの混在/矛盾した重複part/hash不一致を検出する 🟢 |
|
|
73
|
+
| FR-2.6 | hashは破損検出用であり本人性認証と区別する(文書化) 🟢 |
|
|
74
|
+
| FR-2.7 | message length・part数・受信状態保持に上限を設ける。既存上限(128 Ki、64 part、chunk 4096)を出発点に、単位と境界条件を明記する 🟢 |
|
|
75
|
+
| FR-2.8 | `twmp-qr/1`を移設の出発点とする。互換性を壊すならversionを変更し、旧形式の扱いと移行方法を明記する 🟢 |
|
|
76
|
+
|
|
77
|
+
### FR-3 表示と読取りの連携
|
|
78
|
+
|
|
79
|
+
| ID | 要求 |
|
|
80
|
+
|---|---|
|
|
81
|
+
| FR-3.1 | QR画像・part数・現在partを取得し、指定partの表示/次partへの切替/表示終了ができる 🟢 |
|
|
82
|
+
| FR-3.2 | 静止画撮影でも各partを確実に取得できるよう、手動切替とpart識別情報を提供する 🟢 |
|
|
83
|
+
| FR-3.3 | 読取り処理を独自に重複実装せず、jsqrのデコード文字列を受け取る入口を設ける 🟢 |
|
|
84
|
+
| FR-3.4 | camera-sourceの所有・lease規則を尊重し、同じカメラを後続の撮影用途へ引き継げるようにする 🟢 |
|
|
85
|
+
| FR-3.5 | skinを変更した場合、表示終了・取消・プロジェクト停止時に元へ復帰する。アプリ側の画像表示経路を妨げない 🟢 |
|
|
86
|
+
|
|
87
|
+
### FR-4 状態・エラー・ライフサイクル
|
|
88
|
+
|
|
89
|
+
| ID | 要求 |
|
|
90
|
+
|---|---|
|
|
91
|
+
| FR-4.1 | 生成中/表示・受信待ち/部分受信/接続中/接続成立/取消/失敗をアプリが区別できる。最終的な状態名と遷移は実装前に定義する 🟢 |
|
|
92
|
+
| FR-4.2 | QR読取り完了とWebRTC接続成立を別の状態として提供する 🟢 |
|
|
93
|
+
| FR-4.3 | session単位の開始・取消・再試行・状態/進捗/エラー参照を公開する。opcodeと引数は実装時に確定しmanifestへ反映する 🟢 |
|
|
94
|
+
| FR-4.4 | 取消・再試行後に到着した古い非同期結果を新しいsessionへ反映しない 🟢 |
|
|
95
|
+
| FR-4.5 | 再試行時は新しい交換を識別でき、遅れて読み取った古いQRが接続に使われない 🟢 |
|
|
96
|
+
| FR-4.6 | 待ち時間の上限を設定可能とする。期限判定は未同期端末の壁時計一致を前提にしない 🟢 |
|
|
97
|
+
| FR-4.7 | 複数camera端末との接続を対象peer/sessionごとに区別する。初期フローは1台ずつでよく、同時ペアリング画面は必須としない 🟢 |
|
|
98
|
+
| FR-4.8 | 停止・破棄時に所有する表示・購読・タイマ・受信バッファを解放する。共有カメラや成立済み接続の切断は所有関係と明示操作に従う 🟢 |
|
|
99
|
+
| FR-4.9 | 生のSDP・ICE情報・QR payloadを通常ログへ自動出力しない。エラー分類と進捗は診断に利用できる 🟢 |
|
|
100
|
+
|
|
101
|
+
## 6. 非機能要求(NFR)
|
|
102
|
+
|
|
103
|
+
| ID | 要求 | 由来 |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| NFR-1 | 人手の搬送(数分オーダー)に耐える。Offer/Answer生成時のICE収集完了条件と接続情報の有効性を既存実装に照らして確認する | 🟢 |
|
|
106
|
+
| NFR-2 | QR搬送だけで接続可能性が保証されるとは扱わない(ネットワーク条件は`turbowarp-webrtc`の責務) | 🟢 |
|
|
107
|
+
| NFR-3 | 新経路は`src/config/feature-flags.ts`の`qrCodePairing`(仮称)を起動時に読み取り、既定OFFで段階導入する | 🟢 |
|
|
108
|
+
| NFR-4 | courier等の純粋処理の単体検証はフラグと独立に実行できる | 🟢 |
|
|
109
|
+
| NFR-5 | motion-capture側の既存QR/manual pairing経路を削除せず維持する | 🟢 |
|
|
110
|
+
| NFR-6 | 利用アプリが新経路を無効化し従来のmanual Offer/Answer交換へ戻す手順を記載する。フラグOFFは経路選択の切戻しであり、成立済み接続の自動切断ではない | 🟢 |
|
|
111
|
+
| NFR-7 | `pnpm run check`(型検査・lint・テスト・README生成検証・ビルド再現性・repo検査・pack dry-run)が通る | 🟢 |
|
|
112
|
+
| NFR-8 | README(日英)、公開契約・manifest、操作手順、形式互換性、制約、回帰・切戻し手順を更新する | 🟢 |
|
|
113
|
+
|
|
114
|
+
## 7. 移設の出発点
|
|
115
|
+
|
|
116
|
+
🟢 `turbowarp-realtime-motion-capture`から次を抽出の出発点とする。
|
|
117
|
+
|
|
118
|
+
- `src/qr-courier.ts`: envelope生成、分割、parse、再構成、整合性検証
|
|
119
|
+
- `src/qr-svg.ts`: QRのSVG生成
|
|
120
|
+
- `src/extension.ts`: Offer QR準備・表示・part切替・表示終了と関連する状態管理
|
|
121
|
+
|
|
122
|
+
🟢 現在のcourier形式はOffer/Answerに対応するが、高水準の表示処理はOffer側のみ。コピーで完了とせず、Answer側と往復状態管理を補完する。抽出元のテストを移設し、追加部分の受け入れテストを整備する。汎用QR搬送コードからmotion-capture固有の型・命名・runtime依存を切り離す。
|
|
123
|
+
|
|
124
|
+
詳細な選別表は [extraction-plan.md](extraction-plan.md) を参照。
|
|
125
|
+
|
|
126
|
+
## 8. 受け入れ基準(DoD)
|
|
127
|
+
|
|
128
|
+
🟢 Issueのチェックリストをそのまま採用する。テストへの写像は [test-plan.md](test-plan.md) を参照。
|
|
129
|
+
|
|
130
|
+
1. 投影Offer → camera読取り → Answer撮影・スマートフォン搬送 → hub読取りの全工程で接続が成立する。
|
|
131
|
+
2. 接続成立後、既存WebRTC能力によるテストメッセージ送受信を確認する。
|
|
132
|
+
3. 単一QRと複数QRで往復できる。順不同・重複・不足partを検証する。
|
|
133
|
+
4. 不正QR、別session/別peer対応、矛盾part、hash不一致、上限超過が誤った接続情報の受理につながらない。
|
|
134
|
+
5. 取消・期限切れ・再試行・古い非同期応答・古いQRを検証する。
|
|
135
|
+
6. 2台以上のcameraを順に接続し、Answerと対象peerの対応が混線しない。
|
|
136
|
+
7. 表示の復元と所有資源の解放を確認し、共有カメラの利用を妨げない。
|
|
137
|
+
8. 進捗、QR受信完了、WebRTC接続成立、エラーをアプリから参照できる。
|
|
138
|
+
9. 起動時固定・既定OFFの新経路とmanual pairingへの切戻しを確認する。
|
|
139
|
+
10. `pnpm run check`が通る。
|
|
140
|
+
11. README(日英)ほかドキュメントを更新する。
|
|
141
|
+
12. 実機検証では端末・ブラウザ・QR表示条件・ネットワーク条件・part数・結果を記録する。未検証条件を成功済みと扱わない。
|
|
142
|
+
|
|
143
|
+
## 9. 設計時に判明した制約(Issue本文にない事実)
|
|
144
|
+
|
|
145
|
+
| # | 事実 | 影響 | 確認元 |
|
|
146
|
+
|---|---|---|---|
|
|
147
|
+
| C-1 | `turbowarp-webrtc`のruntime capability v2は`createOffer`/`getOffer`しか公開していない。`acceptOffer`/`getAnswer`/`acceptAnswer`/`connectionState`はブロック専用で、他拡張から呼べない | FR-1.1がv2のままでは実装不能。capability v3の追加が前提作業になる | `turbowarp-webrtc/src/runtime-capability.ts:19-24`、`src/manual-peer-session.ts:36-59` |
|
|
148
|
+
| C-2 | `createOffer`/`acceptOffer`はどちらも`waitForIceGathering`で収集完了まで待つ(trickle ICEではない) | 搬送に数分かかってもコード自体は不変で完結している。NFR-1の確認は「収集完了待ちである」ことをもって満たす | `turbowarp-webrtc/src/manual-peer-session.ts:109-149, 484-498` |
|
|
149
|
+
| C-3 | pairing codeは`base64url(JSON)`で印字可能ASCIIのみ。courierの`[\x20-\x7E]`制約と適合する | 形式変換は不要 | `turbowarp-webrtc/src/protocol.ts:26-42` |
|
|
150
|
+
| C-4 | `jsqr`の`waitForQrText`は呼び出しごとにcamera leaseを取得・解放する。partごとに呼ぶとlease取得・解放が繰り返される | session中は自前で1つのleaseを保持し、デコードは`scanFrame`を再利用する | `turbowarp-jsqr/src/extension.ts:95-155` |
|
|
151
|
+
| C-5 | 誤り訂正M・QR v40での1part容量は2331バイト。envelope v2のヘッダ最大長は362文字なので、payloadは最大1969文字/part、64partで126,016文字 | `MAX_MESSAGE_LENGTH = 128 Ki (131,072)`はM以下では到達しない。実効上限はpart数×chunk長 | 本設計での実測(`interfaces.ts`の定数コメント参照) |
|
|
152
|
+
| C-6 | motion-captureはvitest 4系、本リポジトリはvitest 5系 | 移設テストの実行確認が必要 | 両`package.json` |
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# 検証計画(DoD → テスト対応)
|
|
2
|
+
|
|
3
|
+
対応要求: requirements.md §8
|
|
4
|
+
|
|
5
|
+
## 1. テストの層
|
|
6
|
+
|
|
7
|
+
| 層 | 対象 | 依存の扱い |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| 単体(純粋) | `src/qr/**` | 依存なし。フィーチャーフラグと独立に動く(NFR-4) |
|
|
10
|
+
| 単体(ドメイン) | `src/pairing/**` | `WebRtcPairingPort` / `QrScanPort` / `DisplayPort` / `MonotonicClock`をフェイク注入 |
|
|
11
|
+
| 連携(プロセス内) | hub controller ↔ camera controller | 2つのcontrollerをQRテキスト受け渡しで結線。WebRTCは`RTCPeerConnection`のフェイク、またはNode環境では純粋なコード交換フェイク |
|
|
12
|
+
| 実デコード | `qr/svg.ts` → jsQR | 生成SVG/モジュール行列をラスタライズし`jsqr`で復号(移設元の手法を流用) |
|
|
13
|
+
| 実機 | 全工程 | 手順書に従い記録する(自動化しない) |
|
|
14
|
+
|
|
15
|
+
## 2. DoD対応表
|
|
16
|
+
|
|
17
|
+
| DoD | 検証方法 | テストファイル |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| 1. 全工程で接続成立 | プロセス内往復(自動)+実機(手動) | `tests/pairing-roundtrip.test.ts` / 実機記録 |
|
|
20
|
+
| 2. 接続後のメッセージ送受信 | 実機で`turbowarp-webrtc`の`send event`/`next received message`を確認 | 実機記録 |
|
|
21
|
+
| 3. 単一QRと複数QRの往復、順不同・重複・不足 | 短いコード(1part)と6000文字相当(複数part)で往復。partを逆順投入、同一part再投入、1つ欠落 | `tests/qr-courier.test.ts` / `tests/pairing-roundtrip.test.ts` |
|
|
22
|
+
| 4. 不正QR・別session・別peer・矛盾part・hash不一致・上限超過 | 各エラーコードごとにケースを用意し、いずれも`delivered`が立たないことを確認 | `tests/qr-courier.test.ts` / `tests/pairing-validation.test.ts` |
|
|
23
|
+
| 5. 取消・期限・再試行・古い非同期応答・古いQR | フェイク時計を進めて期限、遅延resolveするフェイクWebRTCでepoch検証、retry後に旧QRを投入 | `tests/pairing-lifecycle.test.ts` |
|
|
24
|
+
| 6. 2台以上のcameraの混線なし | hub 1つに対しcamera A/Bを順に接続。Bの回答をAのsession keyへ投入して拒否されることを確認 | `tests/pairing-multi-peer.test.ts` |
|
|
25
|
+
| 7. 表示復元と資源解放、共有カメラを妨げない | フェイクrendererで`updateDrawableSkinId`の復元呼び出しと`destroySkin`を確認。leaseの`release`回数と、アプリ側leaseが残る場合にカメラが停止しないことを確認 | `tests/pairing-display.test.ts` |
|
|
26
|
+
| 8. 進捗・受信完了・接続成立・エラーの参照 | 各phaseで`progress()`の全フィールドを検証。`offer-received`と`connected`が別状態であることを明示的にassert | `tests/pairing-progress.test.ts` |
|
|
27
|
+
| 9. 既定OFFとmanual pairingへの切戻し | フラグ未設定で`getInfo()`にペアリングブロックが無いこと、直接呼出しが`feature-disabled`、`pairingPhase`が`disabled`を返すこと。切戻し手順はREADMEに記載 | `tests/extension.test.ts` |
|
|
28
|
+
| 10. `pnpm run check` | CIとローカル | — |
|
|
29
|
+
| 11. ドキュメント更新 | `pnpm run docs:check`+レビュー | — |
|
|
30
|
+
| 12. 実機記録 | 下記テンプレートで記録 | — |
|
|
31
|
+
|
|
32
|
+
## 3. 重点ケース(受け入れテストの具体)
|
|
33
|
+
|
|
34
|
+
### 3.1 形式・検証(FR-2.5)
|
|
35
|
+
|
|
36
|
+
各ケースは「エラーコードが期待どおり」かつ「WebRTCへ引き渡されない」の両方をassertする。
|
|
37
|
+
|
|
38
|
+
| ケース | 入力 | 期待コード |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| JSONでない | `"not json"` | `invalid-json` |
|
|
41
|
+
| 旧protocol | `twmp-qr/1`のenvelope | `unsupported-protocol` |
|
|
42
|
+
| 未知version | `twqr/2` | `unsupported-protocol` |
|
|
43
|
+
| partIndex >= partCount | `{partIndex:3,partCount:3}` | `index-out-of-range` |
|
|
44
|
+
| partCount > 64 | `{partCount:65}` | `invalid-envelope` |
|
|
45
|
+
| messageLength = 0 | | `invalid-envelope` |
|
|
46
|
+
| messageLength > 131072 | | `message-too-large` |
|
|
47
|
+
| payload > 4096 | | `invalid-envelope` |
|
|
48
|
+
| QRテキスト > 8192 | | `part-too-large` |
|
|
49
|
+
| hashが43文字でない | | `invalid-envelope` |
|
|
50
|
+
| 別sessionIdのpartを混ぜる | | `message-mismatch` |
|
|
51
|
+
| 同indexで異なるpayload | | `conflicting-part` |
|
|
52
|
+
| hashだけ書き換える | 全part揃った状態 | `hash-mismatch` |
|
|
53
|
+
| messageLengthだけ書き換える | 全part揃った状態 | `length-mismatch` |
|
|
54
|
+
| 1part欠落で`assemble` | | `missing-parts` |
|
|
55
|
+
| 分割で65part必要な長さ | | `too-many-parts` |
|
|
56
|
+
|
|
57
|
+
### 3.2 交換の同一性(FR-1.4 / FR-4.5)
|
|
58
|
+
|
|
59
|
+
| ケース | 期待 |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Answerの`replyTo`が別Offerのmessage ID | `reply-mismatch`、`acceptAnswer`未呼出 |
|
|
62
|
+
| Answerの`senderPeerId`がsessionの`remotePeerId`と不一致 | `peer-mismatch` |
|
|
63
|
+
| `retryPairing`後に旧exchangeのAnswerを投入 | `stale-exchange`、`acceptAnswer`未呼出 |
|
|
64
|
+
| 存在しないsessionキーへ投入 | `unknown-session` |
|
|
65
|
+
| cameraでkind=`answer`のQRを読む | `unexpected-kind` |
|
|
66
|
+
| 完成済みsessionへ同じ全partを再投入 | `already-accepted`、`acceptAnswer`は1回だけ |
|
|
67
|
+
|
|
68
|
+
### 3.3 peer対応の非対称性(FR-1.3)
|
|
69
|
+
|
|
70
|
+
hubが`localPeerId="studio"`, `remotePeerId="cam-A"`、cameraが`expectedLocalPeerId=""`のとき:
|
|
71
|
+
|
|
72
|
+
- camera側のWebRTC呼出しは`acceptOffer("studio", …)`であること
|
|
73
|
+
- hub側のWebRTC呼出しは`createOffer("cam-A", …)`/`acceptAnswer("cam-A", …)`であること
|
|
74
|
+
- 両端で同じ文字列を設定していないのに接続が成立すること
|
|
75
|
+
- cameraが`expectedLocalPeerId="cam-B"`を指定した場合は`peer-mismatch`で拒否されること
|
|
76
|
+
|
|
77
|
+
### 3.4 ライフサイクル(FR-4.4 / FR-4.8)
|
|
78
|
+
|
|
79
|
+
| ケース | 期待 |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `createOffer`が遅延resolveする間に`cancelPairing` | 遅延結果が捨てられ、phaseは`cancelled`のまま |
|
|
82
|
+
| `acceptOffer`遅延中に期限到来 | phaseは`expired`、遅延結果でphaseが動かない |
|
|
83
|
+
| 期限到来(未接続) | 表示復元・lease解放・タイマ停止・`closePeer`呼出し |
|
|
84
|
+
| 期限到来(接続済み) | `closePeer`を呼ばない |
|
|
85
|
+
| `PROJECT_RUN_STOP` | 表示復元とlease解放。成立済み接続は維持 |
|
|
86
|
+
| `RUNTIME_DISPOSED` | 全session破棄とリスナ解除 |
|
|
87
|
+
| `targetWasRemoved` | 当該スプライトの表示のみ終了、sessionは継続 |
|
|
88
|
+
| session数が9個目 | `session-limit` |
|
|
89
|
+
|
|
90
|
+
### 3.5 期限が壁時計に依存しないこと(FR-4.6)
|
|
91
|
+
|
|
92
|
+
フェイク`MonotonicClock`だけを進め、`Date.now()`は動かさない(あるいは逆方向へ飛ばす)状態で
|
|
93
|
+
期限が正しく判定されることをassertする。`createdAt`を未来・過去に改竄したenvelopeを投入しても
|
|
94
|
+
期限判定に影響しないことも確認する。
|
|
95
|
+
|
|
96
|
+
### 3.6 プライバシー(FR-4.9)
|
|
97
|
+
|
|
98
|
+
- `console`の全メソッドをスパイし、正常系・異常系いずれでも呼ばれないことを確認する。
|
|
99
|
+
- 全エラーの`message`について、pairing code本文・payload断片を含まないことを検証する
|
|
100
|
+
(テスト用に識別可能なマーカー文字列をpairing codeへ埋め、それが例外メッセージへ現れないこと)。
|
|
101
|
+
|
|
102
|
+
## 4. 実機検証の記録テンプレート(DoD 12)
|
|
103
|
+
|
|
104
|
+
各試行につき以下を記録し、Issue #1のコメントへ貼る。未実施の条件を成功として扱わない。
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
日時:
|
|
108
|
+
役割/端末: hub = <機種/OS/ブラウザ/版> camera = <機種/OS/ブラウザ/版>
|
|
109
|
+
搬送機: <スマートフォン機種/OS/カメラアプリ>
|
|
110
|
+
ICEモード: lan | stun
|
|
111
|
+
ネットワーク: 同一LAN / 別セグメント / その他
|
|
112
|
+
Offer: part数 = / QR version = / ECC = / 表示面 = プロジェクタ(投影サイズ, 距離, 照度)
|
|
113
|
+
Answer: part数 = / QR version = / ECC = / 表示面 = 端末画面(輝度)
|
|
114
|
+
読取り: cameraの読取り所要 = 秒 / hubの読取り所要 = 秒 / 再撮影回数 =
|
|
115
|
+
結果: 接続成立 = yes|no / connectionState = / 疎通確認(送受信) = yes|no
|
|
116
|
+
エラー: code = / 状況 =
|
|
117
|
+
備考:
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 5. 自動化しない/できないもの
|
|
121
|
+
|
|
122
|
+
- プロジェクタ投影の実読取り、スマートフォンでの撮影・搬送。
|
|
123
|
+
- 実ネットワークでのICE成否(NFR-2)。
|
|
124
|
+
- 端末カメラの露出・フォーカス条件によるデコード成功率。
|
|
125
|
+
|
|
126
|
+
これらは実機記録でのみ担保し、CIの通過をもって「実機で動く」とは主張しない。
|
package/docs/index.html
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
6
|
+
<title>TurboWarp-WebRTC-QRCode-Pairing</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<h1>TurboWarp-WebRTC-QRCode-Pairing</h1>
|
|
10
|
+
<p>A TurboWarp extension that pairs WebRTC peers by carrying the offer and the answer optically, as QR codes.</p>
|
|
11
|
+
<h2>How the workflow runs</h2>
|
|
12
|
+
<ol>
|
|
13
|
+
<li>The integration machine creates an offer and projects its QR parts.</li>
|
|
14
|
+
<li>A camera machine scans the parts, accepts the offer, and shows the answer QR parts on its screen.</li>
|
|
15
|
+
<li>An operator photographs every answer part with a smartphone and carries the images back.</li>
|
|
16
|
+
<li>The integration machine scans those images, accepts the answer, and reports the connection.</li>
|
|
17
|
+
</ol>
|
|
18
|
+
<p>No signaling server and no app on the smartphone: showing the photographed image is enough.</p>
|
|
19
|
+
<h2>Before you start</h2>
|
|
20
|
+
<ul>
|
|
21
|
+
<li>Load <code>turbowarp-webrtc</code>, <code>turbowarp-jsqr</code> and <code>turbowarp-camera-source</code> first.</li>
|
|
22
|
+
<li>Run the extension unsandboxed.</li>
|
|
23
|
+
<li>Turn on the pairing blocks at startup with <code>globalThis.__TWQP_FEATURE_FLAGS__ = {qrCodePairing: true};</code></li>
|
|
24
|
+
</ul>
|
|
25
|
+
<p>A projected pairing code is visible to everyone who can see the projection. The QR hash detects damage; it does not authenticate the other machine.</p>
|
|
26
|
+
<h2>Documentation</h2>
|
|
27
|
+
<ul>
|
|
28
|
+
<li><a href="integration-guide.md">Integration guide</a> (<a href="integration-guide.ja.md">日本語</a>) — setup, block sequences for both machines, projection and scanning, error codes, hardware test record</li>
|
|
29
|
+
<li><a href="migration.md">Migration and rollback</a> (<a href="migration.ja.md">日本語</a>) — coming from turbowarp-realtime-motion-capture, returning to manual pairing, regression checks</li>
|
|
30
|
+
<li><a href="architecture.md">Architecture</a> (<a href="architecture.ja.md">日本語</a>) — runtime structure, build outputs, extension API manifest</li>
|
|
31
|
+
<li><a href="https://github.com/kubohiroya/turbowarp-webrtc-qrcode-pairing#readme">Repository documentation and block reference</a></li>
|
|
32
|
+
</ul>
|
|
33
|
+
</body>
|
|
34
|
+
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# chore(scaffold): QR搬送によるWebRTCペアリング拡張の初期化
|
|
2
|
+
|
|
3
|
+
GitHub Issue用の未投稿草案。今回の依頼はローカル初期化であり、外部への投稿は含まない。
|
|
4
|
+
|
|
5
|
+
## Doing / ToDo / Done
|
|
6
|
+
|
|
7
|
+
- Doing: なし。
|
|
8
|
+
- ToDo: GitHubへのタスク記録と公開操作は別途の指示を受けて行う。
|
|
9
|
+
- Done: 専用metadata、ソース、検証環境、README、生成物の整備と全チェック。
|
|
10
|
+
|
|
11
|
+
## ブランチと依存
|
|
12
|
+
|
|
13
|
+
- ブランチ: `chore/scaffold/qrcode-pairing-initialization`
|
|
14
|
+
- 依存: `turbowarp-extension-template` 0.4.0。QRコード搬送の実装移設は本タスクの後続。
|
|
15
|
+
- 将来の依存: webrtcのOffer/Answer能力、jsqrの読取り、camera-sourceのフレーム取得。
|
|
16
|
+
- 本タスクは初期構成のみ。実際のペアリングと他リポジトリの修正は含まない。
|
|
17
|
+
|
|
18
|
+
## 受け入れ基準
|
|
19
|
+
|
|
20
|
+
- [x] 専用package名・拡張ID・クラス名・リポジトリURLを設定する。
|
|
21
|
+
- [x] 日本語/英語READMEに未実装の状態、目的、責務分担、移設元を記載する。
|
|
22
|
+
- [x] 型検査、lint、既存テスト、README生成検証、ビルド再現性、repo検査、pack dry-runが通る。
|
|
23
|
+
- [x] 生成JavaScriptとmanifestを配置する。
|
|
24
|
+
|
|
25
|
+
## フラグとロールバック
|
|
26
|
+
|
|
27
|
+
初期版にはペアリングの実行経路がなく、フィーチャーフラグは不要。移設時は既存経路を維持し、新経路を既定OFFで段階導入する。初期化のロールバックは、この変更で追加したファイルだけを取り除く。既存の`.git`は保持する。
|
|
28
|
+
|
|
29
|
+
## 運用ログ
|
|
30
|
+
|
|
31
|
+
- start: 2026-09-15 ローカル初期化に着手。
|
|
32
|
+
- blocked: 初回checkのdist検査が未追跡ファイルを不一致と判定。初期リポジトリでも機能する内容比較方式へ調整。README検査もGitの追跡状態に依存しない比較へ変更。
|
|
33
|
+
- blocked: README検査の.ts動的importが型検査に非対応。Node子プロセスで生成スクリプトを実行する方式へ修正。
|
|
34
|
+
- done: 2026-09-15 pnpm run check成功。型検査、lint、7テスト、README検査、ビルド再現性、repo検査、pack dry-runを確認。
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# 利用ガイド
|
|
2
|
+
|
|
3
|
+
[English](integration-guide.md)
|
|
4
|
+
|
|
5
|
+
TurboWarpのプロジェクトから本拡張で2台の端末をペアリングする手順です。ブロック単位の一覧は
|
|
6
|
+
[Block reference](../README.md#block-reference)を参照してください。
|
|
7
|
+
|
|
8
|
+
## 1. 準備
|
|
9
|
+
|
|
10
|
+
次の拡張を本拡張より**先に**読み込み、すべてunsandboxedで動かします。
|
|
11
|
+
|
|
12
|
+
| 拡張 | 役割 |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `turbowarp-webrtc` | Offer/Answerの生成と受理、接続の保持 |
|
|
15
|
+
| `turbowarp-jsqr` | カメラフレームからのQRデコード |
|
|
16
|
+
| `turbowarp-camera-source` | カメラの取得とフレームの提供 |
|
|
17
|
+
|
|
18
|
+
`turbowarp-webrtc`はruntime capability **v3**を公開している必要があります。0.4.0以降が該当します。
|
|
19
|
+
0.3.0以前はv2までで、`createOffer`と`getOffer`はありますが`acceptOffer`、`getAnswer`、
|
|
20
|
+
`acceptAnswer`、`connectionState`が無いため往復を完結できません。古い版では
|
|
21
|
+
`webrtc-capability-missing`になります。
|
|
22
|
+
|
|
23
|
+
ペアリング用ブロックは、拡張の読込み前に起動時フラグで有効にします。
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
globalThis.__TWQP_FEATURE_FLAGS__ = {qrCodePairing: true};
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
無効の間はブロックが現れず、`pairing phase of [SESSION]`は`disabled`を返します。
|
|
30
|
+
|
|
31
|
+
フラグはバンドルの評価時に一度だけ読まれるため、後から設定しても効きません。設定済みの
|
|
32
|
+
1ファイルを得るには、リポジトリの補助スクリプトを使います。
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm run build:flagged # 例: pnpm run build:flagged Q
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`local/webrtc-qrcode-pairing.flagged.js`を書き出し、カスタム拡張として読み込む`file://`のURLを
|
|
39
|
+
表示します。引数で誤り訂正レベルを固定できます。このファイルは作業コピー内のみで公開されません。
|
|
40
|
+
既定でブロックが出ないことの確認は、代わりに`dist/webrtc-qrcode-pairing.js`を読み込んで行います。
|
|
41
|
+
|
|
42
|
+
## 2. 役割と名前
|
|
43
|
+
|
|
44
|
+
一方が**統合側(hub)**で、Offerを作って投影し、Answerを読み取ります。もう一方が
|
|
45
|
+
**カメラ側端末**で、Offerを読み取ってAnswerを表示します。
|
|
46
|
+
|
|
47
|
+
名前は各端末が自分で決めます。**両端で一致している必要はありません。**
|
|
48
|
+
|
|
49
|
+
- hubは自分を`studio`、カメラ側を`cam-A`と呼ぶ。
|
|
50
|
+
- カメラ側はOfferから両方の名前を受け取り、接続を`studio`というキーで登録し、`cam-A`として応答する。
|
|
51
|
+
|
|
52
|
+
つまりhubの`remote peer`がカメラ側の`local peer`であり、その逆も同様です。名前は画面を見る人に
|
|
53
|
+
とって意味があれば十分です。
|
|
54
|
+
|
|
55
|
+
カメラ側の`LOCAL_PEER`を空にすると、Offerが割り当てた名前をそのまま採用します。名前を指定すると
|
|
56
|
+
それを要求し、別の端末宛のOfferは`peer-mismatch`で拒否されます。担当者が誤った投影を読み取った
|
|
57
|
+
場合の検出に使えます。
|
|
58
|
+
|
|
59
|
+
## 3. hub側のスクリプト
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
緑の旗が押されたとき
|
|
63
|
+
start offer pairing [pairing-1] as [studio] to [cam-A]
|
|
64
|
+
set pairing timeout of [pairing-1] to (600) seconds
|
|
65
|
+
show pairing QR part (1) of [pairing-1] on this sprite
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
期限の設定はsessionを開いた後に置きます。2つの`start`ブロック以外はすべて
|
|
69
|
+
開いているsessionを必要とし、無い場合は`no-session`になります。期限はsessionを
|
|
70
|
+
開いた時点からの経過で測るため、直後に設定しても失うものはありません。
|
|
71
|
+
|
|
72
|
+
`start offer pairing`はOfferが生成されQR partの準備が終わると戻り、phaseは`offer-ready`になります。
|
|
73
|
+
Offer生成はICE収集の完了を待つため、少し時間がかかります。
|
|
74
|
+
|
|
75
|
+
partを投影してカメラ側に読み取らせ、担当者がAnswerを運んできたら次を実行します。
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
scan pairing QR for [pairing-1] from camera [default]
|
|
79
|
+
wait until pairing [pairing-1] is connected
|
|
80
|
+
end pairing QR display of [pairing-1]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`scan pairing QR`はAnswerの全partが揃い検証を通った時点で戻ります。phaseは`answer-received`から
|
|
84
|
+
`connecting`へ進みます。`wait until ... is connected`はWebRTCが接続を報告すると戻り、取消・期限
|
|
85
|
+
切れ・失敗のときは失敗します。
|
|
86
|
+
|
|
87
|
+
## 4. カメラ側のスクリプト
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
緑の旗が押されたとき
|
|
91
|
+
start answer pairing [pairing-1] as []
|
|
92
|
+
set pairing timeout of [pairing-1] to (600) seconds
|
|
93
|
+
scan pairing QR for [pairing-1] from camera [default]
|
|
94
|
+
show pairing QR part (1) of [pairing-1] on this sprite
|
|
95
|
+
wait until pairing [pairing-1] is connected
|
|
96
|
+
end pairing QR display of [pairing-1]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Offerが揃うと拡張が自動でOfferを受理しAnswerを準備するので、phaseは`receiving`→`offer-received`
|
|
100
|
+
→`creating-answer`→`answer-ready`とブロックを追加せずに進みます。
|
|
101
|
+
|
|
102
|
+
## 5. 撮影しやすいpartの見せ方
|
|
103
|
+
|
|
104
|
+
接続情報が長いとQRは複数枚になります。自動で巡回させず、**1枚ずつ表示して担当者が送る**形にして
|
|
105
|
+
ください。投影を撮影する人は、各partが静止している必要があります。
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
show pairing QR part (1) of [pairing-1] on this sprite
|
|
109
|
+
say (join (join (current pairing QR part of [pairing-1]) " / ") (pairing QR part count of [pairing-1]))
|
|
110
|
+
|
|
111
|
+
[スペース] キーが押されたとき
|
|
112
|
+
show next pairing QR part of [pairing-1] on this sprite
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
実務上の注意です。
|
|
116
|
+
|
|
117
|
+
- 「2 / 3」のようにpart番号と総数を出すと、担当者が残りを把握できます。
|
|
118
|
+
- スプライトの元のコスチュームは保持されます。`end pairing QR display`のほか、取消、期限切れ、
|
|
119
|
+
停止ボタン、スプライトの削除でも元に戻ります。
|
|
120
|
+
- 投影ではスプライトを大きく正方形に保ち、コード周囲の白い余白を削らないでください。余白も
|
|
121
|
+
シンボルの一部です。
|
|
122
|
+
- 誤り訂正レベルを上げると光学条件に強くなりますが、1枚あたりの文字数が減るためpart数が増え、
|
|
123
|
+
運ぶ手間も増えます。既定は`M`です。読取りが不安定なら起動時に`Q`や`H`を指定します。
|
|
124
|
+
`globalThis.__TWQP_QR_CONFIG__ = {errorCorrectionLevel: 'Q'};`
|
|
125
|
+
- スプライトのskinではなく自前で描画する場合は、
|
|
126
|
+
`pairing QR part [INDEX] of [SESSION] as data URI`または`... as SVG`を読みます。この経路は
|
|
127
|
+
rendererが無くても動きます。
|
|
128
|
+
|
|
129
|
+
## 6. partの読取り
|
|
130
|
+
|
|
131
|
+
`scan pairing QR for [SESSION] from camera [CAMERA_ID]`はsessionの間1つのcamera leaseを保持し、
|
|
132
|
+
全partが揃うまで読み続けます。同じpartを何度も読むのは正常で、害はありません。ポスターや別の
|
|
133
|
+
session、前回の試行など、自分のものではないQRは黙って読み飛ばします。
|
|
134
|
+
|
|
135
|
+
実行中は進捗を表示できます。
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
say (join (join (received parts of [pairing-1]) " / ") (required parts of [pairing-1]))
|
|
139
|
+
say (join "未取得: " (missing parts of [pairing-1]))
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
part数はpartの中に入っているため、`required parts`は最初のpartが届くまで0です。
|
|
143
|
+
|
|
144
|
+
QRの文字列を別の方法で得ている場合は、`receive pairing QR text [TEXT] for [SESSION]`で直接
|
|
145
|
+
投入できます。こちらが正規の入口で、カメラ走査はその上に作られています。
|
|
146
|
+
|
|
147
|
+
## 7. 進捗の観測
|
|
148
|
+
|
|
149
|
+
`pairing phase of [SESSION]`が交換の位置を返します。
|
|
150
|
+
|
|
151
|
+
| phase | 意味 |
|
|
152
|
+
|---|---|
|
|
153
|
+
| `disabled` | フィーチャーフラグが無効 |
|
|
154
|
+
| `idle` | その名前のsessionが無い |
|
|
155
|
+
| `creating-offer` | hub: WebRTCのOffer生成待ち |
|
|
156
|
+
| `offer-ready` | hub: Offer QRの投影準備ができた |
|
|
157
|
+
| `awaiting-answer` | hub: Answerのpartを部分受信中 |
|
|
158
|
+
| `answer-received` | hub: Answerが検証を通った |
|
|
159
|
+
| `awaiting-offer` | camera: 最初のOffer partを待っている |
|
|
160
|
+
| `receiving` | camera: Offerのpartを部分受信中 |
|
|
161
|
+
| `offer-received` | camera: Offerが検証を通った |
|
|
162
|
+
| `creating-answer` | camera: WebRTCのAnswer生成待ち |
|
|
163
|
+
| `answer-ready` | camera: Answer QRの表示準備ができた |
|
|
164
|
+
| `connecting` | 接続情報をWebRTCへ渡した。接続はまだ |
|
|
165
|
+
| `connected` | WebRTCが接続成立を報告した |
|
|
166
|
+
| `cancelled` / `expired` / `failed` | 交換が終了した |
|
|
167
|
+
|
|
168
|
+
**運べたことと繋がったことは別です。** `answer-received`と`offer-received`は光学搬送が成功した
|
|
169
|
+
ことを意味し、`connected`はネットワーク経路が通ったことを意味します。接続情報が完全に届いても
|
|
170
|
+
接続が失敗することはあります。到達性はQRではなくネットワークの条件で決まります。
|
|
171
|
+
|
|
172
|
+
## 8. カメラ側端末が2台以上のとき
|
|
173
|
+
|
|
174
|
+
session名と相手の呼称を分けて、1台ずつ順に接続します。
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
start offer pairing [pairing-A] as [studio] to [cam-A]
|
|
178
|
+
...
|
|
179
|
+
start offer pairing [pairing-B] as [studio] to [cam-B]
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`cam-B`のAnswerを`pairing-A`へ投入すると拒否されます。各Answerはsessionと応答対象のOfferを
|
|
183
|
+
持っているため、接続が入れ替わることはありません。`pairing sessions`で開いているsession名を
|
|
184
|
+
確認できます。
|
|
185
|
+
|
|
186
|
+
## 9. 期限、取消、再試行
|
|
187
|
+
|
|
188
|
+
- `set pairing timeout of [SESSION] to [SECONDS] seconds` — 1〜3600秒、既定600秒。期限は
|
|
189
|
+
**その端末自身の時計**で測るため、2台の時刻同期は不要です。`remaining seconds of [SESSION]`で
|
|
190
|
+
残りを表示できます。
|
|
191
|
+
- `cancel pairing [SESSION]` — 表示を戻し、カメラと受信バッファを解放し、**まだ接続していない**
|
|
192
|
+
場合はpeer接続を閉じます。成立済みの接続はそのままです。
|
|
193
|
+
- `retry pairing [SESSION]` — 取消して新しい交換を始めます。新しい交換は別のIDを持つため、前回の
|
|
194
|
+
試行で撮影したQRは適用されずに拒否されます。
|
|
195
|
+
|
|
196
|
+
停止ボタンは表示とカメラを解放し、進行中の交換を取り消します。成立済みの接続は切断しません。
|
|
197
|
+
|
|
198
|
+
## 10. うまくいかないとき
|
|
199
|
+
|
|
200
|
+
`pairing error code of [SESSION]`が安定したコードを、`pairing error message of [SESSION]`が
|
|
201
|
+
担当者向けの文を返します。どちらにも接続情報そのものは含まれません。
|
|
202
|
+
|
|
203
|
+
| コード | 状況 | 対処 |
|
|
204
|
+
|---|---|---|
|
|
205
|
+
| `feature-disabled` | 起動時フラグが無効 | 読込み前に`__TWQP_FEATURE_FLAGS__`を設定する |
|
|
206
|
+
| `webrtc-capability-missing` | `turbowarp-webrtc`が無いかv3未満 | 先に読み込む。capability v3が必要 |
|
|
207
|
+
| `qr-decoder-missing` / `camera-unavailable` | `turbowarp-jsqr`か`turbowarp-camera-source`が無い、またはカメラ取得に失敗 | 先に読み込む。カメラの許可を確認する |
|
|
208
|
+
| `renderer-unavailable` | スプライトに一時skinを設定できない | ステージやクローンではなく通常のスプライトを使う。またはSVGを自分で表示する |
|
|
209
|
+
| `unsupported-protocol` | `twqr/1`ではないQR | 旧`twmp-qr/1`か、別製品のQR |
|
|
210
|
+
| `hash-mismatch` / `length-mismatch` | partは揃ったが内容が壊れている | 全partを読み直す。誤り訂正レベルを上げる |
|
|
211
|
+
| `conflicting-part` | 同じpart番号が別内容で届いた | 異なる交換が混ざっている。やり直す |
|
|
212
|
+
| `missing-parts` | 全partが揃っていない | `missing parts of [SESSION]`で不足を確認する |
|
|
213
|
+
| `peer-mismatch` | 別の端末同士を指すQR | 誤った投影を読み取っている |
|
|
214
|
+
| `reply-mismatch` / `stale-exchange` | 別のOfferへの応答、または前回の試行のQR | 現在のQRを撮り直す |
|
|
215
|
+
| `already-accepted` | この交換はすでにWebRTCへ渡している | 対処不要 |
|
|
216
|
+
| `timeout` | 期限が過ぎた | `retry pairing`する |
|
|
217
|
+
| `webrtc-rejected` | WebRTCが受理を拒否、または接続が失敗 | 搬送ではなくネットワークの問題 |
|
|
218
|
+
| `session-exists` / `session-limit` / `no-session` | 同名が開いている、開きすぎ、開いていない | sessionを閉じるか、名前を確認する |
|
|
219
|
+
|
|
220
|
+
## 11. 本拡張が担当しないこと
|
|
221
|
+
|
|
222
|
+
- **認証ではありません。** ハッシュは破損の検出用です。QRを撮影できる人は同じ値を計算でき、
|
|
223
|
+
投影を見られる人は接続情報を読めます。投影の可視範囲は運用で管理してください。
|
|
224
|
+
- **到達性は保証しません。** ICE、STUN、TURNは`turbowarp-webrtc`の責務です。
|
|
225
|
+
- **映像は運びません。** カメラのデータは接続成立後にWebRTCで送ります。
|
|
226
|
+
- **画面構成は行いません。** 担当者への案内、投影レイアウト、接続後の処理は利用アプリの責務です。
|
|
227
|
+
|
|
228
|
+
## 12. 実機検証の記録
|
|
229
|
+
|
|
230
|
+
光学条件はCIで確認できません。試行ごとに記録し、未検証の条件を検証済みとして扱わないでください。
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
日時:
|
|
234
|
+
hub端末: <機種 / OS / ブラウザと版>
|
|
235
|
+
カメラ側端末: <機種 / OS / ブラウザと版>
|
|
236
|
+
搬送機: <スマートフォン機種 / OS / カメラアプリ>
|
|
237
|
+
ICEモード: lan | stun
|
|
238
|
+
ネットワーク: 同一LAN / 別セグメント / その他
|
|
239
|
+
Offer: part数 = / QR version = / 誤り訂正 = / プロジェクタ(投影サイズ, 距離, 照度)
|
|
240
|
+
Answer: part数 = / QR version = / 誤り訂正 = / 画面輝度
|
|
241
|
+
読取り: カメラ側 秒 / hub側 秒 / 撮り直し回数 =
|
|
242
|
+
結果: 接続成立 = yes|no / connection state = / テストメッセージ送受信 = yes|no
|
|
243
|
+
エラー: code = / 状況 =
|
|
244
|
+
備考:
|
|
245
|
+
```
|