【Linux】bluetoothctlコマンドでBluetoothを操作してみる

# はじめに
@noraworldさんの[bluetoothctl のコマンド一覧と使い方をまとめてみた](https://qiita.com/noraworld/items/55c0cb1eb52cf8dccc12)という記事を参考にしてBluetoothのコマンドを叩いてみました。

`bluetoothctl`はBluetoothに関する一通りの操作ができるので色んな用途に使えそうです:muscle: 

# 確認環境
- Thinkpad X260
- Ubuntu 22.04.2 LTS
- bluetoothctl 5.64

# 1. Bluetoothアダプタの状態を確認する
`hciconig`コマンドで確認できます。`UP RUNNING`とあるので動いてますね :thumbsup: 

```
~ $ hciconfig 
hci0:	Type: Primary  Bus: USB
	BD Address: A4:34:D9:FD:86:FC  ACL MTU: 1021:4  SCO MTU: 96:6
	UP RUNNING 
	RX bytes:1625854 acl:0 sco:0 events:70882 errors:0
	TX bytes:722577 acl:0 sco:0 commands:25880 errors:0
```

# 2. Bluetoothサービスの状態を確認する
Linux上のBluetoothサービスが動いているか確認します。 `active` と表示されてるので動いてますね :thumbsup: 

```shell
$ sudo systemctl status bluetooth
bluetooth.service - Bluetooth service
     Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2023-06-27 09:57:53 JST; 1h 33min ago
       Docs: man:bluetoothd(8)
   Main PID: 719 (bluetoothd)
     Status: "Running"
      Tasks: 1 (limit: 8732)
     Memory: 1.9M
        CPU: 138ms
     CGroup: /system.slice/bluetooth.service
             └─719 /usr/lib/bluetooth/bluetoothd
```

Bluetoothサービスが動いていない場合、以下のコマンドで有効にします。

```shell
$ sudo systemctl enable bluetooth
$ sudo systemctl start bluetooth
```

:::note info
以降のコマンドは `bluetoothctl`コマンドのインタラクティブモードで実行します。
:::

```shell
~ $ bluetoothctl 
Agent registered
[CHG] Controller A4:34:D9:FD:86:FC Pairable: yes
```


# 3. Bluetoothをオフ・オンする

`power off`でオフになります。

```shell 
[bluetooth]# power off
Changing power off succeeded
```

次にオンにしてみます。
```
[bluetooth]# power on
[CHG] Controller A4:34:D9:FD:86:FC Class: 0x007c010c
Changing power on succeeded
[CHG] Controller A4:34:D9:FD:86:FC Powered: yes
```

# 4. 周囲のデバイスをスキャンする

スキャンを開始します。検出されたデバイスのBluetoothアドレス等が表示されます。

```sh
[bluetooth]# scan on
Discovery started
[CHG] Controller A4:34:D9:FD:86:FC Discovering: yes
[NEW] Device 52:E5:7A:A4:08:5B 52-E5-7A-A4-08-5B
[NEW] Device 6B:DF:7E:ED:AC:A6 6B-DF-7E-ED-AC-A6
[NEW] Device 5F:D4:67:B4:E5:76 5F-D4-67-B4-E5-76
[NEW] Device 7D:37:5A:D5:AB:9C 7D-37-5A-D5-AB-9C
[bluetooth]# scan off
Discovery stopped
```

スキャンを停止します。
```sh
[bluetooth]# scan off
Discovery stopped
```


# 5. Bluetooth接続する
`connect` コマンドに接続先のBluetoothアドレスを指定します。
接続が完了するとGATTサービスの情報が表示されます。

```shell接続するデバイスの
[bluetooth]# connect FD:F5:ED:DF:ED:1D
Attempting to connect to FD:F5:ED:DF:ED:1D
[CHG] Device FD:F5:ED:DF:ED:1D Connected: yes
Connection successful
[NEW] Primary Service (Handle 0x0000)
	/org/bluez/hci0/dev_FD_F5_ED_DF_ED_1D/service000a
	00001801-0000-1000-8000-00805f9b34fb
	Generic Attribute Profile
[NEW] Primary Service (Handle 0x0000)
	/org/bluez/hci0/dev_FD_F5_ED_DF_ED_1D/service000b
	0000fd81-0000-1000-8000-00805f9b34fb
	CANDY HOUSE, Inc.
[NEW] Characteristic (Handle 0x0000)
	/org/bluez/hci0/dev_FD_F5_ED_DF_ED_1D/service000b/char000c
	16860002-a5ae-9856-b6d3-dbb4c676993e
	Vendor specific
[NEW] Characteristic (Handle 0x0000)
	/org/bluez/hci0/dev_FD_F5_ED_DF_ED_1D/service000b/char000e
	16860003-a5ae-9856-b6d3-dbb4c676993e
	Vendor specific
[NEW] Primary Service (Handle 0x0000)
	/org/bluez/hci0/dev_FD_F5_ED_DF_ED_1D/service0011
	0000fe59-0000-1000-8000-00805f9b34fb
	Nordic Semiconductor ASA 
[NEW] Characteristic (Handle 0x0000)
	/org/bluez/hci0/dev_FD_F5_ED_DF_ED_1D/service0011/char0012
	8ec90003-f315-4f60-9fb8-838830daea50
	Vendor specific
[CHG] Device FD:F5:ED:DF:ED:1D UUIDs: 00001800-0000-1000-8000-00805f9b34fb
[CHG] Device FD:F5:ED:DF:ED:1D UUIDs: 00001801-0000-1000-8000-00805f9b34fb
[CHG] Device FD:F5:ED:DF:ED:1D ServicesResolved: yes
```

# 6. 接続したデバイスの情報を表示する
`info`コマンドにBluetoothアドレスを指定します。
デバイスの接続状態、GATTサービスUUIDなどが表示されます。

```
[U/0u9BBZk13ePoI6rg3lxA]# info FD:F5:ED:DF:ED:1D
Device FD:F5:ED:DF:ED:1D (random)
	Name: -----------------------
	Alias: -----------------------
	Paired: no
	Trusted: no
	Blocked: no
	Connected: yes
	LegacyPairing: no
	UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
	UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
	UUID: CANDY HOUSE, Inc.         (0000fd81-0000-1000-8000-00805f9b34fb)
	UUID: Nordic Semiconductor AS.. (0000fe59-0000-1000-8000-00805f9b34fb)
	ManufacturerData Key: 0x055a
	ManufacturerData Value:
  03 00 01 85 f8 a6 39 00 5e 1a 55 72 e1 76 ce 96  ......9.^.Ur.v..
```

# 7. 切断する
切断するデバイスのBluetoothアドレスを指定します。

```sh
[FD:F5:ED:DF:ED:1D]# disconnect FD:F5:ED:DF:ED:1D
Attempting to disconnect from FD:F5:ED:DF:ED:1D
Successful disconnected
[CHG] Device FD:F5:ED:DF:ED:1D Connected: no
```

# 8.BLEのアドバタイズを送信する
`advertise on`コマンドでアドバタイズを開始します。

```sh
[bluetooth]# advertise on
[CHG] Controller A4:34:D9:FD:86:FC SupportedInstances: 0x04 (4)
[CHG] Controller A4:34:D9:FD:86:FC ActiveInstances: 0x01 (1)
Advertising object registered
Tx Power: off
LocalName: TestName
Appearance: off
Discoverable: on
```

スマホからスキャンすると以下のようにアドバタイズのデータを確認することができます。

<img width="45%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102273/d1a65040-2f0b-d2d1-173e-42ac36fc155c.png">

アドバタイズを停止する。

```sh
[bluetooth]# advertise off
[CHG] Controller A4:34:D9:FD:86:FC SupportedInstances: 0x05 (5)
[CHG] Controller A4:34:D9:FD:86:FC ActiveInstances: 0x00 (0)
Advertising object unregistered
```

アドバタイズデータのカスタマイズもできそうです。

```
[bluetooth]# menu advertise
Menu advertise:
Available commands:
-------------------
uuids [uuid1 uuid2 ...]                           Set/Get advertise uuids
service [uuid] [data=xx xx ...]                   Set/Get advertise service data
manufacturer [id] [data=xx xx ...]                Set/Get advertise manufacturer data
data [type] [data=xx xx ...]                      Set/Get advertise data
discoverable [on/off]                             Set/Get advertise discoverable
discoverable-timeout [seconds]                    Set/Get advertise discoverable timeout
以下省略
```

# 参考サイト
* [Bluez](http://www.bluez.org/)
* [bluetoothctl のコマンド一覧と使い方をまとめてみた](https://qiita.com/noraworld/items/55c0cb1eb52cf8dccc12)
* [Linux のコマンドラインで Bluetooth 接続](https://qiita.com/propella/items/6daf3c56e26f709b4141)