~saiarcot895/ubuntu/trusty/qtconnectivity-opensource-src/enable-bluetooth

« back to all changes in this revision

Viewing changes to src/imports/bluetooth/qdeclarativebluetoothservice.cpp

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki
  • Date: 2013-08-20 08:46:41 UTC
  • Revision ID: package-import@ubuntu.com-20130820084641-09v00451dpna7ydk
Tags: upstream-5.0~git20130802
ImportĀ upstreamĀ versionĀ 5.0~git20130802

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the QtBluetooth module of the Qt Toolkit.
 
7
**
 
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.
 
16
**
 
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.
 
24
**
 
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.
 
28
**
 
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.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
 
 
42
#include "qdeclarativebluetoothservice_p.h"
 
43
 
 
44
#include <qbluetoothdeviceinfo.h>
 
45
#include <QtBluetooth/QBluetoothSocket>
 
46
#include <QtBluetooth/QBluetoothAddress>
 
47
#include <ql2capserver.h>
 
48
#include <qrfcommserver.h>
 
49
 
 
50
#include <QObject>
 
51
 
 
52
/* ==================== QDeclarativeBluetoothService ======================= */
 
53
 
 
54
/*!
 
55
    \qmltype BluetoothService
 
56
    \instantiates QDeclarativeBluetoothService
 
57
    \inqmlmodule QtBluetooth 5.0
 
58
    \brief Provides information about a particular Bluetooth service.
 
59
 
 
60
    \sa QBluetoothAddress
 
61
    \sa QBluetoothSocket
 
62
 
 
63
    The BluetoothService type was introduced in \b{QtBluetooth 5.0}.
 
64
 
 
65
    It allows a QML project to get information about a remote service, or describe a service
 
66
    for a BluetoothSocket to connect to.
 
67
 */
 
68
 
 
69
/*!
 
70
    \qmlsignal BluetoothService::detailsChanged()
 
71
 
 
72
    This handler is called when any of the following properties changes:
 
73
 
 
74
    \list
 
75
        \li deviceAddress
 
76
        \li deviceName
 
77
        \li serviceDescription
 
78
        \li serviceName
 
79
        \li servicePort
 
80
        \li serviceProtocol
 
81
        \li serviceUuid
 
82
    \endlist
 
83
*/
 
84
 
 
85
class QDeclarativeBluetoothServicePrivate
 
86
{
 
87
public:
 
88
    QDeclarativeBluetoothServicePrivate()
 
89
        : m_componentComplete(false),
 
90
          m_service(0), m_port(0),
 
91
          m_needsRegistration(false),
 
92
          m_listen(0)
 
93
    {
 
94
 
 
95
    }
 
96
 
 
97
    ~QDeclarativeBluetoothServicePrivate()
 
98
    {
 
99
        delete m_service;
 
100
    }
 
101
 
 
102
    int listen();
 
103
 
 
104
    bool m_componentComplete;
 
105
    QBluetoothServiceInfo *m_service;
 
106
    QString m_protocol;
 
107
    qint32 m_port;
 
108
    QString m_description;
 
109
    QString m_name;
 
110
    QString m_uuid;
 
111
    bool m_needsRegistration;
 
112
    QObject *m_listen;
 
113
 
 
114
};
 
115
 
 
116
QDeclarativeBluetoothService::QDeclarativeBluetoothService(QObject *parent) :
 
117
    QObject(parent)
 
118
{
 
119
    d = new QDeclarativeBluetoothServicePrivate;
 
120
}
 
121
 
 
122
QDeclarativeBluetoothService::QDeclarativeBluetoothService(const QBluetoothServiceInfo &service, QObject *parent)
 
123
    : QObject(parent)
 
124
{
 
125
    d = new QDeclarativeBluetoothServicePrivate;
 
126
    d->m_service = new QBluetoothServiceInfo(service);
 
127
}
 
128
 
 
129
QDeclarativeBluetoothService::~QDeclarativeBluetoothService()
 
130
{
 
131
    delete d;
 
132
}
 
133
 
 
134
void QDeclarativeBluetoothService::componentComplete()
 
135
{
 
136
    d->m_componentComplete = true;
 
137
 
 
138
    if (d->m_needsRegistration)
 
139
        setRegistered(true);
 
140
}
 
141
 
 
142
 
 
143
/*!
 
144
    \qmlproperty string BluetoothService::deviceName
 
145
 
 
146
    This property holds the name of the remote device. Changing this property emits the
 
147
    detailsChanged signal.
 
148
  */
 
149
 
 
150
QString QDeclarativeBluetoothService::deviceName() const
 
151
{
 
152
    if (!d->m_service)
 
153
        return QString();
 
154
 
 
155
    return d->m_service->device().name();
 
156
}
 
157
 
 
158
/*!
 
159
    \qmlproperty string BluetoothService::deviceAddress
 
160
 
 
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.
 
164
 
 
165
  */
 
166
 
 
167
QString QDeclarativeBluetoothService::deviceAddress() const
 
168
{
 
169
    if (!d->m_service)
 
170
        return QString();
 
171
 
 
172
    return d->m_service->device().address().toString();
 
173
}
 
174
 
 
175
void QDeclarativeBluetoothService::setDeviceAddress(QString address)
 
176
{
 
177
    if (!d->m_service)
 
178
        d->m_service = new QBluetoothServiceInfo();
 
179
 
 
180
    QBluetoothAddress a(address);
 
181
    QBluetoothDeviceInfo device(a, QString(), QBluetoothDeviceInfo::ComputerDevice);
 
182
    d->m_service->setDevice(device);
 
183
}
 
184
 
 
185
/*!
 
186
    \qmlproperty string BluetoothService::serviceName
 
187
 
 
188
    This property holds the name of the remote service if available. Changing this property emits the
 
189
    detailsChanged signal.
 
190
  */
 
191
 
 
192
QString QDeclarativeBluetoothService::serviceName() const
 
193
{
 
194
    if (!d->m_service)
 
195
        return QString();
 
196
 
 
197
    if (!d->m_name.isEmpty())
 
198
        return d->m_name;
 
199
 
 
200
    return d->m_service->serviceName();
 
201
}
 
202
 
 
203
void QDeclarativeBluetoothService::setServiceName(QString name)
 
204
{
 
205
    d->m_name = name;
 
206
}
 
207
 
 
208
 
 
209
/*!
 
210
    \qmlproperty string BluetoothService::serviceDescription
 
211
 
 
212
    This property holds the description provided by the remote service. Changing this property emits the
 
213
    detailsChanged signal.
 
214
  */
 
215
QString QDeclarativeBluetoothService::serviceDescription() const
 
216
{
 
217
    if (!d->m_service)
 
218
        return QString();
 
219
 
 
220
    if (!d->m_description.isEmpty())
 
221
        return d->m_name;
 
222
 
 
223
    return d->m_service->serviceDescription();
 
224
}
 
225
 
 
226
void QDeclarativeBluetoothService::setServiceDescription(QString description)
 
227
{
 
228
    d->m_description = description;
 
229
    emit detailsChanged();
 
230
}
 
231
 
 
232
/*!
 
233
    \qmlproperty string BluetoothService::serviceProtocol
 
234
 
 
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.
 
238
 
 
239
  */
 
240
 
 
241
QString QDeclarativeBluetoothService::serviceProtocol() const
 
242
{
 
243
    if (!d->m_protocol.isEmpty())
 
244
        return d->m_protocol;
 
245
 
 
246
    if (!d->m_service)
 
247
        return QString();
 
248
 
 
249
    if (d->m_service->socketProtocol() == QBluetoothServiceInfo::L2capProtocol)
 
250
        return QLatin1String("l2cap");
 
251
    if (d->m_service->socketProtocol() == QBluetoothServiceInfo::RfcommProtocol)
 
252
        return QLatin1String("rfcomm");
 
253
 
 
254
    return QLatin1String("unknown");
 
255
}
 
256
 
 
257
void QDeclarativeBluetoothService::setServiceProtocol(QString protocol)
 
258
{
 
259
    if (protocol != "rfcomm" && protocol != "l2cap")
 
260
        qWarning() << "Invalid protocol" << protocol;
 
261
 
 
262
    d->m_protocol = protocol;
 
263
    emit detailsChanged();
 
264
}
 
265
 
 
266
/*!
 
267
    \qmlproperty string BluetoothService::serviceUuid
 
268
 
 
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.
 
274
 
 
275
*/
 
276
 
 
277
QString QDeclarativeBluetoothService::serviceUuid() const
 
278
{
 
279
    if (!d->m_uuid.isEmpty())
 
280
        return d->m_uuid;
 
281
 
 
282
    if (!d->m_service)
 
283
        return QString();
 
284
 
 
285
    return d->m_service->attribute(QBluetoothServiceInfo::ServiceId).toString();
 
286
}
 
287
 
 
288
void QDeclarativeBluetoothService::setServiceUuid(QString uuid)
 
289
{
 
290
    d->m_uuid = uuid;
 
291
    if (!d->m_service)
 
292
        d->m_service = new QBluetoothServiceInfo();
 
293
    d->m_service->setAttribute(QBluetoothServiceInfo::ServiceId, QBluetoothUuid(uuid));
 
294
 
 
295
    emit detailsChanged();
 
296
}
 
297
 
 
298
/*!
 
299
    \qmlproperty int BluetoothService::servicePort
 
300
 
 
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.
 
305
*/
 
306
qint32 QDeclarativeBluetoothService::servicePort() const
 
307
{
 
308
    if (d->m_port > 0)
 
309
        return d->m_port;
 
310
 
 
311
    if (!d->m_service)
 
312
        return -1;
 
313
 
 
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();
 
318
 
 
319
    return -1;
 
320
}
 
321
 
 
322
void QDeclarativeBluetoothService::setServicePort(qint32 port)
 
323
{
 
324
    if (d->m_port != port){
 
325
        d->m_port = port;
 
326
        if (isRegistered())
 
327
            setRegistered(true);
 
328
        emit detailsChanged();
 
329
    }
 
330
}
 
331
 
 
332
/*!
 
333
    \qmlproperty string BluetoothService::registered
 
334
 
 
335
    This property holds the registration/publication status of the service.  If true, the service
 
336
    is published during service discovery.
 
337
*/
 
338
 
 
339
bool QDeclarativeBluetoothService::isRegistered() const
 
340
{
 
341
    if (!d->m_service)
 
342
        return false;
 
343
 
 
344
    return d->m_service->isRegistered();
 
345
}
 
346
 
 
347
 
 
348
int QDeclarativeBluetoothServicePrivate::listen() {
 
349
 
 
350
    if (m_protocol == "l2cap") {
 
351
        QL2capServer *server = new QL2capServer();
 
352
 
 
353
        server->setMaxPendingConnections(1);
 
354
        server->listen(QBluetoothAddress(), m_port);
 
355
        m_port = server->serverPort();
 
356
        m_listen = server;
 
357
    }
 
358
    else if (m_protocol == "rfcomm") {
 
359
        QRfcommServer *server = new QRfcommServer();
 
360
 
 
361
        server->setMaxPendingConnections(1);
 
362
        server->listen(QBluetoothAddress(), m_port);
 
363
        m_port = server->serverPort();
 
364
        m_listen = server;
 
365
    }
 
366
    else {
 
367
        qDebug() << "Unknown protocol, can't make service" << m_protocol;
 
368
    }
 
369
 
 
370
    return m_port;
 
371
 
 
372
}
 
373
 
 
374
void QDeclarativeBluetoothService::setRegistered(bool registered)
 
375
{
 
376
 
 
377
    d->m_needsRegistration = registered;
 
378
 
 
379
    if (!d->m_componentComplete) {
 
380
        return;
 
381
    }
 
382
 
 
383
    if (!registered) {
 
384
        if (!d->m_service)
 
385
            return;
 
386
        d->m_service->unregisterService();
 
387
        emit registeredChanged();
 
388
    }
 
389
 
 
390
    if (!d->m_service) {
 
391
        d->m_service = new QBluetoothServiceInfo();
 
392
    }
 
393
 
 
394
 
 
395
    delete d->m_listen;
 
396
    d->m_listen = 0;
 
397
 
 
398
    d->listen();
 
399
    connect(d->m_listen, SIGNAL(newConnection()), this, SLOT(new_connection()));
 
400
 
 
401
 
 
402
    d->m_service->setAttribute(QBluetoothServiceInfo::ServiceRecordHandle, (uint)0x00010010);
 
403
 
 
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);
 
408
 
 
409
    d->m_service->setAttribute(QBluetoothServiceInfo::ServiceName, d->m_name);
 
410
    d->m_service->setAttribute(QBluetoothServiceInfo::ServiceDescription,
 
411
                             d->m_description);
 
412
 
 
413
    d->m_service->setServiceUuid(QBluetoothUuid(d->m_uuid));
 
414
 
 
415
    qDebug() << "name/uuid" << d->m_name << d->m_uuid << d->m_port;
 
416
 
 
417
    d->m_service->setAttribute(QBluetoothServiceInfo::BrowseGroupList,
 
418
                             QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
 
419
 
 
420
    QBluetoothServiceInfo::Sequence protocolDescriptorList;
 
421
    QBluetoothServiceInfo::Sequence protocol;
 
422
 
 
423
    qDebug() << "Port" << d->m_port;
 
424
 
 
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));
 
429
    }
 
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));
 
434
    }
 
435
    else {
 
436
        qWarning() << "No protocol specified for bluetooth service";
 
437
    }
 
438
    d->m_service->setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList,
 
439
                             protocolDescriptorList);
 
440
 
 
441
    if (d->m_service->registerService()) {
 
442
        qDebug() << "registered";
 
443
        emit registeredChanged();
 
444
    }
 
445
    else {
 
446
        qDebug() << "Failed";
 
447
    }
 
448
}
 
449
 
 
450
QBluetoothServiceInfo *QDeclarativeBluetoothService::serviceInfo() const
 
451
{
 
452
    return d->m_service;
 
453
}
 
454
 
 
455
void QDeclarativeBluetoothService::new_connection()
 
456
{
 
457
    emit newClient();
 
458
}
 
459
 
 
460
QDeclarativeBluetoothSocket *QDeclarativeBluetoothService::nextClient()
 
461
{
 
462
    QL2capServer *server = qobject_cast<QL2capServer *>(d->m_listen);
 
463
    if (server) {
 
464
        if (server->hasPendingConnections()) {
 
465
            QBluetoothSocket *socket = server->nextPendingConnection();
 
466
            return new QDeclarativeBluetoothSocket(socket, this, 0x0);
 
467
        }
 
468
        else {
 
469
            qDebug() << "Socket has no pending connection, failing";
 
470
            return 0x0;
 
471
        }
 
472
    }
 
473
    QRfcommServer *rserver = qobject_cast<QRfcommServer *>(d->m_listen);
 
474
    if (rserver) {
 
475
        if (rserver->hasPendingConnections()) {
 
476
            QBluetoothSocket *socket = rserver->nextPendingConnection();
 
477
            return new QDeclarativeBluetoothSocket(socket, this, 0x0);;
 
478
        }
 
479
        else {
 
480
            qDebug() << "Socket has no pending connection, failing";
 
481
            return 0x0;
 
482
        }
 
483
    }
 
484
    return 0x0;
 
485
}
 
486
 
 
487
void QDeclarativeBluetoothService::assignNextClient(QDeclarativeBluetoothSocket *dbs)
 
488
{
 
489
    QL2capServer *server = qobject_cast<QL2capServer *>(d->m_listen);
 
490
    if (server) {
 
491
        if (server->hasPendingConnections()) {
 
492
            QBluetoothSocket *socket = server->nextPendingConnection();
 
493
            dbs->newSocket(socket, this);
 
494
            return;
 
495
        }
 
496
        else {
 
497
            qDebug() << "Socket has no pending connection, failing";
 
498
            return;
 
499
        }
 
500
    }
 
501
    QRfcommServer *rserver = qobject_cast<QRfcommServer *>(d->m_listen);
 
502
    if (rserver) {
 
503
        if (rserver->hasPendingConnections()) {
 
504
            QBluetoothSocket *socket = rserver->nextPendingConnection();
 
505
            dbs->newSocket(socket, this);
 
506
            return;
 
507
        }
 
508
        else {
 
509
            qDebug() << "Socket has no pending connection, failing";
 
510
            return;
 
511
        }
 
512
    }
 
513
    return;
 
514
}
 
515