onvif-scan(LAN内のONVIFカメラを発見し、資産台帳を作る読み取り専用ツール)の v0.2 開発で、私が下した仕様判断が間違っていた話です。面白いのは、間違いそのものより「どうやって止められたか」です。
何を間違えたか
Media2 デバイス向けの GetVideoEncoderConfigurationOptions は、対象のエンコーダ設定トークンを引数に取ります。私はリクエストボディを「操作要素の中に GetConfiguration 要素を包み、その中に ConfigurationToken を入れる」形だと決めて、実装側に凍結仕様として渡していました。
その形は存在しません。公式の Media2 WSDL にはこう書かれています。
<xs:element name="GetVideoEncoderConfigurationOptions" type="tr2:GetConfiguration"/>
GetConfiguration は操作要素の型名です。その型の sequence が ConfigurationToken(と ProfileToken)を直接含みます。同名のラッパー子要素はありません。正しいリクエストはこれだけです。
<tr2:GetVideoEncoderConfigurationOptions>
<tr2:ConfigurationToken>vec_1</tr2:ConfigurationToken>
</tr2:GetVideoEncoderConfigurationOptions>
実装を担当したエージェントは、私の凍結仕様に対してコードを書くことを拒否しました。WSDL を確認し、その項目だけを停止して、根拠付きで競合を報告し、残りは全部仕上げてきました。Media2 のプロファイルは理由付きで unqueried(未照会)と報告され、黙って省略もされず、レスポンス解析テストだけで「検証済み」ともされませんでした。他人のネットワークに触れる道具には、こうあってほしい。仕様と指示が食い違ったら、止まって証拠を示す。
この件(社内では D1 と呼んでいました)は WSDL 側を正として解決し、シミュレータにリクエスト形状のアサーションを追加して再発防止を入れました。
v0.2.0 で増えた棚卸し項目
プロファイルの「現在の設定」に加えて、デバイスが「宣言している能力」を集めるようにしました。
-
サービス宣言の全件取得。
GetServicesを標準の棚卸し手順に入れ、宣言された namespace・XAddr・バージョンをすべて保持します(未知のサービス、重複、欠けたフィールドも含む)。照会に失敗したら空リストを捏造せずnullを返します。 - プロファイルごとのエンコーダ options。 コーデック集合、コーデックごとの解像度、Media1 のフレームレート「範囲」、Media2 の小数フレームレート宣言リスト(29.97 は 29.97 のまま、30 に丸めません)。デバイスが宣言したことだけを出し、「コーデック×解像度×フレームレートの任意の組み合わせが使える」とは主張しません。
-
PTZ の宣言情報。 ノードの容量(
MaximumNumberOfPresets)、ホームポジション/巡回サポートの宣言、プロファイルごとのプリセット実件数と名前。座標は一切出力せず、同じノードを共有するプロファイル間で件数を合算しません。容量と実数は別フィールドに厳密に分けます。 -
認証ゲートの強化。 SOAP Fault のない素の HTTP 401 を含め、いかなる認証拒否の後も、そのデバイスへ資格情報付きリクエストを二度と送りません。任意照会の結果は
ok/unsupported/auth_blocked/failed/unqueriedの状態で明示され、デバイス全体の評価を静かに引き下げることはありません。
ついでに、正直に書いておくべき意味論バグも直しました。channel_count は物理ソースではなく「設定トークン」を重複排除していたため、1つのソースに2つの設定があると2チャンネルと数えていました。今は実ソーストークンで数え、どちらの基準で数えたかを記録します。
すべて読み取り専用の Get* 照会のみ、ユーザー指定の資格情報は1回だけ試行、パスワードはレポートに書きません。依存ゼロの Python のままです。
正直な現状
検証はシミュレータ(通常/旧ファーム風/厳格な Media2 の3ペルソナ)に対してで、86 テスト(LAN ホスト上での WS-Discovery エンドツーエンド含む)が通っています。実カメラでの検証はまだで、その旨はリリースノートにも明記しています。実機で動かした方は、個人情報を除いたデバイスレポートを Issue テンプレートで送っていただけると、スターより助かります。
リポジトリ:
リリース: