summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/osx
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2016-11-04 10:07:01 +0100
committerAlex Blasche <alexander.blasche@qt.io>2016-11-04 10:19:35 +0000
commit78402e8f96a49462677cd07ae57c7d830228ec3b (patch)
tree78a638ae277c7045e510c0e48a91311536a6715e /src/bluetooth/osx
parent3dbea0c3f9333235629b3249115cd300f8f41112 (diff)
LE peripheral: fix a crash with unrecognized selector (iOS/macOS)
It's nice to re-use some generic functions, but it's not so if they are actually not generic: data_from_bytearray returns NSData, not NSMutableData and NSData (or whatever type they have under the hood) obviously does not have replaceBytesInRange:withBytes: method and we get 'unrecognized selector' exception as a result. Task-number: QTBUG-56898 Change-Id: I8fcaaf2a020c6f5caa8a171b7ac6e534fcb070cd Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/bluetooth/osx')
-rw-r--r--src/bluetooth/osx/osxbtperipheralmanager.mm8
-rw-r--r--src/bluetooth/osx/osxbtperipheralmanager_p.h6
-rw-r--r--src/bluetooth/osx/osxbtutility.mm13
-rw-r--r--src/bluetooth/osx/osxbtutility_p.h4
4 files changed, 23 insertions, 8 deletions
diff --git a/src/bluetooth/osx/osxbtperipheralmanager.mm b/src/bluetooth/osx/osxbtperipheralmanager.mm
index 4731fdd2..0c492aad 100644
--- a/src/bluetooth/osx/osxbtperipheralmanager.mm
+++ b/src/bluetooth/osx/osxbtperipheralmanager.mm
@@ -341,7 +341,7 @@ quint32 qt_countGATTEntries(const QLowEnergyServiceData &data)
return;
}
- const auto nsData = data_from_bytearray(value);
+ const auto nsData = mutable_data_from_bytearray(value);
charValues[charHandle] = nsData;
updateQueue.push_back(UpdateRequest{charHandle, nsData});
[self sendUpdateRequests];
@@ -530,7 +530,7 @@ quint32 qt_countGATTEntries(const QLowEnergyServiceData &data)
const auto charHandle = charMap.key(request.characteristic);
updated.insert(charHandle);
- NSMutableData *const data = static_cast<NSMutableData *>(charValues[charHandle]);
+ NSMutableData *const data = charValues[charHandle];
[data replaceBytesInRange:NSMakeRange(request.offset, request.value.length)
withBytes:data.bytes];
}
@@ -680,7 +680,7 @@ quint32 qt_countGATTEntries(const QLowEnergyServiceData &data)
continue;
}
- const auto nsData(data_from_bytearray(ch.value()));
+ const auto nsData(mutable_data_from_bytearray(ch.value()));
if (!nsData) {
qCWarning(QT_BT_OSX) << "addCharacteristicsAndDescritptors: "
"addService: failed to allocate NSData (char value)";
@@ -692,7 +692,7 @@ quint32 qt_countGATTEntries(const QLowEnergyServiceData &data)
const auto declHandle = ++lastHandle;
// CB part:
charMap[declHandle] = cbChar;
- charValues[declHandle] = data_from_bytearray(ch.value());
+ charValues[declHandle] = nsData;
// QT part:
QLowEnergyServicePrivate::CharData charData;
charData.valueHandle = ++lastHandle;
diff --git a/src/bluetooth/osx/osxbtperipheralmanager_p.h b/src/bluetooth/osx/osxbtperipheralmanager_p.h
index 30ddd073..3367b367 100644
--- a/src/bluetooth/osx/osxbtperipheralmanager_p.h
+++ b/src/bluetooth/osx/osxbtperipheralmanager_p.h
@@ -98,14 +98,14 @@ enum class PeripheralState
struct UpdateRequest
{
UpdateRequest() = default;
- UpdateRequest(QLowEnergyHandle handle, const ObjCStrongReference<NSData> &val)
+ UpdateRequest(QLowEnergyHandle handle, const ObjCStrongReference<NSMutableData> &val)
: charHandle(handle),
value(val)
{
}
QLowEnergyHandle charHandle = {};
- ObjCStrongReference<NSData> value;
+ ObjCStrongReference<NSMutableData> value;
};
@interface QT_MANGLE_NAMESPACE(OSXBTPeripheralManager) : NSObject<CBPeripheralManagerDelegate>
@@ -125,7 +125,7 @@ struct UpdateRequest
ObjCScopedPointer<NSMutableDictionary> advertisementData;
GenericLEMap<CBCharacteristic *> charMap;
- GenericLEMap<ObjCStrongReference<NSData>> charValues;
+ GenericLEMap<ObjCStrongReference<NSMutableData>> charValues;
std::deque<UpdateRequest> updateQueue;
diff --git a/src/bluetooth/osx/osxbtutility.mm b/src/bluetooth/osx/osxbtutility.mm
index adbc327b..139ccc54 100644
--- a/src/bluetooth/osx/osxbtutility.mm
+++ b/src/bluetooth/osx/osxbtutility.mm
@@ -317,6 +317,19 @@ ObjCStrongReference<NSData> data_from_bytearray(const QByteArray & qtData)
return result;
}
+ObjCStrongReference<NSMutableData> mutable_data_from_bytearray(const QByteArray &qtData)
+{
+ using MutableData = ObjCStrongReference<NSMutableData>;
+
+ if (!qtData.size())
+ return MutableData([[NSMutableData alloc] init], false);
+
+ MutableData result([[NSMutableData alloc] initWithLength:qtData.size()], false);
+ [result replaceBytesInRange:NSMakeRange(0, qtData.size())
+ withBytes:qtData.constData()];
+ return result;
+}
+
// A small RAII class for a dispatch queue.
class SerialDispatchQueue
{
diff --git a/src/bluetooth/osx/osxbtutility_p.h b/src/bluetooth/osx/osxbtutility_p.h
index 2d11692d..3c0e05e7 100644
--- a/src/bluetooth/osx/osxbtutility_p.h
+++ b/src/bluetooth/osx/osxbtutility_p.h
@@ -297,7 +297,9 @@ bool equal_uuids(const QBluetoothUuid &qtUuid, CBUUID *cbUuid);
bool equal_uuids(CBUUID *cbUuid, const QBluetoothUuid &qtUuid);
QByteArray qt_bytearray(NSData *data);
QByteArray qt_bytearray(NSObject *data);
-ObjCStrongReference<NSData> data_from_bytearray(const QByteArray & qtData);
+
+ObjCStrongReference<NSData> data_from_bytearray(const QByteArray &qtData);
+ObjCStrongReference<NSMutableData> mutable_data_from_bytearray(const QByteArray &qtData);
dispatch_queue_t qt_LE_queue();