summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@theqtcompany.com>2015-09-04 14:44:19 +0200
committerAlex Blasche <alexander.blasche@theqtcompany.com>2015-09-04 14:44:55 +0200
commit44453809c5c1ca0885499536617c9b3d0d2519d6 (patch)
tree9b391e5c3f7ee3ac1881746ffe7bb4ba581104ee /src
parentb5c5ac26b0066c40a19fcd4498d4feac8e0d8503 (diff)
parentde51d11f61c794a27859b2a33eb2d135f55a288a (diff)
Merge remote-tracking branch 'gerrit/dev' into btle
Diffstat (limited to 'src')
-rw-r--r--src/bluetooth/qbluetoothlocaldevice.h4
-rw-r--r--src/bluetooth/qbluetoothserver_bluez.cpp153
-rw-r--r--src/bluetooth/qbluetoothserver_p.h2
-rw-r--r--src/bluetooth/qbluetoothsocket_android.cpp23
-rw-r--r--src/bluetooth/qbluetoothsocket_bluez.cpp21
-rw-r--r--src/bluetooth/qbluetoothtransferreply.h2
-rw-r--r--src/bluetooth/qlowenergycontroller.h4
-rw-r--r--src/bluetooth/qlowenergycontroller_bluez.cpp5
-rw-r--r--src/bluetooth/qlowenergycontroller_p.h2
-rw-r--r--src/bluetooth/qlowenergyservice.cpp2
-rw-r--r--src/bluetooth/qlowenergyservice.h5
-rw-r--r--src/nfc/qnearfieldmanager_emulator_p.h4
-rw-r--r--src/tools/sdpscanner/main.cpp34
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);