12,796
回編集
356行目: | 356行目: | ||
* discoveryFinishedシグナルで探索完了を検知する | * discoveryFinishedシグナルで探索完了を検知する | ||
* createServiceObjectメソッドを使用して、サービスオブジェクトを生成する | * createServiceObjectメソッドを使用して、サービスオブジェクトを生成する | ||
<br> | |||
==== 使用例 ==== | |||
<syntaxhighlight lang="c++"> | |||
#include <QObject> | |||
#include <QLowEnergyController> | |||
#include <QLowEnergyService> | |||
#include <QTimer> | |||
#include <memory> | |||
#include <QDebug> | |||
class BLEServiceDiscovery : public QObject | |||
{ | |||
Q_OBJECT | |||
private: | |||
std::unique_ptr<QLowEnergyController> controller; | |||
std::unique_ptr<QTimer> discoveryTimeout; | |||
void connectControllerSignals() | |||
{ | |||
connect(controller.get(), &QLowEnergyController::connected, this, &BLEServiceDiscovery::onConnected); | |||
connect(controller.get(), &QLowEnergyController::disconnected, this, &BLEServiceDiscovery::onDisconnected); | |||
connect(controller.get(), &QLowEnergyController::serviceDiscovered, this, &BLEServiceDiscovery::onServiceDiscovered); | |||
connect(controller.get(), &QLowEnergyController::discoveryFinished, this, &BLEServiceDiscovery::onDiscoveryFinished); | |||
connect(controller.get(), static_cast<void(QLowEnergyController::*)(QLowEnergyController::Error)>(&QLowEnergyController::error), this, &BLEServiceDiscovery::onError); | |||
connect(controller.get(), &QLowEnergyController::stateChanged, this, &BLEServiceDiscovery::onStateChanged); | |||
} | |||
void connectServiceSignals(QLowEnergyService *service) | |||
{ | |||
connect(service, &QLowEnergyService::stateChanged, this, [this, service](QLowEnergyService::ServiceState newState) { | |||
qDebug() << "サービス状態が変更: " << getServiceStateMessage(newState); | |||
}); | |||
connect(service, static_cast<void(QLowEnergyService::*)(QLowEnergyService::ServiceError)>(&QLowEnergyService::error), this, [this](QLowEnergyService::ServiceError error) { | |||
qDebug() << "サービスエラー: " << getServiceErrorMessage(error); | |||
}); | |||
} | |||
QString getErrorMessage(QLowEnergyController::Error error) | |||
{ | |||
switch (error) { | |||
case QLowEnergyController::NoError: return "エラーなし"; | |||
case QLowEnergyController::UnknownError: return "不明なエラー"; | |||
case QLowEnergyController::UnknownRemoteDeviceError: return "リモートデバイスが見つからない"; | |||
case QLowEnergyController::NetworkError: return "ネットワークエラー"; | |||
case QLowEnergyController::InvalidBluetoothAdapterError: return "無効なBluetoothアダプタ"; | |||
case QLowEnergyController::ConnectionError: return "接続エラー"; | |||
default: return "予期せぬエラー"; | |||
} | |||
} | |||
QString getStateMessage(QLowEnergyController::ControllerState state) | |||
{ | |||
switch (state) { | |||
case QLowEnergyController::UnconnectedState: return "未接続"; | |||
case QLowEnergyController::ConnectingState: return "接続中"; | |||
case QLowEnergyController::ConnectedState: return "接続済み"; | |||
case QLowEnergyController::DiscoveringState: return "探索中"; | |||
case QLowEnergyController::DiscoveredState: return "探索完了"; | |||
case QLowEnergyController::ClosingState: return "切断中"; | |||
case QLowEnergyController::AdvertisingState: return "アドバタイジング中"; | |||
default: return "不明な状態"; | |||
} | |||
} | |||
QString getServiceStateMessage(QLowEnergyService::ServiceState state) | |||
{ | |||
switch (state) { | |||
case QLowEnergyService::InvalidService: return "無効なサービス"; | |||
case QLowEnergyService::DiscoveryRequired: return "探索が必要"; | |||
case QLowEnergyService::DiscoveringServices: return "サービス探索中"; | |||
case QLowEnergyService::ServiceDiscovered: return "サービス探索完了"; | |||
default: return "不明なサービス状態"; | |||
} | |||
} | |||
QString getServiceErrorMessage(QLowEnergyService::ServiceError error) | |||
{ | |||
switch (error) { | |||
case QLowEnergyService::NoError: return "エラーなし"; | |||
case QLowEnergyService::OperationError: return "操作エラー"; | |||
case QLowEnergyService::CharacteristicReadError: return "キャラクタリスティック読み取りエラー"; | |||
case QLowEnergyService::CharacteristicWriteError: return "キャラクタリスティック書き込みエラー"; | |||
case QLowEnergyService::DescriptorReadError: return "ディスクリプタ読み取りエラー"; | |||
case QLowEnergyService::DescriptorWriteError: return "ディスクリプタ書き込みエラー"; | |||
case QLowEnergyService::UnknownError: return "不明なエラー"; | |||
default: return "予期せぬサービスエラー"; | |||
} | |||
} | |||
public: | |||
explicit BLEServiceDiscovery(QObject* parent = nullptr) : QObject(parent) | |||
{ | |||
// タイムアウトタイマの初期化 | |||
discoveryTimeout = std::make_unique<QTimer>(this); | |||
discoveryTimeout->setInterval(10000); // 10秒のタイムアウト | |||
discoveryTimeout->setSingleShot(true); | |||
connect(discoveryTimeout.get(), &QTimer::timeout, this, &BLEServiceDiscovery::onDiscoveryTimeout); | |||
} | |||
// デバイスへの接続とサービス探索の開始 | |||
void startDiscovery(const QBluetoothDeviceInfo& device) | |||
{ | |||
try { | |||
qDebug() << "サービス探索を開始: " << device.name(); | |||
// コントローラの初期化 | |||
controller = std::make_unique<QLowEnergyController>(device, this); | |||
connectControllerSignals(); | |||
// 接続開始 | |||
controller->connectToDevice(); | |||
discoveryTimeout->start(); | |||
} | |||
catch (const std::exception &e) { | |||
QString errorMsg = QString("探索開始エラー: %1").arg(e.what()); | |||
qDebug() << errorMsg; | |||
emit errorOccurred(errorMsg); | |||
} | |||
} | |||
// 探索を停止 | |||
void stopDiscovery() | |||
{ | |||
try { | |||
if (controller) { | |||
controller->disconnectFromDevice(); | |||
discoveryTimeout->stop(); | |||
} | |||
} | |||
catch (const std::exception &e) { | |||
QString errorMsg = QString("探索停止エラー: %1").arg(e.what()); | |||
qDebug() << errorMsg; | |||
emit errorOccurred(errorMsg); | |||
} | |||
} | |||
signals: | |||
void serviceDiscovered(QLowEnergyService *service); | |||
void discoveryComplete(); | |||
void errorOccurred(const QString &error); | |||
void connectionStateChanged(QLowEnergyController::ControllerState state); | |||
private slots: | |||
void onConnected() | |||
{ | |||
qDebug() << "デバイスに接続"; | |||
discoveryTimeout->stop(); | |||
// サービス探索の開始 | |||
controller->discoverServices(); | |||
} | |||
void onDisconnected() | |||
{ | |||
qDebug() << "デバイスから切断"; | |||
discoveryTimeout->stop(); | |||
} | |||
void onServiceDiscovered(const QBluetoothUuid& uuid) | |||
{ | |||
qDebug() << "サービスを発見:" << uuid.toString(); | |||
// サービスオブジェクトの作成 | |||
QLowEnergyService* service = controller->createServiceObject(uuid, this); | |||
if (service) { | |||
connectServiceSignals(service); | |||
emit serviceDiscovered(service); | |||
} | |||
} | |||
void onDiscoveryFinished() | |||
{ | |||
qDebug() << "サービス探索が完了"; | |||
discoveryTimeout->stop(); | |||
emit discoveryComplete(); | |||
} | |||
void onError(QLowEnergyController::Error error) | |||
{ | |||
QString errorMessage = getErrorMessage(error); | |||
qDebug() << "エラーが発生: " << errorMessage; | |||
emit errorOccurred(errorMessage); | |||
} | |||
void onDiscoveryTimeout() | |||
{ | |||
qDebug() << "サービス探索がタイムアウト"; | |||
stopDiscovery(); | |||
emit errorOccurred("探索タイムアウト"); | |||
} | |||
void onStateChanged(QLowEnergyController::ControllerState state) | |||
{ | |||
qDebug() << "接続状態が変更: " << getStateMessage(state); | |||
emit connectionStateChanged(state); | |||
} | |||
}; | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||