Matter 21 · デバッグとテスト — 切り分けの技術

Chapter 21

デバッグとテスト — 切り分けの技術

この章がなぜ必要なのか——Matter の障害は「症状から原因が読めない」.

「機器が見つかりません」——この 1 つのメッセージの裏に、 IPv6・mDNS・BLE・証明書・ACL・ファームウェアのバグ、 あらゆる可能性がある。

闇雲にログを読むのではなく、層ごとに切り分ける技術が要る。 この章はそのための道具立てである。

この章で使う既出の用語(定義は各リンク先). Matter(01 章 3 節)、コミッショニング(01 章 3 節)、ネットワーク(01 章 3 節)、Cluster(02 章 2 節)、Command(02 章 2 節)、IPv6(02 章 1 節)、MRP(02 章 1 節)、リンク(02 章 1 節)、mDNS(03 章 4 節)、マルチキャスト(03 章 3 節)、Router(04 章 2 節)、Wi-Fi(04 章 9 節)、BLE(05 章 1 節)、Ethernet(05 章 1 節)、必要(05 章 5 節)、DNS-SD(06 章 1 節)、PASE(06 章 4 節)、SAI(06 章 3 節)、SII(06 章 3 節)、SRP(06 章 2 節)、再送(06 章 3 節)、AttributeList(07 章 2 節)、OnOff(08 章 2 節)、Fail-Safe(09 章 9 節)、Read(09 章 1 節)、ステータスコード(09 章)、パスコード(11 章 5 節)、証明書(11 章 5 節)、CSA(12 章 3 節)、DAC(12 章 11 節)、初期状態(13 章 6 節)、ロールバック(18 章 5 節)

1. 切り分けの基本方針

下の層から順に確認する。上から見ると必ず迷子になる。

  [7] ACL / アプリケーション    ← 最後
  [6] CASE / セッション
  [5] 証明書 / PASE
  [4] mDNS / DNS-SD
  [3] IPv6 到達性
  [2] ネットワーク参加(Wi-Fi / Thread)
  [1] 電源・起動・ログ出力        ← 最初
層確認方法
1シリアルログが出るか
2ot-ctl state / Wi-Fi の接続状態
3ping6 ff02::1、ping6 <addr>
4dns-sd -B _matter._tcp / avahi-browse / ot-ctl srp server service
5機器ログの PASE / Attestation
6機器ログの CASE、--paa-trust-store-path
7ステータスコード 0x7E、ACL の読み出し

2. ログ

レベル

レベル内容
Errorエラーのみ
Progress主要な進行(通常はこれ)
Detail詳細
Automationテスト自動化向けの構造化出力
# chip-tool のログレベル
chip-tool --trace_decode 1 onoff toggle 1 1

# 機器側は SDK のビルド設定で(例)
CHIP_CONFIG_LOG_LEVEL=Detail

読むべきキーワード

キーワード意味
Commissioning の各ステージ名どこまで進んだか
PASE, SPAKE2pパスコードの検証
Attestation, DAC, CD証明書の検証
AddNOC, AddTrustedRootCertificateFabric の追加
CASE, Sigma1/2/3運用セッションの確立
MRP, retransmission再送
Access Control, deniedACL の拒否
Fail-safe巻き戻し

「どこまで進んだか」が分かれば、原因の範囲は一気に狭まる. ログの最後に出ているステージの次が失敗している。

3. パケットキャプチャ

Wi-Fi / Ethernet

# Wireshark で Matter のフィルタ
udp.port == 5540
mdns
icmpv6

Wireshark は Matter のディセクタを持っている. ただし暗号化されているので中身は見えない。 セッション鍵をログから取り出して復号する仕組みもあるが、手間がかかる。

見えるのは「パケットが飛んでいるか」「ACK が返っているか」。 それだけでも切り分けには十分役立つ。

Thread

Thread のパケットを見るにはスニファが要る。

[nRF52840 dongle など] + [nRF Sniffer for 802.15.4 / Silicon Labs の Network Analyzer]
   → Wireshark に流し込む
   → Thread のネットワーク鍵を入れれば、リンク層は復号できる

Thread のスニファは、Thread レベルの問題を切り分けるのに極めて有効である. 「機器がそもそも送信しているのか」「親に届いているのか」 「SED が Poll しているのか」が見える。

ネットワーク鍵を入れれば 802.15.4 の暗号は解けるが、 その上の Matter のセッションは別鍵なので中身は見えない。

BLE

nRF Sniffer for Bluetooth LE、または各社のスニファ
   → コミッショニングの BLE 段階を観測できる

4. 症状別の診断

「BLE で見つからない」

確認方法
機器がアドバタイズしているかBLE スキャナアプリ(nRF Connect など)
Discriminator が一致しているかログと QR コードを突き合わせる
Commissioning Window が開いているか機器のログ
スマホの BLE 権限OS の設定
既にコミッショニング済みファクトリリセット

「ネットワーク参加後に見つからない」(最頻出)

1. 機器が IP アドレスを取得しているか
      → 機器のログ、ot-ctl ipaddr
2. ping6 が通るか
      → ping6 <addr>%<iface>
3. mDNS が出ているか
      → dns-sd -B _matter._tcp / avahi-browse -r _matter._tcp
4. Thread なら SRP 登録
      → ot-ctl srp client state / ot-ctl srp server service
5. マルチキャストが通る環境か
      → ping6 ff02::1 で機器が見えるか

ここが 8 割の障害の在り処である。 03 章と 06 章に戻ること。

「コマンドが失敗する」

ステータス原因
0x7E UNSUPPORTED_ACCESSACL(14 章)
0x81 UNSUPPORTED_COMMAND未実装
0x86 UNSUPPORTED_ATTRIBUTE未実装 or ID の誤り
0x87 CONSTRAINT_ERROR値域外
0xC3 UNSUPPORTED_CLUSTERクラスタ未実装
0xC6 NEEDS_TIMED_INTERACTIONTimed Request が必要
# ACL を確認する
chip-tool accesscontrol read acl <node-id> 0
# 実装されている属性を確認する
chip-tool any read-by-id 0x0006 0xFFFB <node-id> 1   # AttributeList
chip-tool any read-by-id 0x0006 0xFFF9 <node-id> 1   # AcceptedCommandList

「時々失敗する」

最も厄介な種類。疑うべきもの:

原因確認
スレッドセーフティ違反別スレッドから SDK を呼んでいないか(16 章)
電波干渉チャネルを変えて再現するか(04 章)
メモリ不足ヒープの使用量、RESOURCE_EXHAUSTED
SED の Poll タイミングSII/SAI の設定、再送ログ
メッセージカウンタ再起動後に失敗するか(06 章)
電源の不安定電流測定

「たまにクラッシュする」の第 1 容疑者はスレッドセーフティである. 割り込みハンドラやセンサーのタスクから 直接 SDK の属性 API を呼んでいないか、コードを全部確認すること。

5. 自動テスト

YAML テスト(従来型)

SDK には YAML で記述されたテストスクリプトがある。

tests:
    - label: "Read OnOff attribute"
      cluster: "On/Off"
      command: "readAttribute"
      attribute: "OnOff"
      response:
          value: false
./scripts/tests/run_test_suite.py --target TestOnOff run

Python テスト(推奨)

from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main
import chip.clusters as Clusters
from mobly import asserts

class TestMyDevice(MatterBaseTest):
    @async_test_body
    async def test_onoff(self):
        # 初期状態
        v = await self.read_single_attribute(
            self.default_controller, self.dut_node_id,
            endpoint=1, attribute=Clusters.OnOff.Attributes.OnOff)
        asserts.assert_false(v, "初期状態は OFF のはず")

        # ON にする
        await self.send_single_cmd(Clusters.OnOff.Commands.On(), endpoint=1)
        v = await self.read_single_attribute(
            self.default_controller, self.dut_node_id,
            endpoint=1, attribute=Clusters.OnOff.Attributes.OnOff)
        asserts.assert_true(v, "ON になっているはず")

if __name__ == "__main__":
    default_matter_test_main()

認証テスト(22 章)も Python で書かれるようになっている. 自社のテストを同じ枠組みで書いておけば、 認証テストの実行環境をそのまま流用できる。

CI に入れるべきもの

項目内容
ビルド全ターゲット
ZAP の再生成差分.zap と生成コードの整合(16 章)
単体テストロジック部分
統合テストLinux 上のサンプルと chip-tool で往復
静的解析メモリ安全性
テスト証明書の混入チェック量産ビルドに VID 0xFFF1 が入っていないか(12 章)

最後の項目は必ず入れること. テスト証明書で量産する事故を、仕組みで防ぐ。

6. 実機テストのチェックリスト

基本

マルチアドミン

異常系

長期

「停電からの一斉復帰」は必ずテストすること. 実験室で 1 台ずつ動かしても発見できない。 家中の機器を模擬して、同時に電源を入れるテストが要る。

7. 便利なツール一覧

ツール用途
chip-toolCLI コントローラ(15 章)
chip-replPython 対話環境
chip-cert証明書の生成・検証
ota_image_tool.pyOTA イメージの作成・確認(18 章)
spake2pSPAKE2+ 検証子の生成
chip-tool payloadQR / 手動コードの解析
ot-ctlThread の操作(04 章)
dns-sd / avahi-browsemDNS の確認
Wiresharkパケット解析
nRF Connect(モバイル)BLE スキャン
Thread スニファ802.15.4 の解析
電流計 / パワーアナライザ電池寿命の実測
# QR コードを解析する
chip-tool payload parse-setup-payload MT:Y.K9042C00KA0648G00

# 手動コードを解析する
chip-tool payload parse-setup-payload 34970112332

# SPAKE2+ 検証子を生成する
./out/spake2p/spake2p gen-verifier -f - -i 10000 -s <base64-salt> -p 20202021

8. 問い合わせ・情報源

情報源内容
仕様書(CSA)最終的な正
GitHub Issues(connectedhomeip)同じ問題に他の人が当たっている可能性が高い
SDK のソース仕様書で分からないときの実装の実際
SoC ベンダーのフォーラムプラットフォーム固有の問題
CSA の会員向けリソース認証関連

GitHub の Issue 検索は極めて有効である. Matter は新しい標準なので、あなたが遭遇する問題の多くは既知である。 エラーメッセージをそのまま検索するだけで解決することが多い。

9. まとめ