mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
[BLE Refactor] Implements BleV2Socket and BleV2ServerSocket.
PiperOrigin-RevId: 450586535
This commit is contained in:
committed by
Copybara-Service
parent
0be161e3bb
commit
a1e84f0597
@@ -45,6 +45,7 @@ cc_library(
|
||||
"base_pcp_handler.cc",
|
||||
"ble_advertisement.cc",
|
||||
"ble_endpoint_channel.cc",
|
||||
"ble_v2_endpoint_channel.cc",
|
||||
"bluetooth_bwu_handler.cc",
|
||||
"bluetooth_device_name.cc",
|
||||
"bluetooth_endpoint_channel.cc",
|
||||
@@ -79,6 +80,7 @@ cc_library(
|
||||
"base_pcp_handler.h",
|
||||
"ble_advertisement.h",
|
||||
"ble_endpoint_channel.h",
|
||||
"ble_v2_endpoint_channel.h",
|
||||
"bluetooth_bwu_handler.h",
|
||||
"bluetooth_device_name.h",
|
||||
"bluetooth_endpoint_channel.h",
|
||||
|
||||
@@ -54,6 +54,9 @@ constexpr std::array<char, 6> kFakeMacAddress = {'a', 'b', 'c', 'd', 'e', 'f'};
|
||||
|
||||
constexpr BooleanMediumSelector kTestCases[] = {
|
||||
BooleanMediumSelector{},
|
||||
BooleanMediumSelector{
|
||||
.ble = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
},
|
||||
@@ -62,6 +65,19 @@ constexpr BooleanMediumSelector kTestCases[] = {
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// 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 "connections/implementation/ble_v2_endpoint_channel.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "internal/platform/ble_v2.h"
|
||||
#include "internal/platform/logging.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
namespace {
|
||||
|
||||
OutputStream* GetOutputStreamOrNull(BleV2Socket& socket) {
|
||||
if (socket.GetRemotePeripheral().IsValid()) {
|
||||
return &socket.GetOutputStream();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
InputStream* GetInputStreamOrNull(BleV2Socket& socket) {
|
||||
if (socket.GetRemotePeripheral().IsValid()) {
|
||||
return &socket.GetInputStream();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BleV2EndpointChannel::BleV2EndpointChannel(const std::string& service_id,
|
||||
const std::string& channel_name,
|
||||
BleV2Socket socket)
|
||||
: BaseEndpointChannel(service_id, channel_name,
|
||||
GetInputStreamOrNull(socket),
|
||||
GetOutputStreamOrNull(socket)),
|
||||
ble_socket_(std::move(socket)) {}
|
||||
|
||||
proto::connections::Medium BleV2EndpointChannel::GetMedium() const {
|
||||
return proto::connections::Medium::BLE;
|
||||
}
|
||||
|
||||
int BleV2EndpointChannel::GetMaxTransmitPacketSize() const {
|
||||
return kDefaultBleMaxTransmitPacketSize;
|
||||
}
|
||||
|
||||
void BleV2EndpointChannel::CloseImpl() {
|
||||
Exception status = ble_socket_.Close();
|
||||
if (!status.Ok()) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "Failed to close underlying socket for BleEndpointChannel "
|
||||
<< GetName() << ": exception=" << status.value;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,49 @@
|
||||
// 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 CONNECTIONS_IMPLEMENTATION_BLE_V2_ENDPOINT_CHANNEL_H_
|
||||
#define CONNECTIONS_IMPLEMENTATION_BLE_V2_ENDPOINT_CHANNEL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "connections/implementation/base_endpoint_channel.h"
|
||||
#include "internal/platform/ble_v2.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
class BleV2EndpointChannel final : public BaseEndpointChannel {
|
||||
public:
|
||||
// Creates both outgoing and incoming Ble channels.
|
||||
BleV2EndpointChannel(const std::string& service_id,
|
||||
const std::string& channel_name, BleV2Socket socket);
|
||||
|
||||
proto::connections::Medium GetMedium() const override;
|
||||
|
||||
int GetMaxTransmitPacketSize() const override;
|
||||
|
||||
private:
|
||||
static constexpr int kDefaultBleMaxTransmitPacketSize = 512; // 512 bytes
|
||||
|
||||
void CloseImpl() override;
|
||||
|
||||
BleV2Socket ble_socket_;
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // CONNECTIONS_IMPLEMENTATION_BLE_V2_ENDPOINT_CHANNEL_H_
|
||||
@@ -64,9 +64,13 @@ BleV2::~BleV2() {
|
||||
while (!advertising_infos_.empty()) {
|
||||
StopAdvertising(advertising_infos_.begin()->first);
|
||||
}
|
||||
while (!server_sockets_.empty()) {
|
||||
StopAcceptingConnections(server_sockets_.begin()->first);
|
||||
}
|
||||
|
||||
serial_executor_.Shutdown();
|
||||
alarm_executor_.Shutdown();
|
||||
accept_loops_runner_.Shutdown();
|
||||
}
|
||||
|
||||
bool BleV2::IsAvailable() const {
|
||||
@@ -165,12 +169,6 @@ bool BleV2::StopAdvertising(const std::string& service_id) {
|
||||
gatt_advertisements_.clear();
|
||||
|
||||
// Restart the BLE advertisement if there is still an advertiser.
|
||||
// TODO(b/213835576): Check the BLE Connections is off. We set the fake
|
||||
// value for the time being till connections is implemented.
|
||||
bool no_incoming_ble_sockets = true;
|
||||
if (advertising_infos_.empty() && !no_incoming_ble_sockets) {
|
||||
return true;
|
||||
}
|
||||
if (!advertising_infos_.empty()) {
|
||||
if (!hosted_gatt_characteristics_.empty()) {
|
||||
// Set the value of characteristic to empty if there is still an
|
||||
@@ -186,27 +184,26 @@ bool BleV2::StopAdvertising(const std::string& service_id) {
|
||||
}
|
||||
hosted_gatt_characteristics_.clear();
|
||||
}
|
||||
// Get the next service_id to restart BLE advertisement.
|
||||
const std::string& service_id = advertising_infos_.begin()->first;
|
||||
if (!StartAdvertisingLocked(service_id)) {
|
||||
const std::string& new_service_id = advertising_infos_.begin()->first;
|
||||
if (!StartAdvertisingLocked(new_service_id)) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "Failed to restart BLE advertisement after stopping "
|
||||
"BLE advertisement for service_id="
|
||||
<< service_id;
|
||||
advertising_infos_.erase(service_id);
|
||||
"BLE advertisement for new service_id="
|
||||
<< new_service_id;
|
||||
advertising_infos_.erase(new_service_id);
|
||||
return false;
|
||||
}
|
||||
NEARBY_LOGS(INFO) << "Restart BLE advertising with service_id="
|
||||
<< service_id;
|
||||
return true;
|
||||
NEARBY_LOGS(INFO) << "Restart BLE advertising with new service_id="
|
||||
<< new_service_id;
|
||||
} else if (incoming_sockets_.empty()) {
|
||||
// Otherwise, if we aren't restarting the BLE advertisement, then shutdown
|
||||
// the gatt server if it's not in use.
|
||||
NEARBY_LOGS(VERBOSE) << "Aggressively stopping any pre-existing "
|
||||
"advertisement GATT servers "
|
||||
"because no incoming BLE sockets are connected.";
|
||||
StopAdvertisementGattServerLocked();
|
||||
}
|
||||
|
||||
// If we aren't restarting the BLE advertisement, then shutdown
|
||||
// the gatt server if it's not in use.
|
||||
NEARBY_LOGS(VERBOSE) << "Aggressively stopping any pre-existing "
|
||||
"advertisement GATT servers "
|
||||
"because no incoming BLE sockets are connected.";
|
||||
StopAdvertisementGattServerLocked();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -348,6 +345,152 @@ bool BleV2::IsScanning(const std::string& service_id) const {
|
||||
return IsScanningLocked(service_id);
|
||||
}
|
||||
|
||||
bool BleV2::StartAcceptingConnections(const std::string& service_id,
|
||||
AcceptedConnectionCallback callback) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
if (service_id.empty()) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Refusing to start accepting BLE connections with empty service id.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsAcceptingConnectionsLocked(service_id)) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Refusing to start accepting BLE connections for " << service_id
|
||||
<< " because another BLE peripheral socket is already in-progress.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!radio_.IsEnabled()) {
|
||||
NEARBY_LOGS(INFO) << "Can't start accepting BLE connections for "
|
||||
<< service_id << " because Bluetooth isn't enabled.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsAvailableLocked()) {
|
||||
NEARBY_LOGS(INFO) << "Can't start accepting BLE connections for "
|
||||
<< service_id << " because BLE isn't available.";
|
||||
return false;
|
||||
}
|
||||
|
||||
BleV2ServerSocket server_socket = medium_.OpenServerSocket(service_id);
|
||||
if (!server_socket.IsValid()) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Failed to start accepting Ble connections for service_id="
|
||||
<< service_id;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Mark the fact that there's an in-progress Ble server accepting
|
||||
// connections.
|
||||
auto owned_server_socket =
|
||||
server_sockets_.insert({service_id, std::move(server_socket)})
|
||||
.first->second;
|
||||
|
||||
// Start the accept loop on a dedicated thread - this stays alive and
|
||||
// listening for new incoming connections until StopAcceptingConnections() is
|
||||
// invoked.
|
||||
accept_loops_runner_.Execute(
|
||||
"ble-accept", [this, &service_id, callback = std::move(callback),
|
||||
server_socket = std::move(owned_server_socket)]() mutable {
|
||||
while (true) {
|
||||
BleV2Socket client_socket = server_socket.Accept();
|
||||
if (!client_socket.IsValid()) {
|
||||
NEARBY_LOGS(WARNING) << "The client socket to accept is invalid.";
|
||||
server_socket.Close();
|
||||
break;
|
||||
}
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
client_socket.SetCloseNotifier([this, service_id]() {
|
||||
MutexLock lock(&mutex_);
|
||||
incoming_sockets_.erase(service_id);
|
||||
});
|
||||
incoming_sockets_.insert({service_id, client_socket});
|
||||
}
|
||||
callback.accepted_cb(std::move(client_socket), service_id);
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BleV2::StopAcceptingConnections(const std::string& service_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
const auto it = server_sockets_.find(service_id);
|
||||
if (it == server_sockets_.end()) {
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "Can't stop accepting BLE connections because it was never started.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Closing the BleServerSocket will kick off the suicide of the thread
|
||||
// in accept_loops_thread_pool_ that blocks on BleServerSocket.accept().
|
||||
// That may take some time to complete, but there's no particular reason to
|
||||
// wait around for it.
|
||||
auto item = server_sockets_.extract(it);
|
||||
|
||||
// Store a handle to the BleServerSocket, so we can use it after
|
||||
// removing the entry from server_sockets_; making it scoped
|
||||
// is a bonus that takes care of deallocation before we leave this method.
|
||||
BleV2ServerSocket& listening_socket = item.mapped();
|
||||
|
||||
// Regardless of whether or not we fail to close the existing
|
||||
// BleServerSocket, remove it from server_sockets_ so that it
|
||||
// frees up this service for another round.
|
||||
|
||||
// Finally, close the BleServerSocket.
|
||||
if (!listening_socket.Close().Ok()) {
|
||||
NEARBY_LOGS(INFO) << "Failed to close Ble server socket for service_id="
|
||||
<< service_id;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BleV2::IsAcceptingConnections(const std::string& service_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
return IsAcceptingConnectionsLocked(service_id);
|
||||
}
|
||||
|
||||
BleV2Socket BleV2::Connect(const std::string& service_id,
|
||||
const BleV2Peripheral& peripheral,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
MutexLock lock(&mutex_);
|
||||
// Socket to return. To allow for NRVO to work, it has to be a single object.
|
||||
BleV2Socket socket;
|
||||
|
||||
if (service_id.empty()) {
|
||||
NEARBY_LOGS(INFO) << "Refusing to create client Ble socket because "
|
||||
"service_id is empty.";
|
||||
return socket;
|
||||
}
|
||||
|
||||
if (!IsAvailableLocked()) {
|
||||
NEARBY_LOGS(INFO) << "Can't create client Ble socket [service_id="
|
||||
<< service_id << "]; Ble isn't available.";
|
||||
return socket;
|
||||
}
|
||||
|
||||
if (cancellation_flag->Cancelled()) {
|
||||
NEARBY_LOGS(INFO) << "Can't create client Ble socket due to cancel.";
|
||||
return socket;
|
||||
}
|
||||
|
||||
socket = medium_.Connect(service_id,
|
||||
PowerLevelToTxPowerLevel(PowerLevel::kHighPower),
|
||||
peripheral, cancellation_flag);
|
||||
if (!socket.IsValid()) {
|
||||
NEARBY_LOGS(INFO) << "Failed to Connect via Ble [service_id=" << service_id
|
||||
<< "]";
|
||||
}
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
bool BleV2::IsAvailableLocked() const { return medium_.IsValid(); }
|
||||
|
||||
bool BleV2::IsAdvertisingLocked(const std::string& service_id) const {
|
||||
@@ -358,6 +501,10 @@ bool BleV2::IsScanningLocked(const std::string& service_id) const {
|
||||
return scanned_service_ids_.contains(service_id);
|
||||
}
|
||||
|
||||
bool BleV2::IsAcceptingConnectionsLocked(const std::string& service_id) {
|
||||
return server_sockets_.contains(service_id);
|
||||
}
|
||||
|
||||
bool BleV2::IsAdvertisementGattServerRunningLocked() {
|
||||
return gatt_server_ && gatt_server_->IsValid();
|
||||
}
|
||||
@@ -398,6 +545,7 @@ bool BleV2::GenerateAdvertisementCharacteristic(
|
||||
std::vector<GattCharacteristic::Property> properties{
|
||||
GattCharacteristic::Property::kRead};
|
||||
|
||||
// NOLINTNEXTLINE(google3-legacy-absl-backports)
|
||||
absl::optional<GattCharacteristic> gatt_characteristic =
|
||||
gatt_server.CreateCharacteristic(
|
||||
std::string(mediums::bleutils::kCopresenceServiceUuid),
|
||||
@@ -647,10 +795,7 @@ bool BleV2::StartGattAdvertisingLocked(
|
||||
// to a loss of GATT callbacks for that remote device. The only time a
|
||||
// remote device is indefinitely connected to this device's GATT server is
|
||||
// when it has a BLE socket connection.
|
||||
// TODO(b/213835576): Check the BLE Connections is off. We set the fake
|
||||
// value for the time being till connections is implemented.
|
||||
bool no_incoming_ble_sockets = true;
|
||||
if (no_incoming_ble_sockets) {
|
||||
if (incoming_sockets_.empty()) {
|
||||
NEARBY_LOGS(VERBOSE)
|
||||
<< "Aggressively stopping any pre-existing advertisement GATT "
|
||||
"servers because no incoming BLE sockets are connected";
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define CORE_INTERNAL_MEDIUMS_BLE_V2_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@@ -29,8 +30,10 @@
|
||||
#include "connections/implementation/mediums/bluetooth_radio.h"
|
||||
#include "connections/power_level.h"
|
||||
#include "internal/platform/ble_v2.h"
|
||||
#include "internal/platform/bluetooth_adapter.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancelable_alarm.h"
|
||||
#include "internal/platform/multi_thread_executor.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
#include "internal/platform/mutex_lock.h"
|
||||
#include "internal/platform/scheduled_executor.h"
|
||||
@@ -46,6 +49,12 @@ class BleV2 final {
|
||||
public:
|
||||
using DiscoveredPeripheralCallback = mediums::DiscoveredPeripheralCallback;
|
||||
|
||||
// Callback that is invoked when a new connection is accepted.
|
||||
struct AcceptedConnectionCallback {
|
||||
std::function<void(BleV2Socket socket, const std::string& service_id)>
|
||||
accepted_cb = DefaultCallback<BleV2Socket, const std::string&>();
|
||||
};
|
||||
|
||||
static constexpr absl::Duration kPeripheralLostTimeout = absl::Seconds(3);
|
||||
|
||||
explicit BleV2(BluetoothRadio& bluetooth_radio);
|
||||
@@ -95,6 +104,26 @@ class BleV2 final {
|
||||
bool IsScanning(const std::string& service_id) const
|
||||
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_);
|
||||
|
||||
// Establishes connection to Ble peripheral.
|
||||
// Returns socket instance. On success, BleSocket.IsValid() return true.
|
||||
BleV2Socket Connect(const std::string& service_id,
|
||||
const BleV2Peripheral& peripheral,
|
||||
CancellationFlag* cancellation_flag)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns true if this object owns a valid platform implementation.
|
||||
bool IsMediumValid() const ABSL_LOCKS_EXCLUDED(mutex_) {
|
||||
MutexLock lock(&mutex_);
|
||||
@@ -119,6 +148,11 @@ class BleV2 final {
|
||||
bool IsScanningLocked(const std::string& service_id) const
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
// Same as IsListeningForIncomingConnections(), but must be called with
|
||||
// `mutex_` held.
|
||||
bool IsAcceptingConnectionsLocked(const std::string& service_id)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
bool IsAdvertisementGattServerRunningLocked()
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
bool StartAdvertisementGattServerLocked(const std::string& service_id,
|
||||
@@ -159,6 +193,8 @@ class BleV2 final {
|
||||
|
||||
void RunOnBleThread(Runnable runnable);
|
||||
|
||||
static constexpr int kMaxConcurrentAcceptLoops = 5;
|
||||
|
||||
SingleThreadExecutor serial_executor_;
|
||||
ScheduledExecutor alarm_executor_;
|
||||
|
||||
@@ -177,6 +213,20 @@ class BleV2 final {
|
||||
std::unique_ptr<CancelableAlarm> lost_alarm_;
|
||||
mediums::DiscoveredPeripheralTracker discovered_peripheral_tracker_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
// A thread pool dedicated to running all the accept loops from
|
||||
// StartAcceptingConnections().
|
||||
MultiThreadExecutor accept_loops_runner_{kMaxConcurrentAcceptLoops};
|
||||
|
||||
// A map of service_id -> ServerSocket. If map is non-empty, we
|
||||
// are currently listening for incoming connections.
|
||||
absl::flat_hash_map<std::string, BleV2ServerSocket> server_sockets_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
// Tracks currently connected incoming sockets. This lets the device know when
|
||||
// it's okay to restart GATT server related operations.
|
||||
absl::flat_hash_map<std::string, BleV2Socket> incoming_sockets_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -27,6 +27,17 @@ 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 kServiceIDA =
|
||||
"com.google.location.nearby.apps.test.a";
|
||||
@@ -34,13 +45,151 @@ constexpr absl::string_view kServiceIDB =
|
||||
"com.google.location.nearby.apps.test.b";
|
||||
constexpr absl::string_view kAdvertisementString = "\x0a\x0b\x0c\x0d";
|
||||
|
||||
class BleV2Test : public testing::Test {
|
||||
class BleV2Test : public testing::TestWithParam<FeatureFlags> {
|
||||
protected:
|
||||
BleV2Test() { env_.Stop(); }
|
||||
|
||||
MediumEnvironment& env_{MediumEnvironment::Instance()};
|
||||
};
|
||||
|
||||
TEST_P(BleV2Test, CanConnect) {
|
||||
FeatureFlags feature_flags = GetParam();
|
||||
env_.SetFeatureFlags(feature_flags);
|
||||
env_.Start();
|
||||
BluetoothRadio radio_client;
|
||||
BluetoothRadio radio_server;
|
||||
BleV2 ble_client{radio_client};
|
||||
BleV2 ble_server{radio_server};
|
||||
radio_client.Enable();
|
||||
radio_server.Enable();
|
||||
std::string service_id(kServiceIDA);
|
||||
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
|
||||
CountDownLatch discovered_latch(1);
|
||||
CountDownLatch accept_latch(1);
|
||||
|
||||
BleV2Socket socket_for_server;
|
||||
EXPECT_TRUE(ble_server.StartAcceptingConnections(
|
||||
service_id, {
|
||||
.accepted_cb =
|
||||
[&socket_for_server, &accept_latch](
|
||||
BleV2Socket socket, const std::string&) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
}));
|
||||
|
||||
ble_server.StartAdvertising(service_id, advertisement_bytes,
|
||||
PowerLevel::kHighPower,
|
||||
/*is_fast_advertisement=*/true);
|
||||
|
||||
BleV2Peripheral discovered_peripheral;
|
||||
ble_client.StartScanning(
|
||||
service_id, PowerLevel::kHighPower,
|
||||
mediums::DiscoveredPeripheralCallback{
|
||||
.peripheral_discovered_cb =
|
||||
[&discovered_latch, &discovered_peripheral](
|
||||
BleV2Peripheral peripheral, const std::string& service_id,
|
||||
const ByteArray& advertisement_bytes,
|
||||
bool fast_advertisement) {
|
||||
discovered_peripheral = peripheral;
|
||||
NEARBY_LOG(
|
||||
INFO,
|
||||
"Discovered peripheral=%p [impl=%p], fast advertisement=%d",
|
||||
&peripheral, &peripheral.GetImpl(), fast_advertisement);
|
||||
discovered_latch.CountDown();
|
||||
},
|
||||
});
|
||||
discovered_latch.Await(kWaitDuration).result();
|
||||
ASSERT_TRUE(discovered_peripheral.IsValid());
|
||||
|
||||
CancellationFlag flag;
|
||||
BleV2Socket socket_for_client =
|
||||
ble_client.Connect(service_id, discovered_peripheral, &flag);
|
||||
EXPECT_TRUE(accept_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(ble_server.StopAcceptingConnections(service_id));
|
||||
EXPECT_TRUE(ble_server.StopAdvertising(service_id));
|
||||
EXPECT_TRUE(socket_for_server.IsValid());
|
||||
EXPECT_TRUE(socket_for_client.IsValid());
|
||||
EXPECT_TRUE(socket_for_server.GetRemotePeripheral().IsValid());
|
||||
EXPECT_TRUE(socket_for_client.GetRemotePeripheral().IsValid());
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_P(BleV2Test, CanCancelConnect) {
|
||||
FeatureFlags feature_flags = GetParam();
|
||||
env_.SetFeatureFlags(feature_flags);
|
||||
env_.Start();
|
||||
BluetoothRadio radio_client;
|
||||
BluetoothRadio radio_server;
|
||||
BleV2 ble_client{radio_client};
|
||||
BleV2 ble_server{radio_server};
|
||||
radio_client.Enable();
|
||||
radio_server.Enable();
|
||||
std::string service_id(kServiceIDA);
|
||||
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
|
||||
CountDownLatch discovered_latch(1);
|
||||
CountDownLatch accept_latch(1);
|
||||
|
||||
BleV2Socket socket_for_server;
|
||||
EXPECT_TRUE(ble_server.StartAcceptingConnections(
|
||||
service_id, {
|
||||
.accepted_cb =
|
||||
[&socket_for_server, &accept_latch](
|
||||
BleV2Socket socket, const std::string&) {
|
||||
socket_for_server = std::move(socket);
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
}));
|
||||
|
||||
ble_server.StartAdvertising(service_id, advertisement_bytes,
|
||||
PowerLevel::kHighPower,
|
||||
/*is_fast_advertisement=*/true);
|
||||
|
||||
BleV2Peripheral discovered_peripheral;
|
||||
ble_client.StartScanning(
|
||||
service_id, PowerLevel::kHighPower,
|
||||
mediums::DiscoveredPeripheralCallback{
|
||||
.peripheral_discovered_cb =
|
||||
[&discovered_latch, &discovered_peripheral](
|
||||
BleV2Peripheral peripheral, const std::string& service_id,
|
||||
const ByteArray& advertisement_bytes,
|
||||
bool fast_advertisement) {
|
||||
discovered_peripheral = peripheral;
|
||||
NEARBY_LOG(
|
||||
INFO,
|
||||
"Discovered peripheral=%p [impl=%p], fast advertisement=%d",
|
||||
&peripheral, &peripheral.GetImpl(), fast_advertisement);
|
||||
discovered_latch.CountDown();
|
||||
},
|
||||
});
|
||||
EXPECT_TRUE(discovered_latch.Await(kWaitDuration).result());
|
||||
ASSERT_TRUE(discovered_peripheral.IsValid());
|
||||
|
||||
CancellationFlag flag(true);
|
||||
BleV2Socket socket_for_client =
|
||||
ble_client.Connect(service_id, discovered_peripheral, &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(ble_server.StopAcceptingConnections(service_id));
|
||||
EXPECT_TRUE(ble_server.StopAdvertising(service_id));
|
||||
EXPECT_TRUE(socket_for_server.IsValid());
|
||||
EXPECT_TRUE(socket_for_client.IsValid());
|
||||
EXPECT_TRUE(socket_for_server.GetRemotePeripheral().IsValid());
|
||||
EXPECT_TRUE(socket_for_client.GetRemotePeripheral().IsValid());
|
||||
} else {
|
||||
EXPECT_FALSE(accept_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(ble_server.StopAcceptingConnections(service_id));
|
||||
EXPECT_TRUE(ble_server.StopAdvertising(service_id));
|
||||
EXPECT_FALSE(socket_for_server.IsValid());
|
||||
EXPECT_FALSE(socket_for_client.IsValid());
|
||||
}
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ParametrisedBleTest, BleV2Test,
|
||||
::testing::ValuesIn(kTestCases));
|
||||
|
||||
TEST_F(BleV2Test, CanConstructValidObject) {
|
||||
env_.Start();
|
||||
BluetoothRadio radio_a;
|
||||
|
||||
@@ -44,6 +44,9 @@ constexpr absl::Duration kDefaultTimeout = absl::Milliseconds(1500);
|
||||
constexpr absl::Duration kDisconnectTimeout = absl::Milliseconds(15000);
|
||||
|
||||
constexpr BooleanMediumSelector kTestCases[] = {
|
||||
BooleanMediumSelector{
|
||||
.ble = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
},
|
||||
@@ -52,6 +55,19 @@ constexpr BooleanMediumSelector kTestCases[] = {
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "connections/implementation/base_pcp_handler.h"
|
||||
#include "connections/implementation/ble_advertisement.h"
|
||||
#include "connections/implementation/ble_endpoint_channel.h"
|
||||
#include "connections/implementation/ble_v2_endpoint_channel.h"
|
||||
#include "connections/implementation/bluetooth_endpoint_channel.h"
|
||||
#include "connections/implementation/bwu_manager.h"
|
||||
#include "connections/implementation/mediums/utils.h"
|
||||
@@ -187,7 +188,7 @@ Status P2pClusterPcpHandler::StopAdvertisingImpl(ClientProxy* client) {
|
||||
|
||||
if (FeatureFlags::GetInstance().GetFlags().support_ble_v2) {
|
||||
ble_v2_medium_.StopAdvertising(client->GetAdvertisingServiceId());
|
||||
// TODO(b/213689498): Implements Stop accept connenction.
|
||||
ble_v2_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId());
|
||||
} else {
|
||||
ble_medium_.StopAdvertising(client->GetAdvertisingServiceId());
|
||||
ble_medium_.StopAcceptingConnections(client->GetAdvertisingServiceId());
|
||||
@@ -1485,7 +1486,53 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleV2Advertising(
|
||||
// Bluetooth Classic.
|
||||
NEARBY_LOGS(INFO) << "P2pClusterPcpHandler::StartBleAdvertising: service_id="
|
||||
<< service_id << " : start";
|
||||
// TODO(b/213689498): Implements accept connenction.
|
||||
// TODO(edwinwu): Move the lambda to a named function.
|
||||
if (!ble_v2_medium_.IsAcceptingConnections(service_id)) {
|
||||
if (!bluetooth_radio_.Enable() ||
|
||||
!ble_v2_medium_.StartAcceptingConnections(
|
||||
service_id, {.accepted_cb = [this, client, local_endpoint_info](
|
||||
BleV2Socket socket,
|
||||
const std::string& service_id) {
|
||||
if (!socket.IsValid()) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "Invalid socket in accept callback("
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
<< "), client=" << client->GetClientId();
|
||||
return;
|
||||
}
|
||||
RunOnPcpHandlerThread(
|
||||
"p2p-ble-on-incoming-connection",
|
||||
[this, client, local_endpoint_info, service_id,
|
||||
socket = std::move(socket)]()
|
||||
RUN_ON_PCP_HANDLER_THREAD() mutable {
|
||||
ByteArray remote_peripheral_info =
|
||||
socket.GetRemotePeripheral().GetId();
|
||||
auto channel = std::make_unique<BleV2EndpointChannel>(
|
||||
service_id, std::string(remote_peripheral_info),
|
||||
socket);
|
||||
|
||||
OnIncomingConnection(client, remote_peripheral_info,
|
||||
std::move(channel),
|
||||
proto::connections::Medium::BLE);
|
||||
});
|
||||
}})) {
|
||||
NEARBY_LOGS(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 proto::connections::UNKNOWN_MEDIUM;
|
||||
}
|
||||
NEARBY_LOGS(INFO)
|
||||
<< "In StartBleAdvertising("
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
<< "), client=" << client->GetClientId()
|
||||
<< " started accepting for incoming BLE connections to service_id="
|
||||
<< service_id;
|
||||
}
|
||||
|
||||
PowerLevel power_level = advertising_options.low_power
|
||||
? PowerLevel::kLowPower
|
||||
: PowerLevel::kHighPower;
|
||||
@@ -1530,7 +1577,7 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleV2Advertising(
|
||||
<< " failed to start accepting for incoming BLE connections to "
|
||||
"service_id="
|
||||
<< service_id;
|
||||
// TODO(b/213689498): Implements stop accepting connenction.
|
||||
ble_v2_medium_.StopAcceptingConnections(service_id);
|
||||
return proto::connections::UNKNOWN_MEDIUM;
|
||||
}
|
||||
NEARBY_LOGS(INFO)
|
||||
@@ -1575,7 +1622,7 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleV2Advertising(
|
||||
<< absl::BytesToHexString(local_endpoint_info.data())
|
||||
<< "), client=" << client->GetClientId()
|
||||
<< " failed to create an advertisement.";
|
||||
// TODO(b/213689498): Implements stop accepting connenction.
|
||||
ble_v2_medium_.StopAcceptingConnections(service_id);
|
||||
return proto::connections::UNKNOWN_MEDIUM;
|
||||
}
|
||||
|
||||
@@ -1594,7 +1641,7 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleV2Advertising(
|
||||
<< "), client=" << client->GetClientId()
|
||||
<< " couldn't start BLE Advertising with BleAdvertisement "
|
||||
<< absl::BytesToHexString(advertisement_bytes.data());
|
||||
// TODO(b/213689498): Implements stop accepting connenction.
|
||||
ble_v2_medium_.StopAcceptingConnections(service_id);
|
||||
return proto::connections::UNKNOWN_MEDIUM;
|
||||
}
|
||||
NEARBY_LOGS(INFO) << "In startBleAdvertising("
|
||||
@@ -1632,11 +1679,28 @@ BasePcpHandler::ConnectImplResult P2pClusterPcpHandler::BleV2ConnectImpl(
|
||||
<< " is attempting to connect to endpoint(id="
|
||||
<< endpoint->endpoint_id << ") over BLE.";
|
||||
|
||||
// TODO(b/213689498): Implements connection.
|
||||
BleV2Peripheral& peripheral = endpoint->ble_peripheral;
|
||||
|
||||
BleV2Socket ble_socket = ble_v2_medium_.Connect(
|
||||
endpoint->service_id, peripheral,
|
||||
client->GetCancellationFlag(endpoint->endpoint_id));
|
||||
if (!ble_socket.IsValid()) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "In BleConnectImpl(), failed to connect to BLE device "
|
||||
<< absl::BytesToHexString(peripheral.GetId().data())
|
||||
<< " for endpoint(id=" << endpoint->endpoint_id << ").";
|
||||
return BasePcpHandler::ConnectImplResult{
|
||||
.status = {Status::kBleError},
|
||||
};
|
||||
}
|
||||
|
||||
auto channel = std::make_unique<BleV2EndpointChannel>(
|
||||
endpoint->service_id, /*channel_name=*/endpoint->endpoint_id, ble_socket);
|
||||
|
||||
return BasePcpHandler::ConnectImplResult{
|
||||
.medium = proto::connections::Medium::BLE,
|
||||
.status = {Status::kBleError},
|
||||
.endpoint_channel = nullptr,
|
||||
.status = {Status::kSuccess},
|
||||
.endpoint_channel = std::move(channel),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "connections/implementation/p2p_cluster_pcp_handler.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
@@ -22,9 +23,9 @@
|
||||
#include "absl/time/time.h"
|
||||
#include "connections/implementation/bwu_manager.h"
|
||||
#include "connections/implementation/injected_bluetooth_device_store.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
#include "internal/platform/count_down_latch.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
@@ -32,6 +33,9 @@ namespace connections {
|
||||
namespace {
|
||||
|
||||
constexpr BooleanMediumSelector kTestCases[] = {
|
||||
BooleanMediumSelector{
|
||||
.ble = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
},
|
||||
@@ -40,16 +44,36 @@ constexpr BooleanMediumSelector kTestCases[] = {
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
};
|
||||
|
||||
// Combines the bool `support_ble_v2` as param testing but should revert it back
|
||||
// if ble_v2 is done and ble will be replaced by ble_v2.
|
||||
class P2pClusterPcpHandlerTest
|
||||
: public ::testing::TestWithParam<BooleanMediumSelector> {
|
||||
: public testing::TestWithParam<std::tuple<BooleanMediumSelector, bool>> {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
NEARBY_LOG(INFO, "SetUp: begin");
|
||||
env_.Stop();
|
||||
FeatureFlags::GetMutableFlagsForTesting().support_ble_v2 =
|
||||
std::get<1>(GetParam());
|
||||
if (advertising_options_.allowed.ble) {
|
||||
NEARBY_LOG(INFO, "SetUp: BLE enabled");
|
||||
}
|
||||
if (advertising_options_.allowed.bluetooth) {
|
||||
NEARBY_LOG(INFO, "SetUp: BT enabled");
|
||||
}
|
||||
@@ -68,19 +92,19 @@ class P2pClusterPcpHandlerTest
|
||||
ConnectionOptions connection_options_{
|
||||
{
|
||||
Strategy::kP2pCluster,
|
||||
GetParam(),
|
||||
std::get<0>(GetParam()),
|
||||
},
|
||||
};
|
||||
AdvertisingOptions advertising_options_{
|
||||
{
|
||||
Strategy::kP2pCluster,
|
||||
GetParam(),
|
||||
std::get<0>(GetParam()),
|
||||
},
|
||||
};
|
||||
DiscoveryOptions discovery_options_{
|
||||
{
|
||||
Strategy::kP2pCluster,
|
||||
GetParam(),
|
||||
std::get<0>(GetParam()),
|
||||
},
|
||||
};
|
||||
MediumEnvironment& env_{MediumEnvironment::Instance()};
|
||||
@@ -265,7 +289,8 @@ TEST_P(P2pClusterPcpHandlerTest, CanConnect) {
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ParametrisedPcpHandlerTest, P2pClusterPcpHandlerTest,
|
||||
::testing::ValuesIn(kTestCases));
|
||||
::testing::Combine(::testing::ValuesIn(kTestCases),
|
||||
::testing::Bool()));
|
||||
|
||||
} // namespace
|
||||
} // namespace connections
|
||||
|
||||
@@ -36,6 +36,9 @@ constexpr absl::Duration kProgressTimeout = absl::Milliseconds(1000);
|
||||
constexpr absl::Duration kDefaultTimeout = absl::Milliseconds(1000);
|
||||
|
||||
constexpr BooleanMediumSelector kTestCases[] = {
|
||||
BooleanMediumSelector{
|
||||
.ble = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
},
|
||||
@@ -44,6 +47,19 @@ constexpr BooleanMediumSelector kTestCases[] = {
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -37,6 +37,9 @@ constexpr char kDeviceA[] = "device-A";
|
||||
constexpr char kDeviceB[] = "device-B";
|
||||
|
||||
constexpr BooleanMediumSelector kTestCases[] = {
|
||||
BooleanMediumSelector{
|
||||
.ble = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
},
|
||||
@@ -45,6 +48,19 @@ constexpr BooleanMediumSelector kTestCases[] = {
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
BooleanMediumSelector{
|
||||
.bluetooth = true,
|
||||
.ble = true,
|
||||
.wifi_lan = true,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -139,6 +139,19 @@ std::unique_ptr<GattClient> BleV2Medium::ConnectToGattServer(
|
||||
return std::make_unique<GattClient>(std::move(api_gatt_client));
|
||||
}
|
||||
|
||||
BleV2ServerSocket BleV2Medium::OpenServerSocket(const std::string& service_id) {
|
||||
return BleV2ServerSocket(impl_->OpenServerSocket(service_id));
|
||||
}
|
||||
|
||||
BleV2Socket BleV2Medium::Connect(const std::string& service_id,
|
||||
TxPowerLevel tx_power_level,
|
||||
const BleV2Peripheral& peripheral,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
return BleV2Socket(impl_->Connect(service_id, tx_power_level,
|
||||
/*mutated=*/peripheral.GetImpl(),
|
||||
cancellation_flag));
|
||||
}
|
||||
|
||||
bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
|
||||
return impl_->IsExtendedAdvertisementsAvailable();
|
||||
}
|
||||
|
||||
@@ -25,11 +25,120 @@
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/implementation/platform.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/mutex.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// Container of operations that can be performed over the BLE GATT client
|
||||
// socket.
|
||||
// This class is copyable but not moveable.
|
||||
class BleV2Socket final {
|
||||
public:
|
||||
BleV2Socket() = default;
|
||||
explicit BleV2Socket(std::unique_ptr<api::ble_v2::BleSocket> socket)
|
||||
: impl_(std::move(socket)) {}
|
||||
BleV2Socket(const BleV2Socket&) = default;
|
||||
BleV2Socket& operator=(const BleV2Socket&) = 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(); }
|
||||
|
||||
// Sets the close notifier by cient side.
|
||||
void SetCloseNotifier(std::function<void()> notifier) {
|
||||
close_notifier_ = std::move(notifier);
|
||||
}
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() {
|
||||
if (close_notifier_) {
|
||||
auto notifier = std::move(close_notifier_);
|
||||
notifier();
|
||||
}
|
||||
return impl_->Close();
|
||||
}
|
||||
|
||||
// Returns BlePeripheral object which wraps a valid BlePeripheral pointer.
|
||||
BleV2Peripheral GetRemotePeripheral() {
|
||||
return BleV2Peripheral(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::ble_v2::BleSocket& GetImpl() { return *impl_; }
|
||||
|
||||
private:
|
||||
std::function<void()> close_notifier_;
|
||||
std::shared_ptr<api::ble_v2::BleSocket> impl_;
|
||||
};
|
||||
|
||||
// Container of operations that can be performed over the BLE GATT server
|
||||
// socket.
|
||||
// This class is copyable but not moveable.
|
||||
class BleV2ServerSocket final {
|
||||
public:
|
||||
explicit BleV2ServerSocket(
|
||||
std::unique_ptr<api::ble_v2::BleServerSocket> socket)
|
||||
: impl_(std::move(socket)) {}
|
||||
BleV2ServerSocket(const BleV2ServerSocket&) = default;
|
||||
BleV2ServerSocket& operator=(const BleV2ServerSocket&) = default;
|
||||
|
||||
// Blocks until either:
|
||||
// - at least one incoming connection request is available, or
|
||||
// - ServerSocket is closed.
|
||||
// On success, returns connected socket, ready to exchange data.
|
||||
// On error, "impl_" will be nullptr and the caller will check it by calling
|
||||
// member function "IsValid()"
|
||||
// Once error is reported, it is permanent, and
|
||||
// ServerSocket has to be closed by caller.
|
||||
BleV2Socket Accept() {
|
||||
std::unique_ptr<api::ble_v2::BleSocket> socket = impl_->Accept();
|
||||
if (!socket) {
|
||||
NEARBY_LOGS(INFO) << "BleServerSocket Accept() failed on server socket: "
|
||||
<< this;
|
||||
}
|
||||
return BleV2Socket(std::move(socket));
|
||||
}
|
||||
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
Exception Close() {
|
||||
NEARBY_LOGS(INFO) << "BleServerSocket Closing:: " << this;
|
||||
return impl_->Close();
|
||||
}
|
||||
|
||||
bool IsValid() const { return impl_ != nullptr; }
|
||||
api::ble_v2::BleServerSocket& GetImpl() { return *impl_; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<api::ble_v2::BleServerSocket> impl_;
|
||||
};
|
||||
|
||||
// Opaque wrapper over a GattServer.
|
||||
// Move only, disallow copy.
|
||||
//
|
||||
@@ -173,6 +282,17 @@ class BleV2Medium final {
|
||||
BleV2Peripheral peripheral, api::ble_v2::TxPowerLevel tx_power_level,
|
||||
ClientGattConnectionCallback callback);
|
||||
|
||||
// Returns a new BleServerSocket.
|
||||
// On Success, BleServerSocket::IsValid() returns true.
|
||||
BleV2ServerSocket OpenServerSocket(const std::string& service_id);
|
||||
|
||||
// Returns a new BleLanSocket.
|
||||
// On Success, BleLanSocket::IsValid() returns true.
|
||||
BleV2Socket Connect(const std::string& service_id,
|
||||
api::ble_v2::TxPowerLevel tx_power_level,
|
||||
const BleV2Peripheral& peripheral,
|
||||
CancellationFlag* cancellation_flag);
|
||||
|
||||
bool IsExtendedAdvertisementsAvailable();
|
||||
|
||||
bool IsValid() const { return impl_ != nullptr; }
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
@@ -28,6 +29,17 @@ namespace location {
|
||||
namespace nearby {
|
||||
namespace {
|
||||
|
||||
using FeatureFlags = FeatureFlags::Flags;
|
||||
|
||||
constexpr FeatureFlags kTestCases[] = {
|
||||
FeatureFlags{
|
||||
.enable_cancellation_flag = true,
|
||||
},
|
||||
FeatureFlags{
|
||||
.enable_cancellation_flag = false,
|
||||
},
|
||||
};
|
||||
|
||||
using ::location::nearby::api::ble_v2::BleAdvertisementData;
|
||||
using ::location::nearby::api::ble_v2::GattCharacteristic;
|
||||
using ::location::nearby::api::ble_v2::TxPowerLevel;
|
||||
@@ -38,6 +50,8 @@ constexpr absl::string_view kAdvertisementString = "\x0a\x0b\x0c\x0d";
|
||||
constexpr absl::string_view kAdvertisementHeaderString = "\x0x\x0y\x0z";
|
||||
constexpr absl::string_view kCopresenceServiceUuid = "F3FE";
|
||||
constexpr TxPowerLevel kTxPowerLevel(TxPowerLevel::kHigh);
|
||||
constexpr absl::string_view kServiceIDA{
|
||||
"com.google.location.nearby.apps.test.a"};
|
||||
|
||||
// A stub BlePeripheral implementation.
|
||||
class BlePeripheralStub : public api::ble_v2::BlePeripheral {
|
||||
@@ -52,13 +66,158 @@ class BlePeripheralStub : public api::ble_v2::BlePeripheral {
|
||||
std::string mac_address_;
|
||||
};
|
||||
|
||||
class BleV2MediumTest : public testing::Test {
|
||||
class BleV2MediumTest : public ::testing::TestWithParam<FeatureFlags> {
|
||||
protected:
|
||||
BleV2MediumTest() { env_.Stop(); }
|
||||
|
||||
MediumEnvironment& env_{MediumEnvironment::Instance()};
|
||||
};
|
||||
|
||||
TEST_P(BleV2MediumTest, CanConnectToService) {
|
||||
FeatureFlags feature_flags = GetParam();
|
||||
env_.SetFeatureFlags(feature_flags);
|
||||
env_.Start();
|
||||
BluetoothAdapter adapter_a_;
|
||||
BluetoothAdapter adapter_b_;
|
||||
BleV2Medium ble_a(adapter_a_);
|
||||
BleV2Medium ble_b(adapter_b_);
|
||||
std::string service_id(kServiceIDA);
|
||||
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
|
||||
CountDownLatch found_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
BleV2ServerSocket server_socket = ble_b.OpenServerSocket(service_id);
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
// Assemble regular advertisement data
|
||||
BleAdvertisementData advertising_data;
|
||||
advertising_data.is_extended_advertisement = false;
|
||||
advertising_data.service_data = {
|
||||
{std::string(kCopresenceServiceUuid), advertisement_bytes}};
|
||||
(ble_b.StartAdvertising(advertising_data, {.tx_power_level = kTxPowerLevel,
|
||||
.is_connectable = true}));
|
||||
|
||||
BleV2Peripheral discovered_peripheral;
|
||||
ble_a.StartScanning(
|
||||
{std::string(kCopresenceServiceUuid)}, kTxPowerLevel,
|
||||
{
|
||||
.advertisement_found_cb =
|
||||
[&found_latch, &discovered_peripheral](
|
||||
BleV2Peripheral peripheral,
|
||||
const BleAdvertisementData& advertisement_data) {
|
||||
discovered_peripheral = std::move(peripheral);
|
||||
found_latch.CountDown();
|
||||
},
|
||||
});
|
||||
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
|
||||
BleV2Socket socket_a;
|
||||
BleV2Socket socket_b;
|
||||
EXPECT_FALSE(socket_a.IsValid());
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
{
|
||||
CancellationFlag flag;
|
||||
SingleThreadExecutor server_executor;
|
||||
SingleThreadExecutor client_executor;
|
||||
client_executor.Execute(
|
||||
[&ble_a, &socket_a, &service_id,
|
||||
discovered_peripheral = std::move(discovered_peripheral),
|
||||
&server_socket, &flag]() {
|
||||
socket_a = ble_a.Connect(service_id, kTxPowerLevel,
|
||||
discovered_peripheral, &flag);
|
||||
if (!socket_a.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
server_executor.Execute([&socket_b, &server_socket]() {
|
||||
socket_b = server_socket.Accept();
|
||||
if (!socket_b.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
EXPECT_TRUE(socket_a.IsValid());
|
||||
EXPECT_TRUE(socket_b.IsValid());
|
||||
server_socket.Close();
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_P(BleV2MediumTest, CanCancelConnect) {
|
||||
FeatureFlags feature_flags = GetParam();
|
||||
env_.SetFeatureFlags(feature_flags);
|
||||
env_.Start();
|
||||
BluetoothAdapter adapter_a_;
|
||||
BluetoothAdapter adapter_b_;
|
||||
BleV2Medium ble_a{adapter_a_};
|
||||
BleV2Medium ble_b{adapter_b_};
|
||||
std::string service_id(kServiceIDA);
|
||||
ByteArray advertisement_bytes((std::string(kAdvertisementString)));
|
||||
CountDownLatch found_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
BleV2ServerSocket server_socket = ble_b.OpenServerSocket(service_id);
|
||||
EXPECT_TRUE(server_socket.IsValid());
|
||||
|
||||
// Assemble regular advertisement data.
|
||||
BleAdvertisementData advertising_data;
|
||||
advertising_data.is_extended_advertisement = false;
|
||||
advertising_data.service_data = {
|
||||
{std::string(kCopresenceServiceUuid), advertisement_bytes}};
|
||||
(ble_b.StartAdvertising(advertising_data, {.tx_power_level = kTxPowerLevel,
|
||||
.is_connectable = true}));
|
||||
|
||||
BleV2Peripheral discovered_peripheral;
|
||||
ble_a.StartScanning(
|
||||
{std::string(kCopresenceServiceUuid)}, kTxPowerLevel,
|
||||
{
|
||||
.advertisement_found_cb =
|
||||
[&found_latch, &discovered_peripheral](
|
||||
BleV2Peripheral peripheral,
|
||||
const BleAdvertisementData& advertisement_data) {
|
||||
discovered_peripheral = std::move(peripheral);
|
||||
found_latch.CountDown();
|
||||
},
|
||||
});
|
||||
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
|
||||
BleV2Socket socket_a;
|
||||
BleV2Socket socket_b;
|
||||
EXPECT_FALSE(socket_a.IsValid());
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
{
|
||||
CancellationFlag flag(true);
|
||||
SingleThreadExecutor server_executor;
|
||||
SingleThreadExecutor client_executor;
|
||||
client_executor.Execute(
|
||||
[&ble_a, &socket_a, &service_id,
|
||||
discovered_peripheral = std::move(discovered_peripheral),
|
||||
&server_socket, &flag]() {
|
||||
socket_a = ble_a.Connect(service_id, kTxPowerLevel,
|
||||
discovered_peripheral, &flag);
|
||||
if (!socket_a.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
server_executor.Execute([&socket_b, &server_socket]() {
|
||||
socket_b = server_socket.Accept();
|
||||
if (!socket_b.IsValid()) {
|
||||
server_socket.Close();
|
||||
}
|
||||
});
|
||||
}
|
||||
// If FeatureFlag is disabled, Cancelled is false as no-op.
|
||||
if (!feature_flags.enable_cancellation_flag) {
|
||||
EXPECT_TRUE(socket_a.IsValid());
|
||||
EXPECT_TRUE(socket_b.IsValid());
|
||||
} else {
|
||||
EXPECT_FALSE(socket_a.IsValid());
|
||||
EXPECT_FALSE(socket_b.IsValid());
|
||||
}
|
||||
server_socket.Close();
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(ParametrisedBleMediumTest, BleV2MediumTest,
|
||||
::testing::ValuesIn(kTestCases));
|
||||
|
||||
TEST_F(BleV2MediumTest, ConstructorDestructorWorks) {
|
||||
env_.Start();
|
||||
BluetoothAdapter adapter_a;
|
||||
|
||||
@@ -52,6 +52,7 @@ class BlePeripheral final {
|
||||
// particular BLE peripheral to connect to its GATT server.
|
||||
class BleV2Peripheral final {
|
||||
public:
|
||||
BleV2Peripheral() = default;
|
||||
explicit BleV2Peripheral(api::ble_v2::BlePeripheral* peripheral)
|
||||
: impl_(peripheral) {}
|
||||
BleV2Peripheral(const BleV2Peripheral&) = default;
|
||||
@@ -87,7 +88,7 @@ class BleV2Peripheral final {
|
||||
|
||||
// Returns reference to platform implementation.
|
||||
// This is used to communicate with platform code, and for debugging purposes.
|
||||
api::ble_v2::BlePeripheral& GetImpl() { return *impl_; }
|
||||
api::ble_v2::BlePeripheral& GetImpl() const { return *impl_; }
|
||||
bool IsValid() const { return impl_ != nullptr; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/input_stream.h"
|
||||
#include "internal/platform/listeners.h"
|
||||
@@ -224,44 +225,48 @@ struct ServerGattConnectionCallback {
|
||||
characteristic_unsubscription_cb;
|
||||
};
|
||||
|
||||
// A BLE GATT client socket for requesting GATT socket.
|
||||
class BleSocket {
|
||||
public:
|
||||
virtual ~BleSocket() {}
|
||||
virtual ~BleSocket() = default;
|
||||
|
||||
// Returns the remote BLE peripheral tied to this socket.
|
||||
virtual BlePeripheral& GetRemotePeripheral() = 0;
|
||||
|
||||
// Writes a message on the socket and blocks until finished. Returns
|
||||
// Exception::kIo upon error, and Exception::kSuccess otherwise.
|
||||
virtual Exception Write(const ByteArray& message) = 0;
|
||||
|
||||
// Closes the socket and blocks until finished. Returns Exception::kIo upon
|
||||
// error, and Exception::kSuccess otherwise.
|
||||
virtual Exception Close() = 0;
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
// Callback for asynchronous events on a BleSocket object.
|
||||
class BleSocketLifeCycleCallback {
|
||||
// A BLE GATT server socket for listening incoming GATT socket.
|
||||
class BleServerSocket {
|
||||
public:
|
||||
virtual ~BleSocketLifeCycleCallback() = default;
|
||||
virtual ~BleServerSocket() = default;
|
||||
|
||||
// Called when a message arrives on a socket.
|
||||
virtual void OnMessageReceived(BleSocket* socket,
|
||||
const ByteArray& message) = 0;
|
||||
// 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.
|
||||
virtual std::unique_ptr<BleSocket> Accept() = 0;
|
||||
|
||||
// Called when a socket gets disconnected.
|
||||
virtual void OnDisconnected(BleSocket* socket) = 0;
|
||||
};
|
||||
|
||||
// Callback for asynchronous events on the server side of a BleSocket object.
|
||||
class ServerBleSocketLifeCycleCallback : public BleSocketLifeCycleCallback {
|
||||
public:
|
||||
~ServerBleSocketLifeCycleCallback() override {}
|
||||
|
||||
// Called when a new incoming socket has been established.
|
||||
virtual void OnSocketEstablished(BleSocket* socket) = 0;
|
||||
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
|
||||
virtual Exception Close() = 0;
|
||||
};
|
||||
|
||||
// The main BLE medium used inside of Nearby. This serves as the entry point
|
||||
@@ -327,13 +332,6 @@ class BleMedium {
|
||||
virtual std::unique_ptr<GattServer> StartGattServer(
|
||||
ServerGattConnectionCallback callback) = 0;
|
||||
|
||||
// Starts listening for incoming BLE sockets and returns false upon error.
|
||||
virtual bool StartListeningForIncomingBleSockets(
|
||||
const ServerBleSocketLifeCycleCallback& callback) = 0;
|
||||
|
||||
// Stops listening for incoming BLE sockets.
|
||||
virtual void StopListeningForIncomingBleSockets() = 0;
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#connectGatt(android.content.Context,%20boolean,%20android.bluetooth.BluetoothGattCallback)
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#requestConnectionPriority(int)
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#requestMtu(int)
|
||||
@@ -350,11 +348,20 @@ class BleMedium {
|
||||
BlePeripheral& peripheral, TxPowerLevel tx_power_level,
|
||||
ClientGattConnectionCallback callback) = 0;
|
||||
|
||||
// Establishes a BLE socket to the specified remote peripheral. Returns
|
||||
// nullptr on error.
|
||||
virtual std::unique_ptr<BleSocket> EstablishBleSocket(
|
||||
BlePeripheral* peripheral,
|
||||
const BleSocketLifeCycleCallback& callback) = 0;
|
||||
// Opens a BLE server socket based on service ID.
|
||||
//
|
||||
// On success, returns a new BleServerSocket.
|
||||
// On error, returns nullptr.
|
||||
virtual std::unique_ptr<BleServerSocket> OpenServerSocket(
|
||||
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(
|
||||
const std::string& service_id, TxPowerLevel tx_power_level,
|
||||
BlePeripheral& peripheral, CancellationFlag* cancellation_flag) = 0;
|
||||
|
||||
// Requests if support extended advertisement.
|
||||
virtual bool IsExtendedAdvertisementsAvailable() = 0;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "internal/platform/implementation/g3/ble_v2.h"
|
||||
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
@@ -22,6 +23,7 @@
|
||||
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
@@ -33,8 +35,6 @@ namespace g3 {
|
||||
namespace {
|
||||
|
||||
using ::location::nearby::api::ble_v2::BleAdvertisementData;
|
||||
using ::location::nearby::api::ble_v2::BleSocket;
|
||||
using ::location::nearby::api::ble_v2::BleSocketLifeCycleCallback;
|
||||
using ::location::nearby::api::ble_v2::TxPowerLevel;
|
||||
|
||||
std::string TxPowerLevelToName(TxPowerLevel power_mode) {
|
||||
@@ -54,15 +54,158 @@ std::string TxPowerLevelToName(TxPowerLevel power_mode) {
|
||||
|
||||
} // namespace
|
||||
|
||||
BleV2Socket::~BleV2Socket() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
DoClose();
|
||||
}
|
||||
|
||||
void BleV2Socket::Connect(BleV2Socket& other) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
remote_socket_ = &other;
|
||||
input_ = other.output_;
|
||||
}
|
||||
|
||||
InputStream& BleV2Socket::GetInputStream() {
|
||||
auto* remote_socket = GetRemoteSocket();
|
||||
CHECK(remote_socket != nullptr);
|
||||
return remote_socket->GetLocalInputStream();
|
||||
}
|
||||
|
||||
OutputStream& BleV2Socket::GetOutputStream() { return GetLocalOutputStream(); }
|
||||
|
||||
BleV2Socket* BleV2Socket::GetRemoteSocket() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return remote_socket_;
|
||||
}
|
||||
|
||||
bool BleV2Socket::IsConnected() const {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return IsConnectedLocked();
|
||||
}
|
||||
|
||||
bool BleV2Socket::IsClosed() const {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return closed_;
|
||||
}
|
||||
|
||||
Exception BleV2Socket::Close() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
DoClose();
|
||||
return {Exception::kSuccess};
|
||||
}
|
||||
|
||||
BleV2Peripheral* BleV2Socket::GetRemotePeripheral() {
|
||||
BluetoothAdapter* remote_adapter = nullptr;
|
||||
{
|
||||
absl::MutexLock lock(&mutex_);
|
||||
if (remote_socket_ == nullptr || remote_socket_->adapter_ == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
remote_adapter = remote_socket_->adapter_;
|
||||
}
|
||||
return remote_adapter ? &remote_adapter->GetPeripheralV2() : nullptr;
|
||||
}
|
||||
|
||||
void BleV2Socket::DoClose() {
|
||||
if (!closed_) {
|
||||
remote_socket_ = nullptr;
|
||||
output_->GetOutputStream().Close();
|
||||
output_->GetInputStream().Close();
|
||||
input_->GetOutputStream().Close();
|
||||
input_->GetInputStream().Close();
|
||||
closed_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool BleV2Socket::IsConnectedLocked() const { return input_ != nullptr; }
|
||||
|
||||
InputStream& BleV2Socket::GetLocalInputStream() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return output_->GetInputStream();
|
||||
}
|
||||
|
||||
OutputStream& BleV2Socket::GetLocalOutputStream() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return output_->GetOutputStream();
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble_v2::BleSocket> BleV2ServerSocket::Accept() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
while (!closed_ && pending_sockets_.empty()) {
|
||||
cond_.Wait(&mutex_);
|
||||
}
|
||||
// whether or not we were running in the wait loop, return early if closed.
|
||||
if (closed_) return {};
|
||||
auto* remote_socket =
|
||||
pending_sockets_.extract(pending_sockets_.begin()).value();
|
||||
CHECK(remote_socket);
|
||||
|
||||
auto local_socket = std::make_unique<BleV2Socket>(adapter_);
|
||||
local_socket->Connect(*remote_socket);
|
||||
remote_socket->Connect(*local_socket);
|
||||
cond_.SignalAll();
|
||||
return local_socket;
|
||||
}
|
||||
|
||||
bool BleV2ServerSocket::Connect(BleV2Socket& socket) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
if (closed_) return false;
|
||||
if (socket.IsConnected()) {
|
||||
NEARBY_LOGS(WARNING)
|
||||
<< "Failed to connect to Ble server socket: already connected";
|
||||
return true; // already connected.
|
||||
}
|
||||
// add client socket to the pending list
|
||||
pending_sockets_.insert(&socket);
|
||||
cond_.SignalAll();
|
||||
while (!socket.IsConnected()) {
|
||||
cond_.Wait(&mutex_);
|
||||
if (closed_) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void BleV2ServerSocket::SetCloseNotifier(std::function<void()> notifier) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
close_notifier_ = std::move(notifier);
|
||||
}
|
||||
|
||||
BleV2ServerSocket::~BleV2ServerSocket() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
DoClose();
|
||||
}
|
||||
|
||||
Exception BleV2ServerSocket::Close() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return DoClose();
|
||||
}
|
||||
|
||||
Exception BleV2ServerSocket::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};
|
||||
}
|
||||
|
||||
BleV2Medium::BleV2Medium(api::BluetoothAdapter& adapter)
|
||||
: adapter_(static_cast<BluetoothAdapter*>(&adapter)) {
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.RegisterBleV2Medium(*this);
|
||||
adapter_->SetBleV2Medium(this);
|
||||
MediumEnvironment::Instance().RegisterBleV2Medium(*this);
|
||||
}
|
||||
|
||||
BleV2Medium::~BleV2Medium() {
|
||||
auto& env = MediumEnvironment::Instance();
|
||||
env.UnregisterBleV2Medium(*this);
|
||||
adapter_->SetBleV2Medium(nullptr);
|
||||
MediumEnvironment::Instance().UnregisterBleV2Medium(*this);
|
||||
}
|
||||
|
||||
bool BleV2Medium::StartAdvertising(
|
||||
@@ -125,25 +268,12 @@ std::unique_ptr<api::ble_v2::GattServer> BleV2Medium::StartGattServer(
|
||||
return std::make_unique<GattServer>();
|
||||
}
|
||||
|
||||
bool BleV2Medium::StartListeningForIncomingBleSockets(
|
||||
const api::ble_v2::ServerBleSocketLifeCycleCallback& callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void BleV2Medium::StopListeningForIncomingBleSockets() {}
|
||||
|
||||
std::unique_ptr<api::ble_v2::GattClient> BleV2Medium::ConnectToGattServer(
|
||||
api::ble_v2::BlePeripheral& peripheral, TxPowerLevel tx_power_level,
|
||||
api::ble_v2::ClientGattConnectionCallback callback) {
|
||||
return std::make_unique<GattClient>();
|
||||
}
|
||||
|
||||
std::unique_ptr<BleSocket> BleV2Medium::EstablishBleSocket(
|
||||
api::ble_v2::BlePeripheral* peripheral,
|
||||
const BleSocketLifeCycleCallback& callback) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
|
||||
return is_support_extended_advertisement_;
|
||||
}
|
||||
@@ -244,6 +374,83 @@ void BleV2Medium::GattClient::Disconnect() {
|
||||
is_connection_alive_ = false;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble_v2::BleServerSocket> BleV2Medium::OpenServerSocket(
|
||||
const std::string& service_id) {
|
||||
auto server_socket = std::make_unique<BleV2ServerSocket>(&GetAdapter());
|
||||
server_socket->SetCloseNotifier([this, service_id]() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
server_sockets_.erase(service_id);
|
||||
});
|
||||
NEARBY_LOGS(INFO) << "G3 Ble Adding server socket: medium=" << this
|
||||
<< ", service_id=" << service_id;
|
||||
absl::MutexLock lock(&mutex_);
|
||||
server_sockets_.insert({service_id, server_socket.get()});
|
||||
return server_socket;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble_v2::BleSocket> BleV2Medium::Connect(
|
||||
const std::string& service_id, TxPowerLevel tx_power_level,
|
||||
api::ble_v2::BlePeripheral& remote_peripheral,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
NEARBY_LOGS(INFO) << "G3 Ble Connect [self]: medium=" << this
|
||||
<< ", adapter=" << &GetAdapter()
|
||||
<< ", peripheral=" << &GetAdapter().GetPeripheralV2()
|
||||
<< ", service_id=" << service_id;
|
||||
// First, find an instance of remote medium, that exposed this peripheral.
|
||||
auto& remote_adapter =
|
||||
static_cast<BleV2Peripheral&>(remote_peripheral).GetAdapter();
|
||||
auto* remote_medium =
|
||||
static_cast<BleV2Medium*>(remote_adapter.GetBleV2Medium());
|
||||
if (!remote_medium) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BleV2ServerSocket* remote_server_socket = nullptr;
|
||||
NEARBY_LOGS(INFO) << "G3 Ble Connect [peer]: medium=" << remote_medium
|
||||
<< ", adapter=" << &remote_adapter
|
||||
<< ", peripheral=" << &remote_peripheral
|
||||
<< ", service_id=" << service_id;
|
||||
// Then, find our server socket context in this medium.
|
||||
{
|
||||
absl::MutexLock medium_lock(&remote_medium->mutex_);
|
||||
auto item = remote_medium->server_sockets_.find(service_id);
|
||||
remote_server_socket =
|
||||
item != server_sockets_.end() ? item->second : nullptr;
|
||||
if (remote_server_socket == nullptr) {
|
||||
NEARBY_LOGS(ERROR)
|
||||
<< "G3 Ble Failed to find Ble Server socket: service_id="
|
||||
<< service_id;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (cancellation_flag->Cancelled()) {
|
||||
NEARBY_LOGS(ERROR) << "G3 BLE Connect: Has been cancelled: "
|
||||
"service_id="
|
||||
<< service_id;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CancellationFlagListener listener(
|
||||
cancellation_flag, [&remote_server_socket]() {
|
||||
NEARBY_LOGS(INFO) << "G3 Ble Cancel Connect.";
|
||||
if (remote_server_socket != nullptr) {
|
||||
remote_server_socket->Close();
|
||||
}
|
||||
});
|
||||
|
||||
auto socket = std::make_unique<BleV2Socket>(&GetAdapter());
|
||||
// Finally, Request to connect to this socket.
|
||||
if (!remote_server_socket->Connect(*socket)) {
|
||||
NEARBY_LOGS(ERROR) << "G3 Ble Failed to connect to existing Ble "
|
||||
"Server socket: service_id="
|
||||
<< service_id;
|
||||
return nullptr;
|
||||
}
|
||||
NEARBY_LOGS(INFO) << "G3 Ble Connect to socket=" << socket.get();
|
||||
return socket;
|
||||
}
|
||||
|
||||
} // namespace g3
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#ifndef PLATFORM_IMPL_G3_BLE_V2_H_
|
||||
#define PLATFORM_IMPL_G3_BLE_V2_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -23,12 +24,129 @@
|
||||
#include "internal/platform/byte_array.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/implementation/g3/bluetooth_adapter.h"
|
||||
#include "internal/platform/implementation/g3/pipe.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace g3 {
|
||||
|
||||
// TODO(b/213691253): Add g3 BleV2 medium tests after more functions are ready.
|
||||
class BleV2nMedium;
|
||||
|
||||
class BleV2Socket : public api::ble_v2::BleSocket {
|
||||
public:
|
||||
explicit BleV2Socket(BluetoothAdapter* adapter) : adapter_(adapter) {}
|
||||
BleV2Socket(const BleV2Socket&) = default;
|
||||
BleV2Socket& operator=(const BleV2Socket&) = default;
|
||||
BleV2Socket(BleV2Socket&&) = default;
|
||||
BleV2Socket& operator=(BleV2Socket&&) = default;
|
||||
~BleV2Socket() override;
|
||||
|
||||
// Connect to another BleSocket, to form a functional low-level channel.
|
||||
// from this point on, and until Close is called, connection exists.
|
||||
void Connect(BleV2Socket& other) ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// 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 address of a remote BleSocket or nullptr.
|
||||
BleV2Socket* GetRemoteSocket() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns true if connection exists to the (possibly closed) remote socket.
|
||||
bool IsConnected() const 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.
|
||||
BleV2Peripheral* GetRemotePeripheral() override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
void DoClose() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
// Returns true if connection exists to the (possibly closed) remote socket.
|
||||
bool IsConnectedLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
// Returns InputStream of our side of a connection.
|
||||
// This is what the remote side is supposed to read from.
|
||||
// This is a helper for GetInputStream() method.
|
||||
InputStream& GetLocalInputStream() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Returns OutputStream of our side of a connection.
|
||||
// This is what the local size is supposed to write to.
|
||||
// This is a helper for GetOutputStream() method.
|
||||
OutputStream& GetLocalOutputStream() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Output pipe is initialized by constructor, it remains always valid, until
|
||||
// it is closed. it represents output part of a local socket. Input part of a
|
||||
// local socket comes from the peer socket, after connection.
|
||||
std::shared_ptr<Pipe> output_{new Pipe};
|
||||
std::shared_ptr<Pipe> input_;
|
||||
mutable absl::Mutex mutex_;
|
||||
BluetoothAdapter* adapter_ = nullptr; // Our Adapter. Read only.
|
||||
BleV2Socket* remote_socket_ ABSL_GUARDED_BY(mutex_) = nullptr;
|
||||
bool closed_ ABSL_GUARDED_BY(mutex_) = false;
|
||||
};
|
||||
|
||||
class BleV2ServerSocket : public api::ble_v2::BleServerSocket {
|
||||
public:
|
||||
explicit BleV2ServerSocket(BluetoothAdapter* adapter) : adapter_(adapter) {}
|
||||
BleV2ServerSocket(const BleV2ServerSocket&) = default;
|
||||
BleV2ServerSocket& operator=(const BleV2ServerSocket&) = default;
|
||||
BleV2ServerSocket(BleV2ServerSocket&&) = default;
|
||||
BleV2ServerSocket& operator=(BleV2ServerSocket&&) = default;
|
||||
~BleV2ServerSocket() override;
|
||||
|
||||
// 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::ble_v2::BleSocket> Accept() override
|
||||
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(BleV2Socket& 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(std::function<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() override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
Exception DoClose() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
mutable absl::Mutex mutex_;
|
||||
absl::CondVar cond_;
|
||||
BluetoothAdapter* adapter_ = nullptr; // Our Adapter. Read only.
|
||||
absl::flat_hash_set<BleV2Socket*> pending_sockets_ ABSL_GUARDED_BY(mutex_);
|
||||
std::function<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 BleV2Medium : public api::ble_v2::BleMedium {
|
||||
public:
|
||||
@@ -50,20 +168,27 @@ class BleV2Medium : public api::ble_v2::BleMedium {
|
||||
std::unique_ptr<api::ble_v2::GattServer> StartGattServer(
|
||||
api::ble_v2::ServerGattConnectionCallback callback) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
bool StartListeningForIncomingBleSockets(
|
||||
const api::ble_v2::ServerBleSocketLifeCycleCallback& callback) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
void StopListeningForIncomingBleSockets() override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
std::unique_ptr<api::ble_v2::GattClient> ConnectToGattServer(
|
||||
api::ble_v2::BlePeripheral& peripheral,
|
||||
api::ble_v2::TxPowerLevel tx_power_level,
|
||||
api::ble_v2::ClientGattConnectionCallback callback) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
std::unique_ptr<api::ble_v2::BleSocket> EstablishBleSocket(
|
||||
api::ble_v2::BlePeripheral* peripheral,
|
||||
const api::ble_v2::BleSocketLifeCycleCallback& callback) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Open server socket to listen for incoming connection.
|
||||
//
|
||||
// On success, returns a new BleServerSocket.
|
||||
// On error, returns nullptr.
|
||||
std::unique_ptr<api::ble_v2::BleServerSocket> OpenServerSocket(
|
||||
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::ble_v2::BleSocket> Connect(
|
||||
const std::string& service_id, api::ble_v2::TxPowerLevel tx_power_level,
|
||||
api::ble_v2::BlePeripheral& remote_peripheral,
|
||||
CancellationFlag* cancellation_flag) override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
bool IsExtendedAdvertisementsAvailable() override;
|
||||
|
||||
@@ -116,6 +241,8 @@ class BleV2Medium : public api::ble_v2::BleMedium {
|
||||
|
||||
absl::Mutex mutex_;
|
||||
BluetoothAdapter* adapter_; // Our device adapter; read-only.
|
||||
absl::flat_hash_map<std::string, BleV2ServerSocket*> server_sockets_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
// TODO(edwinwu): Adds extended advertisement for testing.
|
||||
bool is_support_extended_advertisement_ = false;
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "internal/platform/implementation/g3/bluetooth_adapter.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "internal/platform/implementation/g3/bluetooth_classic.h"
|
||||
#include "internal/platform/medium_environment.h"
|
||||
@@ -78,6 +79,10 @@ void BluetoothAdapter::SetBleMedium(api::BleMedium* medium) {
|
||||
ble_medium_ = medium;
|
||||
}
|
||||
|
||||
void BluetoothAdapter::SetBleV2Medium(api::ble_v2::BleMedium* medium) {
|
||||
ble_v2_medium_ = medium;
|
||||
}
|
||||
|
||||
bool BluetoothAdapter::SetStatus(Status status) {
|
||||
BluetoothAdapter::ScanMode mode;
|
||||
bool enabled = status == Status::kEnabled;
|
||||
|
||||
@@ -138,6 +138,9 @@ class BluetoothAdapter : public api::BluetoothAdapter {
|
||||
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_; }
|
||||
|
||||
void SetMacAddress(std::string& mac_address) { mac_address_ = mac_address; }
|
||||
|
||||
private:
|
||||
@@ -147,6 +150,7 @@ class BluetoothAdapter : public api::BluetoothAdapter {
|
||||
BleV2Peripheral peripheral_v2_{this};
|
||||
api::BluetoothClassicMedium* bluetooth_classic_medium_ = nullptr;
|
||||
api::BleMedium* ble_medium_ = nullptr;
|
||||
api::ble_v2::BleMedium* ble_v2_medium_ = nullptr;
|
||||
std::string mac_address_;
|
||||
ScanMode mode_ ABSL_GUARDED_BY(mutex_) = ScanMode::kNone;
|
||||
std::string name_ ABSL_GUARDED_BY(mutex_) = "unknown G3 BT device";
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace {
|
||||
|
||||
using ::location::nearby::api::ble_v2::AdvertiseParameters;
|
||||
using ::location::nearby::api::ble_v2::BleAdvertisementData;
|
||||
using ::location::nearby::api::ble_v2::BleServerSocket;
|
||||
using ::location::nearby::api::ble_v2::BleSocket;
|
||||
using ::location::nearby::api::ble_v2::BleSocketLifeCycleCallback;
|
||||
using ::location::nearby::api::ble_v2::GattClient;
|
||||
using ::location::nearby::api::ble_v2::ServerGattConnectionCallback;
|
||||
using ::location::nearby::api::ble_v2::TxPowerLevel;
|
||||
@@ -251,22 +251,21 @@ std::unique_ptr<api::ble_v2::GattServer> BleV2Medium::StartGattServer(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool BleV2Medium::StartListeningForIncomingBleSockets(
|
||||
const api::ble_v2::ServerBleSocketLifeCycleCallback& callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void BleV2Medium::StopListeningForIncomingBleSockets() {}
|
||||
|
||||
std::unique_ptr<GattClient> BleV2Medium::ConnectToGattServer(
|
||||
api::ble_v2::BlePeripheral& peripheral, TxPowerLevel tx_power_level,
|
||||
api::ble_v2::ClientGattConnectionCallback callback) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<BleSocket> BleV2Medium::EstablishBleSocket(
|
||||
api::ble_v2::BlePeripheral* peripheral,
|
||||
const BleSocketLifeCycleCallback& callback) {
|
||||
std::unique_ptr<api::ble_v2::BleServerSocket> BleV2Medium::OpenServerSocket(
|
||||
const std::string& service_id) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<api::ble_v2::BleSocket> BleV2Medium::Connect(
|
||||
const std::string& service_id, TxPowerLevel tx_power_level,
|
||||
api::ble_v2::BlePeripheral& remote_peripheral,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,20 +58,17 @@ class BleV2Medium : public api::ble_v2::BleMedium {
|
||||
std::unique_ptr<api::ble_v2::GattServer> StartGattServer(
|
||||
api::ble_v2::ServerGattConnectionCallback callback) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
bool StartListeningForIncomingBleSockets(
|
||||
const api::ble_v2::ServerBleSocketLifeCycleCallback& callback) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
void StopListeningForIncomingBleSockets() override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
std::unique_ptr<api::ble_v2::GattClient> ConnectToGattServer(
|
||||
api::ble_v2::BlePeripheral& peripheral,
|
||||
api::ble_v2::TxPowerLevel tx_power_level,
|
||||
api::ble_v2::ClientGattConnectionCallback callback) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
std::unique_ptr<api::ble_v2::BleSocket> EstablishBleSocket(
|
||||
api::ble_v2::BlePeripheral* peripheral,
|
||||
const api::ble_v2::BleSocketLifeCycleCallback& callback) override
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
std::unique_ptr<api::ble_v2::BleServerSocket> OpenServerSocket(
|
||||
const std::string& service_id) override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
std::unique_ptr<api::ble_v2::BleSocket> Connect(
|
||||
const std::string& service_id, api::ble_v2::TxPowerLevel tx_power_level,
|
||||
api::ble_v2::BlePeripheral& remote_peripheral,
|
||||
CancellationFlag* cancellation_flag) override ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
bool IsExtendedAdvertisementsAvailable() override { return false; }
|
||||
|
||||
BluetoothAdapter& GetAdapter() { return *adapter_; }
|
||||
|
||||
Reference in New Issue
Block a user