2016/07/30

[nrf52]Centralしていく (3)

前回、何もいないのにAdvertisingのログが出る、と書いたけど、そういえばテスト中で動かしっぱなしにしているのがいるのを忘れていた。
それに、近くでAppleTVを持っている人がいるのか、それらしいAdvertisingもスニファで見えていた。

 

スニファと言えば、nRF51 DKをスニファとして使うというのは、ありなんじゃないかと思い始めている。
受信するだけだからだ。
まあ、送信する機能もある装置なのにどうよ、という気もするのだけど、その辺は信じてください、としか言いようがないな。

nRF52 Preview DKをスニファにしてみたのだが、まあまあ動いた。
数字を入力するタイプのペアリングを行うと、どうもうまく拾えないのだ。
まあ、まだ正式なnRF52用のFirmwareが出てないし、そもそもPreviewだしねぇ。

TIのスニファも、ペアリングのときからパスキーを打ち込んでいても途中で止まるのだ。
"TI ペアリング"で検索しても「ティファニーチタンペアリング」が出てきてガックリしたので、本題に戻ろう。


前回は半分寝ながら書いたので、もう一度。

出ているのは、BLE_GAP_EVT_ADV_REPORTイベントのログ。
typeが2と3のログが出ているが、これはまずtype=2で試して、だめだったら3で試す、という方式をとっているからだ。

2は、«Incomplete List of 16-bit Service Class UUIDs»。
3は、«Complete List of 16-bit Service Class UUIDs»。

IncompleteでもCompleteでもいいから、16bitのService UUID、つまりBluetooth SIGに登録されている一般的なUUIDがあるかどうかを見ているのだろう。

HRSのPeripheralでは、Complete Listを使っている。
0x180D(Heart Rate)、0x180F(Battery)、0x180A(Device Information)の3つだ。
services


Advertisingのデータは、Length, Type, Valueの並びだ。
Lengthは自分を含まない長さで、1byte。
TypeはAD Typeで、1byte。
たとえば、<<Flags>>は中身が1byteなので、Lengthは0x03、Typeは0x01だ。

BLE_GAP_EVT_ADV_REPORTイベントが来ると、p_ble_evt->evt.gap_evt.params.adv_reportにデータが返ってくるようだ。
型はble_gap_evt_adv_report_tで、こうなっている。

typedef struct {
  ble_gap_addr_t peer_addr;
  int8_t         rssi;
  uint8_t        scan_rsp : 1;
  uint8_t        type     : 2;
  uint8_t        dlen     : 5;
  uint8_t        data[BLE_GAP_ADV_MAX_SIZE(=31)];
} ble_gap_evt_adv_report_t;

あれ、typeって2bit分しかないの?と思ったが、そうではなくてBLE_GAP_ADV_TYPESの値とのこと。
なるほど、Advertisingの種類ということですな。
scan_rspが0のときだけ有効とのこと。

dataは31byteだから、ADV_INDなどのペイロードが全部入っているのだろう。
adv_report_parse()ではそれを頭から見ていって、typeが一致したらペイロードのアドレスとデータ長を返す、なければNOT_FOUNDを返す、という作りになっている。

 

今コミットしているソースだと、検索しているだけで、実際にそれを使うL.376~をコメントアウトしているから、次はそれを見ると良いだろう。

とりあえず、このくらいのソースでAdvertisingのスニファくらいはできるということはわかった。

2016/07/29

[win10]ウィンドウの枠を太くしようとしたが、ダメだった

Windows10にしてしばらく経つが、ウィンドウの枠が細いのが気になってきた。

普通はそこまでないのだが、コマンドプロンプトやTeraTermを重ねて非アクティブになると、境目がわからないのだ。

image

 

普通のテーマは、Aero.
C:\Windows\Resources\Themes\aero\aero.msstylesを使っている。
同じフォルダにあるaerolite.msstylesを使うと、太くなる!

image

太くなるのだけど、タスクバーの文字が黒になってしまうのだ。
うちは暗めの色を使っているので、これが黒になると使い勝手が悪い。

msstylesファイル自体をいじらないと、ちょっと使うのは厳しいようだ。


とまあ、結果だけだとそれで終わりなのだが、そこまでが長かった。

Themeファイルの構造を調べていたのだ。
https://msdn.microsoft.com/ja-jp/library/windows/desktop/bb773190(v=vs.85).aspx

PanelDesktopWindowMetricsを設定すればいけるかも、と思い、NonclientMetricsのデータ構造まで調べたのだよ。
https://msdn.microsoft.com/ja-jp/library/windows/desktop/ff729175(v=vs.85).aspx
https://msdn.microsoft.com/ja-jp/library/windows/desktop/dd145037(v=vs.85).aspx


 

でも、幅っぽいところを変えても変化が見られなくてね。。。
aeroliteにすると太くなるから、それしかないのだろうと思ったのだ。

msstylesファイルを編集するツールがあったのだけど、編集して保存するとサイズが変わるのよねぇ。
それに、aeroliteをコピーしてaerolite2を作ってみたけど、それをPathにしていしても反映されないようなのだ。
aeroliteのファイル名を変更しようとしたら、TrustedInstallerのアクセス権限がいるとかなんとか。
ちょっと特殊なようだ。

2016/07/28

[nrf52]Centralしていく (2)

nRF52832+S132でCentralを試していくシリーズ。

BLE接続させたくないを動かしてみよう。


立ち上げて、HRSのPeripheralを動かすとこういうログが出てきた。

[on_ble_evt]BLE_GAP_EVT_ADV_REPORT
[adv_report_parse]type=2
[adv_report_parse]type=3
[on_ble_evt]BLE_GAP_EVT_ADV_REPORT
[adv_report_parse]type=2
・・・

まず、最初のADV_REPORTは、ここだ。
on_ble_evt()でイベントを受けるのは、Peripheralと同じだ。
まあ、PeripheralでAdvertising中はon_adv_evt()なので、違うといえば違うのだが、Central目線で考えると妥当な気がするのだ。

 

BLEのPeripheralとCentralは、ネットのServerとClientの関係とちょっと違うように感じてしまうのだ。
ネットのHTTPサーバには、ブラウザというHTTPクライアントが接続しに行く。
BLEだと、PeripheralにCentralが接続しに行く。
だから、PeripheralがServerで、CentralがClientになることが多い。
データの提供元はだいたいセンサで、センサはPeripheralになっていることが多いからね。

なんとなくだが、データを集める方がサーバという気がしてしまうのだ。
クライアントがアップする、ということが多いからだろうか?
しかし、データを提供する方がServerで、もらう方がClientだから、いくらファイルサーバなどと名乗っていたとしても、データを提供するのはセンサだから、データを集めるファイルサーバはクライアントになるのだ。

言葉遊びみたいになってしまいますな。


さて、ログに戻ろう。

下からADV_REPORT通知が来て、adv_report_parse()を呼んでいる。
これはローカルな関数で、データがある限り解析をしているようだ。

そのtypeは、2と3だけだ。
2が"BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE"で、3が"BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE"だろう。

typeの定義値は、ble_gap.hにある。
値は、Bluetooth SIGのAD Typeと一致するようだ。
adv_report_parse()の実装からすると、受信したAdvertisingデータの中で指定したtypeがあったら解析してくれ、というやり方のようだ。

まあ、30バイト前後のデータだから、それでよいのかもしれない。
それに自作ではなく汎用のUUIDなので、この程度のチェックでよいということかもしれない。
自作だったら、Advertisingデータもある程度固定になるので、その内容までチェックしたいはずだ。


今日はこれまでだ。

まだわからないこととして、Peripheralを検知したあと、Peripheralの電源を切ってもイベントが来続けているのだ。
単に、コメントアウトのしかたがまずかったのか、来るのが普通なのかで実装が変わってくるだろう。

2016/07/27

[nrf52]Centralしていく (1)

サンプルソースを読んでいても眠たくなってしまうし、ブログに記事がないのも寂しいので、Centralを動かしていくことにしよう。

nRF52832で見ていくが、たぶんnRF51822+S130でもそんなに変わらないと思う。
うちも、IC rev3があればよかったのだが、まあ彼はPeripheralとしてがんばってもらおう。
S130でもPeripheralは動いているから、Centralでも動くような気はするのだけどね。


今日は初回で眠たいので、準備だけにしておく。

https://github.com/hirokuma/nrf52_central_sample

nRF5 SDK v11のCentralサンプルを、そのまま持ってきた。
gcc以外の環境を削ったり、ログ追加されていたりするが、ほぼそのままだ。

 

このまま動かすとサンプルが動くだけだから、理解のためにBLE接続していると思われる箇所をコメントアウトした。
BLE接続させたくない

これで接続されずにAdvertisingしているログだけ出るのでは、という予想だ。


試してみれば良いのだが、いま机の上でBLEの連続テスト中でね。。。
寝ている間にテストが終わるようにしたいのだ。

 

長い時間動かすと、普通ではわからなかったバグが見つかったりするから、みんなやった方がよいよ。
頻度が低くて、今まで見たこともなかったような現象が出たりするしね。
ええ、今出てますとも。。。

2016/07/24

[nrf52]Centralサンプルを動かす

いままでBLEのPeripheralしか作っていなかった。
受ける側のCentralはスマートフォンに任せておけば良いだろう、と思っていた。

が、通信がうまく行かないことがあって、無線状況が原因では無さそうな感じがした場合、それが誰のせいなのかよくわからない。
スニファで見られるときは良いのだけど、TIのドングルはペアリングしていると接続後に途中でパケットが見えなくなってしまうようなのだ。

スマートフォン側のログを見ても、全部出るわけじゃないし、なんでそういうことになったのかまではわからない。
なんとなくドライバが原因のような気はするのだけど、もしかしたらPeripheral側がちょっとよくないのかもしれない。

 

こういう、Peripheral側にも原因があるのではないかという不安を払拭するためには、もっと信頼性の高いCentralが必要だ。
お客さんに「たぶんスマートフォンのBLEドライバ周りが原因だと思うんですけど。。。」と語尾を濁すのには疲れたのだ。

nRF Connectのデスクトップ版が使えるとよかったのだけど、nRF52 DKのようなNordicが出している基板じゃないと動かないようだった。

nRF51822がいくつかあるので、それでCentralを回せば良いのだけど、どうもS130はIC revisionが3以上ではないと動きを保証してくれないようなのだ。
じゃあ、nRF52832でやろう。


今回は、サンプルを動かすだけの紹介だ。
評価ボードは、太陽誘電さんのEBSHCNZXZを使う。

nRF5 SDK v11.0.0のexamples\ble_central\ble_app_hrs_cを使う。
「_c」は、Centralだと思うが、もしかしたらHRSのclientという意味かもしれない。

gcc版で試しているが、特に難しいことはなく、PCA10040でmakeするだけでよい。
これをEBSHに焼いて起動する。
USBはシリアルポートとして見えるので、TeraTermなどでつないでおく。115200bpsだ。
そうすると起動時に「Heart rate collector example」が出力される。

あとは、HRSのPeripheralを動かすだけだ。
今回はnRF51822のHRSサンプルをS110上で動かした。
そうするとペアリング(たぶんJust Works)して、取得した値をシリアルポートで見ることができる。

あっさりだ。


シリアルに出力されるのはAPPL_LOG()の内容で、デバッグ情報のAPPL_LOG_DEBUG()はそのままでは出力されない。
Makefileに「-DDEBUG」などとしてDEBUGマクロを有効にしておくと、nrf_log.hが使えるようにしてくれる。

 

ペアリングさせないようにSEC_PARAM_BONDをどちらも0にしたけど、DM_LINK_SECURED_INDのルートを通るな、うーむ。。。

まあ、ともかく、サンプルは簡単に動かせることがわかったので、中身を見ていこう。