Brilloのbluetoothtbd とbluetooth-cli についてちょっと調べてみました。
BrilloではAndroid由来のBluetoothプロトコルスタック Fluoride (system/bt)を採用しています。
ただし、AndroidとはAPIが異なります。
AndroidではAndroid Bluetooth HAL(libhardware)をwrapper経由 (core/java/android/bluetooth/)で使っていますが、
Brilloではcppで実装したBinder APIを用います。
ソース
- https://android.googlesource.com/platform/system/bt/+/master/service/main.cc
- https://android.googlesource.com/platform/system/bt/+/master/service/common/android/bluetooth
- https://android.googlesource.com/platform/system/bt/+/master/service/client/main.cc
bluetoothtbd
- Brilloではbluetoothtbdというデーモンがbluetoothプロトコルスタックの本体です。
- bluetoothtbdのメインのソースは service/main.cc にあります。 このソースでプロトコルスタックのメインループを起動しています。
main.cc
if (!bluetooth::Daemon::Initialize()) {
LOG(ERROR) << "Failed to initialize Daemon";
return EXIT_FAILURE;
}
// Start the main event loop.
bluetooth::Daemon::Get()->StartMainLoop();
Brilloのbluetooth API
- APIは、service/common/android/bluetooth のAIDLからヘッダファイルを生成して使います。
- Bluetoothの起動・停止などを行うIBluetooth.aidl
IBluetooth.aidl
package android.bluetooth;
import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothLowEnergy;
import android.bluetooth.IBluetoothGattClient;
import android.bluetooth.IBluetoothGattServer;
import android.bluetooth.UUID;
interface IBluetooth {
boolean IsEnabled();
int GetState();
boolean Enable(boolean startRestricted);
boolean EnableNoAutoConnect();
boolean Disable();
String GetAddress();
UUID[] GetUUIDs();
boolean SetName(String name);
String GetName();
void RegisterCallback(IBluetoothCallback callback);
void UnregisterCallback(IBluetoothCallback callback);
boolean IsMultiAdvertisementSupported();
IBluetoothLowEnergy GetLowEnergyInterface();
IBluetoothGattClient GetGattClientInterface();
IBluetoothGattServer GetGattServerInterface();
}
- binder APIの実装は https://android.googlesource.com/platform/system/bt/+log/master/service/ipc/binder にあります。
bluetooth-cli
- APIのサンプルとして、bluetooh-cli というツールが提供されています。
- bluetooth-cli のソースは service/client/main.cc にあります。
- 現時点ではBLEのアドバタイズ、BLEの接続などをコマンドで行うことができます。
# bluetooth-cli
Fluoride Command-Line Interface
Type "help" to see possible commands.
[FCLI] help
help Display this message
disable Disable Bluetooth
enable Enable Bluetooth
get-state Get the current adapter state
is-enabled Return if Bluetooth is enabled
get-local-address Get the local adapter address
set-local-name Set the local adapter name
get-local-name Get the local adapter name
adapter-info Print adapter properties
supports-multi-adv Whether multi-advertisement is currently supported
register-ble Register with the Bluetooth Low Energy interface
unregister-ble Unregister from the Bluetooth Low Energy interface
unregister-all-ble Unregister all clients from the Bluetooth Low Energy interface
register-gatt Register with the Bluetooth GATT Client interface
unregister-gatt Unregister from the Bluetooth GATT Client interface
connect-le Connect to LE device (-h for options)
disconnect-le Disconnect LE device (-h for options)
set-mtu Set MTU (-h for options)
start-adv Start advertising (-h for options)
stop-adv Stop advertising
start-le-scan Start LE device scan (-h for options)
stop-le-scan Stop LE device scan
- ソースコードを少し見てみました。
- bt_ifaceの取得
sp<IBluetooth> bt_iface;
status_t status = getService(String16(kServiceName.c_str()), &bt_iface);
- コールバックの登録
// Register Adapter state-change callback
sp<CLIBluetoothCallback> callback = new CLIBluetoothCallback();
bt_iface->RegisterCallback(callback);
- Bluetooth起動
bool status;
bt_iface->Enable(is_restricted_mode, &status);
- BDアドレスの取得
String16 address;
bt_iface->GetAddress(&address);
PrintFieldAndValue("\tAddress", std::string(String8(address).string()));
- アドバタイズの開始
base::TimeDelta timeout;
bluetooth::AdvertiseSettings settings(
bluetooth::AdvertiseSettings::MODE_LOW_POWER, timeout,
bluetooth::AdvertiseSettings::TX_POWER_LEVEL_MEDIUM, connectable);
bluetooth::AdvertiseData adv_data(data);
adv_data.set_include_device_name(include_name);
adv_data.set_include_tx_power_level(include_tx_power);
bluetooth::AdvertiseData scan_rsp;
bool status;
ble_iface->StartMultiAdvertising(ble_client_id.load(), adv_data, scan_rsp,
settings, &status);
- Android Bluetooth HALに比べて、callbackがclass化されているので見通しが良くなっている気がします。
- Brilloが正式にリリースされる際には、BluetoothのBinder APIがドキュメント化されるのを期待します。