diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2016-11-04 10:07:01 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@qt.io> | 2016-11-04 10:19:35 +0000 |
commit | 78402e8f96a49462677cd07ae57c7d830228ec3b (patch) | |
tree | 78a638ae277c7045e510c0e48a91311536a6715e /src/bluetooth/osx | |
parent | 3dbea0c3f9333235629b3249115cd300f8f41112 (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.mm | 8 | ||||
-rw-r--r-- | src/bluetooth/osx/osxbtperipheralmanager_p.h | 6 | ||||
-rw-r--r-- | src/bluetooth/osx/osxbtutility.mm | 13 | ||||
-rw-r--r-- | src/bluetooth/osx/osxbtutility_p.h | 4 |
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(); |