diff options
author | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-02-11 07:44:36 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-02-11 07:44:46 +0100 |
commit | 3264db95f965a47f31ffe1ab768467ce827e41e9 (patch) | |
tree | 43235b62d755f1961de895e5b121362c54c33683 /src | |
parent | 515ccffb8d56b42c89e9c2c04abe0ef2619ece4e (diff) | |
parent | b398e069ca8bd01ba7ca67781b7ca21402ffdbbe (diff) |
Merge remote-tracking branch 'gerrit/5.4' into dev
Change-Id: Ia70c3fe64e2ffcb27181bf912b06e6af59d2bc92
Diffstat (limited to 'src')
-rw-r--r-- | src/bluetooth/android/localdevicebroadcastreceiver.cpp | 4 | ||||
-rw-r--r-- | src/bluetooth/bluez/bluez5_helper.cpp | 16 | ||||
-rw-r--r-- | src/bluetooth/bluez/bluez_data_p.h | 94 | ||||
-rw-r--r-- | src/bluetooth/bluez/hcimanager.cpp | 1 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothlocaldevice_android.cpp | 6 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothlocaldevice_bluez.cpp | 14 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothserver.cpp | 4 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent.cpp | 5 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent.h | 6 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp | 107 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothservicediscoveryagent_p.h | 6 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothsocket_android.cpp | 65 | ||||
-rw-r--r-- | src/bluetooth/qlowenergycontroller_bluez.cpp | 2 |
13 files changed, 174 insertions, 156 deletions
diff --git a/src/bluetooth/android/localdevicebroadcastreceiver.cpp b/src/bluetooth/android/localdevicebroadcastreceiver.cpp index c54c5e32..a3b92252 100644 --- a/src/bluetooth/android/localdevicebroadcastreceiver.cpp +++ b/src/bluetooth/android/localdevicebroadcastreceiver.cpp @@ -50,8 +50,8 @@ LocalDeviceBroadcastReceiver::LocalDeviceBroadcastReceiver(QObject *parent) : addAction(valueForStaticField(JavaNames::BluetoothAdapter, JavaNames::ActionScanModeChanged)); addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionAclConnected)); addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionAclDisconnected)); - if (QtAndroidPrivate::androidSdkVersion() >= 19) - addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionPairingRequest)); //API 19 + if (QtAndroidPrivate::androidSdkVersion() >= 15) + addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionPairingRequest)); //API 15 //cache integer values for host & bonding mode //don't use the java fields directly but refer to them by name diff --git a/src/bluetooth/bluez/bluez5_helper.cpp b/src/bluetooth/bluez/bluez5_helper.cpp index eebeae9d..0e3c0063 100644 --- a/src/bluetooth/bluez/bluez5_helper.cpp +++ b/src/bluetooth/bluez/bluez5_helper.cpp @@ -45,16 +45,16 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ) typedef enum Bluez5TestResultType { - Unknown, - Bluez4, - Bluez5 + BluezVersionUnknown, + BluezVersion4, + BluezVersion5 } Bluez5TestResult; -Q_GLOBAL_STATIC_WITH_ARGS(Bluez5TestResult, bluezVersion, (Bluez5TestResult::Unknown)); +Q_GLOBAL_STATIC_WITH_ARGS(Bluez5TestResult, bluezVersion, (BluezVersionUnknown)); bool isBluez5() { - if (*bluezVersion() == Bluez5TestResultType::Unknown) { + if (*bluezVersion() == BluezVersionUnknown) { OrgFreedesktopDBusObjectManagerInterface manager(QStringLiteral("org.bluez"), QStringLiteral("/"), QDBusConnection::systemBus()); @@ -65,15 +65,15 @@ bool isBluez5() QDBusPendingReply<ManagedObjectList> reply = manager.GetManagedObjects(); reply.waitForFinished(); if (reply.isError()) { - *bluezVersion() = Bluez5TestResultType::Bluez4; + *bluezVersion() = BluezVersion4; qCDebug(QT_BT_BLUEZ) << "Bluez 4 detected."; } else { - *bluezVersion() = Bluez5TestResultType::Bluez5; + *bluezVersion() = BluezVersion5; qCDebug(QT_BT_BLUEZ) << "Bluez 5 detected."; } } - return (*bluezVersion() == Bluez5TestResultType::Bluez5); + return (*bluezVersion() == BluezVersion5); } struct AdapterData diff --git a/src/bluetooth/bluez/bluez_data_p.h b/src/bluetooth/bluez/bluez_data_p.h index 7c799977..9d2d96b3 100644 --- a/src/bluetooth/bluez/bluez_data_p.h +++ b/src/bluetooth/bluez/bluez_data_p.h @@ -75,8 +75,8 @@ #define BT_SECURITY 4 struct bt_security { - uint8_t level; - uint8_t key_size; + quint8 level; + quint8 key_size; }; #define BT_SECURITY_SDP 0 #define BT_SECURITY_LOW 1 @@ -162,14 +162,14 @@ static inline void ntoh128(const quint128 *src, quint128 *dst) dst->data[15 - i] = src->data[i]; } -static inline uint16_t bt_get_le16(const void *ptr) +static inline quint16 bt_get_le16(const void *ptr) { - return bt_get_unaligned((const uint16_t *) ptr); + return bt_get_unaligned((const quint16 *) ptr); } #elif __BYTE_ORDER == __BIG_ENDIAN -static inline uint16_t bt_get_le16(const void *ptr) +static inline quint16 bt_get_le16(const void *ptr) { - return bswap_16(bt_get_unaligned((const uint16_t *) ptr)); + return bswap_16(bt_get_unaligned((const quint16 *) ptr)); } static inline void btoh128(const quint128 *src, quint128 *dst) @@ -213,79 +213,79 @@ struct sockaddr_hci { }; struct hci_dev_req { - uint16_t dev_id; - uint32_t dev_opt; + quint16 dev_id; + quint32 dev_opt; }; struct hci_dev_list_req { - uint16_t dev_num; + quint16 dev_num; struct hci_dev_req dev_req[0]; }; struct hci_dev_stats { - uint32_t err_rx; - uint32_t err_tx; - uint32_t cmd_tx; - uint32_t evt_rx; - uint32_t acl_tx; - uint32_t acl_rx; - uint32_t sco_tx; - uint32_t sco_rx; - uint32_t byte_rx; - uint32_t byte_tx; + quint32 err_rx; + quint32 err_tx; + quint32 cmd_tx; + quint32 evt_rx; + quint32 acl_tx; + quint32 acl_rx; + quint32 sco_tx; + quint32 sco_rx; + quint32 byte_rx; + quint32 byte_tx; }; struct hci_dev_info { - uint16_t dev_id; + quint16 dev_id; char name[8]; bdaddr_t bdaddr; - uint32_t flags; - uint8_t type; + quint32 flags; + quint8 type; - uint8_t features[8]; + quint8 features[8]; - uint32_t pkt_type; - uint32_t link_policy; - uint32_t link_mode; + quint32 pkt_type; + quint32 link_policy; + quint32 link_mode; - uint16_t acl_mtu; - uint16_t acl_pkts; - uint16_t sco_mtu; - uint16_t sco_pkts; + quint16 acl_mtu; + quint16 acl_pkts; + quint16 sco_mtu; + quint16 sco_pkts; struct hci_dev_stats stat; }; struct hci_conn_info { - uint16_t handle; + quint16 handle; bdaddr_t bdaddr; - uint8_t type; - uint8_t out; - uint16_t state; - uint32_t link_mode; + quint8 type; + quint8 out; + quint16 state; + quint32 link_mode; }; struct hci_conn_list_req { - uint16_t dev_id; - uint16_t conn_num; + quint16 dev_id; + quint16 conn_num; struct hci_conn_info conn_info[0]; }; struct hci_filter { - uint32_t type_mask; - uint32_t event_mask[2]; - uint16_t opcode; + quint32 type_mask; + quint32 event_mask[2]; + quint16 opcode; }; static inline void hci_set_bit(int nr, void *addr) { - *((uint32_t *) addr + (nr >> 5)) |= (1 << (nr & 31)); + *((quint32 *) addr + (nr >> 5)) |= (1 << (nr & 31)); } static inline void hci_clear_bit(int nr, void *addr) { - *((uint32_t *) addr + (nr >> 5)) &= ~(1 << (nr & 31)); + *((quint32 *) addr + (nr >> 5)) &= ~(1 << (nr & 31)); } static inline void hci_filter_clear(struct hci_filter *f) { @@ -317,16 +317,16 @@ static inline void hci_filter_all_events(struct hci_filter *f) } typedef struct { - uint8_t evt; - uint8_t plen; + quint8 evt; + quint8 plen; } __attribute__ ((packed)) hci_event_hdr; #define HCI_EVENT_HDR_SIZE 2 #define EVT_ENCRYPT_CHANGE 0x08 typedef struct { - uint8_t status; - uint16_t handle; - uint8_t encrypt; + quint8 status; + quint16 handle; + quint8 encrypt; } __attribute__ ((packed)) evt_encrypt_change; #define EVT_ENCRYPT_CHANGE_SIZE 4 diff --git a/src/bluetooth/bluez/hcimanager.cpp b/src/bluetooth/bluez/hcimanager.cpp index 17d54a4b..32450588 100644 --- a/src/bluetooth/bluez/hcimanager.cpp +++ b/src/bluetooth/bluez/hcimanager.cpp @@ -38,6 +38,7 @@ #include <QtCore/QLoggingCategory> +#include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> diff --git a/src/bluetooth/qbluetoothlocaldevice_android.cpp b/src/bluetooth/qbluetoothlocaldevice_android.cpp index 4c1b1d4e..11515743 100644 --- a/src/bluetooth/qbluetoothlocaldevice_android.cpp +++ b/src/bluetooth/qbluetoothlocaldevice_android.cpp @@ -376,9 +376,9 @@ void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pai return; } - // BluetoothDevice::createBond() requires Android API 19 - if (QtAndroidPrivate::androidSdkVersion() < 19 || !d_ptr->adapter()) { - qCWarning(QT_BT_ANDROID) << "Unable to pair: requires Android API 19+"; + // BluetoothDevice::createBond() requires Android API 15 + if (QtAndroidPrivate::androidSdkVersion() < 15 || !d_ptr->adapter()) { + qCWarning(QT_BT_ANDROID) << "Unable to pair: requires Android API 15+"; QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QBluetoothLocalDevice::Error, QBluetoothLocalDevice::PairingError)); diff --git a/src/bluetooth/qbluetoothlocaldevice_bluez.cpp b/src/bluetooth/qbluetoothlocaldevice_bluez.cpp index c7ee556d..0df7cc5d 100644 --- a/src/bluetooth/qbluetoothlocaldevice_bluez.cpp +++ b/src/bluetooth/qbluetoothlocaldevice_bluez.cpp @@ -345,6 +345,7 @@ void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pai QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QBluetoothLocalDevice::Error, QBluetoothLocalDevice::PairingError)); + delete device; return; } delete device; @@ -368,6 +369,7 @@ void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pai QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QBluetoothLocalDevice::Error, QBluetoothLocalDevice::PairingError)); + delete device; return; } delete device; @@ -579,15 +581,21 @@ QBluetoothLocalDevice::Pairing QBluetoothLocalDevice::pairingStatus( QDBusPendingReply<QVariantMap> deviceReply = device->GetProperties(); deviceReply.waitForFinished(); - if (deviceReply.isError()) + if (deviceReply.isError()) { + delete device; return Unpaired; + } QVariantMap map = deviceReply.value(); - if (map.value(QStringLiteral("Trusted")).toBool() && map.value(QStringLiteral("Paired")).toBool()) + if (map.value(QStringLiteral("Trusted")).toBool() && map.value(QStringLiteral("Paired")).toBool()) { + delete device; return AuthorizedPaired; - else if (map.value(QStringLiteral("Paired")).toBool()) + } else if (map.value(QStringLiteral("Paired")).toBool()) { + delete device; return Paired; + } + delete device; } else if (d_ptr->adapterBluez5) { QDBusPendingReply<ManagedObjectList> reply = d_ptr->managerBluez5->GetManagedObjects(); diff --git a/src/bluetooth/qbluetoothserver.cpp b/src/bluetooth/qbluetoothserver.cpp index 3001a00b..1c4676e0 100644 --- a/src/bluetooth/qbluetoothserver.cpp +++ b/src/bluetooth/qbluetoothserver.cpp @@ -204,8 +204,10 @@ QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const //! [listen] QBluetoothServiceInfo serviceInfo; serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceName, serviceName); + QBluetoothServiceInfo::Sequence browseSequence; + browseSequence << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList, - QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); + browseSequence); QBluetoothServiceInfo::Sequence classId; classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.cpp b/src/bluetooth/qbluetoothservicediscoveryagent.cpp index ef28ef82..7274780a 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent.cpp @@ -183,6 +183,11 @@ QBluetoothServiceDiscoveryAgent::QBluetoothServiceDiscoveryAgent(const QBluetoot QBluetoothServiceDiscoveryAgent::~QBluetoothServiceDiscoveryAgent() { + if (isActive()) { + disconnect(); //don't emit any signals due to stop() + stop(); + } + delete d_ptr; } diff --git a/src/bluetooth/qbluetoothservicediscoveryagent.h b/src/bluetooth/qbluetoothservicediscoveryagent.h index 787d58e3..d9f005cd 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent.h +++ b/src/bluetooth/qbluetoothservicediscoveryagent.h @@ -42,6 +42,10 @@ #include <QtBluetooth/QBluetoothUuid> #include <QtBluetooth/QBluetoothDeviceDiscoveryAgent> +#ifdef QT_BLUEZ_BLUETOOTH +#include <QtCore/qprocess.h> +#endif + QT_BEGIN_NAMESPACE class QBluetoothAddress; @@ -108,7 +112,7 @@ private: #ifdef QT_BLUEZ_BLUETOOTH Q_PRIVATE_SLOT(d_func(), void _q_discoveredServices(QDBusPendingCallWatcher*)) Q_PRIVATE_SLOT(d_func(), void _q_createdDevice(QDBusPendingCallWatcher*)) - Q_PRIVATE_SLOT(d_func(), void _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::Error, const QString &, const QStringList &)) + Q_PRIVATE_SLOT(d_func(), void _q_sdpScannerDone(int,QProcess::ExitStatus)) #endif #ifdef QT_ANDROID_BLUETOOTH Q_PRIVATE_SLOT(d_func(), void _q_processFetchedUuids(const QBluetoothAddress &address, diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp index 6958e1b2..90baf1f8 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp +++ b/src/bluetooth/qbluetoothservicediscoveryagent_bluez.cpp @@ -65,7 +65,7 @@ static inline void convertAddress(quint64 from, quint8 (&to)[6]) QBluetoothServiceDiscoveryAgentPrivate::QBluetoothServiceDiscoveryAgentPrivate(const QBluetoothAddress &deviceAdapter) : error(QBluetoothServiceDiscoveryAgent::NoError), m_deviceAdapterAddress(deviceAdapter), state(Inactive), deviceDiscoveryAgent(0), mode(QBluetoothServiceDiscoveryAgent::MinimalDiscovery), singleDevice(false), - manager(0), managerBluez5(0), adapter(0), device(0) + manager(0), managerBluez5(0), adapter(0), device(0), sdpScannerProcess(0) { if (isBluez5()) { managerBluez5 = new OrgFreedesktopDBusObjectManagerInterface( @@ -136,6 +136,7 @@ void QBluetoothServiceDiscoveryAgentPrivate::start(const QBluetoothAddress &addr } +// Bluez 5 void QBluetoothServiceDiscoveryAgentPrivate::startBluez5(const QBluetoothAddress &address) { Q_Q(QBluetoothServiceDiscoveryAgent); @@ -185,81 +186,64 @@ void QBluetoothServiceDiscoveryAgentPrivate::startBluez5(const QBluetoothAddress if (DiscoveryMode() == QBluetoothServiceDiscoveryAgent::MinimalDiscovery) { performMinimalServiceDiscovery(address); } else { - // we need to run the discovery in a different thread - // as it involves blocking calls - QtConcurrent::run(this, &QBluetoothServiceDiscoveryAgentPrivate::runSdpScan, - address, QBluetoothAddress(adapter.address())); + runExternalSdpScan(address, QBluetoothAddress(adapter.address())); } } -/* - * This function runs in a different thread. We need to be very careful what we - * access from here. That's why invokeMethod is used below. - * +/* Bluez 5 * src/tools/sdpscanner performs an SDP scan. This is * done out-of-process to avoid license issues. At this stage Bluez uses GPLv2. */ -void QBluetoothServiceDiscoveryAgentPrivate::runSdpScan( +void QBluetoothServiceDiscoveryAgentPrivate::runExternalSdpScan( const QBluetoothAddress &remoteAddress, const QBluetoothAddress localAddress) { Q_Q(QBluetoothServiceDiscoveryAgent); - const QString binPath = QLibraryInfo::location(QLibraryInfo::BinariesPath); - - QFileInfo fileInfo(binPath, QStringLiteral("sdpscanner")); - if (!fileInfo.exists() || !fileInfo.isExecutable()) { - QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection, - Q_ARG(QBluetoothServiceDiscoveryAgent::Error, - QBluetoothServiceDiscoveryAgent::InputOutputError), - Q_ARG(QString, - QBluetoothServiceDiscoveryAgent::tr("Unable to find sdpscanner")), - Q_ARG(QStringList, QStringList())); - qCWarning(QT_BT_BLUEZ) << "Cannot find sdpscanner:" - << fileInfo.canonicalFilePath(); - return; + if (!sdpScannerProcess) { + const QString binPath = QLibraryInfo::location(QLibraryInfo::BinariesPath); + QFileInfo fileInfo(binPath, QStringLiteral("sdpscanner")); + if (!fileInfo.exists() || !fileInfo.isExecutable()) { + _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::InputOutputError, + QBluetoothServiceDiscoveryAgent::tr("Unable to find sdpscanner"), + QStringList()); + qCWarning(QT_BT_BLUEZ) << "Cannot find sdpscanner:" + << fileInfo.canonicalFilePath(); + return; + } + + sdpScannerProcess = new QProcess(q); + sdpScannerProcess->setReadChannel(QProcess::StandardOutput); + sdpScannerProcess->setProgram(fileInfo.canonicalFilePath()); + q->connect(sdpScannerProcess, SIGNAL(finished(int,QProcess::ExitStatus)), + q, SLOT(_q_sdpScannerDone(int,QProcess::ExitStatus))); + } QStringList arguments; arguments << remoteAddress.toString() << localAddress.toString(); - QByteArray output; - - QProcess process; - process.setProcessChannelMode(QProcess::ForwardedErrorChannel); - process.setReadChannel(QProcess::StandardOutput); - process.start(fileInfo.canonicalFilePath(), arguments); - - if (process.waitForStarted(-1)) { - while (process.waitForReadyRead(-1)) - output += process.readAllStandardOutput(); - } - - process.waitForFinished(); + sdpScannerProcess->setArguments(arguments); + sdpScannerProcess->start(); +} - if (process.exitStatus() != QProcess::NormalExit - || process.exitCode() != 0) { - qCWarning(QT_BT_BLUEZ) << "SDP scan failure" - << process.exitStatus() << process.exitCode() - << remoteAddress; +// Bluez 5 +void QBluetoothServiceDiscoveryAgentPrivate::_q_sdpScannerDone(int exitCode, QProcess::ExitStatus status) +{ + if (status != QProcess::NormalExit || exitCode != 0) { + qCWarning(QT_BT_BLUEZ) << "SDP scan failure" << status << exitCode; if (singleDevice) { - QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection, - Q_ARG(QBluetoothServiceDiscoveryAgent::Error, - QBluetoothServiceDiscoveryAgent::InputOutputError), - Q_ARG(QString, - QBluetoothServiceDiscoveryAgent::tr("Unable to perform SDP scan")), - Q_ARG(QStringList, QStringList())); + _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::InputOutputError, + QBluetoothServiceDiscoveryAgent::tr("Unable to perform SDP scan"), + QStringList()); } else { // go to next device - QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection, - Q_ARG(QBluetoothServiceDiscoveryAgent::Error, - QBluetoothServiceDiscoveryAgent::NoError), - Q_ARG(QString, QString()), - Q_ARG(QStringList, QStringList())); + _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::NoError, QString(), QStringList()); } return; } QStringList xmlRecords; + const QByteArray output = sdpScannerProcess->readAllStandardOutput(); const QString decodedData = QString::fromUtf8(QByteArray::fromBase64(output)); // split the various xml docs up @@ -276,13 +260,10 @@ void QBluetoothServiceDiscoveryAgentPrivate::runSdpScan( } while ( start != -1); } - QMetaObject::invokeMethod(q, "_q_finishSdpScan", Qt::QueuedConnection, - Q_ARG(QBluetoothServiceDiscoveryAgent::Error, - QBluetoothServiceDiscoveryAgent::NoError), - Q_ARG(QString, QString()), - Q_ARG(QStringList, xmlRecords)); + _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::NoError, QString(), xmlRecords); } +// Bluez 5 void QBluetoothServiceDiscoveryAgentPrivate::_q_finishSdpScan(QBluetoothServiceDiscoveryAgent::Error errorCode, const QString &errorDescription, const QStringList &xmlRecords) @@ -352,8 +333,19 @@ void QBluetoothServiceDiscoveryAgentPrivate::stop() Q_ASSERT(!device); } + discoveredDevices.clear(); setDiscoveryState(Inactive); + + // must happen after discoveredDevices.clear() above to avoid retrigger of next scan + // while waitForFinished() is waiting + if (sdpScannerProcess) { // Bluez 5 + if (sdpScannerProcess->state() != QProcess::NotRunning) { + sdpScannerProcess->kill(); + sdpScannerProcess->waitForFinished(); + } + } + Q_Q(QBluetoothServiceDiscoveryAgent); emit q->canceled(); } @@ -591,6 +583,7 @@ QBluetoothServiceInfo QBluetoothServiceDiscoveryAgentPrivate::parseServiceXml( return serviceInfo; } +// Bluez 5 void QBluetoothServiceDiscoveryAgentPrivate::performMinimalServiceDiscovery(const QBluetoothAddress &deviceAddress) { if (foundHostAdapterPath.isEmpty()) { diff --git a/src/bluetooth/qbluetoothservicediscoveryagent_p.h b/src/bluetooth/qbluetoothservicediscoveryagent_p.h index ea985627..3b9c0a42 100644 --- a/src/bluetooth/qbluetoothservicediscoveryagent_p.h +++ b/src/bluetooth/qbluetoothservicediscoveryagent_p.h @@ -58,6 +58,7 @@ class OrgBluezManagerInterface; class OrgBluezAdapterInterface; class OrgBluezDeviceInterface; class OrgFreedesktopDBusObjectManagerInterface; +#include <QtCore/qprocess.h> QT_BEGIN_NAMESPACE class QDBusPendingCallWatcher; @@ -127,6 +128,7 @@ public: void _q_discoverGattCharacteristics(QDBusPendingCallWatcher *watcher); void _q_discoveredGattCharacteristic(QDBusPendingCallWatcher *watcher); */ + void _q_sdpScannerDone(int exitCode, QProcess::ExitStatus status); void _q_finishSdpScan(QBluetoothServiceDiscoveryAgent::Error errorCode, const QString &errorDescription, const QStringList &xmlRecords); @@ -147,8 +149,9 @@ private: #ifdef QT_BLUEZ_BLUETOOTH void startBluez5(const QBluetoothAddress &address); - void runSdpScan(const QBluetoothAddress &remoteAddress, + void runExternalSdpScan(const QBluetoothAddress &remoteAddress, const QBluetoothAddress localAddress); + void sdpScannerDone(int exitCode, QProcess::ExitStatus exitStatus); QVariant readAttributeValue(QXmlStreamReader &xml); QBluetoothServiceInfo parseServiceXml(const QString& xml); void performMinimalServiceDiscovery(const QBluetoothAddress &deviceAddress); @@ -195,6 +198,7 @@ private: OrgFreedesktopDBusObjectManagerInterface *managerBluez5; OrgBluezAdapterInterface *adapter; OrgBluezDeviceInterface *device; + QProcess *sdpScannerProcess; #endif #ifdef QT_ANDROID_BLUETOOTH diff --git a/src/bluetooth/qbluetoothsocket_android.cpp b/src/bluetooth/qbluetoothsocket_android.cpp index 02440abc..c3380836 100644 --- a/src/bluetooth/qbluetoothsocket_android.cpp +++ b/src/bluetooth/qbluetoothsocket_android.cpp @@ -37,6 +37,7 @@ #include "qbluetoothaddress.h" #include <QtCore/QLoggingCategory> #include <QtCore/QTime> +#include <QtCore/private/qjni_p.h> #include <QtConcurrent/QtConcurrentRun> #include <QtAndroidExtras/QAndroidJniEnvironment> @@ -90,32 +91,37 @@ bool QBluetoothSocketPrivate::fallBackConnect(QAndroidJniObject uuid, int channe qCWarning(QT_BT_ANDROID) << "Falling back to workaround."; QAndroidJniEnvironment env; - jclass remoteDeviceClazz = env->GetObjectClass(remoteDevice.object()); - jmethodID getClassMethod = env->GetMethodID(remoteDeviceClazz, "getClass", "()Ljava/lang/Class;"); - if (!getClassMethod) { - qCWarning(QT_BT_ANDROID) << "BluetoothDevice.getClass method could not be found."; - return false; - } - - QAndroidJniObject remoteDeviceClass = QAndroidJniObject(env->CallObjectMethod(remoteDevice.object(), getClassMethod)); + QAndroidJniObject remoteDeviceClass = remoteDevice.callObjectMethod("getClass", "()Ljava/lang/Class;"); if (!remoteDeviceClass.isValid()) { qCWarning(QT_BT_ANDROID) << "Could not invoke BluetoothDevice.getClass."; return false; } - jclass classClass = env->FindClass("java/lang/Class"); - jclass integerClass = env->FindClass("java/lang/Integer"); - jfieldID integerType = env->GetStaticFieldID(integerClass, "TYPE", "Ljava/lang/Class;"); - jobject integerObject = env->GetStaticObjectField(integerClass, integerType); - if (!integerObject) { + QAndroidJniObject integerObject = QAndroidJniObject::getStaticObjectField<jobject>( + "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); + if (!integerObject.isValid()) { qCWarning(QT_BT_ANDROID) << "Could not get Integer.TYPE"; + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + } + return false; } - jobjectArray paramTypes = env->NewObjectArray(1, classClass, integerObject); - if (!paramTypes) { + jclass classClass = QJNIEnvironmentPrivate::findClass("java/lang/Class"); + jobjectArray rawArray = env->NewObjectArray(1, classClass, + integerObject.object<jobject>()); + QAndroidJniObject paramTypes(rawArray); + env->DeleteLocalRef(rawArray); + if (!paramTypes.isValid()) { qCWarning(QT_BT_ANDROID) << "Could not create new Class[]{Integer.TYPE}"; + + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + } return false; } @@ -143,7 +149,7 @@ bool QBluetoothSocketPrivate::fallBackConnect(QAndroidJniObject uuid, int channe "getMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", QAndroidJniObject::fromString(QLatin1String("createRfcommSocket")).object<jstring>(), - paramTypes); + paramTypes.object<jobjectArray>()); if (!method.isValid() || env->ExceptionCheck()) { qCWarning(QT_BT_ANDROID) << "Could not invoke getMethod"; if (env->ExceptionCheck()) { @@ -153,29 +159,23 @@ bool QBluetoothSocketPrivate::fallBackConnect(QAndroidJniObject uuid, int channe return false; } - jclass methodClass = env->GetObjectClass(method.object()); - jmethodID invokeMethodId = env->GetMethodID( - methodClass, "invoke", - "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); - if (!invokeMethodId) { - qCWarning(QT_BT_ANDROID) << "Could not invoke method."; - return false; - } + jclass objectClass = QJNIEnvironmentPrivate::findClass("java/lang/Object"); + QAndroidJniObject channelObject = QAndroidJniObject::callStaticObjectMethod( + "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", channel); + rawArray = env->NewObjectArray(1, objectClass, channelObject.object<jobject>()); - jmethodID valueOfMethodId = env->GetStaticMethodID(integerClass, "valueOf", "(I)Ljava/lang/Integer;"); - jclass objectClass = env->FindClass("java/lang/Object"); - jobjectArray invokeParams = env->NewObjectArray(1, objectClass, env->CallStaticObjectMethod(integerClass, valueOfMethodId, channel)); - - - jobject invokeResult = env->CallObjectMethod(method.object(), invokeMethodId, - remoteDevice.object(), invokeParams); - if (!invokeResult) + QAndroidJniObject invokeResult = method.callObjectMethod("invoke", + "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", + remoteDevice.object<jobject>(), rawArray); + env->DeleteLocalRef(rawArray); + if (!invokeResult.isValid()) { qCWarning(QT_BT_ANDROID) << "Invoke Resulted with error."; if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); } + return false; } @@ -186,7 +186,6 @@ bool QBluetoothSocketPrivate::fallBackConnect(QAndroidJniObject uuid, int channe env->ExceptionClear(); qCWarning(QT_BT_ANDROID) << "Socket connect via workaround failed."; - return false; } diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp index 63de6edb..ae354bc7 100644 --- a/src/bluetooth/qlowenergycontroller_bluez.cpp +++ b/src/bluetooth/qlowenergycontroller_bluez.cpp @@ -41,6 +41,8 @@ #include <QtBluetooth/QBluetoothSocket> #include <QtBluetooth/QLowEnergyService> +#include <errno.h> + #define ATTRIBUTE_CHANNEL_ID 4 #define ATT_DEFAULT_LE_MTU 23 |