mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Add dual-mode Bluetooth Classic Device to support RequestConnection over BLE Fast Advertisement
PiperOrigin-RevId: 452782174
This commit is contained in:
committed by
Copybara-Service
parent
182a1d4568
commit
45386948be
@@ -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};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user