Make bluetooth low energy work for macos

This commit is contained in:
Simon Stürz 2018-07-17 11:59:55 +02:00
parent 5eb4452c51
commit 1b42ffd3e4
7 changed files with 121 additions and 61 deletions

View File

@ -27,7 +27,7 @@ BluetoothDevice::BluetoothDevice(const QBluetoothDeviceInfo &deviceInfo, QObject
m_deviceInfo(deviceInfo),
m_connected(false)
{
m_controller = new QLowEnergyController(deviceInfo.address(), this);
m_controller = new QLowEnergyController(deviceInfo, this);
m_controller->setRemoteAddressType(QLowEnergyController::PublicAddress);
connect(m_controller, &QLowEnergyController::connected, this, &BluetoothDevice::onConnected);
@ -48,6 +48,17 @@ 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;
@ -87,20 +98,20 @@ QLowEnergyController *BluetoothDevice::controller()
void BluetoothDevice::onConnected()
{
qDebug() << "BluetoothDevice: Connected to" << name() << address().toString();
qDebug() << "BluetoothDevice: Connected to" << name() << addressString();
m_controller->discoverServices();
}
void BluetoothDevice::onDisconnected()
{
qWarning() << "BluetoothDevice: Disconnected from" << name() << address().toString();
qWarning() << "BluetoothDevice: Disconnected from" << name() << addressString();
setConnected(false);
setStatusText("Disconnected from " + name());
}
void BluetoothDevice::onDeviceError(const QLowEnergyController::Error &error)
{
qWarning() << "BluetoothDevice: Error" << name() << address().toString() << ": " << error << m_controller->errorString();
qWarning() << "BluetoothDevice: Error" << name() << addressString() << ": " << error << m_controller->errorString();
setConnected(false);
}

View File

@ -41,6 +41,7 @@ public:
QString name() const;
QBluetoothAddress address() const;
QString addressString() const;
bool connected() const;
QString statusText() const;

View File

@ -22,6 +22,8 @@
#include "bluetoothdeviceinfo.h"
#include <QBluetoothUuid>
BluetoothDeviceInfo::BluetoothDeviceInfo()
{
}
@ -33,7 +35,13 @@ BluetoothDeviceInfo::BluetoothDeviceInfo(const QBluetoothDeviceInfo &deviceInfo)
QString BluetoothDeviceInfo::address() 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
}
QString BluetoothDeviceInfo::name() const

View File

@ -119,8 +119,29 @@ void BluetoothDiscovery::onBluetoothHostModeChanged(const QBluetoothLocalDevice:
void BluetoothDiscovery::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo)
{
qDebug() << "BluetoothDiscovery: [+]" << deviceInfo.name() << "(" << deviceInfo.address().toString() << ")" << (deviceInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration ? "LE" : "");
m_deviceInfos->addBluetoothDeviceInfo(new BluetoothDeviceInfo(deviceInfo));
BluetoothDeviceInfo *deviceInformation = new BluetoothDeviceInfo(deviceInfo);
bool isLowEnergy = deviceInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration;
qDebug() << "BluetoothDiscovery: [+]" << deviceInformation->name() << "(" << deviceInformation->address() << ")" << (isLowEnergy ? "LE" : "");
//
if (!isLowEnergy || deviceInformation->name().isEmpty()) {
delete deviceInformation;
return;
}
// Check if we already have added this device info
foreach (BluetoothDeviceInfo *di, m_deviceInfos->deviceInfos()) {
if (di->name() == deviceInformation->name() && di->address() == deviceInformation->address()) {
qWarning() << "BluetoothDiscover: device" << deviceInformation->name() << "(" << deviceInformation->address() << ") already added";
deviceInformation->deleteLater();
deviceInformation = nullptr;
}
}
if (deviceInformation)
m_deviceInfos->addBluetoothDeviceInfo(deviceInformation);
}
void BluetoothDiscovery::discoveryFinished()

View File

@ -21,6 +21,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "networkmanagercontroler.h"
#include "engine.h"
NetworkManagerControler::NetworkManagerControler(QObject *parent) : QObject(parent)
{
@ -61,7 +62,20 @@ void NetworkManagerControler::connectDevice()
emit managerChanged();
}
m_wirelessSetupManager = new WirelessSetupManager(QBluetoothDeviceInfo(QBluetoothAddress(m_address), m_name, 0), this);
// find device info for this address and name
BluetoothDeviceInfo *deviceInfo = nullptr;
foreach (BluetoothDeviceInfo *deviceInformation, Engine::instance()->bluetoothDiscovery()->deviceInfos()->deviceInfos()) {
if (deviceInformation->address() == address() && deviceInformation->name() == name()) {
deviceInfo = deviceInformation;
}
}
if (!deviceInfo) {
qDebug() << "Could not connect to device. There is no device info for" << name() << address();
return;
}
m_wirelessSetupManager = new WirelessSetupManager(deviceInfo->getBluetoothDeviceInfo(), this);
emit managerChanged();
m_wirelessSetupManager->connectDevice();

View File

@ -710,62 +710,11 @@ void WirelessSetupManager::onServiceDiscoveryFinished()
connect(m_deviceInformationService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onDeviceInformationCharacteristicChanged);
connect(m_deviceInformationService, &QLowEnergyService::characteristicRead, this, &WirelessSetupManager::onDeviceInformationCharacteristicChanged);
if (m_deviceInformationService->state() == QLowEnergyService::DiscoveryRequired)
if (m_deviceInformationService->state() == QLowEnergyService::DiscoveryRequired) {
qDebug() << "WifiSetupManager: start discovering device information service...";
m_deviceInformationService->discoverDetails();
}
// Network service
if (!m_netwokService) {
m_netwokService = controller()->createServiceObject(networkServiceUuid, this);
if (!m_netwokService) {
qWarning() << "WifiSetupManager: Could not create network service.";
controller()->disconnectFromDevice();
return;
}
connect(m_netwokService, &QLowEnergyService::stateChanged, this, &WirelessSetupManager::onNetworkServiceStateChanged);
connect(m_netwokService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onNetworkServiceCharacteristicChanged);
connect(m_netwokService, &QLowEnergyService::characteristicRead, this, &WirelessSetupManager::onNetworkServiceReadFinished);
if (m_netwokService->state() == QLowEnergyService::DiscoveryRequired)
m_netwokService->discoverDetails();
}
// Wifi service
if (!m_wifiService) {
m_wifiService = controller()->createServiceObject(wifiServiceUuid, this);
if (!m_wifiService) {
qWarning() << "WifiSetupManager: Could not create wifi service.";
controller()->disconnectFromDevice();
return;
}
connect(m_wifiService, &QLowEnergyService::stateChanged, this, &WirelessSetupManager::onWifiServiceStateChanged);
connect(m_wifiService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onWifiServiceCharacteristicChanged);
connect(m_wifiService, &QLowEnergyService::characteristicRead, this, &WirelessSetupManager::onWifiServiceReadFinished);
if (m_wifiService->state() == QLowEnergyService::DiscoveryRequired)
m_wifiService->discoverDetails();
}
// System service
if (!m_systemService) {
m_systemService = controller()->createServiceObject(systemServiceUuid, this);
if (!m_systemService) {
qWarning() << "WifiSetupManager: Could not create system service. Looks like this networkmanager has not implemented that.";
//controller()->disconnectFromDevice();
} else {
connect(m_systemService, &QLowEnergyService::stateChanged, this, &WirelessSetupManager::onSystemServiceStateChanged);
connect(m_systemService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onSystemServiceCharacteristicChanged);
connect(m_systemService, &QLowEnergyService::characteristicRead, this, &WirelessSetupManager::onSystemServiceReadFinished);
if (m_systemService->state() == QLowEnergyService::DiscoveryRequired)
m_systemService->discoverDetails();
}
}
}
@ -790,6 +739,24 @@ void WirelessSetupManager::onDeviceInformationStateChanged(const QLowEnergyServi
setFirmwareRevision(QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::FirmwareRevisionString).value()));
setHardwareRevision(QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::HardwareRevisionString).value()));
// Network service
if (!m_netwokService) {
m_netwokService = controller()->createServiceObject(networkServiceUuid, this);
if (!m_netwokService) {
qWarning() << "WifiSetupManager: Could not create network service.";
controller()->disconnectFromDevice();
return;
}
connect(m_netwokService, &QLowEnergyService::stateChanged, this, &WirelessSetupManager::onNetworkServiceStateChanged);
connect(m_netwokService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onNetworkServiceCharacteristicChanged);
connect(m_netwokService, &QLowEnergyService::characteristicRead, this, &WirelessSetupManager::onNetworkServiceReadFinished);
if (m_netwokService->state() == QLowEnergyService::DiscoveryRequired) {
qDebug() << "WifiSetupManager: start discovering network service...";
m_netwokService->discoverDetails();
}
}
checkInitialized();
}
@ -852,6 +819,26 @@ void WirelessSetupManager::onNetworkServiceStateChanged(const QLowEnergyService:
setNetworkingEnabled((bool)networkingEnabledCharacteristic.value().toHex().toUInt(0, 16));
setWirelessEnabled((bool)wirelessEnabledCharacteristic.value().toHex().toUInt(0, 16));
// Wifi service
if (!m_wifiService) {
m_wifiService = controller()->createServiceObject(wifiServiceUuid, this);
if (!m_wifiService) {
qWarning() << "WifiSetupManager: Could not create wifi service.";
controller()->disconnectFromDevice();
return;
}
connect(m_wifiService, &QLowEnergyService::stateChanged, this, &WirelessSetupManager::onWifiServiceStateChanged);
connect(m_wifiService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onWifiServiceCharacteristicChanged);
connect(m_wifiService, &QLowEnergyService::characteristicRead, this, &WirelessSetupManager::onWifiServiceReadFinished);
if (m_wifiService->state() == QLowEnergyService::DiscoveryRequired) {
qDebug() << "WifiSetupManager: start discovering wifi service...";
m_wifiService->discoverDetails();
}
}
checkInitialized();
}
@ -930,6 +917,24 @@ void WirelessSetupManager::onWifiServiceStateChanged(const QLowEnergyService::Se
setWirelessStatus(m_wifiService->characteristic(wifiStatusCharacteristicUuid).value().toHex().toUInt(0, 16));
m_accessPointsProxy->invokeSort();
// System service
if (!m_systemService) {
m_systemService = controller()->createServiceObject(systemServiceUuid, this);
if (!m_systemService) {
qWarning() << "WifiSetupManager: Could not create system service. Looks like this networkmanager has not implemented that.";
//controller()->disconnectFromDevice();
} else {
connect(m_systemService, &QLowEnergyService::stateChanged, this, &WirelessSetupManager::onSystemServiceStateChanged);
connect(m_systemService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onSystemServiceCharacteristicChanged);
connect(m_systemService, &QLowEnergyService::characteristicRead, this, &WirelessSetupManager::onSystemServiceReadFinished);
if (m_systemService->state() == QLowEnergyService::DiscoveryRequired) {
qDebug() << "WifiSetupManager: start discovering system service...";
m_systemService->discoverDetails();
}
}
}
checkInitialized();
}

View File

@ -196,7 +196,7 @@ Page {
target: networkManger.manager
onInitializedChanged: {
if (networkManger.manager.initialized) {
pageStack.push(Qt.resolvedUrl("WirelessControlerPage.qml"), { name: root.name, address: root.address, networkManger: networkManger } )
pageStack.push(Qt.resolvedUrl("../WirelessControlerPage.qml"), { name: root.name, address: root.address, networkManger: networkManger } )
} else {
pageStack.pop()
}