BlueZ 開発学習ガイド (1) --- D-Bus の概要

BlueZ 開発学習ガイド (1) - D-Bus の概要

1. BlueZ と D-Bus の概要

  Linux で使用される Bluetooth プロトコル スタックは Blue Z です。これまでの開発方法とは異なり、Blue Z が提供する API はヘッダー ファイルの形式ではなく、D-Bus の形式で提供されます。

  Blue Z が提供するのはホスト側のプロトコル スタックであり、コントロール側のプロトコルは多くの場合、専用のチップ工場によって提供されます。ホストとコントロールは、HCI インターフェイスを介して通信します。HCI インターフェイスは、UART、USB、SD カード、または仮想です。

  以下の図は、アプリケーションが D-Bus を介して Blue Z と通信するプロセスです。D-Bus はもともと、パーソナル コンピュータ上の X-Windows デスクトップ環境のコンポーネント間の相互運用性を促進するための標準的なメッセージ ベースの通信システムとして作成されました。しかし、D-Bus には、デスクトップ GUI コンポーネントの通信を設計するよりも幅広い用途があります。Blue Z バージョン 5.52 以降、Linux 上で実行される Bluetooth アプリケーションと BlueZ 自体の間の標準インターフェイスになりました。Linux で BlueZ 関連の開発を行うには、D-Bus の使用方法を知ることが鍵となります。

画像-20230712182309115

BlueZ で提供される API はすべてコード ウェアハウスの doc ディレクトリにあり、次のリンクからも参照できます: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc

BlueZ アプリケーションは、BlueZ 関数を直接呼び出したり、BlueZ から直接コールバックを受け取ったりしません。BlueZ ヘッダー ファイルに対してアプリケーション コードをコンパイルする必要はありません。D-Bus はアプリケーションを BlueZ から完全に分離するため、Bluetooth アプリケーションの開発には主に D-Bus API を使用したメッセージの送受信が含まれます。

第二に、D-Bus の基本概念

メッセージバス

D-Bus のプロセス間通信はメッセージ バスを中心としています。メッセージは 1 つのプロセスによってバス上に配置され、同じバスに接続されている 1 つ以上の他のプロセスにバスに沿って送信されます。

メッセージ バスには、システム バスとセッション バスの 2 種類があります。

  • システム バスのインスタンスは 1 つだけあり、BlueZ が使用するものです。
  • Linux にはユーザー ログイン セッションごとにセッション バスがあります。

画像-20230712184716438

クライアント、サーバー、接続

  D-Bus 通信では、プロセスをメッセージ バスに接続する必要があります。バスに接続されたプロセスはクライアントと呼ばれ、接続をリッスンして受け入れるプロセスはサーバーと呼ばれます。クライアントとサーバーは接続を確立するための処理のみであり、接続が確立された後はクライアントとサーバーの違いは存在しません。

  アプリケーションがバスに接続すると、コロンで始まる一意の接続名が割り当てられます (例: 1.16)。さまざまなアプリケーションは、接続されているバス上でさまざまなタイプの D-Bus メッセージを送受信することによって相互に通信します。

オブジェクト、インターフェイス、メソッド、信号、プロパティ

  D-Bus はオブジェクト指向の概念を使用しており、D-Bus を使用するアプリケーションにはさまざまなオブジェクトが含まれます。オブジェクトは 1 つ以上の関数またはメソッドで構成されます。

  インターフェイスでは区切り文字としてドットが使用されますが、これはドメイン名のセグメンテーション ルールとよく似ています。例: org.freedesktop.DBus.Introspectable と org.bluez.GattManager1 は 2 つのインターフェイスの名前です。

  アプリケーションは、接続された D-Bus 経由で特別なメッセージを送信することで、別のプログラム オブジェクトのメソッドを呼び出すことができます。送信されたメッセージは、接続を通じてバスに沿って、ターゲット オブジェクトを所有するアプリケーションに渡されます。

 メソッドは結果を返す場合と返さない場合があります。結果がメソッドによって生成された場合は、元の内容に戻します。

  そのメソッドを他のアプリケーションから呼び出すには、オブジェクトを D-Bus デーモンに登録する必要があります。D-Bus にオブジェクトを登録するこの動作は、エクスポートと呼ばれます (エクスポートと言い換えるだけです)。各オブジェクトにはパスの形式で一意の識別子があります。たとえば、Bluetooth デバイスを表すオブジェクトのパス識別子は /org/bluez/hci0/dev_4c_4c_d7_64_cd_22_0a である可能性があります。オブジェクトをそのパスに登録すると、D-Bus デーモンは、所有アプリケーションの識別されたパスへの適切な接続を介して、識別されたパスをオブジェクトにルーティングできるようになります。

  なお、パスは階層構造を有しており、パスの前端にはパスの後端も含まれる。たとえば、パス (/org/bluez/hci0/dev_4c_d7_64_cd_22_0a) 内のデバイス dev_4c_d7_64_cd_22_0a は Bluetooth アダプター オブジェクトによって所有されており、Bluetooth アダプターのパスは /org/bluez/hci0/ です。

  オブジェクトのインターフェイスは (Signal) シグナルを発行でき、シグナルはイベントとみなすことができます。アプリケーションは関心のあるシグナルをサブスクライブまたは登録でき、シグナルは 1 つ以上のアプリケーションによって登録できます。シグナルがトリガーされると、シグナルを登録したアプリケーションに送信されます。

  オブジェクトは属性を持つことができ、属性は Get オペレーションを使用して属性値を取得したり、Set オペレーションを使用して属性値を変更したりすることもできます。プロパティは名前で参照することも、オブジェクトによって実装されたインターフェイスを通じてアクセスすることもできます。

プロキシオブジェクト

  一部の D-Bus API は、別のアプリケーションのリモート オブジェクトとして理解できるプロキシ オブジェクトの概念をサポートしています。ただし、プロキシ オブジェクトはローカル プロセスでインスタンス化され、それが表すリモート オブジェクトと同じメソッドを持ち、アプリケーション コードから直接呼び出すことができます。次に、プロキシ オブジェクトは、これらのネイティブ メソッド呼び出しを D-Bus メッセージの送受信に変換します。プロキシ オブジェクトにより、D-Bus プログラミングが容易になり、かなり低レベルのプログラミングが必要になる可能性がある D-Bus メッセージを直接操作する必要があるアプリケーション開発者の負担が軽減されます。

よく知られた名前

  各 D-Bus には接続名 (例: 1.16) があると上で述べました。ただし、アプリケーションは接続名の代わりにアクセス可能な名前を登録することもできます。これは、どのアプリケーションでも実行できます。たとえば、Bluetooth デーモンは、org.bluez というよく知られた名前の D-Bus サーバーです。

標準インターフェース

BlueZ で開発する場合、いくつかの標準インターフェイスがよく使用されます。例えば:

**org.freedesktop.DBus.ObjectManager**

  このインターフェイスは、信号インターフェイス InterfacesAdded および InterfacesRemoved を定義します。BlueZ が新しいデバイスを検出すると、InterfacesAdded シグナルを送信し、Blue Z がデバイスを失うと、Interfaces Removed 関数を送信します。

このインターフェイスは getManageBjects メソッドも定義します。これにより、アプリケーションは D-Bus 接続プロセスが持つすべてのオブジェクトを検出できるようになります。

org.freedesktop.DBus.ObjectManager

  このインターフェイスは、プロパティ値の取得または設定を可能にするメソッドと信号を定義します。オブジェクトのプロパティが変更されると、PropertiesChanged 命令が送信されます。たとえば、Bluetooth の RSSI プロパティが変更されると、Bluez Device オブジェクトはプロパティ インターフェイスを実装し、 PropertiesChanged シグナルを送信します。

3. D-Bus ツール

D-Bus 開発者が使用する主なツールは、D-feet と DBus-Monitor です。

Dフィート

  D-feet は、システムまたはセッション バスに接続されているアプリケーションを表示し、エクスポートされたオブジェクトとインターフェイスを参照できる GUI アプリケーションです。また、テスト目的で使用できるメソッドを実行することもできます。下の画像は、Raspberry Pi で使用され、リモート デスクトップ ツール VNC を使用してアクセスされている D-Feet のスクリーンショットを示しています。

画像-20230713161618301

  org.bluez サービスが左側のペインで選択されており、これによりサービスに含まれるオブジェクトがリストされ、それぞれが階層パスによって識別されます。オブジェクトを拡張して、サポートされているインターフェイスを表示することができ、インターフェイス内でそのメソッドを確認できます。

D-feet は、テストだけでなく、D-BU の理解を探求し発展させるための優れたツールです。d-feet をインストールするには、次のコマンドを使用できます。

sudo apt-get install d-feet

dbusモニター

DBU-Monitor は、DBUS デーモンと交換されるメッセージをリアルタイムで表示できるコマンドライン ツールです。DBU-Monitor を実行する場合は、システム バスまたはセッション バスを選択する必要があります。特定のシステム メッセージは、リッスンが有効になっている場合にのみ表示されます。

システムバスを監視するコマンド:

sudo dbus-monitor --system

セッションバスを監視するコマンド:

sudo dbus-monitor --session

  監視を有効にする場合は、root ユーザーを使用してセキュリティ ポリシーの監視を有効にする必要があります。たとえば、system-local.conf のようなファイルを作成します。もちろん、監視を有効にするには、デバイスを再起動する必要があります。

pi@raspberrypi:~ $ sudo cat /etc/dbus-1/system-local.conf
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<policy user="root">
<allow eavesdrop="true"/>
<allow eavesdrop="true" send_destination="*"/>
</policy>
</busconfig>

dbus送信

  dbus-send は、ユーザーが D-Bus バスにメッセージを送信できるコマンド ライン ツールで、プログラムのテストに非常に便利です。指定したアプリケーションにテスト メッセージを送信し、メッセージが正しいかどうかを確認できます。買収。例えば:

dbus-send --system --type=signal / com.studyguide.greeting_signal string:"hello world!"

メッセージを含む D-Bus 呼び出しの例を次に示します。

method call time=1634811621.566895 sender=:1.52 -> destination=:1.16 serial=10 path=/org/bluez/hci0/dev_EB_EE_7B_08_EC_3D; interface=org.bluez.Device1; member=Connect

  D-Bus メッセージは、接続 ID が 1.52 のアプリケーションから接続 ID が 1.16 のアプリケーションに送信されます。宛先アドレスのアプリケーションには、パス識別子が /org/bluez/hci0/dev_eb_ee_7b_08_ec_3d である Bluetooth デバイス オブジェクトがあります。このオブジェクトは、反復メソッドと実行される接続を含む org.bluez.device1 インターフェイスを実装します。下の図では、デバイスが D-Bus オブジェクトとして表されていることがわかります。

画像-20230713164104414

D-Bus信号メッセージ

signal time=1634895336.839277 sender=:1.33 -> destination=(null destination) serial=349 path=/org/bluez/hci0/dev_EE_CB_92_97_DB_18/service0025/char0026; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
	string "org.bluez.GattCharacteristic1"
	array [
		dict entry(
			string "Value"
			variant array of bytes [12]
		)
	]
	array []

この D-Bus メッセージは、Bluez デーモンから送信され、登録されているすべてのアプリケーションに配信される信号です。

  このシグナルは、パス ID /org/bluez/hci0/dev_EE_CB_92_97_DB_18/service0025/char0026 を持つ特性オブジェクトによって発信されます。そして、すでにバイト配列の状況には通知値が含まれています。信号を発信できるのは 1 つのオブジェクトだけであり、登録されたアプリケーションはその信号を受信できます。

4. プログラミング言語とAPI

D-Bus バインディング用のプログラミング言語は次のとおりです: https://www.freedesktop.org/wiki/Software/DBusBindings/

  プログラミング言語と D-Bus API の関係は 1 対 1 の関係ではありません。一部の言語では複数の API を使用できます。たとえば、C 言語開発者は、GIO または Embedded Linux Library (ELL) を使用できます。Ell はよりフレンドリーに見えますが、API ドキュメントがないため、開発者はいくつかの例を見てその使用方法を学ぶ必要があります。また、Gio ドキュメントの品質はさまざまであり、使い始めるには確かに学習曲線が必要です。Python 開発者には少なくともいくつかの選択肢があります。Bluez プロジェクト自体は、Bluez ディストリビューションに含まれるテスト ツールとして DBU-PYTHON を使用します。そのドキュメントでは、それ自体が D-BUS プロトコルのリファレンス実装であると説明されています。ただし、D-Bus バインディングの公式リスト (上記のリンクを参照) では、DBus-Python が廃止されたライブラリとしてリストされており、代わりに Pydbus を使用することが推奨されています。つまり、dbus-python は間違いなくアクティブなプロジェクトであり、正式版は 2021 年にリリースされる予定です。

おすすめ

転載: blog.csdn.net/hesuping/article/details/131708132