aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Claudiu Olteanu <olteanu.claudiu@ymail.com>2015-08-18 22:08:32 +0300
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-08-20 22:45:34 -0700
commit2af14ba44588db5b7bfef39edd3a1f922d1474cf (patch)
treee130594a529627a20d42afde87b700538fd679ba
parent3b811552aa19f9f929565f8cec9bb3e233162362 (diff)
downloadsubsurface-2af14ba44588db5b7bfef39edd3a1f922d1474cf.tar.gz
Add implementation for our custom BTH device discovery service
Implement a custom lookup service for remote Bluetooth devices discovery. This will be used on Windows platforms to collect information about the name and the address of a remote Bluetooth device. In the beginning we initialize the queryset with the necessary flags and we start the lookup service. When a device is discovered we collect information about its name and its address and we raise a signal with it using the same signature as the one emitted by QtBluetoothDeviceDiscoveryAgent implementation. Finally we end the lookup service and we reset the internal flags. This code was written with the help of the sample code documenting the relevant APIs provided by Microsoft Corporation at https://code.msdn.microsoft.com/windowsdesktop/Bluetooth-Connection-e3263296 which is under the MS-LPL. No code from the samples was copied and the code in this commit is covered by the GPL and not the MS-LPL. Signed-off-by: Claudiu Olteanu <olteanu.claudiu@ymail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--qt-ui/btdeviceselectiondialog.cpp101
1 files changed, 100 insertions, 1 deletions
diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 74378ee1b..813b07f88 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -475,7 +475,106 @@ QBluetoothDeviceDiscoveryAgent::Error WinBluetoothDeviceDiscoveryAgent::error()
void WinBluetoothDeviceDiscoveryAgent::run()
{
- // TODO initialize the resources and start the device discovery
+ // Initialize query for device and start the lookup service
+ WSAQUERYSET queryset;
+ HANDLE hLookup;
+ int result = SUCCESS;
+
+ running = true;
+ lastError = QBluetoothDeviceDiscoveryAgent::NoError;
+ lastErrorToString = QString("No error");
+
+ memset(&queryset, 0, sizeof(WSAQUERYSET));
+ queryset.dwSize = sizeof(WSAQUERYSET);
+ queryset.dwNameSpace = NS_BTH;
+
+ // The LUP_CONTAINERS flag is used to signal that we are doing a device inquiry
+ // while LUP_FLUSHCACHE flag is used to flush the device cache for all inquiries
+ // and to do a fresh lookup instead.
+ result = WSALookupServiceBegin(&queryset, LUP_CONTAINERS | LUP_FLUSHCACHE, &hLookup);
+
+ if (result != SUCCESS) {
+ // Get the last error and emit a signal
+ lastErrorToString = qt_error_string();
+ lastError = QBluetoothDeviceDiscoveryAgent::PoweredOffError;
+ emit error(lastError);
+
+ // Announce that the inquiry finished and restore the stopped flag
+ running = false;
+ stopped = false;
+
+ return;
+ }
+
+ // Declare the necessary variables to collect the information
+ BYTE buffer[4096];
+ DWORD bufferLength = sizeof(buffer);
+ WSAQUERYSET *pResults = (WSAQUERYSET*)&buffer;
+
+ memset(buffer, 0, sizeof(buffer));
+
+ pResults->dwSize = sizeof(WSAQUERYSET);
+ pResults->dwNameSpace = NS_BTH;
+ pResults->lpBlob = NULL;
+
+ //Start looking for devices
+ while (result == SUCCESS && !stopped){
+ // LUP_RETURN_NAME and LUP_RETURN_ADDR flags are used to return the name and the address of the discovered device
+ result = WSALookupServiceNext(hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &bufferLength, pResults);
+
+ if (result == SUCCESS) {
+ // Found a device
+ QString deviceAddress(BTH_ADDR_STR_LEN, Qt::Uninitialized);
+ DWORD addressSize = BTH_ADDR_STR_LEN;
+
+ // Collect the address of the device from the WSAQUERYSET
+ SOCKADDR_BTH *socketBthAddress = (SOCKADDR_BTH *) pResults->lpcsaBuffer->RemoteAddr.lpSockaddr;
+
+ // Convert the BTH_ADDR to string
+ if (WSAAddressToStringW((LPSOCKADDR) socketBthAddress,
+ sizeof (*socketBthAddress),
+ NULL,
+ reinterpret_cast<wchar_t*>(deviceAddress.data()),
+ &addressSize
+ ) != 0) {
+ // Get the last error and emit a signal
+ lastErrorToString = qt_error_string();
+ lastError = QBluetoothDeviceDiscoveryAgent::UnknownError;
+ emit(lastError);
+
+ break;
+ }
+
+ // Save the name of the discovered device and truncate the address
+ QString deviceName = QString(pResults->lpszServiceInstanceName);
+ deviceAddress.truncate(addressSize / sizeof(wchar_t));
+
+ // Remove the round parentheses
+ deviceAddress.remove(')');
+ deviceAddress.remove('(');
+
+ // Create an object with information about the discovered device
+ QBluetoothDeviceInfo deviceInfo = QBluetoothDeviceInfo(QBluetoothAddress(deviceAddress), deviceName, 0);
+
+ // Raise a signal with information about the found remote device
+ emit deviceDiscovered(deviceInfo);
+ } else {
+ // Get the last error and emit a signal
+ lastErrorToString = qt_error_string();
+ lastError = QBluetoothDeviceDiscoveryAgent::UnknownError;
+ emit(lastError);
+ }
+ }
+
+ // Announce that the inquiry finished and restore the stopped flag
+ running = false;
+ stopped = false;
+
+ // Restore the error status
+ lastError = QBluetoothDeviceDiscoveryAgent::NoError;
+
+ // End the lookup service
+ WSALookupServiceEnd(hLookup);
}
void WinBluetoothDeviceDiscoveryAgent::stop()