// SPDX-License-Identifier: LGPL-3.0-or-later /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 2013 - 2024, nymea GmbH * Copyright (C) 2024 - 2025, chargebyte austria GmbH * * This file is part of libnymea-app. * * libnymea-app is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * libnymea-app is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libnymea-app. If not, see . * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "bluetoothdevice.h" BluetoothDevice::BluetoothDevice(const QBluetoothDeviceInfo &deviceInfo, QObject *parent) : QObject(parent), m_deviceInfo(deviceInfo), m_connected(false) { m_controller = QLowEnergyController::createCentral(deviceInfo, this); // m_controller->setRemoteAddressType(QLowEnergyController::PublicAddress); connect(m_controller, &QLowEnergyController::connected, this, &BluetoothDevice::onConnected); connect(m_controller, &QLowEnergyController::disconnected, this, &BluetoothDevice::onDisconnected); connect(m_controller, &QLowEnergyController::stateChanged, this, &BluetoothDevice::onDeviceStateChanged); connect(m_controller, SIGNAL(error(QLowEnergyController::Error)), this, SLOT(onDeviceError(QLowEnergyController::Error))); connect(m_controller, SIGNAL(discoveryFinished()), this, SIGNAL(serviceDiscoveryFinished())); } QString BluetoothDevice::name() const { return m_deviceInfo.name(); } QBluetoothAddress BluetoothDevice::address() const { return m_deviceInfo.address(); } QString BluetoothDevice::addressString() const { #ifdef Q_OS_MAC // On OS X and iOS we do not have addresses, // only unique UUIDs generated by Core Bluetooth. return m_deviceInfo.deviceUuid().toString(); #else return m_deviceInfo.address().toString(); #endif } bool BluetoothDevice::connected() const { return m_connected; } QString BluetoothDevice::statusText() const { return m_statusText; } void BluetoothDevice::connectDevice() { if (m_controller->state() != QLowEnergyController::UnconnectedState) { qDebug() << "Controller in state:" << m_controller->state() << "Not connecting..."; return; } qDebug() << "QLoweEnergyController connecting..."; m_controller->connectToDevice(); } void BluetoothDevice::disconnectDevice() { m_controller->disconnectFromDevice(); } void BluetoothDevice::setConnected(const bool &connected) { m_connected = connected; emit connectedChanged(); } void BluetoothDevice::setStatusText(const QString &statusText) { m_statusText = statusText; emit statusTextChanged(); } QLowEnergyController *BluetoothDevice::controller() { return m_controller; } void BluetoothDevice::onConnected() { qDebug() << "BluetoothDevice: Connected to" << name() << addressString(); m_controller->discoverServices(); } void BluetoothDevice::onDisconnected() { qWarning() << "BluetoothDevice: Disconnected from" << name() << addressString(); setConnected(false); setStatusText("Disconnected from " + name()); } void BluetoothDevice::onDeviceError(const QLowEnergyController::Error &error) { qWarning() << "BluetoothDevice: Error" << name() << addressString() << ": " << error << m_controller->errorString(); setConnected(false); } void BluetoothDevice::onDeviceStateChanged(const QLowEnergyController::ControllerState &state) { switch (state) { case QLowEnergyController::ConnectingState: qDebug() << "BluetoothDevice: Connecting..."; setStatusText(QString(tr("Connecting to %1...").arg(name()))); break; case QLowEnergyController::ConnectedState: qDebug() << "BluetoothDevice: Connected!"; setStatusText(QString(tr("Connected to %1").arg(name()))); break; case QLowEnergyController::ClosingState: qDebug() << "BluetoothDevice: Connection: Closing..."; setStatusText(QString(tr("Disconnecting from %1...").arg(name()))); break; case QLowEnergyController::DiscoveringState: qDebug() << "BluetoothDevice: Discovering..."; setStatusText(QString(tr("Discovering services of %1...").arg(name()))); break; case QLowEnergyController::DiscoveredState: qDebug() << "BluetoothDevice: Discovered!"; setStatusText(QString(tr("%1 connected and discovered.").arg(name()))); setConnected(true); break; case QLowEnergyController::UnconnectedState: qDebug() << "BluetoothDevice: Not connected."; setStatusText(QString(tr("%1 disconnected.").arg(name()))); break; default: qDebug() << "BluetoothDevice: Unhandled state entered:" << state; break; } }