| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Copyright (C) 2016 BlackBerry Limited. All rights reserved. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtBluetooth module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "qbluetoothserver.h" |
| #include "qbluetoothserver_p.h" |
| #include "qbluetoothsocket.h" |
| #include "qbluetoothserviceinfo.h" |
| |
| QT_BEGIN_NAMESPACE |
| |
| /*! |
| \class QBluetoothServer |
| \inmodule QtBluetooth |
| \brief The QBluetoothServer class uses the RFCOMM or L2cap protocol to communicate with |
| a Bluetooth device. |
| |
| \since 5.2 |
| |
| QBluetoothServer is used to implement Bluetooth services over RFCOMM or L2cap. |
| |
| Start listening for incoming connections with listen(). Wait till the newConnection() signal |
| is emitted when a new connection is established, and call nextPendingConnection() to get a QBluetoothSocket |
| for the new connection. |
| |
| To enable other devices to find your service, create a QBluetoothServiceInfo with the |
| applicable attributes for your service and register it using QBluetoothServiceInfo::registerService(). |
| Call serverPort() to get the channel number that is being used. |
| |
| If the \l QBluetoothServiceInfo::Protocol is not supported by a platform, \l listen() will return \c false. |
| Android and WinRT only support RFCOMM for example. |
| |
| On iOS, this class cannot be used because the platform does not expose |
| an API which may permit access to QBluetoothServer related features. |
| |
| \sa QBluetoothServiceInfo, QBluetoothSocket |
| */ |
| |
| /*! |
| \fn void QBluetoothServer::newConnection() |
| |
| This signal is emitted when a new connection is available. |
| |
| The connected slot should call nextPendingConnection() to get a QBluetoothSocket object to |
| send and receive data over the connection. |
| |
| \sa nextPendingConnection(), hasPendingConnections() |
| */ |
| |
| /*! |
| \fn void QBluetoothServer::error(QBluetoothServer::Error error) |
| |
| This signal is emitted when an \a error occurs. |
| |
| \sa error(), QBluetoothServer::Error |
| */ |
| |
| /*! |
| \fn void QBluetoothServer::close() |
| |
| Closes and resets the listening socket. Any already established \l QBluetoothSocket |
| continues to operate and must be separately \l {QBluetoothSocket::close()}{closed}. |
| */ |
| |
| /*! |
| \enum QBluetoothServer::Error |
| |
| This enum describes Bluetooth server error types. |
| |
| \value NoError No error. |
| \value UnknownError An unknown error occurred. |
| \value PoweredOffError The Bluetooth adapter is powered off. |
| \value InputOutputError An input output error occurred. |
| \value ServiceAlreadyRegisteredError The service or port was already registered |
| \value UnsupportedProtocolError The \l {QBluetoothServiceInfo::Protocol}{Protocol} is not |
| supported on this platform. |
| */ |
| |
| /*! |
| \fn bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port) |
| |
| Start listening for incoming connections to \a address on \a port. \a address |
| must be a local Bluetooth adapter address and \a port must be larger than zero |
| and not be taken already by another Bluetooth server object. It is recommended |
| to avoid setting a port number to enable the system to automatically choose |
| a port. |
| |
| Returns \c true if the operation succeeded and the server is listening for |
| incoming connections, otherwise returns \c false. |
| |
| If the server object is already listening for incoming connections this function |
| always returns \c false. \l close() should be called before calling this function. |
| |
| \sa isListening(), newConnection() |
| */ |
| |
| /*! |
| \fn void QBluetoothServer::setMaxPendingConnections(int numConnections) |
| |
| Sets the maximum number of pending connections to \a numConnections. If |
| the number of pending sockets exceeds this limit new sockets will be rejected. |
| |
| \sa maxPendingConnections() |
| */ |
| |
| /*! |
| \fn bool QBluetoothServer::hasPendingConnections() const |
| Returns true if a connection is pending, otherwise false. |
| */ |
| |
| /*! |
| \fn QBluetoothSocket *QBluetoothServer::nextPendingConnection() |
| |
| Returns a pointer to the QBluetoothSocket for the next pending connection. It is the callers |
| responsibility to delete the pointer. |
| */ |
| |
| /*! |
| \fn QBluetoothAddress QBluetoothServer::serverAddress() const |
| |
| Returns the server address. |
| */ |
| |
| /*! |
| \fn quint16 QBluetoothServer::serverPort() const |
| |
| Returns the server port number. |
| */ |
| |
| /*! |
| Constructs a bluetooth server with \a parent and \a serverType. |
| */ |
| QBluetoothServer::QBluetoothServer(QBluetoothServiceInfo::Protocol serverType, QObject *parent) |
| : QObject(parent), d_ptr(new QBluetoothServerPrivate(serverType, this)) |
| { |
| } |
| |
| /*! |
| Destroys the bluetooth server. |
| */ |
| QBluetoothServer::~QBluetoothServer() |
| { |
| delete d_ptr; |
| } |
| |
| /*! |
| \fn QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const QString &serviceName) |
| |
| Convenience function for registering an SPP service with \a uuid and \a serviceName. |
| Because this function already registers the service, the QBluetoothServiceInfo object |
| which is returned can not be changed any more. To shutdown the server later on it is |
| required to call \l QBluetoothServiceInfo::unregisterService() and \l close() on this |
| server object. |
| |
| Returns a registered QBluetoothServiceInfo instance if successful otherwise an |
| invalid QBluetoothServiceInfo. This function always assumes that the default Bluetooth adapter |
| should be used. |
| |
| If the server object is already listening for incoming connections this function |
| returns an invalid \l QBluetoothServiceInfo. |
| |
| For an RFCOMM server this function is equivalent to following code snippet. |
| |
| \snippet qbluetoothserver.cpp listen |
| \snippet qbluetoothserver.cpp listen2 |
| \snippet qbluetoothserver.cpp listen3 |
| |
| \sa isListening(), newConnection(), listen() |
| */ |
| QBluetoothServiceInfo QBluetoothServer::listen(const QBluetoothUuid &uuid, const QString &serviceName) |
| { |
| Q_D(const QBluetoothServer); |
| if (!listen()) |
| return QBluetoothServiceInfo(); |
| //! [listen] |
| QBluetoothServiceInfo serviceInfo; |
| serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceName, serviceName); |
| QBluetoothServiceInfo::Sequence browseSequence; |
| browseSequence << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); |
| serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList, |
| browseSequence); |
| |
| QBluetoothServiceInfo::Sequence profileSequence; |
| QBluetoothServiceInfo::Sequence classId; |
| classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); |
| classId << QVariant::fromValue(quint16(0x100)); |
| profileSequence.append(QVariant::fromValue(classId)); |
| serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList, |
| profileSequence); |
| |
| classId.clear(); |
| //Android requires custom uuid to be set as service class |
| classId << QVariant::fromValue(uuid); |
| classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort)); |
| serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId); |
| serviceInfo.setServiceUuid(uuid); |
| |
| QBluetoothServiceInfo::Sequence protocolDescriptorList; |
| QBluetoothServiceInfo::Sequence protocol; |
| protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap)); |
| if (d->serverType == QBluetoothServiceInfo::L2capProtocol) |
| protocol << QVariant::fromValue(serverPort()); |
| protocolDescriptorList.append(QVariant::fromValue(protocol)); |
| protocol.clear(); |
| //! [listen] |
| if (d->serverType == QBluetoothServiceInfo::RfcommProtocol) { |
| //! [listen2] |
| protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm)) |
| << QVariant::fromValue(quint8(serverPort())); |
| protocolDescriptorList.append(QVariant::fromValue(protocol)); |
| //! [listen2] |
| } |
| //! [listen3] |
| serviceInfo.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, |
| protocolDescriptorList); |
| bool result = serviceInfo.registerService(); |
| //! [listen3] |
| if (!result) { |
| close(); //close the still listening socket |
| return QBluetoothServiceInfo(); |
| } |
| return serviceInfo; |
| } |
| |
| /*! |
| Returns true if the server is listening for incoming connections, otherwise false. |
| */ |
| bool QBluetoothServer::isListening() const |
| { |
| Q_D(const QBluetoothServer); |
| |
| #if defined(QT_ANDROID_BLUETOOTH) || defined(QT_WINRT_BLUETOOTH) || defined(QT_OSX_BLUETOOTH) |
| return d->isListening(); |
| #endif |
| |
| return d->socket->state() == QBluetoothSocket::ListeningState; |
| } |
| |
| /*! |
| Returns the maximum number of pending connections. |
| |
| \sa setMaxPendingConnections() |
| */ |
| int QBluetoothServer::maxPendingConnections() const |
| { |
| Q_D(const QBluetoothServer); |
| |
| return d->maxPendingConnections; |
| } |
| |
| /*! |
| \fn QBluetoothServer::setSecurityFlags(QBluetooth::SecurityFlags security) |
| Sets the Bluetooth security flags to \a security. This function must be called before calling listen(). |
| The Bluetooth link will always be encrypted when using Bluetooth 2.1 devices as encryption is |
| mandatory. |
| |
| Android only supports two levels of security (secure and non-secure). If this flag is set to |
| \l QBluetooth::NoSecurity the server object will not employ any authentication or encryption. |
| Any other security flag combination will trigger a secure Bluetooth connection. |
| |
| On \macos, security flags are not supported and will be ignored. |
| */ |
| |
| /*! |
| \fn QBluetooth::SecurityFlags QBluetoothServer::securityFlags() const |
| Returns the Bluetooth security flags. |
| */ |
| |
| /*! |
| \fn QBluetoothSocket::ServerType QBluetoothServer::serverType() const |
| Returns the type of the QBluetoothServer. |
| */ |
| QBluetoothServiceInfo::Protocol QBluetoothServer::serverType() const |
| { |
| Q_D(const QBluetoothServer); |
| return d->serverType; |
| } |
| |
| /*! |
| \fn QBluetoothServer::Error QBluetoothServer::error() const |
| Returns the last error of the QBluetoothServer. |
| */ |
| QBluetoothServer::Error QBluetoothServer::error() const |
| { |
| Q_D(const QBluetoothServer); |
| return d->m_lastError; |
| } |
| |
| QT_END_NAMESPACE |
| |
| #include "moc_qbluetoothserver.cpp" |