From 5871209f44b99d0fa1b26aa446584215904cb202 Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Fri, 9 Sep 2022 14:07:27 -0700 Subject: [PATCH] Convert from public to internal broadcast request Add conversion from public BroadcastRequest to internal BLE 4.2 broadcast request. PiperOrigin-RevId: 473338534 --- presence/broadcast_request.h | 4 +- presence/implementation/BUILD | 1 + .../implementation/base_broadcast_request.cc | 36 +++++++++++++++- .../implementation/base_broadcast_request.h | 11 +++++ .../base_broadcast_request_test.cc | 43 ++++++++++++++++++- 5 files changed, 91 insertions(+), 4 deletions(-) diff --git a/presence/broadcast_request.h b/presence/broadcast_request.h index 7dbb0487..02aa64e5 100644 --- a/presence/broadcast_request.h +++ b/presence/broadcast_request.h @@ -16,10 +16,10 @@ #define THIRD_PARTY_NEARBY_PRESENCE_BROADCAST_REQUEST_H_ #include -#include #include #include "absl/types/optional.h" +#include "absl/types/variant.h" #include "internal/proto/credential.pb.h" #include "presence/data_element.h" #include "presence/power_mode.h" @@ -67,7 +67,7 @@ struct BroadcastRequest { // The broadcast frequency hint. PowerMode power_mode; - std::variant variant; + absl::variant variant; }; } // namespace presence diff --git a/presence/implementation/BUILD b/presence/implementation/BUILD index 2b6b9ee3..8055c496 100644 --- a/presence/implementation/BUILD +++ b/presence/implementation/BUILD @@ -122,6 +122,7 @@ cc_test( deps = [ ":internal", "//internal/platform/implementation/g3", # build_cleaner: keep + "//presence:types", "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/types:variant", "@com_google_googletest//:gtest_main", diff --git a/presence/implementation/base_broadcast_request.cc b/presence/implementation/base_broadcast_request.cc index e0aa0a1d..9549e88f 100644 --- a/presence/implementation/base_broadcast_request.cc +++ b/presence/implementation/base_broadcast_request.cc @@ -15,9 +15,13 @@ #include "presence/implementation/base_broadcast_request.h" #include +#include +#include "absl/status/status.h" #include "absl/strings/string_view.h" #include "internal/platform/logging.h" +#include "presence/broadcast_request.h" +#include "presence/implementation/action_factory.h" #include "presence/implementation/encryption.h" namespace nearby { @@ -45,6 +49,12 @@ BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetAction( return *this; } +BasePresenceRequestBuilder& BasePresenceRequestBuilder::SetPowerMode( + PowerMode power_mode) { + power_mode_ = power_mode; + return *this; +} + BasePresenceRequestBuilder::operator BaseBroadcastRequest() const { BaseBroadcastRequest::BasePresence presence{.identity = identity_, .action = action_}; @@ -53,9 +63,33 @@ BasePresenceRequestBuilder::operator BaseBroadcastRequest() const { .salt = salt_.size() == kSaltSize ? salt_ : Encryption::GenerateRandomByteArray(kSaltSize), - .tx_power = tx_power_}; + .tx_power = tx_power_, + .power_mode = power_mode_}; return broadcast_request; } +absl::StatusOr BaseBroadcastRequest::Create( + const BroadcastRequest& request) { + if (absl::holds_alternative(request.variant)) { + const auto& presence_request = + absl::get(request.variant); + if (presence_request.sections.empty()) { + return absl::InvalidArgumentError("Missing broadcast sections"); + } + if (presence_request.sections.size() > 1) { + NEARBY_LOG(WARNING, + "Only first section is used in BLE 4.2 advertisement"); + } + const PresenceBroadcast::BroadcastSection& section = + presence_request.sections.front(); + return BaseBroadcastRequest( + BasePresenceRequestBuilder(section.identity) + .SetTxPower(request.tx_power) + .SetAction(ActionFactory::CreateAction(section.extended_properties)) + .SetPowerMode(request.power_mode)); + } + return absl::UnimplementedError("Request not supported"); +} + } // namespace presence } // namespace nearby diff --git a/presence/implementation/base_broadcast_request.h b/presence/implementation/base_broadcast_request.h index 42f4fc9e..b32b83d4 100644 --- a/presence/implementation/base_broadcast_request.h +++ b/presence/implementation/base_broadcast_request.h @@ -19,9 +19,12 @@ #include +#include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "absl/types/variant.h" #include "internal/proto/credential.pb.h" +#include "presence/broadcast_request.h" +#include "presence/power_mode.h" namespace nearby { namespace presence { @@ -35,6 +38,11 @@ struct Action { /** Defines a Nearby Presence broadcast request */ struct BaseBroadcastRequest { + // Creates `BaseBroadcastRequest` from the public API request in + // `BroadcastRequest`. + static absl::StatusOr Create( + const BroadcastRequest& request); + struct BasePresence { nearby::internal::IdentityType identity; Action action; @@ -56,6 +64,7 @@ struct BaseBroadcastRequest { std::string salt; int8_t tx_power; unsigned int interval_ms; + PowerMode power_mode; }; /** Builds a brodacast request variant with NP identity for BLE 4.2 */ @@ -67,6 +76,7 @@ class BasePresenceRequestBuilder { BasePresenceRequestBuilder& SetSalt(absl::string_view salt); BasePresenceRequestBuilder& SetTxPower(int8_t tx_power); BasePresenceRequestBuilder& SetAction(const Action& action); + BasePresenceRequestBuilder& SetPowerMode(PowerMode power_mode); explicit operator BaseBroadcastRequest() const; @@ -75,6 +85,7 @@ class BasePresenceRequestBuilder { std::string salt_; int8_t tx_power_ = kUnspecifiedTxPower; Action action_; + PowerMode power_mode_ = PowerMode::kNoPower; }; } // namespace presence diff --git a/presence/implementation/base_broadcast_request_test.cc b/presence/implementation/base_broadcast_request_test.cc index 6f4ebf12..a038463e 100644 --- a/presence/implementation/base_broadcast_request_test.cc +++ b/presence/implementation/base_broadcast_request_test.cc @@ -18,22 +18,63 @@ #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/types/variant.h" +#include "presence/broadcast_request.h" +#include "presence/data_element.h" namespace nearby { namespace presence { namespace { +using ::testing::status::StatusIs; + TEST(BroadcastRequestTest, CreateBasePresenceRequest) { nearby::internal::IdentityType identity; constexpr int8_t kTxPower = -13; BaseBroadcastRequest request = BaseBroadcastRequest( - BasePresenceRequestBuilder(identity).SetTxPower(kTxPower)); + BasePresenceRequestBuilder(identity).SetTxPower(kTxPower).SetPowerMode( + PowerMode::kBalanced)); EXPECT_TRUE(absl::holds_alternative( request.variant)); EXPECT_EQ(request.salt.size(), 2); EXPECT_EQ(request.tx_power, kTxPower); + EXPECT_EQ(request.power_mode, PowerMode::kBalanced); +} + +TEST(BroadcastRequestTest, CreateFromPresenceRequest) { + constexpr int8_t kTxPower = 30; + constexpr uint16_t kExpectedAction = 128; // encoded kActiveUnlockAction + PresenceBroadcast::BroadcastSection section = { + .identity = internal::IDENTITY_TYPE_PUBLIC, + .extended_properties = {DataElement(DataElement::kActionFieldType, + action::kActiveUnlockAction)}}; + PresenceBroadcast presence_request = {.sections = {section}}; + BroadcastRequest input = { + .tx_power = kTxPower, + .variant = presence_request, + }; + + absl::StatusOr request = + BaseBroadcastRequest::Create(input); + + ASSERT_OK(request); + EXPECT_THAT(request->tx_power, kTxPower); + EXPECT_THAT( + absl::get(request->variant).identity, + internal::IDENTITY_TYPE_PUBLIC); + EXPECT_THAT(absl::get(request->variant) + .action.action, + kExpectedAction); +} + +TEST(BroadcastRequestTest, CreateFromEmptyPresenceRequestFails) { + BroadcastRequest empty = { + .variant = PresenceBroadcast(), + }; + + EXPECT_THAT(BaseBroadcastRequest::Create(empty), + StatusIs(absl::StatusCode::kInvalidArgument)); } } // namespace