diff options
author | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-09-04 14:44:19 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-09-04 14:44:55 +0200 |
commit | 44453809c5c1ca0885499536617c9b3d0d2519d6 (patch) | |
tree | 9b391e5c3f7ee3ac1881746ffe7bb4ba581104ee /src | |
parent | b5c5ac26b0066c40a19fcd4498d4feac8e0d8503 (diff) | |
parent | de51d11f61c794a27859b2a33eb2d135f55a288a (diff) |
Merge remote-tracking branch 'gerrit/dev' into btle
Change-Id: I4ddf6c4299a533abbbe638f66b7d792d1cc74d58
Diffstat (limited to 'src')
-rw-r--r-- | src/bluetooth/qbluetoothlocaldevice.h | 4 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothserver_bluez.cpp | 153 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothserver_p.h | 2 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothsocket_android.cpp | 23 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothsocket_bluez.cpp | 21 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothtransferreply.h | 2 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller.h | 4 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_bluez.cpp | 5 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_p.h | 2 | ||||
-rw-r--r-- | src/bluetooth/qlowenergyservice.cpp | 2 | ||||
-rw-r--r-- | src/bluetooth/qlowenergyservice.h | 5 | ||||
-rw-r--r-- | src/nfc/qnearfieldmanager_emulator_p.h | 4 | ||||
-rw-r--r-- | src/tools/sdpscanner/main.cpp | 34 |
13 files changed, 168 insertions, 93 deletions
diff --git a/src/bluetooth/qbluetoothlocaldevice.h b/src/bluetooth/qbluetoothlocaldevice.h index 4587bbf0..40e143ab 100644 --- a/src/bluetooth/qbluetoothlocaldevice.h +++ b/src/bluetooth/qbluetoothlocaldevice.h @@ -113,4 +113,8 @@ private: QT_END_NAMESPACE +Q_DECLARE_METATYPE(QBluetoothLocalDevice::Pairing) +Q_DECLARE_METATYPE(QBluetoothLocalDevice::HostMode) +Q_DECLARE_METATYPE(QBluetoothLocalDevice::Error) + #endif // QBLUETOOTHLOCALDEVICE_H diff --git a/src/bluetooth/qbluetoothserver_bluez.cpp b/src/bluetooth/qbluetoothserver_bluez.cpp index d5cdb440..6b538447 100644 --- a/src/bluetooth/qbluetoothserver_bluez.cpp +++ b/src/bluetooth/qbluetoothserver_bluez.cpp @@ -57,8 +57,8 @@ static inline void convertAddress(quint64 from, quint8 (&to)[6]) } QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType) - : maxPendingConnections(1), serverType(sType), m_lastError(QBluetoothServer::NoError), - socketNotifier(0) + : maxPendingConnections(1), securityFlags(QBluetooth::Authorization), serverType(sType), + m_lastError(QBluetoothServer::NoError), socketNotifier(0) { if (sType == QBluetoothServiceInfo::RfcommProtocol) socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol); @@ -81,6 +81,57 @@ void QBluetoothServerPrivate::_q_newConnection() emit q_ptr->newConnection(); } +void QBluetoothServerPrivate::setSocketSecurityLevel( + QBluetooth::SecurityFlags requestedSecLevel, int *errnoCode) +{ + if (requestedSecLevel == QBluetooth::NoSecurity) { + qCWarning(QT_BT_BLUEZ) << "Cannot set NoSecurity on server socket"; + return; + } + + struct bt_security security; + memset(&security, 0, sizeof(security)); + + // ignore QBluetooth::Authentication -> not used anymore + if (requestedSecLevel & QBluetooth::Authorization) + security.level = BT_SECURITY_LOW; + if (requestedSecLevel & QBluetooth::Encryption) + security.level = BT_SECURITY_MEDIUM; + if (requestedSecLevel & QBluetooth::Secure) + security.level = BT_SECURITY_HIGH; + + if (setsockopt(socket->socketDescriptor(), SOL_BLUETOOTH, BT_SECURITY, + &security, sizeof(security)) != 0) { + if (errnoCode) + *errnoCode = errno; + } +} + +QBluetooth::SecurityFlags QBluetoothServerPrivate::socketSecurityLevel() const +{ + struct bt_security security; + memset(&security, 0, sizeof(security)); + socklen_t length = sizeof(security); + + if (getsockopt(socket->socketDescriptor(), SOL_BLUETOOTH, BT_SECURITY, + &security, &length) != 0) { + qCWarning(QT_BT_BLUEZ) << "Failed to get security flags" << qt_error_string(errno); + return QBluetooth::NoSecurity; + } + + switch (security.level) { + case BT_SECURITY_LOW: + return QBluetooth::Authorization; + case BT_SECURITY_MEDIUM: + return QBluetooth::Encryption; + case BT_SECURITY_HIGH: + return QBluetooth::Secure; + default: + qCWarning(QT_BT_BLUEZ) << "Unknown server socket security level" << security.level; + return QBluetooth::NoSecurity; + } +} + void QBluetoothServer::close() { Q_D(QBluetoothServer); @@ -178,6 +229,8 @@ bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port) } } + d->setSocketSecurityLevel(d->securityFlags, 0); + if (::listen(sock, d->maxPendingConnections) < 0) { d->m_lastError = InputOutputError; emit error(d->m_lastError); @@ -269,95 +322,31 @@ void QBluetoothServer::setSecurityFlags(QBluetooth::SecurityFlags security) { Q_D(QBluetoothServer); - int lm = 0; - if (security == QBluetooth::NoSecurity) - lm = 0; - - if (d->serverType == QBluetoothServiceInfo::RfcommProtocol) { - if (security.testFlag(QBluetooth::Authorization)) - lm |= RFCOMM_LM_AUTH; - if (security.testFlag(QBluetooth::Authentication)) - lm |= RFCOMM_LM_TRUSTED; - if (security.testFlag(QBluetooth::Encryption)) - lm |= RFCOMM_LM_ENCRYPT; - if (security.testFlag(QBluetooth::Secure)) - lm |= RFCOMM_LM_SECURE; - - qCDebug(QT_BT_BLUEZ) << hex << "Setting lm to" << lm << security; - - if (setsockopt(d->socket->socketDescriptor(), SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0){ - qCWarning(QT_BT_BLUEZ) << "Failed to set socket option, closing socket for safety" << errno; - qCWarning(QT_BT_BLUEZ) << "Error: " << qt_error_string(errno); - d->m_lastError = InputOutputError; - emit error(d->m_lastError); - d->socket->close(); - } - } else { - if (security.testFlag(QBluetooth::Authorization)) - lm |= L2CAP_LM_AUTH; - if (security.testFlag(QBluetooth::Authentication)) - lm |= L2CAP_LM_TRUSTED; - if (security.testFlag(QBluetooth::Encryption)) - lm |= L2CAP_LM_ENCRYPT; - if (security.testFlag(QBluetooth::Secure)) - lm |= L2CAP_LM_SECURE; - - if (setsockopt(d->socket->socketDescriptor(), SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0){ - qCWarning(QT_BT_BLUEZ) << "Failed to set socket option, closing socket for safety" << errno; - qCWarning(QT_BT_BLUEZ) << "Error: " << qt_error_string(errno); - d->m_lastError = InputOutputError; - emit error(d->m_lastError); - d->socket->close(); - } + if (d->socket->state() == QBluetoothSocket::UnconnectedState) { + // nothing to set beyond the fact to remember the sec level for the next listen() + d->securityFlags = security; + return; } + int errorCode = 0; + d->setSocketSecurityLevel(security, &errorCode); + if (errorCode) { + qCWarning(QT_BT_BLUEZ) << "Failed to set socket option, closing socket for safety" << errorCode; + qCWarning(QT_BT_BLUEZ) << "Error: " << qt_error_string(errorCode); + d->m_lastError = InputOutputError; + emit error(d->m_lastError); + d->socket->close(); + } } QBluetooth::SecurityFlags QBluetoothServer::securityFlags() const { Q_D(const QBluetoothServer); - int lm = 0; - int len = sizeof(lm); - int security = QBluetooth::NoSecurity; - - if (d->serverType == QBluetoothServiceInfo::RfcommProtocol) { - if (getsockopt(d->socket->socketDescriptor(), SOL_RFCOMM, RFCOMM_LM, &lm, (socklen_t *)&len) < 0) { - qCWarning(QT_BT_BLUEZ) << "Failed to get security flags" << qt_error_string(errno); - return QBluetooth::NoSecurity; - } - - if (lm & RFCOMM_LM_SECURE) - security |= QBluetooth::Secure; - - if (lm & RFCOMM_LM_ENCRYPT) - security |= QBluetooth::Encryption; - - if (lm & RFCOMM_LM_TRUSTED) - security |= QBluetooth::Authentication; - - if (lm & RFCOMM_LM_AUTH) - security |= QBluetooth::Authorization; - } else { - if (getsockopt(d->socket->socketDescriptor(), SOL_L2CAP, L2CAP_LM, &lm, (socklen_t *)&len) < 0) { - qCWarning(QT_BT_BLUEZ) << "Failed to get security flags" << qt_error_string(errno); - return QBluetooth::NoSecurity; - } - - if (lm & L2CAP_LM_SECURE) - security |= QBluetooth::Secure; - - if (lm & L2CAP_LM_ENCRYPT) - security |= QBluetooth::Encryption; - - if (lm & L2CAP_LM_TRUSTED) - security |= QBluetooth::Authentication; - - if (lm & L2CAP_LM_AUTH) - security |= QBluetooth::Authorization; - } + if (d->socket->state() == QBluetoothSocket::UnconnectedState) + return d->securityFlags; - return static_cast<QBluetooth::Security>(security); + return d->socketSecurityLevel(); } QT_END_NAMESPACE diff --git a/src/bluetooth/qbluetoothserver_p.h b/src/bluetooth/qbluetoothserver_p.h index ae9b2740..2516c3d3 100644 --- a/src/bluetooth/qbluetoothserver_p.h +++ b/src/bluetooth/qbluetoothserver_p.h @@ -82,6 +82,8 @@ public: #ifdef QT_BLUEZ_BLUETOOTH void _q_newConnection(); + void setSocketSecurityLevel(QBluetooth::SecurityFlags requestedSecLevel, int *errnoCode); + QBluetooth::SecurityFlags socketSecurityLevel() const; #endif public: diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp index 3c526eca..1a5f70b0 100644 --- a/src/bluetooth/qbluetoothsocket_android.cpp +++ b/src/bluetooth/qbluetoothsocket_android.cpp @@ -258,11 +258,22 @@ bool QBluetoothSocketPrivate::fallBackConnect(QAndroidJniObject uuid, int channe } } - QAndroidJniObject method = remoteDeviceClass.callObjectMethod( + QAndroidJniObject method; + if (secFlags == QBluetooth::NoSecurity) { + qCDebug(QT_BT_ANDROID) << "Connnecting via insecure rfcomm"; + method = remoteDeviceClass.callObjectMethod( + "getMethod", + "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", + QAndroidJniObject::fromString(QLatin1String("createInsecureRfcommSocket")).object<jstring>(), + paramTypes.object<jobjectArray>()); + } else { + qCDebug(QT_BT_ANDROID) << "Connnecting via secure rfcomm"; + method = remoteDeviceClass.callObjectMethod( "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", QAndroidJniObject::fromString(QLatin1String("createRfcommSocket")).object<jstring>(), paramTypes.object<jobjectArray>()); + } if (!method.isValid() || env->ExceptionCheck()) { qCWarning(QT_BT_ANDROID) << "Could not invoke getMethod"; if (env->ExceptionCheck()) { @@ -372,9 +383,17 @@ void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, "(Ljava/lang/String;)Ljava/util/UUID;", inputString.object<jstring>()); - socketObject = remoteDevice.callObjectMethod("createRfcommSocketToServiceRecord", + if (secFlags == QBluetooth::NoSecurity) { + qCDebug(QT_BT_ANDROID) << "Connnecting via insecure rfcomm"; + socketObject = remoteDevice.callObjectMethod("createInsecureRfcommSocketToServiceRecord", "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;", uuidObject.object<jobject>()); + } else { + qCDebug(QT_BT_ANDROID) << "Connnecting via secure rfcomm"; + socketObject = remoteDevice.callObjectMethod("createRfcommSocketToServiceRecord", + "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;", + uuidObject.object<jobject>()); + } if (env->ExceptionCheck()) { env->ExceptionDescribe(); diff --git a/src/bluetooth/qbluetoothsocket_bluez.cpp b/src/bluetooth/qbluetoothsocket_bluez.cpp index fde5b58e..51bc5179 100644 --- a/src/bluetooth/qbluetoothsocket_bluez.cpp +++ b/src/bluetooth/qbluetoothsocket_bluez.cpp @@ -133,6 +133,27 @@ void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, return; } + // apply preferred security level + // ignore QBluetooth::Authentication -> not used anymore by kernel + struct bt_security security; + memset(&security, 0, sizeof(security)); + + if (secFlags & QBluetooth::Authorization) + security.level = BT_SECURITY_LOW; + if (secFlags & QBluetooth::Encryption) + security.level = BT_SECURITY_MEDIUM; + if (secFlags & QBluetooth::Secure) + security.level = BT_SECURITY_HIGH; + + if (setsockopt(socket, SOL_BLUETOOTH, BT_SECURITY, + &security, sizeof(security)) != 0) { + qCWarning(QT_BT_BLUEZ) << "Failed to set socket option, closing socket for safety" << errno; + qCWarning(QT_BT_BLUEZ) << "Error: " << qt_error_string(errno); + errorString = QBluetoothSocket::tr("Cannot set connection security level"); + q->setSocketError(QBluetoothSocket::UnknownSocketError); + return; + } + if (socketType == QBluetoothServiceInfo::RfcommProtocol) { sockaddr_rc addr; diff --git a/src/bluetooth/qbluetoothtransferreply.h b/src/bluetooth/qbluetoothtransferreply.h index 428e3cd0..755b9caa 100644 --- a/src/bluetooth/qbluetoothtransferreply.h +++ b/src/bluetooth/qbluetoothtransferreply.h @@ -96,4 +96,6 @@ private: QT_END_NAMESPACE +Q_DECLARE_METATYPE(QBluetoothTransferReply::TransferError) + #endif // QBLUETOOTHTRANSFERREPLY_H diff --git a/src/bluetooth/qlowenergycontroller.h b/src/bluetooth/qlowenergycontroller.h index fd230238..be729dda 100644 --- a/src/bluetooth/qlowenergycontroller.h +++ b/src/bluetooth/qlowenergycontroller.h @@ -119,4 +119,8 @@ private: QT_END_NAMESPACE +Q_DECLARE_METATYPE(QLowEnergyController::Error) +Q_DECLARE_METATYPE(QLowEnergyController::ControllerState) +Q_DECLARE_METATYPE(QLowEnergyController::RemoteAddressType) + #endif // QLOWENERGYCONTROLLER_H diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp index bb490ba9..8906eb06 100644 --- a/src/bluetooth/qlowenergycontroller_bluez.cpp +++ b/src/bluetooth/qlowenergycontroller_bluez.cpp @@ -478,7 +478,7 @@ QLowEnergyHandle parseReadByTypeCharDiscovery( QLowEnergyHandle attributeHandle = bt_get_le16(&data[0]); charData->properties = - (QLowEnergyCharacteristic::PropertyTypes)data[2]; + (QLowEnergyCharacteristic::PropertyTypes)(data[2] & 0xff); charData->valueHandle = bt_get_le16(&data[3]); if (elementLength == 7) // 16 bit uuid @@ -672,6 +672,7 @@ void QLowEnergyControllerPrivate::processReply( lastHandle = parseReadByTypeCharDiscovery( &characteristic, &data[offset], elementLength); p->characteristicList[lastHandle] = characteristic; + offset += elementLength; } else if (attributeType == GATT_INCLUDED_SERVICE) { QList<QBluetoothUuid> includedServices; lastHandle = parseReadByTypeIncludeDiscovery( @@ -1222,7 +1223,7 @@ void QLowEnergyControllerPrivate::readServiceValues( starting the next read request. */ void QLowEnergyControllerPrivate::readServiceValuesByOffset( - quint16 handleData, quint16 offset, bool isLastValue) + uint handleData, quint16 offset, bool isLastValue) { const QLowEnergyHandle charHandle = (handleData & 0xffff); const QLowEnergyHandle descriptorHandle = ((handleData >> 16) & 0xffff); diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h index bb26a538..810f0ff4 100644 --- a/src/bluetooth/qlowenergycontroller_p.h +++ b/src/bluetooth/qlowenergycontroller_p.h @@ -173,7 +173,7 @@ private: void sendReadValueRequest(QLowEnergyHandle attributeHandle, bool isDescriptor); void readServiceValues(const QBluetoothUuid &service, bool readCharacteristics); - void readServiceValuesByOffset(quint16 handleData, quint16 offset, + void readServiceValuesByOffset(uint handleData, quint16 offset, bool isLastValue); void discoverServiceDescriptors(const QBluetoothUuid &serviceUuid); diff --git a/src/bluetooth/qlowenergyservice.cpp b/src/bluetooth/qlowenergyservice.cpp index 0781def5..07590943 100644 --- a/src/bluetooth/qlowenergyservice.cpp +++ b/src/bluetooth/qlowenergyservice.cpp @@ -349,6 +349,8 @@ QLowEnergyService::QLowEnergyService(QSharedPointer<QLowEnergyServicePrivate> p, { qRegisterMetaType<QLowEnergyService::ServiceState>(); qRegisterMetaType<QLowEnergyService::ServiceError>(); + qRegisterMetaType<QLowEnergyService::ServiceType>(); + qRegisterMetaType<QLowEnergyService::WriteMode>(); connect(p.data(), SIGNAL(error(QLowEnergyService::ServiceError)), this, SIGNAL(error(QLowEnergyService::ServiceError))); diff --git a/src/bluetooth/qlowenergyservice.h b/src/bluetooth/qlowenergyservice.h index dc03419d..524650c9 100644 --- a/src/bluetooth/qlowenergyservice.h +++ b/src/bluetooth/qlowenergyservice.h @@ -134,4 +134,9 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QLowEnergyService::ServiceTypes) QT_END_NAMESPACE +Q_DECLARE_METATYPE(QLowEnergyService::ServiceError) +Q_DECLARE_METATYPE(QLowEnergyService::ServiceState) +Q_DECLARE_METATYPE(QLowEnergyService::ServiceType) +Q_DECLARE_METATYPE(QLowEnergyService::WriteMode) + #endif // QLOWENERGYSERVICE_H diff --git a/src/nfc/qnearfieldmanager_emulator_p.h b/src/nfc/qnearfieldmanager_emulator_p.h index 0fd980f9..a71c9fd5 100644 --- a/src/nfc/qnearfieldmanager_emulator_p.h +++ b/src/nfc/qnearfieldmanager_emulator_p.h @@ -50,7 +50,7 @@ #include "qndeffilter.h" #include <QtCore/QObject> -#include <QtCore/QWeakPointer> +#include <QtCore/QPointer> QT_BEGIN_NAMESPACE @@ -74,7 +74,7 @@ private slots: private: void ndefReceived(const QNdefMessage &message, QNearFieldTarget *target); - QMap<TagBase *, QWeakPointer<QNearFieldTarget> > m_targets; + QMap<TagBase *, QPointer<QNearFieldTarget> > m_targets; }; diff --git a/src/tools/sdpscanner/main.cpp b/src/tools/sdpscanner/main.cpp index 1efb6de2..50870651 100644 --- a/src/tools/sdpscanner/main.cpp +++ b/src/tools/sdpscanner/main.cpp @@ -46,9 +46,11 @@ void usage() { fprintf(stderr, "Usage:\n"); - fprintf(stderr, "\tsdpscanner <remote bdaddr> <local bdaddr>\n\n"); + fprintf(stderr, "\tsdpscanner <remote bdaddr> <local bdaddr> [Options]\n\n"); fprintf(stderr, "Performs an SDP scan on remote device, using the SDP server\n" - "represented by the local Bluetooth device.\n"); + "represented by the local Bluetooth device.\n\n" + "Options:\n" + " -p Show scan results in human-readable form\n"); } #define BUFFER_SIZE 1024 @@ -245,7 +247,7 @@ QByteArray parseSdpRecord(sdp_record_t *record) int main(int argc, char **argv) { - if (argc != 3) { + if (argc < 3) { usage(); return RETURN_USAGE; } @@ -266,6 +268,27 @@ int main(int argc, char **argv) return RETURN_INVALPARAM; } + bool showHumanReadable = false; + + for (int i = 3; i < argc; i++) { + if (argv[i][0] != '-') { + usage(); + return RETURN_USAGE; + } + + switch (argv[i][1]) + { + case 'p': + showHumanReadable = true; + break; + default: + fprintf(stderr, "Wrong argument: %s\n", argv[i]); + usage(); + return RETURN_USAGE; + + } + } + sdp_session_t *session = sdp_connect( &local, &remote, SDP_RETRY_IF_BUSY); if (!session) { //try one more time if first time failed @@ -314,7 +337,10 @@ int main(int argc, char **argv) } if (!total.isEmpty()) { - printf("%s", total.toBase64().constData()); + if (showHumanReadable) + printf("%s", total.constData()); + else + printf("%s", total.toBase64().constData()); } sdp_close(session); |