Merged from google/nearby main

This commit is contained in:
lasan
2024-10-22 11:27:36 +05:30
988 changed files with 175061 additions and 15634 deletions
+264 -200
View File
@@ -16,13 +16,27 @@
licenses(["notice"])
cc_library(
name = "logging",
hdrs = [
"logging.h",
],
visibility = [
"//:__subpackages__",
],
deps = [
"@com_google_absl//absl/log",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/log:globals",
],
)
cc_library(
name = "base",
srcs = [
"base64_utils.cc",
"bluetooth_utils.cc",
"input_stream.cc",
"nsd_service_info.cc",
"prng.cc",
],
hdrs = [
@@ -46,20 +60,14 @@ cc_library(
],
copts = ["-DCORE_ADAPTER_DLL"],
visibility = [
"//connections:__subpackages__",
"//fastpair:__subpackages__",
"//internal/auth:__subpackages__",
"//internal/platform:__subpackages__",
"//internal/platform/implementation:__subpackages__",
"//internal/preferences:__subpackages__",
"//internal/weave:__subpackages__",
"//location/nearby/cpp:__subpackages__",
"//presence:__subpackages__",
"//third_party/nearby/sharing:__subpackages__",
"//:__subpackages__",
"//chrome/chromeos/assistant/data_migration/lib:__pkg__",
],
deps = [
"//proto:connections_enums_cc_proto",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/meta:type_traits",
"@com_google_absl//absl/strings",
@@ -77,7 +85,6 @@ cc_library(
],
hdrs = [
"base_input_stream.h",
"base_mutex_lock.h",
"byte_utils.h",
],
visibility = [
@@ -86,7 +93,6 @@ cc_library(
],
deps = [
":base",
"//internal/platform/implementation:types",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/strings:str_format",
],
@@ -113,37 +119,6 @@ cc_library(
],
)
cc_library(
name = "connection_info",
srcs = [
"ble_connection_info.cc",
"bluetooth_connection_info.cc",
"connection_info.cc",
"wifi_lan_connection_info.cc",
],
hdrs = [
"ble_connection_info.h",
"bluetooth_connection_info.h",
"connection_info.h",
"wifi_lan_connection_info.h",
],
visibility = [
"//connections/implementation:__pkg__",
"//connections/v3:__pkg__",
"//internal/interop:__pkg__",
"//presence:__subpackages__",
],
deps = [
":types",
"//proto:connections_enums_cc_proto",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/types:variant",
],
)
cc_library(
name = "error_code_recorder",
srcs = [
@@ -155,7 +130,7 @@ cc_library(
],
visibility = ["//connections/implementation:__subpackages__"],
deps = [
":types",
":logging",
"//proto:connections_enums_cc_proto",
"//proto/errorcode:error_code_enums_cc_proto",
"@com_google_absl//absl/functional:any_invocable",
@@ -177,11 +152,196 @@ cc_library(
"//presence:__subpackages__",
],
deps = [
"//internal/platform/implementation:types",
":base",
"@boringssl//:crypto",
"@com_google_absl//absl/strings",
],
)
cc_library(
name = "connection_info",
srcs = [
"ble_connection_info.cc",
"bluetooth_connection_info.cc",
"connection_info.cc",
"wifi_lan_connection_info.cc",
],
hdrs = [
"ble_connection_info.h",
"bluetooth_connection_info.h",
"connection_info.h",
"wifi_lan_connection_info.h",
],
visibility = [
"//connections/implementation:__pkg__",
"//connections/v3:__pkg__",
"//internal/interop:__pkg__",
"//presence:__subpackages__",
],
deps = [
":logging",
"//proto:connections_enums_cc_proto",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/types:variant",
],
)
cc_library(
name = "types",
srcs = [
"blocking_queue_stream.cc",
"clock_impl.cc",
"device_info_impl.cc",
"monitored_runnable.cc",
"pending_job_registry.cc",
"pipe.cc",
"task_runner_impl.cc",
"timer_impl.cc",
],
hdrs = [
"array_blocking_queue.h",
"atomic_boolean.h",
"atomic_reference.h",
"blocking_queue_stream.h",
"borrowable.h",
"cancelable.h",
"cancelable_alarm.h",
"cancellable_task.h",
"clock.h",
"clock_impl.h",
"condition_variable.h",
"count_down_latch.h",
"crypto.h",
"device_info.h",
"device_info_impl.h",
"direct_executor.h",
"file.h",
"future.h",
"lockable.h",
"logging.h",
"monitored_runnable.h",
"multi_thread_executor.h",
"mutex.h",
"mutex_lock.h",
"pending_job_registry.h",
"pipe.h",
"scheduled_executor.h",
"settable_future.h",
"single_thread_executor.h",
"submittable_executor.h",
"system_clock.h",
"task_runner.h",
"task_runner_impl.h",
"thread_check_callable.h",
"thread_check_runnable.h",
"timer.h",
"timer_impl.h",
],
visibility = [
"//connections:__subpackages__",
"//fastpair:__subpackages__",
"//internal/account:__subpackages__",
"//internal/auth:__subpackages__",
"//internal/auth/credential_store:__subpackages__",
"//internal/base:__subpackages__",
"//internal/crypto:__subpackages__",
"//internal/data:__subpackages__",
"//internal/flags:__subpackages__",
"//internal/interop:__pkg__",
"//internal/network:__subpackages__",
"//internal/platform:__subpackages__",
"//internal/platform/implementation/g3:__pkg__",
"//internal/platform/implementation/windows:__subpackages__",
"//internal/preferences:__subpackages__",
"//internal/proto/analytics:__subpackages__",
"//internal/test:__subpackages__",
"//internal/weave:__subpackages__",
"//location/nearby/apps:__subpackages__",
"//location/nearby/cpp:__subpackages__",
"//location/nearby/sharing/sdk:__subpackages__",
"//location/nearby/testing/nearby_native:__subpackages__",
"//presence:__subpackages__",
"//sharing:__subpackages__",
],
deps = [
":base",
":util",
"//internal/base:files",
"//internal/crypto_cros",
"//internal/flags:nearby_flags",
"//internal/platform/flags:platform_flags",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:types",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/log",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/log:globals",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:span",
],
)
cc_library(
name = "comm",
srcs = [
"ble.cc",
"ble_v2.cc",
"bluetooth_classic.cc",
"credential_storage_impl.cc",
"file.cc",
"wifi_direct.cc",
"wifi_hotspot.cc",
"wifi_lan.cc",
],
hdrs = [
"ble.h",
"ble_v2.h",
"bluetooth_adapter.h",
"bluetooth_classic.h",
"credential_storage_impl.h",
"webrtc.h",
"wifi.h",
"wifi_direct.h",
"wifi_hotspot.h",
"wifi_lan.h",
],
copts = [
"-DCORE_ADAPTER_DLL",
"-DNO_WEBRTC",
],
visibility = [
"//connections:__subpackages__",
"//fastpair:__subpackages__",
"//internal/platform/implementation:__subpackages__",
"//internal/test:__subpackages__",
"//presence:__subpackages__",
],
deps = [
":base",
":cancellation_flag",
":types",
":uuid",
"//internal/base",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:wifi_utils",
# TODO: Support WebRTC
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/types:optional",
],
)
cc_library(
name = "test_util",
testonly = True,
@@ -196,7 +356,6 @@ cc_library(
"//fastpair:__subpackages__",
"//internal/platform/implementation:__subpackages__",
"//presence:__subpackages__",
"//third_party/nearby/sharing:__subpackages__",
],
deps = [
":base",
@@ -205,10 +364,13 @@ cc_library(
"//internal/base",
"//internal/platform/implementation:comm",
"//internal/test",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:optional",
],
)
@@ -275,150 +437,55 @@ cc_test(
],
)
cc_library(
name = "types",
cc_test(
name = "public_device_test",
size = "small",
timeout = "moderate",
srcs = [
"clock_impl.cc",
"device_info_impl.cc",
"monitored_runnable.cc",
"pending_job_registry.cc",
"pipe.cc",
"task_runner_impl.cc",
"timer_impl.cc",
],
hdrs = [
"atomic_boolean.h",
"atomic_reference.h",
"borrowable.h",
"cancelable.h",
"cancelable_alarm.h",
"cancellable_task.h",
"clock.h",
"clock_impl.h",
"condition_variable.h",
"count_down_latch.h",
"crypto.h",
"device_info.h",
"device_info_impl.h",
"direct_executor.h",
"file.h",
"future.h",
"lockable.h",
"logging.h",
"monitored_runnable.h",
"multi_thread_executor.h",
"mutex.h",
"mutex_lock.h",
"pending_job_registry.h",
"pipe.h",
"scheduled_executor.h",
"settable_future.h",
"single_thread_executor.h",
"submittable_executor.h",
"system_clock.h",
"task_runner.h",
"task_runner_impl.h",
"thread_check_callable.h",
"thread_check_runnable.h",
"timer.h",
"timer_impl.h",
],
visibility = [
"//connections:__subpackages__",
"//fastpair:__subpackages__",
"//internal/account:__subpackages__",
"//internal/auth:__subpackages__",
"//internal/auth/credential_store:__subpackages__",
"//internal/base:__subpackages__",
"//internal/data:__subpackages__",
"//internal/flags:__subpackages__",
"//internal/interop:__pkg__",
"//internal/network:__subpackages__",
"//internal/platform:__subpackages__",
"//internal/platform/implementation/g3:__pkg__",
"//internal/platform/implementation/linux:__subpackages__",
"//internal/platform/implementation/windows:__subpackages__",
"//internal/preferences:__subpackages__",
"//internal/proto/analytics:__subpackages__",
"//internal/test:__subpackages__",
"//internal/weave:__subpackages__",
"//location/nearby/analytics/cpp:__subpackages__",
"//location/nearby/apps:__subpackages__",
"//location/nearby/cpp:__subpackages__",
"//location/nearby/testing/nearby_native:__subpackages__",
"//presence:__subpackages__",
"//third_party/nearby/sharing:__subpackages__",
],
deps = [
":base",
":util",
"//internal/crypto_cros",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:types",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_glog//:glog",
],
)
cc_library(
name = "comm",
srcs = [
"ble.cc",
"ble_v2.cc",
"bluetooth_classic.cc",
"credential_storage_impl.cc",
"file.cc",
"wifi_direct.cc",
"wifi_hotspot.cc",
"wifi_lan.cc",
"wifi_utils.cc",
],
hdrs = [
"ble.h",
"ble_v2.h",
"bluetooth_adapter.h",
"bluetooth_classic.h",
"credential_storage_impl.h",
"webrtc.h",
"wifi.h",
"wifi_direct.h",
"wifi_hotspot.h",
"wifi_lan.h",
"wifi_utils.h",
],
copts = [
"-DCORE_ADAPTER_DLL",
"-DNO_WEBRTC",
],
visibility = [
"//connections:__subpackages__",
"//fastpair:__subpackages__",
"//internal/platform/implementation:__subpackages__",
"//internal/test:__subpackages__",
"//presence:__subpackages__",
"ble_connection_info_test.cc",
"ble_test.cc",
"ble_v2_test.cc",
"bluetooth_adapter_test.cc",
"bluetooth_classic_test.cc",
"bluetooth_connection_info_test.cc",
"pipe_test.cc",
"wifi_direct_test.cc",
"wifi_hotspot_test.cc",
"wifi_lan_connection_info_test.cc",
"wifi_lan_test.cc",
"wifi_test.cc",
],
deps = [
":base",
":cancellation_flag",
":comm",
":connection_info",
":test_util",
":types",
":uuid",
"//internal/base",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:platform",
# TODO: Support WebRTC
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/functional:any_invocable",
"//internal/platform/implementation/g3", # build_cleaner: keep
"//proto:connections_enums_cc_proto",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/types:optional",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest_main",
],
)
cc_test(
name = "credential_storage_impl_test",
srcs = ["credential_storage_impl_test.cc"],
deps = [
":comm",
"//internal/platform/implementation:comm",
"//internal/platform/implementation/g3", # build_cleaner: keep
"//internal/proto:credential_cc_proto",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings:string_view",
"@com_google_googletest//:gtest_main",
],
)
@@ -429,38 +496,22 @@ cc_test(
srcs = [
"atomic_boolean_test.cc",
"atomic_reference_test.cc",
"ble_connection_info_test.cc",
"ble_test.cc",
"ble_v2_test.cc",
"bluetooth_adapter_test.cc",
"bluetooth_classic_test.cc",
"bluetooth_connection_info_test.cc",
"borrowable_test.cc",
"cancelable_alarm_test.cc",
"condition_variable_test.cc",
"connection_info_test.cc",
"count_down_latch_test.cc",
"credential_storage_impl_test.cc",
"crypto_test.cc",
"direct_executor_test.cc",
"future_test.cc",
"logging_test.cc",
"multi_thread_executor_test.cc",
"mutex_test.cc",
"pipe_test.cc",
"scheduled_executor_test.cc",
"single_thread_executor_test.cc",
"task_runner_impl_test.cc",
"timer_impl_test.cc",
"uuid_test.cc",
"wifi_direct_test.cc",
"wifi_hotspot_test.cc",
"wifi_lan_connection_info_test.cc",
"wifi_lan_test.cc",
"wifi_test.cc",
"wifi_utils_test.cc",
],
copts = ["-DCORE_ADAPTER_DLL"],
shard_count = 16,
deps = [
":base",
@@ -470,16 +521,29 @@ cc_test(
":test_util",
":types",
":uuid",
"//internal/crypto_cros",
"//internal/flags:nearby_flags",
"//internal/platform/flags:platform_flags",
"//internal/platform/implementation:comm",
"//internal/platform/implementation/g3", # build_cleaner: keep
"//internal/proto:credential_cc_proto",
"//internal/test",
"//proto:connections_enums_cc_proto",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/log",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:variant",
"@com_google_googletest//:gtest_main",
],
] + select({
"@platforms//os:windows": [
"//internal/platform/implementation/windows",
],
"//conditions:default": [
"//internal/platform/implementation/g3",
],
}),
)
+104
View File
@@ -0,0 +1,104 @@
// Copyright 2024 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_ARRAY_BLOCKING_QUEUE_H_
#define PLATFORM_PUBLIC_ARRAY_BLOCKING_QUEUE_H_
#include <cstddef>
#include <optional>
#include <queue>
#include "internal/platform/condition_variable.h"
#include "internal/platform/logging.h"
#include "internal/platform/mutex.h"
#include "internal/platform/mutex_lock.h"
namespace nearby {
/**
* Payload from different services/clients will be put into an
* ArrayBlockingQueue before sending to ensure each client has equal chance to
* send its data. Since C++ doesn't provide ArrayBlockingQueue as Java, we
* implement one here.
*/
template <typename T>
class ArrayBlockingQueue {
public:
explicit ArrayBlockingQueue(size_t capacity) : capacity_(capacity) {}
void Put(const T& value) {
MutexLock lock(&queue_mutex_);
if (queue_.size() >= capacity_) {
has_space_.Wait();
}
queue_.push(value);
NEARBY_LOGS(INFO) << "ArrayBlockingQueue::Put()";
has_data_.Notify();
}
T Take() {
MutexLock lock(&queue_mutex_);
if (queue_.empty()) {
has_data_.Wait();
}
T front = queue_.front();
queue_.pop();
NEARBY_LOGS(INFO) << "ArrayBlockingQueue::Take()";
has_space_.Notify();
return front;
}
bool TryPut(const T& value) {
MutexLock lock(&queue_mutex_);
if (queue_.size() < capacity_) {
queue_.push(value);
has_data_.Notify();
return true;
}
return false;
}
// Returns std::nullopt if the queue is empty.
std::optional<T> TryTake() {
MutexLock lock(&queue_mutex_);
if (!queue_.empty()) {
T front = queue_.front();
queue_.pop();
has_space_.Notify();
return front;
}
return std::nullopt;
}
size_t Size() const {
MutexLock lock(&queue_mutex_);
return queue_.size();
}
bool Empty() const {
MutexLock lock(&queue_mutex_);
return queue_.empty();
}
private:
std::queue<T> queue_;
mutable Mutex queue_mutex_;
ConditionVariable has_data_{&queue_mutex_};
ConditionVariable has_space_{&queue_mutex_};
const size_t capacity_;
};
} // namespace nearby
#endif // PLATFORM_PUBLIC_ARRAY_BLOCKING_QUEUE_H_
+1 -2
View File
@@ -27,9 +27,8 @@ namespace nearby {
// cpp/platform/api/atomic_boolean.h
class AtomicBoolean final : public api::AtomicBoolean {
public:
using Platform = api::ImplementationPlatform;
explicit AtomicBoolean(bool value = false)
: impl_(Platform::CreateAtomicBoolean(value)) {}
: impl_(api::ImplementationPlatform::CreateAtomicBoolean(value)) {}
~AtomicBoolean() override = default;
AtomicBoolean(AtomicBoolean&&) = default;
AtomicBoolean& operator=(AtomicBoolean&&) = default;
-2
View File
@@ -14,8 +14,6 @@
#include "internal/platform/atomic_boolean.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
namespace nearby {
+43
View File
@@ -14,8 +14,16 @@
#include "internal/platform/base64_utils.h"
#include <cstdint>
#include <string>
#include <utility>
#include "absl/strings/escaping.h"
#include "absl/strings/string_view.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
namespace nearby {
@@ -36,4 +44,39 @@ ByteArray Base64Utils::Decode(absl::string_view base64_string) {
return ByteArray(decoded_string.data(), decoded_string.size());
}
std::int32_t Base64Utils::BytesToInt(const ByteArray& bytes) {
const char* int_bytes = bytes.data();
std::int32_t result = 0;
result |= (static_cast<std::int32_t>(int_bytes[0]) & 0x0FF) << 24;
result |= (static_cast<std::int32_t>(int_bytes[1]) & 0x0FF) << 16;
result |= (static_cast<std::int32_t>(int_bytes[2]) & 0x0FF) << 8;
result |= (static_cast<std::int32_t>(int_bytes[3]) & 0x0FF);
return result;
}
ByteArray Base64Utils::IntToBytes(std::int32_t value) {
char int_bytes[sizeof(std::int32_t)];
int_bytes[0] = static_cast<char>((value >> 24) & 0x0FF);
int_bytes[1] = static_cast<char>((value >> 16) & 0x0FF);
int_bytes[2] = static_cast<char>((value >> 8) & 0x0FF);
int_bytes[3] = static_cast<char>((value) & 0x0FF);
return ByteArray(int_bytes, sizeof(int_bytes));
}
ExceptionOr<std::int32_t> Base64Utils::ReadInt(InputStream* reader) {
ExceptionOr<ByteArray> read_bytes = reader->ReadExactly(sizeof(std::int32_t));
if (!read_bytes.ok()) {
return ExceptionOr<std::int32_t>(read_bytes.exception());
}
return ExceptionOr<std::int32_t>(
BytesToInt(std::move(read_bytes.result())));
}
Exception Base64Utils::WriteInt(OutputStream* writer, std::int32_t value) {
return writer->Write(IntToBytes(value));
}
} // namespace nearby
+9
View File
@@ -15,8 +15,13 @@
#ifndef PLATFORM_BASE_BASE64_UTILS_H_
#define PLATFORM_BASE_BASE64_UTILS_H_
#include <cstdint>
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
namespace nearby {
@@ -24,6 +29,10 @@ class Base64Utils {
public:
static std::string Encode(const ByteArray& bytes);
static ByteArray Decode(absl::string_view base64_string);
static std::int32_t BytesToInt(const ByteArray& bytes);
static ByteArray IntToBytes(std::int32_t value);
static ExceptionOr<std::int32_t> ReadInt(InputStream* reader);
static Exception WriteInt(OutputStream* writer, std::int32_t value);
};
} // namespace nearby
+4
View File
@@ -15,6 +15,10 @@
#ifndef PLATFORM_BASE_BASE_INPUT_STREAM_H_
#define PLATFORM_BASE_BASE_INPUT_STREAM_H_
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
#include "internal/platform/input_stream.h"
-38
View File
@@ -1,38 +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_BASE_BASE_MUTEX_LOCK_H_
#define PLATFORM_BASE_BASE_MUTEX_LOCK_H_
#include "absl/base/thread_annotations.h"
#include "internal/platform/implementation/mutex.h"
namespace nearby {
// An RAII mechanism to acquire a Lock over a block of code.
class ABSL_SCOPED_LOCKABLE BaseMutexLock final {
public:
explicit BaseMutexLock(api::Mutex* mutex) ABSL_EXCLUSIVE_LOCK_FUNCTION(mutex)
: mutex_(mutex) {
mutex_->Lock();
}
~BaseMutexLock() ABSL_UNLOCK_FUNCTION() { mutex_->Unlock(); }
private:
api::Mutex* mutex_;
};
} // namespace nearby
#endif // PLATFORM_BASE_BASE_MUTEX_LOCK_H_
+25 -17
View File
@@ -14,6 +14,13 @@
#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"
@@ -49,13 +56,11 @@ bool BleMedium::StartScanning(
auto pair = peripherals_.emplace(
&peripheral, absl::make_unique<ScanningInfo>());
auto& context = *pair.first->second;
if (pair.second) {
context.peripheral = BlePeripheral(&peripheral);
discovered_peripheral_callback_.peripheral_discovered_cb(
context.peripheral, service_id,
context.peripheral.GetAdvertisementBytes(service_id),
fast_advertisement);
}
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,
@@ -64,8 +69,9 @@ bool BleMedium::StartScanning(
if (peripherals_.empty()) return;
auto context = peripherals_.find(&peripheral);
if (context == peripherals_.end()) return;
NEARBY_LOG(INFO, "Removing peripheral=%p, impl=%p",
&(context->second->peripheral), &peripheral);
NEARBY_LOGS(INFO) << "Removing peripheral="
<< context->second->peripheral.GetName()
<< ", impl=" << &peripheral;
discovered_peripheral_callback_.peripheral_lost_cb(
context->second->peripheral, service_id);
},
@@ -77,7 +83,7 @@ bool BleMedium::StopScanning(const std::string& service_id) {
MutexLock lock(&mutex_);
discovered_peripheral_callback_ = {};
peripherals_.clear();
NEARBY_LOG(INFO, "Ble Scanning disabled: impl=%p", &GetImpl());
NEARBY_LOGS(INFO) << "Ble Scanning disabled: impl=" << &GetImpl();
}
return impl_->StopScanning(service_id);
}
@@ -96,12 +102,12 @@ bool BleMedium::StartAcceptingConnections(const std::string& service_id,
&socket, std::make_unique<AcceptedConnectionInfo>());
auto& context = *pair.first->second;
if (!pair.second) {
NEARBY_LOG(INFO, "Accepting (again) socket=%p, impl=%p",
&context.socket, &socket);
NEARBY_LOGS(INFO) << "Accepting (again) socket=" << &context.socket
<< ", impl=" << &socket;
} else {
context.socket = BleSocket(&socket);
NEARBY_LOG(INFO, "Accepting socket=%p, impl=%p", &context.socket,
&socket);
NEARBY_LOGS(INFO)
<< "Accepting socket=" << &context.socket << ", impl=" << &socket;
}
if (accepted_connection_callback_) {
accepted_connection_callback_(context.socket, service_id);
@@ -114,7 +120,8 @@ bool BleMedium::StopAcceptingConnections(const std::string& service_id) {
MutexLock lock(&mutex_);
accepted_connection_callback_ = nullptr;
sockets_.clear();
NEARBY_LOG(INFO, "Ble accepted connection disabled: impl=%p", &GetImpl());
NEARBY_LOGS(INFO) << "Ble accepted connection disabled: impl="
<< &GetImpl();
}
return impl_->StopAcceptingConnections(service_id);
}
@@ -124,8 +131,9 @@ BleSocket BleMedium::Connect(BlePeripheral& peripheral,
CancellationFlag* cancellation_flag) {
{
MutexLock lock(&mutex_);
NEARBY_LOG(INFO, "BleMedium::Connect: peripheral=%p [impl=%p]", &peripheral,
&peripheral.GetImpl());
NEARBY_LOGS(INFO) << "BleMedium::Connect: peripheral="
<< peripheral.GetName()
<< ",impl=" << &peripheral.GetImpl();
}
return BleSocket(
impl_->Connect(peripheral.GetImpl(), service_id, cancellation_flag));
+16 -14
View File
@@ -15,10 +15,14 @@
#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"
@@ -74,11 +78,10 @@ TEST_P(BleMediumTest, CanStartAcceptingConnectionsAndConnect) {
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
NEARBY_LOG(
INFO,
"Peripheral discovered: %s, %p, fast advertisement: %d",
peripheral.GetName().c_str(), &peripheral,
fast_advertisement);
NEARBY_LOGS(INFO)
<< "Discovered peripheral=" << peripheral.GetName()
<< ", impl=" << &peripheral.GetImpl()
<< ", fast advertisement=" << fast_advertisement;
discovered_peripheral = &peripheral;
found_latch.CountDown();
},
@@ -87,8 +90,8 @@ TEST_P(BleMediumTest, CanStartAcceptingConnectionsAndConnect) {
fast_advertisement_service_uuid);
ble_b.StartAcceptingConnections(
service_id, [&](BleSocket socket, const std::string& service_id) {
NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s",
&socket, service_id.c_str());
NEARBY_LOGS(INFO) << "Connection accepted: socket=" << &socket
<< ", service_id=" << service_id;
accepted_latch.CountDown();
});
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
@@ -133,11 +136,10 @@ TEST_P(BleMediumTest, CanCancelConnect) {
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
NEARBY_LOG(
INFO,
"Peripheral discovered: %s, %p, fast advertisement: %d",
peripheral.GetName().c_str(), &peripheral,
fast_advertisement);
NEARBY_LOGS(INFO)
<< "Discovered peripheral=" << peripheral.GetName()
<< ", impl=" << &peripheral.GetImpl()
<< ", fast advertisement=" << fast_advertisement;
discovered_peripheral = &peripheral;
found_latch.CountDown();
},
@@ -146,8 +148,8 @@ TEST_P(BleMediumTest, CanCancelConnect) {
fast_advertisement_service_uuid);
ble_b.StartAcceptingConnections(
service_id, [&](BleSocket socket, const std::string& service_id) {
NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s",
&socket, service_id.c_str());
NEARBY_LOGS(INFO) << "Connection accepted: socket=" << &socket
<< ", service_id=" << service_id;
accepted_latch.CountDown();
});
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
+6 -60
View File
@@ -22,6 +22,7 @@
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/logging.h"
#include "internal/platform/mutex_lock.h"
#include "internal/platform/uuid.h"
namespace nearby {
@@ -43,26 +44,6 @@ bool BleV2Medium::StartAdvertising(
bool BleV2Medium::StopAdvertising() { return impl_->StopAdvertising(); }
std::unique_ptr<api::ble_v2::BleMedium::AdvertisingSession>
BleV2Medium::StartAdvertisingTmp(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertise_set_parameters,
api::ble_v2::BleMedium::AdvertisingCallback callback) {
if (impl_->StartAdvertising(advertising_data, advertise_set_parameters)) {
callback.start_advertising_result(absl::OkStatus());
} else {
callback.start_advertising_result(
absl::InternalError("Failed to start advertising"));
return nullptr;
}
return std::make_unique<api::ble_v2::BleMedium::AdvertisingSession>(
api::ble_v2::BleMedium::AdvertisingSession{.stop_advertising = [this] {
return impl_->StopAdvertising()
? absl::OkStatus()
: absl::InternalError("Failed to stop advertising");
}});
}
std::unique_ptr<api::ble_v2::BleMedium::AdvertisingSession>
BleV2Medium::StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
@@ -111,7 +92,7 @@ bool BleV2Medium::StartScanning(const Uuid& service_uuid,
// prevent the stale data in cache.
peripherals_.clear();
scanning_enabled_ = true;
NEARBY_LOG(INFO, "Ble Scanning enabled; impl=%p", GetImpl());
NEARBY_LOGS(INFO) << "Ble Scanning enabled; impl=" << GetImpl();
}
return success;
}
@@ -126,51 +107,15 @@ bool BleV2Medium::StopScanning() {
scanning_enabled_ = false;
peripherals_.clear();
scan_callback_ = {};
NEARBY_LOG(INFO, "Ble Scanning disabled: impl=%p", GetImpl());
NEARBY_LOGS(INFO) << "Ble Scanning disabled: impl=" << GetImpl();
return impl_->StopScanning();
}
std::unique_ptr<api::ble_v2::BleMedium::ScanningSession>
BleV2Medium::StartScanningTmp(
const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::BleMedium::ScanningCallback callback) {
MutexLock lock(&mutex_);
if (impl_->StartScanning(
service_uuid, tx_power_level,
api::ble_v2::BleMedium::ScanCallback{
.advertisement_found_cb =
[this,
found_callback = std::move(callback.advertisement_found_cb)](
api::ble_v2::BlePeripheral& peripheral,
BleAdvertisementData advertisement_data) mutable {
MutexLock lock(&mutex_);
if (!peripherals_.contains(&peripheral)) {
NEARBY_LOGS(INFO)
<< "Peripheral impl=" << &peripheral
<< " does not exist; add it to the map.";
peripherals_.insert(&peripheral);
}
found_callback(peripheral, advertisement_data);
},
})) {
callback.start_scanning_result(absl::OkStatus());
} else {
callback.start_scanning_result(absl::InternalError("Failed to start scan"));
return nullptr;
}
return std::make_unique<api::ble_v2::BleMedium::ScanningSession>(
api::ble_v2::BleMedium::ScanningSession{.stop_scanning = [this]() {
return impl_->StopScanning()
? absl::OkStatus()
: absl::InternalError("Failed to stop advertising");
}});
}
std::unique_ptr<api::ble_v2::BleMedium::ScanningSession>
BleV2Medium::StartScanning(const Uuid& service_uuid,
api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::BleMedium::ScanningCallback callback) {
NEARBY_LOG(INFO, "platform mutex: %p", &mutex_);
NEARBY_LOGS(INFO) << "platform mutex: " << &mutex_;
return impl_->StartScanning(
service_uuid, tx_power_level,
api::ble_v2::BleMedium::ScanningCallback{
@@ -187,6 +132,7 @@ BleV2Medium::StartScanning(const Uuid& service_uuid,
start_scanning_result(status);
},
.advertisement_found_cb = std::move(callback.advertisement_found_cb),
.advertisement_lost_cb = std::move(callback.advertisement_lost_cb),
});
}
@@ -280,7 +226,7 @@ BleV2Socket BleV2Medium::Connect(const std::string& service_id,
}
bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
return impl_->IsExtendedAdvertisementsAvailable();
return IsValid() && impl_->IsExtendedAdvertisementsAvailable();
}
BleV2Peripheral BleV2Medium::GetRemotePeripheral(
+1 -18
View File
@@ -375,7 +375,7 @@ class BleV2Medium final {
// Returns true once the BLE advertising has been initiated.
// This interface will be deprecated soon.
// TODO(b/271305977) remove this function.
// Use 'unique_ptr<AdvertisingSession> StartAdvertisingTmp' instead.
// Use 'unique_ptr<AdvertisingSession> StartAdvertising' instead.
bool StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertise_parameters);
@@ -383,14 +383,6 @@ class BleV2Medium final {
// TODO(b/271305977) remove this function.
bool StopAdvertising();
// Temp interface for windows client to use before windows has native impl
// for 'unique_ptr<AdvertisingSession> StartAdvertising'.
// TODO(b/271305977) remove this function.
std::unique_ptr<api::ble_v2::BleMedium::AdvertisingSession>
StartAdvertisingTmp(const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertise_set_parameters,
api::ble_v2::BleMedium::AdvertisingCallback callback);
std::unique_ptr<api::ble_v2::BleMedium::AdvertisingSession> StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertise_set_parameters,
@@ -398,8 +390,6 @@ class BleV2Medium final {
// Returns true once the BLE scan has been initiated.
// This interface will be deprecated soon.
// TODO(b/271305977) remove this function.
// Use 'unique_ptr<ScanningSession> StartScanningTmp' instead.
bool StartScanning(const Uuid& service_uuid,
api::ble_v2::TxPowerLevel tx_power_level,
ScanCallback callback);
@@ -411,13 +401,6 @@ class BleV2Medium final {
const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::BleMedium::ScanningCallback callback);
// Temp interface for windows client to use before windows has native impl
// for 'unique_ptr<AdvertisingSession> StartScanning'.
// TODO(b/271305977) remove this function.
std::unique_ptr<api::ble_v2::BleMedium::ScanningSession> StartScanningTmp(
const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::BleMedium::ScanningCallback callback);
// Starts Gatt Server for waiting to client connection.
std::unique_ptr<GattServer> StartGattServer(
ServerGattConnectionCallback callback);
-50
View File
@@ -434,56 +434,6 @@ TEST_F(BleV2MediumTest, CanStartAsyncScanningAndAdvertising) {
env_.Stop();
}
TEST_F(BleV2MediumTest, CanStartAsyncScanningAndAdvertisingWithTmpImpl) {
env_.Start();
BluetoothAdapter adapter_a;
BluetoothAdapter adapter_b;
BleV2Medium ble_a(adapter_a);
BleV2Medium ble_b(adapter_b);
Uuid service_uuid(1234, 5678);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
ByteArray advertisement_header_bytes{std::string(kAdvertisementHeaderString)};
CountDownLatch found_latch(1);
std::unique_ptr<api::ble_v2::BleMedium::ScanningSession> scanning_session =
ble_a.StartScanningTmp(
service_uuid, kTxPowerLevel,
api::ble_v2::BleMedium::ScanningCallback{
.advertisement_found_cb =
[&](api::ble_v2::BlePeripheral& peripheral,
BleAdvertisementData advertisement_data) -> void {
found_latch.CountDown();
},
});
// Succeed to start regular advertisement.
BleAdvertisementData advertising_data;
advertising_data.is_extended_advertisement = false;
advertising_data.service_data = {{service_uuid, advertisement_header_bytes}};
std::unique_ptr<api::ble_v2::BleMedium::AdvertisingSession> adv_session =
ble_b.StartAdvertisingTmp(
advertising_data,
{.tx_power_level = kTxPowerLevel, .is_connectable = true},
{.start_advertising_result = [](absl::Status) {}});
EXPECT_NE(adv_session, nullptr);
EXPECT_TRUE(env_.GetBleV2MediumStatus(*ble_a.GetImpl()).value().is_scanning);
EXPECT_TRUE(
env_.GetBleV2MediumStatus(*ble_b.GetImpl()).value().is_advertising);
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
EXPECT_OK(scanning_session->stop_scanning());
EXPECT_OK(adv_session->stop_advertising());
EXPECT_FALSE(env_.GetBleV2MediumStatus(*ble_a.GetImpl()).value().is_scanning);
EXPECT_FALSE(
env_.GetBleV2MediumStatus(*ble_b.GetImpl()).value().is_advertising);
env_.UnregisterBleV2Medium(*ble_a.GetImpl());
env_.UnregisterBleV2Medium(*ble_b.GetImpl());
EXPECT_EQ(env_.GetBleV2MediumStatus(*ble_a.GetImpl()), absl::nullopt);
EXPECT_EQ(env_.GetBleV2MediumStatus(*ble_b.GetImpl()), absl::nullopt);
env_.Stop();
}
TEST_F(BleV2MediumTest, CanStartGattServer) {
env_.Start();
BluetoothAdapter adapter;
@@ -0,0 +1,72 @@
// Copyright 2024 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/blocking_queue_stream.h"
#include <cstdint>
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
#include "internal/platform/feature_flags.h"
#include "internal/platform/logging.h"
namespace nearby {
BlockingQueueStream::BlockingQueueStream() {
NEARBY_LOGS(INFO) << "Create a BlockingQueueStream with size "
<< FeatureFlags::GetInstance()
.GetFlags()
.blocking_queue_stream_queue_capacity;
}
ExceptionOr<ByteArray> BlockingQueueStream::Read(std::int64_t size) {
if (is_closed_) {
NEARBY_LOGS(INFO)
<< "Failed to read BlockingQueueStream because it was closed.";
return ExceptionOr<ByteArray>(Exception::kInterrupted);
}
NEARBY_LOGS(INFO) << "BlockingQueueStream expect to read " << size
<< " bytes";
return ExceptionOr<ByteArray>(blocking_queue_.Take());
}
void BlockingQueueStream::Write(const ByteArray& bytes) {
if (is_closed_) {
NEARBY_LOGS(INFO)
<< "Failed to write BlockingQueueStream because it was closed.";
return;
}
is_writing_ = true;
blocking_queue_.Put(bytes);
is_writing_ = false;
NEARBY_VLOG(1) << "BlockingQueueStream wrote " << bytes.size() << " bytes";
}
Exception BlockingQueueStream::Close() {
if (is_closed_) {
NEARBY_LOGS(INFO) << "InputBlockingQueueStream has already been closed.";
return {Exception::kSuccess};
}
if (is_writing_) {
NEARBY_LOGS(INFO)
<< "BlockingQueueStream is waiting for writing, read first to unblock";
blocking_queue_.TryTake();
}
blocking_queue_.TryPut(queue_end_);
is_closed_ = true;
NEARBY_LOGS(INFO) << "InputBlockingQueueStream is closed.";
return {Exception::kSuccess};
}
} // namespace nearby
+52
View File
@@ -0,0 +1,52 @@
// Copyright 2024 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_BLOCKING_QUEUE_STREAM_H_
#define PLATFORM_PUBLIC_BLOCKING_QUEUE_STREAM_H_
#include <cstdint>
#include "internal/platform/array_blocking_queue.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
#include "internal/platform/feature_flags.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/mutex.h"
namespace nearby {
class BlockingQueueStream : public InputStream {
public:
BlockingQueueStream();
~BlockingQueueStream() override = default;
ExceptionOr<ByteArray> Read(std::int64_t size) override;
void Write(const ByteArray& bytes);
Exception Close() override;
bool IsWriting() const {
return is_writing_;
}
private:
mutable Mutex mutex_;
ArrayBlockingQueue<ByteArray> blocking_queue_{FeatureFlags::GetInstance()
.GetFlags()
.blocking_queue_stream_queue_capacity};
ByteArray queue_end_{0};
bool is_writing_ = false;
bool is_closed_ = false;
};
} // namespace nearby
#endif // #ifndef PLATFORM_PUBLIC_BLOCKING_QUEUE_STREAM_H_
+92 -17
View File
@@ -14,76 +14,132 @@
#include "internal/platform/bluetooth_classic.h"
#include <memory>
#include <string>
#include <utility>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/implementation/bluetooth_classic.h"
#include "internal/platform/logging.h"
#include "internal/platform/mutex_lock.h"
#include "internal/platform/output_stream.h"
#include "internal/platform/socket.h"
namespace nearby {
using location::nearby::proto::connections::Medium;
MediumSocket* BluetoothSocket::CreateVirtualSocket(OutputStream* outputstream) {
if (IsVirtualSocket()) {
LOG(WARNING)
<< "Creating the virtual socket on a virtual socket is not allowed.";
return nullptr;
}
auto virtual_socket = std::make_shared<BluetoothSocket>(outputstream);
return virtual_socket.get();
}
MediumSocket* BluetoothSocket::CreateVirtualSocket(
const std::string& salted_service_id_hash_key, OutputStream* outputstream,
Medium medium,
absl::flat_hash_map<std::string, std::shared_ptr<MediumSocket>>*
virtual_sockets_ptr) {
if (IsVirtualSocket()) {
LOG(WARNING)
<< "Creating the virtual socket on a virtual socket is not allowed.";
return nullptr;
}
auto virtual_socket = std::make_shared<BluetoothSocket>(outputstream);
virtual_socket->impl_ = this->impl_;
LOG(WARNING) << "Created the virtual socket for Medium: "
<< Medium_Name(virtual_socket->GetMedium());
if (virtual_sockets_ptr_ == nullptr) {
virtual_sockets_ptr_ = virtual_sockets_ptr;
}
(*virtual_sockets_ptr_)[salted_service_id_hash_key] = virtual_socket;
LOG(INFO) << "virtual_sockets_ size: " << virtual_sockets_ptr_->size();
return virtual_socket.get();
}
BluetoothClassicMedium::~BluetoothClassicMedium() {
LOG(INFO) << "~BluetoothClassicMedium: observer_list_ size: "
<< observer_list_.size();
if (!observer_list_.empty()) {
impl_->RemoveObserver(this);
}
StopDiscovery();
LOG(INFO) << "eof ~BluetoothClassicMedium";
}
BluetoothSocket BluetoothClassicMedium::ConnectToService(
BluetoothDevice& remote_device, const std::string& service_uuid,
CancellationFlag* cancellation_flag) {
NEARBY_LOG(INFO,
"BluetoothClassicMedium::ConnectToService: device=%p [impl=%p]",
&remote_device, &remote_device.GetImpl());
LOG(INFO) << "BluetoothClassicMedium::ConnectToService: "
"service_uuid="
<< service_uuid << ", device=" << remote_device.GetMacAddress()
<< ", [impl=" << &remote_device.GetImpl() << "]";
return BluetoothSocket(impl_->ConnectToService(
remote_device.GetImpl(), service_uuid, cancellation_flag));
}
bool BluetoothClassicMedium::StartDiscovery(DiscoveryCallback callback) {
LOG(INFO) << "BluetoothClassicMedium::StartDiscovery";
MutexLock lock(&mutex_);
if (discovery_enabled_) {
NEARBY_LOG(INFO, "BT Discovery already enabled; impl=%p", &GetImpl());
LOG(INFO) << "BT Discovery already enabled; impl=" << &GetImpl();
return false;
}
bool success = impl_->StartDiscovery({
.device_discovered_cb =
[this](api::BluetoothDevice& device) {
VLOG(1) << "BT .device_discovered_cb for " << device.GetName();
MutexLock lock(&mutex_);
auto pair = devices_.emplace(
&device, absl::make_unique<DeviceDiscoveryInfo>());
&device, std::make_unique<DeviceDiscoveryInfo>());
auto& context = *pair.first->second;
if (!pair.second) {
NEARBY_LOG(INFO, "Adding (again) device=%p, impl=%p",
&context.device, &device);
LOG(INFO) << "Adding (again) device="
<< context.device.GetMacAddress()
<< ",impl=" << &device;
return;
}
context.device = BluetoothDevice(&device);
NEARBY_LOG(INFO, "Adding device=%p, impl=%p", &context.device,
&device);
LOG(INFO) << "Adding device=" << context.device.GetMacAddress()
<< ",impl=" << &device;
if (!discovery_enabled_) return;
discovery_callback_.device_discovered_cb(context.device);
},
.device_name_changed_cb =
[this](api::BluetoothDevice& device) {
VLOG(1) << "BT .device_name_changed_cb for " << device.GetName();
MutexLock lock(&mutex_);
// If the device is not already in devices_, we should not be able
// to change its name.
if (devices_.find(&device) == devices_.end()) return;
auto& context = *devices_[&device];
NEARBY_LOG(INFO, "Renaming device=%p, impl=%p", &context.device,
&device);
LOG(INFO) << "Renaming device=" << context.device.GetMacAddress()
<< ",impl=" << &device;
if (!discovery_enabled_) return;
discovery_callback_.device_name_changed_cb(context.device);
},
.device_lost_cb =
[this](api::BluetoothDevice& device) {
VLOG(1) << "BT .device_lost_cb for " << device.GetMacAddress();
MutexLock lock(&mutex_);
auto item = devices_.extract(&device);
if (!item) {
NEARBY_LOGS(WARNING)
<< "Removing unknown device: " << device.GetMacAddress();
LOG(WARNING) << "Removing unknown device: "
<< device.GetMacAddress();
return;
}
auto& context = *item.mapped();
NEARBY_LOG(INFO, "Removing device=%p, impl=%p", &context.device,
&device);
LOG(INFO) << "Removing device=" << context.device.GetMacAddress()
<< ",impl=" << &device;
if (!discovery_enabled_) return;
discovery_callback_.device_lost_cb(context.device);
},
@@ -92,44 +148,54 @@ bool BluetoothClassicMedium::StartDiscovery(DiscoveryCallback callback) {
discovery_callback_ = std::move(callback);
devices_.clear();
discovery_enabled_ = true;
NEARBY_LOG(INFO, "BT Discovery enabled; impl=%p", &GetImpl());
}
LOG(INFO) << "BT StartDiscovery result:" << success
<< ", impl=" << &GetImpl();
return success;
}
bool BluetoothClassicMedium::StopDiscovery() {
LOG(INFO) << "BT StopDiscovery; impl=" << &GetImpl();
MutexLock lock(&mutex_);
if (!discovery_enabled_) return true;
discovery_enabled_ = false;
discovery_callback_ = {};
devices_.clear();
NEARBY_LOG(INFO, "BT Discovery disabled: impl=%p", &GetImpl());
LOG(INFO) << "BT Discovery disabled: impl=" << &GetImpl();
return impl_->StopDiscovery();
}
void BluetoothClassicMedium::AddObserver(Observer* observer) {
LOG(INFO) << "BT AddObserver; impl=" << &GetImpl();
MutexLock lock(&mutex_);
if (observer_list_.empty()) {
impl_->AddObserver(this);
}
observer_list_.AddObserver(observer);
LOG(INFO) << "BT AddObserver done";
}
void BluetoothClassicMedium::RemoveObserver(Observer* observer) {
LOG(INFO) << "BT RemoveObserver; impl=" << &GetImpl();
MutexLock lock(&mutex_);
observer_list_.RemoveObserver(observer);
if (observer_list_.empty()) {
impl_->RemoveObserver(this);
}
LOG(INFO) << "BT RemoveObserver done";
}
// api::BluetoothClassicMedium::Observer methods
void BluetoothClassicMedium::DeviceAdded(api::BluetoothDevice& device) {
VLOG(1) << "BT DeviceAdded; name=" << device.GetName()
<< ", address=" << device.GetMacAddress();
BluetoothDevice bt_device(&device);
for (auto* observer : observer_list_.GetObservers()) {
observer->DeviceAdded(bt_device);
}
}
void BluetoothClassicMedium::DeviceRemoved(api::BluetoothDevice& device) {
VLOG(1) << "BT DeviceRemoved; name=" << device.GetName()
<< ", address=" << device.GetMacAddress();
BluetoothDevice bt_device(&device);
for (auto* observer : observer_list_.GetObservers()) {
observer->DeviceRemoved(bt_device);
@@ -137,6 +203,9 @@ void BluetoothClassicMedium::DeviceRemoved(api::BluetoothDevice& device) {
}
void BluetoothClassicMedium::DeviceAddressChanged(
api::BluetoothDevice& device, absl::string_view old_address) {
VLOG(1) << "BT DeviceAddressChanged; name=" << device.GetName()
<< ", address=" << device.GetMacAddress()
<< ", old_address=" << old_address;
BluetoothDevice bt_device(&device);
for (auto* observer : observer_list_.GetObservers()) {
observer->DeviceAddressChanged(bt_device, old_address);
@@ -144,6 +213,9 @@ void BluetoothClassicMedium::DeviceAddressChanged(
}
void BluetoothClassicMedium::DevicePairedChanged(api::BluetoothDevice& device,
bool new_paired_status) {
VLOG(1) << "BT DevicePairedChanged; name=" << device.GetName()
<< ", address=" << device.GetMacAddress()
<< ", status=" << new_paired_status;
BluetoothDevice bt_device(&device);
for (auto* observer : observer_list_.GetObservers()) {
observer->DevicePairedChanged(bt_device, new_paired_status);
@@ -151,6 +223,9 @@ void BluetoothClassicMedium::DevicePairedChanged(api::BluetoothDevice& device,
}
void BluetoothClassicMedium::DeviceConnectedStateChanged(
api::BluetoothDevice& device, bool connected) {
VLOG(1) << "BT DeviceConnectedStateChanged: name=" << device.GetName()
<< ", address=" << device.GetMacAddress()
<< ", connected=" << connected;
BluetoothDevice bt_device(&device);
for (auto* observer : observer_list_.GetObservers()) {
observer->DeviceConnectedStateChanged(bt_device, connected);
+72 -9
View File
@@ -15,14 +15,19 @@
#ifndef PLATFORM_PUBLIC_BLUETOOTH_CLASSIC_H_
#define PLATFORM_PUBLIC_BLUETOOTH_CLASSIC_H_
#include <stdbool.h>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "internal/base/observer_list.h"
#include "internal/platform/blocking_queue_stream.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancellation_flag.h"
@@ -34,29 +39,79 @@
#include "internal/platform/logging.h"
#include "internal/platform/mutex.h"
#include "internal/platform/output_stream.h"
#include "internal/platform/socket.h"
namespace nearby {
// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html.
class BluetoothSocket final {
class BluetoothSocket : public MediumSocket {
public:
BluetoothSocket() = default;
BluetoothSocket()
: MediumSocket(location::nearby::proto::connections::Medium::BLUETOOTH) {
};
BluetoothSocket(const BluetoothSocket&) = default;
BluetoothSocket& operator=(const BluetoothSocket&) = default;
// Creates a physical BluetoothSocket from a platform implementation.
explicit BluetoothSocket(std::unique_ptr<api::BluetoothSocket> socket)
: impl_(socket.release()) {}
~BluetoothSocket() = default;
: MediumSocket(location::nearby::proto::connections::Medium::BLUETOOTH),
impl_(socket.release()) {}
// Creates a virtual BluetoothSocket from a virtual output stream.
explicit BluetoothSocket(OutputStream* virtual_output_stream)
: MediumSocket(location::nearby::proto::connections::Medium::BLUETOOTH),
blocking_queue_input_stream_(std::make_shared<BlockingQueueStream>()),
virtual_output_stream_(virtual_output_stream),
is_virtual_socket_(true) {}
~BluetoothSocket() override = default;
// Returns the InputStream of this connected BluetoothSocket.
InputStream& GetInputStream() { return impl_->GetInputStream(); }
InputStream& GetInputStream() override {
return IsVirtualSocket() ? *blocking_queue_input_stream_
: impl_->GetInputStream();
}
// Returns the OutputStream of this connected BluetoothSocket.
OutputStream& GetOutputStream() { return impl_->GetOutputStream(); }
OutputStream& GetOutputStream() override {
return IsVirtualSocket() ? *virtual_output_stream_
: impl_->GetOutputStream();
}
// Closes both input and output streams, marks Socket as closed.
// After this call object should be treated as not connected.
// Returns Exception::kIo on error, Exception::kSuccess otherwise.
Exception Close() { return impl_->Close(); }
Exception Close() override {
if (IsVirtualSocket()) {
NEARBY_LOGS(INFO) << "Multiplex: Closing virtual socket: " << this;
blocking_queue_input_stream_->Close();
virtual_output_stream_->Close();
CloseLocal();
return {Exception::kSuccess};
}
NEARBY_LOGS(INFO) << "Multiplex: Closing physical socket: " << this;
return impl_->Close();
}
// Returns true if this is a virtual socket.
bool IsVirtualSocket() override { return is_virtual_socket_; }
// Creates a virtual socket only with outputstream.
MediumSocket* CreateVirtualSocket(OutputStream* outputstream) override;
MediumSocket* CreateVirtualSocket(
const std::string& salted_service_id_hash_key, OutputStream* outputstream,
location::nearby::proto::connections::Medium medium,
absl::flat_hash_map<std::string, std::shared_ptr<MediumSocket>>*
virtual_sockets_ptr) override;
/** Feeds the received incoming data to the client. */
void FeedIncomingData(ByteArray data) override {
if (!IsVirtualSocket()) {
NEARBY_LOGS(INFO) << "Feeding data on a physical socket is not allowed.";
return;
}
blocking_queue_input_stream_->Write(data);
}
// https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#getRemoteDevice()
BluetoothDevice GetRemoteDevice() {
@@ -73,7 +128,10 @@ class BluetoothSocket final {
// BluetoothServerSocket::Accept().
// These methods may also return an invalid socket if connection failed for
// any reason.
bool IsValid() const { return impl_ != nullptr; }
bool IsValid() const {
if (is_virtual_socket_) return true;
return impl_ != nullptr;
}
// Returns reference to platform implementation.
// This is used to communicate with platform code, and for debugging purposes.
@@ -84,6 +142,11 @@ class BluetoothSocket final {
private:
std::shared_ptr<api::BluetoothSocket> impl_;
absl::flat_hash_map<std::string, std::shared_ptr<MediumSocket>>*
virtual_sockets_ptr_ = nullptr;
std::shared_ptr<BlockingQueueStream> blocking_queue_input_stream_ = nullptr;
OutputStream* virtual_output_stream_ = nullptr;
bool is_virtual_socket_ = false;
};
// https://developer.android.com/reference/android/bluetooth/BluetoothServerSocket.html.
+14 -14
View File
@@ -129,7 +129,7 @@ TEST_P(BluetoothClassicMediumTest, CanConnectToService) {
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch, &discovered_device](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
discovered_device = &device;
found_latch.CountDown();
@@ -178,7 +178,7 @@ TEST_P(BluetoothClassicMediumTest, CanCancelConnect) {
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch, &discovered_device](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
discovered_device = &device;
found_latch.CountDown();
@@ -234,7 +234,7 @@ TEST_F(BluetoothClassicMediumTest, SendData) {
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch, &discovered_device](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
discovered_device = &device;
found_latch.CountDown();
@@ -281,7 +281,7 @@ TEST_F(BluetoothClassicMediumTest, IoOnClosedSocketReturnsEmpty) {
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch, &discovered_device](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
discovered_device = &device;
found_latch.CountDown();
@@ -350,13 +350,13 @@ TEST_F(BluetoothClassicMediumTest, CanStartDiscovery) {
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
found_latch.CountDown();
},
.device_lost_cb =
[this, &lost_latch](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device lost: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device lost: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
lost_latch.CountDown();
},
@@ -379,13 +379,13 @@ TEST_F(BluetoothClassicMediumTest, CanStopDiscovery) {
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
found_latch.CountDown();
},
.device_lost_cb =
[this, &lost_latch](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device lost: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device lost: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
lost_latch.CountDown();
},
@@ -406,7 +406,7 @@ TEST_F(BluetoothClassicMediumTest, CanListenForService) {
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
found_latch.CountDown();
},
@@ -435,7 +435,7 @@ TEST_F(BluetoothClassicMediumTest, BluetoothPairingSuccess) {
CountDownLatch found_latch(1);
bt_a_->StartDiscovery(
DiscoveryCallback{.device_discovered_cb = [&](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
discovered_device = &device;
found_latch.CountDown();
@@ -507,7 +507,7 @@ TEST_F(BluetoothClassicMediumTest, BluetoothPairingFailure) {
CountDownLatch found_latch(1);
bt_a_->StartDiscovery(
DiscoveryCallback{.device_discovered_cb = [&](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
discovered_device = &device;
found_latch.CountDown();
@@ -569,9 +569,9 @@ TEST_F(BluetoothClassicMediumTest, CancelBluetoothPairing) {
CountDownLatch found_latch(1);
bt_a_->StartDiscovery(
DiscoveryCallback{.device_discovered_cb = [&](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
NEARBY_LOG(INFO, "Device discovered address: %s",
device.GetMacAddress().c_str());
NEARBY_LOGS(INFO) << "Device discovered: " << device.GetName();
NEARBY_LOGS(INFO) << "Device discovered address: "
<< device.GetMacAddress();
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
discovered_device = &device;
found_latch.CountDown();
+6
View File
@@ -15,9 +15,15 @@
#include "internal/platform/bluetooth_utils.h"
#include <algorithm>
#include <cstdint>
#include <string>
#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "internal/platform/byte_array.h"
namespace nearby {
+3
View File
@@ -15,6 +15,9 @@
#ifndef PLATFORM_BASE_BLUETOOTH_UTILS_H_
#define PLATFORM_BASE_BLUETOOTH_UTILS_H_
#include <cstdint>
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/byte_array.h"
-7
View File
@@ -37,14 +37,7 @@
#include <memory>
#include <utility>
#ifdef NEARBY_CHROMIUM
#include "base/check.h"
#elif defined(NEARBY_SWIFTPM)
#include "internal/platform/logging.h"
#else
#include "absl/log/check.h" // nogncheck
#endif
#include "internal/platform/mutex.h"
#include "internal/platform/mutex_lock.h"
+1
View File
@@ -24,6 +24,7 @@
#include <utility>
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
namespace nearby {
+2
View File
@@ -15,9 +15,11 @@
#include "internal/platform/byte_utils.h"
#include <cstdlib>
#include <string>
#include "absl/strings/str_format.h"
#include "internal/platform/base_input_stream.h"
#include "internal/platform/byte_array.h"
namespace nearby {
+1
View File
@@ -15,6 +15,7 @@
#ifndef PLATFORM_BASE_BYTE_UTILS_H_
#define PLATFORM_BASE_BYTE_UTILS_H_
#include <string>
#include "internal/platform/byte_array.h"
namespace nearby {
+12 -9
View File
@@ -14,8 +14,8 @@
#include "internal/platform/condition_variable.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include <cstdint>
#include "gtest/gtest.h"
#include "absl/time/time.h"
#include "internal/platform/logging.h"
@@ -25,6 +25,7 @@
namespace nearby {
namespace {
constexpr absl::Duration kWaitTime = absl::Milliseconds(500);
TEST(ConditionVariableTest, CanCreate) {
Mutex mutex;
@@ -36,17 +37,17 @@ TEST(ConditionVariableTest, CanWakeupWaiter) {
ConditionVariable cond{&mutex};
bool done = false;
bool waiting = false;
NEARBY_LOG(INFO, "At start; done=%d", done);
NEARBY_LOGS(INFO) << "At start; done=" << done;
{
SingleThreadExecutor executor;
executor.Execute([&cond, &mutex, &done, &waiting]() {
MutexLock lock(&mutex);
NEARBY_LOG(INFO, "Before cond.Wait(); done=%d", done);
NEARBY_LOGS(INFO) << "Before cond.Wait(); done=" << done;
waiting = true;
cond.Wait();
waiting = false;
done = true;
NEARBY_LOG(INFO, "After cond.Wait(); done=%d", done);
NEARBY_LOGS(INFO) << "After cond.Wait(); done=" << done;
});
while (true) {
{
@@ -61,7 +62,7 @@ TEST(ConditionVariableTest, CanWakeupWaiter) {
EXPECT_FALSE(done);
}
}
NEARBY_LOG(INFO, "After executor shutdown: done=%d", done);
NEARBY_LOGS(INFO) << "After executor shutdown: done=" << done;
EXPECT_TRUE(done);
}
@@ -70,11 +71,13 @@ TEST(ConditionVariableTest, WaitTerminatesOnTimeoutWithoutNotify) {
ConditionVariable cond{&mutex};
MutexLock lock(&mutex);
const absl::Duration kWaitTime = absl::Milliseconds(100);
absl::Time start = SystemClock::ElapsedRealtime();
cond.Wait(kWaitTime);
absl::Duration duration = SystemClock::ElapsedRealtime() - start;
EXPECT_GE(duration, kWaitTime);
int64_t bias = absl::ToInt64Milliseconds(SystemClock::ElapsedRealtime() -
start - kWaitTime);
// Windows cannot guarantee the exact time of the timeout.
EXPECT_GE(bias, -100);
}
} // namespace
@@ -14,10 +14,7 @@
#include "internal/platform/credential_storage_impl.h"
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
@@ -25,6 +22,7 @@
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/credential_callbacks.h"
#include "internal/proto/credential.pb.h"
@@ -67,19 +65,19 @@ SharedCredential CreatePublicCredential(absl::string_view secret_id,
std::vector<LocalCredential> BuildPrivateCreds(absl::string_view secret_id) {
std::vector<LocalCredential> private_credentials = {
CreateLocalCredential(secret_id, IdentityType::IDENTITY_TYPE_PRIVATE),
CreateLocalCredential(secret_id, IdentityType::IDENTITY_TYPE_TRUSTED),
CreateLocalCredential(secret_id,
IdentityType::IDENTITY_TYPE_PROVISIONED)};
IdentityType::IDENTITY_TYPE_PRIVATE_GROUP),
CreateLocalCredential(secret_id,
IdentityType::IDENTITY_TYPE_CONTACTS_GROUP)};
return private_credentials;
}
std::vector<SharedCredential> BuildPublicCreds(absl::string_view secret_id) {
std::vector<SharedCredential> public_credentials = {
CreatePublicCredential(secret_id, IdentityType::IDENTITY_TYPE_PRIVATE),
CreatePublicCredential(secret_id, IdentityType::IDENTITY_TYPE_TRUSTED),
CreatePublicCredential(secret_id,
IdentityType::IDENTITY_TYPE_PROVISIONED)};
IdentityType::IDENTITY_TYPE_PRIVATE_GROUP),
CreatePublicCredential(secret_id,
IdentityType::IDENTITY_TYPE_CONTACTS_GROUP)};
return public_credentials;
}
@@ -450,9 +448,10 @@ TEST_P(IdentityFilterTest, FilterLocalCredentialsByIdentityType) {
TEST_P(IdentityFilterTest, FilterLocalCredentialsFailsWhenNoCredentialsMatch) {
IdentityType identity_type = GetParam();
// Create a credential of a different identity type than the one we query.
IdentityType other_type = identity_type == IdentityType::IDENTITY_TYPE_PRIVATE
? IdentityType::IDENTITY_TYPE_TRUSTED
: IdentityType::IDENTITY_TYPE_PRIVATE;
IdentityType other_type =
identity_type == IdentityType::IDENTITY_TYPE_PRIVATE_GROUP
? IdentityType::IDENTITY_TYPE_CONTACTS_GROUP
: IdentityType::IDENTITY_TYPE_PRIVATE_GROUP;
std::vector<LocalCredential> private_creds = {
CreateLocalCredential(kSecretId, other_type)};
CredentialStorageImpl credential_storage;
@@ -486,9 +485,10 @@ TEST_P(IdentityFilterTest, FilterPublicCredentialsByIdentityType) {
TEST_P(IdentityFilterTest, FilterPublicCredentialsFailsWhenNoCredentialsMatch) {
IdentityType identity_type = GetParam();
// Create a credential of a different identity type than the one we query.
IdentityType other_type = identity_type == IdentityType::IDENTITY_TYPE_PRIVATE
? IdentityType::IDENTITY_TYPE_TRUSTED
: IdentityType::IDENTITY_TYPE_PRIVATE;
IdentityType other_type =
identity_type == IdentityType::IDENTITY_TYPE_PRIVATE_GROUP
? IdentityType::IDENTITY_TYPE_CONTACTS_GROUP
: IdentityType::IDENTITY_TYPE_PRIVATE_GROUP;
std::vector<SharedCredential> public_creds = {
CreatePublicCredential(kSecretId, other_type)};
CredentialStorageImpl credential_storage;
@@ -503,9 +503,8 @@ TEST_P(IdentityFilterTest, FilterPublicCredentialsFailsWhenNoCredentialsMatch) {
INSTANTIATE_TEST_SUITE_P(
CredentialStorageImplTest, IdentityFilterTest,
testing::Values(IdentityType::IDENTITY_TYPE_PRIVATE,
IdentityType::IDENTITY_TYPE_TRUSTED,
IdentityType::IDENTITY_TYPE_PROVISIONED));
testing::Values(IdentityType::IDENTITY_TYPE_PRIVATE_GROUP,
IdentityType::IDENTITY_TYPE_CONTACTS_GROUP));
} // namespace
} // namespace nearby
+1 -1
View File
@@ -15,6 +15,6 @@
#ifndef PLATFORM_PUBLIC_CRYPTO_H_
#define PLATFORM_PUBLIC_CRYPTO_H_
#include "internal/platform/implementation/crypto.h"
#include "internal/platform/implementation/crypto.h" // IWYU pragma: export
#endif // PLATFORM_PUBLIC_CRYPTO_H_
+46
View File
@@ -14,12 +14,29 @@
#include "internal/platform/crypto.h"
#include <stddef.h>
#include <cstdint>
#include <string>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "internal/crypto_cros/nearby_base.h"
#include "internal/platform/byte_array.h"
namespace nearby {
namespace {
// Ensures we don't have all trivial data, i.e. that the data is indeed random.
// Currently, that means the bytes cannot be all the same (e.g. all zeros).
bool IsTrivial(const std::string& bytes) {
for (size_t i = 0; i < bytes.size(); i++) {
if (bytes[i] != bytes[0]) {
return false;
}
}
return true;
}
TEST(CryptoTest, Md5GeneratesHash) {
const ByteArray expected_md5(
@@ -44,4 +61,33 @@ TEST(CryptoTest, Sha256ReturnsEmptyOnError) {
EXPECT_EQ(Crypto::Sha256(""), ByteArray{});
}
// Basic functionality tests. Does NOT test the security of the random data.
TEST(CryptoTest, RandBytes) {
std::string bytes(16, '\0');
RandBytes(nearbybase::WriteInto(&bytes, bytes.size()), bytes.size());
EXPECT_TRUE(!IsTrivial(bytes));
}
TEST(CryptoTest, RandomString) {
constexpr size_t kSize = 30;
std::string bytes(kSize, 0);
RandBytes(const_cast<std::string::value_type*>(bytes.data()), bytes.size());
EXPECT_EQ(bytes.size(), kSize);
EXPECT_TRUE(!IsTrivial(bytes));
}
TEST(CryptoTest, RandData) {
uint64_t x = nearby::RandData<uint64_t>();
uint64_t y = nearby::RandData<uint64_t>();
// Once in a billion years, consecutively generated random numbers will be
// the same and the test will fail.
EXPECT_NE(x, y);
EXPECT_NE(x >> 32, x & 0xFFFFFFFF);
}
} // namespace
} // namespace nearby
+12 -13
View File
@@ -15,14 +15,14 @@
#ifndef PLATFORM_PUBLIC_DEVICE_INFO_H_
#define PLATFORM_PUBLIC_DEVICE_INFO_H_
#include <filesystem>
#include <cstddef>
#include <filesystem> // NOLINT
#include <functional>
#include <optional>
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/device_info.h"
#include "internal/platform/implementation/platform.h"
namespace nearby {
@@ -30,17 +30,16 @@ class DeviceInfo {
public:
virtual ~DeviceInfo() = default;
virtual std::u16string GetOsDeviceName() const = 0;
// All strings are UTF-8 encoded.
virtual std::string GetOsDeviceName() const = 0;
virtual api::DeviceInfo::DeviceType GetDeviceType() const = 0;
virtual api::DeviceInfo::OsType GetOsType() const = 0;
virtual std::optional<std::u16string> GetFullName() const = 0;
virtual std::optional<std::u16string> GetGivenName() const = 0;
virtual std::optional<std::u16string> GetLastName() const = 0;
virtual std::optional<std::string> GetProfileUserName() const = 0;
virtual std::optional<std::string> GetGivenName() const = 0;
virtual std::filesystem::path GetDownloadPath() const = 0;
virtual std::filesystem::path GetAppDataPath() const = 0;
virtual std::filesystem::path GetTemporaryPath() const = 0;
virtual std::filesystem::path GetLogPath() const = 0;
virtual std::optional<size_t> GetAvailableDiskSpaceInBytes(
const std::filesystem::path& path) const = 0;
@@ -55,18 +54,18 @@ class DeviceInfo {
virtual bool PreventSleep() = 0;
virtual bool AllowSleep() = 0;
// Returns localized device name depends on device type.
std::u16string GetDeviceTypeName() const {
// Returns UTF-8 encoded localized device name depending on device type.
std::string GetDeviceTypeName() const {
// TODO(b/230132370): return localized device name.
switch (GetDeviceType()) {
case api::DeviceInfo::DeviceType::kPhone:
return u"Phone";
return "Phone";
case api::DeviceInfo::DeviceType::kTablet:
return u"Tablet";
return "Tablet";
case api::DeviceInfo::DeviceType::kLaptop:
return u"PC";
return "PC";
default:
return u"Unknown";
return "Unknown";
}
}
};
+20 -20
View File
@@ -14,21 +14,25 @@
#include "internal/platform/device_info_impl.h"
#include <cstddef>
#include <filesystem> // NOLINT
#include <functional>
#include <optional>
#include <string>
#include <system_error>
#include "absl/strings/string_view.h"
#include "internal/base/files.h"
#include "internal/platform/implementation/device_info.h"
namespace nearby {
std::u16string DeviceInfoImpl::GetOsDeviceName() const {
std::optional<std::u16string> device_name =
std::string DeviceInfoImpl::GetOsDeviceName() const {
std::optional<std::string> device_name =
device_info_impl_->GetOsDeviceName();
if (device_name.has_value()) {
return *device_name;
}
return u"unknown";
return "unknown";
}
api::DeviceInfo::DeviceType DeviceInfoImpl::GetDeviceType() const {
@@ -39,29 +43,18 @@ api::DeviceInfo::OsType DeviceInfoImpl::GetOsType() const {
return device_info_impl_->GetOsType();
}
std::optional<std::u16string> DeviceInfoImpl::GetFullName() const {
return device_info_impl_->GetFullName();
}
std::optional<std::u16string> DeviceInfoImpl::GetGivenName() const {
std::optional<std::string> DeviceInfoImpl::GetGivenName() const {
return device_info_impl_->GetGivenName();
}
std::optional<std::u16string> DeviceInfoImpl::GetLastName() const {
return device_info_impl_->GetLastName();
}
std::optional<std::string> DeviceInfoImpl::GetProfileUserName() const {
return device_info_impl_->GetProfileUserName();
}
std::filesystem::path DeviceInfoImpl::GetDownloadPath() const {
std::optional<std::filesystem::path> path =
device_info_impl_->GetDownloadPath();
if (path.has_value()) {
return *path;
}
return std::filesystem::temp_directory_path();
return nearby::sharing::GetTemporaryDirectory().value_or(
nearby::sharing::CurrentDirectory());
}
std::filesystem::path DeviceInfoImpl::GetAppDataPath() const {
@@ -70,7 +63,8 @@ std::filesystem::path DeviceInfoImpl::GetAppDataPath() const {
if (path.has_value()) {
return *path;
}
return std::filesystem::temp_directory_path();
return nearby::sharing::GetTemporaryDirectory().value_or(
nearby::sharing::CurrentDirectory());
}
std::filesystem::path DeviceInfoImpl::GetTemporaryPath() const {
@@ -79,7 +73,13 @@ std::filesystem::path DeviceInfoImpl::GetTemporaryPath() const {
if (path.has_value()) {
return *path;
}
return std::filesystem::temp_directory_path();
return nearby::sharing::GetTemporaryDirectory().value_or(
nearby::sharing::CurrentDirectory());
}
std::filesystem::path DeviceInfoImpl::GetLogPath() const {
std::optional<std::filesystem::path> path = device_info_impl_->GetLogPath();
return path.value_or(GetTemporaryPath());
}
std::optional<size_t> DeviceInfoImpl::GetAvailableDiskSpaceInBytes(
+7 -6
View File
@@ -15,13 +15,16 @@
#ifndef PLATFORM_PUBLIC_DEVICE_INFO_IMPL_H_
#define PLATFORM_PUBLIC_DEVICE_INFO_IMPL_H_
#include <filesystem>
#include <cstddef>
#include <filesystem> // NOLINT
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/device_info.h"
#include "internal/platform/implementation/device_info.h"
#include "internal/platform/implementation/platform.h"
namespace nearby {
@@ -31,18 +34,16 @@ class DeviceInfoImpl : public DeviceInfo {
DeviceInfoImpl()
: device_info_impl_(api::ImplementationPlatform::CreateDeviceInfo()) {}
std::u16string GetOsDeviceName() const override;
std::string GetOsDeviceName() const override;
api::DeviceInfo::DeviceType GetDeviceType() const override;
api::DeviceInfo::OsType GetOsType() const override;
std::optional<std::u16string> GetFullName() const override;
std::optional<std::u16string> GetGivenName() const override;
std::optional<std::u16string> GetLastName() const override;
std::optional<std::string> GetProfileUserName() const override;
std::optional<std::string> GetGivenName() const override;
std::filesystem::path GetDownloadPath() const override;
std::filesystem::path GetAppDataPath() const override;
std::filesystem::path GetTemporaryPath() const override;
std::filesystem::path GetLogPath() const override;
std::optional<size_t> GetAvailableDiskSpaceInBytes(
const std::filesystem::path& path) const override;
+44 -3
View File
@@ -17,6 +17,7 @@
#include <cstdint>
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
@@ -45,7 +46,7 @@ class FeatureFlags {
bool enable_send_payload_offset = true;
// Provide better bookkeeping for bandwidth upgrade initiation. This is
// necessary to properly support multiple BWU mediums, multiple service, and
// multiple endpionts.
// multiple endpoints.
bool support_multiple_bwu_mediums = true;
// Allows the code to change the bluetooth radio state
bool enable_set_radio_state = false;
@@ -53,7 +54,7 @@ class FeatureFlags {
// create connection with remote device in a duration.
bool enable_connection_timeout = true;
// Controls enable or disable to track the status of Bluetooth classic
// conncetion.
// connection.
bool enable_bluetooth_connection_status_track = true;
// Controls enable or disable BLE scan advertisement for fast pair
// service uuid 0x2cfe
@@ -62,18 +63,58 @@ class FeatureFlags {
// requested service id before attempting to connect over rfcomm. SDP fails
// on Windows when connecting to FP service id but the rfcomm is successful.
bool skip_service_discovery_before_connecting_to_rfcomm = false;
// Controls enable or disable the use of async methods for StartScanning
// and StopScanning for BLE V2.
// TODO(b/333408829): Add flag to control async advertising.
bool enable_ble_v2_async_scanning = false;
// Enable legacy device discovered callback being used inside ble v2
// DiscoverPeripheralTracker flow.
bool enable_invoking_legacy_device_discovered_cb = false;
// Enable 1. safe-to-disconnect check 2. reserved 3. auto-reconnect 4.
// auto-resume 5. non-distance-constraint-recovery 6. payload_ack
std::int32_t min_nc_version_supports_safe_to_disconnect = 1;
std::int32_t min_nc_version_supports_auto_reconnect = 3;
absl::Duration auto_reconnect_retry_delay_millis = absl::Milliseconds(5000);
absl::Duration auto_reconnect_timeout_millis = absl::Milliseconds(30000);
std::int32_t auto_reconnect_retry_attempts = 3;
absl::Duration auto_reconnect_skip_duplicated_endpoint_duration =
absl::Milliseconds(4000);
// Android code won't be able to launch "payload_received_ack" feature for
// in near future, so change "payload_received_ack" version from "2" to "5"
// after auto-reconnect and auto-resume.
std::int32_t min_nc_version_supports_payload_received_ack = 5;
std::int32_t min_nc_version_supports_payload_received_ack = 6;
// If the other part doesn't ack the safe_to_disconnect request, the
// initiator will end the connection in 30s.
absl::Duration safe_to_disconnect_ack_delay_millis =
absl::Milliseconds(30000);
absl::Duration safe_to_disconnect_remote_disc_delay_millis =
absl::Milliseconds(10000);
absl::Duration safe_to_disconnect_auto_resume_timeout_millis =
absl::Milliseconds(60000);
// If the receiver doesn't ack with payload_received_ack frame in 1s, the
// sender will timeout the waiting.
absl::Duration wait_payload_received_ack_millis = absl::Milliseconds(1000);
// Multiplex related flags
// Timeout value for read frame operation in endpoint channel.
absl::Duration mediums_frame_read_timeout_millis =
absl::Milliseconds(15000);
// Timeout value for write frame operation in endpoint channel.
absl::Duration mediums_frame_write_timeout_millis =
absl::Milliseconds(15000);
// The timeout for waiting on connection request response.
absl::Duration multiplex_socket_connection_response_timeout_millis =
absl::Milliseconds(3000);
// The capacity of the middle priority queue inner MultiplexOutputStream.
// The new outgoing frame with the middle priority will wait for space to
// become available if the queue is full.'
std::uint32_t multiplex_socket_middle_priority_queue_capacity = 50;
// The maximum size of frame we'll attempt to read, to avoid a remote device
// from triggering an OutOfMemory error.
std::uint32_t connection_max_frame_length = 1048576;
std::uint32_t blocking_queue_stream_queue_capacity = 10;
bool support_web_rtc_non_cellular_medium = false;
};
static const FeatureFlags& GetInstance() {
+9
View File
@@ -25,6 +25,15 @@ constexpr FeatureFlags::Flags kTestFeatureFlags{
.keep_alive_interval_millis = 5000,
.keep_alive_timeout_millis = 30000};
TEST(FeatureFlagsTest, CastUpdateWorks) {
const FeatureFlags& features = FeatureFlags::GetInstance();
EXPECT_TRUE(features.GetFlags().enable_async_bandwidth_upgrade);
const_cast<FeatureFlags&>(FeatureFlags::GetInstance())
.SetFlags({.enable_async_bandwidth_upgrade = false});
EXPECT_FALSE(features.GetFlags().enable_async_bandwidth_upgrade);
}
TEST(FeatureFlagsTest, ToSetFeatureWorks) {
const FeatureFlags& features = FeatureFlags::GetInstance();
EXPECT_TRUE(features.GetFlags().enable_cancellation_flag);
+1 -1
View File
@@ -19,10 +19,10 @@ cc_library(
"nearby_platform_feature_flags.h",
],
visibility = [
"//connections:__subpackages__",
"//fastpair:__subpackages__",
"//internal:__subpackages__",
"//location/nearby/cpp:__subpackages__",
"//location/nearby/testing:__subpackages__",
],
deps = [
"//internal/flags:flag_reader",
@@ -65,6 +65,18 @@ constexpr auto kWifiHotspotConnectionIntervalMillis =
constexpr auto kWifiHotspotConnectionTimeoutMillis =
flags::Flag<int64_t>(kConfigPackage, "45415888", 10000);
// Enable/Disable Intel PIe SDK to query/set WIFI feature.
constexpr auto kEnableIntelPieSdk =
flags::Flag<bool>(kConfigPackage, "45428547", false);
// Enable/Disable new Bluetooth refactor
constexpr auto kEnableNewBluetoothRefactor =
flags::Flag<bool>(kConfigPackage, "45615156", false);
// Enable/Disable task scheduler for ScheduledExecutor and timer
constexpr auto kEnableTaskScheduler =
flags::Flag<bool>(kConfigPackage, "45643835", false);
} // namespace nearby_platform_feature
} // namespace config_package_nearby
} // namespace platform
+4
View File
@@ -15,8 +15,12 @@
#ifndef PLATFORM_PUBLIC_FUTURE_H_
#define PLATFORM_PUBLIC_FUTURE_H_
#include <memory>
#include <utility>
#include "absl/time/time.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/executor.h"
#include "internal/platform/settable_future.h"
namespace nearby {
+1 -1
View File
@@ -78,7 +78,7 @@ TEST(FutureTest, SupportScopedEnum) {
}
TEST(FutureTest, SetTakesCopyOfValue) {
// Default constructor is zero-initalizing all data in BigSizedStruct.
// Default constructor is zero-initializing all data in BigSizedStruct.
BigSizedStruct v1;
Future<BigSizedStruct> future;
v1.data[0] = 5; // Changing value before calling Set() will affect stored
+57 -4
View File
@@ -13,6 +13,25 @@
# limitations under the License.
licenses(["notice"])
cc_library(
name = "account_manager",
hdrs = ["account_manager.h"],
visibility = [
"//fastpair:__subpackages__",
"//internal/account:__pkg__",
"//internal/platform/implementation:__subpackages__",
"//internal/test:__subpackages__",
"//location/nearby/cpp/sharing/clients/cpp:__subpackages__",
"//location/nearby/sharing/sdk/quick_share_server:__pkg__",
"//sharing:__subpackages__",
],
deps = [
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings:string_view",
],
)
cc_library(
name = "types",
hdrs = [
@@ -39,6 +58,7 @@ cc_library(
"timer.h",
],
visibility = [
"//connections/implementation:__subpackages__",
"//connections/implementation/analytics:__subpackages__",
"//fastpair:__subpackages__",
"//internal/crypto_cros:__pkg__",
@@ -47,14 +67,14 @@ cc_library(
"//internal/preferences:__subpackages__",
"//internal/test:__subpackages__",
"//location/nearby/analytics/cpp:__subpackages__",
"//location/nearby/cpp/common:__subpackages__",
"//location/nearby/cpp/sharing:__subpackages__",
"//presence:__subpackages__",
"//third_party/nearby/sharing:__subpackages__",
"//sharing:__subpackages__",
],
deps = [
"//internal/crypto_cros",
"//internal/platform:base",
"//internal/platform/implementation/shared:crypto", # Non-chromium impl
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/strings",
@@ -64,6 +84,24 @@ cc_library(
],
)
cc_library(
name = "wifi_utils",
srcs = [
"wifi_utils.cc",
],
hdrs = [
"wifi.h",
"wifi_utils.h",
],
visibility = [
"//:__subpackages__",
],
deps = [
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
],
)
cc_library(
name = "comm",
hdrs = [
@@ -84,11 +122,11 @@ cc_library(
copts = ["-DNO_WEBRTC"],
visibility = [
"//connections/implementation:__subpackages__",
"//fastpair/internal:__pkg__",
"//fastpair/internal/mediums:__pkg__",
"//internal/network:__subpackages__",
"//internal/platform:__pkg__",
"//internal/platform/implementation:__subpackages__",
"//presence:__subpackages__",
"//presence/implementation:__subpackages__",
],
deps = [
@@ -121,8 +159,9 @@ cc_library(
"//internal/platform:__pkg__",
"//internal/platform/implementation:__subpackages__",
"//location/nearby/analytics/cpp:__subpackages__",
"//location/nearby/apps/better_together/plugins/preferences_native:__subpackages__",
"//location/nearby/cpp/sharing:__subpackages__",
"//third_party/nearby/sharing:__subpackages__",
"//sharing:__subpackages__",
],
deps = [
":comm",
@@ -132,3 +171,17 @@ cc_library(
"@com_google_absl//absl/strings",
],
)
cc_test(
name = "wifi_utils_test",
size = "small",
timeout = "moderate",
srcs = ["wifi_utils_test.cc"],
shard_count = 8,
deps = [
":wifi_utils",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
@@ -0,0 +1,104 @@
// 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_API_ACCOUNT_MANAGER_H_
#define PLATFORM_API_ACCOUNT_MANAGER_H_
#include <optional>
#include <string>
#include <utility>
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
namespace nearby {
// AccountManager manages the accounts are used to access Nearby backend.
// In current design, AccountManager only support one active account.
class AccountManager {
public:
// Describes a Nearby account. The account class will have more properties
// and methods in the future based on the new feature added.
struct Account {
std::string id; // The unique identify of the account.
std::string display_name;
std::string family_name;
std::string given_name;
std::string picture_url;
std::string email;
};
// Observes the activity of the account manager.
class Observer {
public:
virtual ~Observer() = default;
virtual void OnLoginSucceeded(absl::string_view account_id) = 0;
// |credential_error| is true if the logout is due to critical auth error.
virtual void OnLogoutSucceeded(absl::string_view account_id,
bool credential_error) = 0;
};
virtual ~AccountManager() = default;
// Gets current active account. If no login user, return std::nullopt.
virtual std::optional<Account> GetCurrentAccount() = 0;
// Initializes the login process for a Google account from 1P client.
// |login_success_callback| is called when the login succeeded. Account
// information is passed to callback.
// |login_failure_callback| is called when the login fails.
virtual void Login(
absl::AnyInvocable<void(Account)> login_success_callback,
absl::AnyInvocable<void(absl::Status)> login_failure_callback) = 0;
// Initializes the login process for a Google account from an oauth client.
// |client_id| GCP client_id of the client
// |client_secret| GCP client_secret of the client
// |login_success_callback| is called when the login succeeded. Account
// information is passed to callback.
// |login_failure_callback| is called when the login fails.
virtual void Login(
absl::string_view client_id, absl::string_view client_secret,
absl::AnyInvocable<void(Account)> login_success_callback,
absl::AnyInvocable<void(absl::Status)> login_failure_callback) = 0;
// Logs out current active account. |logout_callback| is called when logout is
// completed.
virtual void Logout(
absl::AnyInvocable<void(absl::Status)> logout_callback) = 0;
// Gets access token for the active account.
// |success_callback| is called when an access token is fetched successfully.
// |failure_callback| is called when fetching an access token failed.
//
// Returns false if account_id is empty or callback is null.
virtual bool GetAccessToken(
absl::string_view account_id,
absl::AnyInvocable<void(absl::string_view)> success_callback,
absl::AnyInvocable<void(absl::Status)> failure_callback) = 0;
// Returns a pair containing the client id and client secret used in the most
// recent Login request.
// If no current user is logged in, returns empty string for both.
virtual std::pair<std::string, std::string> GetOAuthClientCredential() = 0;
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
};
} // namespace nearby
#endif // PLATFORM_API_ACCOUNT_MANAGER_H_
+16 -13
View File
@@ -17,7 +17,7 @@ package(default_visibility = [
"//connections:__subpackages__",
"//internal/platform/implementation/apple:__subpackages__",
"//location/nearby:__subpackages__",
"//third_party/nearby/sharing:__subpackages__",
"//sharing:__subpackages__",
])
objc_library(
@@ -25,7 +25,6 @@ objc_library(
srcs = [
"crypto.mm",
"device_info.mm",
"log_message.mm",
"multi_thread_executor.mm",
"platform.mm",
"preferences_manager.mm",
@@ -35,7 +34,6 @@ objc_library(
],
hdrs = [
"device_info.h",
"log_message.h",
"multi_thread_executor.h",
"preferences_manager.h",
"scheduled_executor.h",
@@ -50,23 +48,25 @@ objc_library(
":Platform_cc",
":Shared",
":ble_v2",
"//internal/platform:base",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:types",
"//internal/platform/implementation/apple/Mediums",
"//internal/platform/implementation/shared:file",
"//third_party/apple_frameworks:CoreBluetooth",
"//third_party/apple_frameworks:Foundation",
"//third_party/apple_frameworks:Network",
"//third_party/objective_c/google_toolbox_for_mac:GTM_Logger",
# Required Reason API File: third_party/nearby/internal/platform/implementation/apple/preferences_manager.mm
"//releasetools/apple/privacy/privacymanifests/requiredreasonsapi:user_defaults-user_defaults-read_write_app_data_ca92_1",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:span",
"//third_party/apple_frameworks:CoreBluetooth",
"//third_party/apple_frameworks:Foundation",
"//third_party/apple_frameworks:Network",
"@nlohmann_json//:json",
"//internal/platform:base",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:types",
"//internal/platform/implementation/apple/Mediums",
"//internal/platform/implementation/shared:file",
"//third_party/objective_c/google_toolbox_for_mac:GTM_Logger",
] + select({
"@platforms//os:platform_ios": [
"//third_party/apple_frameworks:UIKit",
@@ -148,8 +148,10 @@ cc_library(
"mutex.h",
],
deps = [
"//internal/platform:base",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:types",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
@@ -168,6 +170,7 @@ cc_test(
shard_count = 16,
deps = [
":Platform_cc",
"//internal/platform/implementation/g3:crypto",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
@@ -49,6 +49,14 @@ typedef void (^GNCGetCharacteristicCompletionHandler)(
typedef void (^GNCReadCharacteristicValueCompletionHandler)(NSData *_Nullable value,
NSError *_Nullable error);
/**
* A block to be invoked after a call to @c disconnect, requesting that the local connection to the
* remote peripheral be cancelled.
*
* @param peripheral The remote peripheral to disconnect from.
*/
typedef void (^GNCRequestDisconnectionHandler)(id<GNCPeripheral> peripheral);
/**
* An object that can be used to discover, explore, and interact with GATT services and
* characteristics available on a remote peripheral.
@@ -64,8 +72,11 @@ typedef void (^GNCReadCharacteristicValueCompletionHandler)(NSData *_Nullable va
* Initializes the GATT client with a specified peripheral.
*
* @param peripheral The peripheral instance.
* @param requestDisconnectionHandler Called on a private queue with @c peripheral when the
* connection to the peripheral should be cancelled.
*/
- (instancetype)initWithPeripheral:(id<GNCPeripheral>)peripheral;
- (instancetype)initWithPeripheral:(id<GNCPeripheral>)peripheral
requestDisconnectionHandler:(GNCRequestDisconnectionHandler)requestDisconnectionHandler;
/**
* Discovers the specified characteristics of a service.
@@ -112,6 +123,9 @@ typedef void (^GNCReadCharacteristicValueCompletionHandler)(NSData *_Nullable va
completionHandler:
(nullable GNCReadCharacteristicValueCompletionHandler)completionHandler;
/** Cancels an active or pending local connection to a peripheral. */
- (void)disconnect;
@end
NS_ASSUME_NONNULL_END
@@ -49,6 +49,7 @@ static NSError *AlreadyReadingCharacteristicError() {
@implementation GNCBLEGATTClient {
dispatch_queue_t _queue;
id<GNCPeripheral> _peripheral;
GNCRequestDisconnectionHandler _requestDisconnectionHandler;
/**
* A map of service UUIDs with each service holding a map of a list of characterisitcs to a
@@ -70,15 +71,18 @@ static NSError *AlreadyReadingCharacteristicError() {
*_readCharacteristicValueCompletionHandlers;
}
- (instancetype)initWithPeripheral:(id<GNCPeripheral>)peripheral {
return [self
initWithPeripheral:peripheral
queue:dispatch_queue_create(kGNCBLEGATTClientQueueLabel, DISPATCH_QUEUE_SERIAL)];
- (instancetype)initWithPeripheral:(id<GNCPeripheral>)peripheral
requestDisconnectionHandler:(GNCRequestDisconnectionHandler)requestDisconnectionHandler {
return [self initWithPeripheral:peripheral
queue:dispatch_queue_create(kGNCBLEGATTClientQueueLabel,
DISPATCH_QUEUE_SERIAL)
requestDisconnectionHandler:requestDisconnectionHandler];
};
// Private.
- (instancetype)initWithPeripheral:(id<GNCPeripheral>)peripheral
queue:(nullable dispatch_queue_t)queue {
queue:(nullable dispatch_queue_t)queue
requestDisconnectionHandler:(GNCRequestDisconnectionHandler)requestDisconnectionHandler {
self = [super init];
if (self) {
_queue = queue ?: dispatch_get_main_queue();
@@ -86,6 +90,7 @@ static NSError *AlreadyReadingCharacteristicError() {
_peripheral.peripheralDelegate = self;
_discoverCharacteristicsCompletionHandlers = [[NSMutableDictionary alloc] init];
_readCharacteristicValueCompletionHandlers = [[NSMutableDictionary alloc] init];
_requestDisconnectionHandler = requestDisconnectionHandler;
}
return self;
};
@@ -173,6 +178,12 @@ static NSError *AlreadyReadingCharacteristicError() {
});
}
- (void)disconnect {
dispatch_async(_queue, ^{
_requestDisconnectionHandler(_peripheral);
});
}
#pragma mark - Internal
- (CBCharacteristic *)synchronousCharacteristicWithUUID:(CBUUID *)characteristicUUID
@@ -245,7 +245,13 @@ static NSError *AlreadyScanningError() {
GNCGATTConnectionCompletionHandler handler = _connectionCompletionHandlers[peripheral.identifier];
_connectionCompletionHandlers[peripheral.identifier] = nil;
if (handler) {
GNCBLEGATTClient *client = [[GNCBLEGATTClient alloc] initWithPeripheral:peripheral];
GNCBLEGATTClient *client =
[[GNCBLEGATTClient alloc] initWithPeripheral:peripheral
requestDisconnectionHandler:^(id<GNCPeripheral> peripheral) {
dispatch_async(_queue, ^{
[_centralManager cancelPeripheralConnection:peripheral];
});
}];
handler(client, nil);
}
}
@@ -79,6 +79,21 @@ NS_ASSUME_NONNULL_BEGIN
- (void)connectPeripheral:(id<GNCPeripheral>)peripheral
options:(nullable NSDictionary<NSString *, id> *)options;
/**
* Cancels an active or pending local connection to a peripheral.
*
* This method is nonblocking, and any @c CBPeripheral class commands that are still pending to
* @c peripheral may not complete. Because other apps may still have a connection to the peripheral,
* canceling a local connection doesnt guarantee that the underlying physical link is immediately
* disconnected. From the apps perspective, however, the peripheral is effectively disconnected,
* and the central manager object calls the @c centralManager:didDisconnectPeripheral:error: method
* of its delegate object.
*
* @param peripheral The peripheral to which the central manager is either trying to connect or has
* already connected.
*/
- (void)cancelPeripheralConnection:(id<GNCPeripheral>)peripheral;
/** Asks the central manager to stop scanning for peripherals. */
- (void)stopScan;
@@ -50,7 +50,7 @@ NSData *GNCMGenerateBLEFramesIntroductionPacket(NSData *serviceIDHash) {
return packet;
}
NSData *GNCMParseBLEFramesIntroductionPacket(NSData *data) {
NSData *_Nullable GNCMParseBLEFramesIntroductionPacket(NSData *data) {
::location::nearby::mediums::SocketControlFrame socket_control_frame;
NSUInteger prefixLength = sizeof(kGNCMControlPacketServiceIDHash);
NSData *packet = [data subdataWithRange:NSMakeRange(prefixLength, data.length - prefixLength)];
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("//tools/build_defs/swift:swift_explicit_module_build_test.bzl", "swift_explicit_module_build_test")
load("//third_party/nearby:minimum_os.bzl", "IOS_MINIMUM_OS")
load("//tools/build_defs/swift:swift_explicit_module_build_test.bzl", "swift_explicit_module_build_test")
licenses(["notice"])
@@ -32,9 +32,7 @@ objc_library(
deps = [
":Shared",
"//third_party/apple_frameworks:CoreBluetooth",
"//third_party/apple_frameworks:CoreFoundation",
"//third_party/apple_frameworks:Foundation",
"//third_party/apple_frameworks:QuartzCore",
"//third_party/objective_c/google_toolbox_for_mac:GTM_Logger",
],
)
@@ -728,7 +728,11 @@ static NSString *PeripheralStateString(CBPeripheralState state) {
packet.version);
[_connectionConfirmTimer invalidate];
_connectionConfirmTimer = nil;
_socket.packetSize = packet.packetSize;
// Weave is using `CBCharacteristicWriteWithResponse` for writes, so we must query max value since
// it can have a smaller value than the `GNSWeaveConnectionConfirmPacket` size.
NSUInteger maxWriteLength =
[_socket.peerAsPeripheral maximumWriteValueLengthForType:CBCharacteristicWriteWithResponse];
_socket.packetSize = MIN(packet.packetSize, maxWriteLength);
[_socket didConnect];
if (packet.data) {
// According to the Weave BLE protocol the data received during the connection handshake should
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("//tools/build_defs/apple:ios.bzl", "ios_unit_test")
load("//third_party/nearby:minimum_os.bzl", "IOS_LATEST_TEST_RUNNER", "IOS_MINIMUM_OS")
load("//tools/build_defs/apple:ios.bzl", "ios_unit_test")
licenses(["notice"])
@@ -31,9 +31,12 @@ NS_ASSUME_NONNULL_BEGIN
* @param peripheral The peripheral instance.
* @param queue The queue to run on, this must match the queue that the peripheral's delegate is
* running on. Defaults to the main queue when @c nil.
* @param requestDisconnectionHandler Called on a private queue with @c peripheral when the
* connection to the peripheral should be cancelled.
*/
- (instancetype)initWithPeripheral:(id<GNCPeripheral>)peripheral
queue:(nullable dispatch_queue_t)queue;
queue:(nullable dispatch_queue_t)queue
requestDisconnectionHandler:(GNCRequestDisconnectionHandler)requestDisconnectionHandler;
@end
@@ -19,6 +19,7 @@
#import <XCTest/XCTest.h>
#import "internal/platform/implementation/apple/Mediums/BLEv2/GNCBLEGATTCharacteristic.h"
#import "internal/platform/implementation/apple/Mediums/BLEv2/GNCPeripheral.h"
#import "internal/platform/implementation/apple/Tests/GNCBLEGATTClient+Testing.h"
#import "internal/platform/implementation/apple/Tests/GNCFakePeripheral.h"
@@ -37,8 +38,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testDiscoverCharacteristics {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -64,8 +68,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
fakePeripheral.discoverServicesError = [NSError errorWithDomain:@"fake" code:0 userInfo:nil];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -97,8 +104,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
code:0
userInfo:nil];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -123,8 +133,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testDuplicateDiscoverCharacteristics {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -163,8 +176,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testDiscoverCharacteristicsMultipleCallsWithDifferentServices {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID1 = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *serviceUUID2 = [CBUUID UUIDWithString:kServiceUUID2];
@@ -209,8 +225,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testDiscoverCharacteristicsMultipleCallsWithDifferentCharacteristics {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID1 = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -256,8 +275,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testGetCharacteristic {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -287,8 +309,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
fakePeripheral.discoverServicesError = [NSError errorWithDomain:@"fake" code:0 userInfo:nil];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -324,8 +349,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
code:0
userInfo:nil];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -353,8 +381,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testDuplicateGetCharacteristic {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -400,8 +431,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testGetNonExistentCharacteristic {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -425,8 +459,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testReadValueForCharacteristic {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -461,8 +498,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
fakePeripheral.discoverServicesError = [NSError errorWithDomain:@"fake" code:0 userInfo:nil];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -503,8 +543,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
code:0
userInfo:nil];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -541,8 +584,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
code:0
userInfo:nil];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -576,8 +622,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testDuplicateReadValueForCharacteristic {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -630,8 +679,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testReadValueForMultipleCharacteristics {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID1 = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -691,8 +743,11 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
- (void)testReadValueForUndiscoveredCharacteristic {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -714,13 +769,33 @@ static NSString *const kCharacteristicUUID2 = @"00000000-0000-3000-8000-00000000
[self waitForExpectations:@[ expectation ] timeout:3];
}
- (void)testDisconnect {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"Disconnect."];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> peripheral) {
XCTAssertNotNil(peripheral);
[expectation fulfill];
}];
[gattClient disconnect];
[self waitForExpectations:@[ expectation ] timeout:3];
}
#pragma mark - Delegate Calls
- (void)testUnexpectedDelegateCalls {
GNCFakePeripheral *fakePeripheral = [[GNCFakePeripheral alloc] init];
GNCBLEGATTClient *gattClient = [[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil];
GNCBLEGATTClient *gattClient =
[[GNCBLEGATTClient alloc] initWithPeripheral:fakePeripheral
queue:nil
requestDisconnectionHandler:^(id<GNCPeripheral> __unused peripheral){
}];
CBUUID *serviceUUID = [CBUUID UUIDWithString:kServiceUUID1];
CBUUID *characteristicUUID = [CBUUID UUIDWithString:kCharacteristicUUID1];
@@ -18,6 +18,7 @@
#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>
#import "internal/platform/implementation/apple/Mediums/BLEv2/GNCBLEGATTClient.h"
#import "internal/platform/implementation/apple/Mediums/BLEv2/GNCBLEGATTServer.h"
#import "internal/platform/implementation/apple/Mediums/BLEv2/GNCPeripheral.h"
#import "internal/platform/implementation/apple/Tests/GNCBLEMedium+Testing.h"
@@ -313,8 +314,6 @@ static NSString *const kServiceUUID = @"0000FEF3-0000-1000-8000-00805F9B34FB";
- (void)testDisconnect {
GNCFakeCentralManager *fakeCentralManager = [[GNCFakeCentralManager alloc] init];
GNCBLEMedium *medium = [[GNCBLEMedium alloc] initWithCentralManager:fakeCentralManager queue:nil];
XCTestExpectation *connectExpectation =
[[XCTestExpectation alloc] initWithDescription:@"Connect."];
XCTestExpectation *disconnectExpectation =
[[XCTestExpectation alloc] initWithDescription:@"Disconnect."];
@@ -327,13 +326,9 @@ static NSString *const kServiceUUID = @"0000FEF3-0000-1000-8000-00805F9B34FB";
completionHandler:^(GNCBLEGATTClient *client, NSError *error) {
XCTAssertNotNil(client);
XCTAssertNil(error);
[connectExpectation fulfill];
[client disconnect];
}];
[self waitForExpectations:@[ connectExpectation ] timeout:3];
[fakeCentralManager simulateCentralManagerDidDisconnectPeripheral:peripheral];
[self waitForExpectations:@[ disconnectExpectation ] timeout:3];
}
@@ -56,6 +56,10 @@
[centralDelegate gnc_centralManager:self didConnectPeripheral:peripheral];
}
- (void)cancelPeripheralConnection:(id<GNCPeripheral>)peripheral {
[centralDelegate gnc_centralManager:self didDisconnectPeripheral:peripheral error:nil];
}
- (void)stopScan {
}
@@ -127,8 +127,9 @@ bool GattClient::SetCharacteristicSubscription(
return false;
}
// TODO(b/290385712): Implement.
void GattClient::Disconnect() {}
void GattClient::Disconnect() {
[gatt_client_ disconnect];
}
} // namespace apple
} // namespace nearby
@@ -145,9 +145,15 @@ void BleMedium::HandleAdvertisementFound(id<GNCPeripheral> peripheral,
std::unique_ptr<api::ble_v2::BleMedium::ScanningSession> BleMedium::StartScanning(
const Uuid &service_uuid, api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::BleMedium::ScanningCallback callback) {
absl::MutexLock lock(&peripherals_mutex_);
CBUUID *serviceUUID = CBUUID128FromCPP(service_uuid);
scanning_cb_ = std::move(callback);
// Clear the map of discovered peripherals only when we are starting a new scan. If we cleared the
// map every time we stopped a scan, we would not be able to connect to peripherals that we
// discovered in that scan session.
peripherals_.clear();
socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUID];
[socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUID ]];
@@ -171,9 +177,15 @@ std::unique_ptr<api::ble_v2::BleMedium::ScanningSession> BleMedium::StartScannin
bool BleMedium::StartScanning(const Uuid &service_uuid, api::ble_v2::TxPowerLevel tx_power_level,
api::ble_v2::BleMedium::ScanCallback callback) {
absl::MutexLock lock(&peripherals_mutex_);
CBUUID *serviceUUID = CBUUID128FromCPP(service_uuid);
scan_cb_ = std::move(callback);
// Clear the map of discovered peripherals only when we are starting a new scan. If we cleared the
// map every time we stopped a scan, we would not be able to connect to peripherals that we
// discovered in that scan session.
peripherals_.clear();
socketCentralManager_ = [[GNSCentralManager alloc] initWithSocketServiceUUID:serviceUUID];
[socketCentralManager_ startNoScanModeWithAdvertisedServiceUUIDs:@[ serviceUUID ]];
@@ -13,6 +13,9 @@
// limitations under the License.
#include "internal/platform/implementation/apple/count_down_latch.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
#include "internal/platform/exception.h"
namespace nearby {
namespace apple {
@@ -15,7 +15,10 @@
#ifndef PLATFORM_IMPL_APPLE_COUNT_DOWN_LATCH_H_
#define PLATFORM_IMPL_APPLE_COUNT_DOWN_LATCH_H_
#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/count_down_latch.h"
namespace nearby {
@@ -14,7 +14,10 @@
#include "internal/platform/implementation/apple/count_down_latch.h"
#include <atomic>
#include "gtest/gtest.h"
#include "absl/time/time.h"
#include "thread/fiber/fiber.h"
namespace nearby {
@@ -56,11 +59,11 @@ TEST(CountDownLatchTest, LatchAwaitWithTimeoutCanExpire) {
auto response = latch.Await(absl::Milliseconds(100));
EXPECT_TRUE(response.ok());
EXPECT_FALSE(response.ok());
EXPECT_FALSE(response.result());
}
TEST(CountDownLatchTest, InitialCountZero_AwaitDoesNotBlock) {
TEST(CountDownLatchTest, InitialCountZeroAwaitDoesNotBlock) {
CountDownLatch latch(0);
auto response = latch.Await();
@@ -68,7 +71,7 @@ TEST(CountDownLatchTest, InitialCountZero_AwaitDoesNotBlock) {
EXPECT_TRUE(response.Ok());
}
TEST(CountDownLatchTest, InitialCountNegative_AwaitDoesNotBlock) {
TEST(CountDownLatchTest, InitialCountNegativeAwaitDoesNotBlock) {
CountDownLatch latch(-1);
auto response = latch.Await();
@@ -28,16 +28,13 @@ namespace apple {
class DeviceInfo : public api::DeviceInfo {
public:
std::optional<std::u16string> GetOsDeviceName() const override;
std::optional<std::string> GetOsDeviceName() const override;
api::DeviceInfo::DeviceType GetDeviceType() const override;
api::DeviceInfo::OsType GetOsType() const override;
std::optional<std::u16string> GetFullName() const override;
std::optional<std::u16string> GetGivenName() const override;
std::optional<std::u16string> GetLastName() const override;
std::optional<std::string> GetProfileUserName() const override;
std::optional<std::string> GetGivenName() const override;
std::optional<std::filesystem::path> GetDownloadPath() const override;
@@ -33,15 +33,15 @@
namespace nearby {
namespace apple {
std::optional<std::u16string> DeviceInfo::GetOsDeviceName() const {
std::optional<std::string> DeviceInfo::GetOsDeviceName() const {
#if TARGET_OS_IPHONE
NSString *name = UIDevice.currentDevice.name;
const char16_t *cName = (const char16_t *)[name cStringUsingEncoding:NSUTF16StringEncoding];
return std::u16string(cName);
const char *cName = (const char *)[name cStringUsingEncoding:NSUTF8StringEncoding];
return std::string(cName);
#elif TARGET_OS_OSX
NSString *name = NSHost.currentHost.localizedName;
const char16_t *cName = (const char16_t *)[name cStringUsingEncoding:NSUTF16StringEncoding];
return std::u16string(cName);
const char *cName = (const char *)[name cStringUsingEncoding:NSUTF8StringEncoding];
return std::string(cName);
#else
return std::nullopt;
#endif
@@ -78,10 +78,7 @@ api::DeviceInfo::OsType DeviceInfo::GetOsType() const {
#endif
}
std::optional<std::u16string> DeviceInfo::GetFullName() const { return std::nullopt; }
std::optional<std::u16string> DeviceInfo::GetGivenName() const { return std::nullopt; }
std::optional<std::u16string> DeviceInfo::GetLastName() const { return std::nullopt; }
std::optional<std::string> DeviceInfo::GetProfileUserName() const { return std::nullopt; }
std::optional<std::string> DeviceInfo::GetGivenName() const { return std::nullopt; }
std::optional<std::filesystem::path> DeviceInfo::GetDownloadPath() const {
NSFileManager *manager = [NSFileManager defaultManager];
@@ -1,65 +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_APPLE_LOG_MESSAGE_H_
#define PLATFORM_IMPL_APPLE_LOG_MESSAGE_H_
#include <ostream>
#include <sstream>
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/log_message.h"
#include "GoogleToolboxForMac/GTMLogger.h"
namespace nearby {
namespace apple {
class LogStreamer final {
public:
explicit LogStreamer(GTMLoggerLevel severity, absl::string_view func);
~LogStreamer();
std::ostream& stream() { return stream_; }
private:
GTMLoggerLevel severity_;
std::string func_;
std::ostringstream stream_;
};
// Concrete LogMessage implementation
class LogMessage : public api::LogMessage {
public:
LogMessage(const char* file, int line, Severity severity);
~LogMessage() override = default;
LogMessage(const LogMessage&) = delete;
LogMessage& operator=(const LogMessage&) = delete;
void Print(const char* format, ...) override;
std::ostream& Stream() override;
private:
LogStreamer log_streamer_;
GTMLoggerLevel severity_;
std::string func_;
};
} // namespace apple
} // namespace nearby
#endif // PLATFORM_IMPL_APPLE_LOG_MESSAGE_H_
@@ -1,117 +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/apple/log_message.h"
#include <ostream>
#include <string>
#include "internal/platform/implementation/log_message.h"
namespace nearby {
namespace apple {
api::LogMessage::Severity gMinLogSeverity = api::LogMessage::Severity::kInfo;
GTMLoggerLevel ConvertSeverity(api::LogMessage::Severity severity) {
switch (severity) {
case api::LogMessage::Severity::kVerbose:
return kGTMLoggerLevelDebug;
case api::LogMessage::Severity::kInfo:
return kGTMLoggerLevelInfo;
case api::LogMessage::Severity::kWarning:
return kGTMLoggerLevelInfo;
case api::LogMessage::Severity::kError:
return kGTMLoggerLevelError;
case api::LogMessage::Severity::kFatal:
return kGTMLoggerLevelAssert;
}
}
// GTMLogger expects a function name, but we only have file and line. So format the info as
// {basename(file)}:{line} and use that as the function name.
std::string ConvertFileAndLine(absl::string_view filepath, int line) {
size_t path = filepath.find_last_of('/');
if (path != filepath.npos) filepath.remove_prefix(path + 1);
return std::string(filepath) + ":" + std::to_string(line);
}
LogStreamer::LogStreamer(GTMLoggerLevel severity, absl::string_view func)
: severity_(severity), func_(func) {}
LogStreamer::~LogStreamer() {
switch (severity_) {
case kGTMLoggerLevelDebug:
[[GTMLogger sharedLogger] logFuncDebug:func_.c_str() msg:@"%@", @(stream_.str().c_str())];
break;
case kGTMLoggerLevelInfo:
[[GTMLogger sharedLogger] logFuncInfo:func_.c_str() msg:@"%@", @(stream_.str().c_str())];
break;
case kGTMLoggerLevelError:
[[GTMLogger sharedLogger] logFuncError:func_.c_str() msg:@"%@", @(stream_.str().c_str())];
break;
case kGTMLoggerLevelAssert:
[[GTMLogger sharedLogger] logFuncAssert:func_.c_str() msg:@"%@", @(stream_.str().c_str())];
break;
case kGTMLoggerLevelUnknown:
// no-op
break;
}
}
LogMessage::LogMessage(const char* file, int line, Severity severity)
: log_streamer_(ConvertSeverity(severity), ConvertFileAndLine(file, line)),
severity_(ConvertSeverity(severity)),
func_(ConvertFileAndLine(file, line)) {}
void LogMessage::Print(const char* format, ...) {
va_list ap;
va_start(ap, format);
NSString *msg = [[NSString alloc] initWithFormat:@(format) arguments:ap];
switch (severity_) {
case kGTMLoggerLevelDebug:
[[GTMLogger sharedLogger] logFuncDebug:func_.c_str() msg:@"%@", msg];
break;
case kGTMLoggerLevelInfo:
[[GTMLogger sharedLogger] logFuncInfo:func_.c_str() msg:@"%@", msg];
break;
case kGTMLoggerLevelError:
[[GTMLogger sharedLogger] logFuncError:func_.c_str() msg:@"%@", msg];
break;
case kGTMLoggerLevelAssert:
[[GTMLogger sharedLogger] logFuncAssert:func_.c_str() msg:@"%@", msg];
break;
case kGTMLoggerLevelUnknown:
// no-op
break;
}
va_end(ap);
}
std::ostream& LogMessage::Stream() { return log_streamer_.stream(); }
} // namespace apple
namespace api {
// static
void LogMessage::SetMinLogSeverity(Severity severity) { apple::gMinLogSeverity = severity; }
// static
bool LogMessage::ShouldCreateLogMessage(Severity severity) {
return severity >= apple::gMinLogSeverity;
}
} // namespace api
} // namespace nearby
@@ -26,7 +26,6 @@
#include "internal/platform/implementation/apple/condition_variable.h"
#include "internal/platform/implementation/apple/count_down_latch.h"
#include "internal/platform/implementation/apple/device_info.h"
#import "internal/platform/implementation/apple/log_message.h"
#import "internal/platform/implementation/apple/multi_thread_executor.h"
#include "internal/platform/implementation/apple/mutex.h"
#include "internal/platform/implementation/apple/preferences_manager.h"
@@ -135,11 +134,6 @@ std::unique_ptr<OutputFile> ImplementationPlatform::CreateOutputFile(const std::
return shared::IOFile::CreateOutputFile(file_path);
}
std::unique_ptr<LogMessage> ImplementationPlatform::CreateLogMessage(
const char* file, int line, LogMessage::Severity severity) {
return std::make_unique<apple::LogMessage>(file, line, severity);
}
// Java-like Executors
std::unique_ptr<SubmittableExecutor> ImplementationPlatform::CreateSingleThreadExecutor() {
return std::make_unique<apple::SingleThreadExecutor>();
@@ -228,7 +222,7 @@ absl::StatusOr<WebResponse> ImplementationPlatform::SendRequest(const WebRequest
[condition unlock];
if (blockResponse == nil) {
return absl::UnknownError([[blockError localizedDescription] UTF8String]);
return absl::FailedPreconditionError([[blockError localizedDescription] UTF8String]);
}
WebResponse webResponse;
+5 -3
View File
@@ -460,12 +460,14 @@ class BleMedium {
absl::AnyInvocable<void(BlePeripheral& peripheral,
BleAdvertisementData advertisement_data)>
advertisement_found_cb = [](BlePeripheral&, BleAdvertisementData) {};
absl::AnyInvocable<void(BlePeripheral& peripheral)>
advertisement_lost_cb = [](BlePeripheral&) {};
};
// Async interface for StartScanning.
// Result status will be passed to start_advertising_result callback.
// To stop advertising, invoke the stop_advertising callback in
// AdvertisingSession.
// Result status will be passed to start_scanning_result callback.
// To stop scanning, invoke the stop_scanning callback in
// ScanningSession.
virtual std::unique_ptr<ScanningSession> StartScanning(
const Uuid& service_uuid, TxPowerLevel tx_power_level,
ScanningCallback callback) = 0;
+16 -6
View File
@@ -15,12 +15,11 @@
#ifndef PLATFORM_API_CRYPTO_H_
#define PLATFORM_API_CRYPTO_H_
#include <stddef.h>
#include <stdint.h>
#include "absl/strings/string_view.h"
#ifdef NEARBY_CHROMIUM
#include "crypto/random.h"
#else
#include "internal/crypto_cros/random.h"
#endif
#include "absl/types/span.h"
#include "internal/platform/byte_array.h"
namespace nearby {
@@ -36,12 +35,23 @@ class Crypto {
static ByteArray Sha256(absl::string_view input);
};
// Fills the given buffer with |length| random bytes of cryptographically
// secure random numbers.
// |length| must be positive.
//
// TODO(crbug.com/40284755): Convert all callers in Nearby to use spans
// and remove this RandBytes overload.
void RandBytes(void *bytes, size_t length);
// Fills |bytes| with cryptographically-secure random bits.
void RandBytes(absl::Span<uint8_t> bytes);
// Creates an object of type T initialized with random data.
// This template should be used for simple data types: int, char, etc.
template <typename T>
T RandData() {
T data;
::crypto::RandBytes(&data, sizeof(data));
RandBytes(&data, sizeof(data));
return data;
}
@@ -41,15 +41,12 @@ class DeviceInfo {
virtual ~DeviceInfo() = default;
// Gets device name.
virtual std::optional<std::u16string> GetOsDeviceName() const = 0;
virtual std::optional<std::string> GetOsDeviceName() const = 0;
virtual DeviceType GetDeviceType() const = 0;
virtual OsType GetOsType() const = 0;
// Gets basic information of current user.
virtual std::optional<std::u16string> GetFullName() const = 0;
virtual std::optional<std::u16string> GetGivenName() const = 0;
virtual std::optional<std::u16string> GetLastName() const = 0;
virtual std::optional<std::string> GetProfileUserName() const = 0;
virtual std::optional<std::string> GetGivenName() const = 0;
// Gets known paths of current user.
virtual std::optional<std::filesystem::path> GetDownloadPath() const = 0;
+23 -25
View File
@@ -17,7 +17,6 @@ cc_library(
name = "types",
testonly = True,
srcs = [
"log_message.cc",
"preferences_manager.cc",
"scheduled_executor.cc",
"system_clock.cc",
@@ -27,7 +26,6 @@ cc_library(
"atomic_reference.h",
"condition_variable.h",
"device_info.h",
"log_message.h",
"multi_thread_executor.h",
"mutex.h",
"preferences_manager.h",
@@ -35,17 +33,12 @@ cc_library(
"single_thread_executor.h",
"timer.h",
],
visibility = [
"//internal/test:__subpackages__",
"//location/nearby/cpp:__subpackages__",
"//third_party/nearby/sharing:__subpackages__",
],
visibility = ["//visibility:private"],
deps = [
":preferences_repository",
"//internal/platform:base",
"//internal/platform:test_util",
"//internal/platform:types",
"//internal/platform:util",
"//internal/platform/implementation:types",
"//internal/platform/implementation/shared:count_down_latch",
"//internal/platform/implementation/shared:posix_mutex",
@@ -53,11 +46,12 @@ cc_library(
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:btree",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/log:log_streamer",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:span",
"@com_google_glog//:glog",
"@com_google_nisaba//nisaba/port:thread_pool",
"@nlohmann_json//:json",
],
@@ -73,7 +67,6 @@ cc_library(
"bluetooth_adapter.cc",
"bluetooth_classic.cc",
"credential_storage_impl.cc",
"webrtc.cc",
"wifi_direct.cc",
"wifi_hotspot.cc",
"wifi_lan.cc",
@@ -85,7 +78,6 @@ cc_library(
"bluetooth_classic.h",
"credential_storage_impl.h",
"socket_base.h",
"webrtc.h",
"wifi.h",
"wifi_direct.h",
"wifi_hotspot.h",
@@ -94,6 +86,16 @@ cc_library(
visibility = ["//visibility:private"],
deps = [
":types",
"//internal/platform:base",
"//internal/platform:cancellation_flag",
"//internal/platform:test_util",
"//internal/platform:types",
"//internal/platform:uuid",
"//internal/platform/implementation:comm",
"//internal/platform/implementation/shared:count_down_latch",
"//internal/proto:credential_cc_proto",
# TODO: Support WebRTC
"//third_party/webrtc/files/stable/webrtc/api:scoped_refptr",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
@@ -104,17 +106,7 @@ cc_library(
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/synchronization",
"//internal/platform:base",
"//internal/platform:cancellation_flag",
"//internal/platform:test_util",
"//internal/platform:types",
"//internal/platform:uuid",
"//internal/platform/implementation:comm",
"//internal/platform/implementation/shared:count_down_latch",
"//internal/proto:credential_cc_proto",
# TODO: Support WebRTC
"//third_party/webrtc/files/stable/webrtc/api/task_queue:default_task_queue_factory",
"//third_party/webrtc/files/stable/webrtc/rtc_base:checks",
"@com_google_absl//absl/time",
],
)
@@ -124,7 +116,7 @@ cc_library(
srcs = [
"crypto.cc",
],
visibility = ["//visibility:private"],
visibility = ["//internal/platform/implementation:__subpackages__"],
deps = [
"//internal/platform:base",
"//internal/platform/implementation:types",
@@ -140,11 +132,13 @@ cc_library(
srcs = [
"platform.cc",
],
defines = ["NO_WEBRTC"],
visibility = [
"//connections:__subpackages__",
"//fastpair:__subpackages__",
"//internal/account:__subpackages__",
"//internal/auth:__subpackages__",
"//internal/crypto:__subpackages__",
"//internal/data:__subpackages__",
"//internal/flags:__subpackages__",
"//internal/network:__subpackages__",
@@ -154,24 +148,28 @@ cc_library(
"//internal/test:__subpackages__",
"//internal/weave:__subpackages__",
"//location/nearby/cpp:__subpackages__",
"//location/nearby/sharing/sdk:__subpackages__",
"//presence:__subpackages__",
"//third_party/nearby/sharing:__subpackages__",
"//sharing:__subpackages__",
],
deps = [
":comm",
":crypto", # build_cleaner: keep
":types",
"//file/base:path",
"//internal/platform:base",
"//internal/platform:test_util",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:types",
"//internal/platform/implementation/shared:count_down_latch",
"//internal/platform/implementation/shared:file",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/time",
"@com_google_nisaba//nisaba/port:thread_pool",
],
)
+25 -25
View File
@@ -21,6 +21,7 @@
#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"
@@ -64,8 +65,8 @@ bool BleServerSocket::Connect(BleSocket& socket) {
absl::MutexLock lock(&mutex_);
if (closed_) return false;
if (socket.IsConnected()) {
NEARBY_LOG(ERROR,
"Failed to connect to Ble server socket: already connected");
NEARBY_LOGS(ERROR)
<< "Failed to connect to Ble server socket: already connected";
return true; // already connected.
}
// add client socket to the pending list
@@ -126,8 +127,8 @@ BleMedium::~BleMedium() {
StopScanning(scanning_info_.service_id);
accept_loops_runner_.Shutdown();
NEARBY_LOG(INFO, "BleMedium dtor advertising_accept_thread_running_ = %d",
acceptance_thread_running_.load());
NEARBY_LOGS(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_) {
@@ -142,10 +143,11 @@ bool BleMedium::StartAdvertising(
const std::string& service_id, const ByteArray& advertisement_bytes,
const std::string& fast_advertisement_service_uuid) {
NEARBY_LOGS(INFO) << "G3 Ble StartAdvertising: service_id=" << service_id
<< ", advertisement bytes=" << advertisement_bytes.data()
<< ", advertisement bytes="
<< absl::BytesToHexString(std::string(advertisement_bytes))
<< "(" << advertisement_bytes.size() << "),"
<< " fast advertisement service uuid="
<< fast_advertisement_service_uuid;
<< ", fast advertisement service uuid="
<< absl::BytesToHexString(fast_advertisement_service_uuid);
auto& env = MediumEnvironment::Instance();
auto& peripheral = adapter_->GetPeripheral();
peripheral.SetAdvertisementBytes(service_id, advertisement_bytes);
@@ -159,14 +161,13 @@ bool BleMedium::StartAdvertising(
acceptance_thread_running_.exchange(true);
accept_loops_runner_.Execute([&env, this, service_id]() mutable {
if (!accept_loops_runner_.InShutdown()) {
while (true) {
auto client_socket =
server_socket_->Accept(&(this->adapter_->GetPeripheral()));
if (client_socket == nullptr) break;
env.CallBleAcceptedConnectionCallback(*this, *(client_socket.release()),
service_id);
}
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);
});
@@ -262,11 +263,10 @@ bool BleMedium::StopAcceptingConnections(const std::string& service_id) {
std::unique_ptr<api::BleSocket> BleMedium::Connect(
api::BlePeripheral& remote_peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag) {
NEARBY_LOG(INFO,
"G3 Ble Connect [self]: medium=%p, adapter=%p, peripheral=%p, "
"service_id=%s",
this, &GetAdapter(), &GetAdapter().GetPeripheral(),
service_id.c_str());
NEARBY_LOGS(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());
@@ -274,10 +274,10 @@ std::unique_ptr<api::BleSocket> BleMedium::Connect(
if (!medium) return {}; // Can't find medium. Bail out.
BleServerSocket* remote_server_socket = nullptr;
NEARBY_LOG(INFO,
"G3 Ble Connect [peer]: medium=%p, adapter=%p, peripheral=%p, "
"service_id=%s",
medium, &adapter, &remote_peripheral, service_id.c_str());
NEARBY_LOGS(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_);
@@ -312,7 +312,7 @@ std::unique_ptr<api::BleSocket> BleMedium::Connect(
return {};
}
NEARBY_LOG(INFO, "G3 Ble Connect: connected: socket=%p", socket.get());
NEARBY_LOGS(INFO) << "G3 Ble Connect: connected: socket=" << socket.get();
return socket;
}
+1 -1
View File
@@ -184,7 +184,7 @@ class BleMedium : public api::BleMedium {
std::atomic_bool acceptance_thread_running_ = false;
// A thread pool dedicated to wait to complete the accept_loops_runner_.
MultiThreadExecutor close_accept_loops_runner_{kMaxConcurrentAcceptLoops};
MultiThreadExecutor close_accept_loops_runner_{1};
// A server socket is established when start advertising.
std::unique_ptr<BleServerSocket> server_socket_;
@@ -160,6 +160,8 @@ Exception BleV2ServerSocket::DoClose() {
BleV2Medium::BleV2Medium(api::BluetoothAdapter& adapter)
: adapter_(static_cast<BluetoothAdapter*>(&adapter)) {
adapter_->SetBleV2Medium(this);
is_extended_advertisements_available_ =
MediumEnvironment::Instance().IsBleExtendedAdvertisementsAvailable();
MediumEnvironment::Instance().RegisterBleV2Medium(*this, &peripheral_);
}
@@ -180,7 +182,7 @@ bool BleV2Medium::StartAdvertising(
<< TxPowerLevelToName(advertise_parameters.tx_power_level)
<< ", is_connectable=" << advertise_parameters.is_connectable;
if (advertising_data.is_extended_advertisement &&
!is_support_extended_advertisement_) {
!IsExtendedAdvertisementsAvailable()) {
NEARBY_LOGS(INFO)
<< "G3 Ble StartAdvertising does not support extended advertisement";
return false;
@@ -215,7 +217,7 @@ std::unique_ptr<BleV2Medium::AdvertisingSession> BleV2Medium::StartAdvertising(
<< TxPowerLevelToName(advertise_parameters.tx_power_level)
<< ", is_connectable=" << advertise_parameters.is_connectable;
if (advertising_data.is_extended_advertisement &&
!is_support_extended_advertisement_) {
!IsExtendedAdvertisementsAvailable()) {
NEARBY_LOGS(INFO)
<< "G3 Ble StartAdvertising does not support extended advertisement";
return nullptr;
@@ -326,7 +328,7 @@ std::unique_ptr<api::ble_v2::GattClient> BleV2Medium::ConnectToGattServer(
}
bool BleV2Medium::IsExtendedAdvertisementsAvailable() {
return is_support_extended_advertisement_;
return is_extended_advertisements_available_;
}
bool BleV2Medium::GetRemotePeripheral(const std::string& mac_address,
+12 -4
View File
@@ -23,15 +23,24 @@
#include <utility>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/borrowable.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/g3/bluetooth_adapter.h"
#include "internal/platform/implementation/g3/socket_base.h"
#include "internal/platform/medium_environment.h"
#include "internal/platform/prng.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
#include "internal/platform/uuid.h"
namespace nearby {
@@ -323,8 +332,7 @@ class BleV2Medium : public api::ble_v2::BleMedium {
ABSL_GUARDED_BY(mutex_);
absl::flat_hash_set<std::pair<Uuid, std::uint32_t>>
scanning_internal_session_ids_ ABSL_GUARDED_BY(mutex_);
// TODO(edwinwu): Adds extended advertisement for testing.
bool is_support_extended_advertisement_ = false;
bool is_extended_advertisements_available_ = false;
};
} // namespace g3
@@ -217,6 +217,16 @@ std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
<< service_uuid;
return {};
}
if (cancellation_flag->Cancelled()) {
NEARBY_LOGS(ERROR)
<< "G3 Bluetooth Connect: Has been cancelled after connected: "
"service_uuid="
<< service_uuid;
socket->Close();
return {};
}
NEARBY_LOGS(INFO) << "G3 ConnectToService: connected: socket="
<< socket.get();
return socket;
@@ -70,7 +70,6 @@ void CredentialStorageImpl::SaveCredentials(
NEARBY_LOGS(INFO) << "G3 Save Private Credentials for account: ["
<< account_name << "], manager app ID:[" << manager_app_id
<< "]";
absl::MutexLock lock(&private_mutex_);
SaveLocalCredentialsLocked(manager_app_id, account_name,
private_credentials);
}
@@ -83,7 +82,6 @@ void CredentialStorageImpl::SaveCredentials(
NEARBY_LOGS(INFO) << "G3 Save Public Credentials for account: ["
<< account_name << "], manager app ID:[" << manager_app_id
<< "]";
absl::MutexLock lock(&public_mutex_);
PublicCredentialKey key = CreatePublicCredentialKey(
manager_app_id, account_name, public_credential_type);
auto public_result =
@@ -116,7 +114,6 @@ void CredentialStorageImpl::UpdateLocalCredential(
NEARBY_LOGS(INFO) << "G3 Update Private Credential for for account: ["
<< account_name << "], manager app ID:[" << manager_app_id
<< "]";
absl::MutexLock lock(&private_mutex_);
absl::StatusOr<std::vector<LocalCredential>> credentials =
GetLocalCredentialsLocked(CredentialSelector{
.manager_app_id = std::string(manager_app_id),
@@ -126,10 +123,9 @@ void CredentialStorageImpl::UpdateLocalCredential(
NEARBY_LOGS(WARNING) << credentials.status();
credentials = std::vector<LocalCredential>();
}
auto it = std::find_if(credentials->begin(), credentials->end(),
[&](const LocalCredential& a) {
return a.secret_id() == credential.secret_id();
});
auto it = std::find_if(
credentials->begin(), credentials->end(),
[&](const LocalCredential& a) { return a.id() == credential.id(); });
if (it == credentials->end()) {
credentials->push_back(std::move(credential));
} else {
@@ -143,7 +139,6 @@ void CredentialStorageImpl::GetLocalCredentials(
const CredentialSelector& credential_selector,
GetLocalCredentialsResultCallback callback) {
NEARBY_LOGS(INFO) << "G3 Get Private Credentials for " << credential_selector;
absl::MutexLock lock(&private_mutex_);
std::move(callback.credentials_fetched_cb)(
GetLocalCredentialsLocked(credential_selector));
}
@@ -174,7 +169,6 @@ void CredentialStorageImpl::GetPublicCredentials(
PublicCredentialType public_credential_type,
GetPublicCredentialsResultCallback callback) {
NEARBY_LOGS(INFO) << "G3 Get Public Credentials for " << credential_selector;
absl::MutexLock lock(&public_mutex_);
PublicCredentialKey key = CreatePublicCredentialKey(
credential_selector.manager_app_id, credential_selector.account_name,
public_credential_type);
@@ -30,8 +30,8 @@ namespace g3 {
class DeviceInfo : public api::DeviceInfo {
public:
std::optional<std::u16string> GetOsDeviceName() const override {
return u"Windows";
std::optional<std::string> GetOsDeviceName() const override {
return "Windows";
}
api::DeviceInfo::DeviceType GetDeviceType() const override {
@@ -42,16 +42,7 @@ class DeviceInfo : public api::DeviceInfo {
return api::DeviceInfo::OsType::kChromeOs;
}
std::optional<std::u16string> GetFullName() const override {
return u"nearby";
}
std::optional<std::u16string> GetGivenName() const override {
return u"nearby";
}
std::optional<std::u16string> GetLastName() const override {
return u"nearby";
}
std::optional<std::string> GetProfileUserName() const override {
std::optional<std::string> GetGivenName() const override {
return "nearby";
}
@@ -1,84 +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/log_message.h"
#include <algorithm>
#include <cstdio>
namespace nearby {
namespace g3 {
namespace {
// This is a partial copy of base::StringAppendV for OSS compilation.
void NearbyStringAppendV(std::string* dst, const char* format, va_list ap) {
// Fixed size buffer 1024 should be big enough.
static const int kSpaceLength = 1024;
char space[kSpaceLength];
int result = vsnprintf(space, kSpaceLength, format, ap);
va_end(ap);
dst->append(space, result);
}
} // namespace
api::LogMessage::Severity g_min_log_severity = api::LogMessage::Severity::kInfo;
inline absl::LogSeverity ConvertSeverity(api::LogMessage::Severity severity) {
switch (severity) {
// api::LogMessage::Severity kVerbose and kInfo is mapped to
// absl::LogSeverity kInfo since absl::LogSeverity doesn't have kVerbose
// level.
case api::LogMessage::Severity::kVerbose:
case api::LogMessage::Severity::kInfo:
return absl::LogSeverity::kInfo;
case api::LogMessage::Severity::kWarning:
return absl::LogSeverity::kWarning;
case api::LogMessage::Severity::kError:
return absl::LogSeverity::kError;
case api::LogMessage::Severity::kFatal:
return absl::LogSeverity::kFatal;
}
}
LogMessage::LogMessage(const char* file, int line, Severity severity)
: log_streamer_(ConvertSeverity(severity), file, line) {}
LogMessage::~LogMessage() = default;
void LogMessage::Print(const char* format, ...) {
va_list ap;
va_start(ap, format);
std::string result;
NearbyStringAppendV(&result, format, ap);
log_streamer_.stream() << result;
va_end(ap);
}
std::ostream& LogMessage::Stream() { return log_streamer_.stream(); }
} // namespace g3
namespace api {
void LogMessage::SetMinLogSeverity(Severity severity) {
g3::g_min_log_severity = severity;
}
bool LogMessage::ShouldCreateLogMessage(Severity severity) {
return severity >= g3::g_min_log_severity;
}
} // namespace api
} // namespace nearby
@@ -1,42 +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_LOG_MESSAGE_H_
#define PLATFORM_IMPL_G3_LOG_MESSAGE_H_
#include "glog/logging.h"
#include "internal/platform/implementation/log_message.h"
namespace nearby {
namespace g3 {
// See documentation in
// cpp/platform/api/log_message.h
class LogMessage : public api::LogMessage {
public:
LogMessage(const char* file, int line, Severity severity);
~LogMessage() override;
void Print(const char* format, ...) override;
std::ostream& Stream() override;
private:
google::LogMessage log_streamer_;
};
} // namespace g3
} // namespace nearby
#endif // PLATFORM_IMPL_G3_LOG_MESSAGE_H_
@@ -15,28 +15,45 @@
#include "internal/platform/implementation/platform.h"
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include "file/base/path.h"
#include "absl/base/attributes.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.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/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/bluetooth_classic.h"
#include "internal/platform/implementation/condition_variable.h"
#include "internal/platform/implementation/count_down_latch.h"
#include "internal/platform/implementation/credential_storage.h"
#include "internal/platform/implementation/device_info.h"
#include "internal/platform/implementation/http_loader.h"
#include "internal/platform/implementation/input_file.h"
#include "internal/platform/implementation/log_message.h"
#include "internal/platform/implementation/mutex.h"
#include "internal/platform/implementation/output_file.h"
#include "internal/platform/implementation/preferences_manager.h"
#include "internal/platform/implementation/scheduled_executor.h"
#include "internal/platform/implementation/server_sync.h"
#include "internal/platform/implementation/shared/count_down_latch.h"
#include "internal/platform/implementation/submittable_executor.h"
#include "internal/platform/implementation/timer.h"
#include "internal/platform/implementation/wifi_direct.h"
#include "internal/platform/implementation/wifi_hotspot.h"
#include "internal/platform/implementation/wifi_lan.h"
#include "internal/platform/os_name.h"
#include "internal/platform/payload_id.h"
#include "thread/thread.h"
#ifndef NO_WEBRTC
#include "internal/platform/implementation/g3/webrtc.h"
#include "internal/platform/implementation/webrtc.h"
@@ -50,7 +67,6 @@
#include "internal/platform/implementation/g3/condition_variable.h"
#include "internal/platform/implementation/g3/credential_storage_impl.h"
#include "internal/platform/implementation/g3/device_info.h"
#include "internal/platform/implementation/g3/log_message.h"
#include "internal/platform/implementation/g3/multi_thread_executor.h"
#include "internal/platform/implementation/g3/mutex.h"
#include "internal/platform/implementation/g3/preferences_manager.h"
@@ -70,14 +86,12 @@ namespace api {
std::string ImplementationPlatform::GetCustomSavePath(
const std::string& parent_folder, const std::string& file_name) {
return file::JoinPath(parent_folder, file_name);
return absl::StrCat(parent_folder, file_name);
}
std::string ImplementationPlatform::GetDownloadPath(
const std::string& parent_folder, const std::string& file_name) {
std::string fullPath("/tmp");
return file::JoinPath("/tmp", file_name);
return absl::StrCat("/tmp/", file_name);
}
OSName ImplementationPlatform::GetCurrentOS() { return OSName::kLinux; }
@@ -153,7 +167,7 @@ std::unique_ptr<OutputFile> ImplementationPlatform::CreateOutputFile(
std::unique_ptr<LogMessage> ImplementationPlatform::CreateLogMessage(
const char* file, int line, LogMessage::Severity severity) {
return std::make_unique<g3::LogMessage>(file, line, severity);
return nullptr;
}
std::unique_ptr<BluetoothClassicMedium>
@@ -16,8 +16,12 @@
#include <atomic>
#include <memory>
#include <optional>
#include <utility>
#include "absl/strings/str_format.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
#include "internal/platform/implementation/cancelable.h"
#include "internal/platform/medium_environment.h"
#include "internal/platform/runnable.h"
@@ -32,13 +36,14 @@ class ScheduledCancelable : public api::Cancelable {
public:
bool Cancel() override {
Status expected = kNotRun;
while (expected == kNotRun) {
if (status_.compare_exchange_strong(expected, kCanceled)) {
return true;
}
if (status_.compare_exchange_strong(expected, kCanceled)) {
return true;
}
return false;
}
bool IsCanceled() const { return status_ == kCanceled; }
bool MarkExecuted() {
Status expected = kNotRun;
while (expected == kNotRun) {
@@ -61,7 +66,7 @@ class ScheduledCancelable : public api::Cancelable {
} // namespace
ScheduledExecutor::ScheduledExecutor() {
absl::optional<FakeClock*> fake_clock =
std::optional<FakeClock*> fake_clock =
MediumEnvironment::Instance().GetSimulatedClock();
if (fake_clock.has_value()) {
name_ = absl::StrFormat("G3 scheduled executor %p", this);
@@ -70,7 +75,7 @@ ScheduledExecutor::ScheduledExecutor() {
}
ScheduledExecutor::~ScheduledExecutor() {
absl::optional<FakeClock*> fake_clock =
std::optional<FakeClock*> fake_clock =
MediumEnvironment::Instance().GetSimulatedClock();
if (fake_clock.has_value()) {
(*fake_clock)->RemoveObserver(name_);
@@ -86,11 +91,12 @@ std::shared_ptr<api::Cancelable> ScheduledExecutor::Schedule(
}
Runnable task = [this, scheduled_cancelable,
runnable = std::move(runnable)]() mutable {
if (!executor_.InShutdown() && scheduled_cancelable->MarkExecuted()) {
if (!executor_.InShutdown() && !scheduled_cancelable->IsCanceled() &&
scheduled_cancelable->MarkExecuted()) {
runnable();
}
};
absl::optional<FakeClock*> fake_clock =
std::optional<FakeClock*> fake_clock =
MediumEnvironment::Instance().GetSimulatedClock();
if (fake_clock.has_value()) {
absl::Time trigger_time = (*fake_clock)->Now() + delay;
@@ -104,7 +110,7 @@ std::shared_ptr<api::Cancelable> ScheduledExecutor::Schedule(
}
void ScheduledExecutor::RunReadyTasks() {
absl::optional<FakeClock*> fake_clock =
std::optional<FakeClock*> fake_clock =
MediumEnvironment::Instance().GetSimulatedClock();
if (executor_.InShutdown()) {
return;
+24 -3
View File
@@ -15,9 +15,17 @@
#include "internal/platform/implementation/g3/webrtc.h"
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/webrtc.h"
#include "internal/platform/medium_environment.h"
#include "webrtc/api/peer_connection_interface.h"
#include "webrtc/api/scoped_refptr.h"
#include "webrtc/api/task_queue/default_task_queue_factory.h"
#include "webrtc/rtc_base/checks.h"
@@ -56,6 +64,12 @@ const std::string WebRtcMedium::GetDefaultCountryCode() { return "US"; }
void WebRtcMedium::CreatePeerConnection(
webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) {
CreatePeerConnection(std::nullopt, observer, std::move(callback));
}
void WebRtcMedium::CreatePeerConnection(
std::optional<webrtc::PeerConnectionFactoryInterface::Options> options,
webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) {
auto& env = MediumEnvironment::Instance();
if (!env.GetUseValidPeerConnection()) {
callback(nullptr);
@@ -75,10 +89,17 @@ void WebRtcMedium::CreatePeerConnection(
webrtc::CreateDefaultTaskQueueFactory();
factory_dependencies.signaling_thread = signaling_thread.release();
rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface>
peer_connection_factory = webrtc::CreateModularPeerConnectionFactory(
std::move(factory_dependencies));
RTC_CHECK(peer_connection_factory != nullptr)
<< "Failed to create peer connection factory";
if (options.has_value()) {
peer_connection_factory->SetOptions(options.value());
}
auto peer_connection_or_error =
webrtc::CreateModularPeerConnectionFactory(
std::move(factory_dependencies))
->CreatePeerConnectionOrError(rtc_config, std::move(dependencies));
peer_connection_factory->CreatePeerConnectionOrError(
rtc_config, std::move(dependencies));
RTC_CHECK(peer_connection_or_error.ok())
<< "Failed to create peer connection";
@@ -16,8 +16,11 @@
#define PLATFORM_IMPL_G3_WEBRTC_H_
#include <memory>
#include <optional>
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/webrtc.h"
#include "internal/platform/implementation/g3/single_thread_executor.h"
#include "webrtc/api/peer_connection_interface.h"
@@ -63,6 +66,13 @@ class WebRtcMedium : public api::WebRtcMedium {
void CreatePeerConnection(webrtc::PeerConnectionObserver* observer,
PeerConnectionCallback callback) override;
// Creates and returns a new webrtc::PeerConnectionInterface object via
// |callback| with |PeerConnectionFactoryInterface::Options|.
void CreatePeerConnection(
std::optional<webrtc::PeerConnectionFactoryInterface::Options> options,
webrtc::PeerConnectionObserver* observer,
PeerConnectionCallback callback) override;
// Returns a signaling messenger for sending WebRTC signaling messages.
std::unique_ptr<api::WebRtcSignalingMessenger> GetSignalingMessenger(
absl::string_view self_id,
+13 -4
View File
@@ -13,6 +13,18 @@
# limitations under the License.
licenses(["notice"])
cc_library(
name = "crypto",
srcs = [
"crypto.cc",
],
visibility = ["//internal/platform/implementation:__subpackages__"],
deps = [
"@boringssl//:crypto",
"@com_google_absl//absl/types:span",
],
)
cc_library(
name = "posix_mutex",
srcs = [
@@ -45,10 +57,7 @@ cc_library(
name = "file",
srcs = ["file.cc"],
hdrs = ["file.h"],
visibility = [
"//connections/implementation:__subpackages__",
"//internal/platform/implementation:__subpackages__",
],
visibility = ["//internal/platform/implementation:__subpackages__"],
deps = [
"//internal/platform:base",
"//internal/platform/implementation:types",
@@ -1,4 +1,4 @@
// Copyright 2021 Google LLC
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,10 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/nsd_service_info.h"
#include <stddef.h>
#include <stdint.h>
#include "absl/types/span.h"
#include <openssl/rand.h>
namespace nearby {
constexpr absl::string_view NsdServiceInfo::kNsdTypeFormat;
void RandBytes(void* bytes, size_t length) {
RAND_bytes(reinterpret_cast<uint8_t*>(bytes), length);
}
void RandBytes(absl::Span<uint8_t> bytes) {
RAND_bytes(bytes.data(), bytes.size());
}
} // namespace nearby
@@ -14,7 +14,6 @@
#include "internal/platform/implementation/shared/file.h"
#include <algorithm>
#include <cstddef>
#include <ios>
#include <memory>
@@ -37,7 +36,7 @@ IOFile::IOFile(const absl::string_view file_path, size_t size)
: file_(std::string(file_path.data(), file_path.size()),
std::ios::binary | std::ios::in | std::ios::ate),
path_(file_path),
total_size_(file_.tellg()) {
total_size_(size) {
file_.seekg(0);
}
@@ -18,8 +18,10 @@
#ifndef NO_WEBRTC
#include <memory>
#include <optional>
#include <string>
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "connections/implementation/proto/offline_wire_formats.pb.h"
#include "internal/platform/byte_array.h"
@@ -60,6 +62,13 @@ class WebRtcMedium {
virtual void CreatePeerConnection(webrtc::PeerConnectionObserver* observer,
PeerConnectionCallback callback) = 0;
// Creates and returns a new webrtc::PeerConnectionInterface object via
// |callback| with |PeerConnectionFactoryInterface::Options|.
virtual void CreatePeerConnection(
std::optional<webrtc::PeerConnectionFactoryInterface::Options> options,
webrtc::PeerConnectionObserver* observer,
PeerConnectionCallback callback) = 0;
// Returns a signaling messenger for sending WebRTC signaling messages.
virtual std::unique_ptr<WebRtcSignalingMessenger> GetSignalingMessenger(
absl::string_view self_id,
+5 -4
View File
@@ -17,6 +17,7 @@
#include <string>
#include "absl/functional/any_invocable.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/listeners.h"
@@ -99,10 +100,10 @@ class WifiLanMedium {
// Callback that is invoked when a discovered service is found or lost.
struct DiscoveredServiceCallback {
absl::AnyInvocable<void(NsdServiceInfo service_info)>
service_discovered_cb = DefaultCallback<NsdServiceInfo>();
absl::AnyInvocable<void(NsdServiceInfo service_info)> service_lost_cb =
DefaultCallback<NsdServiceInfo>();
absl::AnyInvocable<void(const NsdServiceInfo& service_info)>
service_discovered_cb = DefaultCallback<const NsdServiceInfo&>();
absl::AnyInvocable<void(const NsdServiceInfo& service_info)>
service_lost_cb = DefaultCallback<const NsdServiceInfo&>();
};
// Starts the discovery of nearby WifiLan services.
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/wifi_utils.h"
#include "internal/platform/implementation/wifi_utils.h"
#include <string>
#include <vector>
@@ -21,6 +21,7 @@
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
namespace nearby {
@@ -12,11 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef PLATFORM_BASE_WIFI_UTILS_H_
#define PLATFORM_BASE_WIFI_UTILS_H_
#ifndef PLATFORM_PUBLIC_WIFI_UTILS_H_
#define PLATFORM_PUBLIC_WIFI_UTILS_H_
#include <string>
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/wifi.h"
namespace nearby {
@@ -57,4 +58,4 @@ class WifiUtils {
} // namespace nearby
#endif // PLATFORM_BASE_WIFI_UTILS_H_
#endif // PLATFORM_PUBLIC_WIFI_UTILS_H_
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/wifi_utils.h"
#include "internal/platform/implementation/wifi_utils.h"
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
+72 -22
View File
@@ -18,7 +18,6 @@ cc_library(
name = "types",
srcs = [
"device_info.cc",
"log_message.cc",
"timer.cc",
],
hdrs = [
@@ -31,30 +30,30 @@ cc_library(
"future.h",
"input_file.h",
"listenable_future.h",
"log_message.h",
"mutex.h",
"output_file.h",
"preferences_manager.h",
"scheduled_executor.h",
"settable_future.h",
"submittable_executor.h",
"task_scheduler.h",
"timer.h",
"utils.h",
],
copts = ["-Ithird_party/nearby/internal/platform/implementation/windows/generated"],
defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"],
visibility = ["//third_party/nearby/sharing/internal/impl/windows:__pkg__"],
visibility = [
"//sharing/internal/impl/windows:__pkg__",
],
deps = [
":comm",
"//base",
"//base:stringprintf",
"//internal/base:bluetooth_address",
"//internal/base:files",
"//internal/flags:nearby_flags",
"//internal/platform:base",
"//internal/platform:types",
"//internal/platform:logging",
"//internal/platform:uuid",
"//internal/platform/implementation:types",
"//internal/platform/implementation/windows/generated:types",
"//strings:strappendv",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
@@ -102,16 +101,21 @@ cc_library(
"wifi.h",
"wifi_direct.h",
"wifi_hotspot.h",
"wifi_intel.h",
"wifi_lan.h",
],
copts = ["-DNO_INTEL_PIE"],
visibility = ["//visibility:private"],
deps = [
"//connections/implementation/flags:connections_flags",
"//internal/flags:nearby_flags",
"//internal/platform:base",
"//internal/platform:comm",
"//internal/platform:types",
"//internal/platform:uuid",
"//internal/platform/flags:platform_flags",
"//internal/platform/implementation:account_manager",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:types",
"//internal/platform/implementation:wifi_utils",
"//internal/platform/implementation/shared:count_down_latch",
"//internal/platform/implementation/windows/generated:types",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
@@ -141,6 +145,26 @@ cc_library(
],
)
cc_library(
name = "string_utils",
srcs = [
"string_utils.cc",
],
hdrs = [
"string_utils.h",
],
compatible_with = ["//buildenv/target:non_prod"],
visibility = [
"//internal/platform:__subpackages__",
"//location/nearby:__subpackages__",
],
deps = [
"//internal/platform:logging",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
],
)
cc_library(
name = "windows",
srcs = [
@@ -170,6 +194,7 @@ cc_library(
"session_manager.cc",
"submittable_executor.cc",
"system_clock.cc",
"task_scheduler.cc",
"thread_pool.cc",
"utils.cc",
"webrtc.cc",
@@ -179,6 +204,7 @@ cc_library(
"wifi_hotspot_medium.cc",
"wifi_hotspot_server_socket.cc",
"wifi_hotspot_socket.cc",
"wifi_intel.cc",
"wifi_lan_medium.cc",
"wifi_lan_server_socket.cc",
"wifi_lan_socket.cc",
@@ -186,30 +212,40 @@ cc_library(
],
# This is the temporary solution to solve compilation error of Win32 WFDxxx() related API.
# WFD API is only support after _WIN32_WINNT_WIN8, but the current lexan _WIN32_WINNT is set to _WIN32_WINNT_WIN7
copts = ["-Ithird_party/nearby/internal/platform/implementation/windows/generated -D_WIN32_WINNT=_WIN32_WINNT_WIN10 -DWINVER=_WIN32_WINNT_WIN10"],
copts = [
"-DNO_INTEL_PIE",
"-D_WIN32_WINNT=_WIN32_WINNT_WIN10 -DWINVER=_WIN32_WINNT_WIN10",
"-Wno-unused-variable",
"-Wno-unused-value",
],
defines = ["_SILENCE_CLANG_COROUTINE_MESSAGE"],
visibility = [
"//chrome/chromeos/assistant/data_migration/lib:__pkg__",
"//connections:__subpackages__",
"//fastpair:__subpackages__",
"//internal/platform:__subpackages__",
"//location/nearby:__subpackages__",
"//presence:__subpackages__",
"//third_party/nearby/sharing:__subpackages__",
"//sharing:__subpackages__",
],
deps = [
":comm",
":crypto", # build_cleaner: keep
":string_utils",
":types",
"//connections/implementation/flags:connections_flags",
"//internal/account",
"//internal/base:files",
"//internal/flags:nearby_flags",
"//internal/platform:base",
"//internal/platform:cancellation_flag",
"//internal/platform:comm",
"//internal/platform:types",
"//internal/platform:logging",
"//internal/platform:uuid",
"//internal/platform/flags:platform_flags",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:types",
"//internal/platform/implementation:wifi_utils",
"//internal/platform/implementation/shared:count_down_latch",
"//internal/platform/implementation/shared:file",
"//internal/platform/implementation/windows/generated:types",
@@ -218,7 +254,6 @@ cc_library(
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
@@ -240,9 +275,7 @@ cc_library(
"test_data.h",
"test_utils.h",
],
visibility = [
"//visibility:private", # Only private by automation, not intent. Owner may accept CLs adding visibility. See go/scheuklappen#explicit-private.
],
visibility = ["//visibility:private"],
deps = [
"//internal/platform:base",
"@nlohmann_json//:json",
@@ -270,13 +303,16 @@ cc_test(
"preferences_repository_test.cc",
"scheduled_executor_test.cc",
"submittable_executor_test.cc",
"task_scheduler_test.cc",
"thread_pool_test.cc",
"timer_test.cc",
"utils_test.cc",
"webrtc_test.cc",
"wifi_hotspot_test.cc",
"wifi_medium_test.cc",
],
copts = ["-Ithird_party/nearby/internal/platform/implementation/windows/generated -DCORE_ADAPTER_DLL"],
tags = ["notap"],
copts = ["-DCORE_ADAPTER_DLL"],
tags = ["nozapfhahn"],
deps = [
":comm",
":crypto",
@@ -284,7 +320,7 @@ cc_test(
":types",
":windows",
"//internal/platform:base",
"//internal/platform:types",
"//internal/platform:logging",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:types",
@@ -300,3 +336,17 @@ cc_test(
"@nlohmann_json//:json",
],
)
cc_test(
name = "string_utils_test",
size = "small",
timeout = "short",
srcs = [
"string_utils_test.cc",
],
deps = [
":string_utils",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_googletest//:gtest_main",
],
)
@@ -25,6 +25,7 @@ namespace windows {
// A boolean value that may be updated atomically.
class AtomicBoolean : public api::AtomicBoolean {
public:
explicit AtomicBoolean(bool value = false) : atomic_boolean_(value) {}
~AtomicBoolean() override = default;
// Atomically read and return current value.
@@ -16,6 +16,7 @@
#define PLATFORM_IMPL_WINDOWS_ATOMIC_REFERENCE_H_
#include <atomic>
#include <cstdint>
#include "internal/platform/implementation/atomic_reference.h"
@@ -25,6 +26,7 @@ namespace windows {
// Type that allows 32-bit atomic reads and writes.
class AtomicUint32 : public api::AtomicUint32 {
public:
explicit AtomicUint32(std::uint32_t value = 0) : atomic_uint32_(value) {}
~AtomicUint32() override = default;
// Atomically reads and returns stored value.
@@ -37,6 +37,7 @@
#include "internal/platform/byte_array.h"
#include "internal/platform/flags/nearby_platform_feature_flags.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/utils.h"
#include "internal/platform/logging.h"
#include "internal/platform/uuid.h"
@@ -101,31 +102,42 @@ std::string GattCommunicationStatusToString(GattCommunicationStatus status) {
BleGattClient::BleGattClient(BluetoothLEDevice ble_device)
: ble_device_(ble_device) {
NEARBY_LOGS(VERBOSE) << __func__ << ": GATT client is created.";
if (ble_device_ == nullptr) {
LOG(WARNING) << __func__ << ": ble_device is null.";
} else {
LOG(INFO) << __func__ << ": GATT client is created, address: "
<< uint64_to_mac_address_string(ble_device_.BluetoothAddress());
}
}
BleGattClient::~BleGattClient() {
NEARBY_LOGS(VERBOSE) << __func__ << ": GATT client is released.";
LOG(INFO) << __func__ << ": GATT client is released.";
Disconnect();
}
bool BleGattClient::DiscoverServiceAndCharacteristics(
const Uuid& service_uuid, const std::vector<Uuid>& characteristic_uuids) {
absl::MutexLock lock(&mutex_);
if (!NearbyFlags::GetInstance().GetBoolFlag(
platform::config_package_nearby::nearby_platform_feature::
kEnableBleV2Gatt)) {
auto windows_bluetooth_adapter_ = ::winrt::Windows::Devices::Bluetooth::
BluetoothAdapter::GetDefaultAsync()
.get();
if (windows_bluetooth_adapter_.IsExtendedAdvertisingSupported()) {
NEARBY_LOGS(WARNING) << __func__ << ": GATT is disabled.";
BluetoothAdapter bluetooth_adapter;
if (bluetooth_adapter.IsExtendedAdvertisingSupported()) {
LOG(WARNING) << __func__ << ": GATT is disabled.";
return false;
}
if (!bluetooth_adapter.IsCentralRoleSupported()) {
LOG(ERROR) << __func__
<< ": Bluetooth Hardware does not support Central "
"Role, which is required to start GATT client.";
return false;
}
if (!NearbyFlags::GetInstance().GetBoolFlag(
platform::config_package_nearby::nearby_platform_feature::
kEnableBleV2GattOnNonExtendedDevice)) {
NEARBY_LOGS(WARNING) << __func__ << ": GATT is disabled.";
LOG(WARNING) << __func__ << ": GATT is disabled.";
return false;
}
}
@@ -135,13 +147,12 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
absl::StrAppend(out, std::string(uuid));
});
NEARBY_LOGS(VERBOSE) << __func__ << ": Discover service_uuid="
<< std::string(service_uuid)
<< " with characteristic_uuids=" << flat_characteristics;
VLOG(1) << __func__ << ": Discover service_uuid=" << std::string(service_uuid)
<< " with characteristic_uuids=" << flat_characteristics;
try {
if (ble_device_ == nullptr) {
NEARBY_LOGS(ERROR) << __func__ << ": BLE device is disconnected.";
LOG(ERROR) << __func__ << ": BLE device is disconnected.";
return false;
}
@@ -155,23 +166,21 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
gatt_devices_services_result_ = get_gatt_services_async.GetResults();
break;
case winrt::Windows::Foundation::AsyncStatus::Started:
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get GATT services due to timeout.";
LOG(ERROR) << __func__
<< ": Failed to get GATT services due to timeout.";
get_gatt_services_async.Cancel();
return false;
default:
NEARBY_LOGS(ERROR)
<< __func__
<< ": Failed to get GATT services due to unknown reasons.";
LOG(ERROR) << __func__
<< ": Failed to get GATT services due to unknown reasons.";
return false;
}
if (gatt_devices_services_result_.Status() !=
GattCommunicationStatus::Success) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get gatt service with error: "
<< GattCommunicationStatusToString(
gatt_devices_services_result_.Status());
LOG(ERROR) << __func__ << ": Failed to get gatt service with error: "
<< GattCommunicationStatusToString(
gatt_devices_services_result_.Status());
gatt_devices_services_result_ = nullptr;
return false;
}
@@ -185,9 +194,8 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
winrt::to_string(winrt::to_hstring(service.Uuid())));
});
NEARBY_LOGS(VERBOSE) << __func__
<< ": Found GATT services=" << flat_services
<< " from BLE device.";
LOG(INFO) << __func__ << ": Found GATT services=" << flat_services
<< " from BLE device.";
// Needs to check each service to make sure it includes all characteristic
// uuids. Services may include duplicate service UUID, but each of them may
@@ -196,27 +204,25 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
winrt::guid uuid = service.Uuid();
std::string uuid_string = winrt::to_string(winrt::to_hstring(uuid));
NEARBY_LOGS(VERBOSE) << __func__
<< ": Found service UUID=" << uuid_string;
VLOG(1) << __func__ << ": Found service UUID=" << uuid_string;
if (!is_nearby_uuid_equal_to_winrt_guid(service_uuid, uuid)) {
NEARBY_LOGS(WARNING)
LOG(WARNING)
<< __func__
<< ": Service uuid not match, continue check other services.";
continue;
}
NEARBY_LOGS(INFO) << __func__
<< ": Found the discovery service UUID=" << uuid_string;
LOG(INFO) << __func__
<< ": Found the discovery service UUID=" << uuid_string;
// Try to check the characteristic uuids.
GattCharacteristicsResult gatt_characteristics_result =
service.GetCharacteristicsAsync(BluetoothCacheMode::Uncached).get();
if (gatt_characteristics_result.Status() !=
GattCommunicationStatus::Success) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get characteristics with error: "
<< GattCommunicationStatusToString(
gatt_characteristics_result.Status());
LOG(ERROR) << __func__ << ": Failed to get characteristics with error: "
<< GattCommunicationStatusToString(
gatt_characteristics_result.Status());
continue;
}
@@ -227,8 +233,8 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
gatt_characteristic.Uuid())));
});
NEARBY_LOGS(VERBOSE) << __func__ << ": Found GATT characteristics="
<< flat_characteristics;
VLOG(1) << __func__
<< ": Found GATT characteristics=" << flat_characteristics;
bool found_all = true;
@@ -246,8 +252,8 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
}
}
if (found == false) {
NEARBY_LOGS(WARNING) << __func__ << ": Cannot find characteristic: "
<< std::string(characteristic_uuid);
LOG(WARNING) << __func__ << ": Cannot find characteristic: "
<< std::string(characteristic_uuid);
found_all = false;
break;
}
@@ -258,21 +264,18 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
}
// found all characteristics.
NEARBY_LOGS(VERBOSE) << __func__ << ": Found all characteristics.";
VLOG(1) << __func__ << ": Found all characteristics.";
return true;
}
NEARBY_LOGS(VERBOSE) << __func__
<< ": Failed to find service and all characteristics.";
LOG(ERROR) << __func__
<< ": Failed to find service and all characteristics.";
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get GATT services. exception: "
<< exception.what();
LOG(ERROR) << __func__ << ": Failed to get GATT services. exception: "
<< exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get GATT services. WinRT exception: "
<< error.code() << ": "
<< winrt::to_string(error.message());
LOG(ERROR) << __func__ << ": Failed to get GATT services. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
}
return false;
@@ -281,17 +284,16 @@ bool BleGattClient::DiscoverServiceAndCharacteristics(
absl::optional<api::ble_v2::GattCharacteristic>
BleGattClient::GetCharacteristic(const Uuid& service_uuid,
const Uuid& characteristic_uuid) {
NEARBY_LOGS(VERBOSE) << __func__ << ": Stared to get characteristic UUID="
<< std::string(characteristic_uuid)
<< " in service UUID=" << std::string(service_uuid);
absl::MutexLock lock(&mutex_);
VLOG(1) << __func__ << ": Stared to get characteristic UUID="
<< std::string(characteristic_uuid)
<< " in service UUID=" << std::string(service_uuid);
try {
std::optional<GattCharacteristic> gatt_characteristic =
GetNativeCharacteristic(service_uuid, characteristic_uuid);
if (!gatt_characteristic.has_value()) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get native GATT characteristic.";
LOG(ERROR) << __func__ << ": Failed to get native GATT characteristic.";
return absl::nullopt;
}
@@ -329,18 +331,17 @@ BleGattClient::GetCharacteristic(const Uuid& service_uuid,
native_characteristic_map_[result].native_characteristic =
gatt_characteristic;
NEARBY_LOGS(VERBOSE) << __func__ << ": Return Characteristic. uuid="
<< std::string(characteristic_uuid);
VLOG(1) << __func__ << ": Return Characteristic. uuid="
<< std::string(characteristic_uuid);
return result;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get GATT characteristic. exception: "
<< exception.what();
LOG(ERROR) << __func__ << ": Failed to get GATT characteristic. exception: "
<< exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR)
<< __func__ << ": Failed to get GATT characteristic. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
LOG(ERROR) << __func__
<< ": Failed to get GATT characteristic. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
}
return absl::nullopt;
@@ -348,33 +349,33 @@ BleGattClient::GetCharacteristic(const Uuid& service_uuid,
absl::optional<std::string> BleGattClient::ReadCharacteristic(
const api::ble_v2::GattCharacteristic& characteristic) {
NEARBY_LOGS(VERBOSE) << __func__ << ": Read characteristic="
<< std::string(characteristic.uuid);
absl::MutexLock lock(&mutex_);
VLOG(1) << __func__
<< ": Read characteristic=" << std::string(characteristic.uuid);
try {
std::optional<GattCharacteristic> gatt_characteristic =
GetNativeCharacteristic(characteristic.service_uuid,
characteristic.uuid);
if (!gatt_characteristic.has_value()) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get native GATT characteristic.";
LOG(ERROR) << __func__ << ": Failed to get native GATT characteristic.";
return absl::nullopt;
}
GattReadResult result =
gatt_characteristic->ReadValueAsync(BluetoothCacheMode::Uncached).get();
if (result.Status() != GattCommunicationStatus::Success) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to read GATT characteristic with error: "
<< GattCommunicationStatusToString(result.Status());
LOG(ERROR) << __func__
<< ": Failed to read GATT characteristic with error: "
<< GattCommunicationStatusToString(result.Status());
return absl::nullopt;
}
IBuffer buffer = result.Value();
int size = buffer.Length();
if (size == 0) {
NEARBY_LOGS(WARNING) << __func__ << ": No characteristic value.";
return absl::nullopt;
VLOG(1) << __func__ << ": No characteristic value.";
return "";
}
DataReader data_reader = DataReader::FromBuffer(buffer);
@@ -384,18 +385,17 @@ absl::optional<std::string> BleGattClient::ReadCharacteristic(
data.push_back(static_cast<char>(data_reader.ReadByte()));
}
NEARBY_LOGS(VERBOSE) << __func__
<< ": Got characteristic value length=" << data.size();
VLOG(1) << __func__ << ": Got characteristic value length=" << data.size();
return data;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to read GATT characteristic. exception: "
<< exception.what();
LOG(ERROR) << __func__
<< ": Failed to read GATT characteristic. exception: "
<< exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR)
<< __func__ << ": Failed to read GATT characteristic. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
LOG(ERROR) << __func__
<< ": Failed to read GATT characteristic. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
}
return absl::nullopt;
@@ -404,16 +404,15 @@ absl::optional<std::string> BleGattClient::ReadCharacteristic(
bool BleGattClient::WriteCharacteristic(
const api::ble_v2::GattCharacteristic& characteristic,
absl::string_view value, api::ble_v2::GattClient::WriteType write_type) {
NEARBY_LOGS(VERBOSE) << __func__ << ": write characteristic: "
<< std::string(characteristic.uuid);
absl::MutexLock lock(&mutex_);
VLOG(1) << __func__
<< ": write characteristic: " << std::string(characteristic.uuid);
try {
std::optional<GattCharacteristic> gatt_characteristic =
native_characteristic_map_[characteristic].native_characteristic;
if (!gatt_characteristic.has_value()) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get native GATT characteristic.";
LOG(ERROR) << __func__ << ": Failed to get native GATT characteristic.";
return false;
}
@@ -430,27 +429,25 @@ bool BleGattClient::WriteCharacteristic(
gatt_characteristic->WriteValueAsync(buffer, write_option).get();
if (status != GattCommunicationStatus::Success) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to write data to GATT characteristic: "
<< std::string(characteristic.uuid) << "with error: "
<< GattCommunicationStatusToString(status);
LOG(ERROR) << __func__
<< ": Failed to write data to GATT characteristic: "
<< std::string(characteristic.uuid)
<< "with error: " << GattCommunicationStatusToString(status);
return false;
} else {
NEARBY_LOGS(VERBOSE) << __func__
<< ": Write data to GATT characteristic: "
<< std::string(characteristic.uuid)
<< ", bytes count: " << value.size();
VLOG(1) << __func__ << ": Write data to GATT characteristic: "
<< std::string(characteristic.uuid)
<< ", bytes count: " << value.size();
return true;
}
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to write GATT characteristic. exception: "
<< exception.what();
LOG(ERROR) << __func__
<< ": Failed to write GATT characteristic. exception: "
<< exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR)
<< __func__
<< ": Failed to write GATT characteristic. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
LOG(ERROR) << __func__
<< ": Failed to write GATT characteristic. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
}
return false;
}
@@ -459,8 +456,8 @@ bool BleGattClient::SetCharacteristicSubscription(
const api::ble_v2::GattCharacteristic& characteristic, bool enable,
absl::AnyInvocable<void(absl::string_view value)>
on_characteristic_changed_cb) {
NEARBY_LOGS(VERBOSE) << __func__
<< ": Started to set Characteristic Subscription.";
absl::MutexLock lock(&mutex_);
VLOG(1) << __func__ << ": Started to set Characteristic Subscription.";
GattClientCharacteristicConfigurationDescriptorValue gcccd_value =
GattClientCharacteristicConfigurationDescriptorValue::None;
if ((characteristic.property & Property::kNotify) != Property::kNone) {
@@ -470,22 +467,18 @@ bool BleGattClient::SetCharacteristicSubscription(
gcccd_value =
GattClientCharacteristicConfigurationDescriptorValue::Indicate;
} else {
NEARBY_LOGS(WARNING) << "Characeristic: "
<< std::string(characteristic.uuid)
<< " supports neither notifications nor indications.";
LOG(WARNING) << "Characeristic: " << std::string(characteristic.uuid)
<< " supports neither notifications nor indications.";
return false;
}
std::optional<GattCharacteristic> gatt_characteristic;
{
absl::MutexLock lock(&mutex_);
gatt_characteristic =
native_characteristic_map_[characteristic].native_characteristic;
}
gatt_characteristic =
native_characteristic_map_[characteristic].native_characteristic;
if (!gatt_characteristic.has_value()) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to get native GATT characteristic.";
LOG(ERROR) << __func__ << ": Failed to get native GATT characteristic.";
return false;
}
@@ -498,7 +491,6 @@ bool BleGattClient::SetCharacteristicSubscription(
return false;
}
absl::MutexLock lock(&mutex_);
// Set value changed handler
try {
if (enable) {
@@ -513,27 +505,23 @@ bool BleGattClient::SetCharacteristicSubscription(
});
if (!native_characteristic_map_[characteristic].notification_token) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to add value change handler.";
LOG(ERROR) << __func__ << ": Failed to add value change handler.";
return false;
}
} else if (native_characteristic_map_[characteristic].notification_token) {
gatt_characteristic->ValueChanged(std::exchange(
native_characteristic_map_[characteristic].notification_token, {}));
}
NEARBY_LOGS(ERROR) << __func__
<< ": Successfully set Characteristic Subscription.";
LOG(ERROR) << __func__ << ": Successfully set Characteristic Subscription.";
return true;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to set Characteristic Subscription."
<< exception.what();
LOG(ERROR) << __func__ << ": Failed to set Characteristic Subscription."
<< exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to set Characteristic Subscription."
" WinRT exception: "
<< error.code() << ": "
<< winrt::to_string(error.message());
LOG(ERROR) << __func__
<< ": Failed to set Characteristic Subscription."
" WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
}
return false;
}
@@ -541,38 +529,36 @@ bool BleGattClient::SetCharacteristicSubscription(
void BleGattClient::Disconnect() {
absl::MutexLock lock(&mutex_);
try {
NEARBY_LOGS(VERBOSE) << __func__ << ": Disconnect is called.";
VLOG(1) << __func__ << ": Disconnect is called.";
if (ble_device_ != nullptr) {
ble_device_.Close();
ble_device_ = nullptr;
}
native_characteristic_map_.clear();
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to disconnect GATT device. exception: "
<< exception.what();
LOG(ERROR) << __func__ << ": Failed to disconnect GATT device. exception: "
<< exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR)
<< __func__ << ": Failed to disconnect GATT device. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
LOG(ERROR) << __func__
<< ": Failed to disconnect GATT device. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
}
}
std::optional<GattCharacteristic> BleGattClient::GetNativeCharacteristic(
const Uuid& service_uuid, const Uuid& characteristic_uuid) {
NEARBY_LOGS(VERBOSE) << __func__
<< ": Stared to get native characteristic UUID="
<< std::string(characteristic_uuid)
<< " in service UUID=" << std::string(service_uuid);
VLOG(1) << __func__ << ": Stared to get native characteristic UUID="
<< std::string(characteristic_uuid)
<< " in service UUID=" << std::string(service_uuid);
try {
if (ble_device_ == nullptr) {
NEARBY_LOGS(ERROR) << __func__ << ": BLE device is disconnected.";
LOG(ERROR) << __func__ << ": BLE device is disconnected.";
return absl::nullopt;
}
if (gatt_devices_services_result_ == nullptr) {
NEARBY_LOGS(ERROR) << __func__ << ": No available GATT services.";
LOG(ERROR) << __func__ << ": No available GATT services.";
return absl::nullopt;
}
@@ -582,10 +568,10 @@ std::optional<GattCharacteristic> BleGattClient::GetNativeCharacteristic(
service.GetCharacteristicsAsync(BluetoothCacheMode::Cached).get();
if (gatt_characteristics_result.Status() !=
GattCommunicationStatus::Success) {
NEARBY_LOGS(ERROR)
<< __func__ << ": Failed to get characteristics with error: "
<< GattCommunicationStatusToString(
gatt_characteristics_result.Status());
LOG(ERROR) << __func__
<< ": Failed to get characteristics with error: "
<< GattCommunicationStatusToString(
gatt_characteristics_result.Status());
continue;
}
@@ -593,9 +579,8 @@ std::optional<GattCharacteristic> BleGattClient::GetNativeCharacteristic(
gatt_characteristics_result.Characteristics()) {
if (is_nearby_uuid_equal_to_winrt_guid(characteristic_uuid,
characteristic.Uuid())) {
NEARBY_LOGS(VERBOSE)
<< __func__ << ": Return native Characteristic. uuid="
<< std::string(characteristic_uuid);
VLOG(1) << __func__ << ": Return native Characteristic. uuid="
<< std::string(characteristic_uuid);
return characteristic;
}
@@ -603,13 +588,13 @@ std::optional<GattCharacteristic> BleGattClient::GetNativeCharacteristic(
}
}
NEARBY_LOGS(ERROR) << __func__ << ": Failed to get native characteristic.";
LOG(ERROR) << __func__ << ": Failed to get native characteristic.";
} catch (std::exception exception) {
NEARBY_LOGS(ERROR)
<< __func__ << ": Failed to get native GATT characteristic. exception: "
<< exception.what();
LOG(ERROR) << __func__
<< ": Failed to get native GATT characteristic. exception: "
<< exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR)
LOG(ERROR)
<< __func__
<< ": Failed to get native GATT characteristic. WinRT exception: "
<< error.code() << ": " << winrt::to_string(error.message());
@@ -621,9 +606,8 @@ std::optional<GattCharacteristic> BleGattClient::GetNativeCharacteristic(
bool BleGattClient::WriteCharacteristicConfigurationDescriptor(
GattCharacteristic& characteristic,
GattClientCharacteristicConfigurationDescriptorValue value) {
NEARBY_LOGS(VERBOSE)
<< __func__
<< ": Stared to write characteristic configuration descriptor";
VLOG(1) << __func__
<< ": Stared to write characteristic configuration descriptor";
try {
GattCommunicationStatus status =
@@ -631,23 +615,23 @@ bool BleGattClient::WriteCharacteristicConfigurationDescriptor(
.WriteClientCharacteristicConfigurationDescriptorAsync(value)
.get();
if (status == GattCommunicationStatus::Success) {
NEARBY_LOGS(VERBOSE) << __func__
<< ": Successfully write client characteristic "
"configuration descriptor";
VLOG(1) << __func__
<< ": Successfully write client characteristic "
"configuration descriptor";
return true;
}
NEARBY_LOGS(VERBOSE) << __func__
<< ": Failed to write client characteristic "
"configuration descriptor with error: "
<< GattCommunicationStatusToString(status);
LOG(ERROR) << __func__
<< ": Failed to write client characteristic "
"configuration descriptor with error: "
<< GattCommunicationStatusToString(status);
} catch (std::exception exception) {
// This usually happens when a device reports that it support notify, but
// it actually doesn't.
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to write client characteristic "
"configuration descriptor";
LOG(ERROR) << __func__
<< ": Failed to write client characteristic "
"configuration descriptor";
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR)
LOG(ERROR)
<< __func__
<< ": Failed to write client characteristic configuration descriptor."
" WinRT exception: "
@@ -659,7 +643,7 @@ bool BleGattClient::WriteCharacteristicConfigurationDescriptor(
void BleGattClient::OnCharacteristicValueChanged(
const api::ble_v2::GattCharacteristic& characteristic,
GattValueChangedEventArgs args) {
NEARBY_LOGS(VERBOSE) << __func__ << ": Gatt Characteristic value changed.";
VLOG(1) << __func__ << ": Gatt Characteristic value changed.";
IBuffer buffer = args.CharacteristicValue();
int size = buffer.Length();
DataReader data_reader = DataReader::FromBuffer(buffer);
@@ -668,8 +652,7 @@ void BleGattClient::OnCharacteristicValueChanged(
for (int i = 0; i < size; ++i) {
data.push_back(static_cast<char>(data_reader.ReadByte()));
}
NEARBY_LOGS(VERBOSE) << __func__
<< ": Got characteristic value length= " << data.size();
VLOG(1) << __func__ << ": Got characteristic value length= " << data.size();
absl::AnyInvocable<void(absl::string_view value)>
on_characteristic_changed_cb;
@@ -678,8 +661,7 @@ void BleGattClient::OnCharacteristicValueChanged(
if (!native_characteristic_map_.contains(characteristic) ||
!native_characteristic_map_[characteristic]
.on_characteristic_changed_cb) {
NEARBY_LOGS(INFO) << __func__
<< ": No registered callback for characteristic.";
LOG(INFO) << __func__ << ": No registered callback for characteristic.";
return;
}
on_characteristic_changed_cb =
@@ -23,10 +23,15 @@
#include <string>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/types/optional.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/uuid.h"
#include "winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h"
#include "winrt/Windows.Devices.Bluetooth.h"
#include "winrt/base.h"
@@ -42,25 +47,29 @@ class BleGattClient : public api::ble_v2::GattClient {
bool DiscoverServiceAndCharacteristics(
const Uuid& service_uuid,
const std::vector<Uuid>& characteristic_uuids) override;
const std::vector<Uuid>& characteristic_uuids) override
ABSL_LOCKS_EXCLUDED(mutex_);
absl::optional<api::ble_v2::GattCharacteristic> GetCharacteristic(
const Uuid& service_uuid, const Uuid& characteristic_uuid) override;
const Uuid& service_uuid, const Uuid& characteristic_uuid) override
ABSL_LOCKS_EXCLUDED(mutex_);
absl::optional<std::string> ReadCharacteristic(
const api::ble_v2::GattCharacteristic& characteristic) override;
const api::ble_v2::GattCharacteristic& characteristic) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool WriteCharacteristic(
const api::ble_v2::GattCharacteristic& characteristic,
absl::string_view value,
api::ble_v2::GattClient::WriteType write_type) override;
api::ble_v2::GattClient::WriteType write_type) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool SetCharacteristicSubscription(
const api::ble_v2::GattCharacteristic& characteristic, bool enable,
absl::AnyInvocable<void(absl::string_view value)>
on_characteristic_changed_cb) override;
on_characteristic_changed_cb) override ABSL_LOCKS_EXCLUDED(mutex_);
void Disconnect() override;
void Disconnect() override ABSL_LOCKS_EXCLUDED(mutex_);
private:
// Used to save native data related to the GATT characteristic.
@@ -75,13 +84,15 @@ class BleGattClient : public api::ble_v2::GattClient {
std::optional<::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCharacteristic>
GetNativeCharacteristic(const Uuid& service_uuid,
const Uuid& characteristic_uuid);
const Uuid& characteristic_uuid)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool WriteCharacteristicConfigurationDescriptor(
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCharacteristic& characteristic,
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattClientCharacteristicConfigurationDescriptorValue value);
GattClientCharacteristicConfigurationDescriptorValue value)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void OnCharacteristicValueChanged(
const api::ble_v2::GattCharacteristic& characteristic,
@@ -90,9 +101,11 @@ class BleGattClient : public api::ble_v2::GattClient {
absl::Mutex mutex_;
::winrt::Windows::Devices::Bluetooth::BluetoothLEDevice ble_device_;
::winrt::Windows::Devices::Bluetooth::BluetoothLEDevice ble_device_
ABSL_GUARDED_BY(mutex_);
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceServicesResult gatt_devices_services_result_ = nullptr;
GattDeviceServicesResult gatt_devices_services_result_
ABSL_GUARDED_BY(mutex_) = nullptr;
absl::flat_hash_map<api::ble_v2::GattCharacteristic, GattCharacteristicData>
native_characteristic_map_ ABSL_GUARDED_BY(mutex_);
@@ -15,6 +15,7 @@
#include "internal/platform/implementation/windows/ble_gatt_server.h"
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <exception>
#include <memory>
@@ -25,15 +26,21 @@
#include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/log/check.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_format.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "absl/types/optional.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/utils.h"
#include "internal/platform/logging.h"
#include "internal/platform/uuid.h"
#include "winrt/Windows.Foundation.Collections.h"
#include "winrt/Windows.Storage.Streams.h"
#include "winrt/base.h"
@@ -81,6 +88,9 @@ using ::winrt::Windows::Storage::Streams::DataWriter;
using Permission = api::ble_v2::GattCharacteristic::Permission;
using Property = api::ble_v2::GattCharacteristic::Property;
constexpr absl::Duration kGattServerTimeout = absl::Milliseconds(500);
constexpr int kGattServerCheckIntervalInMills = 50;
std::string ConvertGattStatusToString(
GattServiceProviderAdvertisementStatus status) {
switch (status) {
@@ -106,20 +116,22 @@ BleGattServer::BleGattServer(api::BluetoothAdapter* adapter,
api::ble_v2::ServerGattConnectionCallback callback)
: adapter_(dynamic_cast<BluetoothAdapter*>(adapter)),
peripheral_(adapter_->GetMacAddress()),
gatt_connection_callback_(std::move(callback)) {}
gatt_connection_callback_(std::move(callback)) {
DCHECK(adapter_ != nullptr);
}
absl::optional<api::ble_v2::GattCharacteristic>
BleGattServer::CreateCharacteristic(
const Uuid& service_uuid, const Uuid& characteristic_uuid,
api::ble_v2::GattCharacteristic::Permission permission,
api::ble_v2::GattCharacteristic::Property property) {
NEARBY_LOGS(VERBOSE) << __func__ << ": create characteristic, service_uuid: "
<< std::string(service_uuid) << ", characteristic_uuid: "
<< std::string(characteristic_uuid);
absl::MutexLock lock(&mutex_);
LOG(INFO) << __func__ << ": create characteristic, service_uuid: "
<< std::string(service_uuid)
<< ", characteristic_uuid: " << std::string(characteristic_uuid);
if (!service_uuid_.IsEmpty() && service_uuid_ != service_uuid) {
NEARBY_LOGS(ERROR) << __func__
<< ": Only support one GATT service for now.";
LOG(ERROR) << __func__ << ": Only support one GATT service for now.";
return absl::nullopt;
}
@@ -142,18 +154,18 @@ BleGattServer::CreateCharacteristic(
bool BleGattServer::UpdateCharacteristic(
const api::ble_v2::GattCharacteristic& characteristic,
const nearby::ByteArray& value) {
NEARBY_LOGS(VERBOSE) << __func__ << ": update characteristic: "
<< std::string(characteristic.uuid);
absl::MutexLock lock(&mutex_);
LOG(INFO) << __func__
<< ": update characteristic: " << std::string(characteristic.uuid);
if (characteristic.service_uuid != service_uuid_) {
NEARBY_LOGS(ERROR) << __func__ << ": Cannot found the GATT service.";
LOG(ERROR) << __func__ << ": Cannot found the GATT service.";
return false;
}
for (auto& it : gatt_characteristic_datas_) {
if (it.gatt_characteristic.uuid == characteristic.uuid) {
NEARBY_LOGS(VERBOSE) << __func__
<< ": Found the characteristic to update.";
VLOG(1) << __func__ << ": Found the characteristic to update.";
it.data = value;
// If it is in running, notify the value changed.
@@ -165,8 +177,7 @@ bool BleGattServer::UpdateCharacteristic(
is_indicate_characteristic = true;
}
NEARBY_LOGS(INFO) << __func__
<< ": Notify characteristic value updated.";
LOG(INFO) << __func__ << ": Notify characteristic value updated.";
if (is_indicate_characteristic) {
NotifyValueChanged(it.gatt_characteristic);
}
@@ -176,7 +187,7 @@ bool BleGattServer::UpdateCharacteristic(
}
}
NEARBY_LOGS(ERROR) << __func__ << ": Failed to update the characteristic.";
LOG(ERROR) << __func__ << ": Failed to update the characteristic.";
return false;
}
@@ -184,45 +195,75 @@ bool BleGattServer::UpdateCharacteristic(
absl::Status BleGattServer::NotifyCharacteristicChanged(
const api::ble_v2::GattCharacteristic& characteristic, bool confirm,
const ByteArray& new_value) {
absl::MutexLock lock(&mutex_);
// Currently, the method is not hooked up at platform layer.
NEARBY_LOGS(VERBOSE) << __func__ << ": Notify characteristic="
<< std::string(characteristic.uuid) << " changed.";
VLOG(1) << __func__
<< ": Notify characteristic=" << std::string(characteristic.uuid)
<< " changed.";
return absl::OkStatus();
}
void BleGattServer::Stop() {
NEARBY_LOGS(VERBOSE) << __func__ << ": Start to stop GATT server.";
try {
if (gatt_service_provider_ == nullptr) {
NEARBY_LOGS(WARNING) << __func__ << ": GATT server already stopped.";
return;
}
absl::AnyInvocable<void()> close_notifier = nullptr;
{
absl::MutexLock lock(&mutex_);
VLOG(1) << __func__ << ": Start to stop GATT server.";
if (gatt_service_provider_ != nullptr) {
try {
if (is_advertising_) {
gatt_service_provider_.StopAdvertising();
}
if (is_advertising_) {
gatt_service_provider_.StopAdvertising();
gatt_characteristic_datas_.clear();
service_uuid_ = Uuid();
gatt_service_provider_ = nullptr;
} catch (std::exception exception) {
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
} catch (const winrt::hresult_error& error) {
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
<< winrt::to_string(error.message());
} catch (...) {
LOG(ERROR) << __func__ << ": Unknown exception.";
}
} else {
LOG(WARNING) << __func__ << ": no GATT server is running.";
}
close_notifier = std::move(close_notifier_);
}
gatt_characteristic_datas_.clear();
service_uuid_ = Uuid();
gatt_service_provider_ = nullptr;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception: " << exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR) << __func__ << ": WinRT exception: " << error.code()
<< ": " << winrt::to_string(error.message());
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
if (close_notifier != nullptr) {
close_notifier();
}
}
bool BleGattServer::InitializeGattServer() {
try {
// Create and advertise GATT service.
NEARBY_LOGS(VERBOSE) << __func__ << ": Create GATT service service_uuid="
<< std::string(service_uuid_);
VLOG(1) << __func__ << ": Create GATT service service_uuid="
<< std::string(service_uuid_);
if (adapter_ == nullptr || !adapter_->IsEnabled()) {
NEARBY_LOGS(ERROR) << __func__ << ": Bluetooth adapter is disabled.";
if (adapter_ == nullptr) {
LOG(ERROR) << __func__ << ": Bluetooth adapter is absent.";
return false;
}
if (!adapter_->IsEnabled()) {
LOG(ERROR) << __func__ << ": Bluetooth adapter is disabled.";
return false;
}
if (!adapter_->IsLowEnergySupported()) {
LOG(ERROR) << __func__
<< ": Bluetooth adapter does not support BLE, which "
"is needed to start GATT server.";
return false;
}
if (!adapter_->IsPeripheralRoleSupported()) {
LOG(ERROR)
<< __func__
<< ": Bluetooth Hardware does not support Peripheral Role, which is "
"required to start GATT server.";
return false;
}
@@ -231,9 +272,8 @@ bool BleGattServer::InitializeGattServer() {
GattServiceProvider::CreateAsync(service_uuid).get();
if (service_provider_result.Error() != BluetoothError::Success) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to create GATT service. Error: "
<< static_cast<int>(service_provider_result.Error());
LOG(ERROR) << __func__ << ": Failed to create GATT service. Error: "
<< static_cast<int>(service_provider_result.Error());
return false;
}
@@ -242,7 +282,7 @@ bool BleGattServer::InitializeGattServer() {
service_provider_advertisement_changed_token_ =
gatt_service_provider_.AdvertisementStatusChanged(
{this, &BleGattServer::ServiceProvider_AdvertisementStatusChanged});
NEARBY_LOGS(INFO) << __func__ << ": GATT service created.";
LOG(INFO) << __func__ << ": GATT service created.";
// Create GATT characteristics.
for (auto& characteristic_data : gatt_characteristic_datas_) {
@@ -276,12 +316,11 @@ bool BleGattServer::InitializeGattServer() {
is_notify_supported = true;
}
NEARBY_LOGS(VERBOSE) << __func__
<< ": GATT characteristic properties: read="
<< is_read_supported
<< ",write=" << is_write_supported
<< ",indicate=" << is_indicate_supported
<< ",notify=" << is_notify_supported;
VLOG(1) << __func__
<< ": GATT characteristic properties: read=" << is_read_supported
<< ",write=" << is_write_supported
<< ",indicate=" << is_indicate_supported
<< ",notify=" << is_notify_supported;
gatt_characteristic_parameters.CharacteristicProperties(properties);
gatt_characteristic_parameters.WriteProtectionLevel(
@@ -290,10 +329,8 @@ bool BleGattServer::InitializeGattServer() {
winrt::guid characteristic_uuid = nearby_uuid_to_winrt_guid(
characteristic_data.gatt_characteristic.uuid);
NEARBY_LOGS(VERBOSE) << __func__
<< ": Create characteristic characteristic_uuid="
<< winrt::to_string(
winrt::to_hstring(characteristic_uuid));
VLOG(1) << __func__ << ": Create characteristic characteristic_uuid="
<< winrt::to_string(winrt::to_hstring(characteristic_uuid));
GattLocalCharacteristicResult result =
gatt_service_provider_.Service()
@@ -302,9 +339,9 @@ bool BleGattServer::InitializeGattServer() {
.get();
if (result.Error() != BluetoothError::Success) {
NEARBY_LOGS(ERROR) << __func__
<< ": Failed to create GATT characteristic. Error: "
<< static_cast<int>(result.Error());
LOG(ERROR) << __func__
<< ": Failed to create GATT characteristic. Error: "
<< static_cast<int>(result.Error());
return false;
}
@@ -312,9 +349,8 @@ bool BleGattServer::InitializeGattServer() {
::winrt::guid local_characteristic_guid =
characteristic_data.local_characteristic.Uuid();
NEARBY_LOGS(VERBOSE) << __func__ << ": Local GATT characteristic. uuid: "
<< winrt::to_string(
winrt::to_hstring(local_characteristic_guid));
VLOG(1) << __func__ << ": Local GATT characteristic. uuid: "
<< winrt::to_string(winrt::to_hstring(local_characteristic_guid));
// Setup gatt local characteristic events.
if (is_read_supported) {
@@ -339,15 +375,15 @@ bool BleGattServer::InitializeGattServer() {
is_gatt_server_inited_ = true;
NEARBY_LOGS(INFO) << __func__ << ": GATT service is initalized.";
LOG(INFO) << __func__ << ": GATT service is initalized.";
return true;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception: " << exception.what();
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR) << __func__ << ": WinRT exception: " << error.code()
<< ": " << winrt::to_string(error.message());
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
<< winrt::to_string(error.message());
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
LOG(ERROR) << __func__ << ": Unknown exception.";
}
// Clean up.
@@ -361,21 +397,31 @@ bool BleGattServer::InitializeGattServer() {
bool BleGattServer::StartAdvertisement(const ByteArray& service_data,
bool is_connectable) {
absl::MutexLock lock(&mutex_);
try {
NEARBY_LOGS(VERBOSE) << __func__ << ": service_data="
<< absl::BytesToHexString(service_data.AsStringView())
<< ", is_connectable=" << is_connectable;
VLOG(1) << __func__ << ": service_data="
<< absl::BytesToHexString(service_data.AsStringView())
<< ", is_connectable=" << is_connectable;
if (is_advertising_) {
NEARBY_LOGS(ERROR) << ": GATT server is already in advertising.";
LOG(ERROR) << ": GATT server is already in advertising.";
return false;
}
is_advertising_ = true;
if (!is_gatt_server_inited_ && !InitializeGattServer()) {
NEARBY_LOGS(ERROR) << ":Failed to initalize GATT service.";
is_advertising_ = false;
LOG(ERROR) << ":Failed to initalize GATT service.";
return false;
}
if (gatt_service_provider_ == nullptr) {
LOG(WARNING) << __func__ << ": no GATT server is running.";
return false;
}
if (gatt_service_provider_.AdvertisementStatus() ==
GattServiceProviderAdvertisementStatus::Started) {
LOG(WARNING) << __func__ << ": GATT server is already in advertising.";
return false;
}
@@ -392,69 +438,96 @@ bool BleGattServer::StartAdvertisement(const ByteArray& service_data,
advertisement_parameters.ServiceData(data_writer.DetachBuffer());
gatt_service_provider_.StartAdvertising(advertisement_parameters);
NEARBY_LOGS(INFO) << __func__ << ": GATT server started.";
// Wait for the advertising to start.
int wait_milliseconds = 0;
while (gatt_service_provider_.AdvertisementStatus() !=
GattServiceProviderAdvertisementStatus::Started) {
absl::SleepFor(absl::Milliseconds(kGattServerCheckIntervalInMills));
wait_milliseconds += kGattServerCheckIntervalInMills;
if (absl::Milliseconds(wait_milliseconds) > kGattServerTimeout) {
LOG(ERROR) << __func__
<< ": Failed to start GATT advertising due to timeout.";
return false;
}
}
is_advertising_ = true;
LOG(INFO) << __func__ << ": GATT server started.";
return true;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception: " << exception.what();
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR) << __func__ << ": WinRT exception: " << error.code()
<< ": " << winrt::to_string(error.message());
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
<< winrt::to_string(error.message());
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
LOG(ERROR) << __func__ << ": Unknown exception.";
}
is_advertising_ = false;
NEARBY_LOGS(ERROR) << __func__ << ": Failed to advertise GATT server.";
LOG(ERROR) << __func__ << ": Failed to advertise GATT server.";
return false;
}
bool BleGattServer::StopAdvertisement() {
absl::MutexLock lock(&mutex_);
try {
NEARBY_LOGS(INFO) << __func__ << ": stop advertisement.";
LOG(INFO) << __func__ << ": stop advertisement.";
if (!is_advertising_) {
NEARBY_LOGS(WARNING) << __func__ << ": no GATT advertisement.";
LOG(WARNING) << __func__ << ": no GATT advertisement.";
return true;
}
if (gatt_service_provider_ == nullptr) {
NEARBY_LOGS(WARNING) << __func__ << ": no GATT server is running.";
LOG(WARNING) << __func__ << ": no GATT server is running.";
is_advertising_ = false;
return true;
}
if (gatt_service_provider_.AdvertisementStatus() ==
GattServiceProviderAdvertisementStatus ::Stopped) {
NEARBY_LOGS(WARNING) << __func__ << ": no GATT advertisement is running.";
LOG(WARNING) << __func__ << ": no GATT advertisement is running.";
is_advertising_ = false;
return true;
}
gatt_service_provider_.StopAdvertising();
// Don't wait for the advertising to stop, because the advertisement status
// cannot back to stopped. Based on the observation, the advertisement
// status is stopped after the stop advertising is called.
is_advertising_ = false;
NEARBY_LOGS(INFO) << __func__ << ": GATT server stopped.";
LOG(INFO) << __func__ << ": GATT server stopped.";
return true;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception: " << exception.what();
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR) << __func__ << ": WinRT exception: " << error.code()
<< ": " << winrt::to_string(error.message());
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
<< winrt::to_string(error.message());
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
LOG(ERROR) << __func__ << ": Unknown exception.";
}
return false;
}
void BleGattServer::SetCloseNotifier(absl::AnyInvocable<void()> notifier) {
absl::MutexLock lock(&mutex_);
close_notifier_ = std::move(notifier);
}
::winrt::fire_and_forget BleGattServer::Characteristic_ReadRequestedAsync(
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattLocalCharacteristic const& gatt_local_characteristic,
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattReadRequestedEventArgs args) {
NEARBY_LOGS(VERBOSE) << __func__ << ": Read characteristic. uuid: "
<< winrt::to_string(winrt::to_hstring(
gatt_local_characteristic.Uuid()));
LOG(INFO) << __func__ << ": Read characteristic. uuid: "
<< winrt::to_string(
winrt::to_hstring(gatt_local_characteristic.Uuid()));
auto deferral = args.GetDeferral();
@@ -464,15 +537,15 @@ bool BleGattServer::StopAdvertisement() {
FindGattCharacteristicData(gatt_local_characteristic);
if (characteristic_data == nullptr) {
NEARBY_LOGS(ERROR) << __func__ << ": Failed to find characteristic="
<< ::winrt::to_string(::winrt::to_hstring(
gatt_local_characteristic.Uuid()));
LOG(ERROR) << __func__ << ": Failed to find characteristic="
<< ::winrt::to_string(
::winrt::to_hstring(gatt_local_characteristic.Uuid()));
return {};
}
GattReadRequest request = args.GetRequestAsync().get();
if (request == nullptr) {
NEARBY_LOGS(ERROR) << __func__ << ": Failed to get GATT read request.";
LOG(ERROR) << __func__ << ": Failed to get GATT read request.";
deferral.Complete();
return {};
}
@@ -485,20 +558,20 @@ bool BleGattServer::StopAdvertisement() {
request.RespondWithValue(buffer);
deferral.Complete();
NEARBY_LOGS(VERBOSE) << __func__ << ": Sent data to remote device.";
VLOG(1) << __func__ << ": Sent data to remote device.";
return {};
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception: " << exception.what();
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR) << __func__ << ": WinRT exception: " << error.code()
<< ": " << winrt::to_string(error.message());
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
<< winrt::to_string(error.message());
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
LOG(ERROR) << __func__ << ": Unknown exception.";
}
deferral.Complete();
NEARBY_LOGS(ERROR) << __func__ << ": Failed to send data to remote device.";
LOG(ERROR) << __func__ << ": Failed to send data to remote device.";
return {};
}
@@ -507,7 +580,7 @@ bool BleGattServer::StopAdvertisement() {
GattLocalCharacteristic const& gatt_local_characteristic,
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattWriteRequestedEventArgs args) {
// In Nearby Connctions, don't support write charaterisctics right now.
// In Nearby Connections, don't support write characteristics right now.
throw std::logic_error("Not implemented.");
}
@@ -515,10 +588,9 @@ void BleGattServer::Characteristic_SubscribedClientsChanged(
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattLocalCharacteristic const& gatt_local_characteristic,
::winrt::Windows::Foundation::IInspectable const& args) {
NEARBY_LOGS(VERBOSE) << __func__
<< ": Subscribed clients changed. characteristic="
<< ::winrt::to_string(::winrt::to_hstring(
gatt_local_characteristic.Uuid()));
LOG(INFO) << __func__ << ": Subscribed clients changed. characteristic="
<< ::winrt::to_string(
::winrt::to_hstring(gatt_local_characteristic.Uuid()));
try {
std::vector<api::ble_v2::GattCharacteristic>
@@ -530,9 +602,9 @@ void BleGattServer::Characteristic_SubscribedClientsChanged(
FindGattCharacteristicData(gatt_local_characteristic);
if (characteristic_data == nullptr) {
NEARBY_LOGS(ERROR) << __func__ << ": Failed to find characteristic="
<< ::winrt::to_string(::winrt::to_hstring(
gatt_local_characteristic.Uuid()));
LOG(ERROR) << __func__ << ": Failed to find characteristic="
<< ::winrt::to_string(
::winrt::to_hstring(gatt_local_characteristic.Uuid()));
return;
}
@@ -588,12 +660,12 @@ void BleGattServer::Characteristic_SubscribedClientsChanged(
subscribed_characteristic);
}
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception: " << exception.what();
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR) << __func__ << ": WinRT exception: " << error.code()
<< ": " << winrt::to_string(error.message());
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
<< winrt::to_string(error.message());
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
LOG(ERROR) << __func__ << ": Unknown exception.";
}
}
@@ -602,8 +674,9 @@ void BleGattServer::ServiceProvider_AdvertisementStatusChanged(
GattServiceProvider const& sender,
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattServiceProviderAdvertisementStatusChangedEventArgs const& args) {
NEARBY_LOGS(VERBOSE) << __func__ << ": Advertisement status changed. status="
<< ConvertGattStatusToString(args.Status());
LOG(INFO) << __func__ << ": Advertisement status changed. status="
<< ConvertGattStatusToString(args.Status())
<< ", error=" << static_cast<int>(args.Error());
}
void BleGattServer::NotifyValueChanged(
@@ -613,8 +686,8 @@ void BleGattServer::NotifyValueChanged(
FindGattCharacteristicData(gatt_characteristic);
if (characteristic_data == nullptr) {
NEARBY_LOGS(ERROR) << __func__ << ": Failed to find characteristic="
<< std::string(gatt_characteristic.uuid);
LOG(ERROR) << __func__ << ": Failed to find characteristic="
<< std::string(gatt_characteristic.uuid);
return;
}
@@ -634,19 +707,19 @@ void BleGattServer::NotifyValueChanged(
for (const auto& result : results) {
if (result.Status() != GattCommunicationStatus::Success) {
NEARBY_LOGS(ERROR)
<< __func__ << ": Failed to notify value change. remote device id="
<< ::winrt::to_string(
result.SubscribedClient().Session().DeviceId().Id());
LOG(ERROR) << __func__
<< ": Failed to notify value change. remote device id="
<< ::winrt::to_string(
result.SubscribedClient().Session().DeviceId().Id());
}
}
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception: " << exception.what();
LOG(ERROR) << __func__ << ": Exception: " << exception.what();
} catch (const winrt::hresult_error& error) {
NEARBY_LOGS(ERROR) << __func__ << ": WinRT exception: " << error.code()
<< ": " << winrt::to_string(error.message());
LOG(ERROR) << __func__ << ": WinRT exception: " << error.code() << ": "
<< winrt::to_string(error.message());
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
LOG(ERROR) << __func__ << ": Unknown exception.";
}
}
@@ -17,13 +17,20 @@
#include <windows.h>
#include <optional>
#include <memory>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/synchronization/notification.h"
#include "absl/types/optional.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/ble_v2_peripheral.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
#include "internal/platform/uuid.h"
@@ -37,26 +44,32 @@ namespace windows {
class BleGattServer : public api::ble_v2::GattServer {
public:
// Make sure the adapter parameter is not null.
BleGattServer(api::BluetoothAdapter* adapter,
api::ble_v2::ServerGattConnectionCallback callback);
~BleGattServer() override = default;
absl::optional<api::ble_v2::GattCharacteristic> CreateCharacteristic(
const Uuid& service_uuid, const Uuid& characteristic_uuid,
api::ble_v2::GattCharacteristic::Permission permission,
api::ble_v2::GattCharacteristic::Property property) override;
api::ble_v2::GattCharacteristic::Property property) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool UpdateCharacteristic(
const api::ble_v2::GattCharacteristic& characteristic,
const nearby::ByteArray& value) override;
const nearby::ByteArray& value) override ABSL_LOCKS_EXCLUDED(mutex_);
absl::Status NotifyCharacteristicChanged(
const api::ble_v2::GattCharacteristic& characteristic, bool confirm,
const ByteArray& new_value) override;
const ByteArray& new_value) override ABSL_LOCKS_EXCLUDED(mutex_);
void Stop() override;
void Stop() override ABSL_LOCKS_EXCLUDED(mutex_);
bool StartAdvertisement(const ByteArray& service_data, bool is_connectable);
bool StopAdvertisement();
bool StartAdvertisement(const ByteArray& service_data, bool is_connectable)
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopAdvertisement() ABSL_LOCKS_EXCLUDED(mutex_);
void SetCloseNotifier(absl::AnyInvocable<void()> notifier)
ABSL_LOCKS_EXCLUDED(mutex_);
api::ble_v2::BlePeripheral& GetBlePeripheral() override {
return peripheral_;
@@ -78,51 +91,65 @@ class BleGattServer : public api::ble_v2::GattServer {
::winrt::event_token subscribed_clients_changed_token{};
};
bool InitializeGattServer();
bool InitializeGattServer() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void NotifyValueChanged(
const api::ble_v2::GattCharacteristic& gatt_characteristic);
const api::ble_v2::GattCharacteristic& gatt_characteristic)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
GattCharacteristicData* FindGattCharacteristicData(
const ::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattLocalCharacteristic& gatt_local_characteristic);
GattLocalCharacteristic& gatt_local_characteristic)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
GattCharacteristicData* FindGattCharacteristicData(
const api::ble_v2::GattCharacteristic& gatt_characteristic);
const api::ble_v2::GattCharacteristic& gatt_characteristic)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
::winrt::fire_and_forget Characteristic_ReadRequestedAsync(
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattLocalCharacteristic const& gatt_local_characteristic,
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattReadRequestedEventArgs args);
GattReadRequestedEventArgs args)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
::winrt::fire_and_forget Characteristic_WriteRequestedAsync(
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattLocalCharacteristic const& gatt_local_characteristic,
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattWriteRequestedEventArgs args);
GattWriteRequestedEventArgs args)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void Characteristic_SubscribedClientsChanged(
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattLocalCharacteristic const& gatt_local_characteristic,
::winrt::Windows::Foundation::IInspectable const& args);
::winrt::Windows::Foundation::IInspectable const& args)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void ServiceProvider_AdvertisementStatusChanged(
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattServiceProvider const& sender,
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattServiceProviderAdvertisementStatusChangedEventArgs const& args);
GattServiceProviderAdvertisementStatusChangedEventArgs const& args)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
BluetoothAdapter* adapter_ = nullptr;
absl::Mutex mutex_;
BluetoothAdapter* const adapter_ = nullptr;
BleV2Peripheral peripheral_;
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattServiceProvider gatt_service_provider_ = nullptr;
Uuid service_uuid_;
std::vector<GattCharacteristicData> gatt_characteristic_datas_;
api::ble_v2::ServerGattConnectionCallback gatt_connection_callback_{};
::winrt::event_token service_provider_advertisement_changed_token_{};
bool is_advertising_ = false;
bool is_gatt_server_inited_ = false;
::winrt::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattServiceProvider gatt_service_provider_ ABSL_GUARDED_BY(mutex_) =
nullptr;
absl::AnyInvocable<void()> close_notifier_ ABSL_GUARDED_BY(mutex_) = nullptr;
Uuid service_uuid_ ABSL_GUARDED_BY(mutex_);
std::vector<GattCharacteristicData> gatt_characteristic_datas_
ABSL_GUARDED_BY(mutex_);
bool is_advertising_ ABSL_GUARDED_BY(mutex_) = false;
bool is_gatt_server_inited_ ABSL_GUARDED_BY(mutex_) = false;
::winrt::event_token service_provider_advertisement_changed_token_
ABSL_GUARDED_BY(mutex_) = {};
};
} // namespace windows
@@ -14,10 +14,13 @@
#include "internal/platform/implementation/windows/ble_gatt_server.h"
#include <functional>
#include <string>
#include <utility>
#include "gtest/gtest.h"
#include "absl/synchronization/notification.h"
#include "absl/time/time.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
@@ -44,6 +47,23 @@ TEST(BleV2GattServer, DISABLED_Stop) {
blev2_gatt_server.Stop();
}
TEST(BleV2GattServer, DISABLED_StopNotifierIsCalled) {
BluetoothAdapter bluetoothAdapter;
BleGattServer blev2_gatt_server(&bluetoothAdapter, {});
bool is_close_notifier_called = false;
absl::Notification notification;
std::function<void()> notifier = [&is_close_notifier_called,
&notification]() {
is_close_notifier_called = true;
notification.Notify();
};
blev2_gatt_server.SetCloseNotifier(std::move(notifier));
blev2_gatt_server.Stop();
notification.WaitForNotificationWithTimeout(absl::Seconds(1));
EXPECT_TRUE(is_close_notifier_called);
}
TEST(BleV2GattServer, DISABLED_CreateCharacteristic) {
BluetoothAdapter bluetoothAdapter;
BleGattServer blev2_gatt_server(&bluetoothAdapter, {});
@@ -15,6 +15,7 @@
#include "internal/platform/implementation/windows/ble_medium.h"
#include <chrono> // NOLINT
#include <cstdint>
#include <exception>
#include <future> // NOLINT
#include <list>
@@ -26,7 +27,9 @@
#include "absl/synchronization/mutex.h"
#include "absl/synchronization/notification.h"
#include "absl/time/time.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/feature_flags.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/implementation/windows/utils.h"
@@ -146,22 +149,20 @@ bool BleMedium::StartAdvertising(
const std::string& fast_advertisement_service_uuid) {
try {
if (!adapter_->IsEnabled()) {
NEARBY_LOGS(WARNING) << "BLE cannot start advertising because the "
"bluetooth adapter is not enabled.";
LOG(WARNING) << "BLE cannot start advertising because the "
"bluetooth adapter is not enabled.";
return false;
}
NEARBY_LOGS(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);
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_) {
NEARBY_LOGS(WARNING)
<< "BLE cannot start to advertise again when it is running.";
LOG(WARNING) << "BLE cannot start to advertise again when it is running.";
return false;
}
@@ -205,8 +206,8 @@ bool BleMedium::StartAdvertising(
publisher_.UseExtendedAdvertisement(false);
} else {
// otherwise no-op
NEARBY_LOGS(INFO) << "Everyone Mode unavailable for hardware that does "
"not support Extended Advertising.";
LOG(INFO) << "Everyone Mode unavailable for hardware that does "
"not support Extended Advertising.";
publisher_ = nullptr;
return false;
}
@@ -217,21 +218,21 @@ bool BleMedium::StartAdvertising(
publisher_.Start();
is_publisher_started_ = true;
NEARBY_LOGS(INFO) << "Windows Ble StartAdvertising started.";
LOG(INFO) << "Windows Ble StartAdvertising started.";
return true;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception to start BLE advertising: "
<< exception.what();
LOG(ERROR) << __func__
<< ": Exception to start BLE advertising: " << exception.what();
return false;
} catch (const winrt::hresult_error& ex) {
NEARBY_LOGS(ERROR) << __func__
<< ": Exception to start BLE advertising: " << ex.code()
<< ": " << winrt::to_string(ex.message());
LOG(ERROR) << __func__
<< ": Exception to start BLE advertising: " << ex.code() << ": "
<< winrt::to_string(ex.message());
return false;
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
LOG(ERROR) << __func__ << ": Unknown exception.";
return false;
}
}
@@ -239,16 +240,15 @@ bool BleMedium::StartAdvertising(
bool BleMedium::StopAdvertising(const std::string& service_id) {
try {
if (!adapter_->IsEnabled()) {
NEARBY_LOGS(WARNING) << "BLE cannot stop advertising because the "
"bluetooth adapter is not enabled.";
LOG(WARNING) << "BLE cannot stop advertising because the "
"bluetooth adapter is not enabled.";
return false;
}
NEARBY_LOGS(INFO) << "Windows Ble StopAdvertising: service_id="
<< service_id;
LOG(INFO) << "Windows Ble StopAdvertising: service_id=" << service_id;
if (!is_publisher_started_) {
NEARBY_LOGS(WARNING) << "BLE advertising is not running.";
LOG(WARNING) << "BLE advertising is not running.";
return false;
}
@@ -266,18 +266,18 @@ bool BleMedium::StopAdvertising(const std::string& service_id) {
return true;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception to stop BLE advertising: "
<< exception.what();
LOG(ERROR) << __func__
<< ": Exception to stop BLE advertising: " << exception.what();
return false;
} catch (const winrt::hresult_error& ex) {
NEARBY_LOGS(ERROR) << __func__
<< ": Exception to stop BLE advertising: " << ex.code()
<< ": " << winrt::to_string(ex.message());
LOG(ERROR) << __func__
<< ": Exception to stop BLE advertising: " << ex.code() << ": "
<< winrt::to_string(ex.message());
return false;
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
LOG(ERROR) << __func__ << ": Unknown exception.";
return false;
}
}
@@ -288,16 +288,15 @@ bool BleMedium::StartScanning(
DiscoveredPeripheralCallback callback) {
try {
if (!adapter_->IsEnabled()) {
NEARBY_LOGS(WARNING) << "BLE cannot start scanning because the "
"bluetooth adapter is not enabled.";
LOG(WARNING) << "BLE cannot start scanning because the "
"bluetooth adapter is not enabled.";
return false;
}
NEARBY_LOGS(INFO) << "Windows Ble StartScanning: service_id=" << service_id;
LOG(INFO) << "Windows Ble StartScanning: service_id=" << service_id;
if (is_watcher_started_) {
NEARBY_LOGS(WARNING)
<< "BLE cannot start to scan again when it is running.";
LOG(WARNING) << "BLE cannot start to scan again when it is running.";
return false;
}
@@ -327,21 +326,20 @@ bool BleMedium::StartScanning(
is_watcher_started_ = true;
NEARBY_LOGS(INFO) << "Windows Ble StartScanning started.";
LOG(INFO) << "Windows Ble StartScanning started.";
return true;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception to start BLE scanning: "
<< exception.what();
LOG(ERROR) << __func__
<< ": Exception to start BLE scanning: " << exception.what();
return false;
} catch (const winrt::hresult_error& ex) {
NEARBY_LOGS(ERROR) << __func__
<< ": Exception to start BLE scanning: " << ex.code()
<< ": " << winrt::to_string(ex.message());
LOG(ERROR) << __func__ << ": Exception to start BLE scanning: " << ex.code()
<< ": " << winrt::to_string(ex.message());
return false;
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
LOG(ERROR) << __func__ << ": Unknown exception.";
return false;
}
}
@@ -349,15 +347,15 @@ bool BleMedium::StartScanning(
bool BleMedium::StopScanning(const std::string& service_id) {
try {
if (!adapter_->IsEnabled()) {
NEARBY_LOGS(WARNING) << "BLE cannot stop scanning because the "
"bluetooth adapter is not enabled.";
LOG(WARNING) << "BLE cannot stop scanning because the "
"bluetooth adapter is not enabled.";
return false;
}
NEARBY_LOGS(INFO) << "Windows Ble StopScanning: service_id=" << service_id;
LOG(INFO) << "Windows Ble StopScanning: service_id=" << service_id;
if (!is_watcher_started_) {
NEARBY_LOGS(WARNING) << "BLE scanning is not running.";
LOG(WARNING) << "BLE scanning is not running.";
return false;
}
@@ -368,37 +366,35 @@ bool BleMedium::StopScanning(const std::string& service_id) {
// stopping to finish.
is_watcher_started_ = false;
NEARBY_LOGS(ERROR)
<< "Windows Ble stoped scanning successfully for service_id="
<< service_id;
LOG(ERROR) << "Windows Ble stoped scanning successfully for service_id="
<< service_id;
return true;
} catch (std::exception exception) {
NEARBY_LOGS(ERROR) << __func__ << ": Exception to stop BLE scanning: "
<< exception.what();
LOG(ERROR) << __func__
<< ": Exception to stop BLE scanning: " << exception.what();
return false;
} catch (const winrt::hresult_error& ex) {
NEARBY_LOGS(ERROR) << __func__
<< ": Exception to stop BLE scanning: " << ex.code()
<< ": " << winrt::to_string(ex.message());
LOG(ERROR) << __func__ << ": Exception to stop BLE scanning: " << ex.code()
<< ": " << winrt::to_string(ex.message());
return false;
} catch (...) {
NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception.";
LOG(ERROR) << __func__ << ": Unknown exception.";
return false;
}
}
bool BleMedium::StartAcceptingConnections(const std::string& service_id,
AcceptedConnectionCallback callback) {
NEARBY_LOGS(INFO) << "Windows Ble StartAcceptingConnections: service_id="
<< service_id;
LOG(INFO) << "Windows Ble StartAcceptingConnections: service_id="
<< service_id;
return true;
}
bool BleMedium::StopAcceptingConnections(const std::string& service_id) {
NEARBY_LOGS(INFO) << "Windows Ble StopAcceptingConnections: service_id="
<< service_id;
LOG(INFO) << "Windows Ble StopAcceptingConnections: service_id="
<< service_id;
return true;
}
@@ -406,15 +402,15 @@ std::unique_ptr<api::BleSocket> BleMedium::Connect(
api::BlePeripheral& remote_peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag) {
if (cancellation_flag->Cancelled()) {
NEARBY_LOGS(ERROR) << "Windows BLE Connect: Has been cancelled: "
"service_id="
<< service_id;
LOG(ERROR) << "Windows BLE Connect: Has been cancelled: "
"service_id="
<< service_id;
return {};
}
NEARBY_LOGS(ERROR) << "Windows Ble Connect: Cannot connect over BLE socket. "
"service_id="
<< service_id;
LOG(ERROR) << "Windows Ble Connect: Cannot connect over BLE socket. "
"service_id="
<< service_id;
return {};
}
@@ -424,75 +420,73 @@ void BleMedium::PublisherHandler(
// This method is called when publisher's status is changed.
switch (args.Status()) {
case BluetoothLEAdvertisementPublisherStatus::Created:
NEARBY_LOGS(INFO) << "Nearby BLE Medium created to advertise.";
LOG(INFO) << "Nearby BLE Medium created to advertise.";
return;
case BluetoothLEAdvertisementPublisherStatus::Started:
NEARBY_LOGS(INFO) << "Nearby BLE Medium started to advertise.";
LOG(INFO) << "Nearby BLE Medium started to advertise.";
return;
case BluetoothLEAdvertisementPublisherStatus::Stopping:
NEARBY_LOGS(INFO) << "Nearby BLE Medium is stopping.";
LOG(INFO) << "Nearby BLE Medium is stopping.";
return;
case BluetoothLEAdvertisementPublisherStatus::Waiting:
NEARBY_LOGS(INFO) << "Nearby BLE Medium is waiting.";
LOG(INFO) << "Nearby BLE Medium is waiting.";
return;
case BluetoothLEAdvertisementPublisherStatus::Stopped:
NEARBY_LOGS(INFO) << "Nearby BLE Medium stopped to advertise.";
LOG(INFO) << "Nearby BLE Medium stopped to advertise.";
break;
case BluetoothLEAdvertisementPublisherStatus::Aborted:
switch (args.Error()) {
case BluetoothError::Success:
if (publisher_.Status() ==
BluetoothLEAdvertisementPublisherStatus::Started) {
NEARBY_LOGS(ERROR)
<< "Nearby BLE Medium start advertising operation was "
"successfully completed or serviced.";
LOG(ERROR) << "Nearby BLE Medium start advertising operation was "
"successfully completed or serviced.";
}
if (publisher_.Status() ==
BluetoothLEAdvertisementPublisherStatus::Stopped) {
NEARBY_LOGS(ERROR)
<< "Nearby BLE Medium stop advertising operation was "
"successfully completed or serviced.";
LOG(ERROR) << "Nearby BLE Medium stop advertising operation was "
"successfully completed or serviced.";
} else {
NEARBY_LOGS(ERROR) << "Nearby BLE Medium advertising failed due to "
"unknown errors.";
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"unknown errors.";
}
break;
case BluetoothError::RadioNotAvailable:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium advertising failed due to "
"radio not available.";
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"radio not available.";
break;
case BluetoothError::ResourceInUse:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium advertising failed due to "
"resource in use.";
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"resource in use.";
break;
case BluetoothError::DeviceNotConnected:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium advertising failed due to "
"remote device is not connected.";
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"remote device is not connected.";
break;
case BluetoothError::DisabledByPolicy:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium advertising failed due to "
"disabled by policy.";
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"disabled by policy.";
break;
case BluetoothError::DisabledByUser:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium advertising failed due to "
"disabled by user.";
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"disabled by user.";
break;
case BluetoothError::NotSupported:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium advertising failed due to "
"hardware not supported.";
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"hardware not supported.";
break;
case BluetoothError::TransportNotSupported:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium advertising failed due to "
"transport not supported.";
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"transport not supported.";
break;
case BluetoothError::ConsentRequired:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium advertising failed due to "
"consent required.";
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"consent required.";
break;
case BluetoothError::OtherError:
default:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium advertising failed due to "
"unknown errors.";
LOG(ERROR) << "Nearby BLE Medium advertising failed due to "
"unknown errors.";
break;
}
break;
@@ -502,7 +496,7 @@ void BleMedium::PublisherHandler(
// The publisher is stopped. Clean up the running publisher
if (publisher_ != nullptr) {
NEARBY_LOGS(ERROR) << "Nearby BLE Medium cleaned the publisher.";
LOG(ERROR) << "Nearby BLE Medium cleaned the publisher.";
publisher_.StatusChanged(publisher_token_);
publisher_ = nullptr;
is_publisher_started_ = false;
@@ -516,47 +510,42 @@ void BleMedium::WatcherHandler(
// information on the reason.
switch (args.Error()) {
case BluetoothError::Success:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium stoped to scan successfully.";
LOG(ERROR) << "Nearby BLE Medium stoped to scan successfully.";
break;
case BluetoothError::RadioNotAvailable:
NEARBY_LOGS(ERROR)
LOG(ERROR)
<< "Nearby BLE Medium stoped to scan due to radio not available.";
break;
case BluetoothError::ResourceInUse:
NEARBY_LOGS(ERROR)
<< "Nearby BLE Medium stoped to scan due to resource in use.";
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to resource in use.";
break;
case BluetoothError::DeviceNotConnected:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium stoped to scan due to "
"remote device is not connected.";
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to "
"remote device is not connected.";
break;
case BluetoothError::DisabledByPolicy:
NEARBY_LOGS(ERROR)
LOG(ERROR)
<< "Nearby BLE Medium stoped to scan due to disabled by policy.";
break;
case BluetoothError::DisabledByUser:
NEARBY_LOGS(ERROR)
<< "Nearby BLE Medium stoped to scan due to disabled by user.";
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to disabled by user.";
break;
case BluetoothError::NotSupported:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium stoped to scan due to "
"hardware not supported.";
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to "
"hardware not supported.";
break;
case BluetoothError::TransportNotSupported:
NEARBY_LOGS(ERROR) << "Nearby BLE Medium stoped to scan due to "
"transport not supported.";
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to "
"transport not supported.";
break;
case BluetoothError::ConsentRequired:
NEARBY_LOGS(ERROR)
<< "Nearby BLE Medium stoped to scan due to consent required.";
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to consent required.";
break;
case BluetoothError::OtherError:
NEARBY_LOGS(ERROR)
<< "Nearby BLE Medium stoped to scan due to unknown errors.";
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to unknown errors.";
break;
default:
NEARBY_LOGS(ERROR)
<< "Nearby BLE Medium stoped to scan due to unknown errors.";
LOG(ERROR) << "Nearby BLE Medium stoped to scan due to unknown errors.";
break;
}
@@ -564,7 +553,7 @@ void BleMedium::WatcherHandler(
// The BLE V1 interface doesn't have an API to return the error to the upper
// layer.
if (watcher_ != nullptr) {
NEARBY_LOGS(ERROR) << "Nearby BLE Medium cleaned the watcher.";
LOG(ERROR) << "Nearby BLE Medium cleaned the watcher.";
watcher_.Stopped(watcher_token_);
watcher_.Received(advertisement_received_token_);
watcher_ = nullptr;
@@ -600,11 +589,10 @@ void BleMedium::AdvertisementReceivedHandler(
ByteArray advertisement_data(data);
NEARBY_LOGS(VERBOSE) << "Nearby BLE Medium Advertisement discovered. "
"0x16 Service data: advertisement bytes= 0x"
<< absl::BytesToHexString(
advertisement_data.AsStringView())
<< "(" << advertisement_data.size() << ")";
VLOG(1) << "Nearby BLE Medium Advertisement discovered. "
"0x16 Service data: advertisement bytes= 0x"
<< absl::BytesToHexString(advertisement_data.AsStringView())
<< "(" << advertisement_data.size() << ")";
std::string peripheral_name =
uint64_to_mac_address_string(args.BluetoothAddress());
@@ -616,7 +604,7 @@ void BleMedium::AdvertisementReceivedHandler(
if (peripheral_map_.contains(peripheral_name)) {
if (peripheral_map_[peripheral_name]->GetAdvertisementBytes(
service_id_) != advertisement_data) {
NEARBY_LOGS(INFO) << "BLE reports lost device: " << peripheral_name;
LOG(INFO) << "BLE reports lost device: " << peripheral_name;
// Lost the device first and then the report discovered the
// device.
@@ -644,15 +632,13 @@ void BleMedium::AdvertisementReceivedHandler(
// Received Fast Advertisement packet
if (unconsumed_buffer_length <= 27) {
NEARBY_LOGS(INFO)
<< "Sending Fast Advertisement packet for processing.";
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
NEARBY_LOGS(INFO)
<< "Sending Extended Advertising packet for processing.";
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);
@@ -15,7 +15,10 @@
#include "internal/platform/implementation/windows/ble_socket.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/ble.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 {
File diff suppressed because it is too large Load Diff
@@ -15,18 +15,24 @@
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_V2_H_
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_IMPLEMENTATION_WINDOWS_BLE_V2_H_
#include <algorithm>
#include <cstdint>
#include <memory>
#include <string>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "internal/platform/byte_array.h"
#include "absl/synchronization/notification.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/ble_gatt_server.h"
#include "internal/platform/implementation/windows/ble_v2_peripheral.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/bluetooth_classic.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
#include "internal/platform/uuid.h"
#include "winrt/Windows.Devices.Bluetooth.Advertisement.h"
@@ -42,51 +48,59 @@ class BleV2Medium : public api::ble_v2::BleMedium {
// Returns true once the Ble advertising has been initiated.
bool StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertising_parameters) override;
bool StopAdvertising() override;
api::ble_v2::AdvertiseParameters advertising_parameters) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopAdvertising() override ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<AdvertisingSession> StartAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertise_set_parameters,
AdvertisingCallback callback) override;
AdvertisingCallback callback) override ABSL_LOCKS_EXCLUDED(mutex_);
bool StartScanning(const Uuid& service_uuid,
api::ble_v2::TxPowerLevel tx_power_level,
ScanCallback callback) override;
bool StopScanning() override;
ScanCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StopScanning() override ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<ScanningSession> StartScanning(
const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level,
ScanningCallback callback) override;
std::unique_ptr<api::ble_v2::GattServer> StartGattServer(
api::ble_v2::ServerGattConnectionCallback callback) override;
api::ble_v2::ServerGattConnectionCallback callback) 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;
api::ble_v2::ClientGattConnectionCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
std::unique_ptr<api::ble_v2::BleServerSocket> OpenServerSocket(
const std::string& service_id) override;
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;
CancellationFlag* cancellation_flag) override ABSL_LOCKS_EXCLUDED(mutex_);
bool IsExtendedAdvertisementsAvailable() override;
bool GetRemotePeripheral(const std::string& mac_address,
GetRemotePeripheralCallback callback) override;
GetRemotePeripheralCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool GetRemotePeripheral(api::ble_v2::BlePeripheral::UniqueId id,
GetRemotePeripheralCallback callback) override;
GetRemotePeripheralCallback callback) override
ABSL_LOCKS_EXCLUDED(mutex_);
private:
bool StartBleAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertising_parameters);
bool StopBleAdvertising();
api::ble_v2::AdvertiseParameters advertising_parameters)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool StopBleAdvertising() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool StartGattAdvertising(
const api::ble_v2::BleAdvertisementData& advertising_data,
api::ble_v2::AdvertiseParameters advertising_parameters);
bool StopGattAdvertising();
api::ble_v2::AdvertiseParameters advertising_parameters)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
bool StopGattAdvertising() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void PublisherHandler(
winrt::Windows::Devices::Bluetooth::Advertisement::
@@ -111,50 +125,53 @@ class BleV2Medium : public api::ble_v2::BleMedium {
winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcherStoppedEventArgs args);
uint64_t GenerateSessionId();
uint64_t GenerateSessionId() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Returns nullptr if `address` is invalid.
BleV2Peripheral* GetOrCreatePeripheral(absl::string_view address);
BleV2Peripheral* GetOrCreatePeripheral(absl::string_view address)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Returns nullptr if `id` does not match a known peripheral.
BleV2Peripheral* GetPeripheral(BleV2Peripheral::UniqueId id);
BleV2Peripheral* GetPeripheral(BleV2Peripheral::UniqueId id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void RemoveExpiredPeripherals()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(peripheral_map_mutex_);
void RemoveExpiredPeripherals() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
BluetoothAdapter* adapter_;
absl::Mutex mutex_;
BluetoothAdapter* const adapter_;
Uuid service_uuid_;
api::ble_v2::TxPowerLevel tx_power_level_;
ScanCallback scan_callback_;
absl::Mutex map_mutex_;
// std::map<Uuid, std::map<uint64_t, ScanningCallback>>
absl::flat_hash_map<Uuid, absl::flat_hash_map<uint64_t, ScanningCallback>>
service_uuid_to_session_map_ ABSL_GUARDED_BY(map_mutex_);
service_uuid_to_session_map_ ABSL_GUARDED_BY(mutex_);
// WinRT objects
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementPublisher publisher_ = nullptr;
BluetoothLEAdvertisementPublisher publisher_ ABSL_GUARDED_BY(mutex_) =
nullptr;
::winrt::Windows::Devices::Bluetooth::Advertisement::
BluetoothLEAdvertisementWatcher watcher_ = nullptr;
BluetoothLEAdvertisementWatcher watcher_ ABSL_GUARDED_BY(mutex_) =
nullptr;
bool is_ble_publisher_started_ = false;
bool is_gatt_publisher_started_ = false;
bool is_watcher_started_ = false;
bool is_ble_publisher_started_ ABSL_GUARDED_BY(mutex_) = false;
bool is_gatt_publisher_started_ ABSL_GUARDED_BY(mutex_) = false;
bool is_watcher_started_ ABSL_GUARDED_BY(mutex_) = false;
::winrt::event_token publisher_token_;
::winrt::event_token watcher_token_;
::winrt::event_token advertisement_received_token_;
::winrt::event_token publisher_token_ ABSL_GUARDED_BY(mutex_);
::winrt::event_token watcher_token_ ABSL_GUARDED_BY(mutex_);
::winrt::event_token advertisement_received_token_ ABSL_GUARDED_BY(mutex_);
BleGattServer* ble_gatt_server_ = nullptr;
// Map to protect the pointer for BlePeripheral because
// DiscoveredPeripheralCallback only keeps the pointer to the object
absl::Mutex peripheral_map_mutex_;
struct PeripheralInfo {
absl::Time last_access_time;
std::unique_ptr<BleV2Peripheral> peripheral;
};
absl::flat_hash_map<BleV2Peripheral::UniqueId, PeripheralInfo> peripheral_map_
ABSL_GUARDED_BY(peripheral_map_mutex_);
absl::Time cleanup_time_ ABSL_GUARDED_BY(peripheral_map_mutex_) = absl::Now();
ABSL_GUARDED_BY(mutex_);
absl::Time cleanup_time_ ABSL_GUARDED_BY(mutex_) = absl::Now();
};
} // namespace windows
@@ -35,7 +35,7 @@ BleV2Peripheral::BleV2Peripheral(absl::string_view address) {
bool BleV2Peripheral::SetAddress(absl::string_view address) {
// The address must be in format "00:B0:D0:63:C2:26".
if (address.size() != kMacAddressLength) {
NEARBY_LOGS(ERROR) << ": Invalid MAC address length.";
LOG(ERROR) << ": Invalid MAC address length.";
return false;
}
@@ -52,7 +52,7 @@ bool BleV2Peripheral::SetAddress(absl::string_view address) {
}
}
NEARBY_LOGS(ERROR) << ": Invalid MAC address format.";
LOG(ERROR) << ": Invalid MAC address format.";
return false;
}

Some files were not shown because too many files have changed in this diff Show More