MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Qtの基礎 - Classic Bluetoothのソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Qtの基礎 - Classic Bluetooth
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == QtのBluetoothサポートは、Qt Bluetoothモジュールを通じて提供されている。<br> Qt Bluetoothモジュールは、クロスプラットフォームなBluetooth通信機能を実現するための包括的なAPIセットとなっている。<br> <br> 主要なコンポーネントとして、Classic BluetoothとBluetooth Low Energy (BLE) の両方をサポートしている。 * Classic Bluetooth *: 従来型の高帯域幅通信 * BLE *: 省電力デバイスとの通信 <br> デバイスの検出と管理において、Qt Bluetoothモジュールは以下に示す機能を提供している。<br> * デバイススキャンと検出 * サービスディスカバリ * ペアリング管理 * 接続の確立と維持 <br> 上記の機能は相互に関連しており、アプリケーションでは以下に示すような流れで使用される。<br> # まず、デバイススキャンを行い、周囲のデバイスを探索する。 # 目的のデバイスが存在する場合、サービスディスカバリでそのデバイスの機能を確認する。 # 次に、必要に応じてペアリングを実行する。 # 最後に、接続を確立してデータ通信を開始する。 <br> Classic Bluetoothでの通信では、RFCOMMプロトコルを使用したシリアルポート型の通信が可能である。<br> これは QBluetoothSocketクラスを通じて実装されており、TCP/IPソケットに似た使い方ができる。<br> <br> BLEについては、GATT (Generic Attribute Profile) プロトコルをベースとしたサービスとキャラクタリスティックの概念を使用する。<br> QLowEnergyControllerクラスがBLE通信の中心的な役割を果たしており、デバイスとの接続やデータのやり取りを管理する。<br> <br> セキュリティ面においては、ペアリング、セキュアな接続の確立、暗号化等の機能が組み込まれている。<br> また、プラットフォーム固有のセキュリティ要件にも対応している。<br> <br> 実装する場合の注意点として、OSごとの権限設定や制限事項への対応が必要となる。<br> 特に、モバイルプラットフォームでは適切な権限の設定が重要である。<br> また、Bluetooth機能の有無やステータスの確認も必要である。<br> <br> エラーハンドリングについては、接続の切断、タイムアウト、デバイスが見つからない場合等、様々な状況に対応する必要がある。<br> <br> Qt Bluetoothモジュールは、これらの状況を適切に検出して、シグナル / スロットメカニズムを通じて通知する仕組みを提供している。<br> <br><br> == デバイススキャンと検出 == デバイススキャンは、周囲のBluetooth対応デバイスを探索するプロセスである。<br> このプロセスでは、アクティブに電波を送信して応答を待つアクティブスキャン、他のデバイスからのアドバタイズメントを受信するパッシブスキャンの2種類がある。<br> * アクティブスキャン * パッシブスキャン <br> スキャン中は、各デバイスの基本情報 (デバイス名、MACアドレス、デバイスクラス、信号強度等) を取得できる。<br> また、スキャン時間や範囲を設定可能であり、バッテリー消費とスキャン精度のバランスを取ることができる。<br> <br> <syntaxhighlight lang="c++"> #include <QObject> #include <QBluetoothDeviceDiscoveryAgent> #include <memory> #include <stdexcept> #include <QDebug> class BluetoothScanner : public QObject { Q_OBJECT private: std::unique_ptr<QBluetoothDeviceDiscoveryAgent> discoveryAgent; // デバイスタイプを文字列に変換するヘルパー関数 QString deviceTypeToString(QBluetoothDeviceInfo::MajorDeviceClass type) { switch (type) { case QBluetoothDeviceInfo::MiscellaneousDevice: return "その他"; case QBluetoothDeviceInfo::ComputerDevice: return "コンピュータ"; case QBluetoothDeviceInfo::PhoneDevice: return "電話"; case QBluetoothDeviceInfo::AudioVideoDevice: return "オーディオ/ビデオ"; case QBluetoothDeviceInfo::NetworkDevice: return "ネットワーク"; case QBluetoothDeviceInfo::PeripheralDevice: return "周辺機器"; case QBluetoothDeviceInfo::ImagingDevice: return "イメージング"; case QBluetoothDeviceInfo::WearableDevice: return "ウェアラブル"; case QBluetoothDeviceInfo::ToyDevice: return "おもちゃ"; case QBluetoothDeviceInfo::HealthDevice: return "ヘルスケア"; default: return "不明"; } } // エラーコードを文字列に変換するヘルパー関数 QString errorToString(QBluetoothDeviceDiscoveryAgent::Error error) { switch (error) { case QBluetoothDeviceDiscoveryAgent::NoError: return "エラーなし"; case QBluetoothDeviceDiscoveryAgent::InputOutputError: return "I/Oエラー"; case QBluetoothDeviceDiscoveryAgent::PoweredOffError: return "Bluetoothがオフ"; case QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError: return "無効なアダプタ"; case QBluetoothDeviceDiscoveryAgent::UnsupportedPlatformError: return "未対応のプラットフォーム"; case QBluetoothDeviceDiscoveryAgent::UnsupportedDiscoveryMethod: return "未対応の探索方法"; default: return "不明なエラー"; } } public: explicit BluetoothScanner(QObject* parent = nullptr) : QObject(parent) { try { // デバイス探索エージェントの作成 discoveryAgent = std::make_unique<QBluetoothDeviceDiscoveryAgent>(this); // 各種シグナルとスロットの接続 connect(discoveryAgent.get(), &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothScanner::onDeviceDiscovered); connect(discoveryAgent.get(), &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothScanner::onScanFinished); connect(discoveryAgent.get(), static_cast<void(QBluetoothDeviceDiscoveryAgent::*)(QBluetoothDeviceDiscoveryAgent::Error)>(&QBluetoothDeviceDiscoveryAgent::error), this, &BluetoothScanner::onError); } catch (const std::exception &e) { qDebug() << "初期化エラー: " << e.what(); throw; } } // スキャン開始メソッド void startScan() { try { qDebug() << "デバイススキャンを開始..."; discoveryAgent->start(); } catch (const std::exception &e) { qDebug() << "スキャン開始エラー: " << e.what(); throw; } } // スキャン停止メソッド void stopScan() { try { qDebug() << "デバイススキャンを停止..."; discoveryAgent->stop(); } catch (const std::exception &e) { qDebug() << "スキャン停止エラー: " << e.what(); throw; } } private slots: // デバイスが存在する場合のスロット void onDeviceDiscovered(const QBluetoothDeviceInfo& device) { qDebug() << "デバイスの探索に成功:"; qDebug() << " 名前: " << device.name(); qDebug() << " アドレス: " << device.address().toString(); qDebug() << " RSSI: " << device.rssi(); qDebug() << " デバイスタイプ: " << deviceTypeToString(device.majorDeviceClass()); } // スキャン完了時のスロット void onScanFinished() { qDebug() << "デバイススキャンが完了"; } // エラー発生時のスロット void onError(QBluetoothDeviceDiscoveryAgent::Error error) { qDebug() << "エラーが発生: " << errorToString(error); } }; </syntaxhighlight> <br><br> == サービスディスカバリ == 特定のBluetoothデバイスが提供するサービスを探索するプロセスである。<br> 各Bluetoothデバイスは複数のサービスを提供できるが、<br> サービスディスカバリによってそのデバイスがどのようなサービス (シリアル通信、オーディオ転送、ファイル転送等) を提供しているかを特定できる。<br> <br> 各サービスはUUIDで識別されており、標準的なサービスには予め定義されたUUIDが割り当てられている。<br> また、カスタムサービスの場合は独自のUUIDを使用する。<br> <br> <syntaxhighlight lang="c++"> #include <QBluetoothServiceDiscoveryAgent> #include <QBluetoothAddress> #include <QDebug> #include <memory> class ServiceDiscovery : public QObject { Q_OBJECT private: std::unique_ptr<QBluetoothServiceDiscoveryAgent> discoveryAgent; // プロトコルタイプを文字列に変換するヘルパー関数 QString protocolToString(int protocol) { switch (protocol) { case 0: return "不明なプロトコル"; case 1: return "SDP"; case 3: return "RFCOMM"; case 15: return "L2CAP"; default: return QString("その他のプロトコル (%1)").arg(protocol); } } // エラーコードを文字列に変換するヘルパー関数 QString errorToString(QBluetoothServiceDiscoveryAgent::Error error) { switch (error) { case QBluetoothServiceDiscoveryAgent::NoError: return "エラーなし"; case QBluetoothServiceDiscoveryAgent::InputOutputError: return "I/Oエラー"; case QBluetoothServiceDiscoveryAgent::PoweredOffError: return "Bluetoothがオフ"; case QBluetoothServiceDiscoveryAgent::InvalidBluetoothAdapterError: return "無効なアダプタ"; case QBluetoothServiceDiscoveryAgent::UnknownError: return "不明なエラー"; default: return "予期せぬエラー"; } } public: explicit ServiceDiscovery(QObject* parent = nullptr) : QObject(parent) { try { // サービス探索エージェントの作成 discoveryAgent = std::make_unique<QBluetoothServiceDiscoveryAgent>(this); // 各種シグナルとスロットの接続 connect(discoveryAgent.get(), &QBluetoothServiceDiscoveryAgent::serviceDiscovered, this, &ServiceDiscovery::onServiceDiscovered); connect(discoveryAgent.get(), &QBluetoothServiceDiscoveryAgent::finished, this, &ServiceDiscovery::onScanFinished); connect(discoveryAgent.get(), static_cast<void(QBluetoothServiceDiscoveryAgent::*)(QBluetoothServiceDiscoveryAgent::Error)>(&QBluetoothServiceDiscoveryAgent::error), this, &ServiceDiscovery::onError); } catch (const std::exception &e) { qDebug() << "初期化エラー: " << e.what(); throw; } } // 特定のデバイスのサービス探索を開始 void startDiscovery(const QBluetoothAddress& address) { try { qDebug() << "サービス探索を開始..."; discoveryAgent->setRemoteAddress(address); discoveryAgent->start(QBluetoothServiceDiscoveryAgent::FullDiscovery); } catch (const std::exception &e) { qDebug() << "探索開始エラー:" << e.what(); throw; } } // 探索を停止 void stopDiscovery() { try { qDebug() << "サービス探索を停止..."; discoveryAgent->stop(); } catch (const std::exception &e) { qDebug() << "探索停止エラー:" << e.what(); throw; } } private slots: // サービスの探索に成功した場合のスロット void onServiceDiscovered(const QBluetoothServiceInfo& service) { qDebug() << "サービスの探索に成功:"; qDebug() << " サービス名: " << service.serviceName(); qDebug() << " サービス説明: " << service.serviceDescription(); qDebug() << " プロトコル: " << protocolToString(service.protocolServiceMultiplexer()); // サービスの詳細情報を表示 if (service.serviceUuid().isNull()) { qDebug() << " UUID: カスタムUUID"; } else { qDebug() << " UUID: " << service.serviceUuid().toString(); } // サービスクラスを表示 QList<QBluetoothUuid> serviceClasses = service.serviceClassUuids(); if (!serviceClasses.isEmpty()) { qDebug() << " サービスクラス:"; for (const QBluetoothUuid& uuid : serviceClasses) { qDebug() << " -" << uuid.toString(); } } } // 探索完了時のスロット void onScanFinished() { qDebug() << "サービス探索が完了"; } // エラー発生時のスロット void onError(QBluetoothServiceDiscoveryAgent::Error error) { qDebug() << "エラーが発生: " << errorToString(error); } }; </syntaxhighlight> <br><br> == ペアリング管理 == ペアリングは、2つのBluetoothデバイス間で安全な通信を確立するための認証プロセスである。<br> <br> このプロセスおける重要な要素を以下に示す。<br> * 初回のペアリング時において、PINコードや数値の確認による認証を行う。 * ペアリング情報は両デバイスに保存されて、再接続時に使用する。 * セキュリティレベルの設定が可能であり、必要に応じて暗号化強度を変更できる。 * ペアリング状態の管理 (新規ペアリング、ペアリング解除、ペアリング状態の確認等) が含まれる。 * 1度ペアリングされたデバイスは、特別な設定がない限り、自動的に再接続可能になる。 <br> <syntaxhighlight lang="c++"> #include <QBluetoothLocalDevice> #include <QDebug> #include <memory> class PairingManager : public QObject { Q_OBJECT private: std::unique_ptr<QBluetoothLocalDevice> localDevice; // ペアリング状態を文字列に変換するヘルパー関数 QString pairingStatusToString(QBluetoothLocalDevice::Pairing status) { switch (status) { case QBluetoothLocalDevice::Unpaired: return "未ペアリング"; case QBluetoothLocalDevice::Paired: return "ペアリング済み"; case QBluetoothLocalDevice::AuthorizedPaired: return "認証済みペアリング"; default: return "不明な状態"; } } public: explicit PairingManager(QObject* parent = nullptr) : QObject(parent) { try { // ローカルBluetoothデバイスの初期化 localDevice = std::make_unique<QBluetoothLocalDevice>(this); // 各種シグナルとスロットの接続 connect(localDevice.get(), &QBluetoothLocalDevice::pairingFinished, this, &PairingManager::onPairingFinished); connect(localDevice.get(), &QBluetoothLocalDevice::error, this, &PairingManager::onError); connect(localDevice.get(), &QBluetoothLocalDevice::pairingDisplayConfirmation, this, &PairingManager::onPairingConfirmationRequest); connect(localDevice.get(), &QBluetoothLocalDevice::pairingDisplayPinCode, this, &PairingManager::onPairingDisplayPinCode); } catch (const std::exception &e) { qDebug() << "初期化エラー:" << e.what(); throw; } } // ペアリングを開始 void requestPairing(const QBluetoothAddress& address) { try { qDebug() << "ペアリングを開始..." << address.toString(); localDevice->requestPairing(address, QBluetoothLocalDevice::Paired); } catch (const std::exception &e) { qDebug() << "ペアリング開始エラー: " << e.what(); throw; } } // ペアリングの解除 void removePairing(const QBluetoothAddress& address) { try { qDebug() << "ペアリングを解除..." << address.toString(); localDevice->requestPairing(address, QBluetoothLocalDevice::Unpaired); } catch (const std::exception &e) { qDebug() << "ペアリング解除エラー:" << e.what(); throw; } } // ペアリング状態の確認 QBluetoothLocalDevice::Pairing getPairingStatus(const QBluetoothAddress &address) { try { return localDevice->pairingStatus(address); } catch (const std::exception &e) { qDebug() << "ペアリング状態確認エラー:" << e.what(); throw; } } // ペアリング済みデバイスの一覧を取得 QList<QBluetoothAddress> getPairedDevices() { try { return localDevice->connectedDevices(); } catch (const std::exception &e) { qDebug() << "ペアリング済みデバイス取得エラー: " << e.what(); throw; } } private slots: // ペアリング完了時のスロット void onPairingFinished(const QBluetoothAddress& address, QBluetoothLocalDevice::Pairing status) { qDebug() << "ペアリング処理が完了:"; qDebug() << " デバイス:" << address.toString(); qDebug() << " 状態:" << pairingStatusToString(status); } // エラー発生時のスロット void onError() { qDebug() << "ペアリング処理でエラーが発生"; } // ペアリング確認要求時のスロット void onPairingConfirmationRequest(const QBluetoothAddress& address, QString pin) { qDebug() << "ペアリング確認要求を受信:"; qDebug() << " デバイス:" << address.toString(); qDebug() << " 確認コード:" << pin; // ここに、ユーザに確認を求めるUIを表示する // 以下の例では、自動的に確認している localDevice->pairingConfirmation(true); } // PINコード表示要求時のスロット void onPairingDisplayPinCode(const QBluetoothAddress &address, QString pin) { qDebug() << "PINコード表示要求を受信:"; qDebug() << " デバイス:" << address.toString(); qDebug() << " PINコード:" << pin; } }; </syntaxhighlight> <br><br> == 接続の確立と維持 == 実際のデータ通信を行うための接続管理プロセスである。<br> <br> * 接続の確立 *: ペアリング済みデバイスとの接続を開始する。 * 接続状態の監視 *: 接続品質、切断検知、エラー検出等を常時監視する。 * 再接続管理 *: 予期せぬ切断が発生した場合の自動再接続処理を行う。 * データ転送の管理 *: 送受信バッファの管理、フロー制御、エラー訂正等を実施する。 * 接続パラメータの最適化 *: 電力消費、通信速度、接続の安定性等のバランスを取る。 <br><br> {{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux |image=/resources/assets/MochiuLogo_Single_Blue.png }} __FORCETOC__ [[カテゴリ:Qt]]
Qtの基礎 - Classic Bluetooth
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse