BLE Nano (nRF51) + mbed でセキュリティ付きペアリングをして 0x3d エラーがでる
0x3d はMessage Integrity Check (MIC)が失敗した、というエラーらしい。ホスト側で発生する。デバイス側から送られてきたメッセージのセキュリティチェックエラーのようだ。
ということで、デバイススタックの SoftDevice のバグでは? と思うところだけど、そうではないらしい。どうやら mbed と相性が悪いらしい。
解決の糸口
0x3d が出るのは最初はファームウェアのバグでどこかが stuck しているからだと思っていた。しかしどうも stuck していなくても 0x3d が起こることがある。で、そろそろ Nordic スタックのバグを疑ってみる。しかしそこのバグなら既にハマっている人がいるはずなのでググる。
すると Implement BLE security · Issue #44 · lancaster-university/microbit-dal · GitHub あたりに Nordic のバグじゃね? みたいな話がでてくる。そこからサブイシューがつくられている。
MIC failures observed with secure BLE · Issue #61 · lancaster-university/microbit-dal · GitHub で
Problem is caused by mbed-classic disabling interrupts when a timer interrupt is triggered. This was too long for the underlying BLE stack to code with during critical radio events.
と原因と、さらに解決策がいくつか示されている。一番簡単なのが3つめなので、このプロジェクトでは3つめが採用されたっぽい。しかし肝心のコミットへのリンクはないので頑張って探す。
Merge branch 'secure-ble' · lancaster-university/microbit-dal@3c31479 · GitHub このコミットをつらつら眺めていくと、どうやら対策コードっぽいものが見つかった。
// configure the stack to hold on to CPU during critical timing events.
// mbed-classic performs __disabe_irq calls in its timers, which can cause MIC failures
// on secure BLE channels.
ble_common_opt_radio_cpu_mutex_t opt;
opt.enable = 1;
sd_ble_opt_set(BLE_COMMON_OPT_RADIO_CPU_MUTEX, (const ble_opt_t *)&opt); ここで SoftDevice の API を呼んで、無線アクティビティがあるときはCPUを完全にブロックしてアプリケーションの実行を止めるらしい。簡単なコードだ。
コピペしてみるとエラーの発生がなくなった。まじ良かった……
備考:エラーのログ
Apple が提供している Bluetooth Explorer の Event Log を開きっぱなしにしておけば、接続情報について常にデバッグログに残る。
このエントリを参照するエントリ
関連エントリー
- Mac に RMagick がインストールできない。 $ sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/...
- OSX + BLE で HID over GATT でペアリング(bonding)ができなくてハマった BLE Nano + mbed で HID over GATT しようとして1日ハマっていたので記録しておきます。HID の問題というよりペ...
- mbed USBSerial を WebUSB から扱うには mbed USBDevice ライブラリの中に USB CDC で動く USBSerial クラスが実装されている。これを Web USB ...
- BLE Nano のオンラインプロジェクトをエクスポートして GCC でコンパイルして RAM 32kB 使えるようにする 必要なもの arm-none-eabi-* とsrecord が必要。platformio を使ってるなら arm-none-eabi は ...
- https 通信が不可能な原因が時刻ずれ 手元の NanoPi NEO2 が、証明書エラーでどうしても https 通信が不可能に。 Ubuntu 16.04 なのでそれほど古いOS...