mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
This is the fix for StartDiscovery/Connect/Disconnect/StartDiscovery.
PiperOrigin-RevId: 424866263
This commit is contained in:
@@ -97,9 +97,13 @@ bool BluetoothClassicMedium::StopDiscovery() {
|
|||||||
|
|
||||||
void BluetoothClassicMedium::InitializeDeviceWatcher() {
|
void BluetoothClassicMedium::InitializeDeviceWatcher() {
|
||||||
// create watcher
|
// create watcher
|
||||||
|
const winrt::param::iterable<winrt::hstring> RequestedProperties =
|
||||||
|
winrt::single_threaded_vector<winrt::hstring>(
|
||||||
|
{winrt::to_hstring("System.Devices.Aep.IsPresent")});
|
||||||
|
|
||||||
device_watcher_ = DeviceInformation::CreateWatcher(
|
device_watcher_ = DeviceInformation::CreateWatcher(
|
||||||
BLUETOOTH_SELECTOR, // aqsFilter
|
BLUETOOTH_SELECTOR, // aqsFilter
|
||||||
nullptr, // additionalProperties
|
RequestedProperties, // additionalProperties
|
||||||
DeviceInformationKind::AssociationEndpoint); // kind
|
DeviceInformationKind::AssociationEndpoint); // kind
|
||||||
|
|
||||||
// An app must subscribe to all of the added, removed, and updated events to
|
// An app must subscribe to all of the added, removed, and updated events to
|
||||||
@@ -177,8 +181,6 @@ std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_watcher_.Stop();
|
|
||||||
|
|
||||||
EnterCriticalSection(&critical_section_);
|
EnterCriticalSection(&critical_section_);
|
||||||
|
|
||||||
std::unique_ptr<BluetoothSocket> rfcommSocket =
|
std::unique_ptr<BluetoothSocket> rfcommSocket =
|
||||||
@@ -190,7 +192,7 @@ std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
rfcommSocket->Connect(requestedService.ConnectionHostName(),
|
rfcommSocket->Connect(requestedService.ConnectionHostName(),
|
||||||
requestedService.ConnectionServiceName());
|
requestedService.ConnectionServiceName());
|
||||||
} catch (std::exception exception) {
|
} catch (std::exception exception) {
|
||||||
// We will log and eat the exception since the caller
|
// We will log and eat the exception since the caller
|
||||||
// expects nullptr if it fails
|
// expects nullptr if it fails
|
||||||
@@ -320,6 +322,8 @@ api::BluetoothDevice* BluetoothClassicMedium::GetRemoteDevice(
|
|||||||
|
|
||||||
bool BluetoothClassicMedium::StartScanning() {
|
bool BluetoothClassicMedium::StartScanning() {
|
||||||
if (!IsWatcherStarted()) {
|
if (!IsWatcherStarted()) {
|
||||||
|
discovered_devices_by_id_.clear();
|
||||||
|
|
||||||
// The Start method can only be called when the DeviceWatcher is in the
|
// The Start method can only be called when the DeviceWatcher is in the
|
||||||
// Created, Stopped or Aborted state.
|
// Created, Stopped or Aborted state.
|
||||||
auto status = device_watcher_.Status();
|
auto status = device_watcher_.Status();
|
||||||
@@ -360,32 +364,37 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added(
|
|||||||
|
|
||||||
// Create an iterator for the internal list
|
// Create an iterator for the internal list
|
||||||
std::map<winrt::hstring, std::unique_ptr<BluetoothDevice>>::const_iterator
|
std::map<winrt::hstring, std::unique_ptr<BluetoothDevice>>::const_iterator
|
||||||
it = devices_by_id_.find(deviceInfo.Id());
|
it = discovered_devices_by_id_.find(deviceInfo.Id());
|
||||||
|
|
||||||
// Add to our internal list if necessary
|
// Add to our internal list if necessary
|
||||||
if (it == devices_by_id_.end()) {
|
if (it != discovered_devices_by_id_.end()) {
|
||||||
// Create a bluetooth device out of this id
|
// We're already tracking this one
|
||||||
winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync(
|
return winrt::fire_and_forget();
|
||||||
deviceInfo.Id())
|
|
||||||
.Completed(
|
|
||||||
[this, deviceInfo, wbd = std::move(windowsBluetoothDevice)](
|
|
||||||
auto&& async,
|
|
||||||
winrt::Windows::Foundation::AsyncStatus status) {
|
|
||||||
EnterCriticalSection(&critical_section_);
|
|
||||||
|
|
||||||
std::unique_ptr<BluetoothDevice> bluetoothDevice =
|
|
||||||
std::make_unique<BluetoothDevice>(async.get());
|
|
||||||
|
|
||||||
devices_by_id_[deviceInfo.Id()] = std::move(bluetoothDevice);
|
|
||||||
|
|
||||||
if (discovery_callback_.device_discovered_cb != nullptr) {
|
|
||||||
discovery_callback_.device_discovered_cb(
|
|
||||||
*devices_by_id_[deviceInfo.Id()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
LeaveCriticalSection(&critical_section_);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a bluetooth device out of this id
|
||||||
|
winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync(
|
||||||
|
deviceInfo.Id())
|
||||||
|
.Completed([this, deviceInfo](
|
||||||
|
winrt::Windows::Foundation::IAsyncOperation<
|
||||||
|
winrt::Windows::Devices::Bluetooth::BluetoothDevice>
|
||||||
|
bluetoothDevice,
|
||||||
|
winrt::Windows::Foundation::AsyncStatus status) {
|
||||||
|
EnterCriticalSection(&critical_section_);
|
||||||
|
|
||||||
|
std::unique_ptr<BluetoothDevice> bluetoothDeviceP =
|
||||||
|
std::make_unique<BluetoothDevice>(bluetoothDevice.get());
|
||||||
|
|
||||||
|
discovered_devices_by_id_[deviceInfo.Id()] =
|
||||||
|
std::move(bluetoothDeviceP);
|
||||||
|
|
||||||
|
if (discovery_callback_.device_discovered_cb != nullptr) {
|
||||||
|
discovery_callback_.device_discovered_cb(
|
||||||
|
*discovered_devices_by_id_[deviceInfo.Id()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&critical_section_);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return winrt::fire_and_forget();
|
return winrt::fire_and_forget();
|
||||||
@@ -393,10 +402,30 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added(
|
|||||||
|
|
||||||
winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated(
|
winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated(
|
||||||
DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) {
|
DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) {
|
||||||
if (IsWatcherStarted()) {
|
EnterCriticalSection(&critical_section_);
|
||||||
// TODO(jfcarroll): Check for device name change
|
|
||||||
|
if (!IsWatcherStarted()) {
|
||||||
|
// Spurious call, watcher has stopped or wasn't started
|
||||||
|
LeaveCriticalSection(&critical_section_);
|
||||||
|
return winrt::fire_and_forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto it = discovered_devices_by_id_.find(deviceInfoUpdate.Id());
|
||||||
|
|
||||||
|
if (it == discovered_devices_by_id_.end()) {
|
||||||
|
LeaveCriticalSection(&critical_section_);
|
||||||
|
// Not tracking this device
|
||||||
|
return winrt::fire_and_forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceInfoUpdate.Properties().HasKey(
|
||||||
|
winrt::to_hstring("System.ItemNameDisplay"))) {
|
||||||
|
discovery_callback_.device_name_changed_cb(
|
||||||
|
*discovered_devices_by_id_[deviceInfoUpdate.Id()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&critical_section_);
|
||||||
|
|
||||||
return winrt::fire_and_forget();
|
return winrt::fire_and_forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,14 +433,17 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed(
|
|||||||
DeviceWatcher sender, DeviceInformationUpdate deviceInfo) {
|
DeviceWatcher sender, DeviceInformationUpdate deviceInfo) {
|
||||||
EnterCriticalSection(&critical_section_);
|
EnterCriticalSection(&critical_section_);
|
||||||
|
|
||||||
if (IsWatcherStarted()) {
|
if (!IsWatcherStarted()) {
|
||||||
if (discovery_callback_.device_lost_cb != nullptr) {
|
return winrt::fire_and_forget();
|
||||||
discovery_callback_.device_lost_cb(*devices_by_id_[deviceInfo.Id()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
devices_by_id_.erase(deviceInfo.Id());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (discovery_callback_.device_lost_cb != nullptr) {
|
||||||
|
discovery_callback_.device_lost_cb(
|
||||||
|
*discovered_devices_by_id_[deviceInfo.Id()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
discovered_devices_by_id_.erase(deviceInfo.Id());
|
||||||
|
|
||||||
LeaveCriticalSection(&critical_section_);
|
LeaveCriticalSection(&critical_section_);
|
||||||
|
|
||||||
return winrt::fire_and_forget();
|
return winrt::fire_and_forget();
|
||||||
|
|||||||
@@ -173,7 +173,8 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
|
|||||||
|
|
||||||
// hstring is the only type of string winrt understands.
|
// hstring is the only type of string winrt understands.
|
||||||
// https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/hstring
|
// https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/hstring
|
||||||
std::map<winrt::hstring, std::unique_ptr<BluetoothDevice>> devices_by_id_;
|
std::map<winrt::hstring, std::unique_ptr<BluetoothDevice>>
|
||||||
|
discovered_devices_by_id_;
|
||||||
|
|
||||||
// CRITICAL_SECTION is a lightweight synchronization mechanism
|
// CRITICAL_SECTION is a lightweight synchronization mechanism
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/sync/critical-section-objects
|
// https://docs.microsoft.com/en-us/windows/win32/sync/critical-section-objects
|
||||||
|
|||||||
@@ -23,10 +23,6 @@ namespace windows {
|
|||||||
|
|
||||||
BluetoothSocket::BluetoothSocket(StreamSocket streamSocket)
|
BluetoothSocket::BluetoothSocket(StreamSocket streamSocket)
|
||||||
: windows_socket_(streamSocket) {
|
: windows_socket_(streamSocket) {
|
||||||
bluetooth_device_ = std::make_unique<BluetoothDevice>(
|
|
||||||
winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromHostNameAsync(
|
|
||||||
windows_socket_.Information().RemoteHostName())
|
|
||||||
.get());
|
|
||||||
input_stream_ =
|
input_stream_ =
|
||||||
std::make_unique<BluetoothInputStream>(windows_socket_.InputStream());
|
std::make_unique<BluetoothInputStream>(windows_socket_.InputStream());
|
||||||
output_stream_ =
|
output_stream_ =
|
||||||
|
|||||||
Reference in New Issue
Block a user