blob: 2d395746fc23c8b587eb739b508c6550f46014e9 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// clang-format off
#pragma GCC diagnostic push
#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
#include <Weave/DeviceLayer/internal/BLEManager.h>
#pragma GCC diagnostic pop
#include "src/connectivity/weave/adaptation/ble_manager_impl.h"
// clang-format on
#include <lib/sys/cpp/testing/component_context_provider.h>
#include <lib/syslog/cpp/macros.h>
#include <gtest/gtest.h>
#include "connectivity_manager_delegate_impl.h"
#include "fake_ble_peripheral.h"
#include "fake_gatt_server.h"
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
#include "test_configuration_manager.h"
#include "test_thread_stack_manager.h"
#include "weave_test_fixture.h"
namespace nl::Weave::DeviceLayer::Internal::testing {
namespace {
using nl::Weave::DeviceLayer::ConnectivityManager;
using nl::Weave::DeviceLayer::Internal::BLEManager;
using nl::Weave::DeviceLayer::Internal::BLEManagerImpl;
using weave::adaptation::testing::FakeBLEPeripheral;
using weave::adaptation::testing::FakeGATTService;
using weave::adaptation::testing::TestConfigurationManager;
using weave::adaptation::testing::TestThreadStackManager;
} // namespace
class BLEManagerTest : public WeaveTestFixture<> {
public:
BLEManagerTest() {
context_provider_.service_directory_provider()->AddService(
fake_gatt_server_.GetHandler(dispatcher()));
context_provider_.service_directory_provider()->AddService(
fake_ble_peripheral_.GetHandler(dispatcher()));
}
void SetUp() override {
WeaveTestFixture<>::SetUp();
WeaveTestFixture<>::RunFixtureLoop();
PlatformMgrImpl().SetComponentContextForProcess(context_provider_.TakeContext());
PlatformMgrImpl().SetDispatcher(event_loop_.dispatcher());
PlatformMgrImpl().GetSystemLayer().Init(nullptr);
ThreadStackMgrImpl().SetDelegate(std::make_unique<TestThreadStackManager>());
ConfigurationMgrImpl().SetDelegate(std::make_unique<TestConfigurationManager>());
ConnectivityMgrImpl().SetDelegate(std::make_unique<ConnectivityManagerDelegateImpl>());
EXPECT_EQ(ConfigurationMgrImpl().IsWoBLEEnabled(), true);
ble_mgr_ = std::make_unique<BLEManagerImpl>();
InitBleMgr();
}
void TearDown() override {
event_loop_.Quit();
WeaveTestFixture<>::StopFixtureLoop();
WeaveTestFixture<>::TearDown();
ThreadStackMgrImpl().SetDelegate(nullptr);
ConfigurationMgrImpl().SetDelegate(nullptr);
ConnectivityMgrImpl().SetDelegate(nullptr);
}
protected:
void InitBleMgr() {
EXPECT_EQ(ble_mgr_->_Init(), WEAVE_NO_ERROR);
event_loop_.RunUntilIdle();
EXPECT_EQ(GetBLEMgrServiceMode(), ConnectivityManager::kWoBLEServiceMode_Enabled);
if (ConfigurationMgrImpl().IsWoBLEAdvertisementEnabled()) {
EXPECT_EQ(IsBLEMgrAdvertising(), true);
} else {
EXPECT_EQ(IsBLEMgrAdvertising(), false);
}
}
BLEManager::WoBLEServiceMode GetBLEMgrServiceMode() { return ble_mgr_->_GetWoBLEServiceMode(); }
uint16_t IsBLEMgrAdvertising() { return ble_mgr_->_IsAdvertising(); }
WEAVE_ERROR GetBLEMgrDeviceName(char* device_name, size_t device_name_size) {
return ble_mgr_->_GetDeviceName(device_name, device_name_size);
}
WEAVE_ERROR SetBLEMgrDeviceName(const char* device_name) {
return ble_mgr_->_SetDeviceName(device_name);
}
void SetWoBLEAdvertising(bool enabled) {
EXPECT_EQ(ble_mgr_->_SetAdvertisingEnabled(enabled), WEAVE_NO_ERROR);
event_loop_.RunUntilIdle();
}
void WeaveConnect() {
size_t cb_count = 0;
auto callback = [&cb_count](fuchsia::bluetooth::gatt2::LocalService_WriteValue_Result res) {
FX_LOGS(INFO) << "Received gatt2 write request";
EXPECT_EQ(false, res.is_err());
cb_count++;
};
// Expect the write request to be received by the Weave stack, handled, and positively responded
// to.
fake_gatt_server_.WriteRequest(std::move(callback));
WeaveTestFixture<>::RunFixtureLoop();
event_loop_.Run(zx::time::infinite(), true /*once*/);
WeaveTestFixture<>::StopFixtureLoop();
RunLoopUntil([&]() { return cb_count; });
WeaveTestFixture<>::RunFixtureLoop();
// Expect the provided |callback| to receive the positive response.
EXPECT_EQ(cb_count, 1u);
FX_LOGS(INFO) << "Verified callback for write";
EXPECT_EQ(fake_gatt_server_.WeaveConnectionConfirmed(), false);
fake_gatt_server_.OnCharacteristicConfiguration();
// Event loop will be idle and waiting for subscribe request(characteristic configuration)
// on timer. So we need to wait until either subscribe request is received or timeout.
event_loop_.Run(zx::time::infinite(), true /*once*/);
WeaveTestFixture<>::RunLoopUntilIdle();
FX_LOGS(INFO) << "Ran event loop after CCC";
// Stop fixture loop before waiting for FakeGATTLocalService::NotifyValue
// on dispatcher().
WeaveTestFixture<>::StopFixtureLoop();
// Wait until FakeGATTLocalService::NotifyValue is called.
RunLoopUntil([&]() {
bool res = fake_gatt_server_.WeaveConnectionConfirmed();
return res;
});
// The FakeGattServer has received the notification.
WeaveTestFixture<>::RunFixtureLoop();
FX_LOGS(INFO) << "Got indication from weavestack";
bool is_confirmed = fake_gatt_server_.WeaveConnectionConfirmed();
EXPECT_EQ(is_confirmed, true);
}
private:
sys::testing::ComponentContextProvider context_provider_;
std::unique_ptr<BLEManagerImpl> ble_mgr_;
FakeGATTService fake_gatt_server_;
FakeBLEPeripheral fake_ble_peripheral_;
async::Loop event_loop_{&kAsyncLoopConfigNoAttachToCurrentThread};
};
TEST_F(BLEManagerTest, SetAndGetDeviceName) {
constexpr char kLargeDeviceName[] = "TOO_LARGE_DEVICE_NAME_FUCHSIA";
constexpr char kDeviceName[] = "FUCHSIATEST";
char read_value[kMaxDeviceNameLength + 1];
EXPECT_EQ(SetBLEMgrDeviceName(kLargeDeviceName), WEAVE_ERROR_INVALID_ARGUMENT);
EXPECT_EQ(SetBLEMgrDeviceName(kDeviceName), WEAVE_NO_ERROR);
EXPECT_EQ(GetBLEMgrDeviceName(read_value, 1), WEAVE_ERROR_BUFFER_TOO_SMALL);
EXPECT_EQ(GetBLEMgrDeviceName(read_value, sizeof(read_value)), WEAVE_NO_ERROR);
EXPECT_STREQ(kDeviceName, read_value);
}
TEST_F(BLEManagerTest, EnableAndDisableAdvertising) {
// Disable Weave service advertising
SetWoBLEAdvertising(false);
EXPECT_EQ(IsBLEMgrAdvertising(), false);
// Enable Weave service advertising
SetWoBLEAdvertising(true);
EXPECT_EQ(IsBLEMgrAdvertising(), true);
// Re-enable Weave service advertising
SetWoBLEAdvertising(true);
EXPECT_EQ(IsBLEMgrAdvertising(), true);
}
// TODO(https://fxbug.dev/42085753): Re-enable this test once the GATT Write / Indicate flakes are fixed.
TEST_F(BLEManagerTest, DISABLED_TestWeaveConnect) { WeaveConnect(); }
} // namespace nl::Weave::DeviceLayer::Internal::testing