11#include <QtCore/QFile>
12#include <QtCore/QLibraryInfo>
13#include <QtCore/QLoggingCategory>
14#include <QtCore/QProcess>
15#include <QtCore/QScopeGuard>
17#include <QtDBus/QDBusPendingCallWatcher>
32 qRegisterMetaType<QBluetoothServiceDiscoveryAgent::Error>();
46 if (foundHostAdapterPath.isEmpty()) {
54 errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Cannot access adapter during service discovery");
60 if (foundHostAdapterPath.isEmpty()) {
66 errorString = QBluetoothServiceDiscoveryAgent::tr(
"Cannot find local Bluetooth adapter");
77 if (!adapter.powered()) {
81 errorString = QBluetoothServiceDiscoveryAgent::tr(
"Local device is powered off");
89 performMinimalServiceDiscovery(
address);
99void QBluetoothServiceDiscoveryAgentPrivate::runExternalSdpScan(
104 if (!sdpScannerProcess) {
107 if (!fileInfo.exists() || !fileInfo.isExecutable()) {
109 QBluetoothServiceDiscoveryAgent::tr(
"Unable to find sdpscanner"),
111 qCWarning(QT_BT_BLUEZ) <<
"Cannot find sdpscanner:"
112 << fileInfo.canonicalFilePath();
116 sdpScannerProcess =
new QProcess(
q);
117 sdpScannerProcess->setReadChannel(QProcess::StandardOutput);
118 if (QT_BT_BLUEZ().isDebugEnabled())
119 sdpScannerProcess->setProcessChannelMode(QProcess::ForwardedErrorChannel);
120 sdpScannerProcess->setProgram(fileInfo.canonicalFilePath());
121 q->connect(sdpScannerProcess,
123 q, [
this](
int exitCode, QProcess::ExitStatus status){
124 this->_q_sdpScannerDone(exitCode, status);
129 arguments << remoteAddress.toString() << localAddress.toString();
138 sdpScannerProcess->setArguments(
arguments);
139 sdpScannerProcess->start();
142void QBluetoothServiceDiscoveryAgentPrivate::_q_sdpScannerDone(
int exitCode, QProcess::ExitStatus status)
144 if (status != QProcess::NormalExit || exitCode != 0) {
145 qCWarning(QT_BT_BLUEZ) <<
"SDP scan failure" << status << exitCode;
148 QBluetoothServiceDiscoveryAgent::tr(
"Unable to perform SDP scan"),
173 }
while (
start != -1);
180 const QString &errorDescription,
186 qCWarning(QT_BT_BLUEZ) <<
"SDP search failed for"
202 bool serviceClassMatched =
false;
207 serviceClassMatched =
true;
212 if (!serviceNameMatched && !serviceClassMatched)
224 if (
id.minimumSize() == 16) {
228 QBluetoothServiceDiscoveryAgent::tr(
"Custom Service"));
238 if (!isDuplicatedService(serviceInfo)) {
254void QBluetoothServiceDiscoveryAgentPrivate::stop()
263 if (sdpScannerProcess) {
264 if (sdpScannerProcess->state() != QProcess::NotRunning) {
265 sdpScannerProcess->kill();
266 sdpScannerProcess->waitForFinished();
277 QXmlStreamReader
xml(xmlRecord);
282 while (!
xml.atEnd()) {
285 if (
xml.tokenType() == QXmlStreamReader::StartElement &&
290 if (
xml.readNextStartElement()) {
301void QBluetoothServiceDiscoveryAgentPrivate::performMinimalServiceDiscovery(
const QBluetoothAddress &deviceAddress)
303 if (foundHostAdapterPath.isEmpty()) {
311 reply.waitForFinished();
312 if (
reply.isError()) {
339 if (!uuidStrings.isEmpty())
367 serviceInfo.
setServiceName(QBluetoothServiceDiscoveryAgent::tr(
"Custom Service"));
392 if (!isDuplicatedService(serviceInfo)) {
395 << serviceInfo.serviceName();
396 emit q->serviceDiscovered(serviceInfo);
403QVariant QBluetoothServiceDiscoveryAgentPrivate::readAttributeValue(QXmlStreamReader &
xml)
405 auto skippingCurrentElementByDefault =
qScopeGuard([&] {
xml.skipCurrentElement(); });
425 if (
value.size() == 6) {
428 }
else if (
value.size() == 10) {
440 return value.toString();
444 skippingCurrentElementByDefault.dismiss();
446 while (
xml.readNextStartElement()) {
451 return QVariant::fromValue<QBluetoothServiceInfo::Sequence>(sequence);
453 qCWarning(QT_BT_BLUEZ) <<
"unknown attribute type"
QString findAdapterForAddress(const QBluetoothAddress &wantedAddress, bool *ok=nullptr)
QT_BEGIN_NAMESPACE void initializeBluez5()
QBluetoothAddress address() const
Returns the address of the device.
QBluetoothAddress deviceAddress
void setDiscoveryState(DiscoveryState s)
~QBluetoothServiceDiscoveryAgentPrivate()
QList< QBluetoothServiceInfo > discoveredServices
void _q_serviceDiscoveryFinished()
QBluetoothServiceDiscoveryAgentPrivate(QBluetoothServiceDiscoveryAgent *qp, const QBluetoothAddress &deviceAdapter)
DiscoveryState discoveryState()
QList< QBluetoothDeviceInfo > discoveredDevices
QBluetoothServiceDiscoveryAgent::Error error
QBluetoothAddress m_deviceAdapterAddress
QBluetoothServiceDiscoveryAgent::DiscoveryMode DiscoveryMode()
Error
This enum describes errors that can occur during service discovery.
@ InvalidBluetoothAdapterError
void setServiceUuid(const QBluetoothUuid &uuid)
This is a convenience function.
QBluetoothUuid serviceUuid() const
This is a convenience function.
void setDevice(const QBluetoothDeviceInfo &info)
Sets the Bluetooth device that provides this service to device.
void setAttribute(quint16 attributeId, const QVariant &value)
Sets the attribute identified by attributeId to value.
bool isValid() const
Returns true if the QBluetoothServiceInfo object is valid, otherwise returns false.
QVariant attribute(quint16 attributeId) const
Returns the value of the attribute attributeId.
void setServiceName(const QString &name)
This is a convenience function.
QList< QBluetoothUuid > serviceClassUuids() const
Returns a list of UUIDs describing the service classes that this service conforms to.
QString serviceName() const
This is a convenience function.
int minimumSize() const
Returns the minimum size in bytes that this UUID can be represented in.
ServiceClassUuid
This enum is a convienience type for Bluetooth service class and profile UUIDs.
static QString serviceClassToString(ServiceClassUuid uuid)
Returns a human-readable and translated name for the given service class represented by uuid.
constexpr QByteArrayView sliced(qsizetype pos) const
static QByteArray fromHex(const QByteArray &hexEncoded)
Returns a decoded copy of the hex encoded array hexEncoded.
static QByteArray fromBase64(const QByteArray &base64, Base64Options options=Base64Encoding)
static QDBusConnection systemBus()
Returns a QDBusConnection object opened with the system bus.
\inmodule QtCore \reentrant
static QString path(LibraryPath p)
bool isEmpty() const noexcept
bool removeOne(const AT &t)
const_reference at(qsizetype i) const noexcept
void append(parameter_type t)
T value(const Key &key, const T &defaultValue=T()) const
const_iterator constBegin() const
const_iterator constEnd() const
NetworkError error() const
Returns the error that was found during the processing of this request.
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
bool isNull() const noexcept
Returns true if this is the null UUID {00000000-0000-0000-0000-000000000000}; otherwise returns false...
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
QSet< QString >::iterator it
QList< QVariant > arguments
Combined button and popup list for selecting options.
constexpr QBindableInterface iface
constexpr QStaticByteArrayMatcher< N > qMakeStaticByteArrayMatcher(const char(&pattern)[N]) noexcept
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
#define Q_ARG(Type, data)
GLsizei const GLfloat * v
[13]
GLuint GLuint64EXT address
GLdouble GLdouble GLdouble GLdouble q
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static QStringList toStringList(const QJsonArray &jsonArray)
unsigned long long quint64
static const auto matcher
[0]
QNetworkAccessManager manager
char * toString(const MyType &t)
[31]
bool contains(const AT &t) const noexcept