diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2016-11-08 16:47:51 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2016-11-09 14:15:40 +0000 |
commit | 8c2f88f2294ea871e374ef1a13ea4793854bd214 (patch) | |
tree | 5bea901e0caea907838c20812b955387b8531803 /src | |
parent | 85a626e83fa90bfae09be28e32c957f6bab2d861 (diff) |
Emit descriptorWritten for notification/indication enabled/disabled
From CoreBluetooth's point of view - this is just a callback, not a
descriptor write request (they even consider all descriptors immutable
in peripheral), but for Qt it should be a descriptor write operation,
and we must emit a signal.
Oh, and set endHandle correctly on a LE service object!
Change-Id: I71922507a6ece987ad8b5c317ef618301ae240c2
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/bluetooth/osx/osxbtnotifier_p.h | 1 | ||||
-rw-r--r-- | src/bluetooth/osx/osxbtperipheralmanager.mm | 14 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_osx.mm | 47 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_osx_p.h | 1 |
4 files changed, 61 insertions, 2 deletions
diff --git a/src/bluetooth/osx/osxbtnotifier_p.h b/src/bluetooth/osx/osxbtnotifier_p.h index 0ffd7f51..47ee6ba1 100644 --- a/src/bluetooth/osx/osxbtnotifier_p.h +++ b/src/bluetooth/osx/osxbtnotifier_p.h @@ -88,6 +88,7 @@ Q_SIGNALS: void characteristicUpdated(QLowEnergyHandle charHandle, const QByteArray &value); void descriptorRead(QLowEnergyHandle descHandle, const QByteArray &value); void descriptorWritten(QLowEnergyHandle descHandle, const QByteArray &value); + void notificationEnabled(QLowEnergyHandle charHandle, bool enabled); void LEnotSupported(); void CBManagerError(QBluetoothDeviceDiscoveryAgent::Error error); diff --git a/src/bluetooth/osx/osxbtperipheralmanager.mm b/src/bluetooth/osx/osxbtperipheralmanager.mm index a44fb95c..1a461be9 100644 --- a/src/bluetooth/osx/osxbtperipheralmanager.mm +++ b/src/bluetooth/osx/osxbtperipheralmanager.mm @@ -236,6 +236,8 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) services.push_back(newCBService); serviceIndex[data.uuid()] = newCBService; + newQtService->endHandle = lastHandle; + return newQtService; } @@ -357,6 +359,8 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) return; } + emit notifier->characteristicWritten(charHandle, value); + const auto nsData = mutable_data_from_bytearray(value); charValues[charHandle] = nsData; // We copy data here: sending update requests is async (see sendUpdateRequests), @@ -480,6 +484,9 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) return; [self addConnectedCentral:central]; + + if (const auto handle = charMap.key(characteristic)) + emit notifier->notificationEnabled(handle, true); } - (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central @@ -491,6 +498,11 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) return; [self removeConnectedCentral:central]; + + if (![connectedCentrals count]) { + if (const auto handle = charMap.key(characteristic)) + emit notifier->notificationEnabled(handle, false); + } } - (void)peripheralManager:(CBPeripheralManager *)peripheral @@ -757,7 +769,7 @@ bool qt_validate_value_range(const QLowEnergyCharacteristicData &data) valueRanges[declHandle] = ValueRange(ch.minimumValueLength(), ch.maximumValueLength()); // QT part: QLowEnergyServicePrivate::CharData charData; - charData.valueHandle = ++lastHandle; + charData.valueHandle = declHandle; charData.uuid = ch.uuid(); charData.properties = ch.properties(); charData.value = ch.value(); diff --git a/src/bluetooth/qlowenergycontroller_osx.mm b/src/bluetooth/qlowenergycontroller_osx.mm index 6e85e630..f2b7b0bd 100644 --- a/src/bluetooth/qlowenergycontroller_osx.mm +++ b/src/bluetooth/qlowenergycontroller_osx.mm @@ -444,6 +444,49 @@ void QLowEnergyControllerPrivateOSX::_q_descriptorWritten(QLowEnergyHandle dHand emit service->descriptorWritten(qtDescriptor, value); } +void QLowEnergyControllerPrivateOSX::_q_notificationEnabled(QLowEnergyHandle charHandle, + bool enabled) +{ + // CoreBluetooth in peripheral role does not allow mutable descriptors, + // in central we can only call setNotification:enabled/disabled. + // But from Qt API's point of view, a central has to write into + // client characteristic configuration descriptor. So here we emulate + // such a write (we cannot say if it's a notification or indication and + // report as both). + + Q_ASSERT_X(role == QLowEnergyController::PeripheralRole, Q_FUNC_INFO, + "controller has an invalid role, 'peripheral' expected"); + Q_ASSERT_X(charHandle, Q_FUNC_INFO, "invalid characteristic handle (0)"); + + const QLowEnergyCharacteristic qtChar(characteristicForHandle(charHandle)); + if (!qtChar.isValid()) { + qCWarning(QT_BT_OSX) << "unknown characteristic" << charHandle; + return; + } + + const QLowEnergyDescriptor qtDescriptor = + qtChar.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration); + if (!qtDescriptor.isValid()) { + qCWarning(QT_BT_OSX) << "characteristic" << charHandle + << "does not have a client characteristic " + "descriptor"; + return; + } + + ServicePrivate service(serviceForHandle(charHandle)); + if (service.data()) { + // It's a 16-bit value, the least significant bit is for notifications, + // the next one - for indications (thus 1 means notifications enabled, + // 2 - indications enabled). + // 3 is the maximum value and it means both enabled. + QByteArray value(2, 0); + if (enabled) + value[0] = 3; + updateValueOfDescriptor(charHandle, qtDescriptor.handle(), value, false); + emit service->descriptorWritten(qtDescriptor, value); + } +} + void QLowEnergyControllerPrivateOSX::_q_LEnotSupported() { // Report as an error. But this should not be possible @@ -713,7 +756,7 @@ void QLowEnergyControllerPrivateOSX::writeCharacteristic(QSharedPointer<QLowEner [manager write:newValueCopy charHandle:charHandle]; }); #else - qCWarning(QT_BT_OSX) << "peripheral role is not supported on your platform"; + qCWarning(QT_BT_OSX) << "peripheral role is not supported on your platform"; #endif } } @@ -950,6 +993,8 @@ bool QLowEnergyControllerPrivateOSX::connectSlots(OSXBluetooth::LECBManagerNotif this, &QLowEnergyControllerPrivateOSX::_q_descriptorRead); ok = ok && connect(notifier, &LECBManagerNotifier::descriptorWritten, this, &QLowEnergyControllerPrivateOSX::_q_descriptorWritten); + ok = ok && connect(notifier, &LECBManagerNotifier::notificationEnabled, + this, &QLowEnergyControllerPrivateOSX::_q_notificationEnabled); ok = ok && connect(notifier, &LECBManagerNotifier::LEnotSupported, this, &QLowEnergyControllerPrivateOSX::_q_LEnotSupported); ok = ok && connect(notifier, SIGNAL(CBManagerError(QLowEnergyController::Error)), diff --git a/src/bluetooth/qlowenergycontroller_osx_p.h b/src/bluetooth/qlowenergycontroller_osx_p.h index b7399ed7..5cceb9e6 100644 --- a/src/bluetooth/qlowenergycontroller_osx_p.h +++ b/src/bluetooth/qlowenergycontroller_osx_p.h @@ -104,6 +104,7 @@ private Q_SLOTS: void _q_characteristicUpdated(QLowEnergyHandle charHandle, const QByteArray &value); void _q_descriptorRead(QLowEnergyHandle descHandle, const QByteArray &value); void _q_descriptorWritten(QLowEnergyHandle charHandle, const QByteArray &value); + void _q_notificationEnabled(QLowEnergyHandle charHandle, bool enabled); void _q_LEnotSupported(); void _q_CBManagerError(QLowEnergyController::Error error); |