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 "qbluetoothserver.h"
42#include "qbluetoothserver_p.h"
43#include "qbluetoothsocket.h"
44#include "qbluetoothserviceinfo.h"
45
46QT_BEGIN_NAMESPACE
47
48/*!
49 \class QBluetoothServer
50 \inmodule QtBluetooth
51 \brief The QBluetoothServer class uses the RFCOMM or L2cap protocol to communicate with
52 a Bluetooth device.
53
54 \since 5.2
55
56 QBluetoothServer is used to implement Bluetooth services over RFCOMM or L2cap.
57
58 Start listening for incoming connections with listen(). Wait till the newConnection() signal
59 is emitted when a new connection is established, and call nextPendingConnection() to get a QBluetoothSocket
60 for the new connection.
61
62 To enable other devices to find your service, create a QBluetoothServiceInfo with the
63 applicable attributes for your service and register it using QBluetoothServiceInfo::registerService().
64 Call serverPort() to get the channel number that is being used.
65
66 If the \l QBluetoothServiceInfo::Protocol is not supported by a platform, \l listen() will return \c false.
67 Android and WinRT only support RFCOMM for example.
68
69 On iOS, this class cannot be used because the platform does not expose
70 an API which may permit access to QBluetoothServer related features.
71
72 \sa QBluetoothServiceInfo, QBluetoothSocket
73*/
74
75/*!
76 \fn void QBluetoothServer::newConnection()
77
78 This signal is emitted when a new connection is available.
79
80 The connected slot should call nextPendingConnection() to get a QBluetoothSocket object to
81 send and receive data over the connection.
82
83 \sa nextPendingConnection(), hasPendingConnections()
84*/
85
86/*!
87 \fn void QBluetoothServer::error(QBluetoothServer::Error error)
88
89 This signal is emitted when an \a error occurs.
90
91 \sa error(), QBluetoothServer::Error
92*/
93
94/*!
95 \fn void QBluetoothServer::close()
96
97 Closes and resets the listening socket. Any already established \l QBluetoothSocket
98 continues to operate and must be separately \l {QBluetoothSocket::close()}{closed}.
99*/
100
101/*!
102 \enum QBluetoothServer::Error
103
104 This enum describes Bluetooth server error types.
105
106 \value NoError No error.
107 \value UnknownError An unknown error occurred.
108 \value PoweredOffError The Bluetooth adapter is powered off.
109 \value InputOutputError An input output error occurred.
110 \value ServiceAlreadyRegisteredError The service or port was already registered
111 \value UnsupportedProtocolError The \l {QBluetoothServiceInfo::Protocol}{Protocol} is not
112 supported on this platform.
113*/
114
115/*!
116 \fn bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
117
118 Start listening for incoming connections to \a address on \a port. \a address
119 must be a local Bluetooth adapter address and \a port must be larger than zero
120 and not be taken already by another Bluetooth server object. It is recommended
121 to avoid setting a port number to enable the system to automatically choose
122 a port.
123
124 Returns \c true if the operation succeeded and the server is listening for
125 incoming connections, otherwise returns \c false.
126
127 If the server object is already listening for incoming connections this function
128 always returns \c false. \l close() should be called before calling this function.
129
130 \sa isListening(), newConnection()
131*/
132
133/*!
134 \fn void QBluetoothServer::setMaxPendingConnections(int numConnections)
135
136 Sets the maximum number of pending connections to \a numConnections. If
137 the number of pending sockets exceeds this limit new sockets will be rejected.
138
139 \sa maxPendingConnections()
140*/
141
142/*!
143 \fn bool QBluetoothServer::hasPendingConnections() const
144 Returns true if a connection is pending, otherwise false.
145*/
146
147/*!
148 \fn QBluetoothSocket *QBluetoothServer::nextPendingConnection()
149
150 Returns a pointer to the QBluetoothSocket for the next pending connection. It is the callers
151 responsibility to delete the pointer.
152*/
153
154/*!
155 \fn QBluetoothAddress QBluetoothServer::serverAddress() const
156
157 Returns the server address.
158*/
159
160/*!
161 \fn quint16 QBluetoothServer::serverPort() const
162
163 Returns the server port number.
164*/
165
166/*!
167 Constructs a bluetooth server with \a parent and \a serverType.
168*/
169QBluetoothServer::QBluetoothServer(QBluetoothServiceInfo::Protocol serverType, QObject *parent)
170 : QObject(parent), d_ptr(new QBluetoothServerPrivate(serverType))
171{
172 d_ptr->q_ptr = this;
173}
174
175/*!
176 Destroys the bluetooth server.
177*/
178QBluetoothServer::~QBluetoothServer()
179{
180 delete d_ptr;
181}
182
183/*!
184 \fn QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const QString &serviceName)
185
186 Convenience function for registering an SPP service with \a uuid and \a serviceName.
187 Because this function already registers the service, the QBluetoothServiceInfo object
188 which is returned can not be changed any more. To shutdown the server later on it is
189 required to call \l QBluetoothServiceInfo::unregisterService() and \l close() on this
190 server object.
191
192 Returns a registered QBluetoothServiceInfo instance if successful otherwise an
193 invalid QBluetoothServiceInfo. This function always assumes that the default Bluetooth adapter
194 should be used.
195
196 If the server object is already listening for incoming connections this function
197 returns an invalid \l QBluetoothServiceInfo.
198
199 For an RFCOMM server this function is equivalent to following code snippet.
200
201 \snippet qbluetoothserver.cpp listen
202 \snippet qbluetoothserver.cpp listen2
203 \snippet qbluetoothserver.cpp listen3
204
205 \sa isListening(), newConnection(), listen()
206*/
207QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const QString &serviceName)
208{
209 Q_D(const QBluetoothServer);
210 if (!listen())
211 return QBluetoothServiceInfo();
212//! [listen]
213 QBluetoothServiceInfo serviceInfo;
214 serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceName, serviceName);
215 QBluetoothServiceInfo::Sequence browseSequence;
216 browseSequence << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
217 serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList,
218 browseSequence);
219
220 QBluetoothServiceInfo::Sequence profileSequence;
221 QBluetoothServiceInfo::Sequence classId;
222 classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
223 classId << QVariant::fromValue(quint16(0x100));
224 profileSequence.append(QVariant::fromValue(classId));
225 serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,
226 profileSequence);
227
228 classId.clear();
229 //Android requires custom uuid to be set as service class
230 classId << QVariant::fromValue(uuid);
231 classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
232 serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
233 serviceInfo.setServiceUuid(uuid);
234
235 QBluetoothServiceInfo::Sequence protocolDescriptorList;
236 QBluetoothServiceInfo::Sequence protocol;
237 protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap));
238 if (d->serverType == QBluetoothServiceInfo::L2capProtocol)
239 protocol << QVariant::fromValue(serverPort());
240 protocolDescriptorList.append(QVariant::fromValue(protocol));
241 protocol.clear();
242//! [listen]
243 if (d->serverType == QBluetoothServiceInfo::RfcommProtocol) {
244//! [listen2]
245 protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
246 << QVariant::fromValue(quint8(serverPort()));
247 protocolDescriptorList.append(QVariant::fromValue(protocol));
248//! [listen2]
249 }
250//! [listen3]
251 serviceInfo.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList,
252 protocolDescriptorList);
253 bool result = serviceInfo.registerService();
254//! [listen3]
255 if (!result) {
256 close(); //close the still listening socket
257 return QBluetoothServiceInfo();
258 }
259 return serviceInfo;
260}
261
262/*!
263 Returns true if the server is listening for incoming connections, otherwise false.
264*/
265bool QBluetoothServer::isListening() const
266{
267 Q_D(const QBluetoothServer);
268
269#if defined(QT_ANDROID_BLUETOOTH) || defined(QT_WINRT_BLUETOOTH) || defined(QT_OSX_BLUETOOTH)
270 return d->isListening();
271#endif
272
273 return d->socket->state() == QBluetoothSocket::ListeningState;
274}
275
276/*!
277 Returns the maximum number of pending connections.
278
279 \sa setMaxPendingConnections()
280*/
281int QBluetoothServer::maxPendingConnections() const
282{
283 Q_D(const QBluetoothServer);
284
285 return d->maxPendingConnections;
286}
287
288/*!
289 \fn QBluetoothServer::setSecurityFlags(QBluetooth::SecurityFlags security)
290 Sets the Bluetooth security flags to \a security. This function must be called before calling listen().
291 The Bluetooth link will always be encrypted when using Bluetooth 2.1 devices as encryption is
292 mandatory.
293
294 Android only supports two levels of security (secure and non-secure). If this flag is set to
295 \l QBluetooth::NoSecurity the server object will not employ any authentication or encryption.
296 Any other security flag combination will trigger a secure Bluetooth connection.
297
298 On \macos, security flags are not supported and will be ignored.
299*/
300
301/*!
302 \fn QBluetooth::SecurityFlags QBluetoothServer::securityFlags() const
303 Returns the Bluetooth security flags.
304*/
305
306/*!
307 \fn QBluetoothSocket::ServerType QBluetoothServer::serverType() const
308 Returns the type of the QBluetoothServer.
309*/
310QBluetoothServiceInfo::Protocol QBluetoothServer::serverType() const
311{
312 Q_D(const QBluetoothServer);
313 return d->serverType;
314}
315
316/*!
317 \fn QBluetoothServer::Error QBluetoothServer::error() const
318 Returns the last error of the QBluetoothServer.
319*/
320QBluetoothServer::Error QBluetoothServer::error() const
321{
322 Q_D(const QBluetoothServer);
323 return d->m_lastError;
324}
325
326QT_END_NAMESPACE
327
328#include "moc_qbluetoothserver.cpp"
329