Files
nearby/fastpair/message_stream/medium_test.cc
T
Janusz Sobczak 02ffb5d45e Add Message Stream
Define MessageStream class for exchanging messages betweek the seeker and the
provider over rfcomm.

PiperOrigin-RevId: 516986541
2023-03-15 18:42:39 -07:00

191 lines
7.0 KiB
C++

// Copyright 2023 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 "fastpair/message_stream/medium.h"
#include <deque>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/status/status.h"
#include "absl/strings/escaping.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "fastpair/common/constant.h"
#include "fastpair/common/fast_pair_device.h"
#include "fastpair/message_stream/fake_medium_observer.h"
#include "fastpair/message_stream/fake_provider.h"
#include "fastpair/message_stream/message.h"
#include "internal/platform/bluetooth_classic.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/logging.h"
#include "internal/platform/medium_environment.h"
#include "internal/platform/single_thread_executor.h"
namespace nearby {
namespace fastpair {
namespace {
using ::testing::status::StatusIs;
class MediumEnvironmentStarter {
public:
MediumEnvironmentStarter() { MediumEnvironment::Instance().Start(); }
~MediumEnvironmentStarter() { MediumEnvironment::Instance().Stop(); }
};
class MediumTest : public testing::Test {
protected:
void SetUp() override { MediumEnvironment::Instance().Start(); }
void TearDown() override {
provider_.Shutdown();
MediumEnvironment::Instance().Stop();
}
// The medium environment must be initialized (started) before adding
// adapters.
MediumEnvironmentStarter env_;
BluetoothAdapter seeker_adapter_;
BluetoothClassicMedium seeker_medium_{seeker_adapter_};
FakeProvider provider_;
FakeMediumObserver observer_;
};
TEST_F(MediumTest, ConnectWithNonExistingDeviceFails) {
FastPairDevice fp_device("model id", "ble address",
Protocol::kFastPairRetroactivePairing);
fp_device.set_public_address("11:22:33:44:55:66");
Medium medium =
Medium(fp_device, std::optional<BluetoothClassicMedium*>(&seeker_medium_),
observer_);
ASSERT_OK(medium.OpenRfcomm());
ASSERT_TRUE(observer_.connection_result_.Get().ok());
EXPECT_THAT(observer_.connection_result_.Get().GetResult(),
StatusIs(absl::StatusCode::kUnavailable));
}
TEST_F(MediumTest, Connect) {
FastPairDevice fp_device("model id", "ble address",
Protocol::kFastPairRetroactivePairing);
fp_device.set_public_address(provider_.GetMacAddress());
provider_.DiscoverProvider(seeker_medium_);
provider_.EnableProviderRfcomm();
Medium medium =
Medium(fp_device, std::optional<BluetoothClassicMedium*>(&seeker_medium_),
observer_);
ASSERT_OK(medium.OpenRfcomm());
ASSERT_TRUE(observer_.connection_result_.Get().ok());
EXPECT_OK(observer_.connection_result_.Get().GetResult());
}
TEST_F(MediumTest, ProviderDisconnectsCallsOnDisconnectCallback) {
FastPairDevice fp_device("model id", "ble address",
Protocol::kFastPairRetroactivePairing);
fp_device.set_public_address(provider_.GetMacAddress());
provider_.DiscoverProvider(seeker_medium_);
provider_.EnableProviderRfcomm();
Medium medium =
Medium(fp_device, std::optional<BluetoothClassicMedium*>(&seeker_medium_),
observer_);
ASSERT_OK(medium.OpenRfcomm());
ASSERT_TRUE(observer_.connection_result_.Get().ok());
provider_.DisableProviderRfcomm();
ASSERT_TRUE(observer_.disconnected_reason_.Get().ok());
EXPECT_THAT(observer_.disconnected_reason_.Get().GetResult(),
StatusIs(absl::StatusCode::kDataLoss));
}
TEST_F(MediumTest, DisconnectSendFails) {
FastPairDevice fp_device("model id", "ble address",
Protocol::kFastPairRetroactivePairing);
fp_device.set_public_address(provider_.GetMacAddress());
provider_.DiscoverProvider(seeker_medium_);
provider_.EnableProviderRfcomm();
Medium medium =
Medium(fp_device, std::optional<BluetoothClassicMedium*>(&seeker_medium_),
observer_);
ASSERT_OK(medium.OpenRfcomm());
ASSERT_TRUE(observer_.connection_result_.Get().ok());
ASSERT_OK(medium.Disconnect());
// Medium is disconnected, Send should fail
EXPECT_THAT(medium.Send(Message{}, false),
StatusIs(absl::StatusCode::kFailedPrecondition));
}
TEST_F(MediumTest, SendMessage) {
Message message = {.message_group = MessageGroup::kDeviceInformationEvent,
.message_code = MessageCode::kSessionNonce,
.payload = absl::HexStringToBytes("ABCDEF")};
// See the format definition in
// https://developers.google.com/nearby/fast-pair/specifications/extensions/messagestreamhttps://developers.google.com/nearby/fast-pair/specifications/extensions/messagestream
std::string expected_result = absl::HexStringToBytes("030A0003ABCDEF");
FastPairDevice fp_device("model id", "ble address",
Protocol::kFastPairRetroactivePairing);
fp_device.set_public_address(provider_.GetMacAddress());
provider_.DiscoverProvider(seeker_medium_);
provider_.EnableProviderRfcomm();
Medium medium =
Medium(fp_device, std::optional<BluetoothClassicMedium*>(&seeker_medium_),
observer_);
ASSERT_OK(medium.OpenRfcomm());
ASSERT_TRUE(observer_.connection_result_.Get().ok());
EXPECT_OK(medium.Send(message, false));
Future<std::string> result =
provider_.ReadProviderBytes(expected_result.size());
ASSERT_TRUE(result.Get().ok());
EXPECT_EQ(result.Get().GetResult(), expected_result);
}
TEST_F(MediumTest, ReceiveMessage) {
Message expected_message = {
.message_group = MessageGroup::kDeviceInformationEvent,
.message_code = MessageCode::kSessionNonce,
.payload = absl::HexStringToBytes("ABCDEF")};
std::string input = absl::HexStringToBytes("030A0003ABCDEF");
FastPairDevice fp_device("model id", "ble address",
Protocol::kFastPairRetroactivePairing);
fp_device.set_public_address(provider_.GetMacAddress());
provider_.DiscoverProvider(seeker_medium_);
provider_.EnableProviderRfcomm();
Medium medium =
Medium(fp_device, std::optional<BluetoothClassicMedium*>(&seeker_medium_),
observer_);
ASSERT_OK(medium.OpenRfcomm());
ASSERT_TRUE(observer_.connection_result_.Get().ok());
provider_.WriteProviderBytes(input);
ASSERT_OK(observer_.WaitForMessages(1, absl::Seconds(10)));
std::vector<Message> messages = observer_.GetMessages();
ASSERT_EQ(messages.size(), 1);
EXPECT_EQ(messages[0], expected_message);
}
} // namespace
} // namespace fastpair
} // namespace nearby