blob: 684a181ecb58670eb851d32959db968985c36415 [file]
/*
*
* Copyright (c) 2025 Project CHIP Authors
* All rights reserved.
*
* 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
*
* http://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.
*/
/**
* @file
* This file implements unit tests for the BLE transport re-initialization functionality.
*/
#include <pw_unit_test/framework.h>
#include <lib/core/CHIPCore.h>
#include <lib/support/CodeUtils.h>
#include <transport/raw/BLE.h>
#if CONFIG_NETWORK_LAYER_BLE
namespace chip {
namespace Transport {
namespace {
// Mock BLE layer for testing
class MockBleLayer : public Ble::BleLayer
{
public:
MockBleLayer() {}
};
// Test fixture for BLE re-initialization tests
class TestBLEReinitialization : public ::testing::Test
{
public:
static void SetUpTestSuite() {}
static void TearDownTestSuite() {}
protected:
void SetUp() override
{
mBleLayer = new MockBleLayer();
ASSERT_NE(mBleLayer, nullptr);
}
void TearDown() override
{
if (mBleLayer != nullptr)
{
delete mBleLayer;
mBleLayer = nullptr;
}
}
MockBleLayer * mBleLayer = nullptr;
};
// Test basic BLE initialization
TEST_F(TestBLEReinitialization, TestBasicInitialization)
{
BLE<1> bleTransport;
BleListenParameters params(mBleLayer);
CHIP_ERROR err = bleTransport.Init(params);
EXPECT_EQ(err, CHIP_NO_ERROR);
// Verify transport was set on the BLE layer
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport);
}
// Test re-initialization with PreserveExistingBleLayerTransport = false (default)
TEST_F(TestBLEReinitialization, TestReinitializationOverridesTransport)
{
BLE<1> bleTransport1;
BLE<1> bleTransport2;
// First initialization
BleListenParameters params1(mBleLayer);
CHIP_ERROR err = bleTransport1.Init(params1);
EXPECT_EQ(err, CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport1);
// Second initialization should override the transport
BleListenParameters params2(mBleLayer);
params2.SetPreserveExistingBleLayerTransport(false);
err = bleTransport2.Init(params2);
EXPECT_EQ(err, CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport2);
}
// Test re-initialization with PreserveExistingBleLayerTransport = true
TEST_F(TestBLEReinitialization, TestReinitializationPreservesTransport)
{
BLE<1> bleTransport1;
BLE<1> bleTransport2;
// First initialization
BleListenParameters params1(mBleLayer);
CHIP_ERROR err = bleTransport1.Init(params1);
EXPECT_EQ(err, CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport1);
// Second initialization with preserve flag should NOT override
BleListenParameters params2(mBleLayer);
params2.SetPreserveExistingBleLayerTransport(true);
err = bleTransport2.Init(params2);
EXPECT_EQ(err, CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport1); // Should still be first transport
}
// Test re-initialization when no existing transport
TEST_F(TestBLEReinitialization, TestReinitializationNoExistingTransport)
{
BLE<1> bleTransport;
// Initialize with preserve flag when no existing transport
BleListenParameters params(mBleLayer);
params.SetPreserveExistingBleLayerTransport(true);
CHIP_ERROR err = bleTransport.Init(params);
EXPECT_EQ(err, CHIP_NO_ERROR);
// Should set the transport even with preserve flag since there was none
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport);
}
// Test multiple re-initializations
TEST_F(TestBLEReinitialization, TestMultipleReinitializations)
{
BLE<1> bleTransport1;
BLE<1> bleTransport2;
BLE<1> bleTransport3;
// First initialization
BleListenParameters params1(mBleLayer);
EXPECT_EQ(bleTransport1.Init(params1), CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport1);
// Second initialization (override)
BleListenParameters params2(mBleLayer);
params2.SetPreserveExistingBleLayerTransport(false);
EXPECT_EQ(bleTransport2.Init(params2), CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport2);
// Third initialization (preserve)
BleListenParameters params3(mBleLayer);
params3.SetPreserveExistingBleLayerTransport(true);
EXPECT_EQ(bleTransport3.Init(params3), CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport2); // Should still be second
}
// Test initialization with null BLE layer
TEST_F(TestBLEReinitialization, TestInitializationWithNullBleLayer)
{
BLE<1> bleTransport;
BleListenParameters params(nullptr);
CHIP_ERROR err = bleTransport.Init(params);
EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
}
// Test re-initialization after close
TEST_F(TestBLEReinitialization, TestReinitializationAfterClose)
{
BLE<1> bleTransport;
// First initialization
BleListenParameters params1(mBleLayer);
EXPECT_EQ(bleTransport.Init(params1), CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport);
// Close the transport
bleTransport.Close();
EXPECT_EQ(mBleLayer->mBleTransport, nullptr);
// Re-initialize should work
BleListenParameters params2(mBleLayer);
EXPECT_EQ(bleTransport.Init(params2), CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport);
}
// Test double initialization without close (error case)
TEST_F(TestBLEReinitialization, TestDoubleInitializationSameTransport)
{
BLE<1> bleTransport;
// First initialization
BleListenParameters params1(mBleLayer);
EXPECT_EQ(bleTransport.Init(params1), CHIP_NO_ERROR);
// Second initialization of same transport should fail
BleListenParameters params2(mBleLayer);
CHIP_ERROR err = bleTransport.Init(params2);
EXPECT_EQ(err, CHIP_ERROR_INCORRECT_STATE);
}
// Test that ClearState is called on close
TEST_F(TestBLEReinitialization, TestClearStateOnClose)
{
BLE<1> bleTransport;
BleListenParameters params(mBleLayer);
EXPECT_EQ(bleTransport.Init(params), CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport);
bleTransport.Close();
// Verify transport was cleared
EXPECT_EQ(mBleLayer->mBleTransport, nullptr);
// Note: CancelBleIncompleteConnection is called internally but we can't easily
// track it without modifying the BleLayer implementation. The important thing
// is that the transport reference is cleared, which we verify above.
}
// Test preserve flag behavior with sequential initializations
TEST_F(TestBLEReinitialization, TestPreserveFlagSequence)
{
BLE<1> bleTransport1;
BLE<1> bleTransport2;
BLE<1> bleTransport3;
// Init 1: Set transport
BleListenParameters params1(mBleLayer);
EXPECT_EQ(bleTransport1.Init(params1), CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport1);
// Init 2: Preserve (should keep transport1)
BleListenParameters params2(mBleLayer);
params2.SetPreserveExistingBleLayerTransport(true);
EXPECT_EQ(bleTransport2.Init(params2), CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport1);
// Init 3: Override (should set transport3)
BleListenParameters params3(mBleLayer);
params3.SetPreserveExistingBleLayerTransport(false);
EXPECT_EQ(bleTransport3.Init(params3), CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport3);
}
// Test that state is properly managed across re-initializations
TEST_F(TestBLEReinitialization, TestStateManagement)
{
BLE<1> bleTransport1;
BLE<1> bleTransport2;
// First initialization
BleListenParameters params1(mBleLayer);
EXPECT_EQ(bleTransport1.Init(params1), CHIP_NO_ERROR);
// Close first transport
bleTransport1.Close();
// Second initialization should work independently
BleListenParameters params2(mBleLayer);
EXPECT_EQ(bleTransport2.Init(params2), CHIP_NO_ERROR);
EXPECT_EQ(mBleLayer->mBleTransport, &bleTransport2);
// Close second transport
bleTransport2.Close();
EXPECT_EQ(mBleLayer->mBleTransport, nullptr);
}
} // namespace
} // namespace Transport
} // namespace chip
#endif // CONFIG_NETWORK_LAYER_BLE