Hi there,

As I promised, I created a new set of patches. You can find it
attached to this e-mail.

Here is a list with the changes I did after the feedback:
- initialized the internal variables (patch 06)
- moved the *WSACleanup* call from patch 06 to patch 12
- removed the implementation of my internal *getLastError* and started
using *qt_error_string* (patch 11)
- used *WSAAddressToStringW* instead of *WSAAddressToStringA* (patch 11)
- avoided some code duplication (patches 14, 15, 17)

I hope that I covered all of Thiago's suggestions.

You should know that I didn't call *WSACleanup* if the
*WSAStartup* failed because this call was already made in the
*BtDeviceSelectionDialog* destructor and I didn't know exactly
how I should handle this elegantly :).

Also I didn't remove the call of strdup method from
*qtserialbluetooth::qt_serial_open *because the
*WSAStringToAddressA* method is expecting to receive
LPSTR {aka char*} parameter while I have the address
represented as const char*.

I tried as well to replace the WSAStringToAddressA with
WSAStringToAddressW but I had to represent the
address as a wchar_t* and and when I wanted to use
mbstowcs_s for conversion (from const char* to wchar_t*)
the compiler couldn't find the declaration to the method
(even though I included the stdlib header). After some
failed attempts I gave up :).

Cheers,
Claudiu
From ca22cc110c07284499be9aab4e0230dbc13932e2 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 20:11:25 +0300
Subject: [PATCH 01/18] Cleanup Bluetooth local device and the discovery agent
 on exit

Do some extra cleanup when the BtDeviceSelectionDialog is
destroyed.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 007fe94..ce759cc 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -61,6 +61,15 @@ BtDeviceSelectionDialog::BtDeviceSelectionDialog(QWidget *parent) :
 BtDeviceSelectionDialog::~BtDeviceSelectionDialog()
 {
 	delete ui;
+
+	// Clean the local device
+	delete localDevice;
+
+	// Clean the device discovery agent
+	if (remoteDeviceDiscoveryAgent->isActive())
+		remoteDeviceDiscoveryAgent->stop();
+
+	delete remoteDeviceDiscoveryAgent;
 }
 
 void BtDeviceSelectionDialog::on_changeDeviceState_clicked()
-- 
2.4.3

From a235c7dd8fe18fc40c3efa75f5a01f0787ba43e3 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 20:12:15 +0300
Subject: [PATCH 02/18] Check the last error when the BTH device scanning is
 finished

If there is no error reported when the device scanning is finished
then report to the dialog status that the scanning finished
successfully. Otherwise report the last error.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index ce759cc..3af2501 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -124,7 +124,12 @@ void BtDeviceSelectionDialog::on_scan_clicked()
 
 void BtDeviceSelectionDialog::remoteDeviceScanFinished()
 {
-	ui->dialogStatus->setText("Scanning finished.");
+	if (remoteDeviceDiscoveryAgent->error() == QBluetoothDeviceDiscoveryAgent::NoError) {
+		ui->dialogStatus->setText("Scanning finished successfully.");
+	} else {
+		deviceDiscoveryError(remoteDeviceDiscoveryAgent->error());
+	}
+
 	ui->scan->setEnabled(true);
 }
 
-- 
2.4.3

From ccfd2068dad95052f1c5e473a976d684993efc39 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 20:15:49 +0300
Subject: [PATCH 03/18] Clear the BTH discovered devices list on each search

Clear the Bluetooth discovered devices list on each search.
In this way we will show only the devices that are in range
and active during the last scannning. Also if we clear the
list before each call we don't need to check anymore if the
discovered device is already in the list.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 39 ++++++++++++++++++++-------------------
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 3af2501..7f53740 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -118,6 +118,7 @@ void BtDeviceSelectionDialog::on_clear_clicked()
 void BtDeviceSelectionDialog::on_scan_clicked()
 {
 	ui->dialogStatus->setText("Scanning for remote devices...");
+	ui->discoveredDevicesList->clear();
 	remoteDeviceDiscoveryAgent->start();
 	ui->scan->setEnabled(false);
 }
@@ -145,28 +146,28 @@ void BtDeviceSelectionDialog::hostModeStateChanged(QBluetoothLocalDevice::HostMo
 
 void BtDeviceSelectionDialog::addRemoteDevice(const QBluetoothDeviceInfo &remoteDeviceInfo)
 {
-	QString deviceLabel = QString("%1  (%2)").arg(remoteDeviceInfo.name()).arg(remoteDeviceInfo.address().toString());
-	QList<QListWidgetItem *> itemsWithSameSignature = ui->discoveredDevicesList->findItems(deviceLabel, Qt::MatchStartsWith);
+	// By default we use the status label and the color for the UNPAIRED state
+	QColor pairingColor = QColor(Qt::red);
+	QString pairingStatusLabel = QString("UNPAIRED");
+	QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(remoteDeviceInfo.address());
 
-	// Check if the remote device is already in the list
-	if (itemsWithSameSignature.empty()) {
-		QListWidgetItem *item = new QListWidgetItem(deviceLabel);
-		QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(remoteDeviceInfo.address());
-		item->setData(Qt::UserRole, QVariant::fromValue(remoteDeviceInfo));
+	if (pairingStatus == QBluetoothLocalDevice::Paired) {
+		pairingStatusLabel = QString("PAIRED");
+		pairingColor = QColor(Qt::gray);
+	} else if (pairingStatus == QBluetoothLocalDevice::AuthorizedPaired) {
+		pairingStatusLabel = QString("AUTHORIZED_PAIRED");
+		pairingColor = QColor(Qt::blue);
+	}
 
-		if (pairingStatus == QBluetoothLocalDevice::Paired) {
-			item->setText(QString("%1   [State: PAIRED]").arg(item->text()));
-			item->setBackgroundColor(QColor(Qt::gray));
-		} else if (pairingStatus == QBluetoothLocalDevice::AuthorizedPaired) {
-			item->setText(QString("%1   [State: AUTHORIZED_PAIRED]").arg(item->text()));
-			item->setBackgroundColor(QColor(Qt::blue));
-		} else {
-			item->setText(QString("%1   [State: UNPAIRED]").arg(item->text()));
-			item->setTextColor(QColor(Qt::black));
-		}
+	QString deviceLabel = QString("%1 (%2)   [State: %3]").arg(remoteDeviceInfo.name(),
+								   remoteDeviceInfo.address().toString(),
+								   pairingStatusLabel);
+	QListWidgetItem *item = new QListWidgetItem(deviceLabel);
 
-		ui->discoveredDevicesList->addItem(item);
-	}
+	item->setData(Qt::UserRole, QVariant::fromValue(remoteDeviceInfo));
+	item->setBackgroundColor(pairingColor);
+
+	ui->discoveredDevicesList->addItem(item);
 }
 
 void BtDeviceSelectionDialog::itemClicked(QListWidgetItem *item)
-- 
2.4.3

From 28fe1c399d93c036047b9868085c20f802d9f036 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 20:17:11 +0300
Subject: [PATCH 04/18] Reimplement pairingFinished method

The old implementation didn't use the correct deviceLabel pattern.
When the pairing status of a device was changed the name of the device
was missing from the new label. With the new implementation when the
pairing status is changed we replace the old state with the new one and
maintain the device information from the old label.
Also we set the same pairing background colors used in the
addRemoteDevice callback. In this way the label's state is consistent
and the UX is improved.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 69 +++++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 31 deletions(-)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 7f53740..1f0c36e 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -242,46 +242,53 @@ void BtDeviceSelectionDialog::displayPairingMenu(const QPoint &pos)
 
 void BtDeviceSelectionDialog::pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing)
 {
+	// Determine the color, the new pairing status and the log message. By default we assume that the devices are UNPAIRED.
 	QString remoteDeviceStringAddress = address.toString();
-	QList<QListWidgetItem *> items = ui->discoveredDevicesList->findItems(remoteDeviceStringAddress, Qt::MatchContains);
-
-	if (pairing == QBluetoothLocalDevice::Paired || pairing == QBluetoothLocalDevice::Paired ) {
-		ui->dialogStatus->setText(QString("Device %1 was paired.")
-					  .arg(remoteDeviceStringAddress));
-
-		for (int i = 0; i < items.count(); ++i) {
-			QListWidgetItem *item = items.at(i);
-
-			item->setText(QString("%1   [State: PAIRED]").arg(remoteDeviceStringAddress));
-			item->setBackgroundColor(QColor(Qt::gray));
-		}
+	QColor pairingColor = QColor(Qt::red);
+	QString pairingStatusLabel = QString("UNPAIRED");
+	QString dialogStatusMessage = QString("Device %1 was unpaired.").arg(remoteDeviceStringAddress);
+	bool enableSaveButton = false;
 
-		QListWidgetItem *currentItem = ui->discoveredDevicesList->currentItem();
+	if (pairing == QBluetoothLocalDevice::Paired) {
+		pairingStatusLabel = QString("PAIRED");
+		pairingColor = QColor(Qt::gray);
+		enableSaveButton = true;
+		dialogStatusMessage = QString("Device %1 was paired.").arg(remoteDeviceStringAddress);
+	} else if (pairing == QBluetoothLocalDevice::AuthorizedPaired) {
+		pairingStatusLabel = QString("AUTHORIZED_PAIRED");
+		pairingColor = QColor(Qt::blue);
+		enableSaveButton = true;
+		dialogStatusMessage = QString("Device %1 was authorized paired.").arg(remoteDeviceStringAddress);
+	}
 
-		if (currentItem != NULL && currentItem->text().contains(remoteDeviceStringAddress, Qt::CaseInsensitive)) {
-			ui->dialogStatus->setText(QString("The device %1 can now be used for connection. You can press the Save button.")
-						  .arg(remoteDeviceStringAddress));
-			ui->save->setEnabled(true);
-		}
-	} else {
-		ui->dialogStatus->setText(QString("Device %1 was unpaired.")
-					  .arg(remoteDeviceStringAddress));
+	// Find the items which represent the BTH device and update their state
+	QList<QListWidgetItem *> items = ui->discoveredDevicesList->findItems(remoteDeviceStringAddress, Qt::MatchContains);
 
-		for (int i = 0; i < items.count(); ++i) {
-			QListWidgetItem *item = items.at(i);
+	for (int i = 0; i < items.count(); ++i) {
+		QListWidgetItem *item = items.at(i);
+		QString updatedDeviceLabel = item->text().replace(QRegularExpression("PAIRED|AUTHORIZED_PAIRED|UNPAIRED"),
+								  pairingStatusLabel);
 
-			item->setText(QString("%1   [State: UNPAIRED]").arg(remoteDeviceStringAddress));
-			item->setBackgroundColor(QColor(Qt::white));
-		}
+		item->setText(updatedDeviceLabel);
+		item->setBackgroundColor(pairingColor);
+	}
 
-		QListWidgetItem *currentItem = ui->discoveredDevicesList->currentItem();
+	// Check if the updated device is the selected one from the list and inform the user that it can/cannot start the download mode
+	QListWidgetItem *currentItem = ui->discoveredDevicesList->currentItem();
 
-		if (currentItem != NULL && currentItem->text().contains(remoteDeviceStringAddress, Qt::CaseInsensitive)) {
-			ui->dialogStatus->setText(QString("The device %1 must be paired in order to be used. Please use the context menu for pairing options.")
-						  .arg(remoteDeviceStringAddress));
-			ui->save->setEnabled(false);
+	if (currentItem != NULL && currentItem->text().contains(remoteDeviceStringAddress, Qt::CaseInsensitive)) {
+		if (pairing == QBluetoothLocalDevice::Unpaired) {
+			dialogStatusMessage = QString("The device %1 must be paired in order to be used. Please use the context menu for pairing options.")
+						     .arg(remoteDeviceStringAddress);
+		} else {
+			dialogStatusMessage = QString("The device %1 can now be used for connection. You can press the Save button.")
+						     .arg(remoteDeviceStringAddress);
 		}
 	}
+
+	// Update the save button and the dialog status message
+	ui->save->setEnabled(enableSaveButton);
+	ui->dialogStatus->setText(dialogStatusMessage);
 }
 
 void BtDeviceSelectionDialog::error(QBluetoothLocalDevice::Error error)
-- 
2.4.3

From 973ca8bce707f6dac706140000bc81370b5e2a42 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 20:17:45 +0300
Subject: [PATCH 05/18] Add set_timeout callback for Bluetooth custom serial
 implementation

The new callback will be usefull when we will implement the support
for Windows. The implementation of native serial set_timeout method
uses a HANDLER on Windows and we will use the WinSock2 API which has
a socket descriptor.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qtserialbluetooth.cpp | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/qtserialbluetooth.cpp b/qtserialbluetooth.cpp
index 5a982d6..378f330 100644
--- a/qtserialbluetooth.cpp
+++ b/qtserialbluetooth.cpp
@@ -224,6 +224,15 @@ static int qt_serial_get_transmitted(serial_t *device)
 	return device->socket->bytesToWrite();
 }
 
+static int qt_serial_set_timeout(serial_t *device, long timeout)
+{
+	if (device == NULL)
+		return DC_STATUS_INVALIDARGS;
+
+	device->timeout = timeout;
+
+	return DC_STATUS_SUCCESS;
+}
 
 const dc_serial_operations_t qt_serial_ops = {
 	.open = qt_serial_open,
@@ -232,7 +241,8 @@ const dc_serial_operations_t qt_serial_ops = {
 	.write = qt_serial_write,
 	.flush = qt_serial_flush,
 	.get_received = qt_serial_get_received,
-	.get_transmitted = qt_serial_get_transmitted
+	.get_transmitted = qt_serial_get_transmitted,
+	.set_timeout = qt_serial_set_timeout
 };
 
 extern void dc_serial_init (dc_serial_t *serial, void *data, const dc_serial_operations_t *ops);
-- 
2.4.3

From 49f4def96ee20ddb9b99686d3bc9ae34ce9a4e7d Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 20:51:10 +0300
Subject: [PATCH 06/18] Add skeleton for Bluetooth custom serial implementation
 on Windows platforms

Add a skeleton which will be used to develop the Bluetooth custom
serial implementation for Windows platforms.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 87 ++++++++++++++++++++++++++++++++++++++-
 qt-ui/btdeviceselectiondialog.h   | 46 ++++++++++++++++++++-
 qtserialbluetooth.cpp             | 72 +++++++++++++++++++++++++++++---
 3 files changed, 197 insertions(+), 8 deletions(-)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 1f0c36e..74378ee 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -8,7 +8,6 @@
 
 BtDeviceSelectionDialog::BtDeviceSelectionDialog(QWidget *parent) :
 	QDialog(parent),
-	localDevice(new QBluetoothLocalDevice),
 	ui(new Ui::BtDeviceSelectionDialog)
 {
 	ui->setupUi(this);
@@ -21,9 +20,16 @@ BtDeviceSelectionDialog::BtDeviceSelectionDialog(QWidget *parent) :
 	// Disable the save button because there is no device selected
 	ui->save->setEnabled(false);
 
+	// Add event for item selection
 	connect(ui->discoveredDevicesList, SIGNAL(itemClicked(QListWidgetItem*)),
 		this, SLOT(itemClicked(QListWidgetItem*)));
 
+#if defined(Q_OS_WIN)
+	// TODO do the initialization
+#else
+	// Initialize the local Bluetooth device
+	localDevice = new QBluetoothLocalDevice();
+
 	// Populate the list with local bluetooth devices
 	QList<QBluetoothHostInfo> localAvailableDevices = localDevice->allDevices();
 	int availableDevicesSize = localAvailableDevices.size();
@@ -56,15 +62,19 @@ BtDeviceSelectionDialog::BtDeviceSelectionDialog(QWidget *parent) :
 	// Initialize the device discovery agent
 	if (localDevice->isValid())
 		initializeDeviceDiscoveryAgent();
+#endif
 }
 
 BtDeviceSelectionDialog::~BtDeviceSelectionDialog()
 {
 	delete ui;
 
+#if defined(Q_OS_WIN)
+	// Terminate the use of Winsock 2 DLL
+#else
 	// Clean the local device
 	delete localDevice;
-
+#endif
 	// Clean the device discovery agent
 	if (remoteDeviceDiscoveryAgent->isActive())
 		remoteDeviceDiscoveryAgent->stop();
@@ -74,6 +84,9 @@ BtDeviceSelectionDialog::~BtDeviceSelectionDialog()
 
 void BtDeviceSelectionDialog::on_changeDeviceState_clicked()
 {
+#if defined(Q_OS_WIN)
+	// TODO add implementation
+#else
 	if (localDevice->hostMode() == QBluetoothLocalDevice::HostPoweredOff) {
 		ui->dialogStatus->setText("Trying to turn on the local Bluetooth device...");
 		localDevice->powerOn();
@@ -81,6 +94,7 @@ void BtDeviceSelectionDialog::on_changeDeviceState_clicked()
 		ui->dialogStatus->setText("Trying to turn off the local Bluetooth device...");
 		localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff);
 	}
+#endif
 }
 
 void BtDeviceSelectionDialog::on_save_clicked()
@@ -136,16 +150,23 @@ void BtDeviceSelectionDialog::remoteDeviceScanFinished()
 
 void BtDeviceSelectionDialog::hostModeStateChanged(QBluetoothLocalDevice::HostMode mode)
 {
+#if defined(Q_OS_WIN)
+	// TODO add implementation
+#else
 	bool on = !(mode == QBluetoothLocalDevice::HostPoweredOff);
 
 	ui->dialogStatus->setText(QString("The local Bluetooth device was turned %1.")
 				  .arg(on? "ON" : "OFF"));
 	ui->deviceState->setChecked(on);
 	ui->scan->setEnabled(on);
+#endif
 }
 
 void BtDeviceSelectionDialog::addRemoteDevice(const QBluetoothDeviceInfo &remoteDeviceInfo)
 {
+#if defined(Q_OS_WIN)
+	// TODO add the remote device
+#else
 	// By default we use the status label and the color for the UNPAIRED state
 	QColor pairingColor = QColor(Qt::red);
 	QString pairingStatusLabel = QString("UNPAIRED");
@@ -168,10 +189,14 @@ void BtDeviceSelectionDialog::addRemoteDevice(const QBluetoothDeviceInfo &remote
 	item->setBackgroundColor(pairingColor);
 
 	ui->discoveredDevicesList->addItem(item);
+#endif
 }
 
 void BtDeviceSelectionDialog::itemClicked(QListWidgetItem *item)
 {
+#if defined(Q_OS_WIN)
+	// TODO enable the save button and log the information about the selected item
+#else
 	QBluetoothDeviceInfo remoteDeviceInfo = item->data(Qt::UserRole).value<QBluetoothDeviceInfo>();
 	QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(remoteDeviceInfo.address());
 
@@ -184,10 +209,14 @@ void BtDeviceSelectionDialog::itemClicked(QListWidgetItem *item)
 					  .arg(remoteDeviceInfo.address().toString()));
 		ui->save->setEnabled(true);
 	}
+#endif
 }
 
 void BtDeviceSelectionDialog::localDeviceChanged(int index)
 {
+#if defined(Q_OS_WIN)
+	// TODO add implementation
+#else
 	QBluetoothAddress localDeviceSelectedAddress = ui->localSelectedDevice->itemData(index, Qt::UserRole).value<QBluetoothAddress>();
 
 	// Delete the old localDevice
@@ -208,10 +237,14 @@ void BtDeviceSelectionDialog::localDeviceChanged(int index)
 	// Initialize the device discovery agent
 	if (localDevice->isValid())
 		initializeDeviceDiscoveryAgent();
+#endif
 }
 
 void BtDeviceSelectionDialog::displayPairingMenu(const QPoint &pos)
 {
+#if defined(Q_OS_WIN)
+	// TODO add implementation
+#else
 	QMenu menu(this);
 	QAction *pairAction = menu.addAction("Pair");
 	QAction *removePairAction = menu.addAction("Remove Pairing");
@@ -238,6 +271,7 @@ void BtDeviceSelectionDialog::displayPairingMenu(const QPoint &pos)
 					  .arg(currentRemoteDeviceInfo.address().toString()));
 		localDevice->requestPairing(currentRemoteDeviceInfo.address(), QBluetoothLocalDevice::Unpaired);
 	}
+#endif
 }
 
 void BtDeviceSelectionDialog::pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing)
@@ -338,6 +372,9 @@ QString BtDeviceSelectionDialog::getSelectedDeviceName()
 
 void BtDeviceSelectionDialog::updateLocalDeviceInformation()
 {
+#if defined(Q_OS_WIN)
+	// TODO add implementation
+#else
 	// Check if the selected Bluetooth device can be accessed
 	if (!localDevice->isValid()) {
 		QString na = QString("Not available");
@@ -377,10 +414,14 @@ void BtDeviceSelectionDialog::updateLocalDeviceInformation()
 
 	connect(localDevice, SIGNAL(error(QBluetoothLocalDevice::Error)),
 		this, SLOT(error(QBluetoothLocalDevice::Error)));
+#endif
 }
 
 void BtDeviceSelectionDialog::initializeDeviceDiscoveryAgent()
 {
+#if defined(Q_OS_WIN)
+	// TODO initialize the discovery agent
+#else
 	// Intialize the discovery agent
 	remoteDeviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(localDevice->address());
 
@@ -400,4 +441,46 @@ void BtDeviceSelectionDialog::initializeDeviceDiscoveryAgent()
 		this, SLOT(remoteDeviceScanFinished()));
 	connect(remoteDeviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
 		this, SLOT(deviceDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error)));
+#endif
+}
+
+#if defined(Q_OS_WIN)
+WinBluetoothDeviceDiscoveryAgent::WinBluetoothDeviceDiscoveryAgent(QObject *parent) : QThread(parent)
+{
+	// Initialize the internal flags by their default values
+	running = false;
+	stopped = false;
+	lastError = QBluetoothDeviceDiscoveryAgent::NoError;
+	lastErrorToString = QString("No error");
+}
+
+WinBluetoothDeviceDiscoveryAgent::~WinBluetoothDeviceDiscoveryAgent()
+{
+}
+
+bool WinBluetoothDeviceDiscoveryAgent::isActive() const
+{
+	return running;
+}
+
+QString WinBluetoothDeviceDiscoveryAgent::errorToString() const
+{
+	return lastErrorToString;
+}
+
+QBluetoothDeviceDiscoveryAgent::Error WinBluetoothDeviceDiscoveryAgent::error() const
+{
+	return lastError;
+}
+
+void WinBluetoothDeviceDiscoveryAgent::run()
+{
+	// TODO initialize the resources and start the device discovery
+}
+
+void WinBluetoothDeviceDiscoveryAgent::stop()
+{
+	// Stop the inqury
+	stopped = true;
 }
+#endif
diff --git a/qt-ui/btdeviceselectiondialog.h b/qt-ui/btdeviceselectiondialog.h
index b6c34e8..534e9b9 100644
--- a/qt-ui/btdeviceselectiondialog.h
+++ b/qt-ui/btdeviceselectiondialog.h
@@ -8,7 +8,23 @@
 #include <QtBluetooth/qbluetoothglobal.h>
 #include <QtBluetooth/QBluetoothDeviceDiscoveryAgent>
 
-#if QT_VERSION < 0x050500
+#if defined(Q_OS_WIN)
+	#include <QThread>
+	#include <winsock2.h>
+	#include <ws2bth.h>
+
+	#define SUCCESS				0
+	#define BTH_ADDR_STR_LEN                40
+
+	#undef ERROR				// this is already declared in our headers
+	#undef IGNORE				// this is already declared in our headers
+	#undef DC_VERSION			// this is already declared in libdivecomputer header
+#endif
+
+#if defined(Q_OS_WIN)
+Q_DECLARE_METATYPE(QBluetoothDeviceInfo)
+Q_DECLARE_METATYPE(QBluetoothDeviceDiscoveryAgent::Error)
+#elif QT_VERSION < 0x050500
 Q_DECLARE_METATYPE(QBluetoothDeviceInfo)
 #endif
 
@@ -16,6 +32,30 @@ namespace Ui {
 	class BtDeviceSelectionDialog;
 }
 
+#if defined(Q_OS_WIN)
+class WinBluetoothDeviceDiscoveryAgent : public QThread {
+	Q_OBJECT
+signals:
+	void deviceDiscovered(const QBluetoothDeviceInfo &info);
+	void error(QBluetoothDeviceDiscoveryAgent::Error error);
+
+public:
+	WinBluetoothDeviceDiscoveryAgent(QObject *parent);
+	~WinBluetoothDeviceDiscoveryAgent();
+	bool isActive() const;
+	QString errorToString() const;
+	QBluetoothDeviceDiscoveryAgent::Error error() const;
+	virtual void run();
+	virtual void stop();
+
+private:
+	bool running;
+	bool stopped;
+	QString lastErrorToString;
+	QBluetoothDeviceDiscoveryAgent::Error lastError;
+};
+#endif
+
 class BtDeviceSelectionDialog : public QDialog {
 	Q_OBJECT
 
@@ -42,8 +82,12 @@ private slots:
 
 private:
 	Ui::BtDeviceSelectionDialog *ui;
+#if defined(Q_OS_WIN)
+	WinBluetoothDeviceDiscoveryAgent *remoteDeviceDiscoveryAgent;
+#else
 	QBluetoothLocalDevice *localDevice;
 	QBluetoothDeviceDiscoveryAgent *remoteDeviceDiscoveryAgent;
+#endif
 	QSharedPointer<QBluetoothDeviceInfo> selectedRemoteDeviceInfo;
 
 	void updateLocalDeviceInformation();
diff --git a/qtserialbluetooth.cpp b/qtserialbluetooth.cpp
index 378f330..37ea225 100644
--- a/qtserialbluetooth.cpp
+++ b/qtserialbluetooth.cpp
@@ -10,6 +10,12 @@
 
 #if defined(SSRF_CUSTOM_SERIAL)
 
+#if defined(Q_OS_WIN)
+	#include <winsock2.h>
+	#include <windows.h>
+	#include <ws2bth.h>
+#endif
+
 #include <libdivecomputer/custom_serial.h>
 
 extern "C" {
@@ -19,7 +25,11 @@ typedef struct serial_t {
 	/*
 	 * RFCOMM socket used for Bluetooth Serial communication.
 	 */
+#if defined(Q_OS_WIN)
+	SOCKET socket;
+#else
 	QBluetoothSocket *socket;
+#endif
 	long timeout;
 } serial_t;
 
@@ -40,6 +50,9 @@ static int qt_serial_open(serial_t **out, dc_context_t *context, const char* dev
 	// Default to blocking reads.
 	serial_port->timeout = -1;
 
+#if defined(Q_OS_WIN)
+	// TODO connect the device
+#else
 	// Create a RFCOMM socket
 	serial_port->socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
 
@@ -118,7 +131,7 @@ static int qt_serial_open(serial_t **out, dc_context_t *context, const char* dev
 			return QBluetoothSocket::UnknownSocketError;
 		}
 	}
-
+#endif
 	*out = serial_port;
 
 	return DC_STATUS_SUCCESS;
@@ -126,19 +139,36 @@ static int qt_serial_open(serial_t **out, dc_context_t *context, const char* dev
 
 static int qt_serial_close(serial_t *device)
 {
-	if (device == NULL || device->socket == NULL)
+	if (device == NULL)
 		return DC_STATUS_SUCCESS;
 
+#if defined(Q_OS_WIN)
+	// TODO do the cleanup
+#else
+	if (device->socket == NULL) {
+		free(device);
+		return DC_STATUS_SUCCESS;
+	}
+
 	device->socket->close();
 
 	delete device->socket;
 	free(device);
+#endif
 
 	return DC_STATUS_SUCCESS;
 }
 
 static int qt_serial_read(serial_t *device, void* data, unsigned int size)
 {
+#if defined(Q_OS_WIN)
+	if (device == NULL)
+		return DC_STATUS_INVALIDARGS;
+
+	// TODO read *size* bytes from the device
+
+	return 0;
+#else
 	if (device == NULL || device->socket == NULL)
 		return DC_STATUS_INVALIDARGS;
 
@@ -167,10 +197,19 @@ static int qt_serial_read(serial_t *device, void* data, unsigned int size)
 	}
 
 	return nbytes;
+#endif
 }
 
 static int qt_serial_write(serial_t *device, const void* data, unsigned int size)
 {
+#if defined(Q_OS_WIN)
+	if (device == NULL)
+		return DC_STATUS_INVALIDARGS;
+
+	// TODO write *size* bytes from data to the device
+
+	return 0;
+#else
 	if (device == NULL || device->socket == NULL)
 		return DC_STATUS_INVALIDARGS;
 
@@ -196,32 +235,54 @@ static int qt_serial_write(serial_t *device, const void* data, unsigned int size
 	}
 
 	return nbytes;
+#endif
 }
 
 static int qt_serial_flush(serial_t *device, int queue)
 {
-	if (device == NULL || device->socket == NULL)
+	if (device == NULL)
 		return DC_STATUS_INVALIDARGS;
-
-	//TODO: add implementation
+#if !defined(Q_OS_WIN)
+	if (device->socket == NULL)
+		return DC_STATUS_INVALIDARGS;
+#endif
+	// TODO: add implementation
 
 	return DC_STATUS_SUCCESS;
 }
 
 static int qt_serial_get_received(serial_t *device)
 {
+#if defined(Q_OS_WIN)
+	if (device == NULL)
+		return DC_STATUS_INVALIDARGS;
+
+	// TODO use WSAIoctl to get the information
+
+	return 0;
+#else
 	if (device == NULL || device->socket == NULL)
 		return DC_STATUS_INVALIDARGS;
 
 	return device->socket->bytesAvailable();
+#endif
 }
 
 static int qt_serial_get_transmitted(serial_t *device)
 {
+#if defined(Q_OS_WIN)
+	if (device == NULL)
+		return DC_STATUS_INVALIDARGS;
+
+	// TODO add implementation
+
+	return 0;
+#else
 	if (device == NULL || device->socket == NULL)
 		return DC_STATUS_INVALIDARGS;
 
 	return device->socket->bytesToWrite();
+#endif
 }
 
 static int qt_serial_set_timeout(serial_t *device, long timeout)
@@ -234,6 +295,7 @@ static int qt_serial_set_timeout(serial_t *device, long timeout)
 	return DC_STATUS_SUCCESS;
 }
 
+
 const dc_serial_operations_t qt_serial_ops = {
 	.open = qt_serial_open,
 	.close = qt_serial_close,
-- 
2.4.3

From 144cce27e93c10a413b74c3dcf8ca8f27dd39b48 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 21:37:11 +0300
Subject: [PATCH 07/18] Add implementation for BTH custom serial open method on
 Windows platforms

Implement the custom serial open method using the WinSocket2 API.
First the device address is converted from text representation into
a sockaddr structure. Then a connection is initiated to the device
using device's Serial Port service.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qtserialbluetooth.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/qtserialbluetooth.cpp b/qtserialbluetooth.cpp
index 37ea225..0edd3d4 100644
--- a/qtserialbluetooth.cpp
+++ b/qtserialbluetooth.cpp
@@ -51,7 +51,49 @@ static int qt_serial_open(serial_t **out, dc_context_t *context, const char* dev
 	serial_port->timeout = -1;
 
 #if defined(Q_OS_WIN)
-	// TODO connect the device
+	// Create a RFCOMM socket
+	serial_port->socket = ::socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
+
+	if (serial_port->socket == INVALID_SOCKET)
+		return DC_STATUS_IO;
+
+	SOCKADDR_BTH socketBthAddress;
+	int socketBthAddressBth = sizeof (socketBthAddress);
+	char *address = strdup(devaddr);
+
+	ZeroMemory(&socketBthAddress, socketBthAddressBth);
+	qDebug() << "Trying to connect to address " << devaddr;
+
+	if (WSAStringToAddressA(address,
+				AF_BTH,
+				NULL,
+				(LPSOCKADDR) &socketBthAddress,
+				&socketBthAddressBth
+				) != 0) {
+		qDebug() << "FAiled to convert the address " << address;
+		free(address);
+
+		return DC_STATUS_IO;
+	}
+
+	free(address);
+
+	socketBthAddress.addressFamily = AF_BTH;
+	socketBthAddress.port = BT_PORT_ANY;
+	memset(&socketBthAddress.serviceClassId, 0, sizeof(socketBthAddress.serviceClassId));
+	socketBthAddress.serviceClassId = SerialPortServiceClass_UUID;
+
+	// Try to connect to the device
+	if (::connect(serial_port->socket,
+		      (struct sockaddr *) &socketBthAddress,
+		      socketBthAddressBth
+		      ) != 0) {
+		qDebug() << "Failed to connect to device";
+
+		return DC_STATUS_NODEVICE;
+	}
+
+	qDebug() << "Succesfully connected to device";
 #else
 	// Create a RFCOMM socket
 	serial_port->socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
-- 
2.4.3

From aace54e4b28e17df18aefc329318e65467e6c275 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 21:37:50 +0300
Subject: [PATCH 08/18] Add implementation for BTH custom serial close method
 on Windows

Implement the close method used on Windows platforms for our custom
serial implementation.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qtserialbluetooth.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/qtserialbluetooth.cpp b/qtserialbluetooth.cpp
index 0edd3d4..20f2ecd 100644
--- a/qtserialbluetooth.cpp
+++ b/qtserialbluetooth.cpp
@@ -185,7 +185,9 @@ static int qt_serial_close(serial_t *device)
 		return DC_STATUS_SUCCESS;
 
 #if defined(Q_OS_WIN)
-	// TODO do the cleanup
+	// Cleanup
+	closesocket(device->socket);
+	free(device);
 #else
 	if (device->socket == NULL) {
 		free(device);
-- 
2.4.3

From fb77b91eb893825169b4395d1dc5378ff621c648 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 21:38:17 +0300
Subject: [PATCH 09/18] Add implementation for BTH custom serial read method
 used on Windows

Implement the read method used for our custom serial implementation
on Windows platforms.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qtserialbluetooth.cpp | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/qtserialbluetooth.cpp b/qtserialbluetooth.cpp
index 20f2ecd..9d1c14b 100644
--- a/qtserialbluetooth.cpp
+++ b/qtserialbluetooth.cpp
@@ -209,9 +209,22 @@ static int qt_serial_read(serial_t *device, void* data, unsigned int size)
 	if (device == NULL)
 		return DC_STATUS_INVALIDARGS;
 
-	// TODO read *size* bytes from the device
+	unsigned int nbytes = 0;
+	int rc;
 
-	return 0;
+	while (nbytes < size) {
+		rc = recv (device->socket, (char *) data + nbytes, size - nbytes, 0);
+
+		if (rc < 0) {
+			return -1; // Error during recv call.
+		} else if (rc == 0) {
+			break; // EOF reached.
+		}
+
+		nbytes += rc;
+	}
+
+	return nbytes;
 #else
 	if (device == NULL || device->socket == NULL)
 		return DC_STATUS_INVALIDARGS;
-- 
2.4.3

From 7fd70f862f1e815244e63377cc1876a3fbbfe631 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 21:38:47 +0300
Subject: [PATCH 10/18] Add implementation for BTH custom serial write method
 used on Windows

Implement the write method used for our custom serial implementation
on Windows platforms.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qtserialbluetooth.cpp | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/qtserialbluetooth.cpp b/qtserialbluetooth.cpp
index 9d1c14b..45fc8d1 100644
--- a/qtserialbluetooth.cpp
+++ b/qtserialbluetooth.cpp
@@ -263,9 +263,20 @@ static int qt_serial_write(serial_t *device, const void* data, unsigned int size
 	if (device == NULL)
 		return DC_STATUS_INVALIDARGS;
 
-	// TODO write *size* bytes from data to the device
+	unsigned int nbytes = 0;
+	int rc;
 
-	return 0;
+	while (nbytes < size) {
+	    rc = send(device->socket, (char *) data + nbytes, size - nbytes, 0);
+
+	    if (rc < 0) {
+	       return -1; // Error during send call.
+	    }
+
+	    nbytes += rc;
+	}
+
+	return nbytes;
 #else
 	if (device == NULL || device->socket == NULL)
 		return DC_STATUS_INVALIDARGS;
-- 
2.4.3

From 007f4063b9813e03fdc14b4c6544b3f8f4b806b4 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 22:08:32 +0300
Subject: [PATCH 11/18] 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 <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 101 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 100 insertions(+), 1 deletion(-)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 74378ee..e00c803 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()
-- 
2.4.3

From ddb6bb5e1ba5a4a42528c14f901f330480c45346 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 22:12:58 +0300
Subject: [PATCH 12/18] Initialize WinSock and hide the information about the
 local device

On Windows we cannot select a device or show information about the
local device. Therefore we disable the UI section related to local
device details.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index e00c803..4da3025 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -25,7 +25,23 @@ BtDeviceSelectionDialog::BtDeviceSelectionDialog(QWidget *parent) :
 		this, SLOT(itemClicked(QListWidgetItem*)));
 
 #if defined(Q_OS_WIN)
-	// TODO do the initialization
+	ULONG       ulRetCode = SUCCESS;
+	WSADATA     WSAData = { 0 };
+
+	// Initialize WinSock and ask for version 2.2.
+	ulRetCode = WSAStartup(MAKEWORD(2, 2), &WSAData);
+	if (ulRetCode != SUCCESS) {
+		QMessageBox::StandardButton warningBox;
+		warningBox = QMessageBox::critical(this, "Bluetooth",
+						   "Could not initialize the Winsock version 2.2", QMessageBox::Ok);
+		return;
+	}
+
+	// Initialize the device discovery agent
+	initializeDeviceDiscoveryAgent();
+
+	// On Windows we cannot select a device or show information about the local device
+	ui->localDeviceDetails->hide();
 #else
 	// Initialize the local Bluetooth device
 	localDevice = new QBluetoothLocalDevice();
@@ -71,6 +87,7 @@ BtDeviceSelectionDialog::~BtDeviceSelectionDialog()
 
 #if defined(Q_OS_WIN)
 	// Terminate the use of Winsock 2 DLL
+	WSACleanup();
 #else
 	// Clean the local device
 	delete localDevice;
-- 
2.4.3

From 293e58b0559f2991d2a78bf31277993dd72ed6e1 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 22:16:29 +0300
Subject: [PATCH 13/18] Wait for BTH device discovery thread to finish on stop
 call

We should wait for the WinBluetoothDeviceDiscoveryAgent completion
when the stop method was called.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 4da3025..82512b4 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -93,8 +93,12 @@ BtDeviceSelectionDialog::~BtDeviceSelectionDialog()
 	delete localDevice;
 #endif
 	// Clean the device discovery agent
-	if (remoteDeviceDiscoveryAgent->isActive())
+	if (remoteDeviceDiscoveryAgent->isActive()) {
 		remoteDeviceDiscoveryAgent->stop();
+#if defined(Q_OS_WIN)
+		remoteDeviceDiscoveryAgent->wait();
+#endif
+	}
 
 	delete remoteDeviceDiscoveryAgent;
 }
@@ -126,6 +130,9 @@ void BtDeviceSelectionDialog::on_save_clicked()
 	if (remoteDeviceDiscoveryAgent->isActive()) {
 		// Stop the SDP agent if the clear button is pressed and enable the Scan button
 		remoteDeviceDiscoveryAgent->stop();
+#if defined(Q_OS_WIN)
+		remoteDeviceDiscoveryAgent->wait();
+#endif
 		ui->scan->setEnabled(true);
 	}
 
@@ -142,6 +149,9 @@ void BtDeviceSelectionDialog::on_clear_clicked()
 	if (remoteDeviceDiscoveryAgent->isActive()) {
 		// Stop the SDP agent if the clear button is pressed and enable the Scan button
 		remoteDeviceDiscoveryAgent->stop();
+#if defined(Q_OS_WIN)
+		remoteDeviceDiscoveryAgent->wait();
+#endif
 		ui->scan->setEnabled(true);
 	}
 }
-- 
2.4.3

From b8183839b0e129322d9d4fca2f36a34a85c12391 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 22:27:16 +0300
Subject: [PATCH 14/18] Add implementation for add remote Bluetooth device
 handler

On Windows we cannot determine the pairing status of the
device. Therefore we print only information about its name
and about its BTH address.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 82512b4..375b699 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -192,7 +192,10 @@ void BtDeviceSelectionDialog::hostModeStateChanged(QBluetoothLocalDevice::HostMo
 void BtDeviceSelectionDialog::addRemoteDevice(const QBluetoothDeviceInfo &remoteDeviceInfo)
 {
 #if defined(Q_OS_WIN)
-	// TODO add the remote device
+	// On Windows we cannot obtain the pairing status so we set only the name and the address of the device
+	QString deviceLabel = QString("%1 (%2)").arg(remoteDeviceInfo.name(),
+						     remoteDeviceInfo.address().toString());
+	QColor pairingColor = QColor(Qt::white);
 #else
 	// By default we use the status label and the color for the UNPAIRED state
 	QColor pairingColor = QColor(Qt::red);
@@ -210,13 +213,14 @@ void BtDeviceSelectionDialog::addRemoteDevice(const QBluetoothDeviceInfo &remote
 	QString deviceLabel = QString("%1 (%2)   [State: %3]").arg(remoteDeviceInfo.name(),
 								   remoteDeviceInfo.address().toString(),
 								   pairingStatusLabel);
+#endif
+	// Create the new item, set its information and add it to the list
 	QListWidgetItem *item = new QListWidgetItem(deviceLabel);
 
 	item->setData(Qt::UserRole, QVariant::fromValue(remoteDeviceInfo));
 	item->setBackgroundColor(pairingColor);
 
 	ui->discoveredDevicesList->addItem(item);
-#endif
 }
 
 void BtDeviceSelectionDialog::itemClicked(QListWidgetItem *item)
-- 
2.4.3

From 0bcfd6f061c4f92a2ccd0754047c9761ae389e0b Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 22:43:42 +0300
Subject: [PATCH 18/18] Use the address of the BTH device if its name is empty

There are moments when the name of the device is not collected
properly and it is unavailable. Instead of showing an empty string
then print the address of the device.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/downloadfromdivecomputer.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/qt-ui/downloadfromdivecomputer.cpp b/qt-ui/downloadfromdivecomputer.cpp
index 4127376..907a49a 100644
--- a/qt-ui/downloadfromdivecomputer.cpp
+++ b/qt-ui/downloadfromdivecomputer.cpp
@@ -554,7 +554,13 @@ void DownloadFromDCWidget::bluetoothSelectionDialogIsFinished(int result)
 {
 	if (result == QDialog::Accepted) {
 		/* Make the selected Bluetooth device default */
-		ui.device->setCurrentText(btDeviceSelectionDialog->getSelectedDeviceName());
+		QString selectedDeviceName = btDeviceSelectionDialog->getSelectedDeviceName();
+
+		if (selectedDeviceName == NULL || selectedDeviceName.isEmpty()) {
+			ui.device->setCurrentText(btDeviceSelectionDialog->getSelectedDeviceAddress());
+		} else {
+			ui.device->setCurrentText(selectedDeviceName);
+		}
 	} else if (result == QDialog::Rejected){
 		/* Disable Bluetooth download mode */
 		ui.bluetoothMode->setChecked(false);
-- 
2.4.3

From 6626ac3bf83c0980fd574b66d45cbdd22f4dccc4 Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 22:42:51 +0300
Subject: [PATCH 17/18] Add implementation for device discovery agent
 initialization (Windows)

Register the metatypes needed for Windows platforms and initialize
our custom device discovery agent.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 844b102..b1e037a 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -458,7 +458,14 @@ void BtDeviceSelectionDialog::updateLocalDeviceInformation()
 void BtDeviceSelectionDialog::initializeDeviceDiscoveryAgent()
 {
 #if defined(Q_OS_WIN)
-	// TODO initialize the discovery agent
+	// Register QBluetoothDeviceInfo metatype
+	qRegisterMetaType<QBluetoothDeviceInfo>();
+
+	// Register QBluetoothDeviceDiscoveryAgent metatype (Needed for QBluetoothDeviceDiscoveryAgent::Error)
+	qRegisterMetaType<QBluetoothDeviceDiscoveryAgent::Error>();
+
+	// Intialize the discovery agent
+	remoteDeviceDiscoveryAgent = new WinBluetoothDeviceDiscoveryAgent(this);
 #else
 	// Intialize the discovery agent
 	remoteDeviceDiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(localDevice->address());
@@ -472,14 +479,13 @@ void BtDeviceSelectionDialog::initializeDeviceDiscoveryAgent()
 		ui->clear->setEnabled(false);
 		return;
 	}
-
+#endif
 	connect(remoteDeviceDiscoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),
 		this, SLOT(addRemoteDevice(QBluetoothDeviceInfo)));
 	connect(remoteDeviceDiscoveryAgent, SIGNAL(finished()),
 		this, SLOT(remoteDeviceScanFinished()));
 	connect(remoteDeviceDiscoveryAgent, SIGNAL(error(QBluetoothDeviceDiscoveryAgent::Error)),
 		this, SLOT(deviceDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error)));
-#endif
 }
 
 #if defined(Q_OS_WIN)
-- 
2.4.3

From c8792dfe46df8d1d61e0c08ea49b21a414c93dde Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 22:39:51 +0300
Subject: [PATCH 16/18] Get a pretty print message when a device discovery
 error occured

Try to get a pretty print message when a device discovery error
is raised and it is unknown.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 54cec11..844b102 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -379,7 +379,11 @@ void BtDeviceSelectionDialog::deviceDiscoveryError(QBluetoothDeviceDiscoveryAgen
 		errorDescription = QString("Writing or reading from the device resulted in an error.");
 		break;
 	default:
+#if defined(Q_OS_WIN)
+		errorDescription = remoteDeviceDiscoveryAgent->errorToString();
+#else
 		errorDescription = QString("An unknown error has occurred.");
+#endif
 		break;
 	}
 
-- 
2.4.3

From aa8738c5d6d5ace9f568c9657f2061b8628b27da Mon Sep 17 00:00:00 2001
From: Claudiu Olteanu <[email protected]>
Date: Tue, 18 Aug 2015 22:38:14 +0300
Subject: [PATCH 15/18] Add implementation for BTH device item selection on
 Windows platforms

When a Bluetooth device is selected from the discovered list
display information about its address and enable the save button.
On Windows we don't need to check if the devices are paired because
the pairing process is done automatically on the connection step.
If the devices are not paired Windows will ask for user's permission
to continue the process.

Signed-off-by: Claudiu Olteanu <[email protected]>
---
 qt-ui/btdeviceselectiondialog.cpp | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/qt-ui/btdeviceselectiondialog.cpp b/qt-ui/btdeviceselectiondialog.cpp
index 375b699..54cec11 100644
--- a/qt-ui/btdeviceselectiondialog.cpp
+++ b/qt-ui/btdeviceselectiondialog.cpp
@@ -225,22 +225,25 @@ void BtDeviceSelectionDialog::addRemoteDevice(const QBluetoothDeviceInfo &remote
 
 void BtDeviceSelectionDialog::itemClicked(QListWidgetItem *item)
 {
-#if defined(Q_OS_WIN)
-	// TODO enable the save button and log the information about the selected item
-#else
+	// By default we assume that the devices are paired
 	QBluetoothDeviceInfo remoteDeviceInfo = item->data(Qt::UserRole).value<QBluetoothDeviceInfo>();
+	QString statusMessage = QString("The device %1 can be used for connection. You can press the Save button.")
+					.arg(remoteDeviceInfo.address().toString());
+	bool enableSaveButton = true;
+
+#if !defined(Q_OS_WIN)
+	// On other platforms than Windows we can obtain the pairing status so if the devices are not paired we disable the button
 	QBluetoothLocalDevice::Pairing pairingStatus = localDevice->pairingStatus(remoteDeviceInfo.address());
 
 	if (pairingStatus == QBluetoothLocalDevice::Unpaired) {
-		ui->dialogStatus->setText(QString("The device %1 must be paired in order to be used. Please use the context menu for pairing options.")
-					  .arg(remoteDeviceInfo.address().toString()));
-		ui->save->setEnabled(false);
-	} else {
-		ui->dialogStatus->setText(QString("The device %1 can be used for connection. You can press the Save button.")
-					  .arg(remoteDeviceInfo.address().toString()));
-		ui->save->setEnabled(true);
+		statusMessage = QString("The device %1 must be paired in order to be used. Please use the context menu for pairing options.")
+				.arg(remoteDeviceInfo.address().toString());
+		enableSaveButton = false;
 	}
 #endif
+	// Update the status message and the save button
+	ui->dialogStatus->setText(statusMessage);
+	ui->save->setEnabled(enableSaveButton);
 }
 
 void BtDeviceSelectionDialog::localDeviceChanged(int index)
-- 
2.4.3

_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to