概要
RaspberryPi で BLE と connect するために gatttool やら hcitool を使っていたのですがタイトルのエラーが解消できずに悩んでいました
ようやく解決できたので紹介します
環境
- Raspberry Pi Type B Single Board Computer 512MB
- Raspbian 7.8 (Wheezy) -> 8.0 (Jessie)
- Kernel Version 4.17 -> 4.1.10
- BlueZ 5.35 -> 5.23-2+b1
- Bluetoothレシーバ : ELECOM Bluetooth PC用USBアダプタ 超小型 Ver4.0 Class2 forWin8 ブラック LBT-UAN05C2
解決方法
結論から述べると自分のケースでは
OS と kernel をアップグレードし BlueZ を再インストール
することで解決しました
OS アップグレード方法
一旦 Wheezy のパッケージを最新にします
- sudo apt-get update
- sudo apt-get upgrade
- sudo apt-get dist-upgrade
apt の対象リポジトリを Jessie に変更します
- sudo cp /etc/apt/sources.list{,.wheezy}
- sudo vim /etc/apt/sources.list
deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpi
再度アップデートコマンドを実行します
- sudo apt-get update
- sudo apt-get upgrade
- sudo apt-get dist-upgrade
すべて完了したら再起動します
OS のバージョンと kernel のバージョンを確かめましょう
- sudo reboot
- cat /etc/issue
- uname -a
BlueZ の再インストール
過去にソースをコンパイルしてインストールしていたものを Jessie にすることで apt でインストールできる BlueZ に入れ替えます
ソースからインストールした hcitool 等は直接 rm で削除しました
- sudo rm /usr/local/bin/*
あとは apt-get で BlueZ をインストールすれば OK です
- sudo apt-get install bluetooth bluez blueman
Jessie になると bluez-utils というパッケージがなくなって bluez に統一されているようです
自分は念のためインストール後に再起動も実施しました
また、apt-get でインストールできるものに hcidump
がないので、これだけはソースコンパイルしてできた hcidump を適当に配置しました
- sudo cp ./bluez-5.35/tools/hcidump /usr/bin
P.S 20151029
hcidump は bluez-hcidump というパッケージに含まれているので sudo apt-get install bluez-hcidump
でもインストール可能です
BLE デバイスの検知
OS をアップグレードした状態で hcitool と gatttool を使ってBLE デバイス(今回は SensorTag ) を検知してみました
USBドングルを接続はあらかじめ接続しておいてください
Macアドレスのスキャンおよび接続テスト
別ターミナルで詳細を確認するために hcidump を起動しておいてください
- sudo hcidump -X
まずは BLE デバイスをスキャンします
もちろん BLE デバイスは Advertise できるように電源を入れてください
- sudo hcitool -i hci0 lescan
検出された Mac アドレスに接続テストします
- sudo hcitool -i hci0 lecc xx:xx:xx:xx:xx:xx
接続が持続されているか確認します
- sudo hcitool con
これで接続したはずの BLE デバイスが表示されないとうまく接続できていないことになります
おそらく大丈夫だと思いますがダメな場合は lecc のコマンドに --random
のオプションを付けて実行してみてください
安定した接続が確認できたら lecc 時に発行されるハンドル番号をもとに一旦切断します
- sudo hcitool ledc NN
切断しない状態で gatttool 等を実行すると
Error: connect error: Device or resource busy (16)
というエラーが発生してしまいます
gatttool で接続する
では次に gatttool でも接続してみましょう
先ほど lescan で検知した同一の Mac アドレスに接続してください
- gatttool -b xx:xx:xx:xx:xx:xx -I
lecc 時に --random
をつけていた場合には gatttool 実行時にも random で接続してください
- gatttool -t random -b xx:xx:xx:xx:xx:xx -I
これでインタラクティブモードに入ります
問題の元凶である Connection refused (111) はここで connect 時に発生していました
[xx:xx:xx:xx:xx:xx][LE]> connect
Attempting to connect to xx:xx:xx:xx:xx:xx
Connection successful
こんな感じになれば OK です
あとは SensorTag を Read/Write してみましょう
終わったら disconnect してください
[xx:xx:xx:xx:xx:xx][LE]> char-read-hnd 0x25
Characteristic value/descriptor: 0a 26 00 00 00 00 00 00 00 00 b0 00 40 51 04 03 aa 00 f0
[xx:xx:xx:xx:xx:xx][LE]> char-write-cmd 0x29 01
[xx:xx:xx:xx:xx:xx][LE]> disconnect
その他試したこと
いろいろと Try&Error したので覚えている限りで事象を記載します
もちろんここに記載していることは全部ダメでした
hcitool, gatttool のコマンドオプションをいろいろ変更してテスト
特にタイプの public や random を変更してやってみました
関係ないわけではないですが、根本対応が問題で効果はありませんでした異なる USB ドングルを使ってみる
RaspberryPi に接続されているドングルが原因なのではと思い ELECOM 製以外の USB ドングルを接続してみましたがダメでした
また、USB ドングルの再接続も何度か試しましたHCIの再起動
sudo hciconfig hci0 down
sudo hciconfig hci0 up
で再起動してみましたがダメでしたBlueZ のバージョンアップ
実は初めは 4.99 で試していました
それでダメだったのでソースインストールに切り替えたのですがそれでもダメでした既存の BlueZ の削除
apt-get でインストールした 4.99 を apt-get –purge remove してからソースインストールしたのですが、ダメでした別のBLEデバイスを用意してテスト
BLE デバイス側が悪いのではと原因を切り分けるために別の BLE デバイスを用意してテストしました
用意したデバイスは BL600 と 自作のペリフェラルiPhoneアプリを作成しましたKernel のバージョンだけあげて BlueZ を再コンパイル&インストール
rpi-update を使ってカーネルのバージョンをアップデートしました
結果的にカーネルだけではダメでしたOS のバージョンをあげて BlueZ を再コンパイル&インストール
OS のバージョンをあげた場合はソースインストールせず、apt で配布されている BlueZ を使用するのが正解でした
Tips
bluez-simple-agent や bluez-test-device, bluez-test-input 等のコマンドがなくなっています
bluez-utils のパッケージが Jessie では削除されているため上記のコマンドが使えなくなります
調べた限りだと bluetoothctl というコマンドで代用するみたいですが、詳細な方法(コマンド)までは調べていませんCould not create connection: Connection timed out
hcitool lecc
コマンドで上記のエラーが発生することがあります
このエラーがでると同じ Mac アドレスに次回以降接続しようとしても Could not create connection: Input/output error となり接続できません
その場合は hcitool を使って対象の hci を再起動してくださいsudo hciconfig hci0 down
sudo hciconfig hci0 upBluetooth: SMP security requested but not available
lecc 実行時に dmesg のログに発生する
初めはこれが問題だと思いいろいろとググるが結果的に問題なく lecc できていたときにも発生していた
とりあえず原因不明のまま無視することにした接続できない場合の hcidump の特徴
> HCI Event: Command Status (0x0f) plen 4
LE Create Connection (0x08|0x000d) status 0x00 ncmd 1
> HCI Event: Command Status (0x0f) plen 4
LE Read Remote Used Features (0x08|0x0016) status 0x00 ncmd 1
> HCI Event: Command Status (0x0f) plen 4
Disconnect (0x01|0x0006) status 0x00 ncmd 1
> HCI Event: Disconn Complete (0x05) plen 4
status 0x00 handle 72 reason 0x16
Reason: Connection Terminated by Local Host
うまく接続できない場合には hcidump にずっと上記のようなログが出力されていました
うまく接続できたと思っても Connection Terminated by Local Host が強制的に発生し BLE デバイスとの接続を勝手に切断sれていました
対処後はこのログも出なくなりました
最後に
対象のエラー文でググるとカーネルがバグっている系と BlueZ のバージョンをあげてくださいという記事が多く見受けられたような気がします
カーネルは確かに怪しかったので rpi-update でアップデートしたのですが、まさか OS まであげないとダメとは思いませんでした
そしてソースインストールした BlueZ も悪いとは思いませんでした
1週間はがんばったと思います
この記事が誰かの助けになれば幸いです
同じエラーで困っていました。大変助かりました!
返信削除詳細な記事をありがとうございます