1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QBLUETOOTHSERVER_P_H |
5 | #define QBLUETOOTHSERVER_P_H |
6 | |
7 | // |
8 | // W A R N I N G |
9 | // ------------- |
10 | // |
11 | // This file is not part of the Qt API. It exists purely as an |
12 | // implementation detail. This header file may change from version to |
13 | // version without notice, or even be removed. |
14 | // |
15 | // We mean it. |
16 | // |
17 | |
18 | #include <QtGlobal> |
19 | #include <QList> |
20 | #include <QtBluetooth/QBluetoothSocket> |
21 | #include "qbluetoothserver.h" |
22 | #include "qbluetooth.h" |
23 | |
24 | #if QT_CONFIG(bluez) |
25 | QT_FORWARD_DECLARE_CLASS(QSocketNotifier) |
26 | #endif |
27 | |
28 | #ifdef QT_ANDROID_BLUETOOTH |
29 | #include <QtCore/QJniEnvironment> |
30 | #include <QtCore/QJniObject> |
31 | #include <QtBluetooth/QBluetoothUuid> |
32 | |
33 | class ServerAcceptanceThread; |
34 | #endif |
35 | |
36 | #ifdef QT_WINRT_BLUETOOTH |
37 | #include <QtCore/QMutex> |
38 | |
39 | #include <wrl.h> |
40 | // No forward declares because QBluetoothServerPrivate::listener does not work with them |
41 | #include <windows.networking.sockets.h> |
42 | #endif |
43 | |
44 | #ifdef QT_OSX_BLUETOOTH |
45 | |
46 | #include "darwin/btdelegates_p.h" |
47 | #include "darwin/btraii_p.h" |
48 | |
49 | #include <QtCore/QMutex> |
50 | |
51 | #endif // QT_OSX_BLUETOOTH |
52 | |
53 | QT_BEGIN_NAMESPACE |
54 | |
55 | class QBluetoothAddress; |
56 | class QBluetoothSocket; |
57 | class QBluetoothServer; |
58 | |
59 | class QBluetoothServerPrivate |
60 | #ifdef QT_OSX_BLUETOOTH |
61 | : public DarwinBluetooth::SocketListener |
62 | #endif |
63 | { |
64 | Q_DECLARE_PUBLIC(QBluetoothServer) |
65 | |
66 | public: |
67 | QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol serverType, QBluetoothServer *parent); |
68 | ~QBluetoothServerPrivate(); |
69 | |
70 | #if QT_CONFIG(bluez) |
71 | void _q_newConnection(); |
72 | void setSocketSecurityLevel(QBluetooth::SecurityFlags requestedSecLevel, int *errnoCode); |
73 | QBluetooth::SecurityFlags socketSecurityLevel() const; |
74 | static QBluetoothSocket *createSocketForServer( |
75 | QBluetoothServiceInfo::Protocol socketType = QBluetoothServiceInfo::RfcommProtocol); |
76 | #endif |
77 | |
78 | public: |
79 | QBluetoothSocket *socket = nullptr; |
80 | |
81 | int maxPendingConnections = 1; |
82 | QBluetooth::SecurityFlags securityFlags = QBluetooth::Security::NoSecurity; |
83 | QBluetoothServiceInfo::Protocol serverType; |
84 | |
85 | protected: |
86 | QBluetoothServer *q_ptr; |
87 | |
88 | private: |
89 | QBluetoothServer::Error m_lastError = QBluetoothServer::NoError; |
90 | #if QT_CONFIG(bluez) |
91 | QSocketNotifier *socketNotifier = nullptr; |
92 | #elif defined(QT_ANDROID_BLUETOOTH) |
93 | ServerAcceptanceThread *thread; |
94 | QString m_serviceName; |
95 | QBluetoothUuid m_uuid; |
96 | public: |
97 | bool isListening() const; |
98 | bool initiateActiveListening(const QBluetoothUuid& uuid, const QString &serviceName); |
99 | bool deactivateActiveListening(); |
100 | #elif defined(QT_WINRT_BLUETOOTH) |
101 | EventRegistrationToken connectionToken {-1}; |
102 | |
103 | mutable QMutex pendingConnectionsMutex; |
104 | QList<Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocket>> |
105 | pendingConnections; |
106 | |
107 | Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> socketListener; |
108 | HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *listener, |
109 | ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args); |
110 | |
111 | public: |
112 | bool isListening() const; |
113 | Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> listener() { return socketListener; } |
114 | bool initiateActiveListening(const QString &serviceName); |
115 | bool deactivateActiveListening(); |
116 | #endif |
117 | |
118 | #ifdef QT_OSX_BLUETOOTH |
119 | |
120 | public: |
121 | |
122 | friend class QBluetoothServer; |
123 | friend class QBluetoothServiceInfoPrivate; |
124 | |
125 | private: |
126 | bool startListener(quint16 realPort); |
127 | void stopListener(); |
128 | bool isListening() const; |
129 | |
130 | // SocketListener (delegate): |
131 | void openNotifyRFCOMM(void *channel) override; |
132 | void openNotifyL2CAP(void *channel) override; |
133 | |
134 | // Either a "temporary" channelID/PSM assigned by QBluetoothServer::listen, |
135 | // or a real channelID/PSM returned by IOBluetooth after we've registered |
136 | // a service. |
137 | quint16 port; |
138 | |
139 | DarwinBluetooth::StrongReference listener; |
140 | |
141 | // These static functions below |
142 | // deal with differences between bluetooth sockets |
143 | // (bluez and QtBluetooth's API) and IOBluetooth, where it's not possible |
144 | // to have a real PSM/channelID _before_ a service is registered, |
145 | // the solution - "fake" ports. |
146 | // These functions require external locking - using channelMapMutex. |
147 | static QMutex &channelMapMutex(); |
148 | |
149 | static bool channelIsBusy(quint16 channelID); |
150 | static quint16 findFreeChannel(); |
151 | |
152 | static bool psmIsBusy(quint16 psm); |
153 | static quint16 findFreePSM(); |
154 | |
155 | static void registerServer(QBluetoothServerPrivate *server, quint16 port); |
156 | static QBluetoothServerPrivate *registeredServer(quint16 port, QBluetoothServiceInfo::Protocol protocol); |
157 | static void unregisterServer(QBluetoothServerPrivate *server); |
158 | |
159 | using PendingConnection = DarwinBluetooth::StrongReference; |
160 | QList<PendingConnection> pendingConnections; |
161 | |
162 | #endif // QT_OSX_BLUETOOTH |
163 | }; |
164 | |
165 | QT_END_NAMESPACE |
166 | |
167 | #endif |
168 | |