Remove BLE V1 codes

PiperOrigin-RevId: 811369802
This commit is contained in:
Guogang Li
2025-09-25 08:56:51 -07:00
committed by Copybara-Service
parent 72088b7fe2
commit 5fbef9e11e
51 changed files with 200 additions and 4969 deletions
-2
View File
@@ -56,7 +56,6 @@ cc_library(
"base_bwu_handler.cc",
"base_endpoint_channel.cc",
"base_pcp_handler.cc",
"ble_endpoint_channel.cc",
"ble_l2cap_endpoint_channel.cc",
"ble_v2_endpoint_channel.cc",
"bluetooth_bwu_handler.cc",
@@ -98,7 +97,6 @@ cc_library(
"base_bwu_handler.h",
"base_endpoint_channel.h",
"base_pcp_handler.h",
"ble_endpoint_channel.h",
"ble_l2cap_endpoint_channel.h",
"ble_v2_endpoint_channel.h",
"bluetooth_bwu_handler.h",
+5 -16
View File
@@ -186,8 +186,8 @@ std::vector<ConnectionInfoVariant> BasePcpHandler::GetConnectionInfoFromResult(
std::vector<ConnectionInfoVariant> connection_infos;
for (const auto& medium : result.mediums) {
if (medium == location::nearby::proto::connections::BLUETOOTH) {
BluetoothConnectionInfo info(
mediums_->GetBluetoothClassic().GetAddress(), "", {});
BluetoothConnectionInfo info(mediums_->GetBluetoothClassic().GetAddress(),
"", {});
connection_infos.push_back(info);
} else if (medium == location::nearby::proto::connections::BLE) {
// TODO(b/284311319): Add relevant information.
@@ -1159,12 +1159,7 @@ void BasePcpHandler::StripOutUnavailableMediums(
allowed.bluetooth = mediums_->GetBluetoothClassic().IsAvailable();
}
if (allowed.ble) {
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
allowed.ble = mediums_->GetBleV2().IsAvailable();
} else {
allowed.ble = mediums_->GetBle().IsAvailable();
}
allowed.ble = mediums_->GetBleV2().IsAvailable();
}
if (allowed.web_rtc) {
allowed.web_rtc = mediums_->GetWebRtc().IsAvailable();
@@ -1211,12 +1206,7 @@ void BasePcpHandler::StripOutUnavailableMediums(
allowed.bluetooth = mediums_->GetBluetoothClassic().IsAvailable();
}
if (allowed.ble) {
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
allowed.ble = mediums_->GetBleV2().IsAvailable();
} else {
allowed.ble = mediums_->GetBle().IsAvailable();
}
allowed.ble = mediums_->GetBleV2().IsAvailable();
}
if (allowed.web_rtc) {
allowed.web_rtc = mediums_->GetWebRtc().IsAvailable();
@@ -2188,8 +2178,7 @@ void BasePcpHandler::ProcessTieBreakLoss(
}
bool BasePcpHandler::AppendRemoteBluetoothMacAddressEndpoint(
const std::string& endpoint_id,
MacAddress remote_bluetooth_mac_address,
const std::string& endpoint_id, MacAddress remote_bluetooth_mac_address,
const DiscoveryOptions& local_discovery_options) {
if (!local_discovery_options.allowed.bluetooth) {
return false;
@@ -236,14 +236,6 @@ class BasePcpHandler : public PcpHandler,
BluetoothDevice bluetooth_device;
};
struct BleEndpoint : public BasePcpHandler::DiscoveredEndpoint {
BleEndpoint(DiscoveredEndpoint endpoint, BlePeripheral peripheral)
: DiscoveredEndpoint(std::move(endpoint)),
ble_peripheral(std::move(peripheral)) {}
BlePeripheral ble_peripheral;
};
struct BleV2Endpoint : public BasePcpHandler::DiscoveredEndpoint {
BleV2Endpoint(DiscoveredEndpoint endpoint, BleV2Peripheral peripheral)
: DiscoveredEndpoint(std::move(endpoint)),
@@ -1,73 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "connections/implementation/ble_endpoint_channel.h"
#include <string>
#include <utility>
#include "connections/implementation/base_endpoint_channel.h"
#include "internal/platform/ble.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/logging.h"
#include "internal/platform/output_stream.h"
namespace nearby {
namespace connections {
namespace {
OutputStream* GetOutputStreamOrNull(BleSocket& socket) {
if (socket.IsValid()) {
return &socket.GetOutputStream();
}
return nullptr;
}
InputStream* GetInputStreamOrNull(BleSocket& socket) {
if (socket.IsValid()) {
return &socket.GetInputStream();
}
return nullptr;
}
} // namespace
BleEndpointChannel::BleEndpointChannel(const std::string& service_id,
const std::string& channel_name,
BleSocket socket)
: BaseEndpointChannel(service_id, channel_name,
GetInputStreamOrNull(socket),
GetOutputStreamOrNull(socket)),
ble_socket_(std::move(socket)) {}
location::nearby::proto::connections::Medium BleEndpointChannel::GetMedium()
const {
return location::nearby::proto::connections::Medium::BLE;
}
int BleEndpointChannel::GetMaxTransmitPacketSize() const {
return kDefaultBleMaxTransmitPacketSize;
}
void BleEndpointChannel::CloseImpl() {
auto status = ble_socket_.Close();
if (!status.Ok()) {
LOG(INFO) << "Failed to close underlying socket for BleEndpointChannel "
<< GetName() << ": exception=" << status.value;
}
}
} // namespace connections
} // namespace nearby
@@ -1,47 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CORE_INTERNAL_BLE_ENDPOINT_CHANNEL_H_
#define CORE_INTERNAL_BLE_ENDPOINT_CHANNEL_H_
#include <string>
#include "connections/implementation/base_endpoint_channel.h"
#include "internal/platform/ble.h"
namespace nearby {
namespace connections {
class BleEndpointChannel final : public BaseEndpointChannel {
public:
// Creates both outgoing and incoming Ble channels.
BleEndpointChannel(const std::string& service_id,
const std::string& channel_name, BleSocket socket);
location::nearby::proto::connections::Medium GetMedium() const override;
int GetMaxTransmitPacketSize() const override;
private:
static constexpr int kDefaultBleMaxTransmitPacketSize = 512; // 512 bytes
void CloseImpl() override;
BleSocket ble_socket_;
};
} // namespace connections
} // namespace nearby
#endif // CORE_INTERNAL_BLE_ENDPOINT_CHANNEL_H_
+7 -13
View File
@@ -970,8 +970,6 @@ BwuManager::ProcessBwuPathAvailableEventInternal(
old_medium = old_channel->GetMedium();
}
bool enable_ble_v2 = NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2);
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableStopBleScanningOnWifiUpgrade)) {
@@ -979,13 +977,11 @@ BwuManager::ProcessBwuPathAvailableEventInternal(
location::nearby::connections::OsInfo::APPLE &&
old_medium == Medium::BLE && medium == Medium::WIFI_HOTSPOT) {
disable_ble_scanning = true;
if (enable_ble_v2) {
LOG(INFO) << "For Apple OS, if upgrade from BLE_V2 to WIFI_HOTSPOT, "
"we need to pause "
"BLE_V2 scanning because it can interfere with WIFI "
"Hotspot scanning and connection.";
ble_v2_medium_.PauseMediumScanning();
}
LOG(INFO) << "For Apple OS, if upgrade from BLE_V2 to WIFI_HOTSPOT, "
"we need to pause "
"BLE_V2 scanning because it can interfere with WIFI "
"Hotspot scanning and connection.";
ble_v2_medium_.PauseMediumScanning();
}
}
@@ -997,10 +993,8 @@ BwuManager::ProcessBwuPathAvailableEventInternal(
config_package_nearby::nearby_connections_feature::
kEnableStopBleScanningOnWifiUpgrade)) {
if (disable_ble_scanning) {
if (enable_ble_v2) {
LOG(INFO) << "Resume BLE_V2 scanning.";
ble_v2_medium_.ResumeMediumScanning();
}
LOG(INFO) << "Resume BLE_V2 scanning.";
ble_v2_medium_.ResumeMediumScanning();
}
}
+4 -6
View File
@@ -1,6 +1,3 @@
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_cc//cc:cc_test.bzl", "cc_test")
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,13 +11,16 @@ load("@rules_cc//cc:cc_test.bzl", "cc_test")
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_cc//cc:cc_test.bzl", "cc_test")
licenses(["notice"])
cc_library(
name = "mediums",
srcs = [
"awdl.cc",
"ble.cc",
"ble_v2.cc",
"bluetooth_classic.cc",
"bluetooth_radio.cc",
@@ -33,7 +33,6 @@ cc_library(
],
hdrs = [
"awdl.h",
"ble.h",
"ble_v2.h",
"bluetooth_classic.h",
"bluetooth_radio.h",
@@ -147,7 +146,6 @@ cc_test(
size = "small",
srcs = [
"awdl_test.cc",
"ble_test.cc",
"ble_v2_test.cc",
"bluetooth_classic_test.cc",
"bluetooth_radio_test.cc",
-440
View File
@@ -1,440 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "connections/implementation/mediums/ble.h"
#include <array>
#include <cstddef>
#include <string>
#include <utility>
#include "absl/strings/escaping.h"
#include "connections/implementation/mediums/ble_v2/ble_advertisement.h"
#include "connections/implementation/mediums/bluetooth_radio.h"
#include "connections/implementation/mediums/utils.h"
#include "internal/platform/ble.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/expected.h"
#include "internal/platform/logging.h"
#include "internal/platform/mutex_lock.h"
#include "internal/platform/prng.h"
namespace nearby {
namespace connections {
namespace {
using location::nearby::proto::connections::OperationResultCode;
} // namespace
ByteArray Ble::GenerateHash(const std::string& source, size_t size) {
return Utils::Sha256Hash(source, size);
}
ByteArray Ble::GenerateDeviceToken() {
return Utils::Sha256Hash(std::to_string(Prng().NextUint32()),
mediums::BleAdvertisement::kDeviceTokenLength);
}
Ble::Ble(BluetoothRadio& radio) : radio_(radio) {}
bool Ble::IsAvailable() const {
MutexLock lock(&mutex_);
return IsAvailableLocked();
}
bool Ble::IsAvailableLocked() const {
return medium_.IsValid() && adapter_.IsValid() && adapter_.IsEnabled();
}
bool Ble::StartAdvertising(const std::string& service_id,
const ByteArray& advertisement_bytes,
const std::string& fast_advertisement_service_uuid) {
MutexLock lock(&mutex_);
if (advertisement_bytes.Empty()) {
LOG(INFO)
<< "Refusing to turn on BLE advertising. Empty advertisement data.";
return false;
}
if (advertisement_bytes.size() > kMaxAdvertisementLength) {
LOG(INFO) << "Refusing to start BLE advertising because the advertisement "
"was too long. Expected at most "
<< kMaxAdvertisementLength << " bytes but received "
<< advertisement_bytes.size();
return false;
}
if (IsAdvertisingLocked(service_id)) {
LOG(INFO) << "Failed to BLE advertise because we're already advertising.";
return false;
}
if (!radio_.IsEnabled()) {
LOG(INFO)
<< "Can't start BLE adveertising because Bluetooth was never turned on";
return false;
}
if (!IsAvailableLocked()) {
LOG(INFO) << "Can't turn on BLE advertising. BLE is not available.";
return false;
}
LOG(INFO) << "Turning on BLE advertising (advertisement size="
<< advertisement_bytes.size() << ")"
<< ", service id=" << service_id
<< ", fast advertisement service uuid="
<< absl::BytesToHexString(fast_advertisement_service_uuid);
// Wrap the connections advertisement to the medium advertisement.
const bool fast_advertisement = !fast_advertisement_service_uuid.empty();
ByteArray service_id_hash{GenerateHash(
service_id, mediums::BleAdvertisement::kServiceIdHashLength)};
ByteArray medium_advertisement_bytes{mediums::BleAdvertisement{
mediums::BleAdvertisement::Version::kV2,
mediums::BleAdvertisement::SocketVersion::kV2,
fast_advertisement ? ByteArray{} : service_id_hash, advertisement_bytes,
GenerateDeviceToken()}};
if (medium_advertisement_bytes.Empty()) {
LOG(INFO) << "Failed to BLE advertise because we could not "
"create a medium advertisement.";
return false;
}
if (!medium_.StartAdvertising(service_id, medium_advertisement_bytes,
fast_advertisement_service_uuid)) {
LOG(ERROR) << "Failed to turn on BLE advertising with advertisement bytes="
<< absl::BytesToHexString(advertisement_bytes.data())
<< ", size=" << advertisement_bytes.size()
<< ", fast advertisement service uuid="
<< fast_advertisement_service_uuid;
return false;
}
advertising_info_.Add(service_id);
return true;
}
bool Ble::StopAdvertising(const std::string& service_id) {
MutexLock lock(&mutex_);
if (!IsAdvertisingLocked(service_id)) {
LOG(INFO) << "Can't turn off BLE advertising; it is already off";
return false;
}
LOG(INFO) << "Turned off BLE advertising with service id=" << service_id;
bool ret = medium_.StopAdvertising(service_id);
// Reset our bundle of advertising state to mark that we're no longer
// advertising.
advertising_info_.Remove(service_id);
return ret;
}
bool Ble::StartLegacyAdvertising(
const std::string& input_service_id, const std::string& local_endpoint_id,
const std::string& fast_advertisement_service_uuid) {
LOG(INFO) << "StartLegacyAdvertising: " << input_service_id
<< ", local_endpoint_id: " << local_endpoint_id;
MutexLock lock(&mutex_);
std::string service_id = input_service_id + "-Legacy";
if (IsAdvertisingLocked(service_id)) {
LOG(INFO)
<< "Failed to BLE legacy advertise because we're already advertising.";
return false;
}
if (!radio_.IsEnabled()) {
LOG(INFO) << "Can't start BLE legacy advertising because Bluetooth "
"was never turned on";
return false;
}
if (!IsAvailableLocked()) {
LOG(INFO) << "Can't turn on BLE legacy advertising. BLE is not available.";
return false;
}
// TODO(hais) improve working dummy set to feed proper hash value.
std::array<char, 23> encoded_legacy_char_array = {
0x51, 0x43, 0x41, 0x41, 0x41, 0x42, 0x41, 0x43, 0x41, 0x41, 0x41, 0x44,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41};
ByteArray encoded_bytes{encoded_legacy_char_array};
LOG(INFO) << "Turning on BLE advertising (advertisement size="
<< encoded_bytes.size()
<< "): " << absl::BytesToHexString(encoded_bytes.data())
<< ", service id=" << service_id
<< ", fast advertisement service uuid="
<< fast_advertisement_service_uuid;
if (!medium_.StartAdvertising(service_id, encoded_bytes,
fast_advertisement_service_uuid)) {
LOG(ERROR) << "Failed to turn on BLE advertising with advertisement bytes="
<< absl::BytesToHexString(encoded_bytes.data())
<< ", size=" << encoded_bytes.size()
<< ", fast advertisement service uuid="
<< fast_advertisement_service_uuid;
return false;
}
advertising_info_.Add(service_id);
return true;
}
bool Ble::StopLegacyAdvertising(const std::string& input_service_id) {
LOG(INFO) << "StopLegacyAdvertising:" << input_service_id;
MutexLock lock(&mutex_);
std::string service_id = input_service_id + "-Legacy";
if (!IsAdvertisingLocked(service_id)) {
LOG(INFO) << "Can't turn off BLE legacy advertising; it is already off";
return false;
}
LOG(INFO) << "Turned off BLE legacy advertising with service id="
<< service_id;
bool ret = medium_.StopAdvertising(service_id);
// Reset our bundle of advertising state to mark that we're no longer
// advertising.
advertising_info_.Remove(service_id);
return ret;
}
bool Ble::IsAdvertising(const std::string& service_id) {
MutexLock lock(&mutex_);
return IsAdvertisingLocked(service_id);
}
bool Ble::IsAdvertisingLocked(const std::string& service_id) {
return advertising_info_.Existed(service_id);
}
bool Ble::StartScanning(const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
DiscoveredPeripheralCallback callback) {
MutexLock lock(&mutex_);
discovered_peripheral_callback_ = std::move(callback);
if (service_id.empty()) {
LOG(INFO) << "Refusing to start BLE scanning with empty service id.";
return false;
}
if (IsScanningLocked(service_id)) {
LOG(INFO) << "Refusing to start scan of BLE peripherals because "
"another scanning is already in-progress.";
return false;
}
if (!radio_.IsEnabled()) {
LOG(INFO)
<< "Can't start BLE scanning because Bluetooth was never turned on";
return false;
}
if (!IsAvailableLocked()) {
LOG(INFO) << "Can't scan BLE peripherals because BLE isn't available.";
return false;
}
if (!medium_.StartScanning(
service_id, fast_advertisement_service_uuid,
{
.peripheral_discovered_cb =
[this](BlePeripheral& peripheral,
const std::string& service_id,
const ByteArray& medium_advertisement_bytes,
bool fast_advertisement) {
// Don't bother trying to parse zero byte advertisements.
if (medium_advertisement_bytes.size() == 0) {
LOG(INFO) << "Skipping zero byte advertisement "
<< "with service_id: " << service_id;
return;
}
// Unwrap connection BleAdvertisement from medium
// BleAdvertisement.
auto connection_advertisement_bytes =
UnwrapAdvertisementBytes(medium_advertisement_bytes);
discovered_peripheral_callback_.peripheral_discovered_cb(
peripheral, service_id, connection_advertisement_bytes,
fast_advertisement);
},
.peripheral_lost_cb =
[this](BlePeripheral& peripheral,
const std::string& service_id) {
discovered_peripheral_callback_.peripheral_lost_cb(
peripheral, service_id);
},
})) {
LOG(INFO) << "Failed to start scan of BLE services.";
return false;
}
LOG(INFO) << "Turned on BLE scanning with service id=" << service_id;
// Mark the fact that we're currently performing a BLE discovering.
scanning_info_.Add(service_id);
return true;
}
bool Ble::StopScanning(const std::string& service_id) {
MutexLock lock(&mutex_);
if (!IsScanningLocked(service_id)) {
LOG(INFO) << "Can't turn off BLE scanning because we never "
"started scanning.";
return false;
}
LOG(INFO) << "Turned off BLE scanning with service id=" << service_id;
bool ret = medium_.StopScanning(service_id);
scanning_info_.Clear();
return ret;
}
bool Ble::IsScanning(const std::string& service_id) {
MutexLock lock(&mutex_);
return IsScanningLocked(service_id);
}
bool Ble::IsScanningLocked(const std::string& service_id) {
return scanning_info_.Existed(service_id);
}
bool Ble::StartAcceptingConnections(const std::string& service_id,
AcceptedConnectionCallback callback) {
MutexLock lock(&mutex_);
if (service_id.empty()) {
LOG(INFO)
<< "Refusing to start accepting BLE connections with empty service id.";
return false;
}
if (IsAcceptingConnectionsLocked(service_id)) {
LOG(INFO)
<< "Refusing to start accepting BLE connections for " << service_id
<< " because another BLE peripheral socket is already in-progress.";
return false;
}
if (!radio_.IsEnabled()) {
LOG(INFO) << "Can't start accepting BLE connections for " << service_id
<< " because Bluetooth isn't enabled.";
return false;
}
if (!IsAvailableLocked()) {
LOG(INFO) << "Can't start accepting BLE connections for " << service_id
<< " because BLE isn't available.";
return false;
}
if (!medium_.StartAcceptingConnections(service_id, std::move(callback))) {
LOG(INFO) << "Failed to accept connections callback for " << service_id
<< " .";
return false;
}
accepting_connections_info_.Add(service_id);
return true;
}
bool Ble::StopAcceptingConnections(const std::string& service_id) {
MutexLock lock(&mutex_);
if (!IsAcceptingConnectionsLocked(service_id)) {
LOG(INFO)
<< "Can't stop accepting BLE connections because it was never started.";
return false;
}
bool ret = medium_.StopAcceptingConnections(service_id);
// Reset our bundle of accepting connections state to mark that we're no
// longer accepting connections.
accepting_connections_info_.Remove(service_id);
return ret;
}
bool Ble::IsAcceptingConnections(const std::string& service_id) {
MutexLock lock(&mutex_);
return IsAcceptingConnectionsLocked(service_id);
}
bool Ble::IsAcceptingConnectionsLocked(const std::string& service_id) {
return accepting_connections_info_.Existed(service_id);
}
ErrorOr<BleSocket> Ble::Connect(BlePeripheral& peripheral,
const std::string& service_id,
CancellationFlag* cancellation_flag) {
MutexLock lock(&mutex_);
LOG(INFO) << "BLE::Connect: service=" << &peripheral;
// Socket to return. To allow for NRVO to work, it has to be a single object.
BleSocket socket;
if (service_id.empty()) {
LOG(INFO) << "Refusing to create BLE socket with empty service_id.";
return {Error(OperationResultCode::NEARBY_LOCAL_CLIENT_STATE_WRONG)};
}
if (!radio_.IsEnabled()) {
LOG(INFO) << "Can't create client BLE socket to " << &peripheral
<< " because Bluetooth isn't enabled.";
return {Error(OperationResultCode::MISCELLEANEOUS_BLE_SYSTEM_SERVICE_NULL)};
}
if (!IsAvailableLocked()) {
LOG(INFO) << "Can't create client BLE socket [service_id=" << service_id
<< "]; BLE isn't available.";
return {Error(OperationResultCode::MEDIUM_UNAVAILABLE_BLE_NOT_AVAILABLE)};
}
if (cancellation_flag->Cancelled()) {
LOG(INFO) << "Can't create client BLE socket due to cancel.";
return {Error(OperationResultCode::
CLIENT_CANCELLATION_CANCEL_BLE_OUTGOING_CONNECTION)};
}
socket = medium_.Connect(peripheral, service_id, cancellation_flag);
if (!socket.IsValid()) {
LOG(INFO) << "Failed to Connect via BLE [service=" << service_id << "]";
}
return socket;
}
ByteArray Ble::UnwrapAdvertisementBytes(
const ByteArray& medium_advertisement_data) {
auto medium_ble_advertisement_status_or =
mediums::BleAdvertisement::CreateBleAdvertisement(
medium_advertisement_data);
if (!medium_ble_advertisement_status_or.ok()) {
LOG(INFO) << medium_ble_advertisement_status_or.status();
return ByteArray();
}
return medium_ble_advertisement_status_or.value().GetData();
}
} // namespace connections
} // namespace nearby
-201
View File
@@ -1,201 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CORE_INTERNAL_MEDIUMS_BLE_H_
#define CORE_INTERNAL_MEDIUMS_BLE_H_
#include <string>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_set.h"
#include "connections/implementation/mediums/bluetooth_radio.h"
#include "connections/listeners.h"
#include "internal/platform/ble.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/expected.h"
#include "internal/platform/multi_thread_executor.h"
#include "internal/platform/mutex.h"
namespace nearby {
namespace connections {
class Ble {
public:
using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback;
using AcceptedConnectionCallback = BleMedium::AcceptedConnectionCallback;
explicit Ble(BluetoothRadio& bluetooth_radio);
~Ble() = default;
// Returns true, if Ble communications are supported by a platform.
bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_);
// Sets custom advertisement data, and then enables Ble advertising.
// Returns true, if data is successfully set, and false otherwise.
bool StartAdvertising(const std::string& service_id,
const ByteArray& advertisement_bytes,
const std::string& fast_advertisement_service_uuid)
ABSL_LOCKS_EXCLUDED(mutex_);
// Disables Ble advertising.
bool StopAdvertising(const std::string& service_id)
ABSL_LOCKS_EXCLUDED(mutex_);
// (TODO:hais) remove this after ble_v2 refactor
// Sets custom advertisement data, and then enables Ble advertising.
// Returns true, if data is successfully set, and false otherwise.
bool StartLegacyAdvertising(
const std::string& service_id, const std::string& local_endpoint_id,
const std::string& fast_advertisement_service_uuid)
ABSL_LOCKS_EXCLUDED(mutex_);
// (TODO:hais) remove this after ble_v2 refactor
// Disables Ble advertising.
bool StopLegacyAdvertising(const std::string& service_id)
ABSL_LOCKS_EXCLUDED(mutex_);
bool IsAdvertising(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_);
// Enables Ble scanning mode. Will report any discoverable peripherals in
// range through a callback. Returns true, if scanning mode was enabled,
// false otherwise.
bool StartScanning(const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
DiscoveredPeripheralCallback callback)
ABSL_LOCKS_EXCLUDED(mutex_);
// Disables Ble discovery mode.
bool StopScanning(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_);
bool IsScanning(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_);
// Starts a worker thread, creates a Ble socket, associates it with a
// service id.
bool StartAcceptingConnections(const std::string& service_id,
AcceptedConnectionCallback callback)
ABSL_LOCKS_EXCLUDED(mutex_);
// Closes socket corresponding to a service id.
bool StopAcceptingConnections(const std::string& service_id)
ABSL_LOCKS_EXCLUDED(mutex_);
bool IsAcceptingConnections(const std::string& service_id)
ABSL_LOCKS_EXCLUDED(mutex_);
// Returns true if this object owns a valid platform implementation.
bool IsMediumValid() const ABSL_LOCKS_EXCLUDED(mutex_) {
MutexLock lock(&mutex_);
return medium_.IsValid();
}
// Returns true if this object has a valid BluetoothAdapter reference.
bool IsAdapterValid() const ABSL_LOCKS_EXCLUDED(mutex_) {
MutexLock lock(&mutex_);
return adapter_.IsValid();
}
// Establishes connection to Ble peripheral that was might be started on
// another peripheral with StartAcceptingConnections() using the same
// service_id. Blocks until connection is established, or server-side is
// terminated. Returns socket instance. On success, BleSocket.IsValid() return
// true.
ErrorOr<BleSocket> Connect(BlePeripheral& peripheral,
const std::string& service_id,
CancellationFlag* cancellation_flag)
ABSL_LOCKS_EXCLUDED(mutex_);
private:
struct AdvertisingInfo {
bool Empty() const { return service_ids.empty(); }
void Clear() { service_ids.clear(); }
void Add(const std::string& service_id) { service_ids.emplace(service_id); }
void Remove(const std::string& service_id) {
service_ids.erase(service_id);
}
bool Existed(const std::string& service_id) const {
return service_ids.contains(service_id);
}
absl::flat_hash_set<std::string> service_ids;
};
struct ScanningInfo {
bool Empty() const { return service_ids.empty(); }
void Clear() { service_ids.clear(); }
void Add(const std::string& service_id) { service_ids.emplace(service_id); }
void Remove(const std::string& service_id) {
service_ids.erase(service_id);
}
bool Existed(const std::string& service_id) const {
return service_ids.contains(service_id);
}
absl::flat_hash_set<std::string> service_ids;
};
struct AcceptingConnectionsInfo {
bool Empty() const { return service_ids.empty(); }
void Clear() { service_ids.clear(); }
void Add(const std::string& service_id) { service_ids.emplace(service_id); }
void Remove(const std::string& service_id) {
service_ids.erase(service_id);
}
bool Existed(const std::string& service_id) const {
return service_ids.contains(service_id);
}
absl::flat_hash_set<std::string> service_ids;
};
static constexpr int kMaxAdvertisementLength = 512;
static ByteArray GenerateHash(const std::string& source, size_t size);
static ByteArray GenerateDeviceToken();
// Same as IsAvailable(), but must be called with mutex_ held.
bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Same as IsAdvertising(), but must be called with mutex_ held.
bool IsAdvertisingLocked(const std::string& service_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Same as IsDiscovering(), but must be called with mutex_ held.
bool IsScanningLocked(const std::string& service_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Same as IsAcceptingConnections(), but must be called with mutex_ held.
bool IsAcceptingConnectionsLocked(const std::string& service_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Extract connection advertisement from medium advertisement.
ByteArray UnwrapAdvertisementBytes(
const ByteArray& medium_advertisement_data);
mutable Mutex mutex_;
BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_);
BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_){
radio_.GetBluetoothAdapter()};
BleMedium medium_ ABSL_GUARDED_BY(mutex_){adapter_};
AdvertisingInfo advertising_info_ ABSL_GUARDED_BY(mutex_);
ScanningInfo scanning_info_ ABSL_GUARDED_BY(mutex_);
DiscoveredPeripheralCallback discovered_peripheral_callback_;
AcceptingConnectionsInfo accepting_connections_info_ ABSL_GUARDED_BY(mutex_);
};
} // namespace connections
} // namespace nearby
#endif // CORE_INTERNAL_MEDIUMS_BLE_H_
@@ -1,311 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "connections/implementation/mediums/ble.h"
#include <atomic>
#include <string>
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "connections/implementation/mediums/bluetooth_radio.h"
#include "internal/platform/ble.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/expected.h"
#include "internal/platform/feature_flags.h"
#include "internal/platform/logging.h"
#include "internal/platform/medium_environment.h"
namespace nearby {
namespace connections {
namespace {
using FeatureFlags = FeatureFlags::Flags;
constexpr FeatureFlags kTestCases[] = {
FeatureFlags{
.enable_cancellation_flag = true,
},
FeatureFlags{
.enable_cancellation_flag = false,
},
};
constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000);
constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"};
constexpr absl::string_view kAdvertisementString{"\x0a\x0b\x0c\x0d"};
constexpr absl::string_view kFastAdvertisementServiceUuid{"\xf3\xfe"};
class BleTest : public ::testing::TestWithParam<FeatureFlags> {
protected:
using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback;
MediumEnvironment& env_{MediumEnvironment::Instance()};
};
TEST_P(BleTest, CanStartAcceptingConnectionsAndConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
BluetoothRadio radio_a;
BluetoothRadio radio_b;
Ble ble_a{radio_a};
Ble ble_b{radio_b};
radio_a.Enable();
radio_b.Enable();
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch accept_latch(1);
ble_a.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid);
ble_a.StartAcceptingConnections(
service_id,
[&](BleSocket socket, const std::string&) { accept_latch.CountDown(); });
std::atomic<BlePeripheral> atomic_discovered_peripheral;
ble_b.StartScanning(
service_id, fast_advertisement_service_uuid,
{
.peripheral_discovered_cb =
[&found_latch, &atomic_discovered_peripheral](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
LOG(INFO) << "Discovered peripheral=" << peripheral.GetName()
<< ", impl=" << &peripheral.GetImpl()
<< ", fast advertisement=" << fast_advertisement;
atomic_discovered_peripheral.store(peripheral);
found_latch.CountDown();
},
});
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
BlePeripheral discovered_peripheral = atomic_discovered_peripheral.load();
ASSERT_TRUE(discovered_peripheral.IsValid());
CancellationFlag flag;
ErrorOr<BleSocket> socket_result =
ble_b.Connect(discovered_peripheral, service_id, &flag);
EXPECT_TRUE(accept_latch.Await(kWaitDuration).result());
EXPECT_TRUE(socket_result.has_value());
EXPECT_TRUE(socket_result.value().IsValid());
ble_b.StopScanning(service_id);
ble_a.StopAdvertising(service_id);
env_.Stop();
}
TEST_P(BleTest, CanCancelConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
BluetoothRadio radio_a;
BluetoothRadio radio_b;
Ble ble_a{radio_a};
Ble ble_b{radio_b};
radio_a.Enable();
radio_b.Enable();
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch accept_latch(1);
ble_a.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid);
ble_a.StartAcceptingConnections(
service_id,
[&](BleSocket socket, const std::string&) { accept_latch.CountDown(); });
std::atomic<BlePeripheral> atomic_discovered_peripheral;
ble_b.StartScanning(
service_id, fast_advertisement_service_uuid,
{
.peripheral_discovered_cb =
[&found_latch, &atomic_discovered_peripheral](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
LOG(INFO) << "Discovered peripheral=" << peripheral.GetName()
<< ", impl=" << &peripheral.GetImpl()
<< ", fast advertisement=" << fast_advertisement;
atomic_discovered_peripheral.store(peripheral);
found_latch.CountDown();
},
});
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
BlePeripheral discovered_peripheral = atomic_discovered_peripheral.load();
ASSERT_TRUE(discovered_peripheral.IsValid());
CancellationFlag flag(true);
ErrorOr<BleSocket> socket_result =
ble_b.Connect(discovered_peripheral, service_id, &flag);
// If FeatureFlag is disabled, Cancelled is false as no-op.
if (!feature_flags.enable_cancellation_flag) {
EXPECT_TRUE(accept_latch.Await(kWaitDuration).result());
EXPECT_TRUE(socket_result.has_value());
EXPECT_TRUE(socket_result.value().IsValid());
} else {
EXPECT_FALSE(accept_latch.Await(kWaitDuration).result());
EXPECT_TRUE(socket_result.has_error());
}
ble_b.StopScanning(service_id);
ble_a.StopAdvertising(service_id);
env_.Stop();
}
INSTANTIATE_TEST_SUITE_P(ParametrisedBleTest, BleTest,
::testing::ValuesIn(kTestCases));
TEST_F(BleTest, CanConstructValidObject) {
env_.Start();
BluetoothRadio radio_a;
BluetoothRadio radio_b;
Ble ble_a{radio_a};
Ble ble_b{radio_b};
EXPECT_TRUE(ble_a.IsMediumValid());
EXPECT_TRUE(ble_a.IsAdapterValid());
EXPECT_TRUE(ble_a.IsAvailable());
EXPECT_TRUE(ble_b.IsMediumValid());
EXPECT_TRUE(ble_b.IsAdapterValid());
EXPECT_TRUE(ble_b.IsAvailable());
EXPECT_NE(&radio_a.GetBluetoothAdapter(), &radio_b.GetBluetoothAdapter());
env_.Stop();
}
TEST_F(BleTest, CanStartAdvertising) {
env_.Start();
BluetoothRadio radio_a;
BluetoothRadio radio_b;
Ble ble_a{radio_a};
Ble ble_b{radio_b};
radio_a.Enable();
radio_b.Enable();
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
ble_b.StartScanning(
service_id, fast_advertisement_service_uuid,
DiscoveredPeripheralCallback{
.peripheral_discovered_cb =
[&found_latch](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { found_latch.CountDown(); },
});
EXPECT_TRUE(ble_a.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid));
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
EXPECT_TRUE(ble_a.StopAdvertising(service_id));
EXPECT_TRUE(ble_b.StopScanning(service_id));
env_.Stop();
}
TEST_F(BleTest, CanStartDiscovery) {
env_.Start();
BluetoothRadio radio_a;
BluetoothRadio radio_b;
Ble ble_a{radio_a};
Ble ble_b{radio_b};
radio_a.Enable();
radio_b.Enable();
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch accept_latch(1);
CountDownLatch lost_latch(1);
ble_b.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid);
EXPECT_TRUE(ble_a.StartScanning(
service_id, fast_advertisement_service_uuid,
DiscoveredPeripheralCallback{
.peripheral_discovered_cb =
[&accept_latch](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { accept_latch.CountDown(); },
.peripheral_lost_cb =
[&lost_latch](BlePeripheral& peripheral,
const std::string& service_id) {
lost_latch.CountDown();
},
}));
EXPECT_TRUE(accept_latch.Await(kWaitDuration).result());
ble_b.StopAdvertising(service_id);
EXPECT_TRUE(lost_latch.Await(kWaitDuration).result());
EXPECT_TRUE(ble_a.StopScanning(service_id));
env_.Stop();
}
TEST_F(BleTest, CanStartAndStopLegacyAdvertising) {
env_.Start();
BluetoothRadio radio_a;
Ble ble_a{radio_a};
radio_a.Enable();
std::string service_id(kServiceID);
std::string legacy_service_id(std::string{kServiceID} + "-Legacy");
std::string device_a_endpoint_id{"1A1A"};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
EXPECT_TRUE(ble_a.StartLegacyAdvertising(service_id, device_a_endpoint_id,
fast_advertisement_service_uuid));
EXPECT_FALSE(ble_a.IsAdvertising(service_id));
EXPECT_TRUE(ble_a.IsAdvertising(legacy_service_id));
EXPECT_TRUE(ble_a.StopLegacyAdvertising(service_id));
EXPECT_FALSE(ble_a.IsAdvertising(legacy_service_id));
env_.Stop();
}
TEST_F(BleTest, CanStartLegacyAdvertisingWithEmptyServiceUuid) {
env_.Start();
BluetoothRadio radio_a;
Ble ble_a{radio_a};
radio_a.Enable();
std::string service_id(kServiceID);
std::string legacy_service_id(std::string{kServiceID} + "-Legacy");
std::string device_a_endpoint_id{"1A1A"};
EXPECT_TRUE(
ble_a.StartLegacyAdvertising(service_id, device_a_endpoint_id,
/*fast_advertisement_service_uuid=*/""));
EXPECT_FALSE(ble_a.IsAdvertising(service_id));
EXPECT_TRUE(ble_a.IsAdvertising(legacy_service_id));
EXPECT_TRUE(ble_a.StopLegacyAdvertising(service_id));
EXPECT_FALSE(ble_a.IsAdvertising(legacy_service_id));
env_.Stop();
}
TEST_F(BleTest, ConnectWithEmptyServiceId) {
env_.Start();
BluetoothRadio radio_a;
Ble ble_a{radio_a};
radio_a.Enable();
BlePeripheral peripheral;
CancellationFlag flag;
ErrorOr<BleSocket> socket_result =
ble_a.Connect(peripheral, /*service_id=*/"", &flag);
EXPECT_TRUE(socket_result.has_error());
env_.Stop();
}
} // namespace
} // namespace connections
} // namespace nearby
@@ -37,8 +37,8 @@ constexpr int BleAdvertisementHeader::kPsmValueByteLength;
BleAdvertisementHeader::BleAdvertisementHeader(
Version version, bool support_extended_advertisement, int num_slots,
const ByteArray &service_id_bloom_filter,
const ByteArray &advertisement_hash, int psm) {
const ByteArray& service_id_bloom_filter,
const ByteArray& advertisement_hash, int psm) {
if (version != Version::kV2 || num_slots < 0 ||
service_id_bloom_filter.size() != kServiceIdBloomFilterByteLength ||
advertisement_hash.size() != kAdvertisementHashByteLength) {
@@ -54,27 +54,20 @@ BleAdvertisementHeader::BleAdvertisementHeader(
}
BleAdvertisementHeader::BleAdvertisementHeader(
const ByteArray &ble_advertisement_header_bytes) {
const ByteArray& ble_advertisement_header_bytes) {
ByteArray advertisement_header_bytes =
Base64Utils::Decode(ble_advertisement_header_bytes.AsStringView());
if (advertisement_header_bytes.Empty()) {
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
// The BLE advertisement header is not encoded in base64, but still try to
// parse it as raw bytes.
if (ble_advertisement_header_bytes.size() ==
kMinAdvertisementHeaderLength ||
ble_advertisement_header_bytes.size() ==
kMinAdvertisementHeaderLength + 2) {
advertisement_header_bytes = ble_advertisement_header_bytes;
} else {
VLOG(1) << "Cannot deserialize BLEAdvertisementHeader. "
"Invalid advertising data.";
return;
}
// The BLE advertisement header is not encoded in base64, but still try to
// parse it as raw bytes.
if (ble_advertisement_header_bytes.size() ==
kMinAdvertisementHeaderLength ||
ble_advertisement_header_bytes.size() ==
kMinAdvertisementHeaderLength + 2) {
advertisement_header_bytes = ble_advertisement_header_bytes;
} else {
LOG(INFO) << "Cannot deserialize BLEAdvertisementHeader: failed "
"Base64 decoding";
VLOG(1) << "Cannot deserialize BLEAdvertisementHeader. "
"Invalid advertising data.";
return;
}
}
@@ -145,7 +138,7 @@ BleAdvertisementHeader::operator ByteArray() const {
// Convert psm_ value to 2-bytes.
ByteArray psm_bytes{kPsmValueByteLength};
char *data = psm_bytes.data();
char* data = psm_bytes.data();
data[0] = (psm_ & 0xFF00) >> 8;
data[1] = psm_ & 0x00FF;
@@ -155,16 +148,11 @@ BleAdvertisementHeader::operator ByteArray() const {
std::string(advertisement_hash_),
std::string(psm_bytes));
// clang-format on
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
return ByteArray(std::move(out));
} else {
return ByteArray(Base64Utils::Encode(ByteArray(std::move(out))));
}
return ByteArray(std::move(out));
}
bool BleAdvertisementHeader::operator==(
const BleAdvertisementHeader &rhs) const {
const BleAdvertisementHeader& rhs) const {
return GetVersion() == rhs.GetVersion() &&
IsSupportExtendedAdvertisement() ==
rhs.IsSupportExtendedAdvertisement() &&
@@ -22,8 +22,6 @@ BluetoothRadio& Mediums::GetBluetoothRadio() { return bluetooth_radio_; }
BluetoothClassic& Mediums::GetBluetoothClassic() { return bluetooth_classic_; }
Ble& Mediums::GetBle() { return ble_; }
BleV2& Mediums::GetBleV2() { return ble_v2_; }
Wifi& Mediums::GetWifi() { return wifi_; }
@@ -16,7 +16,6 @@
#define CORE_INTERNAL_MEDIUMS_MEDIUMS_H_
#include "connections/implementation/mediums/awdl.h"
#include "connections/implementation/mediums/ble.h"
#include "connections/implementation/mediums/ble_v2.h"
#include "connections/implementation/mediums/bluetooth_classic.h"
#include "connections/implementation/mediums/bluetooth_radio.h"
@@ -45,9 +44,6 @@ class Mediums {
// Returns a handle to the Bluetooth Classic medium.
BluetoothClassic& GetBluetoothClassic();
// Returns a handle to the Ble medium.
Ble& GetBle();
// Returns a handle to the Ble medium.
BleV2& GetBleV2();
@@ -80,7 +76,6 @@ class Mediums {
// corresponding radio.
BluetoothRadio bluetooth_radio_;
BluetoothClassic bluetooth_classic_{bluetooth_radio_};
Ble ble_{bluetooth_radio_};
BleV2 ble_v2_{bluetooth_radio_};
Wifi wifi_;
WifiLan wifi_lan_;
@@ -95,8 +95,6 @@ class OfflineServiceControllerTest
: public ::testing::TestWithParam<BooleanMediumSelector> {
protected:
void SetUp() override {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableBleV2, true);
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::
kEnableSafeToDisconnect,
@@ -32,7 +32,6 @@
#include "connections/implementation/awdl_endpoint_channel.h"
#include "connections/implementation/base_pcp_handler.h"
#include "connections/implementation/ble_advertisement.h"
#include "connections/implementation/ble_endpoint_channel.h"
#include "connections/implementation/ble_l2cap_endpoint_channel.h"
#include "connections/implementation/ble_v2_endpoint_channel.h"
#include "connections/implementation/bluetooth_device_name.h"
@@ -63,7 +62,6 @@
#include "internal/flags/nearby_flags.h"
#include "internal/interop/device.h"
#include "internal/platform/awdl.h"
#include "internal/platform/ble.h"
#include "internal/platform/ble_v2.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/bluetooth_classic.h"
@@ -117,7 +115,6 @@ P2pClusterPcpHandler::P2pClusterPcpHandler(
awdl_medium_(mediums->GetAwdl()),
bluetooth_radio_(mediums->GetBluetoothRadio()),
bluetooth_medium_(mediums->GetBluetoothClassic()),
ble_medium_(mediums->GetBle()),
ble_v2_medium_(mediums->GetBleV2()),
wifi_lan_medium_(mediums->GetWifiLan()),
wifi_hotspot_medium_(mediums->GetWifiHotspot()),
@@ -144,15 +141,8 @@ std::vector<Medium> P2pClusterPcpHandler::GetConnectionMediumsByPriority() {
if (bluetooth_medium_.IsAvailable()) {
mediums.push_back(BLUETOOTH);
}
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
if (ble_v2_medium_.IsAvailable()) {
mediums.push_back(BLE);
}
} else {
if (ble_medium_.IsAvailable()) {
mediums.push_back(BLE);
}
if (ble_v2_medium_.IsAvailable()) {
mediums.push_back(BLE);
}
return mediums;
@@ -230,34 +220,9 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl(
if (bluetooth_medium != UNKNOWN_MEDIUM) {
LOG(INFO) << "P2pClusterPcpHandler::StartAdvertisingImpl: BT started";
// TODO(hais): update this after ble_v2 refactor.
if (api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kChromeOS &&
!NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleV2)) {
if (ble_medium_.StartLegacyAdvertising(
service_id, local_endpoint_id,
advertising_options.fast_advertisement_service_uuid)) {
VLOG(1) << "P2pClusterPcpHandler::StartAdvertisingImpl: "
"Ble legacy started advertising";
VLOG(1) << "P2pClusterPcpHandler::StartAdvertisingImpl: BT added";
mediums_started_successfully.push_back(bluetooth_medium);
bluetooth_classic_advertiser_client_id_ = client->GetClientId();
} else {
// TODO(hais): update this after ble_v2 refactor.
LOG(WARNING) << "P2pClusterPcpHandler::StartAdvertisingImpl: "
"BLE legacy failed, revert BTC";
bluetooth_medium_.TurnOffDiscoverability();
bluetooth_medium_.StopAcceptingConnections(service_id);
}
} else if ((api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kChromeOS ||
api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kLinux) &&
NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleV2)) {
api::OSName::kChromeOS ||
api::ImplementationPlatform::GetCurrentOS() == api::OSName::kLinux) {
if (ble_v2_medium_.StartLegacyAdvertising(
service_id, local_endpoint_id,
advertising_options.fast_advertisement_service_uuid)) {
@@ -290,24 +255,14 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl(
if (advertising_options.allowed.ble) {
ErrorOr<Medium> ble_result = {Error(OperationResultCode::DETAIL_UNKNOWN)};
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
ble_result = StartBleV2Advertising(client, service_id, local_endpoint_id,
local_endpoint_info,
advertising_options, web_rtc_state);
if (ble_result.has_value() && ble_result.value() != UNKNOWN_MEDIUM) {
VLOG(1) << "P2pClusterPcpHandler::StartAdvertisingImpl: Ble added";
mediums_started_successfully.push_back(ble_result.value());
}
} else {
ble_result = StartBleAdvertising(client, service_id, local_endpoint_id,
ble_result = StartBleV2Advertising(client, service_id, local_endpoint_id,
local_endpoint_info, advertising_options,
web_rtc_state);
if (ble_result.has_value() && ble_result.value() != UNKNOWN_MEDIUM) {
VLOG(1) << "P2pClusterPcpHandler::StartAdvertisingImpl: Ble added";
mediums_started_successfully.push_back(ble_result.value());
}
if (ble_result.has_value() && ble_result.value() != UNKNOWN_MEDIUM) {
VLOG(1) << "P2pClusterPcpHandler::StartAdvertisingImpl: Ble added";
mediums_started_successfully.push_back(ble_result.value());
}
std::unique_ptr<ConnectionsLog::OperationResultWithMedium>
operation_result_with_medium = GetOperationResultWithMediumByResultCode(
client, BLE, /*update_index=*/0,
@@ -342,18 +297,8 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartAdvertisingImpl(
Status P2pClusterPcpHandler::StopAdvertisingImpl(ClientProxy* client) {
if (client->GetClientId() == bluetooth_classic_advertiser_client_id_) {
bluetooth_medium_.TurnOffDiscoverability();
// TODO(hais): update this after ble_v2 refactor.
if (api::ImplementationPlatform::GetCurrentOS() == api::OSName::kChromeOS &&
!NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
ble_medium_.StopLegacyAdvertising(client->GetAdvertisingServiceId());
} else if ((api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kChromeOS ||
api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kLinux) &&
NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleV2)) {
if (api::ImplementationPlatform::GetCurrentOS() == api::OSName::kChromeOS ||
api::ImplementationPlatform::GetCurrentOS() == api::OSName::kLinux) {
ble_v2_medium_.StopLegacyAdvertising(client->GetAdvertisingServiceId());
}
bluetooth_classic_advertiser_client_id_ = 0;
@@ -365,20 +310,12 @@ Status P2pClusterPcpHandler::StopAdvertisingImpl(ClientProxy* client) {
}
bluetooth_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId());
ble_v2_medium_.StopAdvertising(client->GetAdvertisingServiceId());
ble_v2_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId());
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
ble_v2_medium_.StopAdvertising(client->GetAdvertisingServiceId());
ble_v2_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId());
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleL2cap)) {
ble_v2_medium_.StopAcceptingL2capConnections(
client->GetAdvertisingServiceId());
}
} else {
ble_medium_.StopAdvertising(client->GetAdvertisingServiceId());
ble_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId());
config_package_nearby::nearby_connections_feature::kEnableBleL2cap)) {
ble_v2_medium_.StopAcceptingL2capConnections(
client->GetAdvertisingServiceId());
}
wifi_lan_medium_.StopAdvertising(client->GetAdvertisingServiceId());
@@ -592,165 +529,6 @@ void P2pClusterPcpHandler::BluetoothDeviceLostHandler(
});
}
bool P2pClusterPcpHandler::IsRecognizedBleEndpoint(
const std::string& service_id,
const BleAdvertisement& advertisement) const {
if (advertisement.GetPcp() != GetPcp()) {
LOG(INFO) << "BleAdvertisement doesn't match on Pcp; expected "
<< PcpToStrategy(GetPcp()).GetName() << ", found "
<< PcpToStrategy(advertisement.GetPcp()).GetName();
return false;
}
// Check ServiceId for normal advertisement.
// ServiceIdHash is empty for fast advertisement.
if (!advertisement.IsFastAdvertisement()) {
ByteArray expected_service_id_hash =
GenerateHash(service_id, BleAdvertisement::kServiceIdHashLength);
if (advertisement.GetServiceIdHash() != expected_service_id_hash) {
LOG(INFO)
<< "BleAdvertisement doesn't match on expected service_id_hash; "
"expected "
<< absl::BytesToHexString(expected_service_id_hash.data())
<< ", found "
<< absl::BytesToHexString(advertisement.GetServiceIdHash().data());
return false;
}
}
return true;
}
void P2pClusterPcpHandler::BlePeripheralDiscoveredHandler(
ClientProxy* client, BlePeripheral& peripheral,
const std::string& service_id, const ByteArray& advertisement_bytes,
bool fast_advertisement) {
RunOnPcpHandlerThread(
"p2p-ble-device-discovered",
[this, client, &peripheral, service_id, advertisement_bytes,
fast_advertisement]() RUN_ON_PCP_HANDLER_THREAD() {
// Make sure we are still discovering before proceeding.
if (!client->IsDiscovering() || stop_.Get()) {
LOG(WARNING) << "Skipping discovery of BleAdvertisement header "
<< absl::BytesToHexString(advertisement_bytes.data())
<< " because we are no longer discovering.";
return;
}
auto ble_status_or = BleAdvertisement::CreateBleAdvertisement(
fast_advertisement, advertisement_bytes);
if (!ble_status_or.ok()) {
LOG(ERROR) << ble_status_or.status();
return;
}
const auto& advertisement = ble_status_or.value();
// Make sure the BLE advertisement points to a valid
// endpoint we're discovering.
if (!IsRecognizedBleEndpoint(service_id, advertisement)) return;
// Store all the state we need to be able to re-create a BleEndpoint
// in BlePeripheralLostHandler, since that isn't privy to
// the bytes of the ble advertisement itself.
found_ble_endpoints_.emplace(
peripheral.GetName(),
BleEndpointState(advertisement.GetEndpointId(),
advertisement.GetEndpointInfo()));
StopEndpointLostByMediumAlarm(advertisement.GetEndpointId(), BLE);
// Report the discovered endpoint to the client.
VLOG(1) << "Found BleAdvertisement "
<< absl::BytesToHexString(advertisement_bytes.data())
<< " (with endpoint_id=" << advertisement.GetEndpointId()
<< ", and endpoint_info="
<< absl::BytesToHexString(
advertisement.GetEndpointInfo().data())
<< ").";
OnEndpointFound(
client,
std::make_shared<BleEndpoint>(BleEndpoint{
{advertisement.GetEndpointId(), advertisement.GetEndpointInfo(),
service_id, BLE, advertisement.GetWebRtcState()},
peripheral,
}));
// Make sure we can connect to this device via Classic Bluetooth.
MacAddress remote_bluetooth_mac_address =
advertisement.GetBluetoothMacAddress();
if (!remote_bluetooth_mac_address.IsSet()) {
LOG(INFO)
<< "No Bluetooth Classic MAC address found in advertisement.";
return;
}
BluetoothDevice remote_bluetooth_device =
bluetooth_medium_.GetRemoteDevice(remote_bluetooth_mac_address);
if (!remote_bluetooth_device.IsValid()) {
LOG(INFO)
<< "A valid Bluetooth device could not be derived from the MAC "
"address "
<< remote_bluetooth_mac_address.ToString();
return;
}
StopEndpointLostByMediumAlarm(advertisement.GetEndpointId(), BLUETOOTH);
OnEndpointFound(client,
std::make_shared<BluetoothEndpoint>(BluetoothEndpoint{
{
advertisement.GetEndpointId(),
advertisement.GetEndpointInfo(),
service_id,
BLUETOOTH,
advertisement.GetWebRtcState(),
},
remote_bluetooth_device,
}));
});
}
void P2pClusterPcpHandler::BlePeripheralLostHandler(
ClientProxy* client, BlePeripheral& peripheral,
const std::string& service_id) {
std::string peripheral_name = peripheral.GetName();
LOG(INFO) << "Ble: [LOST, SCHED] peripheral_name=" << peripheral_name;
RunOnPcpHandlerThread(
"p2p-ble-device-lost",
[this, client, service_id, &peripheral]() RUN_ON_PCP_HANDLER_THREAD() {
// Make sure we are still discovering before proceeding.
if (!client->IsDiscovering() || stop_.Get()) {
LOG(WARNING) << "Ignoring lost BlePeripheral because we are "
"no longer discovering.";
return;
}
// Remove this BlePeripheral from found_ble_endpoints_, and
// report the endpoint as lost to the client.
auto item = found_ble_endpoints_.find(peripheral.GetName());
if (item != found_ble_endpoints_.end()) {
BleEndpointState ble_endpoint_state(item->second);
found_ble_endpoints_.erase(item);
// Report the discovered endpoint to the client.
VLOG(1) << "Lost BleEndpoint for BlePeripheral "
<< peripheral.GetName()
<< " (with endpoint_id=" << ble_endpoint_state.endpoint_id
<< " and endpoint_info="
<< absl::BytesToHexString(
ble_endpoint_state.endpoint_info.data())
<< ").";
OnEndpointLost(client, DiscoveredEndpoint{
ble_endpoint_state.endpoint_id,
ble_endpoint_state.endpoint_info,
service_id,
BLE,
WebRtcState::kUndefined,
});
}
});
}
bool P2pClusterPcpHandler::IsRecognizedBleV2Endpoint(
absl::string_view service_id, const BleAdvertisement& advertisement) const {
if (!advertisement.IsValid()) {
@@ -1320,30 +1098,16 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl(
if (discovery_options.allowed.ble) {
ErrorOr<Medium> ble_result = {Error(OperationResultCode::DETAIL_UNKNOWN)};
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
ble_result = StartBleV2Scanning(client, service_id, discovery_options);
Medium ble_v2_medium = UNKNOWN_MEDIUM;
if (ble_result.has_value()) {
ble_v2_medium = ble_result.value();
}
if (ble_v2_medium != UNKNOWN_MEDIUM) {
LOG(INFO) << "P2pClusterPcpHandler::StartDiscoveryImpl: Ble v2 added";
mediums_started_successfully.push_back(ble_v2_medium);
}
} else {
ble_result =
StartBleScanning(client, service_id,
discovery_options.fast_advertisement_service_uuid);
Medium ble_medium = UNKNOWN_MEDIUM;
if (ble_result.has_value()) {
ble_medium = ble_result.value();
}
if (ble_medium != UNKNOWN_MEDIUM) {
LOG(INFO) << "P2pClusterPcpHandler::StartDiscoveryImpl: Ble added";
mediums_started_successfully.push_back(ble_medium);
}
ble_result = StartBleV2Scanning(client, service_id, discovery_options);
Medium ble_v2_medium = UNKNOWN_MEDIUM;
if (ble_result.has_value()) {
ble_v2_medium = ble_result.value();
}
if (ble_v2_medium != UNKNOWN_MEDIUM) {
LOG(INFO) << "P2pClusterPcpHandler::StartDiscoveryImpl: Ble v2 added";
mediums_started_successfully.push_back(ble_v2_medium);
}
std::unique_ptr<ConnectionsLog::OperationResultWithMedium>
operation_result_with_medium = GetOperationResultWithMediumByResultCode(
client, BLE,
@@ -1420,12 +1184,7 @@ Status P2pClusterPcpHandler::StopDiscoveryImpl(ClientProxy* client) {
<< " because it is not in discovery.";
}
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
ble_v2_medium_.StopScanning(client->GetDiscoveryServiceId());
} else {
ble_medium_.StopScanning(client->GetDiscoveryServiceId());
}
ble_v2_medium_.StopScanning(client->GetDiscoveryServiceId());
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
@@ -1486,20 +1245,11 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::ConnectImpl(
break;
}
case BLE: {
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleV2)) {
auto* ble_v2_endpoint = down_cast<BleV2Endpoint*>(endpoint);
if (ble_v2_endpoint) {
return BleV2ConnectImpl(client, ble_v2_endpoint);
}
} else {
auto* ble_endpoint = down_cast<BleEndpoint*>(endpoint);
if (ble_endpoint) {
return BleConnectImpl(client, ble_endpoint);
}
auto* ble_v2_endpoint = down_cast<BleV2Endpoint*>(endpoint);
if (ble_v2_endpoint) {
return BleV2ConnectImpl(client, ble_v2_endpoint);
}
break;
}
case WIFI_LAN: {
@@ -1561,64 +1311,45 @@ P2pClusterPcpHandler::StartListeningForIncomingConnectionsImpl(
: OperationResultCode::DETAIL_SUCCESS);
operation_result_with_mediums.push_back(*operation_result_with_medium);
}
// ble
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
// ble_v2
// TODO(mingshiouwu): Add unit test for ble_l2cap flow
bool accepting_ble_connections_success = false;
if (options.enable_ble_listening &&
NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleL2cap) &&
!ble_v2_medium_.IsAcceptingL2capConnections(std::string(service_id))) {
if (!ble_v2_medium_.StartAcceptingL2capConnections(
std::string(service_id),
absl::bind_front(
&P2pClusterPcpHandler::BleL2capConnectionAcceptedHandler,
this, client_proxy, local_endpoint_id,
options.listening_endpoint_type))) {
LOG(WARNING) << "Failed to start listening for incoming L2CAP "
"connections on ble_v2";
} else {
accepting_ble_connections_success = true;
}
}
if (options.enable_ble_listening &&
!ble_v2_medium_.IsAcceptingConnections(std::string(service_id))) {
if (!ble_v2_medium_.StartAcceptingConnections(
std::string(service_id),
absl::bind_front(
&P2pClusterPcpHandler::BleV2ConnectionAcceptedHandler, this,
client_proxy, local_endpoint_id,
options.listening_endpoint_type))) {
LOG(WARNING)
<< "Failed to start listening for incoming connections on ble_v2";
} else {
accepting_ble_connections_success = true;
}
}
if (accepting_ble_connections_success) {
started_mediums.push_back(BLE);
}
} else {
// ble v1
if (options.enable_ble_listening &&
!ble_medium_.IsAcceptingConnections(std::string(service_id))) {
if (!ble_medium_.StartAcceptingConnections(
std::string(service_id),
absl::bind_front(
&P2pClusterPcpHandler::BleConnectionAcceptedHandler, this,
client_proxy, local_endpoint_id,
options.listening_endpoint_type))) {
LOG(WARNING)
<< "Failed to start listening for incoming connections on ble";
} else {
started_mediums.push_back(BLE);
}
// ble
// TODO(mingshiouwu): Add unit test for ble_l2cap flow
bool accepting_ble_connections_success = false;
if (options.enable_ble_listening &&
NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleL2cap) &&
!ble_v2_medium_.IsAcceptingL2capConnections(std::string(service_id))) {
if (!ble_v2_medium_.StartAcceptingL2capConnections(
std::string(service_id),
absl::bind_front(
&P2pClusterPcpHandler::BleL2capConnectionAcceptedHandler, this,
client_proxy, local_endpoint_id,
options.listening_endpoint_type))) {
LOG(WARNING) << "Failed to start listening for incoming L2CAP "
"connections on ble_v2";
} else {
accepting_ble_connections_success = true;
}
}
if (options.enable_ble_listening &&
!ble_v2_medium_.IsAcceptingConnections(std::string(service_id))) {
if (!ble_v2_medium_.StartAcceptingConnections(
std::string(service_id),
absl::bind_front(
&P2pClusterPcpHandler::BleV2ConnectionAcceptedHandler, this,
client_proxy, local_endpoint_id,
options.listening_endpoint_type))) {
LOG(WARNING)
<< "Failed to start listening for incoming connections on ble_v2";
} else {
accepting_ble_connections_success = true;
}
}
if (accepting_ble_connections_success) {
started_mediums.push_back(BLE);
}
// wifi lan
if (options.enable_wlan_listening &&
!wifi_lan_medium_.IsAcceptingConnections(std::string(service_id))) {
@@ -1677,23 +1408,13 @@ void P2pClusterPcpHandler::StopListeningForIncomingConnectionsImpl(
<< "Unable to stop bluetooth medium from accepting connections.";
}
}
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
if (ble_v2_medium_.IsAcceptingConnections(
if (ble_v2_medium_.IsAcceptingConnections(
client->GetListeningForIncomingConnectionsServiceId())) {
if (!ble_v2_medium_.StopAcceptingConnections(
client->GetListeningForIncomingConnectionsServiceId())) {
if (!ble_v2_medium_.StopAcceptingConnections(
client->GetListeningForIncomingConnectionsServiceId())) {
LOG(WARNING)
<< "Unable to stop ble_v2 medium from accepting connections.";
}
}
} else {
if (ble_medium_.IsAcceptingConnections(
client->GetListeningForIncomingConnectionsServiceId())) {
if (!ble_medium_.StopAcceptingConnections(
client->GetListeningForIncomingConnectionsServiceId())) {
LOG(WARNING) << "Unable to stop ble medium from accepting connections.";
}
LOG(WARNING)
<< "Unable to stop ble_v2 medium from accepting connections.";
}
}
}
@@ -1708,14 +1429,8 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl(
// ble
if (NeedsToTurnOffAdvertisingMedium(BLE, old_options, advertising_options) ||
needs_restart) {
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
mediums_->GetBleV2().StopAdvertising(std::string(service_id));
mediums_->GetBleV2().StopAcceptingConnections(std::string(service_id));
} else {
mediums_->GetBle().StopAdvertising(std::string(service_id));
mediums_->GetBle().StopAcceptingConnections(std::string(service_id));
}
mediums_->GetBleV2().StopAdvertising(std::string(service_id));
mediums_->GetBleV2().StopAcceptingConnections(std::string(service_id));
}
// awdl
if (NearbyFlags::GetInstance().GetBoolFlag(
@@ -1741,16 +1456,8 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl(
mediums_->GetBluetoothClassic().TurnOffDiscoverability();
mediums_->GetBluetoothClassic().StopAcceptingConnections(
std::string(service_id));
// TODO(hais): update this after ble_v2 refactor.
if (api::ImplementationPlatform::GetCurrentOS() == api::OSName::kChromeOS) {
mediums_->GetBle().StopLegacyAdvertising(std::string(service_id));
} else if ((api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kChromeOS ||
api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kLinux) &&
NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleV2)) {
if (api::ImplementationPlatform::GetCurrentOS() == api::OSName::kChromeOS ||
api::ImplementationPlatform::GetCurrentOS() == api::OSName::kLinux) {
mediums_->GetBleV2().StopLegacyAdvertising(
client->GetAdvertisingServiceId());
}
@@ -1780,29 +1487,16 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl(
operation_result_with_mediums.push_back(*operation_result_with_medium);
} else {
ErrorOr<Medium> ble_result = {Error(OperationResultCode::DETAIL_UNKNOWN)};
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleV2)) {
ble_result = StartBleV2Advertising(
client, std::string(service_id), std::string(local_endpoint_id),
ByteArray(std::string(local_endpoint_info)), advertising_options,
web_rtc_state);
if (ble_result.has_value() && ble_result.value() != UNKNOWN_MEDIUM) {
restarted_mediums.push_back(BLE);
} else {
status = {Status::kBleError};
}
ble_result = StartBleV2Advertising(
client, std::string(service_id), std::string(local_endpoint_id),
ByteArray(std::string(local_endpoint_info)), advertising_options,
web_rtc_state);
if (ble_result.has_value() && ble_result.value() != UNKNOWN_MEDIUM) {
restarted_mediums.push_back(BLE);
} else {
ble_result = StartBleAdvertising(
client, std::string(service_id), std::string(local_endpoint_id),
ByteArray(std::string(local_endpoint_info)), advertising_options,
web_rtc_state);
if (ble_result.has_value() && ble_result.value() != UNKNOWN_MEDIUM) {
restarted_mediums.push_back(BLE);
} else {
status = {Status::kBleError};
}
status = {Status::kBleError};
}
std::unique_ptr<ConnectionsLog::OperationResultWithMedium>
operation_result_with_medium =
GetOperationResultWithMediumByResultCode(
@@ -1893,34 +1587,10 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl(
ByteArray(std::string(local_endpoint_info)), web_rtc_state);
if (bluetooth_result.has_value() &&
bluetooth_result.value() != UNKNOWN_MEDIUM) {
// TODO(hais): update this after ble_v2 refactor.
if (api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kChromeOS &&
!NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleV2)) {
if (ble_medium_.StartLegacyAdvertising(
std::string(service_id), std::string(local_endpoint_id),
advertising_options.fast_advertisement_service_uuid)) {
LOG(INFO) << "P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl: "
"Ble legacy started advertising";
LOG(INFO) << "P2pClusterPcpHandler::"
"UpdateAdvertisingOptionsImpl: BT added";
restarted_mediums.push_back(BLUETOOTH);
} else {
LOG(WARNING)
<< "P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl: BLE "
"legacy failed, revert BTC";
bluetooth_medium_.TurnOffDiscoverability();
bluetooth_medium_.StopAcceptingConnections(std::string(service_id));
}
} else if ((api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kChromeOS ||
api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kLinux) &&
NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleV2)) {
api::OSName::kChromeOS ||
api::ImplementationPlatform::GetCurrentOS() ==
api::OSName::kLinux) {
if (ble_v2_medium_.StartLegacyAdvertising(
std::string(service_id), std::string(local_endpoint_id),
advertising_options.fast_advertisement_service_uuid)) {
@@ -1937,10 +1607,10 @@ P2pClusterPcpHandler::UpdateAdvertisingOptionsImpl(
bluetooth_medium_.TurnOffDiscoverability();
bluetooth_medium_.StopAcceptingConnections(std::string(service_id));
}
} else {
restarted_mediums.push_back(BLUETOOTH);
}
std::unique_ptr<ConnectionsLog::OperationResultWithMedium>
operation_result_with_medium =
GetOperationResultWithMediumByResultCode(
@@ -1984,12 +1654,7 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl(
bool needs_restart = old_options.low_power != discovery_options.low_power;
// ble
if (NeedsToTurnOffDiscoveryMedium(BLE, old_options, discovery_options)) {
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
ble_v2_medium_.StopScanning(std::string(service_id));
} else {
ble_medium_.StopScanning(std::string(service_id));
}
ble_v2_medium_.StopScanning(std::string(service_id));
StartEndpointLostByMediumAlarms(client, BLE);
}
// bt classic
@@ -2035,28 +1700,15 @@ P2pClusterPcpHandler::UpdateDiscoveryOptionsImpl(
operation_result_with_mediums.push_back(*operation_result_with_medium);
} else {
ErrorOr<Medium> ble_result = {Error(OperationResultCode::DETAIL_UNKNOWN)};
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::
kEnableBleV2)) {
ble_result = StartBleV2Scanning(client, std::string(service_id),
discovery_options);
if (ble_result.has_value()) {
restarted_mediums.push_back(BLE);
} else {
LOG(WARNING) << "UpdateDiscoveryOptionsImpl: unable to "
"restart blev2 scanning";
}
ble_result = StartBleV2Scanning(client, std::string(service_id),
discovery_options);
if (ble_result.has_value()) {
restarted_mediums.push_back(BLE);
} else {
ble_result =
StartBleScanning(client, std::string(service_id),
discovery_options.fast_advertisement_service_uuid);
if (ble_result.has_value()) {
restarted_mediums.push_back(BLE);
} else {
LOG(WARNING)
<< "UpdateDiscoveryOptionsImpl: unable to restart ble scanning";
}
LOG(WARNING) << "UpdateDiscoveryOptionsImpl: unable to "
"restart blev2 scanning";
}
std::unique_ptr<ConnectionsLog::OperationResultWithMedium>
operation_result_with_medium =
GetOperationResultWithMediumByResultCode(
@@ -2436,257 +2088,6 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BluetoothConnectImpl(
.endpoint_channel = std::move(channel)};
}
void P2pClusterPcpHandler::BleConnectionAcceptedHandler(
ClientProxy* client, absl::string_view local_endpoint_info,
NearbyDevice::Type device_type, BleSocket socket,
const std::string& service_id) {
if (!socket.IsValid()) {
LOG(WARNING) << "Invalid socket in accept callback("
<< absl::BytesToHexString(local_endpoint_info)
<< "), client=" << client->GetClientId();
return;
}
RunOnPcpHandlerThread(
"p2p-ble-on-incoming-connection",
[this, client, service_id, socket = std::move(socket), device_type]()
RUN_ON_PCP_HANDLER_THREAD() mutable {
std::string remote_peripheral_name =
socket.GetRemotePeripheral().GetName();
auto channel = std::make_unique<BleEndpointChannel>(
service_id,
/*channel_name=*/remote_peripheral_name, socket);
ByteArray remote_peripheral_info =
socket.GetRemotePeripheral().GetAdvertisementBytes(service_id);
OnIncomingConnection(client, remote_peripheral_info,
std::move(channel), BLE, device_type);
});
}
ErrorOr<Medium> P2pClusterPcpHandler::StartBleAdvertising(
ClientProxy* client, const std::string& service_id,
const std::string& local_endpoint_id, const ByteArray& local_endpoint_info,
const AdvertisingOptions& advertising_options, WebRtcState web_rtc_state) {
bool fast_advertisement =
!advertising_options.fast_advertisement_service_uuid.empty();
PowerLevel power_level = advertising_options.low_power
? PowerLevel::kLowPower
: PowerLevel::kHighPower;
// Start listening for connections before advertising in case a connection
// request comes in very quickly. BLE allows connecting over BLE itself, as
// well as advertising the Bluetooth MAC address to allow connecting over
// Bluetooth Classic.
LOG(INFO) << "P2pClusterPcpHandler::StartBleAdvertising: service_id="
<< service_id << " : start";
if (!ble_medium_.IsAcceptingConnections(service_id)) {
// TODO(b/380411884): Remove this check since we shouldn't enable radio by
// NC.
if (!bluetooth_radio_.Enable()) {
LOG(WARNING)
<< "In StartBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< "), client=" << client->GetClientId()
<< " failed to start accepting for incoming BLE connections to "
"service_id="
<< service_id;
return {Error(OperationResultCode::DEVICE_STATE_RADIO_ENABLING_FAILURE)};
}
ErrorOr<bool> accept_result = ble_medium_.StartAcceptingConnections(
service_id,
absl::bind_front(&P2pClusterPcpHandler::BleConnectionAcceptedHandler,
this, client, local_endpoint_info.AsStringView(),
NearbyDevice::Type::kConnectionsDevice));
if (!accept_result.has_value()) {
LOG(WARNING)
<< "In StartBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< "), client=" << client->GetClientId()
<< " failed to start accepting for incoming BLE connections to "
"service_id="
<< service_id;
return {Error(accept_result.error().operation_result_code().value())};
}
LOG(INFO)
<< "In StartBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< "), client=" << client->GetClientId()
<< " started accepting for incoming BLE connections to service_id="
<< service_id;
}
if (ShouldAdvertiseBluetoothMacOverBle(power_level) ||
ShouldAcceptBluetoothConnections(advertising_options)) {
if (bluetooth_medium_.IsAvailable() &&
!bluetooth_medium_.IsAcceptingConnections(service_id)) {
// TODO(b/380411884): Remove this check since we shouldn't enable radio by
// NC.
if (!bluetooth_radio_.Enable()) {
LOG(WARNING)
<< "In BT StartBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< "), client=" << client->GetClientId()
<< " failed to start accepting for incoming BLE connections to "
"service_id="
<< service_id;
return {
Error(OperationResultCode::DEVICE_STATE_RADIO_ENABLING_FAILURE)};
}
ErrorOr<bool> accept_result = bluetooth_medium_.StartAcceptingConnections(
service_id,
absl::bind_front(
&P2pClusterPcpHandler::BluetoothConnectionAcceptedHandler, this,
client, local_endpoint_info.AsStringView(),
NearbyDevice::Type::kConnectionsDevice));
if (!accept_result.has_value()) {
LOG(WARNING)
<< "In BT StartBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< "), client=" << client->GetClientId()
<< " failed to start accepting for incoming BLE connections to "
"service_id="
<< service_id;
ble_medium_.StopAcceptingConnections(service_id);
return {Error(accept_result.error().operation_result_code().value())};
}
LOG(INFO)
<< "In BT StartBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< "), client=" << client->GetClientId()
<< " started accepting for incoming BLE connections to service_id="
<< service_id;
}
}
LOG(INFO) << "In StartBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< "), client=" << client->GetClientId()
<< " start to generate BleAdvertisement with service_id="
<< service_id << ", local endpoint_id=" << local_endpoint_id;
// Generate a BleAdvertisement. If a fast advertisement service UUID was
// provided, create a fast BleAdvertisement.
ByteArray advertisement_bytes;
// TODO(b/169550050): Implement UWBAddress.
if (fast_advertisement) {
advertisement_bytes = ByteArray(
BleAdvertisement(kBleAdvertisementVersion, GetPcp(), local_endpoint_id,
local_endpoint_info, ByteArray{}));
} else {
const ByteArray service_id_hash =
GenerateHash(service_id, BleAdvertisement::kServiceIdHashLength);
MacAddress bluetooth_mac_address;
if (bluetooth_medium_.IsAvailable() &&
ShouldAdvertiseBluetoothMacOverBle(power_level))
bluetooth_mac_address = bluetooth_medium_.GetAddress();
advertisement_bytes = ByteArray(
BleAdvertisement(kBleAdvertisementVersion, GetPcp(), service_id_hash,
local_endpoint_id, local_endpoint_info,
bluetooth_mac_address, ByteArray{}, web_rtc_state));
}
if (advertisement_bytes.Empty()) {
LOG(WARNING) << "In StartBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< "), client=" << client->GetClientId()
<< " failed to create an advertisement.";
ble_medium_.StopAcceptingConnections(service_id);
return {Error(OperationResultCode::NEARBY_BLE_ADVERTISE_TO_BYTES_FAILURE)};
}
LOG(INFO) << "In StartBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< "), client=" << client->GetClientId()
<< " generated BleAdvertisement with service_id=" << service_id
<< ", bytes: "
<< absl::BytesToHexString(advertisement_bytes.data());
ErrorOr<bool> ble_result = ble_medium_.StartAdvertising(
service_id, advertisement_bytes,
advertising_options.fast_advertisement_service_uuid);
if (ble_result.has_error()) {
LOG(WARNING) << "In StartBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< "), client=" << client->GetClientId()
<< " couldn't start BLE Advertising with BleAdvertisement "
<< absl::BytesToHexString(advertisement_bytes.data());
ble_medium_.StopAcceptingConnections(service_id);
return {Error(ble_result.error().operation_result_code().value())};
}
LOG(INFO) << "In startBleAdvertising("
<< absl::BytesToHexString(local_endpoint_info.data())
<< ", fast_advertisement: " << fast_advertisement
<< "), client=" << client->GetClientId()
<< " started BLE Advertising with BleAdvertisement "
<< absl::BytesToHexString(advertisement_bytes.data());
return {BLE};
}
ErrorOr<Medium> P2pClusterPcpHandler::StartBleScanning(
ClientProxy* client, const std::string& service_id,
const std::string& fast_advertisement_service_uuid) {
// TODO(b/380411884): Remove this check since we shouldn't enable radio by NC.
if (!bluetooth_radio_.Enable()) {
LOG(INFO) << "In StartBleScanning(), client=" << client->GetClientId()
<< " couldn't start scanning on BLE for service_id="
<< service_id;
return {Error(OperationResultCode::DEVICE_STATE_RADIO_ENABLING_FAILURE)};
}
ErrorOr<bool> result = ble_medium_.StartScanning(
service_id, fast_advertisement_service_uuid,
{
.peripheral_discovered_cb = absl::bind_front(
&P2pClusterPcpHandler::BlePeripheralDiscoveredHandler, this,
client),
.peripheral_lost_cb = absl::bind_front(
&P2pClusterPcpHandler::BlePeripheralLostHandler, this, client),
});
if (!result.has_error()) {
LOG(INFO) << "In StartBleScanning(), client=" << client->GetClientId()
<< " started scanning for BLE advertisements for service_id="
<< service_id;
return {BLE};
} else {
LOG(INFO) << "In StartBleScanning(), client=" << client->GetClientId()
<< " couldn't start scanning on BLE for service_id="
<< service_id;
return {Error(result.error().operation_result_code().value())};
}
}
BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BleConnectImpl(
ClientProxy* client, BleEndpoint* endpoint) {
VLOG(1) << "Client " << client->GetClientId()
<< " is attempting to connect to endpoint(id="
<< endpoint->endpoint_id << ") over BLE.";
BlePeripheral& peripheral = endpoint->ble_peripheral;
ErrorOr<BleSocket> ble_socket_result =
ble_medium_.Connect(peripheral, endpoint->service_id,
client->GetCancellationFlag(endpoint->endpoint_id));
if (ble_socket_result.has_error()) {
LOG(ERROR) << "In BleConnectImpl(), failed to connect to BLE device "
<< peripheral.GetName()
<< " for endpoint(id=" << endpoint->endpoint_id << ").";
return BasePcpHandler::ConnectImplResult{
.status = {Status::kBleError},
.operation_result_code =
ble_socket_result.error().operation_result_code().value(),
};
}
auto channel = std::make_unique<BleEndpointChannel>(
endpoint->service_id, /*channel_name=*/endpoint->endpoint_id,
ble_socket_result.value());
return BasePcpHandler::ConnectImplResult{
.medium = BLE,
.status = {Status::kSuccess},
.operation_result_code = OperationResultCode::DETAIL_SUCCESS,
.endpoint_channel = std::move(channel),
};
}
void P2pClusterPcpHandler::BleV2ConnectionAcceptedHandler(
ClientProxy* client, absl::string_view local_endpoint_info,
NearbyDevice::Type device_type, BleV2Socket socket,
@@ -33,7 +33,6 @@
#include "connections/implementation/endpoint_manager.h"
#include "connections/implementation/injected_bluetooth_device_store.h"
#include "connections/implementation/mediums/awdl.h"
#include "connections/implementation/mediums/ble.h"
#include "connections/implementation/mediums/ble_v2.h"
#include "connections/implementation/mediums/bluetooth_classic.h"
#include "connections/implementation/mediums/bluetooth_radio.h"
@@ -47,7 +46,6 @@
#include "connections/status.h"
#include "connections/v3/connection_listening_options.h"
#include "internal/interop/device.h"
#include "internal/platform/ble.h"
#include "internal/platform/ble_v2.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/bluetooth_classic.h"
@@ -164,7 +162,6 @@ class P2pClusterPcpHandler : public BasePcpHandler {
using BluetoothDiscoveredDeviceCallback =
BluetoothClassic::DiscoveredDeviceCallback;
using BleDiscoveredPeripheralCallback = Ble::DiscoveredPeripheralCallback;
using BleV2DiscoveredPeripheralCallback = BleV2::DiscoveredPeripheralCallback;
using WifiLanDiscoveredServiceCallback = WifiLan::DiscoveredServiceCallback;
using AwdlDiscoveredServiceCallback = Awdl::DiscoveredServiceCallback;
@@ -217,32 +214,6 @@ class P2pClusterPcpHandler : public BasePcpHandler {
BasePcpHandler::ConnectImplResult BluetoothConnectImpl(
ClientProxy* client, BluetoothEndpoint* endpoint);
// Ble
bool IsRecognizedBleEndpoint(const std::string& service_id,
const BleAdvertisement& advertisement) const;
void BlePeripheralDiscoveredHandler(ClientProxy* client,
BlePeripheral& peripheral,
const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement);
void BlePeripheralLostHandler(ClientProxy* client, BlePeripheral& peripheral,
const std::string& service_id);
void BleConnectionAcceptedHandler(ClientProxy* client,
absl::string_view local_endpoint_info,
NearbyDevice::Type device_type,
BleSocket socket,
const std::string& service_id);
ErrorOr<location::nearby::proto::connections::Medium> StartBleAdvertising(
ClientProxy* client, const std::string& service_id,
const std::string& local_endpoint_id,
const ByteArray& local_endpoint_info,
const AdvertisingOptions& advertising_options, WebRtcState web_rtc_state);
ErrorOr<location::nearby::proto::connections::Medium> StartBleScanning(
ClientProxy* client, const std::string& service_id,
const std::string& fast_advertisement_service_uuid);
BasePcpHandler::ConnectImplResult BleConnectImpl(ClientProxy* client,
BleEndpoint* endpoint);
// BleV2
bool IsRecognizedBleV2Endpoint(absl::string_view service_id,
const BleAdvertisement& advertisement) const;
@@ -330,7 +301,6 @@ class P2pClusterPcpHandler : public BasePcpHandler {
Awdl& awdl_medium_;
BluetoothRadio& bluetooth_radio_;
BluetoothClassic& bluetooth_medium_;
Ble& ble_medium_;
BleV2& ble_v2_medium_;
WifiLan& wifi_lan_medium_;
WifiHotspot& wifi_hotspot_medium_;
@@ -92,7 +92,6 @@ class P2pClusterPcpHandlerTest : public testing::Test {
config_package_nearby::nearby_connections_feature::kEnableAwdl, true);
SetBleExtendedAdvertisementsAvailable(true);
SetDisableBluetoothClassicScanning(true);
SetBleV2Enabled(true);
}
void SetBleExtendedAdvertisementsAvailable(bool available) {
@@ -106,12 +105,6 @@ class P2pClusterPcpHandlerTest : public testing::Test {
disable);
}
void SetBleV2Enabled(bool enabled) {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableBleV2,
enabled);
}
AdvertisingOptions GetBluetoothOnlyAdvertisingOptions() {
return AdvertisingOptions{
{Strategy::kP2pCluster,
@@ -247,23 +240,17 @@ TEST_F(P2pClusterPcpHandlerTest,
env_.Stop();
}
// Combines the bool `kEnableBleV2` as param testing but should revert it back
// if ble_v2 is done and ble will be replaced by ble_v2.
class P2pClusterPcpHandlerTestWithParam
: public testing::TestWithParam<
/*mediums=*/std::tuple<BooleanMediumSelector, /*ble_v2_enabled=*/bool,
/*mediums=*/std::tuple<BooleanMediumSelector,
/*disable_bluetooth_scanning*/ bool>> {
protected:
void SetUp() override {
LOG(INFO) << "SetUp: begin";
env_.SetBleExtendedAdvertisementsAvailable(false);
bool ble_v2_enabled = std::get<1>(GetParam());
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableBleV2,
ble_v2_enabled);
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableAwdl, true);
bool is_disable_bluetooth_scanning = std::get<2>(GetParam());
bool is_disable_bluetooth_scanning = std::get<1>(GetParam());
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::
kDisableBluetoothClassicScanning,
@@ -285,7 +272,6 @@ class P2pClusterPcpHandlerTestWithParam
if (advertising_options_.allowed.awdl) {
LOG(INFO) << "SetUp: Awdl enabled";
}
LOG(INFO) << "SetUp: ble v2 enabled: " << ble_v2_enabled;
LOG(INFO) << "SetUp: is_disable_bluetooth_scanning: "
<< is_disable_bluetooth_scanning;
LOG(INFO) << "SetUp: end";
@@ -374,14 +360,11 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, AdvertiseForLegacyDeviceWithBt) {
{.endpoint_info = ByteArray{endpoint_name}}),
Status{Status::kSuccess});
// advertising for legacy device depends on both BT and BLE V2 enabled.
if (std::get<0>(GetParam()).bluetooth && std::get<1>(GetParam())) {
if (std::get<0>(GetParam()).bluetooth) {
EXPECT_TRUE(mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
} else {
EXPECT_FALSE(
mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
handler_a.StopAdvertising(&client_a_);
if (std::get<0>(GetParam()).bluetooth && std::get<1>(GetParam())) {
if (std::get<0>(GetParam()).bluetooth) {
EXPECT_FALSE(
mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
@@ -389,11 +372,6 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, AdvertiseForLegacyDeviceWithBt) {
}
TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateAdvertisingOptions) {
bool ble_v2_enabled = std::get<1>(GetParam());
if (!ble_v2_enabled) {
// Just don't run the test if ble_v2 is disabled.
return;
}
env_.Start();
std::string endpoint_name{"endpoint_name"};
Mediums mediums_a;
@@ -417,7 +395,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateAdvertisingOptions) {
mediums_a.GetBleV2().StopAdvertising(service_id_);
ASSERT_FALSE(mediums_a.GetBleV2().IsAdvertising(service_id_));
BooleanMediumSelector enabled = advertising_options_.allowed;
if (ble_v2_enabled && enabled.bluetooth) {
if (enabled.bluetooth) {
EXPECT_FALSE(
mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
@@ -433,7 +411,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateAdvertisingOptions) {
mediums_a.GetBluetoothClassic().IsAcceptingConnections(service_id_));
EXPECT_EQ(enabled.bluetooth,
mediums_a.GetBluetoothClassic().TurnOffDiscoverability());
if (ble_v2_enabled && enabled.bluetooth) {
if (enabled.bluetooth) {
EXPECT_TRUE(mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
// Turn discoverability back on
@@ -450,15 +428,11 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateAdvertisingOptions) {
EXPECT_EQ(
handler_a.UpdateAdvertisingOptions(&client_a_, service_id_, new_options),
Status{Status::kSuccess});
if (ble_v2_enabled) {
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsAdvertising(service_id_));
// Low power won't restart BT, nor BLE advertising for legacy device.
if (enabled.bluetooth) {
EXPECT_FALSE(
mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
} else {
EXPECT_EQ(enabled.ble, mediums_a.GetBle().IsAdvertising(service_id_));
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsAdvertising(service_id_));
// Low power won't restart BT, nor BLE advertising for legacy device.
if (enabled.bluetooth) {
EXPECT_FALSE(
mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
EXPECT_FALSE(mediums_a.GetWifiLan().IsAdvertising(service_id_));
EXPECT_FALSE(mediums_a.GetBluetoothClassic().TurnOffDiscoverability());
@@ -470,11 +444,6 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateAdvertisingOptions) {
TEST_P(P2pClusterPcpHandlerTestWithParam,
CanUpdateAdvertisingOptionsNoLowPower) {
bool ble_v2_enabled = std::get<1>(GetParam());
if (!ble_v2_enabled) {
// Just don't run the test if ble_v2 is disabled.
return;
}
env_.Start();
std::string endpoint_name{"endpoint_name"};
Mediums mediums_a;
@@ -508,7 +477,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam,
true, // low_power
false, // enable_bluetooth_listening
};
if (ble_v2_enabled && enabled.bluetooth) {
if (enabled.bluetooth) {
EXPECT_FALSE(
mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
@@ -522,7 +491,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam,
EXPECT_EQ(
enabled.bluetooth,
mediums_a.GetBluetoothClassic().IsAcceptingConnections(service_id_));
if (ble_v2_enabled && enabled.bluetooth) {
if (enabled.bluetooth) {
EXPECT_TRUE(mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
EXPECT_EQ(enabled.bluetooth,
@@ -530,14 +499,9 @@ TEST_P(P2pClusterPcpHandlerTestWithParam,
EXPECT_EQ(handler_a.UpdateAdvertisingOptions(&client_a_, service_id_,
advertising_options_),
Status{Status::kSuccess});
if (ble_v2_enabled) {
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsAdvertising(service_id_));
if (enabled.bluetooth) {
EXPECT_TRUE(
mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
} else {
EXPECT_EQ(enabled.ble, mediums_a.GetBle().IsAdvertising(service_id_));
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsAdvertising(service_id_));
if (enabled.bluetooth) {
EXPECT_TRUE(mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
EXPECT_EQ(enabled.wifi_lan,
mediums_a.GetWifiLan().IsAdvertising(service_id_));
@@ -547,7 +511,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam,
enabled.bluetooth || enabled.ble,
mediums_a.GetBluetoothClassic().IsAcceptingConnections(service_id_));
handler_a.StopAdvertising(&client_a_);
if (ble_v2_enabled && enabled.bluetooth) {
if (enabled.bluetooth) {
EXPECT_FALSE(
mediums_a.GetBleV2().IsAdvertisingForLegacyDevice(service_id_));
}
@@ -626,11 +590,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanDiscoverLegacy) {
}),
Status{Status::kSuccess});
// advertising for legacy device depends on both BT and BLE V2 enabled.
// if (std::get<0>(GetParam()).bluetooth && std::get<1>(GetParam())) {
EXPECT_TRUE(latch.Await(absl::Milliseconds(1000)).result());
/* } else {
EXPECT_FALSE(latch.Await(absl::Milliseconds(1000)).result());
}*/
// We discovered endpoint over one medium. Before we finish the test, we have
// to stop discovery for other mediums that may be still ongoing.
handler_b.StopDiscovery(&client_b_);
@@ -639,8 +599,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanDiscoverLegacy) {
TEST_P(P2pClusterPcpHandlerTestWithParam, PauseBluetoothClassicDiscovery) {
// Skip the case which not disable bluetooth scanning.
if (!std::get<2>(GetParam()) || !std::get<1>(GetParam()) ||
!advertising_options_.allowed.bluetooth ||
if (!std::get<1>(GetParam()) || !advertising_options_.allowed.bluetooth ||
!advertising_options_.allowed.ble) {
return;
}
@@ -669,8 +628,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, PauseBluetoothClassicDiscovery) {
TEST_P(P2pClusterPcpHandlerTestWithParam, ResumeBluetoothClassicDiscovery) {
// Skip the case which not disable bluetooth scanning.
if (!std::get<2>(GetParam()) || !std::get<1>(GetParam()) ||
!advertising_options_.allowed.bluetooth ||
if (!std::get<1>(GetParam()) || !advertising_options_.allowed.bluetooth ||
!advertising_options_.allowed.ble) {
return;
}
@@ -825,12 +783,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateDiscoveryOptions) {
handler_a.StartDiscovery(&client_a_, service_id_, discovery_options_, {}),
Status{Status::kSuccess});
BooleanMediumSelector enabled = std::get<0>(GetParam());
bool ble_v2_enabled = std::get<1>(GetParam());
if (ble_v2_enabled) {
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
} else {
EXPECT_EQ(enabled.ble, mediums_a.GetBle().IsScanning(service_id_));
}
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
EXPECT_EQ(enabled.wifi_lan,
mediums_a.GetWifiLan().IsDiscovering(service_id_));
DiscoveryOptions new_options{
@@ -847,11 +800,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateDiscoveryOptions) {
EXPECT_EQ(
handler_a.UpdateDiscoveryOptions(&client_a_, service_id_, new_options),
Status{Status::kSuccess});
if (ble_v2_enabled) {
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
} else {
EXPECT_EQ(enabled.ble, mediums_a.GetBle().IsScanning(service_id_));
}
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
EXPECT_FALSE(mediums_a.GetWifiLan().IsDiscovering(service_id_));
handler_a.StopDiscovery(&client_a_);
env_.Stop();
@@ -876,13 +825,8 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateDiscoveryOptionsNoLowPower) {
ASSERT_FALSE(mediums_a.GetBluetoothClassic().TurnOffDiscoverability());
mediums_a.GetWifiLan().StopDiscovery(service_id_);
ASSERT_FALSE(mediums_a.GetWifiLan().IsDiscovering(service_id_));
if (std::get<1>(GetParam())) {
mediums_a.GetBleV2().StopScanning(service_id_);
ASSERT_FALSE(mediums_a.GetBleV2().IsScanning(service_id_));
} else {
mediums_a.GetBle().StopScanning(service_id_);
ASSERT_FALSE(mediums_a.GetBle().IsScanning(service_id_));
}
mediums_a.GetBleV2().StopScanning(service_id_);
ASSERT_FALSE(mediums_a.GetBleV2().IsScanning(service_id_));
DiscoveryOptions old_options = discovery_options_;
old_options.low_power = true;
old_options.allowed = old_enabled;
@@ -891,11 +835,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateDiscoveryOptionsNoLowPower) {
// Start discovery
EXPECT_EQ(handler_a.StartDiscovery(&client_a_, service_id_, old_options, {}),
Status{Status::kSuccess});
if (std::get<1>(GetParam())) {
EXPECT_EQ(old_enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
} else {
EXPECT_EQ(old_enabled.ble, mediums_a.GetBle().IsScanning(service_id_));
}
EXPECT_EQ(old_enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
EXPECT_EQ(old_enabled.wifi_lan,
mediums_a.GetWifiLan().IsDiscovering(service_id_));
EXPECT_EQ(old_enabled.bluetooth,
@@ -906,11 +846,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam, CanUpdateDiscoveryOptionsNoLowPower) {
handler_a.UpdateDiscoveryOptions(&client_a_, service_id_, new_options)
.Ok());
LOG(INFO) << "updated discovery options";
if (std::get<1>(GetParam())) {
EXPECT_EQ(new_enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
} else {
EXPECT_EQ(new_enabled.ble, mediums_a.GetBle().IsScanning(service_id_));
}
EXPECT_EQ(new_enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
EXPECT_EQ(new_enabled.wifi_lan,
mediums_a.GetWifiLan().IsDiscovering(service_id_));
EXPECT_EQ(new_enabled.bluetooth,
@@ -935,22 +871,14 @@ TEST_P(P2pClusterPcpHandlerTestWithParam,
ASSERT_FALSE(mediums_a.GetBluetoothClassic().TurnOffDiscoverability());
mediums_a.GetWifiLan().StopDiscovery(service_id_);
ASSERT_FALSE(mediums_a.GetWifiLan().IsDiscovering(service_id_));
if (std::get<1>(GetParam())) {
mediums_a.GetBleV2().StopScanning(service_id_);
ASSERT_FALSE(mediums_a.GetBleV2().IsScanning(service_id_));
} else {
mediums_a.GetBle().StopScanning(service_id_);
ASSERT_FALSE(mediums_a.GetBle().IsScanning(service_id_));
}
mediums_a.GetBleV2().StopScanning(service_id_);
ASSERT_FALSE(mediums_a.GetBleV2().IsScanning(service_id_));
// Start discovery
EXPECT_EQ(
handler_a.StartDiscovery(&client_a_, service_id_, discovery_options_, {}),
Status{Status::kSuccess});
if (std::get<1>(GetParam())) {
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
} else {
EXPECT_EQ(enabled.ble, mediums_a.GetBle().IsScanning(service_id_));
}
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
EXPECT_EQ(enabled.wifi_lan,
mediums_a.GetWifiLan().IsDiscovering(service_id_));
EXPECT_EQ(enabled.bluetooth,
@@ -960,11 +888,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam,
discovery_options_);
EXPECT_TRUE(result.Ok());
LOG(INFO) << "updated discovery options";
if (std::get<1>(GetParam())) {
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
} else {
EXPECT_EQ(enabled.ble, mediums_a.GetBle().IsScanning(service_id_));
}
EXPECT_EQ(enabled.ble, mediums_a.GetBleV2().IsScanning(service_id_));
EXPECT_EQ(enabled.wifi_lan,
mediums_a.GetWifiLan().IsDiscovering(service_id_));
// We didn't restart the medium.
@@ -1250,11 +1174,8 @@ TEST_P(P2pClusterPcpHandlerTestWithParam,
ASSERT_FALSE(
mediums_a.GetBluetoothClassic().IsAcceptingConnections(service_id_));
ASSERT_FALSE(mediums_a.GetWifiLan().IsAcceptingConnections(service_id_));
if (std::get<1>(GetParam())) {
ASSERT_FALSE(mediums_a.GetBleV2().IsAcceptingConnections(service_id_));
} else {
ASSERT_FALSE(mediums_a.GetBle().IsAcceptingConnections(service_id_));
}
ASSERT_FALSE(mediums_a.GetBleV2().IsAcceptingConnections(service_id_));
// call handler.
auto result = handler_a.StartListeningForIncomingConnections(
&client_a_, service_id_, v3_options, {});
@@ -1262,11 +1183,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam,
EXPECT_TRUE(
mediums_a.GetBluetoothClassic().IsAcceptingConnections(service_id_));
EXPECT_TRUE(mediums_a.GetWifiLan().IsAcceptingConnections(service_id_));
if (std::get<1>(GetParam())) {
EXPECT_TRUE(mediums_a.GetBleV2().IsAcceptingConnections(service_id_));
} else {
EXPECT_TRUE(mediums_a.GetBle().IsAcceptingConnections(service_id_));
}
EXPECT_TRUE(mediums_a.GetBleV2().IsAcceptingConnections(service_id_));
EXPECT_EQ(result.second.size(), 3);
ASSERT_TRUE(client_a_.IsListeningForIncomingConnections());
EXPECT_EQ(client_a_.GetListeningForIncomingConnectionsServiceId(),
@@ -1304,11 +1221,7 @@ TEST_P(P2pClusterPcpHandlerTestWithParam,
ASSERT_FALSE(
mediums_a.GetBluetoothClassic().IsAcceptingConnections(service_id_));
ASSERT_FALSE(mediums_a.GetWifiLan().IsAcceptingConnections(service_id_));
if (std::get<1>(GetParam())) {
ASSERT_FALSE(mediums_a.GetBleV2().IsAcceptingConnections(service_id_));
} else {
ASSERT_FALSE(mediums_a.GetBle().IsAcceptingConnections(service_id_));
}
ASSERT_FALSE(mediums_a.GetBleV2().IsAcceptingConnections(service_id_));
// call handler.
auto result = handler_a.StartListeningForIncomingConnections(
&client_a_, service_id_, v3_options, {});
@@ -1316,21 +1229,13 @@ TEST_P(P2pClusterPcpHandlerTestWithParam,
ASSERT_TRUE(
mediums_a.GetBluetoothClassic().IsAcceptingConnections(service_id_));
ASSERT_TRUE(mediums_a.GetWifiLan().IsAcceptingConnections(service_id_));
if (std::get<1>(GetParam())) {
ASSERT_TRUE(mediums_a.GetBleV2().IsAcceptingConnections(service_id_));
} else {
ASSERT_TRUE(mediums_a.GetBle().IsAcceptingConnections(service_id_));
}
ASSERT_TRUE(mediums_a.GetBleV2().IsAcceptingConnections(service_id_));
// stop.
handler_a.StopListeningForIncomingConnections(&client_a_);
EXPECT_FALSE(
mediums_a.GetBluetoothClassic().IsAcceptingConnections(service_id_));
EXPECT_FALSE(mediums_a.GetWifiLan().IsAcceptingConnections(service_id_));
if (std::get<1>(GetParam())) {
EXPECT_FALSE(mediums_a.GetBleV2().IsAcceptingConnections(service_id_));
} else {
EXPECT_FALSE(mediums_a.GetBle().IsAcceptingConnections(service_id_));
}
EXPECT_FALSE(mediums_a.GetBleV2().IsAcceptingConnections(service_id_));
env_.Stop();
}
@@ -1696,9 +1601,6 @@ class P2pLostHandlerTestWithParam : public testing::TestWithParam<bool> {
config_package_nearby::nearby_connections_feature::
kDisableBluetoothClassicScanning,
false);
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableBleV2,
true);
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableInstantOnLost,
GetParam());
@@ -1732,7 +1634,6 @@ class P2pLostHandlerTestWithParam : public testing::TestWithParam<bool> {
MediumEnvironment& env_{MediumEnvironment::Instance()};
};
TEST_P(P2pLostHandlerTestWithParam, CanConnectWithInstantLostEnabled) {
env_.Start();
@@ -1843,7 +1744,6 @@ TEST_P(P2pLostHandlerTestWithParam, CanConnectWithInstantLostEnabled) {
INSTANTIATE_TEST_SUITE_P(
ParametrisedPcpHandlerTest, P2pClusterPcpHandlerTestWithParam,
::testing::Combine(/*mediums=*/::testing::ValuesIn(kTestCases),
/*ble_v2_enabled=*/::testing::Bool(),
/*disable_bluetooth_scanning=*/::testing::Bool()));
INSTANTIATE_TEST_SUITE_P(ParametrisedP2pLostHandlerTest,
P2pLostHandlerTestWithParam, testing::Bool());
@@ -63,15 +63,8 @@ P2pPointToPointPcpHandler::GetConnectionMediumsByPriority() {
if (mediums_->GetBluetoothClassic().IsAvailable()) {
mediums.push_back(location::nearby::proto::connections::BLUETOOTH);
}
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
if (mediums_->GetBleV2().IsAvailable()) {
mediums.push_back(location::nearby::proto::connections::BLE);
}
} else {
if (mediums_->GetBle().IsAvailable()) {
mediums.push_back(location::nearby::proto::connections::BLE);
}
if (mediums_->GetBleV2().IsAvailable()) {
mediums.push_back(location::nearby::proto::connections::BLE);
}
return mediums;
}
@@ -55,7 +55,7 @@ constexpr BooleanMediumSelector kTestCases[] = {
.bluetooth = true,
},
BooleanMediumSelector{
.awdl = true,
.awdl = true,
},
BooleanMediumSelector{
.wifi_lan = true,
@@ -93,18 +93,13 @@ constexpr BooleanMediumSelector kTestCases[] = {
},
};
// Combines the bool `kEnableBleV2` as param testing but should revert it back
// if ble_v2 is done and ble will be replaced by ble_v2.
class P2pPointToPointPcpHandlerTest
: public testing::TestWithParam<std::tuple<BooleanMediumSelector, bool>> {
: public testing::TestWithParam<std::tuple<BooleanMediumSelector>> {
protected:
void SetUp() override {
LOG(INFO) << "SetUp: begin";
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableAwdl, true);
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableBleV2,
std::get<1>(GetParam()));
if (advertising_options_.allowed.ble) {
LOG(INFO) << "SetUp: BLE enabled";
}
@@ -138,7 +133,7 @@ class P2pPointToPointPcpHandlerTest
std::get<0>(GetParam()),
},
false, // auto_upgrade_bandwidth
true, // enforce_topology_constraints
true, // enforce_topology_constraints
};
AdvertisingOptions advertising_options_{
{
@@ -146,7 +141,7 @@ class P2pPointToPointPcpHandlerTest
std::get<0>(GetParam()),
},
false, // auto_upgrade_bandwidth
true, // enforce_topology_constraints
true, // enforce_topology_constraints
};
DiscoveryOptions discovery_options_{
{
@@ -296,8 +291,7 @@ TEST_P(P2pPointToPointPcpHandlerTest, CanConnect) {
INSTANTIATE_TEST_SUITE_P(ParametrisedPcpHandlerTest,
P2pPointToPointPcpHandlerTest,
::testing::Combine(::testing::ValuesIn(kTestCases),
::testing::Bool()));
::testing::Combine(::testing::ValuesIn(kTestCases)));
} // namespace
} // namespace connections
@@ -58,15 +58,8 @@ P2pStarPcpHandler::GetConnectionMediumsByPriority() {
if (mediums_->GetBluetoothClassic().IsAvailable()) {
mediums.push_back(location::nearby::proto::connections::BLUETOOTH);
}
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2)) {
if (mediums_->GetBleV2().IsAvailable()) {
mediums.push_back(location::nearby::proto::connections::BLE);
}
} else {
if (mediums_->GetBle().IsAvailable()) {
mediums.push_back(location::nearby::proto::connections::BLE);
}
if (mediums_->GetBleV2().IsAvailable()) {
mediums.push_back(location::nearby::proto::connections::BLE);
}
return mediums;
}
@@ -84,16 +84,11 @@ constexpr BooleanMediumSelector kTestCases[] = {
},
};
// Combines the bool `kEnableBleV2` as param testing but should revert it back
// if ble_v2 is done and ble will be replaced by ble_v2.
class P2pStarPcpHandlerTest
: public testing::TestWithParam<std::tuple<BooleanMediumSelector, bool>> {
: public testing::TestWithParam<std::tuple<BooleanMediumSelector>> {
protected:
void SetUp() override {
LOG(INFO) << "SetUp: begin";
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableBleV2,
std::get<1>(GetParam()));
if (advertising_options_.allowed.ble) {
LOG(INFO) << "SetUp: BLE enabled";
}
@@ -124,7 +119,7 @@ class P2pStarPcpHandlerTest
std::get<0>(GetParam()),
},
false, // auto_upgrade_bandwidth
true, // enforce_topology_constraints
true, // enforce_topology_constraints
};
AdvertisingOptions advertising_options_{
{
@@ -132,7 +127,7 @@ class P2pStarPcpHandlerTest
std::get<0>(GetParam()),
},
false, // auto_upgrade_bandwidth
true, // enforce_topology_constraints
true, // enforce_topology_constraints
};
DiscoveryOptions discovery_options_{
{
@@ -280,10 +275,8 @@ TEST_P(P2pStarPcpHandlerTest, CanConnect) {
env_.Stop();
}
INSTANTIATE_TEST_SUITE_P(ParametrisedPcpHandlerTest,
P2pStarPcpHandlerTest,
::testing::Combine(::testing::ValuesIn(kTestCases),
::testing::Bool()));
INSTANTIATE_TEST_SUITE_P(ParametrisedPcpHandlerTest, P2pStarPcpHandlerTest,
::testing::Combine(::testing::ValuesIn(kTestCases)));
} // namespace
} // namespace connections
@@ -98,24 +98,6 @@ ServiceControllerRouter::ServiceControllerRouter(
absl::AnyInvocable<bool()> if_hp_realtek_device)
: if_hp_realtek_device_(std::move(if_hp_realtek_device)) {}
// Constructor called by the CrOS platform implementation to override the
// kEnableBleV2 flag.
ServiceControllerRouter::ServiceControllerRouter(bool enable_ble_v2)
: ServiceControllerRouter() {
if (NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2) !=
enable_ble_v2) {
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableBleV2,
enable_ble_v2);
// CrOS uses the async signature for Scanning and has no support for the
// sync version.
// TODO(b/333408829): Enable async advertising flag once supported.
const_cast<FeatureFlags&>(FeatureFlags::GetInstance())
.SetFlags({.enable_ble_v2_async_scanning = true});
}
}
ServiceControllerRouter::~ServiceControllerRouter() {
LOG(INFO) << "ServiceControllerRouter going down.";
@@ -57,7 +57,6 @@ namespace connections {
class ServiceControllerRouter {
public:
ServiceControllerRouter();
explicit ServiceControllerRouter(bool enable_ble_v2);
explicit ServiceControllerRouter(
absl::AnyInvocable<bool()> if_hp_realtek_device);
virtual ~ServiceControllerRouter();
@@ -14,7 +14,6 @@
#include "connections/implementation/service_controller_router.h"
#include <array>
#include <cstdint>
#include <memory>
@@ -561,32 +560,6 @@ TEST_F(ServiceControllerRouterTest, QualityConversionWorks) {
EXPECT_EQ(router_.GetMediumQuality(Medium::WIFI_AWARE), v3::Quality::kHigh);
}
TEST_F(ServiceControllerRouterTest, EnableBleV2InConstructor) {
// This constructor is used to allow the platform to set the value
// of kEnableBleV2 to |enable_ble_v2|.
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableBleV2, false);
EXPECT_FALSE(NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2));
ServiceControllerRouter ble_v2_enabled_router =
ServiceControllerRouter(/*enable_ble_v2=*/true);
EXPECT_TRUE(NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2));
}
TEST_F(ServiceControllerRouterTest, DisableBleV2InConstructor) {
// This constructor is used to allow the platform to set the value
// of kEnableBleV2 to |enable_ble_v2|.
NearbyFlags::GetInstance().OverrideBoolFlagValue(
config_package_nearby::nearby_connections_feature::kEnableBleV2, true);
EXPECT_TRUE(NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2));
ServiceControllerRouter ble_v2_disabled_router =
ServiceControllerRouter(/*enable_ble_v2=*/false);
EXPECT_FALSE(NearbyFlags::GetInstance().GetBoolFlag(
config_package_nearby::nearby_connections_feature::kEnableBleV2));
}
TEST_F(ServiceControllerRouterTest, StartAdvertisingCalled) {
StartAdvertising(&client_, kServiceId, kAdvertisingOptions,
kConnectionRequestInfo, [this](Status status) {
@@ -1358,12 +1331,12 @@ TEST_F(ServiceControllerRouterTest,
TEST_F(ServiceControllerRouterTest, UpdateAdvertisingOptionsV3Called) {
EXPECT_CALL(*mock_, UpdateAdvertisingOptions)
.WillOnce(Return(Status{Status::kSuccess}));
router_.UpdateAdvertisingOptionsV3(
&client_, kServiceId, kAdvertisingOptions, [this](Status status) {
MutexLock lock(&mutex_);
result_ = status;
cond_.Notify();
});
router_.UpdateAdvertisingOptionsV3(&client_, kServiceId, kAdvertisingOptions,
[this](Status status) {
MutexLock lock(&mutex_);
result_ = status;
cond_.Notify();
});
{
MutexLock lock(&mutex_);
if (cond_.Wait(absl::Seconds(1)).value == Exception::kSuccess) {
@@ -1375,12 +1348,12 @@ TEST_F(ServiceControllerRouterTest, UpdateAdvertisingOptionsV3Called) {
TEST_F(ServiceControllerRouterTest, UpdateDiscoveryOptionsV3Called) {
EXPECT_CALL(*mock_, UpdateDiscoveryOptions)
.WillOnce(Return(Status{Status::kSuccess}));
router_.UpdateDiscoveryOptionsV3(
&client_, kServiceId, kDiscoveryOptions, [this](Status status) {
MutexLock lock(&mutex_);
result_ = status;
cond_.Notify();
});
router_.UpdateDiscoveryOptionsV3(&client_, kServiceId, kDiscoveryOptions,
[this](Status status) {
MutexLock lock(&mutex_);
result_ = status;
cond_.Notify();
});
{
MutexLock lock(&mutex_);
if (cond_.Wait(absl::Seconds(1)).value == Exception::kSuccess) {
-3
View File
@@ -303,7 +303,6 @@ cc_library(
name = "comm",
srcs = [
"awdl.cc",
"ble.cc",
"ble_v2.cc",
"bluetooth_classic.cc",
"credential_storage_impl.cc",
@@ -314,7 +313,6 @@ cc_library(
],
hdrs = [
"awdl.h",
"ble.h",
"ble_v2.h",
"bluetooth_adapter.h",
"bluetooth_classic.h",
@@ -488,7 +486,6 @@ cc_test(
timeout = "moderate",
srcs = [
"ble_connection_info_test.cc",
"ble_test.cc",
"ble_v2_test.cc",
"blocking_queue_stream_test.cc",
"bluetooth_adapter_test.cc",
-140
View File
@@ -1,140 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/ble.h"
#include <memory>
#include <string>
#include <utility>
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/logging.h"
#include "internal/platform/mutex_lock.h"
namespace nearby {
bool BleMedium::StartAdvertising(
const std::string& service_id, const ByteArray& advertisement_bytes,
const std::string& fast_advertisement_service_uuid) {
return impl_->StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid);
}
bool BleMedium::StopAdvertising(const std::string& service_id) {
return impl_->StopAdvertising(service_id);
}
bool BleMedium::StartScanning(
const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
DiscoveredPeripheralCallback callback) {
{
MutexLock lock(&mutex_);
discovered_peripheral_callback_ = std::move(callback);
peripherals_.clear();
}
return impl_->StartScanning(
service_id, fast_advertisement_service_uuid,
{
.peripheral_discovered_cb =
[this](api::BlePeripheral& peripheral,
const std::string& service_id, bool fast_advertisement) {
MutexLock lock(&mutex_);
auto pair = peripherals_.emplace(
&peripheral, absl::make_unique<ScanningInfo>());
auto& context = *pair.first->second;
context.peripheral = BlePeripheral(&peripheral);
discovered_peripheral_callback_.peripheral_discovered_cb(
context.peripheral, service_id,
context.peripheral.GetAdvertisementBytes(service_id),
fast_advertisement);
},
.peripheral_lost_cb =
[this](api::BlePeripheral& peripheral,
const std::string& service_id) {
MutexLock lock(&mutex_);
if (peripherals_.empty()) return;
auto context = peripherals_.find(&peripheral);
if (context == peripherals_.end()) return;
LOG(INFO) << "Removing peripheral="
<< context->second->peripheral.GetName()
<< ", impl=" << &peripheral;
discovered_peripheral_callback_.peripheral_lost_cb(
context->second->peripheral, service_id);
},
});
}
bool BleMedium::StopScanning(const std::string& service_id) {
{
MutexLock lock(&mutex_);
discovered_peripheral_callback_ = {};
peripherals_.clear();
LOG(INFO) << "Ble Scanning disabled: impl=" << &GetImpl();
}
return impl_->StopScanning(service_id);
}
bool BleMedium::StartAcceptingConnections(const std::string& service_id,
AcceptedConnectionCallback callback) {
{
MutexLock lock(&mutex_);
accepted_connection_callback_ = std::move(callback);
}
return impl_->StartAcceptingConnections(
service_id,
[this](api::BleSocket& socket, const std::string& service_id) {
MutexLock lock(&mutex_);
auto pair = sockets_.emplace(
&socket, std::make_unique<AcceptedConnectionInfo>());
auto& context = *pair.first->second;
if (!pair.second) {
LOG(INFO) << "Accepting (again) socket=" << &context.socket
<< ", impl=" << &socket;
} else {
context.socket = BleSocket(&socket);
LOG(INFO) << "Accepting socket=" << &context.socket
<< ", impl=" << &socket;
}
if (accepted_connection_callback_) {
accepted_connection_callback_(context.socket, service_id);
}
});
}
bool BleMedium::StopAcceptingConnections(const std::string& service_id) {
{
MutexLock lock(&mutex_);
accepted_connection_callback_ = nullptr;
sockets_.clear();
LOG(INFO) << "Ble accepted connection disabled: impl=" << &GetImpl();
}
return impl_->StopAcceptingConnections(service_id);
}
BleSocket BleMedium::Connect(BlePeripheral& peripheral,
const std::string& service_id,
CancellationFlag* cancellation_flag) {
{
MutexLock lock(&mutex_);
LOG(INFO) << "BleMedium::Connect: peripheral=" << peripheral.GetName()
<< ",impl=" << &peripheral.GetImpl();
}
return BleSocket(
impl_->Connect(peripheral.GetImpl(), service_id, cancellation_flag));
}
} // namespace nearby
-162
View File
@@ -1,162 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PLATFORM_PUBLIC_BLE_H_
#define PLATFORM_PUBLIC_BLE_H_
#include "absl/container/flat_hash_map.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/platform.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/mutex.h"
#include "internal/platform/output_stream.h"
namespace nearby {
class BleSocket final {
public:
BleSocket() = default;
BleSocket(const BleSocket&) = default;
BleSocket& operator=(const BleSocket&) = default;
explicit BleSocket(api::BleSocket* socket) : impl_(socket) {}
explicit BleSocket(std::unique_ptr<api::BleSocket> socket)
: impl_(socket.release()) {}
~BleSocket() = default;
// Returns the InputStream of the BleSocket.
// On error, returned stream will report Exception::kIo on any operation.
//
// The returned object is not owned by the caller, and can be invalidated once
// the BleSocket object is destroyed.
InputStream& GetInputStream() { return impl_->GetInputStream(); }
// Returns the OutputStream of the BleSocket.
// On error, returned stream will report Exception::kIo on any operation.
//
// The returned object is not owned by the caller, and can be invalidated once
// the BleSocket object is destroyed.
OutputStream& GetOutputStream() { return impl_->GetOutputStream(); }
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
Exception Close() { return impl_->Close(); }
BlePeripheral GetRemotePeripheral() {
return BlePeripheral(impl_->GetRemotePeripheral());
}
// Returns true if a socket is usable. If this method returns false,
// it is not safe to call any other method.
// NOTE(socket validity):
// Socket created by a default public constructor is not valid, because
// it is missing platform implementation.
// The only way to obtain a valid socket is through connection, such as
// an object returned by BleMedium::Connect
// These methods may also return an invalid socket if connection failed for
// any reason.
bool IsValid() const { return impl_ != nullptr; }
// Returns reference to platform implementation.
// This is used to communicate with platform code, and for debugging purposes.
// Returned reference will remain valid for while BleSocket object is
// itself valid. Typically BleSocket lifetime matches duration of the
// connection, and is controlled by end user, since they hold the instance.
api::BleSocket& GetImpl() { return *impl_; }
private:
std::shared_ptr<api::BleSocket> impl_;
};
// Container of operations that can be performed over the BLE medium.
class BleMedium final {
public:
using Platform = api::ImplementationPlatform;
struct DiscoveredPeripheralCallback {
absl::AnyInvocable<void(
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes, bool fast_advertisement)>
peripheral_discovered_cb =
DefaultCallback<BlePeripheral&, const std::string&,
const ByteArray&, bool>();
absl::AnyInvocable<void(BlePeripheral& peripheral,
const std::string& service_id)>
peripheral_lost_cb =
DefaultCallback<BlePeripheral&, const std::string&>();
};
struct ScanningInfo {
BlePeripheral peripheral;
};
using AcceptedConnectionCallback = absl::AnyInvocable<void(
BleSocket& socket, const std::string& service_id)>;
struct AcceptedConnectionInfo {
BleSocket socket;
};
explicit BleMedium(BluetoothAdapter& adapter)
: impl_(Platform::CreateBleMedium(adapter.GetImpl())),
adapter_(adapter) {}
~BleMedium() = default;
// Returns true once the BLE advertising has been initiated.
bool StartAdvertising(const std::string& service_id,
const ByteArray& advertisement_bytes,
const std::string& fast_advertisement_service_uuid);
bool StopAdvertising(const std::string& service_id);
// Returns true once the BLE scan has been initiated.
bool StartScanning(const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
DiscoveredPeripheralCallback callback);
// Returns true once BLE scanning for service_id is well and truly stopped;
// after this returns, there must be no more invocations of the
// DiscoveredPeripheralCallback passed in to StartScanning() for service_id.
bool StopScanning(const std::string& service_id);
// Returns true once BLE socket connection requests to service_id can be
// accepted.
bool StartAcceptingConnections(const std::string& service_id,
AcceptedConnectionCallback callback);
bool StopAcceptingConnections(const std::string& service_id);
// Returns a new BleSocket. On Success, BleSocket::IsValid()
// returns true.
BleSocket Connect(BlePeripheral& peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag);
bool IsValid() const { return impl_ != nullptr; }
api::BleMedium& GetImpl() { return *impl_; }
BluetoothAdapter& GetAdapter() { return adapter_; }
private:
Mutex mutex_;
std::unique_ptr<api::BleMedium> impl_;
BluetoothAdapter& adapter_;
absl::flat_hash_map<api::BlePeripheral*, std::unique_ptr<ScanningInfo>>
peripherals_ ABSL_GUARDED_BY(mutex_);
absl::flat_hash_map<api::BleSocket*, std::unique_ptr<AcceptedConnectionInfo>>
sockets_ ABSL_GUARDED_BY(mutex_);
DiscoveredPeripheralCallback discovered_peripheral_callback_
ABSL_GUARDED_BY(mutex_);
AcceptedConnectionCallback accepted_connection_callback_
ABSL_GUARDED_BY(mutex_);
};
} // namespace nearby
#endif // PLATFORM_PUBLIC_BLE_H_
-296
View File
@@ -1,296 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/ble.h"
#include <memory>
#include <string>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/logging.h"
#include "internal/platform/medium_environment.h"
namespace nearby {
namespace {
using FeatureFlags = FeatureFlags::Flags;
constexpr FeatureFlags kTestCases[] = {
FeatureFlags{
.enable_cancellation_flag = true,
},
FeatureFlags{
.enable_cancellation_flag = false,
},
};
constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000);
constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"};
constexpr absl::string_view kAdvertisementString{"\x0a\x0b\x0c\x0d"};
constexpr absl::string_view kFastAdvertisementServiceUuid{"\xf3\xfe"};
class BleMediumTest : public ::testing::TestWithParam<FeatureFlags> {
protected:
using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback;
using AcceptedConnectionCallback = BleMedium::AcceptedConnectionCallback;
MediumEnvironment& env_{MediumEnvironment::Instance()};
};
TEST_P(BleMediumTest, CanStartAcceptingConnectionsAndConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
BluetoothAdapter adapter_a_;
BluetoothAdapter adapter_b_;
BleMedium ble_a{adapter_a_};
BleMedium ble_b{adapter_b_};
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
CancellationFlag flag;
BlePeripheral* discovered_peripheral = nullptr;
ble_a.StartScanning(
service_id, fast_advertisement_service_uuid,
DiscoveredPeripheralCallback{
.peripheral_discovered_cb =
[&found_latch, &discovered_peripheral](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
LOG(INFO) << "Discovered peripheral=" << peripheral.GetName()
<< ", impl=" << &peripheral.GetImpl()
<< ", fast advertisement=" << fast_advertisement;
discovered_peripheral = &peripheral;
found_latch.CountDown();
},
});
ble_b.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid);
ble_b.StartAcceptingConnections(
service_id, [&](BleSocket socket, const std::string& service_id) {
LOG(INFO) << "Connection accepted: socket=" << &socket
<< ", service_id=" << service_id;
accepted_latch.CountDown();
});
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
BleSocket socket_a;
EXPECT_FALSE(socket_a.IsValid());
{
SingleThreadExecutor client_executor;
client_executor.Execute(
[&ble_a, &socket_a, discovered_peripheral, &service_id, &flag]() {
socket_a = ble_a.Connect(*discovered_peripheral, service_id, &flag);
});
}
EXPECT_TRUE(accepted_latch.Await(kWaitDuration).result());
EXPECT_TRUE(socket_a.IsValid());
ble_b.StopAdvertising(service_id);
ble_a.StopScanning(service_id);
env_.Stop();
}
TEST_P(BleMediumTest, CanCancelConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
BluetoothAdapter adapter_a_;
BluetoothAdapter adapter_b_;
BleMedium ble_a{adapter_a_};
BleMedium ble_b{adapter_b_};
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
CancellationFlag flag(true);
BlePeripheral* discovered_peripheral = nullptr;
ble_a.StartScanning(
service_id, fast_advertisement_service_uuid,
DiscoveredPeripheralCallback{
.peripheral_discovered_cb =
[&found_latch, &discovered_peripheral](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
LOG(INFO) << "Discovered peripheral=" << peripheral.GetName()
<< ", impl=" << &peripheral.GetImpl()
<< ", fast advertisement=" << fast_advertisement;
discovered_peripheral = &peripheral;
found_latch.CountDown();
},
});
ble_b.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid);
ble_b.StartAcceptingConnections(
service_id, [&](BleSocket socket, const std::string& service_id) {
LOG(INFO) << "Connection accepted: socket=" << &socket
<< ", service_id=" << service_id;
accepted_latch.CountDown();
});
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
BleSocket socket_a;
EXPECT_FALSE(socket_a.IsValid());
{
SingleThreadExecutor client_executor;
client_executor.Execute(
[&ble_a, &socket_a, discovered_peripheral, &service_id, &flag]() {
socket_a = ble_a.Connect(*discovered_peripheral, service_id, &flag);
});
}
// If FeatureFlag is disabled, Cancelled is false as no-op.
if (!feature_flags.enable_cancellation_flag) {
EXPECT_TRUE(accepted_latch.Await(kWaitDuration).result());
EXPECT_TRUE(socket_a.IsValid());
} else {
EXPECT_FALSE(accepted_latch.Await(kWaitDuration).result());
EXPECT_FALSE(socket_a.IsValid());
}
ble_b.StopAdvertising(service_id);
ble_a.StopScanning(service_id);
env_.Stop();
}
INSTANTIATE_TEST_SUITE_P(ParametrisedBleMediumTest, BleMediumTest,
::testing::ValuesIn(kTestCases));
TEST_F(BleMediumTest, ConstructorDestructorWorks) {
env_.Start();
BluetoothAdapter adapter_a_;
BluetoothAdapter adapter_b_;
BleMedium ble_a{adapter_a_};
BleMedium ble_b{adapter_b_};
// Make sure we can create functional mediums.
ASSERT_TRUE(ble_a.IsValid());
ASSERT_TRUE(ble_b.IsValid());
// Make sure we can create 2 distinct mediums.
EXPECT_NE(&ble_a.GetImpl(), &ble_b.GetImpl());
env_.Stop();
}
TEST_F(BleMediumTest, CanStartAdvertising) {
env_.Start();
BluetoothAdapter adapter_a_;
BluetoothAdapter adapter_b_;
BleMedium ble_a{adapter_a_};
BleMedium ble_b{adapter_b_};
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
ble_a.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid);
EXPECT_TRUE(ble_b.StartScanning(
service_id, fast_advertisement_service_uuid,
DiscoveredPeripheralCallback{
.peripheral_discovered_cb =
[&found_latch](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { found_latch.CountDown(); },
}));
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
EXPECT_TRUE(ble_a.StopAdvertising(service_id));
EXPECT_TRUE(ble_b.StopScanning(service_id));
env_.Stop();
}
TEST_F(BleMediumTest, CanStartScanning) {
env_.Start();
BluetoothAdapter adapter_a_;
BluetoothAdapter adapter_b_;
BleMedium ble_a{adapter_a_};
BleMedium ble_b{adapter_b_};
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch lost_latch(1);
ble_a.StartScanning(
service_id, fast_advertisement_service_uuid,
DiscoveredPeripheralCallback{
.peripheral_discovered_cb =
[&found_latch](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { found_latch.CountDown(); },
.peripheral_lost_cb =
[&lost_latch](BlePeripheral& peripheral,
const std::string& service_id) {
lost_latch.CountDown();
},
});
EXPECT_TRUE(ble_b.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid));
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
EXPECT_TRUE(ble_b.StopAdvertising(service_id));
EXPECT_TRUE(lost_latch.Await(kWaitDuration).result());
EXPECT_TRUE(ble_a.StopScanning(service_id));
env_.Stop();
}
TEST_F(BleMediumTest, CanStopDiscovery) {
env_.Start();
BluetoothAdapter adapter_a_;
BluetoothAdapter adapter_b_;
BleMedium ble_a{adapter_a_};
BleMedium ble_b{adapter_b_};
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch lost_latch(1);
ble_a.StartScanning(
service_id, fast_advertisement_service_uuid,
DiscoveredPeripheralCallback{
.peripheral_discovered_cb =
[&found_latch](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) { found_latch.CountDown(); },
.peripheral_lost_cb =
[&lost_latch](BlePeripheral& peripheral,
const std::string& service_id) {
lost_latch.CountDown();
},
});
EXPECT_TRUE(ble_b.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid));
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
EXPECT_TRUE(ble_a.StopScanning(service_id));
EXPECT_TRUE(ble_b.StopAdvertising(service_id));
EXPECT_FALSE(lost_latch.Await(kWaitDuration).result());
env_.Stop();
}
} // namespace
} // namespace nearby
-24
View File
@@ -19,8 +19,6 @@
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/bluetooth_classic.h"
#include "internal/platform/implementation/platform.h"
@@ -28,28 +26,6 @@
namespace nearby {
// Opaque wrapper over a BLE peripheral. Must contain enough data about a
// particular BLE peripheral to connect to its GATT server.
class BlePeripheral final {
public:
BlePeripheral() = default;
BlePeripheral(const BlePeripheral&) = default;
BlePeripheral& operator=(const BlePeripheral&) = default;
explicit BlePeripheral(api::BlePeripheral* peripheral) : impl_(peripheral) {}
std::string GetName() const { return impl_->GetName(); }
ByteArray GetAdvertisementBytes(const std::string& service_id) const {
return impl_->GetAdvertisementBytes(service_id);
}
api::BlePeripheral& GetImpl() { return *impl_; }
bool IsValid() const { return impl_ != nullptr; }
private:
api::BlePeripheral* impl_;
};
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html.
class BluetoothDevice final {
public:
-1
View File
@@ -152,7 +152,6 @@ cc_library(
name = "comm",
hdrs = [
"awdl.h",
"ble.h",
"ble_v2.h",
"bluetooth_adapter.h",
"bluetooth_classic.h",
@@ -308,12 +308,6 @@ void GNCEnsureFileAtPath(std::string path) {
XCTAssertEqual(bluetooth_classic_medium.get(), nullptr);
}
- (void)testCreateBleMedium {
auto bluetooth_adapter = nearby::api::ImplementationPlatform::CreateBluetoothAdapter();
auto ble_medium = nearby::api::ImplementationPlatform::CreateBleMedium(*bluetooth_adapter);
XCTAssertEqual(ble_medium.get(), nullptr);
}
- (void)testCreateBleV2Medium {
auto bluetooth_adapter = nearby::api::ImplementationPlatform::CreateBluetoothAdapter();
auto ble_medium = nearby::api::ImplementationPlatform::CreateBleV2Medium(*bluetooth_adapter);
@@ -172,10 +172,6 @@ std::unique_ptr<BluetoothClassicMedium> ImplementationPlatform::CreateBluetoothC
return nullptr;
}
std::unique_ptr<BleMedium> ImplementationPlatform::CreateBleMedium(api::BluetoothAdapter& adapter) {
return nullptr;
}
std::unique_ptr<ble_v2::BleMedium> ImplementationPlatform::CreateBleV2Medium(
api::BluetoothAdapter& adapter) {
return std::make_unique<apple::BleMedium>();
-122
View File
@@ -1,122 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PLATFORM_API_BLE_H_
#define PLATFORM_API_BLE_H_
#include "internal/platform/byte_array.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/implementation/bluetooth_classic.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
namespace nearby {
namespace api {
// Opaque wrapper over a BLE peripheral. Must contain enough data about a
// particular BLE device to connect to its GATT server.
class BlePeripheral {
public:
virtual ~BlePeripheral() = default;
virtual std::string GetName() const = 0;
virtual ByteArray GetAdvertisementBytes(
const std::string& service_id) const = 0;
};
class BleSocket {
public:
virtual ~BleSocket() = default;
// Returns the InputStream of the BleSocket.
// On error, returned stream will report Exception::kIo on any operation.
//
// The returned object is not owned by the caller, and can be invalidated once
// the BleSocket object is destroyed.
virtual InputStream& GetInputStream() = 0;
// Returns the OutputStream of the BleSocket.
// On error, returned stream will report Exception::kIo on any operation.
//
// The returned object is not owned by the caller, and can be invalidated once
// the BleSocket object is destroyed.
virtual OutputStream& GetOutputStream() = 0;
// Conforms to the same contract as
// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#close().
//
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
virtual Exception Close() = 0;
// Returns valid BlePeripheral pointer if there is a connection, and
// nullptr otherwise.
virtual BlePeripheral* GetRemotePeripheral() = 0;
};
// Container of operations that can be performed over the BLE medium.
class BleMedium {
public:
virtual ~BleMedium() = default;
virtual bool StartAdvertising(
const std::string& service_id, const ByteArray& advertisement_bytes,
const std::string& fast_advertisement_service_uuid) = 0;
virtual bool StopAdvertising(const std::string& service_id) = 0;
// Callback that is invoked when a discovered peripheral is found or lost.
struct DiscoveredPeripheralCallback {
absl::AnyInvocable<void(BlePeripheral& peripheral,
const std::string& service_id,
bool fast_advertisement)>
peripheral_discovered_cb =
DefaultCallback<BlePeripheral&, const std::string&, bool>();
absl::AnyInvocable<void(BlePeripheral& peripheral,
const std::string& service_id)>
peripheral_lost_cb =
DefaultCallback<BlePeripheral&, const std::string&>();
};
// Returns true once the BLE scan has been initiated.
virtual bool StartScanning(const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
DiscoveredPeripheralCallback callback) = 0;
// Returns true once BLE scanning for service_id is well and truly stopped;
// after this returns, there must be no more invocations of the
// DiscoveredPeripheralCallback passed in to StartScanning() for service_id.
virtual bool StopScanning(const std::string& service_id) = 0;
// Callback that is invoked when a new connection is accepted.
using AcceptedConnectionCallback = absl::AnyInvocable<void(
BleSocket& socket, const std::string& service_id)>;
// Returns true once BLE socket connection requests to service_id can be
// accepted.
virtual bool StartAcceptingConnections(
const std::string& service_id, AcceptedConnectionCallback callback) = 0;
virtual bool StopAcceptingConnections(const std::string& service_id) = 0;
// Connects to a BLE peripheral.
// On success, returns a new BleSocket.
// On error, returns nullptr.
virtual std::unique_ptr<BleSocket> Connect(
BlePeripheral& peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag) = 0;
};
} // namespace api
} // namespace nearby
#endif // PLATFORM_API_BLE_H_
+4 -5
View File
@@ -1,6 +1,3 @@
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_cc//cc:cc_test.bzl", "cc_test")
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,6 +11,10 @@ load("@rules_cc//cc:cc_test.bzl", "cc_test")
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_cc//cc:cc_test.bzl", "cc_test")
licenses(["notice"])
cc_library(
@@ -79,7 +80,6 @@ cc_library(
testonly = True,
srcs = [
"awdl.cc",
"ble.cc",
"ble_v2.cc",
"bluetooth_adapter.cc",
"bluetooth_classic.cc",
@@ -90,7 +90,6 @@ cc_library(
],
hdrs = [
"awdl.h",
"ble.h",
"ble_v2.h",
"bluetooth_adapter.h",
"bluetooth_classic.h",
-316
View File
@@ -1,316 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/implementation/g3/ble.h"
#include <iostream>
#include <memory>
#include <string>
#include <utility>
#include "absl/functional/any_invocable.h"
#include "absl/log/check.h"
#include "absl/strings/escaping.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/cancellation_flag_listener.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/g3/bluetooth_adapter.h"
#include "internal/platform/implementation/shared/count_down_latch.h"
#include "internal/platform/logging.h"
#include "internal/platform/medium_environment.h"
namespace nearby {
namespace g3 {
BlePeripheral* BleSocket::GetRemotePeripheral() {
absl::MutexLock lock(mutex_);
return peripheral_;
}
std::unique_ptr<api::BleSocket> BleServerSocket::Accept(
BlePeripheral* peripheral) {
absl::MutexLock lock(mutex_);
if (closed_) return {};
while (pending_sockets_.empty()) {
cond_.Wait(&mutex_);
if (closed_) break;
}
if (closed_) return {};
auto* remote_socket =
pending_sockets_.extract(pending_sockets_.begin()).value();
CHECK(remote_socket);
auto local_socket = std::make_unique<BleSocket>(peripheral);
local_socket->Connect(*remote_socket);
remote_socket->Connect(*local_socket);
cond_.SignalAll();
return local_socket;
}
bool BleServerSocket::Connect(BleSocket& socket) {
absl::MutexLock lock(mutex_);
if (closed_) return false;
if (socket.IsConnected()) {
LOG(ERROR) << "Failed to connect to Ble server socket: already connected";
return true; // already connected.
}
// add client socket to the pending list
pending_sockets_.emplace(&socket);
cond_.SignalAll();
while (!socket.IsConnected()) {
cond_.Wait(&mutex_);
if (closed_) return false;
}
return true;
}
void BleServerSocket::SetCloseNotifier(absl::AnyInvocable<void()> notifier) {
absl::MutexLock lock(mutex_);
close_notifier_ = std::move(notifier);
}
BleServerSocket::~BleServerSocket() {
absl::MutexLock lock(mutex_);
DoClose();
}
Exception BleServerSocket::Close() {
absl::MutexLock lock(mutex_);
return DoClose();
}
Exception BleServerSocket::DoClose() {
bool should_notify = !closed_;
closed_ = true;
if (should_notify) {
cond_.SignalAll();
if (close_notifier_) {
auto notifier = std::move(close_notifier_);
mutex_.unlock();
// Notifier may contain calls to public API, and may cause deadlock, if
// mutex_ is held during the call.
notifier();
mutex_.lock();
}
}
return {Exception::kSuccess};
}
BleMedium::BleMedium(api::BluetoothAdapter& adapter)
: adapter_(static_cast<BluetoothAdapter*>(&adapter)) {
adapter_->SetBleMedium(this);
auto& env = MediumEnvironment::Instance();
env.RegisterBleMedium(*this);
}
BleMedium::~BleMedium() {
adapter_->SetBleMedium(nullptr);
auto& env = MediumEnvironment::Instance();
env.UnregisterBleMedium(*this);
StopAdvertising(advertising_info_.service_id);
StopScanning(scanning_info_.service_id);
accept_loops_runner_.Shutdown();
LOG(INFO) << "BleMedium dtor advertising_accept_thread_running_ = "
<< acceptance_thread_running_.load();
// If acceptance thread is still running, wait to finish.
if (acceptance_thread_running_) {
while (acceptance_thread_running_) {
shared::CountDownLatch latch(1);
close_accept_loops_runner_.Execute([&latch]() { latch.CountDown(); });
latch.Await();
}
}
}
bool BleMedium::StartAdvertising(
const std::string& service_id, const ByteArray& advertisement_bytes,
const std::string& fast_advertisement_service_uuid) {
LOG(INFO) << "G3 Ble StartAdvertising: service_id=" << service_id
<< ", advertisement bytes="
<< absl::BytesToHexString(std::string(advertisement_bytes)) << "("
<< advertisement_bytes.size() << "),"
<< ", fast advertisement service uuid="
<< absl::BytesToHexString(fast_advertisement_service_uuid);
auto& env = MediumEnvironment::Instance();
auto& peripheral = adapter_->GetPeripheral();
peripheral.SetAdvertisementBytes(service_id, advertisement_bytes);
bool fast_advertisement = !fast_advertisement_service_uuid.empty();
env.UpdateBleMediumForAdvertising(*this, peripheral, service_id,
fast_advertisement, true);
absl::MutexLock lock(mutex_);
if (server_socket_ != nullptr) server_socket_.release();
server_socket_ = std::make_unique<BleServerSocket>();
acceptance_thread_running_.exchange(true);
accept_loops_runner_.Execute([&env, this, service_id]() mutable {
while (true) {
if (accept_loops_runner_.InShutdown()) break;
auto client_socket =
server_socket_->Accept(&(this->adapter_->GetPeripheral()));
if (client_socket == nullptr) break;
env.CallBleAcceptedConnectionCallback(*this, *(client_socket.release()),
service_id);
}
acceptance_thread_running_.exchange(false);
});
advertising_info_.service_id = service_id;
return true;
}
bool BleMedium::StopAdvertising(const std::string& service_id) {
LOG(INFO) << "G3 Ble StopAdvertising: service_id=" << service_id;
{
absl::MutexLock lock(mutex_);
if (advertising_info_.Empty()) {
LOG(INFO) << "G3 Ble StopAdvertising: Can't stop advertising "
"because we never started advertising.";
return false;
}
advertising_info_.Clear();
}
auto& env = MediumEnvironment::Instance();
env.UpdateBleMediumForAdvertising(*this, adapter_->GetPeripheral(),
service_id, /*fast_advertisement=*/false,
/*enabled=*/false);
accept_loops_runner_.Shutdown();
if (server_socket_ == nullptr) {
LOG(ERROR) << "G3 Ble StopAdvertising: Failed to find Ble Server "
"socket: service_id="
<< service_id;
// Fall through for server socket not found.
return true;
}
if (!server_socket_->Close().Ok()) {
LOG(INFO)
<< "G3 Ble StopAdvertising: Failed to close Ble server socket for "
<< service_id;
return false;
}
return true;
}
bool BleMedium::StartScanning(
const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
DiscoveredPeripheralCallback callback) {
LOG(INFO) << "G3 Ble StartScanning: service_id=" << service_id;
auto& env = MediumEnvironment::Instance();
env.UpdateBleMediumForScanning(*this, service_id,
fast_advertisement_service_uuid,
std::move(callback), true);
{
absl::MutexLock lock(mutex_);
scanning_info_.service_id = service_id;
}
return true;
}
bool BleMedium::StopScanning(const std::string& service_id) {
LOG(INFO) << "G3 Ble StopScanning: service_id=" << service_id;
{
absl::MutexLock lock(mutex_);
if (scanning_info_.Empty()) {
LOG(INFO) << "G3 Ble StopDiscovery: Can't stop scanning because "
"we never started scanning.";
return false;
}
scanning_info_.Clear();
}
auto& env = MediumEnvironment::Instance();
env.UpdateBleMediumForScanning(*this, service_id, {}, {}, false);
return true;
}
bool BleMedium::StartAcceptingConnections(const std::string& service_id,
AcceptedConnectionCallback callback) {
LOG(INFO) << "G3 Ble StartAcceptingConnections: service_id=" << service_id;
auto& env = MediumEnvironment::Instance();
env.UpdateBleMediumForAcceptedConnection(*this, service_id,
std::move(callback));
return true;
}
bool BleMedium::StopAcceptingConnections(const std::string& service_id) {
LOG(INFO) << "G3 Ble StopAcceptingConnections: service_id=" << service_id;
auto& env = MediumEnvironment::Instance();
env.UpdateBleMediumForAcceptedConnection(*this, service_id, {});
return true;
}
std::unique_ptr<api::BleSocket> BleMedium::Connect(
api::BlePeripheral& remote_peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag) {
LOG(INFO) << "G3 Ble Connect [self]: medium=" << this
<< ", adapter=" << &GetAdapter()
<< ", peripheral=" << &GetAdapter().GetPeripheral()
<< ", service_id=" << service_id;
// First, find an instance of remote medium, that exposed this peripheral.
auto& adapter = static_cast<BlePeripheral&>(remote_peripheral).GetAdapter();
auto* medium = static_cast<BleMedium*>(adapter.GetBleMedium());
if (!medium) return {}; // Can't find medium. Bail out.
BleServerSocket* remote_server_socket = nullptr;
LOG(INFO) << "G3 Ble Connect [peer]: medium=" << medium
<< ", adapter=" << &adapter << ", peripheral=" << &remote_peripheral
<< ", service_id=" << service_id;
// Then, find our server socket context in this medium.
{
absl::MutexLock medium_lock(medium->mutex_);
remote_server_socket = medium->server_socket_.get();
if (remote_server_socket == nullptr) {
LOG(ERROR)
<< "G3 Ble Connect: Failed to find Ble Server socket: service_id="
<< service_id;
return {};
}
}
if (cancellation_flag->Cancelled()) {
LOG(ERROR) << "G3 BLE Connect: Has been cancelled: "
"service_id="
<< service_id;
return {};
}
CancellationFlagListener listener(cancellation_flag, [this]() {
LOG(INFO) << "G3 BLE Cancel Connect.";
if (server_socket_ != nullptr) server_socket_->Close();
});
BlePeripheral peripheral = static_cast<BlePeripheral&>(remote_peripheral);
auto socket = std::make_unique<BleSocket>(&peripheral);
// Finally, Request to connect to this socket.
if (!remote_server_socket->Connect(*socket)) {
LOG(ERROR) << "G3 Ble Connect: Failed to connect to existing Ble "
"Server socket: service_id="
<< service_id;
return {};
}
LOG(INFO) << "G3 Ble Connect: connected: socket=" << socket.get();
return socket;
}
} // namespace g3
} // namespace nearby
-198
View File
@@ -1,198 +0,0 @@
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PLATFORM_IMPL_G3_BLE_H_
#define PLATFORM_IMPL_G3_BLE_H_
#include <memory>
#include <string>
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/escaping.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/g3/bluetooth_adapter.h"
#include "internal/platform/implementation/g3/bluetooth_classic.h"
#include "internal/platform/implementation/g3/multi_thread_executor.h"
#include "internal/platform/implementation/g3/socket_base.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
namespace nearby {
namespace g3 {
class BleMedium;
class BleSocket : public api::BleSocket, public SocketBase {
public:
BleSocket() = default;
explicit BleSocket(BlePeripheral* peripheral) : peripheral_(peripheral) {}
// Returns the InputStream of this connected BleSocket.
InputStream& GetInputStream() override {
return SocketBase::GetInputStream();
}
// Returns the OutputStream of this connected BleSocket.
// This stream is for local side to write.
OutputStream& GetOutputStream() override {
return SocketBase::GetOutputStream();
}
// Returns address of a remote BleSocket or nullptr.
BleSocket* GetRemoteSocket() {
return static_cast<BleSocket*>(SocketBase::GetRemoteSocket());
}
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
Exception Close() override { return SocketBase::Close(); }
// Returns valid BlePeripheral pointer if there is a connection, and
// nullptr otherwise.
BlePeripheral* GetRemotePeripheral() override ABSL_LOCKS_EXCLUDED(mutex_);
private:
BlePeripheral* peripheral_;
};
class BleServerSocket {
public:
~BleServerSocket();
// Blocks until either:
// - at least one incoming connection request is available, or
// - ServerSocket is closed.
// On success, returns connected socket, ready to exchange data.
// Returns nullptr on error.
// Once error is reported, it is permanent, and ServerSocket has to be closed.
//
// Called by the server side of a connection.
// Returns BleSocket to the server side.
// If not null, returned socket is connected to its remote (client-side) peer.
std::unique_ptr<api::BleSocket> Accept(BlePeripheral* peripheral)
ABSL_LOCKS_EXCLUDED(mutex_);
// Blocks until either:
// - connection is available, or
// - server socket is closed, or
// - error happens.
//
// Called by the client side of a connection.
// Returns true, if socket is successfully connected.
bool Connect(BleSocket& socket) ABSL_LOCKS_EXCLUDED(mutex_);
// Called by the server side of a connection before passing ownership of
// BleServerSocker to user, to track validity of a pointer to this
// server socket,
void SetCloseNotifier(absl::AnyInvocable<void()> notifier)
ABSL_LOCKS_EXCLUDED(mutex_);
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
// Calls close_notifier if it was previously set, and marks socket as closed.
Exception Close() ABSL_LOCKS_EXCLUDED(mutex_);
private:
Exception DoClose() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
absl::Mutex mutex_;
absl::CondVar cond_;
absl::flat_hash_set<BleSocket*> pending_sockets_ ABSL_GUARDED_BY(mutex_);
absl::AnyInvocable<void()> close_notifier_ ABSL_GUARDED_BY(mutex_);
bool closed_ ABSL_GUARDED_BY(mutex_) = false;
};
// Container of operations that can be performed over the BLE medium.
class BleMedium : public api::BleMedium {
public:
explicit BleMedium(api::BluetoothAdapter& adapter);
~BleMedium() override;
// Returns true once the Ble advertising has been initiated.
bool StartAdvertising(
const std::string& service_id, const ByteArray& advertisement_bytes,
const std::string& fast_advertisement_service_uuid) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopAdvertising(const std::string& service_id) override
ABSL_LOCKS_EXCLUDED(mutex_);
// Returns true once the Ble scanning has been initiated.
bool StartScanning(const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
DiscoveredPeripheralCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
// Returns true once Ble scanning for service_id is well and truly
// stopped; after this returns, there must be no more invocations of the
// DiscoveredPeripheralCallback passed in to StartScanning() for service_id.
bool StopScanning(const std::string& service_id) override
ABSL_LOCKS_EXCLUDED(mutex_);
// Returns true once Ble socket connection requests to service_id can be
// accepted.
bool StartAcceptingConnections(const std::string& service_id,
AcceptedConnectionCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopAcceptingConnections(const std::string& service_id) override
ABSL_LOCKS_EXCLUDED(mutex_);
// Connects to existing remote Ble peripheral.
//
// On success, returns a new BleSocket.
// On error, returns nullptr.
std::unique_ptr<api::BleSocket> Connect(
api::BlePeripheral& remote_peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag) override ABSL_LOCKS_EXCLUDED(mutex_);
BluetoothAdapter& GetAdapter() { return *adapter_; }
private:
static constexpr int kMaxConcurrentAcceptLoops = 5;
struct AdvertisingInfo {
bool Empty() const { return service_id.empty(); }
void Clear() { service_id.clear(); }
std::string service_id;
};
struct ScanningInfo {
bool Empty() const { return service_id.empty(); }
void Clear() { service_id.clear(); }
std::string service_id;
};
absl::Mutex mutex_;
BluetoothAdapter* adapter_; // Our device adapter; read-only.
// A thread pool dedicated to running all the accept loops from
// StartAdvertising().
MultiThreadExecutor accept_loops_runner_{kMaxConcurrentAcceptLoops};
std::atomic_bool acceptance_thread_running_ = false;
// A thread pool dedicated to wait to complete the accept_loops_runner_.
MultiThreadExecutor close_accept_loops_runner_{1};
// A server socket is established when start advertising.
std::unique_ptr<BleServerSocket> server_socket_;
AdvertisingInfo advertising_info_ ABSL_GUARDED_BY(mutex_);
ScanningInfo scanning_info_ ABSL_GUARDED_BY(mutex_);
};
} // namespace g3
} // namespace nearby
#endif // PLATFORM_IMPL_G3_BLE_H_
@@ -14,9 +14,14 @@
#include "internal/platform/implementation/g3/bluetooth_adapter.h"
#include <cstdint>
#include <string>
#include <utility>
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_classic.h"
#include "internal/platform/mac_address.h"
#include "internal/platform/medium_environment.h"
#include "internal/platform/prng.h"
@@ -27,22 +32,6 @@ namespace {
constexpr std::uint64_t kMacAddressMask = 0x0000FFFFFFFFFFFF;
}
BlePeripheral::BlePeripheral(BluetoothAdapter* adapter) : adapter_(*adapter) {}
std::string BlePeripheral::GetName() const {
return adapter_.GetAddress().ToString();
}
ByteArray BlePeripheral::GetAdvertisementBytes(
const std::string& service_id) const {
return advertisement_bytes_;
}
void BlePeripheral::SetAdvertisementBytes(
const std::string& service_id, const ByteArray& advertisement_bytes) {
advertisement_bytes_ = advertisement_bytes;
}
BluetoothDevice::BluetoothDevice(BluetoothAdapter* adapter)
: adapter_(*adapter) {}
@@ -52,9 +41,7 @@ std::string BluetoothDevice::GetMacAddress() const {
return GetAddress().ToString();
}
MacAddress BluetoothDevice::GetAddress() const {
return adapter_.GetAddress();
}
MacAddress BluetoothDevice::GetAddress() const { return adapter_.GetAddress(); }
BluetoothAdapter::BluetoothAdapter() {
std::uint64_t raw_mac_addr = Prng().NextInt64() & kMacAddressMask;
@@ -73,10 +60,6 @@ void BluetoothAdapter::SetBluetoothClassicMedium(
bluetooth_classic_medium_ = medium;
}
void BluetoothAdapter::SetBleMedium(api::BleMedium* medium) {
ble_medium_ = medium;
}
void BluetoothAdapter::SetBleV2Medium(api::ble_v2::BleMedium* medium) {
ble_v2_medium_ = medium;
}
@@ -21,7 +21,6 @@
#include "absl/base/thread_annotations.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/bluetooth_classic.h"
@@ -33,28 +32,6 @@ namespace g3 {
// BluetoothDevice and BluetoothAdapter have a mutual dependency.
class BluetoothAdapter;
// Opaque wrapper over a Ble peripheral. Must contain enough data about a
// particular Ble device to connect to its GATT server.
class BlePeripheral : public api::BlePeripheral {
public:
~BlePeripheral() override = default;
std::string GetName() const override;
ByteArray GetAdvertisementBytes(const std::string& service_id) const override;
void SetAdvertisementBytes(const std::string& service_id,
const ByteArray& advertisement_bytes);
BluetoothAdapter& GetAdapter() { return adapter_; }
private:
// Only BluetoothAdapter may instantiate BlePeripheral.
friend class BluetoothAdapter;
explicit BlePeripheral(BluetoothAdapter* adapter);
BluetoothAdapter& adapter_;
ByteArray advertisement_bytes_;
};
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html.
class BluetoothDevice : public api::BluetoothDevice {
public:
@@ -121,11 +98,6 @@ class BluetoothAdapter : public api::BluetoothAdapter {
return bluetooth_classic_medium_;
}
BlePeripheral& GetPeripheral() { return peripheral_; }
void SetBleMedium(api::BleMedium* medium);
api::BleMedium* GetBleMedium() { return ble_medium_; }
void SetBleV2Medium(api::ble_v2::BleMedium* medium);
api::ble_v2::BleMedium* GetBleV2Medium() { return ble_v2_medium_; }
@@ -138,9 +110,7 @@ class BluetoothAdapter : public api::BluetoothAdapter {
private:
mutable absl::Mutex mutex_;
BluetoothDevice device_{this};
BlePeripheral peripheral_{this};
api::BluetoothClassicMedium* bluetooth_classic_medium_ = nullptr;
api::BleMedium* ble_medium_ = nullptr;
api::ble_v2::BleMedium* ble_v2_medium_ = nullptr;
MacAddress mac_address_;
ScanMode mode_ ABSL_GUARDED_BY(mutex_) = ScanMode::kNone;
@@ -29,7 +29,6 @@
#include "internal/platform/implementation/atomic_boolean.h"
#include "internal/platform/implementation/atomic_reference.h"
#include "internal/platform/implementation/awdl.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/bluetooth_classic.h"
@@ -62,7 +61,6 @@
#endif
#include "internal/platform/implementation/g3/atomic_boolean.h"
#include "internal/platform/implementation/g3/atomic_reference.h"
#include "internal/platform/implementation/g3/ble.h"
#include "internal/platform/implementation/g3/ble_v2.h"
#include "internal/platform/implementation/g3/bluetooth_adapter.h"
#include "internal/platform/implementation/g3/bluetooth_classic.h"
@@ -187,11 +185,6 @@ ImplementationPlatform::CreateBluetoothClassicMedium(
return std::make_unique<g3::BluetoothClassicMedium>(adapter);
}
std::unique_ptr<BleMedium> ImplementationPlatform::CreateBleMedium(
api::BluetoothAdapter& adapter) {
return std::make_unique<g3::BleMedium>(adapter);
}
std::unique_ptr<api::ble_v2::BleMedium>
ImplementationPlatform::CreateBleV2Medium(api::BluetoothAdapter& adapter) {
return std::make_unique<g3::BleV2Medium>(
+1 -3
View File
@@ -21,10 +21,9 @@
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/awdl.h"
#include "internal/platform/implementation/atomic_boolean.h"
#include "internal/platform/implementation/atomic_reference.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/awdl.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/bluetooth_classic.h"
@@ -131,7 +130,6 @@ class ImplementationPlatform {
static std::unique_ptr<BluetoothAdapter> CreateBluetoothAdapter();
static std::unique_ptr<BluetoothClassicMedium> CreateBluetoothClassicMedium(
BluetoothAdapter&);
static std::unique_ptr<BleMedium> CreateBleMedium(BluetoothAdapter&);
static std::unique_ptr<api::ble_v2::BleMedium> CreateBleV2Medium(
api::BluetoothAdapter&);
static std::unique_ptr<api::CredentialStorage> CreateCredentialStorage();
@@ -101,12 +101,8 @@ cc_library(
cc_library(
name = "comm",
hdrs = [
"ble.h",
"ble_gatt_client.h",
"ble_gatt_server.h",
"ble_medium.h",
"ble_peripheral.h",
"ble_socket.h",
"ble_v2.h",
"ble_v2_server_socket.h",
"ble_v2_socket.h",
@@ -208,8 +204,6 @@ cc_library(
srcs = [
"ble_gatt_client.cc",
"ble_gatt_server.cc",
"ble_medium.cc",
"ble_socket.cc",
"ble_v2.cc",
"ble_v2_server_socket.cc",
"ble_v2_socket.cc",
@@ -341,7 +335,6 @@ cc_test(
"atomic_boolean_test.cc",
"atomic_reference_test.cc",
"ble_gatt_server_test.cc",
"ble_medium_test.cc",
"ble_v2_test.cc",
"bluetooth_adapter_test.cc",
"count_down_latch_test.cc",
@@ -1,22 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PLATFORM_IMPL_WINDOWS_BLE_H_
#define PLATFORM_IMPL_WINDOWS_BLE_H_
#include "internal/platform/implementation/windows/ble_peripheral.h"
#include "internal/platform/implementation/windows/ble_medium.h"
#include "internal/platform/implementation/windows/ble_socket.h"
#endif // PLATFORM_IMPL_WINDOWS_BLE_H_
@@ -1,651 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/implementation/windows/ble_medium.h"
#include <chrono> // NOLINT
#include <cstdint>
#include <exception>
#include <future> // NOLINT
#include <list>
#include <memory>
#include <string>
#include <utility>
#include "absl/strings/escaping.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/feature_flags.h"
#include "internal/platform/mac_address.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/ble_peripheral.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
#include "internal/platform/logging.h"
#include "winrt/Windows.Devices.Bluetooth.Advertisement.h"
#include "winrt/Windows.Devices.Bluetooth.h"
#include "winrt/Windows.Foundation.Collections.h"
#include "winrt/Windows.Storage.Streams.h"
#include "winrt/base.h"
namespace nearby {
namespace windows {
namespace {
// Specifies common Bluetooth error cases.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetootherror?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::BluetoothError;
// Represents a Bluetooth LE advertisement payload.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisement?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisement;
// Represents a Bluetooth LE advertisement section. A Bluetooth LE advertisement
// packet can contain multiple instances of these
// BluetoothLEAdvertisementDataSection objects.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementdatasection?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementDataSection;
// Represents the Bluetooth LE advertisement types defined in the Generic Access
// Profile (GAP) by the Bluetooth Special Interest Group (SIG).
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementdatatypes?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementDataTypes;
// Represents an object to send Bluetooth Low Energy (LE) advertisements.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementpublisher?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementPublisher;
// Represents the possible states of the BluetoothLEAdvertisementPublisher.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementpublisherstatus?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementPublisherStatus;
// Provides data for a StatusChanged event on a
// BluetoothLEAdvertisementPublisher.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementpublisherstatuschangedeventargs?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementPublisherStatusChangedEventArgs;
// BluetoothLEAdvertisement
// https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisement?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisement;
// Provides data for a Received event on a BluetoothLEAdvertisementWatcher. A
// BluetoothLEAdvertisementReceivedEventArgs instance is created when the
// Received event occurs on a BluetoothLEAdvertisementWatcher object.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementreceivedeventargs?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementReceivedEventArgs;
// Represents an object to receive Bluetooth Low Energy (LE) advertisements.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcher?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcher;
// Represents the possible states of the BluetoothLEAdvertisementWatcher.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcherstatus?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcherStatus;
// Provides data for a Stopped event on a BluetoothLEAdvertisementWatcher. A
// BluetoothLEAdvertisementWatcherStoppedEventArgs instance is created when the
// Stopped event occurs on a BluetoothLEAdvertisementWatcher object.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothleadvertisementwatcherstoppedeventargs?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcherStoppedEventArgs;
// Defines constants that specify a Bluetooth LE scanning mode.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.advertisement.bluetoothlescanningmode?view=winrt-22621
using ::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEScanningMode;
// Reads data from an input stream.
// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-22621
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-22621
using ::winrt::Windows::Storage::Streams::DataWriter;
// Represents a time interval as a signed 64-bit integer value.
// https://docs.microsoft.com/en-us/uwp/api/windows.foundation.timespan?view=winrt-22621
using ::winrt::Windows::Foundation::TimeSpan;
template <typename T>
using IVector = winrt::Windows::Foundation::Collections::IVector<T>;
// Copresence Service UUID 0xfef3 (little-endian)
constexpr uint16_t kCopresenceServiceUuid = 0xf3fe;
bool IsFastPairScanner() {
return FeatureFlags::GetInstance()
.GetFlags()
.enable_scan_for_fast_pair_advertisement;
}
} // namespace
BleMedium::BleMedium(api::BluetoothAdapter& adapter)
: adapter_(static_cast<BluetoothAdapter*>(&adapter)) {}
bool BleMedium::StartAdvertising(
const std::string& service_id, const ByteArray& advertisement_bytes,
const std::string& fast_advertisement_service_uuid) {
try {
if (!adapter_->IsEnabled()) {
LOG(WARNING) << "BLE cannot start advertising because the "
"bluetooth adapter is not enabled.";
return false;
}
LOG(INFO) << "Windows Ble StartAdvertising: service_id=" << service_id
<< ", advertisement bytes= 0x"
<< absl::BytesToHexString(advertisement_bytes.AsStringView())
<< "(" << advertisement_bytes.size() << "),"
<< " fast advertisement service uuid= 0x"
<< absl::BytesToHexString(fast_advertisement_service_uuid);
if (is_publisher_started_) {
LOG(WARNING) << "BLE cannot start to advertise again when it is running.";
return false;
}
DataWriter data_writer;
// TODO(b/234229562): Add parsing logic for fast_advertisement_service_uuid
// and insert into the 0x16 Service Data field in the BLE advertisement when
// Fast Advertisement is enabled. For Extended Advertising, use the same
// hardcoded Copresence service uuid 0xFEF3.
// Copresence Service UUID 0xfef3 (little-endian)
data_writer.WriteUInt16(kCopresenceServiceUuid);
for (int i = 0; i < advertisement_bytes.size(); ++i) {
data_writer.WriteByte(
static_cast<uint8_t>(*(advertisement_bytes.data() + i)));
}
BluetoothLEAdvertisementDataSection service_data =
BluetoothLEAdvertisementDataSection(0x16, data_writer.DetachBuffer());
BluetoothLEAdvertisement advertisement;
IVector<BluetoothLEAdvertisementDataSection> data_sections =
advertisement.DataSections();
data_sections.Append(service_data);
advertisement.DataSections() = data_sections;
// Use Extended Advertising if Fast Advertisement Service Uuid is empty
// string because the long format advertisement will be used
if (adapter_->IsExtendedAdvertisingSupported() &&
fast_advertisement_service_uuid.empty()) {
publisher_ = BluetoothLEAdvertisementPublisher(advertisement);
publisher_.UseExtendedAdvertisement(true);
} else {
// Extended Advertisement not supported, must make sure
// advertisement_bytes is less than 27 bytes
if (advertisement_bytes.size() <= 27) {
publisher_ = BluetoothLEAdvertisementPublisher(advertisement);
publisher_.UseExtendedAdvertisement(false);
} else {
// otherwise no-op
LOG(INFO) << "Everyone Mode unavailable for hardware that does "
"not support Extended Advertising.";
publisher_ = nullptr;
return false;
}
}
publisher_token_ =
publisher_.StatusChanged({this, &BleMedium::PublisherHandler});
publisher_.Start();
is_publisher_started_ = true;
LOG(INFO) << "Windows Ble StartAdvertising started.";
return true;
} catch (std::exception exception) {
LOG(ERROR) << __func__
<< ": Exception to start BLE advertising: " << exception.what();
return false;
} catch (const winrt::hresult_error& ex) {
LOG(ERROR) << __func__
<< ": Exception to start BLE advertising: " << ex.code() << ": "
<< winrt::to_string(ex.message());
return false;
} catch (...) {
LOG(ERROR) << __func__ << ": Unknown exception.";
return false;
}
}
bool BleMedium::StopAdvertising(const std::string& service_id) {
try {
if (!adapter_->IsEnabled()) {
LOG(WARNING) << "BLE cannot stop advertising because the "
"bluetooth adapter is not enabled.";
return false;
}
LOG(INFO) << "Windows Ble StopAdvertising: service_id=" << service_id;
if (!is_publisher_started_) {
LOG(WARNING) << "BLE advertising is not running.";
return false;
}
// publisher_ may be null when status changed during advertising.
if (publisher_ != nullptr &&
publisher_.Status() ==
BluetoothLEAdvertisementPublisherStatus::Started) {
publisher_.Stop();
}
// Don't need to wait for the status becomes to `Stopped`. If application
// starts to scanning immediately, the scanning still needs to wait the
// stopping to finish.
is_publisher_started_ = false;
return true;
} catch (std::exception exception) {
LOG(ERROR) << __func__
<< ": Exception to stop BLE advertising: " << exception.what();
return false;
} catch (const winrt::hresult_error& ex) {
LOG(ERROR) << __func__
<< ": Exception to stop BLE advertising: " << ex.code() << ": "
<< winrt::to_string(ex.message());
return false;
} catch (...) {
LOG(ERROR) << __func__ << ": Unknown exception.";
return false;
}
}
bool BleMedium::StartScanning(
const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
DiscoveredPeripheralCallback callback) {
try {
if (!adapter_->IsEnabled()) {
LOG(WARNING) << "BLE cannot start scanning because the "
"bluetooth adapter is not enabled.";
return false;
}
LOG(INFO) << "Windows Ble StartScanning: service_id=" << service_id;
if (is_watcher_started_) {
LOG(WARNING) << "BLE cannot start to scan again when it is running.";
return false;
}
service_id_ = service_id;
advertisement_received_callback_ = std::move(callback);
{
absl::MutexLock lock(&peripheral_map_mutex_);
peripheral_map_.clear();
lost_peripherals_.clear();
}
watcher_ = BluetoothLEAdvertisementWatcher();
watcher_token_ = watcher_.Stopped({this, &BleMedium::WatcherHandler});
advertisement_received_token_ =
watcher_.Received({this, &BleMedium::AdvertisementReceivedHandler});
if (adapter_->IsExtendedAdvertisingSupported()) {
watcher_.AllowExtendedAdvertisements(true);
}
// Active mode indicates that scan request packets will be sent to query
// for Scan Response
watcher_.ScanningMode(BluetoothLEScanningMode::Active);
::winrt::Windows::Devices::Bluetooth::BluetoothSignalStrengthFilter filter;
filter.SamplingInterval(TimeSpan(std::chrono::seconds(2)));
watcher_.SignalStrengthFilter(filter);
watcher_.Start();
is_watcher_started_ = true;
LOG(INFO) << "Windows Ble StartScanning started.";
return true;
} catch (std::exception exception) {
LOG(ERROR) << __func__
<< ": Exception to start BLE scanning: " << exception.what();
return false;
} catch (const winrt::hresult_error& ex) {
LOG(ERROR) << __func__ << ": Exception to start BLE scanning: " << ex.code()
<< ": " << winrt::to_string(ex.message());
return false;
} catch (...) {
LOG(ERROR) << __func__ << ": Unknown exception.";
return false;
}
}
bool BleMedium::StopScanning(const std::string& service_id) {
try {
if (!adapter_->IsEnabled()) {
LOG(WARNING) << "BLE cannot stop scanning because the "
"bluetooth adapter is not enabled.";
return false;
}
LOG(INFO) << "Windows Ble StopScanning: service_id=" << service_id;
if (!is_watcher_started_) {
LOG(WARNING) << "BLE scanning is not running.";
return false;
}
watcher_.Stop();
// Don't need to wait for the status becomes to `Stopped`. If application
// starts to scanning immediately, the scanning still needs to wait the
// stopping to finish.
is_watcher_started_ = false;
LOG(ERROR) << "Windows Ble stoped scanning successfully for service_id="
<< service_id;
return true;
} catch (std::exception exception) {
LOG(ERROR) << __func__
<< ": Exception to stop BLE scanning: " << exception.what();
return false;
} catch (const winrt::hresult_error& ex) {
LOG(ERROR) << __func__ << ": Exception to stop BLE scanning: " << ex.code()
<< ": " << winrt::to_string(ex.message());
return false;
} catch (...) {
LOG(ERROR) << __func__ << ": Unknown exception.";
return false;
}
}
bool BleMedium::StartAcceptingConnections(const std::string& service_id,
AcceptedConnectionCallback callback) {
LOG(INFO) << "Windows Ble StartAcceptingConnections: service_id="
<< service_id;
return true;
}
bool BleMedium::StopAcceptingConnections(const std::string& service_id) {
LOG(INFO) << "Windows Ble StopAcceptingConnections: service_id="
<< service_id;
return true;
}
std::unique_ptr<api::BleSocket> BleMedium::Connect(
api::BlePeripheral& remote_peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag) {
if (cancellation_flag->Cancelled()) {
LOG(ERROR) << "Windows BLE Connect: Has been cancelled: "
"service_id="
<< service_id;
return {};
}
LOG(ERROR) << "Windows Ble Connect: Cannot connect over BLE socket. "
"service_id="
<< service_id;
return {};
}
void BleMedium::PublisherHandler(
BluetoothLEAdvertisementPublisher publisher,
BluetoothLEAdvertisementPublisherStatusChangedEventArgs args) {
// This method is called when publisher's status is changed.
switch (args.Status()) {
case BluetoothLEAdvertisementPublisherStatus::Created:
LOG(INFO) << "Nearby BLE Medium created to advertise.";
return;
case BluetoothLEAdvertisementPublisherStatus::Started:
LOG(INFO) << "Nearby BLE Medium started to advertise.";
return;
case BluetoothLEAdvertisementPublisherStatus::Stopping:
LOG(INFO) << "Nearby BLE Medium is stopping.";
return;
case BluetoothLEAdvertisementPublisherStatus::Waiting:
LOG(INFO) << "Nearby BLE Medium is waiting.";
return;
case BluetoothLEAdvertisementPublisherStatus::Stopped:
LOG(INFO) << "Nearby BLE Medium stopped to advertise.";
break;
case BluetoothLEAdvertisementPublisherStatus::Aborted:
switch (args.Error()) {
case BluetoothError::Success:
if (publisher_.Status() ==
BluetoothLEAdvertisementPublisherStatus::Started) {
LOG(ERROR) << "Nearby BLE Medium start advertising operation was "
"successfully completed or serviced.";
}
if (publisher_.Status() ==
BluetoothLEAdvertisementPublisherStatus::Stopped) {
LOG(ERROR) << "Nearby BLE Medium stop advertising operation was "
"successfully completed or serviced.";
} else {
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"unknown errors.";
}
break;
case BluetoothError::RadioNotAvailable:
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"radio not available.";
break;
case BluetoothError::ResourceInUse:
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"resource in use.";
break;
case BluetoothError::DeviceNotConnected:
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"remote device is not connected.";
break;
case BluetoothError::DisabledByPolicy:
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"disabled by policy.";
break;
case BluetoothError::DisabledByUser:
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"disabled by user.";
break;
case BluetoothError::NotSupported:
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"hardware not supported.";
break;
case BluetoothError::TransportNotSupported:
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"transport not supported.";
break;
case BluetoothError::ConsentRequired:
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"consent required.";
break;
case BluetoothError::OtherError:
default:
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"unknown errors.";
break;
}
break;
default:
break;
}
// The publisher is stopped. Clean up the running publisher
if (publisher_ != nullptr) {
LOG(ERROR) << "Nearby BLE Medium cleaned the publisher.";
publisher_.StatusChanged(publisher_token_);
publisher_ = nullptr;
is_publisher_started_ = false;
}
}
void BleMedium::WatcherHandler(
BluetoothLEAdvertisementWatcher watcher,
BluetoothLEAdvertisementWatcherStoppedEventArgs args) {
// This method is called when watcher stopped. Args give more detailed
// information on the reason.
switch (args.Error()) {
case BluetoothError::Success:
LOG(ERROR) << "Nearby BLE Medium stoped to scan successfully.";
break;
case BluetoothError::RadioNotAvailable:
LOG(ERROR)
<< "Nearby BLE Medium stoped to scan due to radio not available.";
break;
case BluetoothError::ResourceInUse:
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to resource in use.";
break;
case BluetoothError::DeviceNotConnected:
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to "
"remote device is not connected.";
break;
case BluetoothError::DisabledByPolicy:
LOG(ERROR)
<< "Nearby BLE Medium stoped to scan due to disabled by policy.";
break;
case BluetoothError::DisabledByUser:
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to disabled by user.";
break;
case BluetoothError::NotSupported:
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to "
"hardware not supported.";
break;
case BluetoothError::TransportNotSupported:
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to "
"transport not supported.";
break;
case BluetoothError::ConsentRequired:
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to consent required.";
break;
case BluetoothError::OtherError:
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to unknown errors.";
break;
default:
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to unknown errors.";
break;
}
// No matter the reason, I should clean up the watcher if it is not empty.
// The BLE V1 interface doesn't have an API to return the error to the upper
// layer.
if (watcher_ != nullptr) {
LOG(ERROR) << "Nearby BLE Medium cleaned the watcher.";
watcher_.Stopped(watcher_token_);
watcher_.Received(advertisement_received_token_);
watcher_ = nullptr;
is_watcher_started_ = false;
}
}
void BleMedium::AdvertisementReceivedHandler(
BluetoothLEAdvertisementWatcher watcher,
BluetoothLEAdvertisementReceivedEventArgs args) {
// Handle all BLE advertisements and determine whether the BLE Medium
// Advertisement Scan Response packet (containing Copresence UUID 0xFEF3 in
// 0x16 Service Data) has been received in the handler
BluetoothLEAdvertisement advertisement = args.Advertisement();
for (BluetoothLEAdvertisementDataSection service_data :
advertisement.GetSectionsByType(0x16)) {
// Parse Advertisement Data for Section 0x16 (Service Data)
DataReader data_reader = DataReader::FromBuffer(service_data.Data());
// Discard the first 2 bytes of Service Uuid in Service Data
uint8_t first_byte = data_reader.ReadByte();
uint8_t second_byte = data_reader.ReadByte();
if ((IsFastPairScanner() && first_byte == 0x2c && second_byte == 0xfe) ||
(!IsFastPairScanner() && first_byte == 0xf3 && second_byte == 0xfe)) {
std::string data;
uint8_t unconsumed_buffer_length = data_reader.UnconsumedBufferLength();
for (int i = 0; i < unconsumed_buffer_length; i++) {
data.append(1, static_cast<unsigned char>(data_reader.ReadByte()));
}
ByteArray advertisement_data(data);
VLOG(1) << "Nearby BLE Medium Advertisement discovered. "
"0x16 Service data: advertisement bytes= 0x"
<< absl::BytesToHexString(advertisement_data.AsStringView())
<< "(" << advertisement_data.size() << ")";
MacAddress mac_address;
MacAddress::FromUint64(args.BluetoothAddress(), mac_address);
std::string peripheral_name = mac_address.ToString();
BlePeripheral* peripheral_ptr = nullptr;
{
absl::MutexLock lock(&peripheral_map_mutex_);
if (peripheral_map_.contains(peripheral_name)) {
if (peripheral_map_[peripheral_name]->GetAdvertisementBytes(
service_id_) != advertisement_data) {
LOG(INFO) << "BLE reports lost device: " << peripheral_name;
// Lost the device first and then the report discovered the
// device.
advertisement_received_callback_.peripheral_lost_cb(
/*ble_peripheral*/ *peripheral_map_[peripheral_name],
/*service_id*/ service_id_);
// put the lost peripheral in the lost peripheral list.
lost_peripherals_.push_back(
std::move(peripheral_map_[peripheral_name]));
} else {
// The device is already reported to discover, so don't need to
// call it again.
return;
}
}
auto peripheral = std::make_unique<BlePeripheral>();
peripheral->SetName(peripheral_name);
peripheral->SetAdvertisementBytes(advertisement_data);
peripheral_map_[peripheral_name] = std::move(peripheral);
peripheral_ptr = peripheral_map_[peripheral_name].get();
}
// Received Fast Advertisement packet
if (unconsumed_buffer_length <= 27) {
LOG(INFO) << "Sending Fast Advertisement packet for processing.";
advertisement_received_callback_.peripheral_discovered_cb(
/*ble_peripheral*/ *peripheral_ptr, /*service_id*/ service_id_,
/*is_fast_advertisement*/ true);
} else {
// Received Extended Advertising packet
LOG(INFO) << "Sending Extended Advertising packet for processing.";
advertisement_received_callback_.peripheral_discovered_cb(
/*ble_peripheral*/ *peripheral_ptr, /*service_id*/ service_id_,
/*is_fast_advertisement*/ false);
}
}
}
}
} // namespace windows
} // namespace nearby
@@ -1,129 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_MEDIUM_H_
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_MEDIUM_H_
#include <guiddef.h>
#include <future> // NOLINT
#include <list>
#include <memory>
#include <string>
#include <utility>
#include "absl/container/flat_hash_map.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/ble.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
#include "winrt/Windows.Devices.Bluetooth.Advertisement.h"
namespace nearby {
namespace windows {
// Only Fast Advertisement is supported where the remote device's static
// bluetooth MAC address is resolved from Nearby Share Contact certificates
// using salt and encrypted_metadata_key from the BLE advertisement packet.
// The MAC address is then used directly to establish a Bluetooth Classic
// RFCOMM socket.
// Container of operations that can be performed over the BLE medium.
class BleMedium : public api::BleMedium {
public:
explicit BleMedium(api::BluetoothAdapter& adapter);
~BleMedium() override = default;
bool StartAdvertising(
const std::string& service_id, const ByteArray& advertisement_bytes,
const std::string& fast_advertisement_service_uuid) override;
bool StopAdvertising(const std::string& service_id) override;
// Returns true once the BLE scan has been initiated.
bool StartScanning(const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
DiscoveredPeripheralCallback callback) override;
// Returns true once BLE scanning for service_id is well and truly stopped;
// after this returns, there must be no more invocations of the
// DiscoveredPeripheralCallback passed in to StartScanning() for service_id.
bool StopScanning(const std::string& service_id) override;
// Returns true once BLE socket connection requests to service_id can be
// accepted.
bool StartAcceptingConnections(const std::string& service_id,
AcceptedConnectionCallback callback) override;
bool StopAcceptingConnections(const std::string& service_id) override;
// Connects to a BLE peripheral.
// On success, returns a new BleSocket.
// On error, returns nullptr.
std::unique_ptr<api::BleSocket> Connect(api::BlePeripheral& peripheral,
const std::string& service_id,
CancellationFlag* cancellation_flag);
private:
void PublisherHandler(
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementPublisher publisher,
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementPublisherStatusChangedEventArgs args);
void AdvertisementReceivedHandler(
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcher watcher,
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementReceivedEventArgs args);
void WatcherHandler(::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcher watcher,
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcherStoppedEventArgs args);
BluetoothAdapter* adapter_;
std::string service_id_;
DiscoveredPeripheralCallback advertisement_received_callback_;
// Map to protect the pointer for BlePeripheral because
// DiscoveredPeripheralCallback only keeps the pointer to the object
absl::Mutex peripheral_map_mutex_;
absl::flat_hash_map<std::string, std::unique_ptr<BlePeripheral>>
peripheral_map_ ABSL_GUARDED_BY(peripheral_map_mutex_);
// The platform implementation will reference lost peripheral in another
// thread after report loss, so we still need to keep the peripheral to
// avoid potential memory issues.
std::list<std::unique_ptr<BlePeripheral>> lost_peripherals_
ABSL_GUARDED_BY(peripheral_map_mutex_);
// WinRT objects
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementPublisher publisher_ = nullptr;
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcher watcher_ = nullptr;
bool is_publisher_started_ = false;
bool is_watcher_started_ = false;
::winrt::event_token publisher_token_;
::winrt::event_token watcher_token_;
::winrt::event_token advertisement_received_token_;
};
} // namespace windows
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_MEDIUM_H_
@@ -1,302 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/implementation/windows/ble_medium.h"
#include <array>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/synchronization/notification.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/ble.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
namespace nearby {
namespace windows {
namespace {
constexpr uint8_t kVersionBitmask = 0xE0;
constexpr uint8_t kSocketVersionBitmask = 0x1C;
constexpr uint8_t kFastAdvertisementFlagBitmask = 0x02;
constexpr uint8_t kPcpBitmask = 0x1F;
constexpr uint8_t kVisibilityBitmask = 0x01;
TEST(BleMedium, DISABLED_StartAdvertising_FastAdvertisement) {
BluetoothAdapter bluetoothAdapter;
BleMedium ble_medium(bluetoothAdapter);
std::array<char, 27> advertising_data_byte_array;
// (1 byte) version [3-bits] + socket_version [3-bits] +
// fast_advertisement_flag [1-bit] + reserved [1-bit]
uint8_t ble_medium_version = 0x02; // mediums::BleAdvertisement::Version::kV2
uint8_t socket_version =
0x02; // mediums::BleAdvertisement::SocketVersion::kV2
bool fast_advertisement = true; // Is Fast Advertisement
uint8_t ble_medium_advertisement_metadata_byte =
(ble_medium_version << 5) & kVersionBitmask;
ble_medium_advertisement_metadata_byte |=
(socket_version << 2) & kSocketVersionBitmask;
ble_medium_advertisement_metadata_byte |=
((fast_advertisement ? 1 : 0) << 1) & kFastAdvertisementFlagBitmask;
advertising_data_byte_array.at(0) =
static_cast<unsigned char>(ble_medium_advertisement_metadata_byte);
// (1 byte) body_length
advertising_data_byte_array.at(1) = static_cast<unsigned char>(
0x17); // always 23 bytes for Fast Advertisement
// (1 byte) Nearby Connection version [3-bits] + pcp [5-bits]
uint8_t ble_connections_version =
0x01; // connections::BleAdvertisement::Version::kV1
uint8_t pcp = 0x02; // connections::Pcp::kP2pCluster
uint8_t ble_connections_advertisement_metadata_byte =
(ble_connections_version << 5) & kVersionBitmask;
ble_connections_advertisement_metadata_byte |= pcp & kPcpBitmask;
advertising_data_byte_array.at(2) =
static_cast<unsigned char>(ble_connections_advertisement_metadata_byte);
// (4 bytes) endpoint_id
for (int i = 0; i < 4; ++i) {
advertising_data_byte_array.at(3 + i) = static_cast<unsigned char>(0x00);
}
// (1 byte) endpoint_info_size
advertising_data_byte_array.at(7) = static_cast<unsigned char>(
0x11); // always 17-bytes for Fast Advertisement
// =========endpoint_info [17-bytes]============
// (1 byte) Nearby Share version [3-bits] + visibility [1-bit] + reserved
// [4-bits]
uint8_t nearby_share_version = 0x00; // nearby share v1
uint8_t visibility = 0x00; // [placeholder] sharing::Visibility::kAllContacts
uint8_t nearby_share_metadata_byte =
(nearby_share_version << 5) & kVersionBitmask;
nearby_share_metadata_byte |= ((visibility & kVisibilityBitmask) << 4);
advertising_data_byte_array.at(8) = static_cast<unsigned char>(0x00);
// (2 bytes) salt
for (int i = 0; i < 2; ++i) {
advertising_data_byte_array.at(9 + i) = static_cast<unsigned char>(0x00);
}
// (14 bytes) encrypted_metadata_key
for (int i = 0; i < 14; ++i) {
advertising_data_byte_array.at(11 + i) = static_cast<unsigned char>(0x00);
}
// =========endpoint_info [17-bytes]============
// (2 bytes) device_token
for (int i = 0; i < 2; ++i) {
advertising_data_byte_array.at(25 + i) = static_cast<unsigned char>(0x00);
}
ByteArray advertising_data(advertising_data_byte_array);
EXPECT_TRUE(
ble_medium.StartAdvertising("NearbyShare", advertising_data, "\xfe\xf3"));
}
TEST(BleMedium, DISABLED_StartAdvertising_ExtendedAdvertising) {
BluetoothAdapter bluetoothAdapter;
BleMedium ble_medium(bluetoothAdapter);
std::array<char, 167> advertising_data_byte_array;
// (1 byte) version [3-bits] + socket_version [3-bits] +
// fast_advertisement_flag [1-bit] + reserved [1-bit]
uint8_t ble_medium_version = 0x02; // mediums::BleAdvertisement::Version::kV2
uint8_t socket_version =
0x02; // mediums::BleAdvertisement::SocketVersion::kV2
bool fast_advertisement = false; // Is Fast Advertisement
uint8_t ble_medium_advertisement_metadata_byte =
(ble_medium_version << 5) & kVersionBitmask;
ble_medium_advertisement_metadata_byte |=
(socket_version << 2) & kSocketVersionBitmask;
ble_medium_advertisement_metadata_byte |=
((fast_advertisement ? 1 : 0) << 1) & kFastAdvertisementFlagBitmask;
advertising_data_byte_array.at(0) =
static_cast<unsigned char>(ble_medium_advertisement_metadata_byte);
// (3 bytes) service_id_hash
for (int i = 0; i < 3; ++i) {
advertising_data_byte_array.at(1 + i) = static_cast<unsigned char>(0x00);
}
// (4 bytes) body_length
advertising_data_byte_array.at(7) = static_cast<unsigned char>(
0x9C); // max 156 bytes for Extended Advertising
// (1 byte) Nearby Connection version [3-bits] + pcp [5-bits]
uint8_t ble_connections_version =
0x01; // connections::BleAdvertisement::Version::kV1
uint8_t pcp = 0x02; // connections::Pcp::kP2pCluster
uint8_t ble_connections_advertisement_metadata_byte =
(ble_connections_version << 5) & kVersionBitmask;
ble_connections_advertisement_metadata_byte |= pcp & kPcpBitmask;
advertising_data_byte_array.at(8) =
static_cast<unsigned char>(ble_connections_advertisement_metadata_byte);
// (3 bytes) service_id_hash
for (int i = 0; i < 3; ++i) {
advertising_data_byte_array.at(9 + i) = static_cast<unsigned char>(0x00);
}
// (4 bytes) endpoint_id
for (int i = 0; i < 4; ++i) {
advertising_data_byte_array.at(12 + i) = static_cast<unsigned char>(0x00);
}
// (1 byte) endpoint_info_size
advertising_data_byte_array.at(16) = static_cast<unsigned char>(
0x83); // max 131-bytes for Extended Advertising
// =========endpoint_info [Max 131-bytes]============
// (1 byte) Nearby Share version [3-bits] + visibility [1-bit] + reserved
// [4-bits]
uint8_t nearby_share_version = 0x00; // nearby share v1
uint8_t visibility = 0x00; // [placeholder] sharing::Visibility::kAllContacts
uint8_t nearby_share_metadata_byte =
(nearby_share_version << 5) & kVersionBitmask;
nearby_share_metadata_byte |= ((visibility & kVisibilityBitmask) << 4);
advertising_data_byte_array.at(17) = static_cast<unsigned char>(0x00);
// (2 bytes) salt
for (int i = 0; i < 2; ++i) {
advertising_data_byte_array.at(18 + i) = static_cast<unsigned char>(0x00);
}
// (14 bytes) encrypted_metadata_key
for (int i = 0; i < 14; ++i) {
advertising_data_byte_array.at(20 + i) = static_cast<unsigned char>(0x00);
}
// [optional]
// (1 byte) human_readable_name_size
advertising_data_byte_array.at(34) = static_cast<unsigned char>(0x72);
// [optional]
// (max 114 bytes) human_readable_name
for (int i = 0; i < 114; ++i) {
advertising_data_byte_array.at(35 + i) = static_cast<unsigned char>(0x00);
}
// =========endpoint_info [131-bytes]============
// (6 bytes) bluetooth_mac_address
for (int i = 0; i < 6; ++i) {
advertising_data_byte_array.at(149 + i) = static_cast<unsigned char>(0x00);
}
// (1 byte) uwb_address_size
advertising_data_byte_array.at(155) = static_cast<unsigned char>(0x72);
// (8 bytes) uwb_address
for (int i = 0; i < 6; ++i) {
advertising_data_byte_array.at(156 + i) = static_cast<unsigned char>(0x00);
}
// (1 byte) extra_field [web_rtc_connectable]
advertising_data_byte_array.at(164) = static_cast<unsigned char>(0x72);
// (2 bytes) device_token
for (int i = 0; i < 2; ++i) {
advertising_data_byte_array.at(165 + i) = static_cast<unsigned char>(0x00);
}
ByteArray advertising_data(advertising_data_byte_array);
EXPECT_TRUE(ble_medium.StartAdvertising("NearbyShare", advertising_data, ""));
}
TEST(BleMedium, DISABLED_StopAdvertising) {
BluetoothAdapter bluetoothAdapter;
BleMedium ble_medium(bluetoothAdapter);
std::array<char, 2> advertising_data_byte_array;
// (2 bytes) 16-bit Service UUID 0xf3fe
advertising_data_byte_array.at(0) = static_cast<unsigned char>(0xf3);
advertising_data_byte_array.at(1) = static_cast<unsigned char>(0xfe);
ByteArray advertising_data(advertising_data_byte_array);
EXPECT_TRUE(
ble_medium.StartAdvertising("NearbyShare", advertising_data, "\xfe\xf3"));
EXPECT_TRUE(ble_medium.StopAdvertising("NearbyShare"));
}
TEST(BleMedium, DISABLED_StartScanning) {
BluetoothAdapter bluetoothAdapter;
BleMedium ble_medium(bluetoothAdapter);
EXPECT_TRUE(ble_medium.StartScanning(
"NearbyShare", "\xfe\xf3",
{.peripheral_discovered_cb = [](api::BlePeripheral& peripheral,
const std::string& service_id,
bool fast_advertisement) {},
.peripheral_lost_cb = [](api::BlePeripheral& peripheral,
const std::string& service_id) {}}));
}
TEST(BleMedium, DISABLED_ReceiveAdvertisement) {
absl::Notification advertisement_received_notification;
BluetoothAdapter bluetoothAdapter;
BleMedium ble_medium(bluetoothAdapter);
EXPECT_TRUE(ble_medium.StartScanning(
"NearbyShare", "\xfe\xf3",
{.peripheral_discovered_cb =
[&](api::BlePeripheral& peripheral, const std::string& service_id,
bool fast_advertisement) {
advertisement_received_notification.Notify();
},
.peripheral_lost_cb = [](api::BlePeripheral& peripheral,
const std::string& service_id) {}}));
EXPECT_TRUE(
advertisement_received_notification.WaitForNotificationWithTimeout(
absl::Seconds(5)));
}
TEST(BleMedium, DISABLED_StopScanning) {
BluetoothAdapter bluetoothAdapter;
BleMedium ble_medium(bluetoothAdapter);
EXPECT_TRUE(ble_medium.StartScanning(
"NearbyShare", "\xfe\xf3",
{.peripheral_discovered_cb =
[](api::BlePeripheral& peripheral, const std::string& service_id,
bool fast_advertisement) { EXPECT_TRUE(fast_advertisement); },
.peripheral_lost_cb = [](api::BlePeripheral& peripheral,
const std::string& service_id) {}}));
EXPECT_TRUE(ble_medium.StopScanning("NearbyShare"));
}
} // namespace
} // namespace windows
} // namespace nearby
@@ -1,60 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_PERIPHERAL_H_
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_PERIPHERAL_H_
#include <string>
#include "internal/platform/implementation/ble.h"
namespace nearby {
namespace windows {
// TODO(b/269152309): Implement BLE Peripheral
// This is just a fake stub to appease the BLE Medium abstraction. Windows
// does not support BLE GATT-based advertising/discovery and socket currently,
// so a BlePeripheral is not required. The remote device is recognized as a
// BluetoothClassicDevice instead.
// Opaque wrapper over a BLE peripheral. Must contain enough data about a
// particular BLE device to connect to its GATT server.
class BlePeripheral : public api::BlePeripheral {
public:
~BlePeripheral() override = default;
std::string GetName() const override { return name_; }
ByteArray GetAdvertisementBytes(
const std::string& service_id) const override {
return advertisement_data_;
}
void SetName(const std::string& name) {
name_ = name;
}
void SetAdvertisementBytes(ByteArray advertisement_bytes) {
advertisement_data_ = advertisement_bytes;
}
private:
std::string name_;
ByteArray advertisement_data_;
};
} // namespace windows
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_PERIPHERAL_H_
@@ -1,50 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/implementation/windows/ble_socket.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/windows/ble_peripheral.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
namespace nearby {
namespace windows {
InputStream& BleSocket::GetInputStream() {
return fake_input_stream_;
}
OutputStream& BleSocket::GetOutputStream() {
return fake_output_stream_;
}
bool BleSocket::IsClosed() const {
absl::MutexLock lock(&mutex_);
return closed_;
}
Exception BleSocket::Close() {
absl::MutexLock lock(&mutex_);
return {Exception::kSuccess};
}
BlePeripheral* BleSocket::GetRemotePeripheral() {
absl::MutexLock lock(&mutex_);
return peripheral_;
}
} // namespace windows
} // namespace nearby
@@ -1,81 +0,0 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_SOCKET_H_
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_SOCKET_H_
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/windows/ble.h"
#include "internal/platform/exception.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
namespace nearby {
namespace windows {
// TODO(b/269152309): Implement BLE Weave Socket
// This is just a fake stub to appease the BLE Medium abstraction. Windows
// does not support BLE Weave sockets currently. BLE is only used in the
// pre-connection phase handshake (advertising & discovering), connection is
// delegated to Bluetooth Classic Medium to establish RFCOMM socket.
class BleSocket : public api::BleSocket {
public:
~BleSocket() override;
// Returns the InputStream of this connected BleSocket.
InputStream& GetInputStream() override ABSL_LOCKS_EXCLUDED(mutex_);
// Returns the OutputStream of this connected BleSocket.
// This stream is for local side to write.
OutputStream& GetOutputStream() override ABSL_LOCKS_EXCLUDED(mutex_);
// Returns true if socket is closed.
bool IsClosed() const ABSL_LOCKS_EXCLUDED(mutex_);
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
Exception Close() override ABSL_LOCKS_EXCLUDED(mutex_);
// Returns valid BlePeripheral pointer if there is a connection, and
// nullptr otherwise.
BlePeripheral* GetRemotePeripheral() override ABSL_LOCKS_EXCLUDED(mutex_);
// Unhooked InputStream & OutputStream for empty implementation.
private:
class FakeInputStream : public InputStream {
~FakeInputStream() override = default;
ExceptionOr<ByteArray> Read(std::int64_t size) override {
return ExceptionOr<ByteArray>(Exception::kFailed);
}
Exception Close() override { return {.value = Exception::kFailed}; }
};
class FakeOutputStream : public OutputStream {
~FakeOutputStream() override = default;
Exception Write(const ByteArray& data) override {
return {.value = Exception::kFailed};
}
Exception Flush() override { return {.value = Exception::kFailed}; }
Exception Close() override { return {.value = Exception::kFailed}; }
};
FakeInputStream fake_input_stream_;
FakeOutputStream fake_output_stream_;
mutable absl::Mutex mutex_;
BlePeripheral* peripheral_;
bool closed_ ABSL_GUARDED_BY(mutex_) = false;
};
} // namespace windows
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_SOCKET_H_
@@ -41,7 +41,6 @@
#include "internal/platform/implementation/atomic_boolean.h"
#include "internal/platform/implementation/atomic_reference.h"
#include "internal/platform/implementation/awdl.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/bluetooth_classic.h"
@@ -60,7 +59,6 @@
#include "internal/platform/implementation/wifi_lan.h"
#include "internal/platform/implementation/windows/atomic_boolean.h"
#include "internal/platform/implementation/windows/atomic_reference.h"
#include "internal/platform/implementation/windows/ble_medium.h"
#include "internal/platform/implementation/windows/ble_v2.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/bluetooth_classic_medium.h"
@@ -257,11 +255,6 @@ ImplementationPlatform::CreateBluetoothClassicMedium(
return std::make_unique<windows::BluetoothClassicMedium>(adapter);
}
std::unique_ptr<BleMedium> ImplementationPlatform::CreateBleMedium(
BluetoothAdapter& adapter) {
return std::make_unique<windows::BleMedium>(adapter);
}
// TODO(b/184975123): replace with real implementation.
std::unique_ptr<api::ble_v2::BleMedium>
ImplementationPlatform::CreateBleV2Medium(api::BluetoothAdapter& adapter) {
-148
View File
@@ -33,7 +33,6 @@
#include "internal/platform/count_down_latch.h"
#include "internal/platform/feature_flags.h"
#include "internal/platform/implementation/awdl.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/bluetooth_classic.h"
@@ -88,7 +87,6 @@ void MediumEnvironment::Reset() {
LOG(INFO) << "MediumEnvironment::Reset()";
bluetooth_adapters_.clear();
bluetooth_mediums_.clear();
ble_mediums_.clear();
ble_v2_mediums_.clear();
#ifndef NO_WEBRTC
webrtc_signaling_message_callback_.clear();
@@ -267,28 +265,6 @@ api::ble_v2::BleMedium* MediumEnvironment::FindBleV2Medium(
return device;
}
void MediumEnvironment::OnBlePeripheralStateChanged(
BleMediumContext& info, api::BlePeripheral& peripheral,
const std::string& service_id, bool fast_advertisement, bool enabled) {
if (!enabled_) return;
LOG(INFO) << "OnBleServiceStateChanged [peripheral impl=" << &peripheral
<< "]; context=" << &info << "; service_id=" << service_id
<< "; notify=" << enable_notifications_.load();
if (!enable_notifications_) return;
if (enabled) {
RunOnMediumEnvironmentThread(
[&info, &peripheral, service_id, fast_advertisement]() {
LOG(INFO) << "[Run] OnBleServiceStateChanged [peripheral impl="
<< &peripheral << "]; context=" << &info
<< "; service_id=" << service_id;
info.discovery_callback.peripheral_discovered_cb(
peripheral, service_id, fast_advertisement);
});
} else {
info.discovery_callback.peripheral_lost_cb(peripheral, service_id);
}
}
void MediumEnvironment::OnBleV2PeripheralStateChanged(
bool enabled, BleV2MediumContext& context, const Uuid& service_id,
const api::ble_v2::BleAdvertisementData& ble_advertisement_data,
@@ -497,130 +473,6 @@ void MediumEnvironment::UnregisterBluetoothMedium(
latch.Await();
}
void MediumEnvironment::RegisterBleMedium(api::BleMedium& medium) {
if (!enabled_) return;
RunOnMediumEnvironmentThread([this, &medium]() {
ble_mediums_.insert({&medium, BleMediumContext{}});
LOG(INFO) << "Registered: BLE medium:" << &medium;
});
}
void MediumEnvironment::UpdateBleMediumForAdvertising(
api::BleMedium& medium, api::BlePeripheral& peripheral,
const std::string& service_id, bool fast_advertisement, bool enabled) {
if (!enabled_) return;
RunOnMediumEnvironmentThread(
[this, &medium, &peripheral, service_id, fast_advertisement, enabled]() {
auto item = ble_mediums_.find(&medium);
if (item == ble_mediums_.end()) {
LOG(INFO) << "UpdateBleMediumForAdvertising failed. There is no "
"medium registered.";
return;
}
auto& context = item->second;
context.ble_peripheral = &peripheral;
context.advertising = enabled;
context.fast_advertisement = fast_advertisement;
LOG(INFO) << "Update Ble medium for advertising: this=" << this
<< "; medium=" << &medium << "; service_id=" << service_id
<< "; name=" << peripheral.GetName()
<< "; fast_advertisement=" << fast_advertisement
<< "; enabled=" << enabled;
for (auto& medium_info : ble_mediums_) {
auto& local_medium = medium_info.first;
auto& info = medium_info.second;
// Do not send notification to the same medium.
if (local_medium == &medium) continue;
OnBlePeripheralStateChanged(info, peripheral, service_id,
fast_advertisement, enabled);
}
});
}
void MediumEnvironment::UpdateBleMediumForScanning(
api::BleMedium& medium, const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
BleDiscoveredPeripheralCallback callback, bool enabled) {
if (!enabled_) return;
RunOnMediumEnvironmentThread(
[this, &medium, service_id, fast_advertisement_service_uuid,
callback = std::move(callback), enabled]() mutable {
auto item = ble_mediums_.find(&medium);
if (item == ble_mediums_.end()) {
LOG(INFO) << "UpdateBleMediumFoScanning failed. There is no medium "
"registered.";
return;
}
auto& context = item->second;
context.discovery_callback = std::move(callback);
LOG(INFO) << "Update Ble medium for scanning: this=" << this
<< "; medium=" << &medium << "; service_id=" << service_id
<< "; fast_advertisement_service_uuid="
<< absl::BytesToHexString(fast_advertisement_service_uuid)
<< "; enabled=" << enabled;
for (auto& medium_info : ble_mediums_) {
auto& local_medium = medium_info.first;
auto& info = medium_info.second;
// Do not send notification to the same medium.
if (local_medium == &medium) continue;
// Search advertising mediums and send notification.
if (info.advertising && enabled) {
OnBlePeripheralStateChanged(context, *(info.ble_peripheral),
service_id, info.fast_advertisement,
enabled);
}
}
});
}
void MediumEnvironment::UpdateBleMediumForAcceptedConnection(
api::BleMedium& medium, const std::string& service_id,
BleAcceptedConnectionCallback callback) {
if (!enabled_) return;
RunOnMediumEnvironmentThread([this, &medium, service_id,
callback = std::move(callback)]() mutable {
auto item = ble_mediums_.find(&medium);
if (item == ble_mediums_.end()) {
LOG(INFO) << "Update Ble medium failed. There is no medium registered.";
return;
}
auto& context = item->second;
context.accepted_connection_callback = std::move(callback);
LOG(INFO) << "Update Ble medium for accepted callback: this=" << this
<< "; medium=" << &medium << "; service_id=" << service_id;
});
}
void MediumEnvironment::UnregisterBleMedium(api::BleMedium& medium) {
if (!enabled_) return;
CountDownLatch latch(1);
RunOnMediumEnvironmentThread([&]() {
auto item = ble_mediums_.extract(&medium);
latch.CountDown();
if (item.empty()) return;
LOG(INFO) << "Unregistered BLE medium:" << &medium;
});
latch.Await();
}
void MediumEnvironment::CallBleAcceptedConnectionCallback(
api::BleMedium& medium, api::BleSocket& socket,
const std::string& service_id) {
if (!enabled_) return;
RunOnMediumEnvironmentThread([this, &medium, &socket, service_id]() {
auto item = ble_mediums_.find(&medium);
if (item == ble_mediums_.end()) {
LOG(INFO) << "Call AcceptedConnectionCallback failed. There is no medium "
"registered.";
return;
}
auto& info = item->second;
if (info.accepted_connection_callback) {
info.accepted_connection_callback(socket, service_id);
}
});
}
void MediumEnvironment::RegisterBleV2Medium(
api::ble_v2::BleMedium& medium,
api::ble_v2::BlePeripheral::UniqueId peripheral_id) {
-59
View File
@@ -29,7 +29,6 @@
#include "internal/base/observer_list.h"
#include "internal/platform/borrowable.h"
#include "internal/platform/implementation/awdl.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/bluetooth_classic.h"
@@ -75,10 +74,6 @@ class MediumEnvironment {
public:
using BluetoothDiscoveryCallback =
api::BluetoothClassicMedium::DiscoveryCallback;
using BleDiscoveredPeripheralCallback =
api::BleMedium::DiscoveredPeripheralCallback;
using BleAcceptedConnectionCallback =
api::BleMedium::AcceptedConnectionCallback;
using BleScanCallback = api::ble_v2::BleMedium::ScanningCallback;
#ifndef NO_WEBRTC
using OnSignalingMessageCallback =
@@ -193,46 +188,6 @@ class MediumEnvironment {
absl::Duration GetPeerConnectionLatency();
// Adds medium-related info to allow for scanning/advertising to work.
// This provides access to this medium from other mediums, when protocol
// expects they should communicate.
void RegisterBleMedium(api::BleMedium& medium);
// Updates advertising info to indicate the current medium is exposing
// advertising event.
void UpdateBleMediumForAdvertising(api::BleMedium& medium,
api::BlePeripheral& peripheral,
const std::string& service_id,
bool fast_advertisement, bool enabled);
// Updates discovery callback info to allow for dispatch of discovery events.
//
// Invokes callback asynchronously when any changes happen to discoverable
// devices if it is turned on.
//
// This should be called when discoverable state changes.
// A valid callback should be assigned when discovery `enabled` as true; or
// an empty callback is assigned with discovery `enabled` as false.
void UpdateBleMediumForScanning(
api::BleMedium& medium, const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
BleDiscoveredPeripheralCallback callback, bool enabled);
// Updates Accepted connection callback info to allow for dispatch of
// advertising events.
void UpdateBleMediumForAcceptedConnection(
api::BleMedium& medium, const std::string& service_id,
BleAcceptedConnectionCallback callback);
// Removes medium-related info. This should correspond to device power off.
void UnregisterBleMedium(api::BleMedium& medium);
// Call back when advertising has created the server socket and is ready for
// connect.
void CallBleAcceptedConnectionCallback(api::BleMedium& medium,
api::BleSocket& socket,
const std::string& service_id);
// Adds medium-related info to allow for scanning/advertising to work.
// This provides access to this medium from other mediums, when protocol
// expects they should communicate.
@@ -433,14 +388,6 @@ class MediumEnvironment {
absl::flat_hash_map<api::BluetoothDevice*, std::string> devices;
};
struct BleMediumContext {
BleDiscoveredPeripheralCallback discovery_callback;
BleAcceptedConnectionCallback accepted_connection_callback;
api::BlePeripheral* ble_peripheral = nullptr;
bool advertising = false;
bool fast_advertisement = false;
};
struct BleV2MediumContext {
absl::flat_hash_map<std::pair<Uuid, std::uint32_t>, BleScanCallback>
scan_callback_map;
@@ -508,11 +455,6 @@ class MediumEnvironment {
api::BluetoothAdapter::ScanMode mode,
bool enabled);
void OnBlePeripheralStateChanged(BleMediumContext& info,
api::BlePeripheral& peripheral,
const std::string& service_id,
bool fast_advertisement, bool enabled);
void OnBleV2PeripheralStateChanged(
bool enabled, BleV2MediumContext& context, const Uuid& service_id,
const api::ble_v2::BleAdvertisementData& ble_advertisement_data,
@@ -541,7 +483,6 @@ class MediumEnvironment {
absl::flat_hash_map<api::BluetoothClassicMedium*, BluetoothMediumContext>
bluetooth_mediums_;
absl::flat_hash_map<api::BleMedium*, BleMediumContext> ble_mediums_;
absl::flat_hash_map<api::ble_v2::BleMedium*, BleV2MediumContext>
ble_v2_mediums_;
absl::flat_hash_map<api::BluetoothDevice*, BluetoothPairingContext>