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

View File

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

View File

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

View File

@ -119,8 +119,29 @@ void BluetoothDiscovery::onBluetoothHostModeChanged(const QBluetoothLocalDevice:
void BluetoothDiscovery::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo) void BluetoothDiscovery::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo)
{ {
qDebug() << "BluetoothDiscovery: [+]" << deviceInfo.name() << "(" << deviceInfo.address().toString() << ")" << (deviceInfo.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration ? "LE" : ""); BluetoothDeviceInfo *deviceInformation = new BluetoothDeviceInfo(deviceInfo);
m_deviceInfos->addBluetoothDeviceInfo(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() void BluetoothDiscovery::discoveryFinished()

View File

@ -21,6 +21,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "networkmanagercontroler.h" #include "networkmanagercontroler.h"
#include "engine.h"
NetworkManagerControler::NetworkManagerControler(QObject *parent) : QObject(parent) NetworkManagerControler::NetworkManagerControler(QObject *parent) : QObject(parent)
{ {
@ -61,7 +62,20 @@ void NetworkManagerControler::connectDevice()
emit managerChanged(); 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(); emit managerChanged();
m_wirelessSetupManager->connectDevice(); m_wirelessSetupManager->connectDevice();

View File

@ -710,62 +710,11 @@ void WirelessSetupManager::onServiceDiscoveryFinished()
connect(m_deviceInformationService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onDeviceInformationCharacteristicChanged); connect(m_deviceInformationService, &QLowEnergyService::characteristicChanged, this, &WirelessSetupManager::onDeviceInformationCharacteristicChanged);
connect(m_deviceInformationService, &QLowEnergyService::characteristicRead, 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(); 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())); setFirmwareRevision(QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::FirmwareRevisionString).value()));
setHardwareRevision(QString::fromUtf8(m_deviceInformationService->characteristic(QBluetoothUuid::HardwareRevisionString).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(); checkInitialized();
} }
@ -852,6 +819,26 @@ void WirelessSetupManager::onNetworkServiceStateChanged(const QLowEnergyService:
setNetworkingEnabled((bool)networkingEnabledCharacteristic.value().toHex().toUInt(0, 16)); setNetworkingEnabled((bool)networkingEnabledCharacteristic.value().toHex().toUInt(0, 16));
setWirelessEnabled((bool)wirelessEnabledCharacteristic.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(); checkInitialized();
} }
@ -930,6 +917,24 @@ void WirelessSetupManager::onWifiServiceStateChanged(const QLowEnergyService::Se
setWirelessStatus(m_wifiService->characteristic(wifiStatusCharacteristicUuid).value().toHex().toUInt(0, 16)); setWirelessStatus(m_wifiService->characteristic(wifiStatusCharacteristicUuid).value().toHex().toUInt(0, 16));
m_accessPointsProxy->invokeSort(); 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(); checkInitialized();
} }

View File

@ -196,7 +196,7 @@ Page {
target: networkManger.manager target: networkManger.manager
onInitializedChanged: { onInitializedChanged: {
if (networkManger.manager.initialized) { 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 { } else {
pageStack.pop() pageStack.pop()
} }