summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@digia.com>2014-07-02 10:52:17 +0200
committerAlex Blasche <alexander.blasche@digia.com>2014-07-02 16:17:24 +0200
commit3e26211bf0d92fb46a5a5f1830766be2ea832d7b (patch)
tree44e6ea87d749024ee92db421af0f34c64023643d
parente1fdef843fd8a6d8495bf96810e0ffc32d9ca0f6 (diff)
Support writing of characteristic
Right now we assume that the target characteristic is writable with confirmation response. WriteNoResponse support is still missing. Change-Id: Ie584db43f80a0bf90ec67499772488f509fc3d29 Reviewed-by: Fabian Bumberger <fbumberger@rim.com>
-rw-r--r--src/bluetooth/qlowenergycharacteristic.cpp19
-rw-r--r--src/bluetooth/qlowenergycharacteristic.h4
-rw-r--r--src/bluetooth/qlowenergycontrollernew_bluez.cpp65
-rw-r--r--src/bluetooth/qlowenergycontrollernew_p.cpp8
-rw-r--r--src/bluetooth/qlowenergycontrollernew_p.h6
-rw-r--r--src/bluetooth/qlowenergyservice.cpp54
-rw-r--r--src/bluetooth/qlowenergyservice.h7
-rw-r--r--src/bluetooth/qlowenergyserviceprivate_p.h2
-rw-r--r--tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp150
9 files changed, 296 insertions, 19 deletions
diff --git a/src/bluetooth/qlowenergycharacteristic.cpp b/src/bluetooth/qlowenergycharacteristic.cpp
index aa1795c3..d1c1a14c 100644
--- a/src/bluetooth/qlowenergycharacteristic.cpp
+++ b/src/bluetooth/qlowenergycharacteristic.cpp
@@ -162,6 +162,8 @@ QLowEnergyCharacteristic::PropertyTypes QLowEnergyCharacteristic::properties() c
/*!
Returns value of the gatt characteristic.
+
+ The returned QByteArray contains the hex representation of the value.
*/
QByteArray QLowEnergyCharacteristic::value() const
{
@@ -186,17 +188,6 @@ QLowEnergyHandle QLowEnergyCharacteristic::handle() const
}
/*!
- Sets the value \a value of the characteristic. This only caches the value. To write
- a value directly to the device QLowEnergyController class must be used.
-
- \sa QLowEnergyController::writeCharacteristic()
-*/
-void QLowEnergyCharacteristic::setValue(const QByteArray &value)
-{
- //d_ptr->value = value;
-}
-
-/*!
Makes a copy of \a other and assigns it to this QLowEnergyCharacteristic object.
The two copies continue to share the same service and registration details.
*/
@@ -276,7 +267,13 @@ bool QLowEnergyCharacteristic::isValid() const
return true;
}
+QLowEnergyHandle QLowEnergyCharacteristic::attributeHandle() const
+{
+ if (d_ptr.isNull() || !data)
+ return 0;
+ return data->handle;
+}
/*!
Returns the list of characteristic descriptors.
diff --git a/src/bluetooth/qlowenergycharacteristic.h b/src/bluetooth/qlowenergycharacteristic.h
index 9a14d57c..65f59c7a 100644
--- a/src/bluetooth/qlowenergycharacteristic.h
+++ b/src/bluetooth/qlowenergycharacteristic.h
@@ -82,7 +82,6 @@ public:
QBluetoothUuid uuid() const;
- void setValue(const QByteArray &value); //TODO shift to QLowEnergyControllerNew
QByteArray value() const;
QLowEnergyCharacteristic::PropertyTypes properties() const;
@@ -93,9 +92,12 @@ public:
bool isValid() const;
protected:
+ QLowEnergyHandle attributeHandle() const;
+
QSharedPointer<QLowEnergyServicePrivate> d_ptr;
friend class QLowEnergyService;
+ friend class QLowEnergyControllerNewPrivate;
QLowEnergyCharacteristicPrivate *data;
QLowEnergyCharacteristic(QSharedPointer<QLowEnergyServicePrivate> p,
QLowEnergyHandle handle);
diff --git a/src/bluetooth/qlowenergycontrollernew_bluez.cpp b/src/bluetooth/qlowenergycontrollernew_bluez.cpp
index 400d2dbc..8aca2b54 100644
--- a/src/bluetooth/qlowenergycontrollernew_bluez.cpp
+++ b/src/bluetooth/qlowenergycontrollernew_bluez.cpp
@@ -64,12 +64,15 @@
#define ATT_OP_READ_RESPONSE 0xB
#define ATT_OP_READ_BY_GROUP_REQUEST 0x10 //discover services
#define ATT_OP_READ_BY_GROUP_RESPONSE 0x11
+#define ATT_OP_WRITE_REQUEST 0x12 //write characteristic
+#define ATT_OP_WRITE_RESPONSE 0x13
//GATT command sizes in bytes
#define FIND_INFO_REQUEST_SIZE 5
#define GRP_TYPE_REQ_SIZE 7
#define READ_BY_TYPE_REQ_SIZE 7
#define READ_REQUEST_SIZE 3
+#define WRITE_REQUEST_SIZE 3
// GATT error codes
#define ATT_ERROR_INVALID_HANDLE 0x01
@@ -547,6 +550,28 @@ void QLowEnergyControllerNewPrivate::processReply(
}
}
break;
+ case ATT_OP_WRITE_REQUEST: //error case
+ case ATT_OP_WRITE_RESPONSE:
+ {
+ //Write command response
+ Q_ASSERT(request.command == ATT_OP_WRITE_REQUEST);
+
+ QLowEnergyHandle charHandle = request.reference.toUInt();
+ QSharedPointer<QLowEnergyServicePrivate> service = serviceForHandle(charHandle);
+ if (service.isNull() || !service->characteristicList.contains(charHandle))
+ break;
+
+ if (isErrorResponse) {
+ service->setError(QLowEnergyService::CharacteristicWriteError);
+ break;
+ }
+
+ const QByteArray newValue = request.reference2.toByteArray();
+ service->characteristicList[charHandle].value = newValue;
+ QLowEnergyCharacteristic ch(service, charHandle);
+ emit service->characteristicChanged(ch, newValue);
+ }
+ break;
default:
qCDebug(QT_BT_BLUEZ) << "Unknown packet: " << response.toHex();
break;
@@ -762,7 +787,7 @@ void QLowEnergyControllerNewPrivate::discoverNextDescriptor(
bt_put_unaligned(htobs(charEndHandle), (quint16 *) &packet[3]);
QByteArray data(FIND_INFO_REQUEST_SIZE, Qt::Uninitialized);
- memcpy(data.data(), packet, FIND_INFO_REQUEST_SIZE);
+ memcpy(data.data(), packet, FIND_INFO_REQUEST_SIZE);
Request request;
request.payload = data;
@@ -773,4 +798,42 @@ void QLowEnergyControllerNewPrivate::discoverNextDescriptor(
sendNextPendingRequest();
}
+
+void QLowEnergyControllerNewPrivate::writeCharacteristic(
+ const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle,
+ const QByteArray &newValue)
+{
+ Q_ASSERT(!service.isNull());
+
+ if (!service->characteristicList.contains(charHandle))
+ return;
+
+ const QLowEnergyHandle valueHandle = service->characteristicList[charHandle].valueHandle;
+ const QByteArray rawData = QByteArray::fromHex(newValue);
+ // sizeof(command) + sizeof(handle) + sizeof(newValue)
+ const int size = 1 + 2 + rawData.size();
+
+ quint8 packet[WRITE_REQUEST_SIZE];
+ packet[0] = ATT_OP_WRITE_REQUEST;
+ bt_put_unaligned(htobs(valueHandle), (quint16 *) &packet[1]);
+
+
+ QByteArray data(size, Qt::Uninitialized);
+ memcpy(data.data(), packet, WRITE_REQUEST_SIZE);
+ memcpy(&(data.data()[WRITE_REQUEST_SIZE]), rawData.constData(), rawData.size());
+
+ qCDebug(QT_BT_BLUEZ) << "Writing characteristic" << hex << charHandle
+ << "(size:" << size << ")";
+
+ Request request;
+ request.payload = data;
+ request.command = ATT_OP_WRITE_REQUEST;
+ request.reference = charHandle;
+ request.reference2 = newValue;
+ openRequests.enqueue(request);
+
+ sendNextPendingRequest();
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergycontrollernew_p.cpp b/src/bluetooth/qlowenergycontrollernew_p.cpp
index 01a36faf..f2841d46 100644
--- a/src/bluetooth/qlowenergycontrollernew_p.cpp
+++ b/src/bluetooth/qlowenergycontrollernew_p.cpp
@@ -74,4 +74,12 @@ void QLowEnergyControllerNewPrivate::discoverServiceDetails(const QBluetoothUuid
}
+void QLowEnergyControllerNewPrivate::writeCharacteristic(
+ const QLowEnergyCharacteristic & /*characteristic*/,
+ const QLowEnergyHandle /*charHandle*/,
+ const QByteArray &/*newValue*/)
+{
+
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergycontrollernew_p.h b/src/bluetooth/qlowenergycontrollernew_p.h
index bac00e93..1d3ec095 100644
--- a/src/bluetooth/qlowenergycontrollernew_p.h
+++ b/src/bluetooth/qlowenergycontrollernew_p.h
@@ -77,7 +77,7 @@ public:
void discoverServiceDetails(const QBluetoothUuid &service);
- // misc lookup helpers
+ // misc helpers
QSharedPointer<QLowEnergyServicePrivate> serviceForHandle(
QLowEnergyHandle handle);
void updateValueOfCharacteristic(QLowEnergyHandle charHandle,
@@ -85,6 +85,10 @@ public:
void updateValueOfDescriptor(QLowEnergyHandle charHandle,
QLowEnergyHandle descriptorHandle,
const QByteArray &value);
+ void writeCharacteristic(const QSharedPointer<QLowEnergyServicePrivate> service,
+ const QLowEnergyHandle charHandle,
+ const QByteArray &newValue);
+
QBluetoothAddress remoteDevice;
QBluetoothAddress localAdapter;
diff --git a/src/bluetooth/qlowenergyservice.cpp b/src/bluetooth/qlowenergyservice.cpp
index d8f80397..6469474f 100644
--- a/src/bluetooth/qlowenergyservice.cpp
+++ b/src/bluetooth/qlowenergyservice.cpp
@@ -70,6 +70,8 @@ QLowEnergyService::QLowEnergyService(QSharedPointer<QLowEnergyServicePrivate> p,
this, SIGNAL(error(QLowEnergyService::ServiceError)));
connect(p.data(), SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
this, SIGNAL(stateChanged(QLowEnergyService::ServiceState)));
+ connect(p.data(), SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)),
+ this, SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)));
}
@@ -153,5 +155,57 @@ QLowEnergyService::ServiceError QLowEnergyService::error() const
return d_ptr->lastError;
}
+bool QLowEnergyService::contains(const QLowEnergyCharacteristic &characteristic)
+{
+ if (characteristic.d_ptr.isNull() || !characteristic.data)
+ return false;
+
+ if (d_ptr == characteristic.d_ptr
+ && d_ptr->characteristicList.contains(characteristic.attributeHandle())) {
+ return true;
+ }
+
+ return false;
+}
+
+/*!
+ Writes \a newValue as value for the \a characteristic. If the operation is successful
+ the \l characteristicChanged() signal will be emitted. \a newValue must contain the
+ hexadecimal representation of new value.
+
+ A characteristic can only be written if this service is in the \l ServiceDiscovered state
+ and \a characteristic is writable.
+ */
+void QLowEnergyService::writeCharacteristic(
+ const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue)
+{
+ //TODO check behavior when writing to WriteNoResponse characteristic
+ //TODO check behavior when writing to WriteSigned characteristic
+ //TODO add support for write long characteristic value (newValue.size() > MTU - 3)
+ Q_D(QLowEnergyService);
+
+ // not a characteristic of this service
+ if (!contains(characteristic))
+ return;
+
+ // don't write if we don't have to
+ if (characteristic.value() == newValue)
+ return;
+
+ // don't write write-protected or undiscovered characteristic
+ if (!(characteristic.properties() & QLowEnergyCharacteristic::Write)
+ || state() != ServiceDiscovered) {
+ d->setError(QLowEnergyService::OperationError);
+ return;
+ }
+
+ if (!d->controller)
+ return;
+
+ d->controller->writeCharacteristic(characteristic.d_ptr,
+ characteristic.attributeHandle(),
+ newValue);
+}
+
QT_END_NAMESPACE
diff --git a/src/bluetooth/qlowenergyservice.h b/src/bluetooth/qlowenergyservice.h
index 9c53aea7..d26d3fa8 100644
--- a/src/bluetooth/qlowenergyservice.h
+++ b/src/bluetooth/qlowenergyservice.h
@@ -60,7 +60,9 @@ public:
enum ServiceError {
NoError = 0,
- ServiceNotValidError
+ ServiceNotValidError,
+ OperationError,
+ CharacteristicWriteError // emitted when writeCharacteristic() failed
};
enum ServiceState {
@@ -85,6 +87,9 @@ public:
ServiceError error() const;
+ bool contains(const QLowEnergyCharacteristic &characteristic);
+ void writeCharacteristic(const QLowEnergyCharacteristic &characteristic,
+ const QByteArray &newValue);
Q_SIGNALS:
void stateChanged(QLowEnergyService::ServiceState newState);
diff --git a/src/bluetooth/qlowenergyserviceprivate_p.h b/src/bluetooth/qlowenergyserviceprivate_p.h
index 72caeeac..f5474864 100644
--- a/src/bluetooth/qlowenergyserviceprivate_p.h
+++ b/src/bluetooth/qlowenergyserviceprivate_p.h
@@ -86,6 +86,8 @@ public:
signals:
void stateChanged(QLowEnergyService::ServiceState newState);
void error(QLowEnergyService::ServiceError error);
+ void characteristicChanged(const QLowEnergyCharacteristic &characteristic,
+ const QByteArray &newValue);
public:
QLowEnergyHandle startHandle;
diff --git a/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp b/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp
index 2e88d97f..66f458f6 100644
--- a/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp
+++ b/tests/auto/qlowenergycontroller/tst_qlowenergycontroller.cpp
@@ -72,6 +72,7 @@ private slots:
void tst_connectNew();
void tst_concurrentDiscovery();
void tst_defaultBehavior();
+ void tst_writeCharacteristic();
private:
void verifyServiceProperties(const QLowEnergyServiceInfo &info);
@@ -82,12 +83,17 @@ private:
QList<QLowEnergyServiceInfo> foundServices;
};
+Q_DECLARE_METATYPE(QLowEnergyCharacteristic)
+Q_DECLARE_METATYPE(QLowEnergyService::ServiceError)
+
tst_QLowEnergyController::tst_QLowEnergyController()
{
qRegisterMetaType<QLowEnergyServiceInfo>("QLowEnergyServiceInfo");
qRegisterMetaType<QLowEnergyController::Error>("QLowEnergyController::Error");
+ //qRegisterMetaType<QLowEnergyService::ServiceError>();
qRegisterMetaType<QLowEnergyCharacteristicInfo>("QLowEnergyCharacteristicInfo");
+ qRegisterMetaType<QLowEnergyCharacteristic>();
QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true"));
const QString remote = qgetenv("BT_TEST_DEVICE");
@@ -932,7 +938,7 @@ void tst_QLowEnergyController::tst_concurrentDiscovery()
// initialize services
for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++) {
- services[i] = control.createServiceObject(uuids.at(i));
+ services[i] = control.createServiceObject(uuids.at(i), this);
QVERIFY(services[i]);
}
@@ -971,8 +977,10 @@ void tst_QLowEnergyController::tst_concurrentDiscovery()
// get all details
for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++) {
- services_second[i] = control.createServiceObject(uuids.at(i));
+ services_second[i] = control.createServiceObject(uuids.at(i), this);
+ QVERIFY(services_second[i]->parent() == this);
QVERIFY(services[i]);
+ QVERIFY(services_second[i]->state() == QLowEnergyService::DiscoveryRequired);
services_second[i]->discoverDetails();
}
@@ -986,7 +994,6 @@ void tst_QLowEnergyController::tst_concurrentDiscovery()
// verify discovered services (1st and 2nd round)
for (int i = 0; i<MAX_SERVICES_SAME_TIME_ACCESS; i++) {
-
verifyServiceProperties(services_second[i]);
//after disconnect all related characteristics and descriptors are invalid
const QList<QLowEnergyCharacteristic> chars = services[i]->characteristics();
@@ -1198,7 +1205,7 @@ void tst_QLowEnergyController::verifyServiceProperties(
QCOMPARE(chars[0].handle(), 0x25u);
QCOMPARE(chars[0].properties(),
(QLowEnergyCharacteristic::Read|QLowEnergyCharacteristic::Notify));
- //QCOMPARE(chars[0].value(), QByteArray("30303030"));
+ QCOMPARE(chars[0].value(), QByteArray("00000000"));
QVERIFY(chars[0].isValid());
QCOMPARE(chars[0].descriptors().count(), 2);
@@ -1762,6 +1769,141 @@ void tst_QLowEnergyController::tst_defaultBehavior()
}
+void tst_QLowEnergyController::tst_writeCharacteristic()
+{
+ QList<QBluetoothHostInfo> localAdapters = QBluetoothLocalDevice::allDevices();
+ if (localAdapters.isEmpty() || remoteDevice.isNull())
+ QSKIP("No local Bluetooth or remote BTLE device found. Skipping test.");
+
+ // quick setup - more elaborate test is done by connectNew()
+ QLowEnergyControllerNew control(remoteDevice);
+ QCOMPARE(control.state(), QLowEnergyControllerNew::UnconnectedState);
+ QCOMPARE(control.error(), QLowEnergyControllerNew::NoError);
+
+ control.connectToDevice();
+ {
+ QTRY_IMPL(control.state() != QLowEnergyControllerNew::ConnectingState,
+ 30000);
+ }
+
+ if (control.state() == QLowEnergyControllerNew::ConnectingState
+ || control.error() != QLowEnergyControllerNew::NoError) {
+ // default BTLE backend forever hangs in ConnectingState
+ QSKIP("Cannot connect to remote device");
+ }
+
+ QCOMPARE(control.state(), QLowEnergyControllerNew::ConnectedState);
+ QSignalSpy discoveryFinishedSpy(&control, SIGNAL(discoveryFinished()));
+ control.discoverServices();
+ QTRY_VERIFY_WITH_TIMEOUT(discoveryFinishedSpy.count() == 1, 10000);
+
+ const QBluetoothUuid testService(QString("f000aa60-0451-4000-b000-000000000000"));
+ QList<QBluetoothUuid> uuids = control.services();
+ QVERIFY(uuids.contains(testService));
+
+ QLowEnergyService *service = control.createServiceObject(testService, this);
+ QVERIFY(service);
+ service->discoverDetails();
+ QTRY_VERIFY_WITH_TIMEOUT(
+ service->state() == QLowEnergyService::ServiceDiscovered, 30000);
+
+ //test service described by http://processors.wiki.ti.com/index.php/SensorTag_User_Guide
+ const QList<QLowEnergyCharacteristic> chars = service->characteristics();
+
+ QLowEnergyCharacteristic dataChar;
+ QLowEnergyCharacteristic configChar;
+ for (int i = 0; i < chars.count(); i++) {
+ if (chars[i].uuid() == QBluetoothUuid(QString("f000aa61-0451-4000-b000-000000000000")))
+ dataChar = chars[i];
+ else if (chars[i].uuid() == QBluetoothUuid(QString("f000aa62-0451-4000-b000-000000000000")))
+ configChar = chars[i];
+ }
+
+ QVERIFY(dataChar.isValid());
+ QVERIFY(!(dataChar.properties() & ~QLowEnergyCharacteristic::Read)); // only a read char
+ QVERIFY(configChar.isValid());
+ QVERIFY(configChar.properties() & QLowEnergyCharacteristic::Write);
+
+ QCOMPARE(dataChar.value(), QByteArray("3f00"));
+ QVERIFY(configChar.value() == QByteArray("00") || configChar.value() == QByteArray("81"));
+
+ QSignalSpy writeSpy(service,
+ SIGNAL(characteristicChanged(QLowEnergyCharacteristic,QByteArray)));
+
+ // *******************************************
+ // test writing of characteristic
+ // enable Blinking LED if not already enabled
+ if (configChar.value() != QByteArray("81")) {
+ service->writeCharacteristic(configChar, QByteArray("81")); //0x81 blink LED D1
+ QTRY_VERIFY_WITH_TIMEOUT(!writeSpy.isEmpty(), 10000);
+ QCOMPARE(configChar.value(), QByteArray("81"));
+ QList<QVariant> firstSignalData= writeSpy.first();
+ QLowEnergyCharacteristic signalChar = firstSignalData[0].value<QLowEnergyCharacteristic>();
+ QByteArray signalValue = firstSignalData[1].toByteArray();
+
+ QCOMPARE(signalValue, QByteArray("81"));
+ QVERIFY(signalChar == configChar);
+
+ writeSpy.clear();
+ }
+
+ service->writeCharacteristic(configChar, QByteArray("00")); //0x81 blink LED D1
+ QTRY_VERIFY_WITH_TIMEOUT(!writeSpy.isEmpty(), 10000);
+ QCOMPARE(configChar.value(), QByteArray("00"));
+ QList<QVariant> firstSignalData = writeSpy.first();
+ QLowEnergyCharacteristic signalChar = firstSignalData[0].value<QLowEnergyCharacteristic>();
+ QByteArray signalValue = firstSignalData[1].toByteArray();
+
+ QCOMPARE(signalValue, QByteArray("00"));
+ QVERIFY(signalChar == configChar);
+
+ // *******************************************
+ // write wrong value -> error response required
+ QSignalSpy errorSpy(service, SIGNAL(error(QLowEnergyService::ServiceError)));
+ writeSpy.clear();
+ QCOMPARE(errorSpy.count(), 0);
+ QCOMPARE(writeSpy.count(), 0);
+
+ // write 2 byte value to 1 byte characteristic
+ service->writeCharacteristic(configChar, QByteArray("1111"));
+ QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 10000);
+ QCOMPARE(errorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
+ QLowEnergyService::CharacteristicWriteError);
+ QCOMPARE(service->error(), QLowEnergyService::CharacteristicWriteError);
+ QCOMPARE(writeSpy.count(), 0);
+ QCOMPARE(configChar.value(), QByteArray("00"));
+
+ // *******************************************
+ // write to read-only characteristic -> error
+ errorSpy.clear();
+ QCOMPARE(errorSpy.count(), 0);
+ service->writeCharacteristic(dataChar, QByteArray("ffff"));
+
+ QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 10000);
+ QCOMPARE(errorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
+ QLowEnergyService::OperationError);
+ QCOMPARE(service->error(), QLowEnergyService::OperationError);
+ QCOMPARE(writeSpy.count(), 0);
+ QCOMPARE(dataChar.value(), QByteArray("3f00"));
+
+
+ control.disconnectFromDevice();
+
+ // *******************************************
+ // write value while disconnected -> error
+ errorSpy.clear();
+ QCOMPARE(errorSpy.count(), 0);
+ service->writeCharacteristic(configChar, QByteArray("ffff"));
+ QTRY_VERIFY_WITH_TIMEOUT(!errorSpy.isEmpty(), 2000);
+ QCOMPARE(errorSpy[0].at(0).value<QLowEnergyService::ServiceError>(),
+ QLowEnergyService::OperationError);
+ QCOMPARE(service->error(), QLowEnergyService::OperationError);
+ QCOMPARE(writeSpy.count(), 0);
+ QCOMPARE(configChar.value(), QByteArray("00"));
+
+ delete service;
+}
+
QTEST_MAIN(tst_QLowEnergyController)
#include "tst_qlowenergycontroller.moc"