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