blob: 46afd0207f302b66fafbc9e35ed38c89856a36f8 [file] [log] [blame]
/*
*
* Copyright (c) 2025 Project CHIP Authors
*
* 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.
*/
#include <cstdint>
#include <cstring>
#include <string>
#include <type_traits>
#include <utility>
#include <pw_unit_test/framework.h>
#include <lib/core/CHIPError.h>
#include <lib/core/StringBuilderAdapters.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/Span.h>
#include <lib/support/TypeTraits.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/CHIPDeviceLayer.h>
#include <system/SystemLayer.h>
#include <system/SystemPacketBuffer.h>
#include <wifipaf/WiFiPAFTP.h>
namespace chip {
namespace WiFiPAF {
class TestWiFiPAFTP : public WiFiPAFTP, public ::testing::Test
{
public:
static void SetUpTestSuite()
{
ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR);
ASSERT_EQ(DeviceLayer::SystemLayer().Init(), CHIP_NO_ERROR);
}
static void TearDownTestSuite()
{
DeviceLayer::SystemLayer().Shutdown();
chip::Platform::MemoryShutdown();
}
void SetUp() override { ASSERT_EQ(Init(nullptr, false), CHIP_NO_ERROR); }
void TearDown() override {}
};
TEST_F(TestWiFiPAFTP, CheckLogState)
{
LogState();
TakeTxPacket();
TakeRxPacket();
PacketBufferHandle AckToSend = System::PacketBufferHandle::New(kTransferProtocolStandaloneAckHeaderSize);
EXPECT_EQ(EncodeStandAloneAck(AckToSend), CHIP_NO_ERROR);
EXPECT_NE(GetAndIncrementNextTxSeqNum(), 0);
EXPECT_NE(GetAndRecordRxAckSeqNum(), 0);
HasUnackedData();
uint16_t FragSize = 300;
SetTxFragmentSize(FragSize);
SetRxFragmentSize(FragSize);
EXPECT_EQ(GetTxFragmentSize(), FragSize);
EXPECT_EQ(GetRxFragmentSize(), FragSize);
EXPECT_NE(GetRxNextSeqNum(), 0);
EXPECT_NE(GetLastReceivedSequenceNumber(), 0);
EXPECT_NE(GetNewestUnackedSentSequenceNumber(), 0);
EXPECT_EQ(ExpectingAck(), true);
ClearRxPacket();
ClearTxPacket();
}
TEST_F(TestWiFiPAFTP, CheckSendSingle)
{
constexpr size_t kShortPacketLength = 100;
auto buf = System::PacketBufferHandle::New(kShortPacketLength);
buf->SetDataLength(kShortPacketLength);
memset(buf->Start(), 0, buf->DataLength());
mRxNextSeqNum = 1;
EXPECT_TRUE(HandleCharacteristicSend(buf.Retain(), true));
EXPECT_EQ(TxState(), kState_Complete);
TakeTxPacket();
EXPECT_EQ(TxState(), kState_Idle);
}
TEST_F(TestWiFiPAFTP, CheckSendMultiple)
{
constexpr size_t kLongPacketLength = 500;
auto buf = System::PacketBufferHandle::New(kLongPacketLength);
ASSERT_FALSE(buf.IsNull());
buf->SetDataLength(kLongPacketLength);
memset(buf->Start(), 0, buf->DataLength());
EXPECT_TRUE(HandleCharacteristicSend(buf.Retain(), false));
EXPECT_EQ(TxState(), kState_InProgress);
EXPECT_TRUE(HandleCharacteristicSend(nullptr, false));
EXPECT_EQ(TxState(), kState_Complete);
TakeTxPacket();
EXPECT_EQ(TxState(), kState_Idle);
}
TEST_F(TestWiFiPAFTP, CheckRecv)
{
SequenceNumber_t receivedAck = 0;
bool didReceiveAck = false;
// Receive a packet
constexpr uint8_t packetData0[] = {
to_underlying(HeaderFlags::kStartMessage) | to_underlying(HeaderFlags::kEndMessage),
0x01,
0x01,
0x00,
0xff, // payload
};
auto packet0 = System::PacketBufferHandle::NewWithData(packetData0, sizeof(packetData0));
EXPECT_EQ(packet0->DataLength(), static_cast<size_t>(5));
receivedAck = 0;
didReceiveAck = false;
EXPECT_EQ(HandleCharacteristicReceived(std::move(packet0), receivedAck, didReceiveAck), CHIP_NO_ERROR);
EXPECT_EQ(RxState(), kState_Complete);
TakeRxPacket();
EXPECT_EQ(RxState(), kState_Idle);
}
TEST_F(TestWiFiPAFTP, CheckAckRecv)
{
constexpr uint8_t packetData0[] = {
to_underlying(HeaderFlags::kStartMessage) | to_underlying(HeaderFlags::kEndMessage) |
to_underlying(HeaderFlags::kFragmentAck),
0x01,
0x01,
0x00,
0x00, // payload
};
auto packet0 = System::PacketBufferHandle::NewWithData(packetData0, sizeof(packetData0));
EXPECT_EQ(packet0->DataLength(), static_cast<size_t>(5));
SequenceNumber_t receivedAck = 0;
bool didReceiveAck = true;
mExpectingAck = true;
EXPECT_EQ(HandleCharacteristicReceived(std::move(packet0), receivedAck, didReceiveAck), CHIP_NO_ERROR);
EXPECT_EQ(RxState(), kState_Idle);
}
TEST_F(TestWiFiPAFTP, CheckErrorRecv)
{
SequenceNumber_t receivedAck = 0;
bool didReceiveAck = false;
// Null-buffer
auto nullbuf = System::PacketBufferHandle::New(0);
EXPECT_NE(HandleCharacteristicReceived(std::move(nullbuf), receivedAck, didReceiveAck), CHIP_NO_ERROR);
// Reveived Invalid packet
constexpr uint8_t packetData_invalid_ack[] = {
to_underlying(HeaderFlags::kFragmentAck) | to_underlying(HeaderFlags::kEndMessage),
0xf0,
0x01,
0x00,
0xff, // payload
};
auto packet_invalid_ack = System::PacketBufferHandle::NewWithData(packetData_invalid_ack, sizeof(packetData_invalid_ack));
EXPECT_EQ(HandleCharacteristicReceived(std::move(packet_invalid_ack), receivedAck, didReceiveAck), CHIP_NO_ERROR);
}
}; // namespace WiFiPAF
}; // namespace chip