summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/qlowenergycontroller_bluez.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bluetooth/qlowenergycontroller_bluez.cpp')
-rw-r--r--src/bluetooth/qlowenergycontroller_bluez.cpp313
1 files changed, 202 insertions, 111 deletions
diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp
index ca3f7760..502f42ad 100644
--- a/src/bluetooth/qlowenergycontroller_bluez.cpp
+++ b/src/bluetooth/qlowenergycontroller_bluez.cpp
@@ -39,15 +39,21 @@
****************************************************************************/
#include "lecmaccalculator_p.h"
-#include "qlowenergycontroller_p.h"
-#include "qbluetoothsocket_p.h"
+#include "qlowenergycontroller_bluez_p.h"
+#include "qbluetoothsocketbase_p.h"
#include "qleadvertiser_p.h"
#include "bluez/bluez_data_p.h"
#include "bluez/hcimanager_p.h"
+#include "bluez/objectmanager_p.h"
#include "bluez/remotedevicemanager_p.h"
#include "bluez/bluez5_helper_p.h"
#include "bluez/bluetoothmanagement_p.h"
+// Bluez 4
+#include "bluez/adapter_p.h"
+#include "bluez/device_p.h"
+#include "bluez/manager_p.h"
+
#include <QtCore/QFileInfo>
#include <QtCore/QLoggingCategory>
#include <QtCore/QSettings>
@@ -263,11 +269,8 @@ template<> void putDataAndIncrement(const QByteArray &value, char *&dst)
dst += value.count();
}
-QLowEnergyControllerPrivate::QLowEnergyControllerPrivate()
- : QObject(),
- state(QLowEnergyController::UnconnectedState),
- error(QLowEnergyController::NoError),
- lastLocalHandle(0),
+QLowEnergyControllerPrivateBluez::QLowEnergyControllerPrivateBluez()
+ : QLowEnergyControllerPrivate(),
l2cpSocket(0), requestPending(false),
mtuSize(ATT_DEFAULT_LE_MTU),
securityLevelValue(-1),
@@ -280,7 +283,7 @@ QLowEnergyControllerPrivate::QLowEnergyControllerPrivate()
qRegisterMetaType<QList<QLowEnergyHandle> >();
}
-void QLowEnergyControllerPrivate::init()
+void QLowEnergyControllerPrivateBluez::init()
{
hciManager = new HciManager(localAdapter, this);
if (!hciManager->isValid())
@@ -331,12 +334,12 @@ void QLowEnergyControllerPrivate::init()
requestTimer->setSingleShot(true);
requestTimer->setInterval(gattRequestTimeout);
connect(requestTimer, &QTimer::timeout,
- this, &QLowEnergyControllerPrivate::handleGattRequestTimeout);
+ this, &QLowEnergyControllerPrivateBluez::handleGattRequestTimeout);
}
}
}
-void QLowEnergyControllerPrivate::handleGattRequestTimeout()
+void QLowEnergyControllerPrivateBluez::handleGattRequestTimeout()
{
// antyhing open that might require cancellation or a warning?
if (encryptionChangePending) {
@@ -346,8 +349,8 @@ void QLowEnergyControllerPrivate::handleGattRequestTimeout()
}
if (!openRequests.isEmpty() && requestPending) {
- requestPending = false; // reset pending flag
const Request currentRequest = openRequests.dequeue();
+ requestPending = false; // reset pending flag
qCWarning(QT_BT_BLUEZ).nospace() << "****** Request type 0x" << hex << currentRequest.command
<< " to server/peripheral timed out";
@@ -372,7 +375,6 @@ void QLowEnergyControllerPrivate::handleGattRequestTimeout()
case ATT_OP_EXCHANGE_MTU_REQUEST: // MTU change request
// never received reply to MTU request
// it is safe to skip and go to next request
- sendNextPendingRequest();
break;
case ATT_OP_READ_BY_GROUP_REQUEST: // primary or secondary service discovery
case ATT_OP_READ_BY_TYPE_REQUEST: // characteristic or included service discovery
@@ -406,12 +408,17 @@ void QLowEnergyControllerPrivate::handleGattRequestTimeout()
break;
default:
// not a command used by central role implementation
- return;
+ qCWarning(QT_BT_BLUEZ) << "Missing response for ATT peripheral command: "
+ << hex << command;
+ break;
}
+
+ // spin openRequest queue further
+ sendNextPendingRequest();
}
}
-QLowEnergyControllerPrivate::~QLowEnergyControllerPrivate()
+QLowEnergyControllerPrivateBluez::~QLowEnergyControllerPrivateBluez()
{
closeServerSocket();
delete cmacCalculator;
@@ -467,7 +474,7 @@ private:
};
-void QLowEnergyControllerPrivate::startAdvertising(const QLowEnergyAdvertisingParameters &params,
+void QLowEnergyControllerPrivateBluez::startAdvertising(const QLowEnergyAdvertisingParameters &params,
const QLowEnergyAdvertisingData &advertisingData,
const QLowEnergyAdvertisingData &scanResponseData)
{
@@ -476,7 +483,7 @@ void QLowEnergyControllerPrivate::startAdvertising(const QLowEnergyAdvertisingPa
advertiser = new QLeAdvertiserBluez(params, advertisingData, scanResponseData, *hciManager,
this);
connect(advertiser, &QLeAdvertiser::errorOccurred, this,
- &QLowEnergyControllerPrivate::handleAdvertisingError);
+ &QLowEnergyControllerPrivateBluez::handleAdvertisingError);
}
setState(QLowEnergyController::AdvertisingState);
advertiser->startAdvertising();
@@ -497,16 +504,16 @@ void QLowEnergyControllerPrivate::startAdvertising(const QLowEnergyAdvertisingPa
const int socketFd = serverSocket.takeSocket();
serverSocketNotifier = new QSocketNotifier(socketFd, QSocketNotifier::Read, this);
connect(serverSocketNotifier, &QSocketNotifier::activated, this,
- &QLowEnergyControllerPrivate::handleConnectionRequest);
+ &QLowEnergyControllerPrivateBluez::handleConnectionRequest);
}
-void QLowEnergyControllerPrivate::stopAdvertising()
+void QLowEnergyControllerPrivateBluez::stopAdvertising()
{
setState(QLowEnergyController::UnconnectedState);
advertiser->stopAdvertising();
}
-void QLowEnergyControllerPrivate::requestConnectionUpdate(const QLowEnergyConnectionParameters &params)
+void QLowEnergyControllerPrivateBluez::requestConnectionUpdate(const QLowEnergyConnectionParameters &params)
{
// The spec says that the connection update command can be used by both slave and master
// devices, but BlueZ allows it only for master devices. So for slave devices, we have to use a
@@ -518,7 +525,7 @@ void QLowEnergyControllerPrivate::requestConnectionUpdate(const QLowEnergyConnec
hciManager->sendConnectionParameterUpdateRequest(connectionHandle, params);
}
-void QLowEnergyControllerPrivate::connectToDevice()
+void QLowEnergyControllerPrivateBluez::connectToDevice()
{
if (remoteDevice.isNull()) {
qCWarning(QT_BT_BLUEZ) << "Invalid/null remote device address";
@@ -527,8 +534,10 @@ void QLowEnergyControllerPrivate::connectToDevice()
}
setState(QLowEnergyController::ConnectingState);
- if (l2cpSocket)
+ if (l2cpSocket) {
delete l2cpSocket;
+ l2cpSocket = nullptr;
+ }
createServicesForCentralIfRequired();
@@ -550,7 +559,7 @@ void QLowEnergyControllerPrivate::connectToDevice()
if (!device1Manager) {
device1Manager = new RemoteDeviceManager(localAdapter, this);
connect(device1Manager, &RemoteDeviceManager::finished,
- this, &QLowEnergyControllerPrivate::activeConnectionTerminationDone);
+ this, &QLowEnergyControllerPrivateBluez::activeConnectionTerminationDone);
}
QVector<QBluetoothAddress> connectedAddresses;
@@ -568,7 +577,7 @@ void QLowEnergyControllerPrivate::connectToDevice()
/*!
* Handles outcome of attempts to close external connections.
*/
-void QLowEnergyControllerPrivate::activeConnectionTerminationDone()
+void QLowEnergyControllerPrivateBluez::activeConnectionTerminationDone()
{
if (!device1Manager)
return;
@@ -581,6 +590,7 @@ void QLowEnergyControllerPrivate::activeConnectionTerminationDone()
qCWarning(QT_BT_BLUEZ) << "Cannot close pending external BTLE connections. Aborting connect attempt";
setError(QLowEnergyController::ConnectionError);
setState(QLowEnergyController::UnconnectedState);
+ l2cpDisconnected();
return;
} else {
establishL2cpClientSocket();
@@ -590,7 +600,7 @@ void QLowEnergyControllerPrivate::activeConnectionTerminationDone()
/*!
* Establishes the L2CP client socket.
*/
-void QLowEnergyControllerPrivate::establishL2cpClientSocket()
+void QLowEnergyControllerPrivateBluez::establishL2cpClientSocket()
{
//we are already in Connecting state
@@ -646,7 +656,7 @@ void QLowEnergyControllerPrivate::establishL2cpClientSocket()
loadSigningDataIfNecessary(LocalSigningKey);
}
-void QLowEnergyControllerPrivate::createServicesForCentralIfRequired()
+void QLowEnergyControllerPrivateBluez::createServicesForCentralIfRequired()
{
bool ok = false;
int value = qEnvironmentVariableIntValue("QT_DEFAULT_CENTRAL_SERVICES", &ok);
@@ -712,7 +722,7 @@ void QLowEnergyControllerPrivate::createServicesForCentralIfRequired()
service->setParent(q);
}
-void QLowEnergyControllerPrivate::l2cpConnected()
+void QLowEnergyControllerPrivateBluez::l2cpConnected()
{
Q_Q(QLowEnergyController);
@@ -723,26 +733,37 @@ void QLowEnergyControllerPrivate::l2cpConnected()
emit q->connected();
}
-void QLowEnergyControllerPrivate::disconnectFromDevice()
+void QLowEnergyControllerPrivateBluez::disconnectFromDevice()
{
setState(QLowEnergyController::ClosingState);
- l2cpSocket->close();
+ if (l2cpSocket)
+ l2cpSocket->close();
resetController();
+
+ // this may happen when RemoteDeviceManager::JobType::JobDisconnectDevice
+ // is pending.
+ if (!l2cpSocket) {
+ qWarning(QT_BT_BLUEZ) << "Unexpected closure of device. Cleaning up internal states.";
+ l2cpDisconnected();
+ }
}
-void QLowEnergyControllerPrivate::l2cpDisconnected()
+void QLowEnergyControllerPrivateBluez::l2cpDisconnected()
{
Q_Q(QLowEnergyController);
- if (role == QLowEnergyController::PeripheralRole)
+ if (role == QLowEnergyController::PeripheralRole) {
storeClientConfigurations();
+ remoteDevice.clear();
+ remoteName.clear();
+ }
invalidateServices();
resetController();
setState(QLowEnergyController::UnconnectedState);
emit q->disconnected();
}
-void QLowEnergyControllerPrivate::l2cpErrorChanged(QBluetoothSocket::SocketError e)
+void QLowEnergyControllerPrivateBluez::l2cpErrorChanged(QBluetoothSocket::SocketError e)
{
switch (e) {
case QBluetoothSocket::HostNotFoundError:
@@ -775,7 +796,7 @@ void QLowEnergyControllerPrivate::l2cpErrorChanged(QBluetoothSocket::SocketError
}
-void QLowEnergyControllerPrivate::resetController()
+void QLowEnergyControllerPrivateBluez::resetController()
{
openRequests.clear();
openPrepareWriteRequests.clear();
@@ -784,15 +805,19 @@ void QLowEnergyControllerPrivate::resetController()
requestPending = false;
encryptionChangePending = false;
receivedMtuExchangeRequest = false;
+ mtuSize = ATT_DEFAULT_LE_MTU;
securityLevelValue = -1;
connectionHandle = 0;
- // public API behavior requires stop of advertisement
- if (role == QLowEnergyController::PeripheralRole && advertiser)
- advertiser->stopAdvertising();
+ if (role == QLowEnergyController::PeripheralRole) {
+ // public API behavior requires stop of advertisement
+ if (advertiser)
+ advertiser->stopAdvertising();
+ localAttributes.clear();
+ }
}
-void QLowEnergyControllerPrivate::restartRequestTimer()
+void QLowEnergyControllerPrivateBluez::restartRequestTimer()
{
if (!requestTimer)
return;
@@ -801,7 +826,7 @@ void QLowEnergyControllerPrivate::restartRequestTimer()
requestTimer->start(gattRequestTimeout);
}
-void QLowEnergyControllerPrivate::l2cpReadyRead()
+void QLowEnergyControllerPrivateBluez::l2cpReadyRead()
{
const QByteArray incomingPacket = l2cpSocket->readAll();
qCDebug(QT_BT_BLUEZ) << "Received size:" << incomingPacket.size() << "data:"
@@ -899,7 +924,7 @@ void QLowEnergyControllerPrivate::l2cpReadyRead()
* callback is called. The first pending request in the queue is the request
* that triggered the encryption request.
*/
-void QLowEnergyControllerPrivate::encryptionChangedEvent(
+void QLowEnergyControllerPrivateBluez::encryptionChangedEvent(
const QBluetoothAddress &address, bool wasSuccess)
{
if (!encryptionChangePending) // somebody else caused change event
@@ -948,7 +973,7 @@ void QLowEnergyControllerPrivate::encryptionChangedEvent(
sendNextPendingRequest();
}
-void QLowEnergyControllerPrivate::sendPacket(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::sendPacket(const QByteArray &packet)
{
qint64 result = l2cpSocket->write(packet.constData(),
packet.size());
@@ -967,7 +992,7 @@ void QLowEnergyControllerPrivate::sendPacket(const QByteArray &packet)
}
-void QLowEnergyControllerPrivate::sendNextPendingRequest()
+void QLowEnergyControllerPrivateBluez::sendNextPendingRequest()
{
if (openRequests.isEmpty() || requestPending || encryptionChangePending)
return;
@@ -1032,7 +1057,7 @@ QLowEnergyHandle parseReadByTypeIncludeDiscovery(
return attributeHandle;
}
-void QLowEnergyControllerPrivate::processReply(
+void QLowEnergyControllerPrivateBluez::processReply(
const Request &request, const QByteArray &response)
{
Q_Q(QLowEnergyController);
@@ -1233,9 +1258,9 @@ void QLowEnergyControllerPrivate::processReply(
} else if (!isServiceDiscoveryRun) {
// not encryption problem -> abort readCharacteristic()/readDescriptor() run
if (!descriptorHandle)
- emit service->error(QLowEnergyService::CharacteristicReadError);
+ service->setError(QLowEnergyService::CharacteristicReadError);
else
- emit service->error(QLowEnergyService::DescriptorReadError);
+ service->setError(QLowEnergyService::DescriptorReadError);
}
} else {
if (!descriptorHandle)
@@ -1570,12 +1595,12 @@ void QLowEnergyControllerPrivate::processReply(
}
}
-void QLowEnergyControllerPrivate::discoverServices()
+void QLowEnergyControllerPrivateBluez::discoverServices()
{
sendReadByGroupRequest(0x0001, 0xFFFF, GATT_PRIMARY_SERVICE);
}
-void QLowEnergyControllerPrivate::sendReadByGroupRequest(
+void QLowEnergyControllerPrivateBluez::sendReadByGroupRequest(
QLowEnergyHandle start, QLowEnergyHandle end, quint16 type)
{
//call for primary and secondary services
@@ -1600,7 +1625,7 @@ void QLowEnergyControllerPrivate::sendReadByGroupRequest(
sendNextPendingRequest();
}
-void QLowEnergyControllerPrivate::discoverServiceDetails(const QBluetoothUuid &service)
+void QLowEnergyControllerPrivateBluez::discoverServiceDetails(const QBluetoothUuid &service)
{
if (!serviceList.contains(service)) {
qCWarning(QT_BT_BLUEZ) << "Discovery of unknown service" << service.toString()
@@ -1613,7 +1638,7 @@ void QLowEnergyControllerPrivate::discoverServiceDetails(const QBluetoothUuid &s
sendReadByTypeRequest(serviceData, serviceData->startHandle, GATT_INCLUDED_SERVICE);
}
-void QLowEnergyControllerPrivate::sendReadByTypeRequest(
+void QLowEnergyControllerPrivateBluez::sendReadByTypeRequest(
QSharedPointer<QLowEnergyServicePrivate> serviceData,
QLowEnergyHandle nextHandle, quint16 attributeType)
{
@@ -1649,7 +1674,7 @@ void QLowEnergyControllerPrivate::sendReadByTypeRequest(
\a readCharacteristics determines whether we intend to read a characteristic;
otherwise we read a descriptor.
*/
-void QLowEnergyControllerPrivate::readServiceValues(
+void QLowEnergyControllerPrivateBluez::readServiceValues(
const QBluetoothUuid &serviceUuid, bool readCharacteristics)
{
quint8 packet[READ_REQUEST_HEADER_SIZE];
@@ -1743,7 +1768,7 @@ void QLowEnergyControllerPrivate::readServiceValues(
open requests to finish the current value read up before
starting the next read request.
*/
-void QLowEnergyControllerPrivate::readServiceValuesByOffset(
+void QLowEnergyControllerPrivateBluez::readServiceValuesByOffset(
uint handleData, quint16 offset, bool isLastValue)
{
const QLowEnergyHandle charHandle = (handleData & 0xffff);
@@ -1782,7 +1807,7 @@ void QLowEnergyControllerPrivate::readServiceValuesByOffset(
openRequests.prepend(request);
}
-void QLowEnergyControllerPrivate::discoverServiceDescriptors(
+void QLowEnergyControllerPrivateBluez::discoverServiceDescriptors(
const QBluetoothUuid &serviceUuid)
{
qCDebug(QT_BT_BLUEZ) << "Discovering descriptor values for"
@@ -1802,7 +1827,7 @@ void QLowEnergyControllerPrivate::discoverServiceDescriptors(
discoverNextDescriptor(service, keys, keys[0]);
}
-void QLowEnergyControllerPrivate::processUnsolicitedReply(const QByteArray &payload)
+void QLowEnergyControllerPrivateBluez::processUnsolicitedReply(const QByteArray &payload)
{
const char *data = payload.constData();
bool isNotification = (data[0] == ATT_OP_HANDLE_VAL_NOTIFICATION);
@@ -1826,7 +1851,7 @@ void QLowEnergyControllerPrivate::processUnsolicitedReply(const QByteArray &payl
}
}
-void QLowEnergyControllerPrivate::exchangeMTU()
+void QLowEnergyControllerPrivateBluez::exchangeMTU()
{
qCDebug(QT_BT_BLUEZ) << "Exchanging MTU";
@@ -1845,7 +1870,7 @@ void QLowEnergyControllerPrivate::exchangeMTU()
sendNextPendingRequest();
}
-int QLowEnergyControllerPrivate::securityLevel() const
+int QLowEnergyControllerPrivateBluez::securityLevel() const
{
int socket = l2cpSocket->socketDescriptor();
if (socket < 0) {
@@ -1884,7 +1909,7 @@ int QLowEnergyControllerPrivate::securityLevel() const
return -1;
}
-bool QLowEnergyControllerPrivate::setSecurityLevel(int level)
+bool QLowEnergyControllerPrivateBluez::setSecurityLevel(int level)
{
if (level > BT_SECURITY_HIGH || level < BT_SECURITY_LOW)
return false;
@@ -1931,7 +1956,7 @@ bool QLowEnergyControllerPrivate::setSecurityLevel(int level)
return false;
}
-void QLowEnergyControllerPrivate::discoverNextDescriptor(
+void QLowEnergyControllerPrivateBluez::discoverNextDescriptor(
QSharedPointer<QLowEnergyServicePrivate> serviceData,
const QList<QLowEnergyHandle> pendingCharHandles,
const QLowEnergyHandle startingHandle)
@@ -1968,7 +1993,7 @@ void QLowEnergyControllerPrivate::discoverNextDescriptor(
sendNextPendingRequest();
}
-void QLowEnergyControllerPrivate::sendNextPrepareWriteRequest(
+void QLowEnergyControllerPrivateBluez::sendNextPrepareWriteRequest(
const QLowEnergyHandle handle, const QByteArray &newValue,
quint16 offset)
{
@@ -2023,7 +2048,7 @@ void QLowEnergyControllerPrivate::sendNextPrepareWriteRequest(
Otherwise this function sends an execute request for all pending prepare
write requests.
*/
-void QLowEnergyControllerPrivate::sendExecuteWriteRequest(
+void QLowEnergyControllerPrivateBluez::sendExecuteWriteRequest(
const QLowEnergyHandle attrHandle, const QByteArray &newValue,
bool isCancelation)
{
@@ -2055,7 +2080,7 @@ void QLowEnergyControllerPrivate::sendExecuteWriteRequest(
TODO Reliable/prepare write across multiple characteristics is not supported
*/
-void QLowEnergyControllerPrivate::writeCharacteristic(
+void QLowEnergyControllerPrivateBluez::writeCharacteristic(
const QSharedPointer<QLowEnergyServicePrivate> service,
const QLowEnergyHandle charHandle,
const QByteArray &newValue,
@@ -2073,7 +2098,7 @@ void QLowEnergyControllerPrivate::writeCharacteristic(
writeCharacteristicForCentral(service, charHandle, charData.valueHandle, newValue, mode);
}
-void QLowEnergyControllerPrivate::writeDescriptor(
+void QLowEnergyControllerPrivateBluez::writeDescriptor(
const QSharedPointer<QLowEnergyServicePrivate> service,
const QLowEnergyHandle charHandle,
const QLowEnergyHandle descriptorHandle,
@@ -2092,7 +2117,7 @@ void QLowEnergyControllerPrivate::writeDescriptor(
Reads the value of one specific characteristic.
*/
-void QLowEnergyControllerPrivate::readCharacteristic(
+void QLowEnergyControllerPrivateBluez::readCharacteristic(
const QSharedPointer<QLowEnergyServicePrivate> service,
const QLowEnergyHandle charHandle)
{
@@ -2130,7 +2155,7 @@ void QLowEnergyControllerPrivate::readCharacteristic(
sendNextPendingRequest();
}
-void QLowEnergyControllerPrivate::readDescriptor(
+void QLowEnergyControllerPrivateBluez::readDescriptor(
const QSharedPointer<QLowEnergyServicePrivate> service,
const QLowEnergyHandle charHandle,
const QLowEnergyHandle descriptorHandle)
@@ -2169,7 +2194,7 @@ void QLowEnergyControllerPrivate::readDescriptor(
* Returns true if the encryption change was successfully requested.
* The request is triggered if we got a related ATT error.
*/
-bool QLowEnergyControllerPrivate::increaseEncryptLevelfRequired(quint8 errorCode)
+bool QLowEnergyControllerPrivateBluez::increaseEncryptLevelfRequired(quint8 errorCode)
{
if (securityLevelValue == BT_SECURITY_HIGH)
return false;
@@ -2197,14 +2222,14 @@ bool QLowEnergyControllerPrivate::increaseEncryptLevelfRequired(quint8 errorCode
return false;
}
-void QLowEnergyControllerPrivate::handleAdvertisingError()
+void QLowEnergyControllerPrivateBluez::handleAdvertisingError()
{
qCWarning(QT_BT_BLUEZ) << "received advertising error";
setError(QLowEnergyController::AdvertisingError);
setState(QLowEnergyController::UnconnectedState);
}
-bool QLowEnergyControllerPrivate::checkPacketSize(const QByteArray &packet, int minSize,
+bool QLowEnergyControllerPrivateBluez::checkPacketSize(const QByteArray &packet, int minSize,
int maxSize)
{
if (maxSize == -1)
@@ -2217,7 +2242,7 @@ bool QLowEnergyControllerPrivate::checkPacketSize(const QByteArray &packet, int
return false;
}
-bool QLowEnergyControllerPrivate::checkHandle(const QByteArray &packet, QLowEnergyHandle handle)
+bool QLowEnergyControllerPrivateBluez::checkHandle(const QByteArray &packet, QLowEnergyHandle handle)
{
if (handle != 0 && handle <= lastLocalHandle)
return true;
@@ -2225,7 +2250,7 @@ bool QLowEnergyControllerPrivate::checkHandle(const QByteArray &packet, QLowEner
return false;
}
-bool QLowEnergyControllerPrivate::checkHandlePair(quint8 request, QLowEnergyHandle startingHandle,
+bool QLowEnergyControllerPrivateBluez::checkHandlePair(quint8 request, QLowEnergyHandle startingHandle,
QLowEnergyHandle endingHandle)
{
if (startingHandle == 0 || startingHandle > endingHandle) {
@@ -2236,7 +2261,7 @@ bool QLowEnergyControllerPrivate::checkHandlePair(quint8 request, QLowEnergyHand
return true;
}
-void QLowEnergyControllerPrivate::handleExchangeMtuRequest(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handleExchangeMtuRequest(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.2
@@ -2263,7 +2288,7 @@ void QLowEnergyControllerPrivate::handleExchangeMtuRequest(const QByteArray &pac
qCDebug(QT_BT_BLUEZ) << "Sending server RX MTU" << ATT_MAX_LE_MTU;
}
-void QLowEnergyControllerPrivate::handleFindInformationRequest(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handleFindInformationRequest(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.3.1-2
@@ -2296,7 +2321,7 @@ void QLowEnergyControllerPrivate::handleFindInformationRequest(const QByteArray
}
-void QLowEnergyControllerPrivate::handleFindByTypeValueRequest(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handleFindByTypeValueRequest(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.3.3-4
@@ -2331,7 +2356,7 @@ void QLowEnergyControllerPrivate::handleFindByTypeValueRequest(const QByteArray
sendListResponse(responsePrefix, elemSize, results, elemWriter);
}
-void QLowEnergyControllerPrivate::handleReadByTypeRequest(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handleReadByTypeRequest(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.4.1-2
@@ -2384,7 +2409,7 @@ void QLowEnergyControllerPrivate::handleReadByTypeRequest(const QByteArray &pack
sendListResponse(responsePrefix, elementSize, results, elemWriter);
}
-void QLowEnergyControllerPrivate::handleReadRequest(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handleReadRequest(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.4.3-4
@@ -2411,7 +2436,7 @@ void QLowEnergyControllerPrivate::handleReadRequest(const QByteArray &packet)
sendPacket(response);
}
-void QLowEnergyControllerPrivate::handleReadBlobRequest(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handleReadBlobRequest(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.4.5-6
@@ -2450,7 +2475,7 @@ void QLowEnergyControllerPrivate::handleReadBlobRequest(const QByteArray &packet
sendPacket(response);
}
-void QLowEnergyControllerPrivate::handleReadMultipleRequest(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handleReadMultipleRequest(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.4.7-8
@@ -2486,7 +2511,7 @@ void QLowEnergyControllerPrivate::handleReadMultipleRequest(const QByteArray &pa
sendPacket(response);
}
-void QLowEnergyControllerPrivate::handleReadByGroupTypeRequest(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handleReadByGroupTypeRequest(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.4.9-10
@@ -2545,7 +2570,7 @@ void QLowEnergyControllerPrivate::handleReadByGroupTypeRequest(const QByteArray
sendListResponse(responsePrefix, elementSize, results, elemWriter);
}
-void QLowEnergyControllerPrivate::updateLocalAttributeValue(
+void QLowEnergyControllerPrivateBluez::updateLocalAttributeValue(
QLowEnergyHandle handle,
const QByteArray &value,
QLowEnergyCharacteristic &characteristic,
@@ -2579,7 +2604,7 @@ void QLowEnergyControllerPrivate::updateLocalAttributeValue(
static bool isNotificationEnabled(quint16 clientConfigValue) { return clientConfigValue & 0x1; }
static bool isIndicationEnabled(quint16 clientConfigValue) { return clientConfigValue & 0x2; }
-void QLowEnergyControllerPrivate::writeCharacteristicForPeripheral(
+void QLowEnergyControllerPrivateBluez::writeCharacteristicForPeripheral(
QLowEnergyServicePrivate::CharData &charData,
const QByteArray &newValue)
{
@@ -2636,7 +2661,7 @@ void QLowEnergyControllerPrivate::writeCharacteristicForPeripheral(
}
}
-void QLowEnergyControllerPrivate::writeCharacteristicForCentral(const QSharedPointer<QLowEnergyServicePrivate> &service,
+void QLowEnergyControllerPrivateBluez::writeCharacteristicForCentral(const QSharedPointer<QLowEnergyServicePrivate> &service,
QLowEnergyHandle charHandle,
QLowEnergyHandle valueHandle,
const QByteArray &newValue,
@@ -2710,7 +2735,7 @@ void QLowEnergyControllerPrivate::writeCharacteristicForCentral(const QSharedPoi
sendNextPendingRequest();
}
-void QLowEnergyControllerPrivate::writeDescriptorForPeripheral(
+void QLowEnergyControllerPrivateBluez::writeDescriptorForPeripheral(
const QSharedPointer<QLowEnergyServicePrivate> &service,
const QLowEnergyHandle charHandle,
const QLowEnergyHandle descriptorHandle,
@@ -2727,7 +2752,7 @@ void QLowEnergyControllerPrivate::writeDescriptorForPeripheral(
service->characteristicList[charHandle].descriptorList[descriptorHandle].value = newValue;
}
-void QLowEnergyControllerPrivate::writeDescriptorForCentral(
+void QLowEnergyControllerPrivateBluez::writeDescriptorForCentral(
const QLowEnergyHandle charHandle,
const QLowEnergyHandle descriptorHandle,
const QByteArray &newValue)
@@ -2760,7 +2785,7 @@ void QLowEnergyControllerPrivate::writeDescriptorForCentral(
sendNextPendingRequest();
}
-void QLowEnergyControllerPrivate::handleWriteRequestOrCommand(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handleWriteRequestOrCommand(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.5.1-3
@@ -2854,7 +2879,7 @@ void QLowEnergyControllerPrivate::handleWriteRequestOrCommand(const QByteArray &
}
}
-void QLowEnergyControllerPrivate::handlePrepareWriteRequest(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handlePrepareWriteRequest(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.6.1
@@ -2885,7 +2910,7 @@ void QLowEnergyControllerPrivate::handlePrepareWriteRequest(const QByteArray &pa
sendPacket(response);
}
-void QLowEnergyControllerPrivate::handleExecuteWriteRequest(const QByteArray &packet)
+void QLowEnergyControllerPrivateBluez::handleExecuteWriteRequest(const QByteArray &packet)
{
// Spec v4.2, Vol 3, Part F, 3.4.6.3
@@ -2933,7 +2958,7 @@ void QLowEnergyControllerPrivate::handleExecuteWriteRequest(const QByteArray &pa
emit descriptor.d_ptr->descriptorWritten(descriptor, descriptor.value());
}
-void QLowEnergyControllerPrivate::sendErrorResponse(quint8 request, quint16 handle, quint8 code)
+void QLowEnergyControllerPrivateBluez::sendErrorResponse(quint8 request, quint16 handle, quint8 code)
{
// An ATT command never receives an error response.
if (request == ATT_OP_WRITE_COMMAND || request == ATT_OP_SIGNED_WRITE_COMMAND)
@@ -2949,7 +2974,7 @@ void QLowEnergyControllerPrivate::sendErrorResponse(quint8 request, quint16 hand
sendPacket(packet);
}
-void QLowEnergyControllerPrivate::sendListResponse(const QByteArray &packetStart, int elemSize,
+void QLowEnergyControllerPrivateBluez::sendListResponse(const QByteArray &packetStart, int elemSize,
const QVector<Attribute> &attributes, const ElemWriter &elemWriter)
{
const int offset = packetStart.count();
@@ -2965,19 +2990,19 @@ void QLowEnergyControllerPrivate::sendListResponse(const QByteArray &packetStart
sendPacket(response);
}
-void QLowEnergyControllerPrivate::sendNotification(QLowEnergyHandle handle)
+void QLowEnergyControllerPrivateBluez::sendNotification(QLowEnergyHandle handle)
{
sendNotificationOrIndication(ATT_OP_HANDLE_VAL_NOTIFICATION, handle);
}
-void QLowEnergyControllerPrivate::sendIndication(QLowEnergyHandle handle)
+void QLowEnergyControllerPrivateBluez::sendIndication(QLowEnergyHandle handle)
{
Q_ASSERT(!indicationInFlight);
indicationInFlight = true;
sendNotificationOrIndication(ATT_OP_HANDLE_VAL_INDICATION, handle);
}
-void QLowEnergyControllerPrivate::sendNotificationOrIndication(
+void QLowEnergyControllerPrivateBluez::sendNotificationOrIndication(
quint8 opCode,
QLowEnergyHandle handle)
{
@@ -2993,13 +3018,76 @@ void QLowEnergyControllerPrivate::sendNotificationOrIndication(
sendPacket(packet);
}
-void QLowEnergyControllerPrivate::sendNextIndication()
+void QLowEnergyControllerPrivateBluez::sendNextIndication()
{
if (!scheduledIndications.isEmpty())
sendIndication(scheduledIndications.takeFirst());
}
-void QLowEnergyControllerPrivate::handleConnectionRequest()
+static QString nameOfRemoteCentral(const QBluetoothAddress &peerAddress, const QBluetoothAddress &localAdapter)
+{
+ const QString peerAddressString = peerAddress.toString();
+ if (isBluez5()) {
+ OrgFreedesktopDBusObjectManagerInterface manager(QStringLiteral("org.bluez"),
+ QStringLiteral("/"),
+ QDBusConnection::systemBus());
+ QDBusPendingReply<ManagedObjectList> reply = manager.GetManagedObjects();
+ reply.waitForFinished();
+ if (reply.isError())
+ return QString();
+
+ ManagedObjectList managedObjectList = reply.value();
+ for (ManagedObjectList::const_iterator it = managedObjectList.constBegin(); it != managedObjectList.constEnd(); ++it) {
+ const InterfaceList &ifaceList = it.value();
+
+ for (InterfaceList::const_iterator jt = ifaceList.constBegin(); jt != ifaceList.constEnd(); ++jt) {
+ const QString &iface = jt.key();
+ const QVariantMap &ifaceValues = jt.value();
+
+ if (iface == QStringLiteral("org.bluez.Device1")) {
+ if (ifaceValues.value(QStringLiteral("Address")).toString() == peerAddressString)
+ return ifaceValues.value(QStringLiteral("Alias")).toString();
+ }
+ }
+ }
+ return QString();
+ } else {
+ OrgBluezManagerInterface manager(QStringLiteral("org.bluez"), QStringLiteral("/"),
+ QDBusConnection::systemBus());
+
+ QDBusPendingReply<QDBusObjectPath> reply = manager.FindAdapter(localAdapter.toString());
+ reply.waitForFinished();
+ if (reply.isError())
+ return QString();
+
+ OrgBluezAdapterInterface adapter(QStringLiteral("org.bluez"), reply.value().path(),
+ QDBusConnection::systemBus());
+
+ QDBusPendingReply<QDBusObjectPath> deviceObjectPath = adapter.FindDevice(peerAddressString);
+ deviceObjectPath.waitForFinished();
+ if (deviceObjectPath.isError()) {
+ if (deviceObjectPath.error().name() != QStringLiteral("org.bluez.Error.DoesNotExist"))
+ return QString();
+
+ deviceObjectPath = adapter.CreateDevice(peerAddressString);
+ deviceObjectPath.waitForFinished();
+ if (deviceObjectPath.isError())
+ return QString();
+ }
+
+ OrgBluezDeviceInterface device(QStringLiteral("org.bluez"), deviceObjectPath.value().path(),
+ QDBusConnection::systemBus());
+
+ QDBusPendingReply<QVariantMap> properties = device.GetProperties();
+ properties.waitForFinished();
+ if (properties.isError())
+ return QString();
+
+ return properties.value().value(QStringLiteral("Alias")).toString();
+ }
+}
+
+void QLowEnergyControllerPrivateBluez::handleConnectionRequest()
{
if (state != QLowEnergyController::AdvertisingState) {
qCWarning(QT_BT_BLUEZ) << "Incoming connection request in unexpected state" << state;
@@ -3017,18 +3105,21 @@ void QLowEnergyControllerPrivate::handleConnectionRequest()
serverSocketNotifier->setEnabled(true);
return;
}
+
remoteDevice = QBluetoothAddress(convertAddress(clientAddr.l2_bdaddr.b));
- qCDebug(QT_BT_BLUEZ) << "GATT connection from device" << remoteDevice;
+ remoteName = nameOfRemoteCentral(remoteDevice, localAdapter);
+ qCDebug(QT_BT_BLUEZ) << "GATT connection from device" << remoteDevice << remoteName;
+
if (connectionHandle == 0)
qCWarning(QT_BT_BLUEZ) << "Received client connection, but no connection complete event";
closeServerSocket();
l2cpSocket = new QBluetoothSocket(QBluetoothServiceInfo::L2capProtocol, this);
connect(l2cpSocket, &QBluetoothSocket::disconnected,
- this, &QLowEnergyControllerPrivate::l2cpDisconnected);
+ this, &QLowEnergyControllerPrivateBluez::l2cpDisconnected);
connect(l2cpSocket, static_cast<void (QBluetoothSocket::*)(QBluetoothSocket::SocketError)>
- (&QBluetoothSocket::error), this, &QLowEnergyControllerPrivate::l2cpErrorChanged);
- connect(l2cpSocket, &QIODevice::readyRead, this, &QLowEnergyControllerPrivate::l2cpReadyRead);
+ (&QBluetoothSocket::error), this, &QLowEnergyControllerPrivateBluez::l2cpErrorChanged);
+ connect(l2cpSocket, &QIODevice::readyRead, this, &QLowEnergyControllerPrivateBluez::l2cpReadyRead);
l2cpSocket->d_ptr->lowEnergySocketType = addressType == QLowEnergyController::PublicAddress
? BDADDR_LE_PUBLIC : BDADDR_LE_RANDOM;
l2cpSocket->setSocketDescriptor(clientSocket, QBluetoothServiceInfo::L2capProtocol,
@@ -3041,7 +3132,7 @@ void QLowEnergyControllerPrivate::handleConnectionRequest()
emit q->connected();
}
-void QLowEnergyControllerPrivate::closeServerSocket()
+void QLowEnergyControllerPrivateBluez::closeServerSocket()
{
if (!serverSocketNotifier)
return;
@@ -3051,7 +3142,7 @@ void QLowEnergyControllerPrivate::closeServerSocket()
serverSocketNotifier = nullptr;
}
-bool QLowEnergyControllerPrivate::isBonded() const
+bool QLowEnergyControllerPrivateBluez::isBonded() const
{
// Pairing does not necessarily imply bonding, but we don't know whether the
// bonding flag was set in the original pairing request.
@@ -3059,7 +3150,7 @@ bool QLowEnergyControllerPrivate::isBonded() const
!= QBluetoothLocalDevice::Unpaired;
}
-QVector<QLowEnergyControllerPrivate::TempClientConfigurationData> QLowEnergyControllerPrivate::gatherClientConfigData()
+QVector<QLowEnergyControllerPrivateBluez::TempClientConfigurationData> QLowEnergyControllerPrivateBluez::gatherClientConfigData()
{
QVector<TempClientConfigurationData> data;
foreach (const auto &service, localServices) {
@@ -3080,7 +3171,7 @@ QVector<QLowEnergyControllerPrivate::TempClientConfigurationData> QLowEnergyCont
return data;
}
-void QLowEnergyControllerPrivate::storeClientConfigurations()
+void QLowEnergyControllerPrivateBluez::storeClientConfigurations()
{
if (!isBonded()) {
clientConfigData.remove(remoteDevice.toUInt64());
@@ -3099,7 +3190,7 @@ void QLowEnergyControllerPrivate::storeClientConfigurations()
clientConfigData.insert(remoteDevice.toUInt64(), clientConfigs);
}
-void QLowEnergyControllerPrivate::restoreClientConfigurations()
+void QLowEnergyControllerPrivateBluez::restoreClientConfigurations()
{
const QVector<TempClientConfigurationData> &tempConfigList = gatherClientConfigData();
const QVector<ClientConfigurationData> &restoredClientConfigs = isBonded()
@@ -3133,7 +3224,7 @@ void QLowEnergyControllerPrivate::restoreClientConfigurations()
sendNextIndication();
}
-void QLowEnergyControllerPrivate::loadSigningDataIfNecessary(SigningKeyType keyType)
+void QLowEnergyControllerPrivateBluez::loadSigningDataIfNecessary(SigningKeyType keyType)
{
const auto signingDataIt = signingData.constFind(remoteDevice.toUInt64());
if (signingDataIt != signingData.constEnd())
@@ -3165,7 +3256,7 @@ void QLowEnergyControllerPrivate::loadSigningDataIfNecessary(SigningKeyType keyT
signingData.insert(remoteDevice.toUInt64(), SigningData(csrk, counter - 1));
}
-void QLowEnergyControllerPrivate::storeSignCounter(SigningKeyType keyType) const
+void QLowEnergyControllerPrivateBluez::storeSignCounter(SigningKeyType keyType) const
{
const auto signingDataIt = signingData.constFind(remoteDevice.toUInt64());
if (signingDataIt == signingData.constEnd())
@@ -3186,12 +3277,12 @@ void QLowEnergyControllerPrivate::storeSignCounter(SigningKeyType keyType) const
settings.setValue(counterKey, counterValue);
}
-QString QLowEnergyControllerPrivate::signingKeySettingsGroup(SigningKeyType keyType) const
+QString QLowEnergyControllerPrivateBluez::signingKeySettingsGroup(SigningKeyType keyType) const
{
return QLatin1String(keyType == LocalSigningKey ? "LocalSignatureKey" : "RemoteSignatureKey");
}
-QString QLowEnergyControllerPrivate::keySettingsFilePath() const
+QString QLowEnergyControllerPrivateBluez::keySettingsFilePath() const
{
return QString::fromLatin1("/var/lib/bluetooth/%1/%2/info")
.arg(localAdapter.toString(), remoteDevice.toString());
@@ -3213,7 +3304,7 @@ static QByteArray uuidToByteArray(const QBluetoothUuid &uuid)
return ba;
}
-void QLowEnergyControllerPrivate::addToGenericAttributeList(const QLowEnergyServiceData &service,
+void QLowEnergyControllerPrivateBluez::addToGenericAttributeList(const QLowEnergyServiceData &service,
QLowEnergyHandle startHandle)
{
// Construct generic attribute data for the service with handles as keys.
@@ -3323,7 +3414,7 @@ void QLowEnergyControllerPrivate::addToGenericAttributeList(const QLowEnergyServ
localAttributes[serviceAttribute.handle] = serviceAttribute;
}
-void QLowEnergyControllerPrivate::ensureUniformAttributes(QVector<Attribute> &attributes,
+void QLowEnergyControllerPrivateBluez::ensureUniformAttributes(QVector<Attribute> &attributes,
const std::function<int (const Attribute &)> &getSize)
{
if (attributes.isEmpty())
@@ -3336,19 +3427,19 @@ void QLowEnergyControllerPrivate::ensureUniformAttributes(QVector<Attribute> &at
}
-void QLowEnergyControllerPrivate::ensureUniformUuidSizes(QVector<Attribute> &attributes)
+void QLowEnergyControllerPrivateBluez::ensureUniformUuidSizes(QVector<Attribute> &attributes)
{
ensureUniformAttributes(attributes,
[](const Attribute &attr) { return getUuidSize(attr.type); });
}
-void QLowEnergyControllerPrivate::ensureUniformValueSizes(QVector<Attribute> &attributes)
+void QLowEnergyControllerPrivateBluez::ensureUniformValueSizes(QVector<Attribute> &attributes)
{
ensureUniformAttributes(attributes,
[](const Attribute &attr) { return attr.value.count(); });
}
-QVector<QLowEnergyControllerPrivate::Attribute> QLowEnergyControllerPrivate::getAttributes(QLowEnergyHandle startHandle,
+QVector<QLowEnergyControllerPrivateBluez::Attribute> QLowEnergyControllerPrivateBluez::getAttributes(QLowEnergyHandle startHandle,
QLowEnergyHandle endHandle, const AttributePredicate &attributePredicate)
{
QVector<Attribute> results;
@@ -3367,7 +3458,7 @@ QVector<QLowEnergyControllerPrivate::Attribute> QLowEnergyControllerPrivate::get
return results;
}
-int QLowEnergyControllerPrivate::checkPermissions(const Attribute &attr,
+int QLowEnergyControllerPrivateBluez::checkPermissions(const Attribute &attr,
QLowEnergyCharacteristic::PropertyType type)
{
const bool isReadAccess = type == QLowEnergyCharacteristic::Read;
@@ -3401,12 +3492,12 @@ int QLowEnergyControllerPrivate::checkPermissions(const Attribute &attr,
return 0;
}
-int QLowEnergyControllerPrivate::checkReadPermissions(const Attribute &attr)
+int QLowEnergyControllerPrivateBluez::checkReadPermissions(const Attribute &attr)
{
return checkPermissions(attr, QLowEnergyCharacteristic::Read);
}
-int QLowEnergyControllerPrivate::checkReadPermissions(QVector<Attribute> &attributes)
+int QLowEnergyControllerPrivateBluez::checkReadPermissions(QVector<Attribute> &attributes)
{
if (attributes.isEmpty())
return 0;
@@ -3426,7 +3517,7 @@ int QLowEnergyControllerPrivate::checkReadPermissions(QVector<Attribute> &attrib
return 0;
}
-bool QLowEnergyControllerPrivate::verifyMac(const QByteArray &message, const quint128 &csrk,
+bool QLowEnergyControllerPrivateBluez::verifyMac(const QByteArray &message, const quint128 &csrk,
quint32 signCounter, quint64 expectedMac)
{
if (!cmacCalculator)