1
/****************************************************************************
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the QtBluetooth module of the Qt Toolkit.
8
** $QT_BEGIN_LICENSE:LGPL$
9
** Commercial License Usage
10
** Licensees holding valid commercial Qt licenses may use this file in
11
** accordance with the commercial license agreement provided with the
12
** Software or, alternatively, in accordance with the terms contained in
13
** a written agreement between you and Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
17
** GNU Lesser General Public License Usage
18
** Alternatively, this file may be used under the terms of the GNU Lesser
19
** General Public License version 2.1 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
42
#include "qdeclarativebluetoothservice_p.h"
44
#include <qbluetoothdeviceinfo.h>
45
#include <QtBluetooth/QBluetoothSocket>
46
#include <QtBluetooth/QBluetoothAddress>
47
#include <ql2capserver.h>
48
#include <qrfcommserver.h>
52
/* ==================== QDeclarativeBluetoothService ======================= */
55
\qmltype BluetoothService
56
\instantiates QDeclarativeBluetoothService
57
\inqmlmodule QtBluetooth 5.0
58
\brief Provides information about a particular Bluetooth service.
63
The BluetoothService type was introduced in \b{QtBluetooth 5.0}.
65
It allows a QML project to get information about a remote service, or describe a service
66
for a BluetoothSocket to connect to.
70
\qmlsignal BluetoothService::detailsChanged()
72
This handler is called when any of the following properties changes:
77
\li serviceDescription
85
class QDeclarativeBluetoothServicePrivate
88
QDeclarativeBluetoothServicePrivate()
89
: m_componentComplete(false),
90
m_service(0), m_port(0),
91
m_needsRegistration(false),
97
~QDeclarativeBluetoothServicePrivate()
104
bool m_componentComplete;
105
QBluetoothServiceInfo *m_service;
108
QString m_description;
111
bool m_needsRegistration;
116
QDeclarativeBluetoothService::QDeclarativeBluetoothService(QObject *parent) :
119
d = new QDeclarativeBluetoothServicePrivate;
122
QDeclarativeBluetoothService::QDeclarativeBluetoothService(const QBluetoothServiceInfo &service, QObject *parent)
125
d = new QDeclarativeBluetoothServicePrivate;
126
d->m_service = new QBluetoothServiceInfo(service);
129
QDeclarativeBluetoothService::~QDeclarativeBluetoothService()
134
void QDeclarativeBluetoothService::componentComplete()
136
d->m_componentComplete = true;
138
if (d->m_needsRegistration)
144
\qmlproperty string BluetoothService::deviceName
146
This property holds the name of the remote device. Changing this property emits the
147
detailsChanged signal.
150
QString QDeclarativeBluetoothService::deviceName() const
155
return d->m_service->device().name();
159
\qmlproperty string BluetoothService::deviceAddress
161
This property holds the remote device's MAC address. It must be a valid address to
162
connect to a remote device using a Bluetooth socket. Changing this property emits the
163
detailsChanged signal.
167
QString QDeclarativeBluetoothService::deviceAddress() const
172
return d->m_service->device().address().toString();
175
void QDeclarativeBluetoothService::setDeviceAddress(QString address)
178
d->m_service = new QBluetoothServiceInfo();
180
QBluetoothAddress a(address);
181
QBluetoothDeviceInfo device(a, QString(), QBluetoothDeviceInfo::ComputerDevice);
182
d->m_service->setDevice(device);
186
\qmlproperty string BluetoothService::serviceName
188
This property holds the name of the remote service if available. Changing this property emits the
189
detailsChanged signal.
192
QString QDeclarativeBluetoothService::serviceName() const
197
if (!d->m_name.isEmpty())
200
return d->m_service->serviceName();
203
void QDeclarativeBluetoothService::setServiceName(QString name)
210
\qmlproperty string BluetoothService::serviceDescription
212
This property holds the description provided by the remote service. Changing this property emits the
213
detailsChanged signal.
215
QString QDeclarativeBluetoothService::serviceDescription() const
220
if (!d->m_description.isEmpty())
223
return d->m_service->serviceDescription();
226
void QDeclarativeBluetoothService::setServiceDescription(QString description)
228
d->m_description = description;
229
emit detailsChanged();
233
\qmlproperty string BluetoothService::serviceProtocol
235
This property holds the protocol used for the service. Can be the string,
236
"l2cap" or "rfcomm". Changing this property emits the
237
detailsChanged signal.
241
QString QDeclarativeBluetoothService::serviceProtocol() const
243
if (!d->m_protocol.isEmpty())
244
return d->m_protocol;
249
if (d->m_service->socketProtocol() == QBluetoothServiceInfo::L2capProtocol)
250
return QLatin1String("l2cap");
251
if (d->m_service->socketProtocol() == QBluetoothServiceInfo::RfcommProtocol)
252
return QLatin1String("rfcomm");
254
return QLatin1String("unknown");
257
void QDeclarativeBluetoothService::setServiceProtocol(QString protocol)
259
if (protocol != "rfcomm" && protocol != "l2cap")
260
qWarning() << "Invalid protocol" << protocol;
262
d->m_protocol = protocol;
263
emit detailsChanged();
267
\qmlproperty string BluetoothService::serviceUuid
269
This property holds the UUID of the remote service. Service UUID or port,
270
and the address must be set to connect to a remote service. If UUID and
271
port are set, the port is used. The UUID takes longer to connect as
272
service discovery must be initiated to discover the port value. Changing
273
this property emits the detailsChanged signal.
277
QString QDeclarativeBluetoothService::serviceUuid() const
279
if (!d->m_uuid.isEmpty())
285
return d->m_service->attribute(QBluetoothServiceInfo::ServiceId).toString();
288
void QDeclarativeBluetoothService::setServiceUuid(QString uuid)
292
d->m_service = new QBluetoothServiceInfo();
293
d->m_service->setAttribute(QBluetoothServiceInfo::ServiceId, QBluetoothUuid(uuid));
295
emit detailsChanged();
299
\qmlproperty int BluetoothService::servicePort
301
This property holds the port value for the remote service. Bluetooth does not
302
use well defined port values, so port values should not be stored and used
303
later. Connecting using UUID is much more consistent. Changing this property emits the
304
detailsChanged signal.
306
qint32 QDeclarativeBluetoothService::servicePort() const
314
if (d->m_service->serverChannel() > 0)
315
return d->m_service->serverChannel();
316
if (d->m_service->protocolServiceMultiplexer() > 0)
317
return d->m_service->protocolServiceMultiplexer();
322
void QDeclarativeBluetoothService::setServicePort(qint32 port)
324
if (d->m_port != port){
328
emit detailsChanged();
333
\qmlproperty string BluetoothService::registered
335
This property holds the registration/publication status of the service. If true, the service
336
is published during service discovery.
339
bool QDeclarativeBluetoothService::isRegistered() const
344
return d->m_service->isRegistered();
348
int QDeclarativeBluetoothServicePrivate::listen() {
350
if (m_protocol == "l2cap") {
351
QL2capServer *server = new QL2capServer();
353
server->setMaxPendingConnections(1);
354
server->listen(QBluetoothAddress(), m_port);
355
m_port = server->serverPort();
358
else if (m_protocol == "rfcomm") {
359
QRfcommServer *server = new QRfcommServer();
361
server->setMaxPendingConnections(1);
362
server->listen(QBluetoothAddress(), m_port);
363
m_port = server->serverPort();
367
qDebug() << "Unknown protocol, can't make service" << m_protocol;
374
void QDeclarativeBluetoothService::setRegistered(bool registered)
377
d->m_needsRegistration = registered;
379
if (!d->m_componentComplete) {
386
d->m_service->unregisterService();
387
emit registeredChanged();
391
d->m_service = new QBluetoothServiceInfo();
399
connect(d->m_listen, SIGNAL(newConnection()), this, SLOT(new_connection()));
402
d->m_service->setAttribute(QBluetoothServiceInfo::ServiceRecordHandle, (uint)0x00010010);
404
// QBluetoothServiceInfo::Sequence classId;
405
//// classId << QVariant::fromVhttp://theunderstatement.com/alue(QBluetoothUuid(serviceUuid));
406
// classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
407
// d->m_service->setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
409
d->m_service->setAttribute(QBluetoothServiceInfo::ServiceName, d->m_name);
410
d->m_service->setAttribute(QBluetoothServiceInfo::ServiceDescription,
413
d->m_service->setServiceUuid(QBluetoothUuid(d->m_uuid));
415
qDebug() << "name/uuid" << d->m_name << d->m_uuid << d->m_port;
417
d->m_service->setAttribute(QBluetoothServiceInfo::BrowseGroupList,
418
QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
420
QBluetoothServiceInfo::Sequence protocolDescriptorList;
421
QBluetoothServiceInfo::Sequence protocol;
423
qDebug() << "Port" << d->m_port;
425
if (d->m_protocol == "l2cap") {
426
protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap))
427
<< QVariant::fromValue(quint16(d->m_port));
428
protocolDescriptorList.append(QVariant::fromValue(protocol));
430
else if (d->m_protocol == "rfcomm") {
431
protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
432
<< QVariant::fromValue(quint8(d->m_port));
433
protocolDescriptorList.append(QVariant::fromValue(protocol));
436
qWarning() << "No protocol specified for bluetooth service";
438
d->m_service->setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList,
439
protocolDescriptorList);
441
if (d->m_service->registerService()) {
442
qDebug() << "registered";
443
emit registeredChanged();
446
qDebug() << "Failed";
450
QBluetoothServiceInfo *QDeclarativeBluetoothService::serviceInfo() const
455
void QDeclarativeBluetoothService::new_connection()
460
QDeclarativeBluetoothSocket *QDeclarativeBluetoothService::nextClient()
462
QL2capServer *server = qobject_cast<QL2capServer *>(d->m_listen);
464
if (server->hasPendingConnections()) {
465
QBluetoothSocket *socket = server->nextPendingConnection();
466
return new QDeclarativeBluetoothSocket(socket, this, 0x0);
469
qDebug() << "Socket has no pending connection, failing";
473
QRfcommServer *rserver = qobject_cast<QRfcommServer *>(d->m_listen);
475
if (rserver->hasPendingConnections()) {
476
QBluetoothSocket *socket = rserver->nextPendingConnection();
477
return new QDeclarativeBluetoothSocket(socket, this, 0x0);;
480
qDebug() << "Socket has no pending connection, failing";
487
void QDeclarativeBluetoothService::assignNextClient(QDeclarativeBluetoothSocket *dbs)
489
QL2capServer *server = qobject_cast<QL2capServer *>(d->m_listen);
491
if (server->hasPendingConnections()) {
492
QBluetoothSocket *socket = server->nextPendingConnection();
493
dbs->newSocket(socket, this);
497
qDebug() << "Socket has no pending connection, failing";
501
QRfcommServer *rserver = qobject_cast<QRfcommServer *>(d->m_listen);
503
if (rserver->hasPendingConnections()) {
504
QBluetoothSocket *socket = rserver->nextPendingConnection();
505
dbs->newSocket(socket, this);
509
qDebug() << "Socket has no pending connection, failing";