You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dvmhost/tests/p25/P25_DFSI_Tests.cpp

132 lines
4.3 KiB

// SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Test Suite
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2026 Bryan Biedenkapp, N2PLL
*
*/
#include "host/Defines.h"
#include "common/p25/P25Defines.h"
#include "common/p25/dfsi/DFSIDefines.h"
#include "common/p25/dfsi/frames/StartOfStream.h"
#include "common/p25/dfsi/frames/FullRateVoice.h"
#include <catch2/catch_test_macros.hpp>
#include <cstring>
using namespace p25;
using namespace p25::defines;
using namespace p25::dfsi;
using namespace p25::dfsi::defines;
using namespace p25::dfsi::frames;
TEST_CASE("DFSI StartOfStream and FullRateVoice encode/decode round-trips", "[p25][dfsi][frames]")
{
SECTION("StartOfStream preserves NID and low nibble error count") {
StartOfStream tx;
tx.setNID(0xA55AU);
tx.setErrorCount(0x1DU);
uint8_t buffer[StartOfStream::LENGTH] = { 0U };
tx.encode(buffer);
StartOfStream rx;
REQUIRE(rx.decode(buffer));
REQUIRE(rx.getNID() == 0xA55AU);
REQUIRE(rx.getErrorCount() == 0x0DU);
}
SECTION("FullRateVoice LDU1 voice3 includes four additional bytes") {
FullRateVoice tx;
tx.setFrameType(DFSIFrameType::LDU1_VOICE3);
tx.setTotalErrors(5U);
tx.setMuteFrame(true);
tx.setLostFrame(false);
tx.setSuperframeCnt(2U);
tx.setBusy(DFSI_BUSY_BITS_BUSY);
for (uint8_t i = 0U; i < FullRateVoice::IMBE_BUF_LEN; i++)
tx.imbeData[i] = (uint8_t)(0x20U + i);
tx.additionalData[0U] = 0x11U;
tx.additionalData[1U] = 0x22U;
tx.additionalData[2U] = 0x33U;
tx.additionalData[3U] = 0x44U;
uint8_t buffer[FullRateVoice::LENGTH] = { 0U };
tx.encode(buffer);
FullRateVoice rx;
REQUIRE(rx.decode(buffer));
REQUIRE(rx.getFrameType() == DFSIFrameType::LDU1_VOICE3);
REQUIRE(rx.getLength() == FullRateVoice::LENGTH);
REQUIRE(rx.getTotalErrors() == 5U);
REQUIRE(rx.getMuteFrame() == true);
REQUIRE(rx.getLostFrame() == false);
REQUIRE(rx.getSuperframeCnt() == 2U);
REQUIRE(rx.getBusy() == DFSI_BUSY_BITS_BUSY);
REQUIRE(::memcmp(rx.imbeData, tx.imbeData, FullRateVoice::IMBE_BUF_LEN) == 0);
REQUIRE(::memcmp(rx.additionalData, tx.additionalData, FullRateVoice::ADDITIONAL_LENGTH) == 0);
}
SECTION("FullRateVoice LDU1 voice9 uses three-byte additional payload") {
FullRateVoice tx;
tx.setFrameType(DFSIFrameType::LDU1_VOICE9);
tx.setTotalErrors(1U);
tx.setMuteFrame(false);
tx.setLostFrame(true);
tx.setSuperframeCnt(1U);
tx.setBusy(DFSI_BUSY_BITS_INBOUND);
for (uint8_t i = 0U; i < FullRateVoice::IMBE_BUF_LEN; i++)
tx.imbeData[i] = (uint8_t)(0x40U + i);
tx.additionalData[0U] = 0xAAU;
tx.additionalData[1U] = 0xBBU;
tx.additionalData[2U] = 0xCCU;
tx.additionalData[3U] = 0xDDU;
uint8_t buffer[FullRateVoice::LENGTH_918] = { 0U };
tx.encode(buffer);
FullRateVoice rx;
REQUIRE(rx.decode(buffer));
REQUIRE(rx.getFrameType() == DFSIFrameType::LDU1_VOICE9);
REQUIRE(rx.getLength() == FullRateVoice::LENGTH_918);
REQUIRE(rx.additionalData != nullptr);
REQUIRE(rx.additionalData[0U] == 0xAAU);
REQUIRE(rx.additionalData[1U] == 0xBBU);
REQUIRE(rx.additionalData[2U] == 0xCCU);
REQUIRE(rx.additionalData[3U] == 0x00U);
}
SECTION("FullRateVoice LDU1 voice2 has no additional payload") {
FullRateVoice tx;
tx.setFrameType(DFSIFrameType::LDU1_VOICE2);
tx.setTotalErrors(7U);
tx.setMuteFrame(false);
tx.setLostFrame(false);
tx.setSuperframeCnt(3U);
tx.setBusy(DFSI_BUSY_BITS_IDLE);
for (uint8_t i = 0U; i < FullRateVoice::IMBE_BUF_LEN; i++)
tx.imbeData[i] = (uint8_t)(0x60U + i);
uint8_t buffer[FullRateVoice::LENGTH_121011] = { 0U };
tx.encode(buffer);
FullRateVoice rx;
REQUIRE(rx.decode(buffer));
REQUIRE(rx.getFrameType() == DFSIFrameType::LDU1_VOICE2);
REQUIRE(rx.getLength() == FullRateVoice::LENGTH_121011);
REQUIRE(rx.additionalData == nullptr);
}
}

Powered by TurnKey Linux.