ターミナルからBluetooth経由でファイル送信の画像
芽萌丸プログラミング部 @programming
投稿日 2020/10/28
更新日 2022/12/01 ✏

Linux

ターミナルからBluetooth経由でファイル送信

LinuxのターミナルからBluetooth経由でファイルを送信する方法のメモです。

目次:

前提

  • OS: Ubuntu 16.04.6 LTS

Bluetooth関連ツールのセットアップ

もしBluetooth関連ツールのインストールがまだなら:

## Bluetooth関連ツールのインストール:
$ sudo apt install bluez bluez-utils gnome-bluetooth

## Bluetoothデーモンの起動:
$ sudo systemctl start bluetooth
## 起動時にサービスを有効化:
$ sudo systemctl enable bluetooth

端末同士のペアリング

端末同士のBluetoothペアリングにはbluetoothctlというCLIツールを使うと簡単です。

例えば、Linuxマシンからターゲット端末(MACアドレスaa:bb:cc:dd:ee:ff)にBluetooth接続したいなら、ターゲット端末のBluetoothがONになっていることを確認後、Linuxマシンのターミナルから以下のようにペアリングを行います:

# bluetoothctlを実行
$ sudo bluetoothctl

[bluetooth]# power on

## ペアリング準備:
[bluetooth]# pairable on
[bluetooth]# discoverable on

## ペアリングの確認を出さないagentを設定:
[bluetooth]# agent NoInputNoOutput
[bluetooth]# default-agent

## 周辺デバイスのスキャンを開始:
[bluetooth]# scan on
Discovery started
[CHG] Controller xx:xx:xx:xx:xx:xx Discovering: yes
[NEW] Device aa:bb:cc:dd:ee:ff MyTargetDevice # <= ターゲット端末を発見!

## ターゲット端末(aa:bb:cc:dd:ee:ff)を発見したのでスキャンを止める:
[bluetooth]# scan off

## ペアリング:
[bluetooth]# pair aa:bb:cc:dd:ee:ff
# ...ここで相手のデバイス側にペアリング要求ダイアログが表示されます。

## 接続が完了したら次からは自動的にセットアップできるようにトラストしておきます:
[bluetooth]# trust aa:bb:cc:dd:ee:ff

## 一旦終了:
[bluetooth]# quit

## もう一度bluetoothctlを実行してみる:
$ sudo bluetoothctl
[NEW] Device aa:bb:cc:dd:ee:ff MyTargetDevice # <= 自動的にセットアップされています!
[bluetooth]# quit

Bluetooth経由でファイルを送信

CLIでファイル送信

ペアリングが完了していれば、以下の手順でターゲット端末へファイルを送信することができます: (ターゲット端末上ではファイルの受信要求に許可を出す必要があります。)

## 送信先のチャンネルを取得するために以下のコマンドを実行:
$ sdptool search --bdaddr aa:bb:cc:dd:ee:ff OPUSH

    Searching for OPUSH on aa:bb:cc:dd:ee:ff ...
    Service Name: OBEX Object Push
    Service RecHandle: 0x10004
    Service Class ID List:
      "OBEX Object Push" (0x1105)
    Protocol Descriptor List:
      "L2CAP" (0x0100)
      "RFCOMM" (0x0003)
        Channel: 12 # <=== チャンネルは 12 と判明!
      "OBEX" (0x0008)
    Profile Descriptor List:
      "OBEX Object Push" (0x1105)
        Version: 0x0100

## 送信先MACアドレス(aa:bb:cc:dd:ee:ff)とチャンネル(12)を指定して hoge.txt を送信:
$ obexftp --nopath --noconn --uuid none --bluetooth aa:bb:cc:dd:ee:ff --channel 12 --put ./hoge.txt

CLIでファイル送信 (要GNOME)

bluetooth-sendtoを使えばもっと簡単にファイル送信することもできます: (ただし、この方法は完全なヘッドレスではありません。GNOMEのWindowが立ち上がる半GUIプログラムです。)

# ./hoge.txtをMACアドレス aa:bb:cc:dd:ee:ff の端末に送信:
$ bluetooth-sendto --device=aa:bb:cc:dd:ee:ff ./hoge.txt

Bluetooth経由でファイルを受信

ファイル受信を待受け

例えば、スマホからBluetooth送信されたファイルをUbuntu PC側で受信したい場合は、Ubuntu PC側にobexpushデーモンをセットアップする必要があります:

# obexpushdをインストール:
$ sudo apt install obexpushd

# ファイル出力先フォルダを作成:
$ mkdir ~/bluetooth

# bluetoothdの起動パラメータをカスタム:
$ sudo nano /etc/systemd/system/bluetooth.target.wants/bluetooth.service

...
## obex系の処理を行うためには bluetoothd 起動時に --compat オプションを付加する必要があります:
#ExecStart=/usr/lib/bluetooth/bluetoothd
ExecStart=/usr/lib/bluetooth/bluetoothd --compat
...

# obexpushをサービスとして登録:
$ sudo nano /etc/systemd/system/obexpush.service

[Unit]
Description=OBEX Push service
After=bluetooth.service
Requires=bluetooth.service

[Service]
## TODO:
## /home/<ユーザ名>/bluetooth/ の箇所はファイル出力先です。
## ご自身の環境に合わせて変更して下さい:
ExecStart=/usr/bin/obexpushd -B -n -o /home/<ユーザ名>/bluetooth/

[Install]
WantedBy=multi-user.target

# obexpushサービスの有効化:
$ sudo systemctl enable obexpush

# bluetoothd & obexpushを再起動:
$ sudo systemctl daemon-reload
$ sudo systemctl restart bluetooth
$ sudo systemctl restart obexpush

以上でBluetooth経由で外部からファイルを受信できるようになります。

TIPs: ペアリング済みのBluetooth機器からファイル送信がうまく行かない、またはBluetooth機器自体が動作しない場合の対処

対処A: ファイル送信がうまく行かない場合は、ペアリングを一旦削除して上述のペアリング作業をもう一度やり直すとうまく行く場合があります。ちなみにペアリング削除は bluetoothctl から[bluetooth]# remove aa:bb:cc:dd:ee:ff で行うことができます。

対処B: ホスト側に接続されているBluetooth機器を再接続することで対処できる場合があります:

#
# 接続済みのBT機器を再接続させます:
#
$ sudo systemctl restart bluetooth
$ bluetooth-wizard
## GUIが開いて「デバイスの検索」を暫く走らせておくとBT機器が再接続されます。
## 機器の再接続が確認できたらGUIを閉じても大丈夫です。

再接続の手順は上記の通り、 まずホスト側で bluetoothd を再起動し、その後に blutooth-wizard のGUIを起動し「デバイスの検索」を走らせます。暫くするとペアリング済みのBluetooth機器が再接続されます。

BT機器からのファイル送信がうまく行かなかった場合でも、上記の手順で再接続後にもう一度ファイル送信を行うと成功する場合があります。

以上です。


芽萌丸プログラミング部
芽萌丸プログラミング部 @programming
プログラミング関連アカウント。Web標準技術を中心に書いていきます。フロントエンドからサーバサイドまで JavaScript だけで済ませたい人たちの集いです。記事は主に @TanakaSoftwareLab が担当。