Add dual-mode Bluetooth Classic Device to support RequestConnection over BLE Fast Advertisement

PiperOrigin-RevId: 452782174
This commit is contained in:
aaronyujiaze
2022-06-03 09:33:59 -07:00
committed by Copybara-Service
parent 182a1d4568
commit 45386948be
7 changed files with 84 additions and 8 deletions
@@ -20,8 +20,8 @@
#include <locale>
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.h"
#include "internal/platform/implementation/windows/utils.h"
namespace location {
@@ -30,6 +30,18 @@ namespace windows {
BluetoothDevice::~BluetoothDevice() {}
BluetoothDevice::BluetoothDevice(absl::string_view mac_address)
: windows_bluetooth_device_(nullptr) {
mac_address_ = std::string(mac_address);
windows_bluetooth_device_ =
winrt::Windows::Devices::Bluetooth::BluetoothDevice::
FromBluetoothAddressAsync(mac_address_string_to_uint64(mac_address))
.get();
if (windows_bluetooth_device_ != nullptr) {
id_ = winrt::to_string(windows_bluetooth_device_.DeviceId());
}
}
BluetoothDevice::BluetoothDevice(
const winrt::Windows::Devices::Bluetooth::BluetoothDevice& bluetoothDevice)
: windows_bluetooth_device_(bluetoothDevice) {
@@ -19,6 +19,7 @@
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/bluetooth_classic.h"
#include "internal/platform/exception.h"
#include "internal/platform/input_stream.h"
@@ -52,8 +53,7 @@ using winrt::Windows::Devices::Bluetooth::BluetoothCacheMode;
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html.
class BluetoothDevice : public api::BluetoothDevice {
public:
BluetoothDevice(std::string mac_address)
: windows_bluetooth_device_(nullptr), mac_address_(mac_address) {}
BluetoothDevice(absl::string_view mac_address);
BluetoothDevice(const winrt::Windows::Devices::Bluetooth::BluetoothDevice&
bluetoothDevice);
@@ -19,6 +19,7 @@
#include <codecvt>
#include <locale>
#include <memory>
#include <regex> // NOLINT
#include <string>
@@ -99,7 +100,8 @@ void BluetoothClassicMedium::InitializeDeviceWatcher() {
// create watcher
const winrt::param::iterable<winrt::hstring> RequestedProperties =
winrt::single_threaded_vector<winrt::hstring>(
{winrt::to_hstring("System.Devices.Aep.IsPresent")});
{winrt::to_hstring("System.Devices.Aep.IsPresent"),
winrt::to_hstring("System.Devices.Aep.DeviceAddress")});
device_watcher_ = DeviceInformation::CreateWatcher(
BLUETOOTH_SELECTOR, // aqsFilter
@@ -157,8 +159,39 @@ std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
return nullptr;
}
BluetoothDevice* currentDevice =
dynamic_cast<BluetoothDevice*>(&remote_device);
BluetoothDevice* currentDevice = nullptr;
remote_device_to_connect_ =
std::make_unique<BluetoothDevice>(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<winrt::hstring, std::unique_ptr<BluetoothDevice>>::const_iterator
it = discovered_devices_by_id_.find(
winrt::to_hstring(remote_device_to_connect_->GetId()));
if (it != discovered_devices_by_id_.end()) {
currentDevice = 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;
}
BluetoothDevice device{remote_bluetooth_device_from_mac_address};
currentDevice = &device;
}
if (currentDevice == nullptr) {
NEARBY_LOGS(ERROR) << __func__ << ": Failed to get current device.";
@@ -216,8 +249,8 @@ bool BluetoothClassicMedium::HaveAccess(winrt::hstring deviceId) {
if (accessStatus == DeviceAccessStatus::DeniedByUser ||
// This status is most likely caused by app permissions (did not declare
// the device in the app's package.appxmanifest)
// This status does not cover the case where the device is already opened
// by another app.
// This status does not cover the case where the device is already
// opened by another app.
accessStatus == DeviceAccessStatus::DeniedBySystem ||
// Most likely the device is opened by another app, but cannot be sure
accessStatus == DeviceAccessStatus::Unspecified) {
@@ -183,6 +183,7 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
BluetoothAdapter& bluetooth_adapter_;
BluetoothAdapter::ScanMode scan_mode_;
std::unique_ptr<BluetoothDevice> remote_device_to_connect_;
};
} // namespace windows
@@ -16,11 +16,13 @@
// Windows headers
#include <inaddr.h>
#include <stdlib.h>
#include <strsafe.h>
#include <winsock.h>
// Standard C/C++ headers
#include <codecvt>
#include <cstdint>
#include <exception>
#include <string>
@@ -29,6 +31,9 @@
#include "absl/strings/str_format.h"
// Nearby connections headers
#include "absl/strings/string_view.h"
#include "internal/platform/bluetooth_utils.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/crypto.h"
namespace location {
@@ -45,6 +50,17 @@ std::string uint64_to_mac_address_string(uint64_t bluetoothAddress) {
return absl::AsciiStrToUpper(buffer);
}
uint64_t mac_address_string_to_uint64(absl::string_view mac_address) {
ByteArray mac_address_array = BluetoothUtils::FromString(mac_address);
uint64_t mac_address_uint64 = 0;
for (int i = 0; i < mac_address_array.size(); i++) {
mac_address_uint64 <<= 8;
mac_address_uint64 |= static_cast<uint8_t>(
static_cast<unsigned char>(*(mac_address_array.data() + i)));
}
return mac_address_uint64;
}
std::string ipaddr_4bytes_to_dotdecimal_string(
absl::string_view ipaddr_4bytes) {
in_addr address;
@@ -18,6 +18,7 @@
#include <Windows.h>
#include <stdio.h>
#include <cstdint>
#include <string>
#include "absl/strings/string_view.h"
@@ -32,6 +33,7 @@ namespace windows {
using winrt::Windows::Foundation::IInspectable;
std::string uint64_to_mac_address_string(uint64_t bluetoothAddress);
uint64_t mac_address_string_to_uint64(absl::string_view mac_address);
std::string ipaddr_4bytes_to_dotdecimal_string(absl::string_view ipaddr_4bytes);
std::string ipaddr_dotdecimal_to_4bytes_string(std::string ipv4_s);
@@ -36,6 +36,18 @@ TEST(UtilsTests, MacAddressToString) {
EXPECT_EQ(result, expected);
}
TEST(UtilsTests, StringToMacAddress) {
// Arrange
std::string input = "34:36:3B:C7:8C:71";
const uint64_t expected = 0x000034363bc78c71;
// Act
uint64_t result = mac_address_string_to_uint64(input);
// Assert
EXPECT_EQ(result, expected);
}
constexpr absl::string_view kIpDotdecimal{"192.168.1.37"};
constexpr char kIp4Bytes[] = {192, 168, 1, 37};