1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 BlackBerry Limited. All rights reserved.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtBluetooth module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "qdeclarativebluetoothdiscoverymodel_p.h"
42
43#include <QPixmap>
44
45#include <QtCore/QLoggingCategory>
46#include <QtBluetooth/QBluetoothDeviceInfo>
47#include <QtBluetooth/QBluetoothAddress>
48
49#include "qdeclarativebluetoothservice_p.h"
50
51/*!
52 \qmltype BluetoothDiscoveryModel
53 \instantiates QDeclarativeBluetoothDiscoveryModel
54 \inqmlmodule QtBluetooth
55 \since 5.2
56 \brief Enables searching for the Bluetooth devices and services in
57 range.
58
59 BluetoothDiscoveryModel provides a model of connectable services. The
60 contents of the model can be filtered by UUID allowing discovery to be
61 limited to a single service such as a game.
62
63 The model roles provided by BluetoothDiscoveryModel are
64 \c service, \c name, \c remoteAddress and \c deviceName. The meaning of the roles
65 changes based on the current \l discoveryMode.
66
67 \table
68 \header
69 \li Model role
70 \li Device Discovery
71 \li Service Discovery
72 \row
73 \li \c name
74 \li The device's name and address.
75 \li The service name and the name of the device offering the service. If the device name is empty the devices address will be used.
76 \row
77 \li \c deviceName
78 \li The name of the device.
79 \li The name of the device offering the service.
80 \row
81 \li \c service
82 \li The role is undefined in this mode.
83 \li The \l BluetoothService object describing the discovered service.
84 \row
85 \li \c remoteAddress
86 \li The address of the found device.
87 \li The address of the device offering the service.
88 \endtable
89
90 \sa QBluetoothServiceDiscoveryAgent
91*/
92
93Q_DECLARE_LOGGING_CATEGORY(QT_BT_QML)
94
95class QDeclarativeBluetoothDiscoveryModelPrivate
96{
97public:
98 QDeclarativeBluetoothDiscoveryModelPrivate()
99 :
100 m_error(QDeclarativeBluetoothDiscoveryModel::NoError),
101 m_discoveryMode(QDeclarativeBluetoothDiscoveryModel::MinimalServiceDiscovery),
102 m_running(false),
103 m_runningRequested(true),
104 m_componentCompleted(false),
105 m_currentState(QDeclarativeBluetoothDiscoveryModel::IdleAction),
106 m_nextState(QDeclarativeBluetoothDiscoveryModel::IdleAction),
107 m_wasDirectDeviceAgentCancel(false)
108 {
109 }
110 ~QDeclarativeBluetoothDiscoveryModelPrivate()
111 {
112 if (m_deviceAgent)
113 delete m_deviceAgent;
114
115 if (m_serviceAgent)
116 delete m_serviceAgent;
117
118 qDeleteAll(c: m_services);
119 }
120
121 QBluetoothServiceDiscoveryAgent *m_serviceAgent = nullptr;
122 QBluetoothDeviceDiscoveryAgent *m_deviceAgent = nullptr;
123
124 QDeclarativeBluetoothDiscoveryModel::Error m_error;
125 QList<QDeclarativeBluetoothService *> m_services;
126 QList<QBluetoothDeviceInfo> m_devices;
127 QDeclarativeBluetoothDiscoveryModel::DiscoveryMode m_discoveryMode;
128 QString m_uuid;
129 bool m_running;
130 bool m_runningRequested;
131 bool m_componentCompleted;
132 QString m_remoteAddress;
133
134 QDeclarativeBluetoothDiscoveryModel::Action m_currentState;
135 QDeclarativeBluetoothDiscoveryModel::Action m_nextState;
136 bool m_wasDirectDeviceAgentCancel;
137};
138
139QDeclarativeBluetoothDiscoveryModel::QDeclarativeBluetoothDiscoveryModel(QObject *parent) :
140 QAbstractListModel(parent),
141 d(new QDeclarativeBluetoothDiscoveryModelPrivate)
142{
143 d->m_deviceAgent = new QBluetoothDeviceDiscoveryAgent(this);
144 connect(sender: d->m_deviceAgent, signal: &QBluetoothDeviceDiscoveryAgent::deviceDiscovered,
145 receiver: this, slot: QOverload<const QBluetoothDeviceInfo&>::of(ptr: &QDeclarativeBluetoothDiscoveryModel::deviceDiscovered));
146 connect(sender: d->m_deviceAgent, signal: &QBluetoothDeviceDiscoveryAgent::finished,
147 receiver: this, slot: &QDeclarativeBluetoothDiscoveryModel::finishedDiscovery);
148 connect(sender: d->m_deviceAgent, signal: &QBluetoothDeviceDiscoveryAgent::canceled,
149 receiver: this, slot: &QDeclarativeBluetoothDiscoveryModel::finishedDiscovery);
150 connect(sender: d->m_deviceAgent,
151 signal: QOverload<QBluetoothDeviceDiscoveryAgent::Error>::of(ptr: &QBluetoothDeviceDiscoveryAgent::error),
152 receiver: this,
153 slot: &QDeclarativeBluetoothDiscoveryModel::errorDeviceDiscovery);
154 d->m_deviceAgent->setObjectName(QStringLiteral("DeviceDiscoveryAgent"));
155
156 d->m_serviceAgent = new QBluetoothServiceDiscoveryAgent(this);
157 connect(sender: d->m_serviceAgent, signal: &QBluetoothServiceDiscoveryAgent::serviceDiscovered,
158 receiver: this, slot: QOverload<const QBluetoothServiceInfo&>::of(ptr: &QDeclarativeBluetoothDiscoveryModel::serviceDiscovered));
159 connect(sender: d->m_serviceAgent, signal: &QBluetoothServiceDiscoveryAgent::finished,
160 receiver: this, slot: &QDeclarativeBluetoothDiscoveryModel::finishedDiscovery);
161 connect(sender: d->m_serviceAgent, signal: &QBluetoothServiceDiscoveryAgent::canceled,
162 receiver: this, slot: &QDeclarativeBluetoothDiscoveryModel::finishedDiscovery);
163 connect(sender: d->m_serviceAgent,
164 signal: QOverload<QBluetoothServiceDiscoveryAgent::Error>::of(ptr: &QBluetoothServiceDiscoveryAgent::error),
165 receiver: this,
166 slot: &QDeclarativeBluetoothDiscoveryModel::errorDiscovery);
167 d->m_serviceAgent->setObjectName(QStringLiteral("ServiceDiscoveryAgent"));
168}
169
170QDeclarativeBluetoothDiscoveryModel::~QDeclarativeBluetoothDiscoveryModel()
171{
172 delete d;
173}
174void QDeclarativeBluetoothDiscoveryModel::componentComplete()
175{
176 d->m_componentCompleted = true;
177 if (d->m_runningRequested)
178 setRunning(true);
179}
180
181void QDeclarativeBluetoothDiscoveryModel::errorDiscovery(QBluetoothServiceDiscoveryAgent::Error error)
182{
183 switch (error) {
184 case QBluetoothServiceDiscoveryAgent::InvalidBluetoothAdapterError:
185 d->m_error = QDeclarativeBluetoothDiscoveryModel::InvalidBluetoothAdapterError; break;
186 case QBluetoothServiceDiscoveryAgent::NoError:
187 d->m_error = QDeclarativeBluetoothDiscoveryModel::NoError; break;
188 case QBluetoothServiceDiscoveryAgent::InputOutputError:
189 d->m_error = QDeclarativeBluetoothDiscoveryModel::InputOutputError; break;
190 case QBluetoothServiceDiscoveryAgent::PoweredOffError:
191 d->m_error = QDeclarativeBluetoothDiscoveryModel::PoweredOffError; break;
192 case QBluetoothServiceDiscoveryAgent::UnknownError:
193 d->m_error = QDeclarativeBluetoothDiscoveryModel::UnknownError; break;
194 }
195
196 emit errorChanged();
197}
198
199void QDeclarativeBluetoothDiscoveryModel::errorDeviceDiscovery(QBluetoothDeviceDiscoveryAgent::Error error)
200{
201 d->m_error = static_cast<QDeclarativeBluetoothDiscoveryModel::Error>(error);
202 emit errorChanged();
203
204 //QBluetoothDeviceDiscoveryAgent::finished() signal is not emitted in case of an error
205 //Note that this behavior is different from QBluetoothServiceDiscoveryAgent.
206 //This resets the models running flag.
207 finishedDiscovery();
208}
209
210void QDeclarativeBluetoothDiscoveryModel::clearModel()
211{
212 beginResetModel();
213 qDeleteAll(c: d->m_services);
214 d->m_services.clear();
215 d->m_devices.clear();
216 endResetModel();
217}
218
219/*!
220 \qmlproperty enumeration BluetoothDiscoveryModel::error
221
222 This property holds the last error reported during discovery.
223 \table
224 \header \li Property \li Description
225 \row \li \c BluetoothDiscoveryModel.NoError
226 \li No error occurred.
227 \row \li \c BluetoothDiscoveryModel.InputOutputError
228 \li An IO failure occurred during device discovery
229 \row \li \c BluetoothDiscoveryModel.PoweredOffError
230 \li The bluetooth device is not powered on.
231 \row \li \c BluetoothDiscoveryModel.InvalidBluetoothAdapterError
232 \li There is no default Bluetooth device to perform the
233 service discovery. The model always uses the local default adapter.
234 Specifying a default adapter is not possible. If that's required,
235 \l QBluetoothServiceDiscoveryAgent should be directly used. This
236 value was introduced by Qt 5.4.
237 \row \li \c BluetoothDiscoveryModel.UnknownError
238 \li An unknown error occurred.
239 \endtable
240
241 This property is read-only.
242 */
243QDeclarativeBluetoothDiscoveryModel::Error QDeclarativeBluetoothDiscoveryModel::error() const
244{
245 return d->m_error;
246}
247
248int QDeclarativeBluetoothDiscoveryModel::rowCount(const QModelIndex &parent) const
249{
250 Q_UNUSED(parent);
251 if (discoveryMode() == DeviceDiscovery)
252 return d->m_devices.count();
253 else
254 return d->m_services.count();
255}
256
257QVariant QDeclarativeBluetoothDiscoveryModel::data(const QModelIndex &index, int role) const
258{
259 if (!index.isValid() || index.row() < 0)
260 return QVariant();
261
262 if (discoveryMode() != DeviceDiscovery) {
263 if (index.row() >= d->m_services.count()){
264 qCWarning(QT_BT_QML) << "index out of bounds";
265 return QVariant();
266 }
267
268 QDeclarativeBluetoothService *service = d->m_services.value(i: index.row());
269
270 switch (role) {
271 case Name: {
272 QString label = service->deviceName();
273 if (label.isEmpty())
274 label += service->deviceAddress();
275 else
276 label+= QStringLiteral(":");
277 label += QStringLiteral(" ") + service->serviceName();
278 return label;
279 }
280 case ServiceRole:
281 return QVariant::fromValue(value: service);
282 case DeviceName:
283 return service->deviceName();
284 case RemoteAddress:
285 return service->deviceAddress();
286 }
287 } else {
288 if (index.row() >= d->m_devices.count()) {
289 qCWarning(QT_BT_QML) << "index out of bounds";
290 return QVariant();
291 }
292
293 QBluetoothDeviceInfo device = d->m_devices.value(i: index.row());
294 switch (role) {
295 case Name:
296 return (device.name() + QStringLiteral(" (") + device.address().toString() + QStringLiteral(")"));
297 case ServiceRole:
298 break;
299 case DeviceName:
300 return device.name();
301 case RemoteAddress:
302 return device.address().toString();
303 }
304 }
305
306 return QVariant();
307}
308
309QHash<int,QByteArray> QDeclarativeBluetoothDiscoveryModel::roleNames() const
310{
311 return {{Name, "name"},
312 {ServiceRole, "service"},
313 {RemoteAddress, "remoteAddress"},
314 {DeviceName, "deviceName"}};
315}
316
317/*!
318 \qmlsignal BluetoothDiscoveryModel::serviceDiscovered(BluetoothService service)
319
320 This signal is emitted when a new service is discovered. The \a service
321 parameter contains the service details.
322
323 The corresponding handler is \c onServiceDiscovered.
324
325 \sa BluetoothService
326 */
327
328void QDeclarativeBluetoothDiscoveryModel::serviceDiscovered(const QBluetoothServiceInfo &service)
329{
330 //qDebug() << "service discovered";
331
332 QDeclarativeBluetoothService *bs = new QDeclarativeBluetoothService(service, this);
333 QDeclarativeBluetoothService *current = nullptr;
334 for (int i = 0; i < d->m_services.count(); i++) {
335 current = d->m_services.at(i);
336 if (bs->deviceAddress() == current->deviceAddress()
337 && bs->serviceName() == current->serviceName()
338 && bs->serviceUuid() == current->serviceUuid()) {
339 delete bs;
340 return;
341 }
342 }
343
344 beginInsertRows(parent: QModelIndex(),first: d->m_services.count(), last: d->m_services.count());
345 d->m_services.append(t: bs);
346 endInsertRows();
347 emit serviceDiscovered(service: bs);
348}
349
350/*!
351 \qmlsignal BluetoothDiscoveryModel::deviceDiscovered(string device)
352
353 This signal is emitted when a new device is discovered. \a device contains
354 the Bluetooth address of the discovered device.
355
356 The corresponding handler is \c onDeviceDiscovered.
357 */
358
359void QDeclarativeBluetoothDiscoveryModel::deviceDiscovered(const QBluetoothDeviceInfo &device)
360{
361 //qDebug() << "Device discovered" << device.address().toString() << device.name();
362
363 beginInsertRows(parent: QModelIndex(),first: d->m_devices.count(), last: d->m_devices.count());
364 d->m_devices.append(t: device);
365 endInsertRows();
366 emit deviceDiscovered(device: device.address().toString());
367}
368
369void QDeclarativeBluetoothDiscoveryModel::finishedDiscovery()
370{
371 QDeclarativeBluetoothDiscoveryModel::Action previous = d->m_currentState;
372 d->m_currentState = IdleAction;
373
374 switch (previous) {
375 case IdleAction:
376 // last transition didn't even start
377 // can happen when start() or stop() immediately returned
378 // usually this happens within a current transitionToNextAction call
379 break;
380 case StopAction:
381 qCDebug(QT_BT_QML) << "Agent cancel detected";
382 transitionToNextAction();
383 break;
384 default: // all other
385 qCDebug(QT_BT_QML) << "Discovery finished" << sender()->objectName();
386
387 //TODO Qt6 This hack below is once again due to the pendingCancel logic
388 // because QBluetoothDeviceDiscoveryAgent::isActive() is not reliable.
389 // In toggleStartStop() we need to know whether the stop() is delayed or immediate.
390 // isActive() cannot be used. Hence we have to wait for the canceled() signal.
391 // Android, WinRT and Bluez5 are immediate, Bluez4 is always delayed.
392 // The immediate case is what we catch here.
393 if (sender() == d->m_deviceAgent && d->m_nextState == StopAction) {
394 d->m_wasDirectDeviceAgentCancel = true;
395 return;
396 }
397 setRunning(false);
398 break;
399 }
400}
401
402/*!
403 \qmlproperty enumeration BluetoothDiscoveryModel::discoveryMode
404
405 Sets the discovery mode. The discovery mode has to be set before the discovery is started
406 \table
407 \header \li Property \li Description
408 \row \li \c BluetoothDiscoveryModel.FullServiceDiscovery
409 \li Starts a full discovery of all services of all devices in range.
410 \row \li \c BluetoothDiscoveryModel.MinimalServiceDiscovery
411 \li (Default) Starts a minimal discovery of all services of all devices in range. A minimal discovery is
412 faster but only guarantees the device and UUID information to be correct.
413 \row \li \c BluetoothDiscoveryModel.DeviceDiscovery
414 \li Discovers only devices in range. The service role will be 0 for any model item.
415 \endtable
416*/
417
418QDeclarativeBluetoothDiscoveryModel::DiscoveryMode QDeclarativeBluetoothDiscoveryModel::discoveryMode() const
419{
420 return d->m_discoveryMode;
421}
422
423void QDeclarativeBluetoothDiscoveryModel::setDiscoveryMode(DiscoveryMode discovery)
424{
425 d->m_discoveryMode = discovery;
426 emit discoveryModeChanged();
427}
428
429
430void QDeclarativeBluetoothDiscoveryModel::updateNextAction(Action action)
431{
432 qCDebug(QT_BT_QML) << "New action queue:"
433 << d->m_currentState << d->m_nextState << action;
434
435 if (action == IdleAction)
436 return;
437
438 switch (d->m_nextState) {
439 case IdleAction:
440 d->m_nextState = action;
441 return;
442 case StopAction:
443 qWarning() << "Invalid Stop state when processing new action" << action;
444 return;
445 case DeviceDiscoveryAction:
446 case MinimalServiceDiscoveryAction:
447 case FullServiceDiscoveryAction:
448 if (action == StopAction) // cancel out previous start call
449 d->m_nextState = IdleAction;
450 else
451 qWarning() << "Ignoring new DMF state while another DMF state is scheduled.";
452 return;
453 }
454}
455
456void QDeclarativeBluetoothDiscoveryModel::transitionToNextAction()
457{
458 qCDebug(QT_BT_QML) << "Before transition change:" << d->m_currentState << d->m_nextState;
459 bool isRunning;
460 switch (d->m_currentState) {
461 case IdleAction:
462 switch (d->m_nextState) {
463 case IdleAction: break; // nothing to do
464 case StopAction: d->m_nextState = IdleAction; break; // clear, nothing to do
465 case DeviceDiscoveryAction:
466 case MinimalServiceDiscoveryAction:
467 case FullServiceDiscoveryAction:
468 Action temp = d->m_nextState;
469 clearModel();
470 isRunning = toggleStartStop(action: d->m_nextState);
471 d->m_nextState = IdleAction;
472 if (isRunning) {
473 d->m_currentState = temp;
474 } else {
475 if (temp != DeviceDiscoveryAction )
476 errorDiscovery(error: d->m_serviceAgent->error());
477 d->m_running = false;
478 }
479 }
480 break;
481 case StopAction:
482 break; // do nothing, StopAction cleared by finished()/cancelled()/error() handlers
483 case DeviceDiscoveryAction:
484 case MinimalServiceDiscoveryAction:
485 case FullServiceDiscoveryAction:
486 switch (d->m_nextState) {
487 case IdleAction: break;
488 case StopAction:
489 isRunning = toggleStartStop(action: StopAction);
490 (isRunning) ? d->m_currentState = StopAction : d->m_currentState = IdleAction;
491 d->m_nextState = IdleAction;
492 break;
493 default:
494 Q_ASSERT(false); // should never happen
495 break;
496 }
497
498 break;
499 }
500
501 qCDebug(QT_BT_QML) << "After transition change:" << d->m_currentState << d->m_nextState;
502}
503
504// Returns true if the agent is active
505// this can be used to detect whether the agent still needs time to
506// perform the requested action.
507bool QDeclarativeBluetoothDiscoveryModel::toggleStartStop(Action action)
508{
509 Q_ASSERT(action != IdleAction);
510 switch (action) {
511 case DeviceDiscoveryAction:
512 Q_ASSERT(!d->m_deviceAgent->isActive() && !d->m_serviceAgent->isActive());
513 d->m_deviceAgent->start();
514 return d->m_deviceAgent->isActive();
515 case MinimalServiceDiscoveryAction:
516 case FullServiceDiscoveryAction:
517 Q_ASSERT(!d->m_deviceAgent->isActive() && !d->m_serviceAgent->isActive());
518 d->m_serviceAgent->setRemoteAddress(QBluetoothAddress(d->m_remoteAddress));
519 d->m_serviceAgent->clear();
520
521 if (!d->m_uuid.isEmpty())
522 d->m_serviceAgent->setUuidFilter(QBluetoothUuid(d->m_uuid));
523
524 if (action == FullServiceDiscoveryAction) {
525 qCDebug(QT_BT_QML) << "Full Discovery";
526 d->m_serviceAgent->start(mode: QBluetoothServiceDiscoveryAgent::FullDiscovery);
527 } else {
528 qCDebug(QT_BT_QML) << "Minimal Discovery";
529 d->m_serviceAgent->start(mode: QBluetoothServiceDiscoveryAgent::MinimalDiscovery);
530 }
531 return d->m_serviceAgent->isActive();
532 case StopAction:
533 Q_ASSERT(d->m_currentState != StopAction && d->m_currentState != IdleAction);
534 if (d->m_currentState == DeviceDiscoveryAction) {
535 d->m_deviceAgent->stop();
536
537 // TODO Qt6 Crude hack below
538 // cannot use isActive() below due to pendingCancel logic
539 // we always wait for canceled() signal coming through or check
540 // for directly invoked cancel() response caused by stop() above
541 bool stillActive = !d->m_wasDirectDeviceAgentCancel;
542 d->m_wasDirectDeviceAgentCancel = false;
543 return stillActive;
544 } else {
545 d->m_serviceAgent->stop();
546 return d->m_serviceAgent->isActive();
547 }
548 default:
549 return true;
550 }
551}
552
553
554/*!
555 \qmlproperty bool BluetoothDiscoveryModel::running
556
557 This property starts or stops discovery. A restart of the discovery process
558 requires setting this property to \c false and subsequently to \c true again.
559
560*/
561
562bool QDeclarativeBluetoothDiscoveryModel::running() const
563{
564 return d->m_running;
565}
566
567void QDeclarativeBluetoothDiscoveryModel::setRunning(bool running)
568{
569 if (!d->m_componentCompleted) {
570 d->m_runningRequested = running;
571 return;
572 }
573
574 if (d->m_running == running)
575 return;
576
577 d->m_running = running;
578
579 Action nextAction = IdleAction;
580 if (running) {
581 if (discoveryMode() == MinimalServiceDiscovery)
582 nextAction = MinimalServiceDiscoveryAction;
583 else if (discoveryMode() == FullServiceDiscovery)
584 nextAction = FullServiceDiscoveryAction;
585 else
586 nextAction = DeviceDiscoveryAction;
587 } else {
588 nextAction = StopAction;
589 }
590
591 Q_ASSERT(nextAction != IdleAction);
592 updateNextAction(action: nextAction);
593 transitionToNextAction();
594
595 qCDebug(QT_BT_QML) << "Running state:" << d->m_running;
596 emit runningChanged();
597}
598
599/*!
600 \qmlproperty string BluetoothDiscoveryModel::uuidFilter
601
602 This property holds an optional UUID filter. A UUID can be used to return only
603 matching services. 16 bit, 32 bit or 128 bit UUIDs can be used. The string format
604 is same as the format of QUuid.
605
606 \sa QBluetoothUuid
607 \sa QUuid
608 */
609
610
611QString QDeclarativeBluetoothDiscoveryModel::uuidFilter() const
612{
613 return d->m_uuid;
614}
615
616void QDeclarativeBluetoothDiscoveryModel::setUuidFilter(QString uuid)
617{
618 if (uuid == d->m_uuid)
619 return;
620
621 QBluetoothUuid qbuuid(uuid);
622 if (qbuuid.isNull()) {
623 qCWarning(QT_BT_QML) << "Invalid UUID providded " << uuid;
624 return;
625 }
626 d->m_uuid = uuid;
627 emit uuidFilterChanged();
628}
629
630/*!
631 \qmlproperty string BluetoothDiscoveryModel::remoteAddress
632
633 This property holds an optional bluetooth address for a remote bluetooth device.
634 Only services on this remote device will be discovered. It has no effect if
635 an invalid bluetooth address was set or if the property was set after the discovery
636 was started.
637
638 The property is ignored if device discovery is selected.
639
640*/
641
642QString QDeclarativeBluetoothDiscoveryModel::remoteAddress()
643{
644 return d->m_remoteAddress;
645}
646
647void QDeclarativeBluetoothDiscoveryModel::setRemoteAddress(QString address)
648{
649 d->m_remoteAddress = address;
650 emit remoteAddressChanged();
651}
652

source code of qtconnectivity/src/imports/bluetooth/qdeclarativebluetoothdiscoverymodel.cpp