18#include <QtCore/qloggingcategory.h>
19#include <QtCore/qsharedpointer.h>
20#include <QtCore/qbytearray.h>
21#include <QtCore/qglobal.h>
22#include <QtCore/qstring.h>
23#include <QtCore/qlist.h>
24#include <QtCore/qcoreapplication.h>
25#include <QtCore/qpermissions.h>
39 CBUUID *
const cbUuid = cbService.UUID;
41 qCDebug(QT_BT_DARWIN) <<
"invalid service, UUID is nil";
50 newService->
uuid = qtUuid;
90 qRegisterMetaType<QLowEnergyHandle>(
"QLowEnergyHandle");
91 qRegisterMetaType<QSharedPointer<QLowEnergyServicePrivate>>();
99 dispatch_sync(leQueue, ^{
104 dispatch_sync(leQueue, ^{
113 return centralManager || peripheralManager;
127 if (peripheralManager || centralManager)
132 "Use of Bluetooth LE must be explicitly requested by the application.");
137 std::unique_ptr<LECBManagerNotifier>
notifier = std::make_unique<LECBManagerNotifier>();
150 qCWarning(QT_BT_DARWIN) <<
"failed to connect to notifier's signal(s)";
183 dispatch_async(leQueue, ^{
198 const auto oldState =
state;
205 dispatch_async(leQueue, ^{
217 qCCritical(QT_BT_DARWIN) <<
"qt LE queue is nil, "
218 "can not dispatch 'disconnect'";
237 dispatch_async(leQueue, ^{
247 qCWarning(QT_BT_DARWIN) <<
"can not discover service details in the current state, "
248 "QLowEnergyController::DiscoveredState is expected";
253 qCWarning(QT_BT_DARWIN) <<
"unknown service: " << serviceUuid;
260 ServicePrivate qtService(
serviceList.value(serviceUuid));
265 dispatch_async(leQueue, ^{
274 qCWarning(QT_BT_DARWIN) <<
"Connection update not implemented on your platform";
297 dispatch_sync(leQueue, ^{
314 dispatch_async(leQueue, ^{
323 qCWarning(QT_BT_DARWIN) <<
"invalid peripheral";
327 for (
auto includedService : service.includedServices())
332 if (
const auto servicePrivate = [
manager addService:service]) {
333 servicePrivate->setController(
this);
342void QLowEnergyControllerPrivateDarwin::_q_connected()
348void QLowEnergyControllerPrivateDarwin::_q_disconnected()
357void QLowEnergyControllerPrivateDarwin::_q_mtuChanged(
int newValue)
362void QLowEnergyControllerPrivateDarwin::_q_serviceDiscoveryFinished()
384 if (!newService.data())
388 qCDebug(QT_BT_DARWIN) <<
"discovered service with a duplicated UUID"
393 discoveredCBServices.
insert(newService->uuid, cbService);
402 CBService *
const s = [toVisit objectAtIndex:
i];
403 if (![visited containsObject:
s]) {
404 [visited addObject:
s];
405 if (
s.includedServices &&
s.includedServices.count)
406 [toVisitNext addObjectsFromArray:
s.includedServices];
417 if (![toVisitNext
count])
421 CBService *
const s = [toVisitNext objectAtIndex:
i];
424 if (discoveredCBServices.
value(uuid) ==
s) {
432 discoveredCBServices.
insert(newService->uuid,
s);
436 toVisit.
swap(toVisitNext);
437 toVisitNext.reset([[NSMutableArray alloc]
init], RetainPolicy::noInitialRetain);
440 qCDebug(QT_BT_DARWIN) <<
"no services found";
462 qCDebug(QT_BT_DARWIN) <<
"unknown service uuid:"
469 qtService->startHandle =
service->startHandle;
470 qtService->endHandle =
service->endHandle;
471 qtService->characteristicList =
service->characteristicList;
476void QLowEnergyControllerPrivateDarwin::_q_servicesWereModified()
480 qCWarning(QT_BT_DARWIN) <<
"services were modified while controller is not in Discovered/Discovering state";
491void QLowEnergyControllerPrivateDarwin::_q_characteristicRead(
QLowEnergyHandle charHandle,
501 if (!characteristic.isValid()) {
502 qCWarning(QT_BT_DARWIN) <<
"unknown characteristic";
507 updateValueOfCharacteristic(charHandle,
value,
false);
512void QLowEnergyControllerPrivateDarwin::_q_characteristicWritten(
QLowEnergyHandle charHandle,
519 qCWarning(QT_BT_DARWIN) <<
"can not find service for characteristic handle"
525 if (!characteristic.isValid()) {
526 qCWarning(QT_BT_DARWIN) <<
"unknown characteristic";
531 updateValueOfCharacteristic(charHandle,
value,
false);
536void QLowEnergyControllerPrivateDarwin::_q_characteristicUpdated(
QLowEnergyHandle charHandle,
554 if (!characteristic.isValid()) {
555 qCWarning(QT_BT_DARWIN) <<
"unknown characteristic";
560 updateValueOfCharacteristic(charHandle,
value,
false);
565void QLowEnergyControllerPrivateDarwin::_q_descriptorRead(
QLowEnergyHandle dHandle,
571 if (!qtDescriptor.isValid()) {
572 qCWarning(QT_BT_DARWIN) <<
"unknown descriptor" << dHandle;
577 updateValueOfDescriptor(qtDescriptor.characteristicHandle(), dHandle,
value,
false);
581void QLowEnergyControllerPrivateDarwin::_q_descriptorWritten(
QLowEnergyHandle dHandle,
587 if (!qtDescriptor.isValid()) {
588 qCWarning(QT_BT_DARWIN) <<
"unknown descriptor" << dHandle;
594 updateValueOfDescriptor(qtDescriptor.characteristicHandle(), dHandle,
value,
false);
598void QLowEnergyControllerPrivateDarwin::_q_notificationEnabled(
QLowEnergyHandle charHandle,
609 "controller has an invalid role, 'peripheral' expected");
613 if (!qtChar.isValid()) {
614 qCWarning(QT_BT_DARWIN) <<
"unknown characteristic" << charHandle;
621 qCWarning(QT_BT_DARWIN) <<
"characteristic" << charHandle
622 <<
"does not have a client characteristic "
636 updateValueOfDescriptor(charHandle, qtDescriptor.handle(),
value,
false);
641void QLowEnergyControllerPrivateDarwin::_q_LEnotSupported()
651 qCDebug(QT_BT_DARWIN) <<
"QLowEnergyController error:" << errorCode <<
"in state:" <<
state;
669void QLowEnergyControllerPrivateDarwin::_q_CBManagerError(
const QBluetoothUuid &serviceUuid,
680 qCDebug(QT_BT_DARWIN) <<
"error reported for unknown service"
685void QLowEnergyControllerPrivateDarwin::_q_CBManagerError(
const QBluetoothUuid &serviceUuid,
689 qCDebug(QT_BT_DARWIN) <<
"unknown service uuid:"
705 qCWarning(QT_BT_DARWIN) <<
"invalid role (peripheral)";
710 if (newValue.
size() > 2) {
715 qCWarning(QT_BT_DARWIN) <<
"client characteristic configuration descriptor"
716 "is 2 bytes, but value size is: " << newValue.
size();
722 qCWarning(QT_BT_DARWIN) <<
"no service with uuid:" <<
service->uuid <<
"found";
726 if (!
service->characteristicList.contains(charHandle)) {
727 qCDebug(QT_BT_DARWIN) <<
"no characteristic with handle:"
728 << charHandle <<
"found";
738 dispatch_async(leQueue, ^{
739 [
manager setNotifyValue:newValueCopy
740 forCharacteristic:charHandle
741 onService:serviceUuid];
751 qCWarning(QT_BT_DARWIN) <<
"invalid role (peripheral)";
756 qCWarning(QT_BT_DARWIN) <<
"no service with uuid:"
757 << service->uuid <<
"found";
761 if (!service->characteristicList.contains(charHandle)) {
762 qCDebug(QT_BT_DARWIN) <<
"no characteristic with handle:"
763 << charHandle <<
"found";
773 dispatch_async(leQueue, ^{
788 qCWarning(QT_BT_DARWIN) <<
"no service with uuid:"
789 << service->uuid <<
" found";
793 if (!service->characteristicList.contains(charHandle)) {
794 qCDebug(QT_BT_DARWIN) <<
"no characteristic with handle:"
795 << charHandle <<
" found";
806 dispatch_async(leQueue, ^{
808 charHandle:charHandle
809 onService:serviceUuid
814 dispatch_async(leQueue, ^{
825 if (!service.isNull()) {
827 if (charIt != service->characteristicList.end()) {
850 qCWarning(QT_BT_DARWIN) <<
"invalid role (peripheral)";
855 qCWarning(QT_BT_DARWIN) <<
"no service with uuid:"
856 << service->uuid <<
"found";
862 qCWarning(QT_BT_DARWIN) <<
"no LE queue found";
868 dispatch_async(leQueue, ^{
870 onService:serviceUuid];
884 qCWarning(QT_BT_DARWIN) <<
"invalid role (peripheral)";
892 qCWarning(QT_BT_DARWIN) <<
"no service with uuid:"
893 << service->uuid <<
" found";
903 dispatch_async(leQueue, ^{
905 descHandle:descriptorHandle
906 onService:serviceUuid];
914 if (!service.isNull()) {
916 if (charIt != service->characteristicList.end()) {
943 this, &QLowEnergyControllerPrivateDarwin::_q_connected);
945 this, &QLowEnergyControllerPrivateDarwin::_q_disconnected);
947 this, &QLowEnergyControllerPrivateDarwin::_q_serviceDiscoveryFinished);
949 this, &QLowEnergyControllerPrivateDarwin::_q_servicesWereModified);
951 this, &QLowEnergyControllerPrivateDarwin::_q_serviceDetailsDiscoveryFinished);
953 this, &QLowEnergyControllerPrivateDarwin::_q_characteristicRead);
955 this, &QLowEnergyControllerPrivateDarwin::_q_characteristicWritten);
957 this, &QLowEnergyControllerPrivateDarwin::_q_characteristicUpdated);
959 this, &QLowEnergyControllerPrivateDarwin::_q_descriptorRead);
961 this, &QLowEnergyControllerPrivateDarwin::_q_descriptorWritten);
963 this, &QLowEnergyControllerPrivateDarwin::_q_notificationEnabled);
965 this, &QLowEnergyControllerPrivateDarwin::_q_LEnotSupported);
973 &QLowEnergyControllerPrivateDarwin::_q_mtuChanged);
994 [
manager setParameters:
params data:advertisingData scanResponse:scanResponseData];
998 dispatch_async(leQueue, ^{
1009 qCDebug(QT_BT_DARWIN) <<
"cannot stop advertising, called in state" <<
state;
1016 dispatch_sync(leQueue, ^{
CBPeripheral * peripheral
DarwinBluetooth::LECBManagerNotifier * notifier
std::vector< ObjCStrongReference< CBMutableService > > services
#define QT_BT_MAC_AUTORELEASEPOOL
void swap(StrongReference &other) noexcept
Access Bluetooth peripherals.
@ ClientCharacteristicConfiguration
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
void append(parameter_type t)
The QLowEnergyAdvertisingData class represents the data to be broadcast during Bluetooth Low Energy a...
The QLowEnergyAdvertisingParameters class represents the parameters used for Bluetooth Low Energy adv...
The QLowEnergyConnectionParameters class is used when requesting or reporting an update of the parame...
void discoverServices() override
void writeDescriptor(const QSharedPointer< QLowEnergyServicePrivate > service, const QLowEnergyHandle charHandle, const QLowEnergyHandle descriptorHandle, const QByteArray &newValue) override
void readDescriptor(const QSharedPointer< QLowEnergyServicePrivate > service, const QLowEnergyHandle charHandle, const QLowEnergyHandle descriptorHandle) override
void startAdvertising(const QLowEnergyAdvertisingParameters ¶ms, const QLowEnergyAdvertisingData &advertisingData, const QLowEnergyAdvertisingData &scanResponseData) override
void connectToDevice() override
void disconnectFromDevice() override
~QLowEnergyControllerPrivateDarwin()
void writeCharacteristic(const QSharedPointer< QLowEnergyServicePrivate > service, const QLowEnergyHandle charHandle, const QByteArray &newValue, QLowEnergyService::WriteMode mode) override
void discoverServiceDetails(const QBluetoothUuid &serviceUuid, QLowEnergyService::DiscoveryMode mode) override
QLowEnergyControllerPrivateDarwin()
friend class QLowEnergyService
QLowEnergyService * addServiceHelper(const QLowEnergyServiceData &service) override
void addToGenericAttributeList(const QLowEnergyServiceData &service, QLowEnergyHandle startHandle) override
void stopAdvertising() override
void requestConnectionUpdate(const QLowEnergyConnectionParameters ¶ms) override
void readCharacteristic(const QSharedPointer< QLowEnergyServicePrivate > service, const QLowEnergyHandle charHandle) override
QLowEnergyCharacteristic characteristicForHandle(QLowEnergyHandle handle)
Returns a valid characteristic if the given handle is the handle of the characteristic itself or one ...
QSharedPointer< QLowEnergyServicePrivate > serviceForHandle(QLowEnergyHandle handle)
void invalidateServices()
QLowEnergyDescriptor descriptorForHandle(QLowEnergyHandle handle)
Returns a valid descriptor if handle belongs to a descriptor; otherwise an invalid one.
ServiceDataMap localServices
ServiceDataMap serviceList
void setError(QLowEnergyController::Error newError)
QLowEnergyController::Role role
QBluetoothUuid deviceUuid
QLowEnergyController * q_ptr
QLowEnergyController::ControllerState state
void setState(QLowEnergyController::ControllerState newState)
ControllerState
Indicates the state of the controller object.
void connected()
This signal is emitted when the controller successfully connects to the remote Low Energy device (if ...
void rssiRead(qint16 rssi)
This signal is emitted after successful read of RSSI (received signal strength indicator) for a conne...
Error
Indicates all possible error conditions found during the controller's existence.
@ UnknownRemoteDeviceError
@ MissingPermissionsError
void disconnected()
This signal is emitted when the controller disconnects from the remote Low Energy device or vice vers...
void discoverServices()
Initiates the service discovery process.
void discoveryFinished()
This signal is emitted when the running service discovery finishes.
void mtuChanged(int mtu)
This signal is emitted as a result of a successful MTU change.
bool isValid() const
Returns true if the QLowEnergyDescriptor object is valid, otherwise returns false.
The QLowEnergyServiceData class is used to set up GATT service data. \inmodule QtBluetooth.
void setController(QLowEnergyControllerPrivate *control)
QLowEnergyService::ServiceTypes type
DiscoveryMode
This enum lists service discovery modes.
ServiceError
This enum describes all possible error conditions during the service's existence.
@ RemoteServiceDiscovered
@ RemoteServiceDiscovering
WriteMode
This enum describes the mode to be used when writing a characteristic value.
iterator insert(const Key &key, const T &value)
T value(const Key &key, const T &defaultValue=T()) const
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
bool isNull() const noexcept
Returns true if this is the null UUID {00000000-0000-0000-0000-000000000000}; otherwise returns false...
QSet< QString >::iterator it
QBluetoothUuid qt_uuid(NSUUID *nsUuid)
dispatch_queue_t qt_LE_queue()
Combined button and popup list for selecting options.
ServicePrivate qt_createLEService(QLowEnergyControllerPrivateDarwin *controller, CBService *cbService, bool included)
QSharedPointer< QLowEnergyServicePrivate > ServicePrivate
UUIDList qt_servicesUuids(NSArray *services)
Q_CORE_EXPORT QtJniTypes::Service service()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qCCritical(category,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
void registerQLowEnergyControllerMetaType()
#define Q_ARG(Type, data)
GLenum GLenum GLsizei count
GLenum GLenum GLsizei const GLuint GLboolean enabled
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
#define Q_ASSERT_X(cond, x, msg)
gzip write("uncompressed data")
QNetworkAccessManager manager
QHash< QLowEnergyHandle, DescData > descriptorList