前回は USB シリアル変換アダプタによる通信だったので今回は Bluetooth で。
メインの Ubuntu から Raspberry Pi に Bluetooth で接続してシェルで操作できるようにするまで。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 17.04 Release: 17.04 Codename: zesty
pi@raspberrypi:~$ lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 8.0 (jessie) Release: 8.0 Codename: jessie
とりあえず bluetoothctl
でのペアリングが終わってるものとする。
まず、Bluetooth でシリアル通信を行うには bluetoothd
を -C
オプション付きで起動しなければならない。-C
オプションが無い場合、sdptool
が使えない。
サービスとして起動している bluetoothd
を一旦止める。
pi@raspberrypi:~$ sudo systemctl stop bluetooth
bluetoothd
を手動でバックグラウンド起動。アダプタが落ちていることがあるので立ち上げ直しておく。
pi@raspberrypi:~$ sudo bluetoothd -C & pi@raspberrypi:~$ sudo hciconfig hci0 up
この時点ではまだシリアル通信ができない。
pi@raspberrypi:~$ sudo sdptool browse local | grep -i serial
sdptool
で SPP を追加する。add --channel={n}
で任意のチャンネルも指定できる。
pi@raspberrypi:~$ sudo sdptool add SP
pi@raspberrypi:~$ sudo sdptool browse local | grep -i serial Service Name: Serial Port "Serial Port" (0x1101) "Serial Port" (0x1101)
/dev/rfcomm0
に端末を割り当てて待機状態にする。rfcomm
コマンドの使い方がまだ掴めていない。getty
は agetty
へのリンク。
書式とオプションは以下の通り。
RFCOMM configuration utility ver 5.43 Usage: rfcomm [options] <command> <dev> Options: -i, --device [hciX|bdaddr] Local HCI device or BD Address -h, --help Display help -r, --raw Switch TTY into raw mode -A, --auth Enable authentication -E, --encrypt Enable encryption -S, --secure Secure connection -M, --master Become the master of a piconet -L, --linger [seconds] Set linger timeout -a Show all devices (default) Commands: bind <dev> <bdaddr> [channel] Bind device release <dev> Release device show <dev> Show device connect <dev> <bdaddr> [channel] Connect device listen <dev> [channel [cmd]] Listen watch <dev> [channel [cmd]] Watch
普通にログインさせる場合。
pi@raspberrypi:~$ sudo rfcomm watch 0 1 agetty rfcomm0 115200 linux
ユーザ pi
でオートログインするさせる場合。
pi@raspberrypi:~$ sudo rfcomm watch 0 1 agetty rfcomm0 115200 linux -a pi
認証無しでルートログインさせる場合。
pi@raspberrypi:~$ sudo rfcomm watch 0 1 agetty -n -l /bin/bash rfcomm0 115200 linux
watch
ではなく listen
もあるが、こっちは接続を切るとサーバ側の rfcomm
も終了する。
agetty
のオプションがよくわからんのだが、ログイン後に下記のエラーが表示される。apt-get update
なんかをやると躓く。
-bash: cannot set terminal process group (1825): Inappropriate ioctl for device -bash: no job control in this shell
接続元からは screen
コマンドなどで接続しにいくので rfcomm connect
ではなく rfcomm bind
しておく。
■書式
bind <dev> <bdaddr> [channel]
チャンネルは指定しなくても勝手に見つけてくれる。
$ sudo rfcomm bind 0 01:23:45:67:89:AB $ rfcomm rfcomm0: 01:23:45:67:89:AB channel 1 clean
これで接続元の /dev/rfcomm0
を使って接続する準備ができた。
screen
コマンドで rfcomm bind
してある /dev/rfcomm0
に接続する。
$ screen /dev/rfcomm0 115200 Raspbian GNU/Linux 8 raspberrypi rfcomm0 raspberrypi login:
別の端末で watch
なんかで状態のチェックをしておくといいかもしれない。
$ watch rfcomm -a rfcomm0: B8:27:EB:0D:F6:C4 channel 1 connected [tty-attached]
無事 Raspberry Pi に接続できたが、接続する度に最初に AT AT ???
みたいな AT
コマンドを何か送ってるっぽいのだが何だこれ?
USB シリアル変換アダプタで接続しているときは出ないので多分 rfcomm
関係だが AT
というワードで探すのは辛い…。なんとか見つけた「Disable AT command on rfcomm connect」に書いてあった。
ModemManager よ、またお前か…。
$ sudo systemctl stop ModemManager $ sudo systemctl disable ModemManager
コンソールのサイズが小さいのは stty
で調整。tmux
を使っている場合は一回 detach
してから。
$ stty rows 44 cols 148 $ tmux
とりあえずプロセスグループが設定できない問題以外はなんとかなったので /lib/systemd/system/bluetooth.service
を変更して起動時に Bluetooth シリアル通信ができるようにしておく。
pi@raspberrypi:~$ diff -u <(zcat /lib/systemd/system/bluetooth.service.gz) /lib/systemd/system/bluetooth.service --- /dev/fd/63 2017-07-02 14:53:53.958932366 +0900 +++ /lib/systemd/system/bluetooth.service 2017-07-02 13:35:31.721916663 +0900 @@ -5,7 +5,8 @@ [Service] Type=dbus BusName=org.bluez -ExecStart=/usr/lib/bluetooth/bluetoothd +ExecStart=/usr/lib/bluetooth/bluetoothd -C +ExecStartPost=/usr/bin/sdptool add SP NotifyAccess=main #WatchdogSec=10 #Restart=on-failure
pi@raspberrypi:~$ sudo systemctl daemon-reload pi@raspberrypi:~$ sudo systemctl restart bluetooth
/etc/systemd/system/rfcomm.service
を作成。
[Unit] Description=RFCOMM service After=bluetooth.service Requires=bluetooth.service [Service] ExecStart=/usr/bin/rfcomm watch 0 1 /sbin/agetty rfcomm0 115200 linux [Install] WantedBy=multi-user.target
pi@raspberrypi:~$ sudo systemctl daemon-reload pi@raspberrypi:~$ sudo systemctl start rfcomm pi@raspberrypi:~$ sudo systemctl enable rfcomm
プロセスグループが設定できない問題はよくわからんが、とりあえず Raspberry Pi にログインしたあとに tmux
起動すればいいっぽいので今日はここまで。(ctrl+a と ctrl+b が…)