From fe9c9f90b6b86181d5322759b2b596aefc628019 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Tue, 12 Sep 2023 13:20:14 -0700 Subject: [PATCH] Refactored Bluetooth classic medium PiperOrigin-RevId: 564813626 --- .../windows/bluetooth_classic_medium.cc | 256 ++++++++++-------- .../windows/bluetooth_classic_medium.h | 112 ++------ 2 files changed, 166 insertions(+), 202 deletions(-) diff --git a/internal/platform/implementation/windows/bluetooth_classic_medium.cc b/internal/platform/implementation/windows/bluetooth_classic_medium.cc index 9daaa8d7..f1f98264 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_medium.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_medium.cc @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,11 +14,9 @@ #include "internal/platform/implementation/windows/bluetooth_classic_medium.h" -#include #include #include -#include #include #include #include @@ -31,6 +29,8 @@ #include "internal/platform/cancellation_flag.h" #include "internal/platform/cancellation_flag_listener.h" #include "internal/platform/exception.h" +#include "internal/platform/feature_flags.h" +#include "internal/platform/implementation/bluetooth_adapter.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/windows/bluetooth_adapter.h" #include "internal/platform/implementation/windows/bluetooth_classic_device.h" @@ -49,12 +49,31 @@ namespace nearby { namespace windows { namespace { -using winrt::Windows::Foundation::IInspectable; -using winrt::Windows::Foundation::Collections::IMapView; +using ::winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService; +using ::winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId; +using ::winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider; +using ::winrt::Windows::Devices::Enumeration::DeviceAccessInformation; +using ::winrt::Windows::Devices::Enumeration::DeviceAccessStatus; +using ::winrt::Windows::Devices::Enumeration::DeviceInformation; +using ::winrt::Windows::Devices::Enumeration::DeviceInformationKind; +using ::winrt::Windows::Devices::Enumeration::DeviceInformationUpdate; +using ::winrt::Windows::Devices::Enumeration::DeviceWatcher; +using ::winrt::Windows::Devices::Enumeration::DeviceWatcherStatus; +using ::winrt::Windows::Foundation::IInspectable; +using ::winrt::Windows::Foundation::Collections::IMapView; +using ::winrt::Windows::Storage::Streams::DataReader; +using ::winrt::Windows::Storage::Streams::DataWriter; +using ::winrt::Windows::Storage::Streams::UnicodeEncoding; -// Used to cntrol the dump output for device information. It is only for debug +// Used to control the dump output for device information. It is only for debug // purpose. constexpr bool kEnableDumpDeviceInfomation = false; +// The maximum length of Bluetooth device name Android can discover. +constexpr int kAndroidDiscoverableBluetoothNameMaxLength = 37; // bytes +// Used to select bluetooth devices. +constexpr wchar_t kBluetoothSelector[] = + L"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}" + L"\""; void DumpDeviceInformation( const IMapView& properties) { @@ -88,11 +107,9 @@ void DumpDeviceInformation( } // namespace -constexpr uint8_t kAndroidDiscoverableBluetoothNameMaxLength = 37; // bytes - BluetoothClassicMedium::BluetoothClassicMedium( - api::BluetoothAdapter& bluetoothAdapter) - : bluetooth_adapter_(dynamic_cast(bluetoothAdapter)) { + api::BluetoothAdapter& bluetooth_adapter) + : bluetooth_adapter_(dynamic_cast(bluetooth_adapter)) { InitializeDeviceWatcher(); bluetooth_adapter_.RestoreRadioNameIfNecessary(); @@ -103,17 +120,17 @@ BluetoothClassicMedium::BluetoothClassicMedium( BluetoothClassicMedium::~BluetoothClassicMedium() {} void BluetoothClassicMedium::OnScanModeChanged( - BluetoothAdapter::ScanMode scanMode) { + BluetoothAdapter::ScanMode scan_mode) { NEARBY_LOGS(INFO) << __func__ << ": OnScanModeChanged is called with scanMode: " - << static_cast(scanMode); + << static_cast(scan_mode); - if (scanMode == scan_mode_) { + if (scan_mode == scan_mode_) { NEARBY_LOGS(INFO) << __func__ << ": No change of scan mode."; return; } - scan_mode_ = scanMode; + scan_mode_ = scan_mode; bool radio_discoverable = scan_mode_ == BluetoothAdapter::ScanMode::kConnectableDiscoverable; @@ -130,7 +147,7 @@ void BluetoothClassicMedium::OnScanModeChanged( } if (rfcomm_provider_ == nullptr) { - NEARBY_LOGS(INFO) << __func__ << ": No advertising."; + NEARBY_LOGS(WARNING) << __func__ << ": No advertising."; return; } @@ -184,14 +201,14 @@ bool BluetoothClassicMedium::StopDiscovery() { void BluetoothClassicMedium::InitializeDeviceWatcher() { try { // create watcher - const winrt::param::iterable RequestedProperties = + const winrt::param::iterable requested_properties = winrt::single_threaded_vector( {winrt::to_hstring("System.Devices.Aep.IsPresent"), winrt::to_hstring("System.Devices.Aep.DeviceAddress")}); device_watcher_ = DeviceInformation::CreateWatcher( - BLUETOOTH_SELECTOR, // aqsFilter - RequestedProperties, // additionalProperties + kBluetoothSelector, // aqsFilter + requested_properties, // additionalProperties DeviceInformationKind::AssociationEndpoint); // kind // An app must subscribe to all of the added, removed, and updated events @@ -258,49 +275,18 @@ std::unique_ptr BluetoothClassicMedium::ConnectToService( return nullptr; } - remote_device_to_connect_ = - std::make_unique(remote_device.GetMacAddress()); + auto remote_device_to_connect_ = dynamic_cast( + GetRemoteDevice(remote_device.GetMacAddress())); - // First try, check if the remote device that we want to request connection - // to has already been discovered by the Bluetooth Classic Device Watcher - // beforehand inside the discovered_devices_by_id_ map - std::map>::const_iterator - it = discovered_devices_by_id_.find( - winrt::to_hstring(remote_device_to_connect_->GetId())); - - std::unique_ptr device = nullptr; - BluetoothDevice* current_device = nullptr; - - if (it != discovered_devices_by_id_.end()) { - current_device = it->second.get(); - } else { - // The remote device was not discovered by the Bluetooth Classic Device - // Watcher beforehand. - // Second try, request Windows to scan for nearby - // bluetooth devices that has this static mac address again in this - // instance - auto remote_bluetooth_device_from_mac_address = - winrt::Windows::Devices::Bluetooth::BluetoothDevice:: - FromBluetoothAddressAsync( - mac_address_string_to_uint64(remote_device.GetMacAddress())) - .get(); - if (remote_bluetooth_device_from_mac_address == nullptr) { - NEARBY_LOGS(ERROR) << __func__ - << ": Windows failed to get remote bluetooth device " - "from static mac address."; - return nullptr; - } - device = std::make_unique( - remote_bluetooth_device_from_mac_address); - current_device = device.get(); - } - - if (current_device == nullptr) { - NEARBY_LOGS(ERROR) << __func__ << ": Failed to get current device."; + if (remote_device_to_connect_ == nullptr || + remote_device_to_connect_->GetId().empty()) { + NEARBY_LOGS(ERROR) << __func__ + << ": Failed to get remote device from MAC address."; return nullptr; } - winrt::hstring device_id = winrt::to_hstring(current_device->GetId()); + winrt::hstring device_id = + winrt::to_hstring(remote_device_to_connect_->GetId()); if (!HaveAccess(device_id)) { NEARBY_LOGS(ERROR) << __func__ << ": Failed to gain access to device: " @@ -309,7 +295,7 @@ std::unique_ptr BluetoothClassicMedium::ConnectToService( } RfcommDeviceService requested_service( - GetRequestedService(current_device, service)); + GetRequestedService(remote_device_to_connect_, service)); if (!FeatureFlags::GetInstance() .GetFlags() @@ -420,31 +406,32 @@ bool BluetoothClassicMedium::HaveAccess(winrt::hstring device_id) { RfcommDeviceService BluetoothClassicMedium::GetRequestedService( BluetoothDevice* device, winrt::guid service) { - RfcommServiceId rfcommServiceId = RfcommServiceId::FromUuid(service); - return device->GetRfcommServiceForIdAsync(rfcommServiceId); + RfcommServiceId rfcomm_service_id = RfcommServiceId::FromUuid(service); + return device->GetRfcommServiceForIdAsync(rfcomm_service_id); } -bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requestedService) { +bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requested_service) { // Do various checks of the SDP record to make sure you are talking to a // device that actually supports the Bluetooth Rfcomm Service // https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommdeviceservice.getsdprawattributesasync?view=winrt-20348 try { - if (requestedService == nullptr) { + if (requested_service == nullptr) { + NEARBY_LOGS(WARNING) << __func__ << ": Request service is empty."; return false; } - auto attributes = requestedService.GetSdpRawAttributesAsync().get(); + auto attributes = requested_service.GetSdpRawAttributesAsync().get(); if (!attributes.HasKey(Constants::SdpServiceNameAttributeId)) { NEARBY_LOGS(ERROR) << __func__ << ": Missing SdpServiceNameAttributeId."; return false; } - auto attributeReader = DataReader::FromBuffer( + auto attribute_reader = DataReader::FromBuffer( attributes.Lookup(Constants::SdpServiceNameAttributeId)); - auto attributeType = attributeReader.ReadByte(); + auto attribute_type = attribute_reader.ReadByte(); - if (attributeType != Constants::SdpServiceNameAttributeType) { + if (attribute_type != Constants::SdpServiceNameAttributeType) { NEARBY_LOGS(ERROR) << __func__ << ": Missing SdpServiceNameAttributeType."; return false; @@ -503,7 +490,22 @@ BluetoothClassicMedium::ListenForService(const std::string& service_name, api::BluetoothDevice* BluetoothClassicMedium::GetRemoteDevice( const std::string& mac_address) { - return new BluetoothDevice(mac_address); + auto it = mac_address_to_bluetooth_device_map_.find(mac_address); + + if (it == mac_address_to_bluetooth_device_map_.end()) { + NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " << mac_address + << " is not in list. create it"; + auto bluetooth_device = std::make_unique(mac_address); + + mac_address_to_bluetooth_device_map_[mac_address] = + std::move(bluetooth_device); + return mac_address_to_bluetooth_device_map_[mac_address].get(); + } + + NEARBY_LOGS(INFO) << __func__ << ": Bluetooth device " << mac_address + << " is in cache"; + + return it->second.get(); } bool BluetoothClassicMedium::StartScanning() { @@ -515,7 +517,7 @@ bool BluetoothClassicMedium::StartScanning() { return false; } - discovered_devices_by_id_.clear(); + mac_address_to_bluetooth_device_map_.clear(); // The Start method can only be called when the DeviceWatcher is in the // Created, Stopped or Aborted state. @@ -548,9 +550,9 @@ bool BluetoothClassicMedium::StopScanning() { } winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added( - DeviceWatcher sender, DeviceInformation deviceInfo) { - NEARBY_LOGS(INFO) << "Device added " << winrt::to_string(deviceInfo.Id()); - IMapView properties = deviceInfo.Properties(); + DeviceWatcher sender, DeviceInformation device_info) { + NEARBY_LOGS(INFO) << "Device added " << winrt::to_string(device_info.Id()); + IMapView properties = device_info.Properties(); DumpDeviceInformation(properties); if (!IsWatcherStarted()) { @@ -560,14 +562,14 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added( // If device no item name, ignore it. if (!properties.HasKey(L"System.ItemNameDisplay")) { NEARBY_LOGS(WARNING) << __func__ << ": Ignore the Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + << winrt::to_string(device_info.Id()) << " due to no name."; return winrt::fire_and_forget(); } if (properties.Lookup(L"System.ItemNameDisplay") == nullptr) { NEARBY_LOGS(WARNING) << __func__ << ": Ignore the Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + << winrt::to_string(device_info.Id()) << " due to empty name."; return winrt::fire_and_forget(); } @@ -575,7 +577,7 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added( // If device doesn't support pair, ignore it. if (!properties.HasKey(L"System.Devices.Aep.CanPair")) { NEARBY_LOGS(WARNING) << __func__ << ": Ignore the Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + << winrt::to_string(device_info.Id()) << " due to no pair property."; return winrt::fire_and_forget(); } @@ -583,61 +585,72 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added( if (!InspectableReader::ReadBoolean( properties.Lookup(L"System.Devices.Aep.CanPair"))) { NEARBY_LOGS(WARNING) << __func__ << ": Ignore the Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + << winrt::to_string(device_info.Id()) << " due to not support pair."; return winrt::fire_and_forget(); } + // Create a bluetooth device out of this id + auto native_bluetooth_device = + ::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( + device_info.Id()) + .get(); + + std::string mac_address = + uint64_to_mac_address_string(native_bluetooth_device.BluetoothAddress()); + // Create an iterator for the internal list - std::map>::const_iterator - it = discovered_devices_by_id_.find(deviceInfo.Id()); + auto it = mac_address_to_bluetooth_device_map_.find(mac_address); // Add to our internal list if necessary - if (it != discovered_devices_by_id_.end()) { + if (it != mac_address_to_bluetooth_device_map_.end()) { // We're already tracking this one - NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " << mac_address << " is alreay added."; return winrt::fire_and_forget(); } - // Create a bluetooth device out of this id - auto bluetoothDevice = - winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( - deviceInfo.Id()) - .get(); - auto bluetoothDeviceP = std::make_unique(bluetoothDevice); + auto bluetooth_device = + std::make_unique(native_bluetooth_device); - discovered_devices_by_id_[deviceInfo.Id()] = std::move(bluetoothDeviceP); + mac_address_to_bluetooth_device_map_[mac_address] = + std::move(bluetooth_device); - NEARBY_LOGS(INFO) << __func__ << ": Notifying bluetooth device added"; + NEARBY_LOGS(INFO) << __func__ << ": Notifying bluetooth device " + << mac_address << " added"; if (discovery_callback_.device_discovered_cb != nullptr) { discovery_callback_.device_discovered_cb( - *discovered_devices_by_id_[deviceInfo.Id()]); + *mac_address_to_bluetooth_device_map_[mac_address]); } for (auto& observer : observers_.GetObservers()) { - observer->DeviceAdded(*discovered_devices_by_id_[deviceInfo.Id()]); + observer->DeviceAdded(*mac_address_to_bluetooth_device_map_[mac_address]); } return winrt::fire_and_forget(); } winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated( - DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) { - auto it = discovered_devices_by_id_.find(deviceInfoUpdate.Id()); + DeviceWatcher sender, DeviceInformationUpdate device_update_info) { + auto native_bluetooth_device = + ::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( + device_update_info.Id()) + .get(); + std::string mac_address = + uint64_to_mac_address_string(native_bluetooth_device.BluetoothAddress()); - if (it == discovered_devices_by_id_.end()) { - NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " - << winrt::to_string(deviceInfoUpdate.Id()) + auto it = mac_address_to_bluetooth_device_map_.find(mac_address); + + if (it == mac_address_to_bluetooth_device_map_.end()) { + NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " << mac_address << " is not in list."; return winrt::fire_and_forget(); } NEARBY_LOGS(INFO) << "Device updated name: " - << discovered_devices_by_id_[deviceInfoUpdate.Id()]->GetName() << " (" - << winrt::to_string(deviceInfoUpdate.Id()) << ")"; + << mac_address_to_bluetooth_device_map_[mac_address]->GetName() << " (" + << mac_address << ")"; IMapView properties = - deviceInfoUpdate.Properties(); + device_update_info.Properties(); DumpDeviceInformation(properties); if (!IsWatcherStarted()) { @@ -659,10 +672,10 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated( NEARBY_LOGS(INFO) << "Updated device name:" - << discovered_devices_by_id_[deviceInfoUpdate.Id()]->GetName(); + << mac_address_to_bluetooth_device_map_[mac_address]->GetName(); discovery_callback_.device_name_changed_cb( - *discovered_devices_by_id_[deviceInfoUpdate.Id()]); + *mac_address_to_bluetooth_device_map_[mac_address]); } } @@ -675,7 +688,8 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated( << new_paired_status; for (auto& observer : observers_.GetObservers()) { observer->DevicePairedChanged( - *discovered_devices_by_id_[deviceInfoUpdate.Id()], new_paired_status); + *mac_address_to_bluetooth_device_map_[mac_address], + new_paired_status); } } @@ -683,19 +697,25 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated( } winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed( - DeviceWatcher sender, DeviceInformationUpdate deviceInfo) { - auto it = discovered_devices_by_id_.find(deviceInfo.Id()); + DeviceWatcher sender, DeviceInformationUpdate device_update_info) { + auto native_bluetooth_device = + ::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync( + device_update_info.Id()) + .get(); + std::string mac_address = + uint64_to_mac_address_string(native_bluetooth_device.BluetoothAddress()); + auto it = mac_address_to_bluetooth_device_map_.find(mac_address); - if (it == discovered_devices_by_id_.end()) { - NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " - << winrt::to_string(deviceInfo.Id()) + if (it == mac_address_to_bluetooth_device_map_.end()) { + NEARBY_LOGS(WARNING) << __func__ << ": Bluetooth device " << mac_address << " is not in list."; return winrt::fire_and_forget(); } - NEARBY_LOGS(INFO) << "Device removed " - << discovered_devices_by_id_[deviceInfo.Id()]->GetName() - << " (" << winrt::to_string(deviceInfo.Id()) << ")"; + NEARBY_LOGS(INFO) + << "Device removed " + << mac_address_to_bluetooth_device_map_[mac_address]->GetName() << " (" + << mac_address << ")"; if (!IsWatcherStarted()) { return winrt::fire_and_forget(); @@ -704,14 +724,14 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed( NEARBY_LOGS(INFO) << __func__ << ": Notifying bluetooth device removed"; if (discovery_callback_.device_lost_cb != nullptr) { discovery_callback_.device_lost_cb( - *discovered_devices_by_id_[deviceInfo.Id()]); + *mac_address_to_bluetooth_device_map_[mac_address]); } for (auto& observer : observers_.GetObservers()) { - observer->DeviceRemoved(*discovered_devices_by_id_[deviceInfo.Id()]); + observer->DeviceRemoved(*mac_address_to_bluetooth_device_map_[mac_address]); } - discovered_devices_by_id_.erase(deviceInfo.Id()); + mac_address_to_bluetooth_device_map_.erase(mac_address); return winrt::fire_and_forget(); } @@ -870,21 +890,21 @@ bool BluetoothClassicMedium::StopAdvertising() { bool BluetoothClassicMedium::InitializeServiceSdpAttributes( RfcommServiceProvider rfcomm_provider, std::string service_name) { try { - auto sdpWriter = DataWriter(); + auto sdp_writer = DataWriter(); // Write the Service Name Attribute. - sdpWriter.WriteByte(Constants::SdpServiceNameAttributeType); + sdp_writer.WriteByte(Constants::SdpServiceNameAttributeType); // The length of the UTF-8 encoded Service Name SDP Attribute. - sdpWriter.WriteByte(service_name.size()); + sdp_writer.WriteByte(service_name.size()); // The UTF-8 encoded Service Name value. - sdpWriter.UnicodeEncoding(UnicodeEncoding::Utf8); - sdpWriter.WriteString(winrt::to_hstring(service_name)); + sdp_writer.UnicodeEncoding(UnicodeEncoding::Utf8); + sdp_writer.WriteString(winrt::to_hstring(service_name)); // Set the SDP Attribute on the RFCOMM Service Provider. rfcomm_provider.SdpRawAttributes().Insert( - Constants::SdpServiceNameAttributeId, sdpWriter.DetachBuffer()); + Constants::SdpServiceNameAttributeId, sdp_writer.DetachBuffer()); return true; } catch (...) { diff --git a/internal/platform/implementation/windows/bluetooth_classic_medium.h b/internal/platform/implementation/windows/bluetooth_classic_medium.h index 44f62d06..9465f83d 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_medium.h +++ b/internal/platform/implementation/windows/bluetooth_classic_medium.h @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2020-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -20,6 +20,8 @@ #include #include "internal/base/observer_list.h" +#include "internal/platform/cancellation_flag.h" +#include "internal/platform/implementation/bluetooth_adapter.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/windows/bluetooth_adapter.h" #include "internal/platform/implementation/windows/bluetooth_classic_device.h" @@ -32,76 +34,11 @@ namespace nearby { namespace windows { -// Represents a device. This class allows access to well-known device properties -// as well as additional properties specified during device enumeration. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformation?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceInformation; - -// Represents the kind of DeviceInformation object. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformationkind?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceInformationKind; - -// Contains updated properties for a DeviceInformation object. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceinformationupdate?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceInformationUpdate; - -// Enumerates devices dynamically, so that the app receives notifications if -// devices are added, removed, or changed after the initial enumeration is -// complete. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceWatcher; - -// Writes data to an output stream. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datawriter?view=winrt-20348 -using winrt::Windows::Storage::Streams::DataWriter; - -// Specifies the type of character encoding for a stream. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.unicodeencoding?view=winrt-20348 -using winrt::Windows::Storage::Streams::UnicodeEncoding; - -// Describes the state of a DeviceWatcher object. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcherstatus?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceWatcherStatus; - -// Represents an instance of a service on a Bluetooth basic rate device. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommdeviceservice?view=winrt-20348 -using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommDeviceService; - -// Indicates the status of the access to a device. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceaccessstatus?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceAccessStatus; - -// Contains the information about access to a device. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.deviceaccessinformation?view=winrt-20348 -using winrt::Windows::Devices::Enumeration::DeviceAccessInformation; - -// Represents an RFCOMM service ID. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommserviceid?view=winrt-20348 -using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId; - -// Represents an instance of a local RFCOMM service. -// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.rfcomm.rfcommserviceprovider?view=winrt-20348 -using winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider; - -// Reads data from an input stream. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-20348 -using winrt::Windows::Storage::Streams::DataReader; - -// Writes data to an output stream. -// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datawriter?view=winrt-20348 -using winrt::Windows::Storage::Streams::DataWriter; - -// Bluetooth protocol ID = \"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\" -// https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/aep-service-class-ids -#define BLUETOOTH_SELECTOR \ - L"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\"" - // Container of operations that can be performed over the Bluetooth Classic // medium. class BluetoothClassicMedium : public api::BluetoothClassicMedium { public: - explicit BluetoothClassicMedium(api::BluetoothAdapter& bluetoothAdapter); - + explicit BluetoothClassicMedium(api::BluetoothAdapter& bluetooth_adapter); ~BluetoothClassicMedium() override; // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#startDiscovery() @@ -166,56 +103,63 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium { bool StopScanning(); bool StartAdvertising(bool radio_discoverable); bool StopAdvertising(); - bool InitializeServiceSdpAttributes(RfcommServiceProvider rfcomm_provider, - std::string service_name); + bool InitializeServiceSdpAttributes( + ::winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider + rfcomm_provider, + std::string service_name); bool IsWatcherStarted(); bool IsWatcherRunning(); void InitializeDeviceWatcher(); - void OnScanModeChanged(BluetoothAdapter::ScanMode scanMode); + void OnScanModeChanged(BluetoothAdapter::ScanMode scan_mode); // This is for a coroutine whose return type is winrt::fire_and_forget, which // handles async operations which don't have any dependencies. // https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/fire-and-forget - winrt::fire_and_forget DeviceWatcher_Added(DeviceWatcher sender, - DeviceInformation deviceInfo); + winrt::fire_and_forget DeviceWatcher_Added( + ::winrt::Windows::Devices::Enumeration::DeviceWatcher sender, + ::winrt::Windows::Devices::Enumeration::DeviceInformation device_info); winrt::fire_and_forget DeviceWatcher_Updated( - DeviceWatcher sender, DeviceInformationUpdate deviceInfo); + ::winrt::Windows::Devices::Enumeration::DeviceWatcher sender, + ::winrt::Windows::Devices::Enumeration::DeviceInformationUpdate + device_update_info); winrt::fire_and_forget DeviceWatcher_Removed( - DeviceWatcher sender, DeviceInformationUpdate deviceInfo); + ::winrt::Windows::Devices::Enumeration::DeviceWatcher sender, + ::winrt::Windows::Devices::Enumeration::DeviceInformationUpdate + device_update_info); // Check to make sure we can connect if we try - bool HaveAccess(winrt::hstring deviceId); + bool HaveAccess(::winrt::hstring device_id); // Get the service requested RfcommDeviceService GetRequestedService(BluetoothDevice* device, - winrt::guid service); + ::winrt::guid service); // Check to see that the device actually handles the requested service - bool CheckSdp(RfcommDeviceService requestedService); + bool CheckSdp(RfcommDeviceService requested_service); BluetoothClassicMedium::DiscoveryCallback discovery_callback_; - DeviceWatcher device_watcher_ = nullptr; + ::winrt::Windows::Devices::Enumeration::DeviceWatcher device_watcher_ = + nullptr; std::unique_ptr bluetooth_socket_; std::string service_name_; std::string service_uuid_; - // hstring is the only type of string winrt understands. - // https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/hstring - std::map> - discovered_devices_by_id_; + // Map MAC address to bluetooth device. + std::map> + mac_address_to_bluetooth_device_map_; BluetoothAdapter& bluetooth_adapter_; BluetoothAdapter::ScanMode scan_mode_ = BluetoothAdapter::ScanMode::kUnknown; - std::unique_ptr remote_device_to_connect_; // Used for advertising. - RfcommServiceProvider rfcomm_provider_ = nullptr; + ::winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceProvider + rfcomm_provider_ = nullptr; std::unique_ptr server_socket_ = nullptr; BluetoothServerSocket* raw_server_socket_ = nullptr; bool is_radio_discoverable_ = false;