11#include <QtCore/QLoggingCategory>
12#include <QtCore/private/qfunctions_winrt_p.h>
14#include <windows.networking.h>
15#include <windows.networking.connectivity.h>
16#include <windows.networking.sockets.h>
18using namespace Microsoft::WRL;
19using namespace Microsoft::WRL::Wrappers;
20using namespace ABI::Windows::Devices;
21using namespace ABI::Windows::Devices::Enumeration;
22using namespace ABI::Windows::Foundation;
24using namespace ABI::Windows::Networking::Sockets;
25using namespace ABI::Windows::Networking::Connectivity;
31Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINDOWS)
33QHash<QBluetoothServerPrivate *,
int> __fakeServerPorts;
36 QBluetoothServer *parent)
37 : serverType(sType),
q_ptr(parent)
44 deactivateActiveListening();
45 __fakeServerPorts.remove(
this);
48 socketListener =
nullptr;
54 return __fakeServerPorts.contains(
const_cast<QBluetoothServerPrivate *>(
this));
59 HStringReference serviceNameRef(
reinterpret_cast<LPCWSTR>(serviceName.utf16()));
61 ComPtr<IAsyncAction> bindAction;
62 HRESULT hr = socketListener->BindServiceNameAsync(serviceNameRef.Get(), &bindAction);
63 Q_ASSERT_SUCCEEDED(hr);
64 hr = QWinRTFunctions::await(bindAction);
65 Q_ASSERT_SUCCEEDED(hr);
75 hr = socketListener->remove_ConnectionReceived(connectionToken);
76 Q_ASSERT_SUCCEEDED(hr);
81 IStreamSocketListenerConnectionReceivedEventArgs *args)
83 Q_Q(QBluetoothServer);
84 if (!socketListener || socketListener.Get() != listener) {
85 qCDebug(QT_BT_WINDOWS) <<
"Accepting connection from wrong listener. We should not be here.";
91 ComPtr<IStreamSocket> socket;
92 hr = args->get_Socket(&
socket);
93 Q_ASSERT_SUCCEEDED(hr);
94 QMutexLocker locker(&pendingConnectionsMutex);
95 if (pendingConnections.size() < maxPendingConnections) {
96 qCDebug(QT_BT_WINDOWS) <<
"Accepting connection";
97 pendingConnections.append(socket);
101 qCDebug(QT_BT_WINDOWS) <<
"Refusing connection";
107void QBluetoothServer::close()
109 Q_D(QBluetoothServer);
111 d->deactivateActiveListening();
112 __fakeServerPorts.remove(d);
115bool QBluetoothServer::listen(
const QBluetoothAddress &address, quint16 port)
118 Q_D(QBluetoothServer);
119 if (serverType() != QBluetoothServiceInfo::RfcommProtocol) {
120 d->m_lastError = UnsupportedProtocolError;
121 emit errorOccurred(d->m_lastError);
128 HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(),
130 Q_ASSERT_SUCCEEDED(hr);
131 hr = d->socketListener->add_ConnectionReceived(Callback<ClientConnectedHandler>(d, &QBluetoothServerPrivate::handleClientConnection).Get(),
132 &d->connectionToken);
133 Q_ASSERT_SUCCEEDED(hr);
138 for (
int i = 1; ; i++){
139 if (__fakeServerPorts.key(i) == 0) {
146 if (__fakeServerPorts.key(port) == 0) {
147 __fakeServerPorts[d] = port;
149 qCDebug(QT_BT_WINDOWS) <<
"Port" << port <<
"registered";
151 qCWarning(QT_BT_WINDOWS) <<
"server with port" << port <<
"already registered or port invalid";
152 d->m_lastError = ServiceAlreadyRegisteredError;
153 emit errorOccurred(d->m_lastError);
160void QBluetoothServer::setMaxPendingConnections(
int numConnections)
162 Q_D(QBluetoothServer);
163 QMutexLocker locker(&d->pendingConnectionsMutex);
164 if (d->pendingConnections.size() > numConnections) {
165 qCWarning(QT_BT_WINDOWS) <<
"There are currently more than" << numConnections <<
"connections"
166 <<
"pending. Number of maximum pending connections was not changed.";
170 d->maxPendingConnections = numConnections;
173bool QBluetoothServer::hasPendingConnections()
const
175 Q_D(
const QBluetoothServer);
176 QMutexLocker locker(&d->pendingConnectionsMutex);
177 return !d->pendingConnections.isEmpty();
180QBluetoothSocket *QBluetoothServer::nextPendingConnection()
182 Q_D(QBluetoothServer);
183 if (d->pendingConnections.isEmpty())
186 ComPtr<IStreamSocket> socket = d->pendingConnections.takeFirst();
188 QBluetoothSocket *newSocket =
new QBluetoothSocket();
189 bool success = newSocket->d_ptr->setSocketDescriptor(socket, d->serverType);
198QBluetoothAddress QBluetoothServer::serverAddress()
const
200 QList<QBluetoothHostInfo> hosts = QBluetoothLocalDevice::allDevices();
203 return QBluetoothAddress();
205 return hosts.at(0).address();
208quint16 QBluetoothServer::serverPort()
const
211 Q_D(
const QBluetoothServer);
212 return __fakeServerPorts.value((QBluetoothServerPrivate*)d, 0);
215void QBluetoothServer::setSecurityFlags(QBluetooth::SecurityFlags security)
220QBluetooth::SecurityFlags QBluetoothServer::securityFlags()
const
222 return QBluetooth::Security::NoSecurity;
~QBluetoothServerPrivate()
QBluetoothSocket * socket
ITypedEventHandler< StreamSocketListener *, StreamSocketListenerConnectionReceivedEventArgs * > ClientConnectedHandler
void mainThreadCoInit(void *caller)
void mainThreadCoUninit(void *caller)