2015年10月15日木曜日

RaspberryPi で Error: connect: Connection refused (111)

概要

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 up

  • Bluetooth: 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週間はがんばったと思います
この記事が誰かの助けになれば幸いです

1 件のコメント:

  1. 同じエラーで困っていました。大変助かりました!
    詳細な記事をありがとうございます

    返信削除