implement Reed-Soloman tests as actual P25 test cases using Catch2;

3.0-rcon_maint 2023-03-16
Bryan Biedenkapp 3 years ago
parent 16dc1ac374
commit 095611d573

@ -130,6 +130,8 @@ file(GLOB dvmcmd_SRC
# dvmtest source/header files # dvmtest source/header files
file(GLOB dvmtests_SRC file(GLOB dvmtests_SRC
"tests/nulltest.cpp" "tests/nulltest.cpp"
"tests/p25/lc/*.cpp"
) )
# digital mode options # digital mode options
@ -360,7 +362,8 @@ FetchContent_Declare(
FetchContent_MakeAvailable(Catch2) FetchContent_MakeAvailable(Catch2)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
add_executable(dvmtests ${dvmtests_SRC}) add_executable(dvmtests ${dvmhost_SRC} ${dvmtests_SRC})
target_compile_definitions(dvmtests PUBLIC -DCATCH2_TEST_COMPILATION)
target_link_libraries(dvmtests PRIVATE Catch2::Catch2WithMain Threads::Threads util) target_link_libraries(dvmtests PRIVATE Catch2::Catch2WithMain Threads::Threads util)
target_include_directories(dvmtests PRIVATE .) target_include_directories(dvmtests PRIVATE .)
endif (ENABLE_TESTS) endif (ENABLE_TESTS)

@ -105,7 +105,7 @@ uint8_t* g_gitHashBytes = nullptr;
// Global Functions // Global Functions
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#if !defined(_WIN32) && !defined(_WIN64) #if !defined(_WIN32) && !defined(_WIN64) && !defined(CATCH2_TEST_COMPILATION)
static void sigHandler(int signum) static void sigHandler(int signum)
{ {
g_killed = true; g_killed = true;
@ -245,7 +245,7 @@ int checkArgs(int argc, char* argv[])
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Program Entry Point // Program Entry Point
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#if !defined(CATCH2_TEST_COMPILATION)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
g_gitHashBytes = new uint8_t[4U]; g_gitHashBytes = new uint8_t[4U];
@ -314,3 +314,4 @@ int main(int argc, char** argv)
return ret; return ret;
} }
#endif

@ -38,6 +38,10 @@
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#if defined(CATCH2_TEST_COMPILATION)
#include <catch2/catch_test_macros.hpp>
#endif
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstdarg> #include <cstdarg>
@ -91,6 +95,9 @@ static char LEVELS[] = " DMIWEF";
/// <returns>True, if log file is opened, otherwise false. /// <returns>True, if log file is opened, otherwise false.
static bool LogOpen() static bool LogOpen()
{ {
#if defined(CATCH2_TEST_COMPILATION)
return true;
#endif
if (m_fileLevel == 0U) if (m_fileLevel == 0U)
return true; return true;
@ -158,6 +165,9 @@ static bool ActivityLogOpen()
/// <param name="network">Instance of the Network class.</param> /// <param name="network">Instance of the Network class.</param>
void LogSetNetwork(void* network) void LogSetNetwork(void* network)
{ {
#if defined(CATCH2_TEST_COMPILATION)
return;
#endif
// note: The Network class is passed here as a void so we can avoid including the Network.h // note: The Network class is passed here as a void so we can avoid including the Network.h
// header in Log.h. This is dirty and probably terrible... // header in Log.h. This is dirty and probably terrible...
m_network = (network::Network*)network; m_network = (network::Network*)network;
@ -170,6 +180,9 @@ void LogSetNetwork(void* network)
/// <param name="fileRoot">Prefix of the activity log file name.</param> /// <param name="fileRoot">Prefix of the activity log file name.</param>
bool ActivityLogInitialise(const std::string& filePath, const std::string& fileRoot) bool ActivityLogInitialise(const std::string& filePath, const std::string& fileRoot)
{ {
#if defined(CATCH2_TEST_COMPILATION)
return true;
#endif
m_actFilePath = filePath; m_actFilePath = filePath;
m_actFileRoot = fileRoot; m_actFileRoot = fileRoot;
m_network = nullptr; m_network = nullptr;
@ -182,6 +195,9 @@ bool ActivityLogInitialise(const std::string& filePath, const std::string& fileR
/// </summary> /// </summary>
void ActivityLogFinalise() void ActivityLogFinalise()
{ {
#if defined(CATCH2_TEST_COMPILATION)
return;
#endif
if (m_actFpLog != nullptr) if (m_actFpLog != nullptr)
::fclose(m_actFpLog); ::fclose(m_actFpLog);
} }
@ -194,6 +210,9 @@ void ActivityLogFinalise()
/// <param name="msg">Formatted string to write to activity log.</param> /// <param name="msg">Formatted string to write to activity log.</param>
void ActivityLog(const char *mode, const bool sourceRf, const char* msg, ...) void ActivityLog(const char *mode, const bool sourceRf, const char* msg, ...)
{ {
#if defined(CATCH2_TEST_COMPILATION)
return;
#endif
assert(mode != nullptr); assert(mode != nullptr);
assert(msg != nullptr); assert(msg != nullptr);
@ -268,6 +287,9 @@ bool LogInitialise(const std::string& filePath, const std::string& fileRoot, uin
/// </summary> /// </summary>
void LogFinalise() void LogFinalise()
{ {
#if defined(CATCH2_TEST_COMPILATION)
return;
#endif
if (m_fpLog != nullptr) if (m_fpLog != nullptr)
::fclose(m_fpLog); ::fclose(m_fpLog);
} }
@ -281,7 +303,9 @@ void LogFinalise()
void Log(uint32_t level, const char *module, const char* fmt, ...) void Log(uint32_t level, const char *module, const char* fmt, ...)
{ {
assert(fmt != nullptr); assert(fmt != nullptr);
#if defined(CATCH2_TEST_COMPILATION)
m_disableTimeDisplay = true;
#endif
char buffer[LOG_BUFFER_LEN]; char buffer[LOG_BUFFER_LEN];
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
if (!m_disableTimeDisplay) { if (!m_disableTimeDisplay) {
@ -341,6 +365,11 @@ void Log(uint32_t level, const char *module, const char* fmt, ...)
} }
} }
#if defined(CATCH2_TEST_COMPILATION)
UNSCOPED_INFO(buffer);
return;
#endif
if (level >= m_fileLevel && m_fileLevel != 0U) { if (level >= m_fileLevel && m_fileLevel != 0U) {
bool ret = ::LogOpen(); bool ret = ::LogOpen();
if (!ret) if (!ret)

@ -96,7 +96,7 @@ void Utils::dump(int level, const std::string& title, const uint8_t* data, uint3
::sprintf(temp, "%02X ", data[offset + i]); ::sprintf(temp, "%02X ", data[offset + i]);
output += temp; output += temp;
} }
#if !defined(CATCH2_TEST_COMPILATION)
for (uint32_t i = bytes; i < 16U; i++) for (uint32_t i = bytes; i < 16U; i++)
output += " "; output += " ";
@ -112,7 +112,7 @@ void Utils::dump(int level, const std::string& title, const uint8_t* data, uint3
} }
output += '*'; output += '*';
#endif
::Log(level, "DUMP", "%04X: %s", offset, output.c_str()); ::Log(level, "DUMP", "%04X: %s", offset, output.c_str());
offset += 16U; offset += 16U;

@ -1,3 +1,30 @@
/**
* Digital Voice Modem - Host Software (Test Suite)
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / Host Software / Test Suite
*
*/
/*
* Copyright (C) 2022 by Natalie Moore <https://github.com/jelimoore>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Defines.h"
#include <catch2/catch_test_macros.hpp> #include <catch2/catch_test_macros.hpp>
TEST_CASE("NullTest", "[NullTest]") { TEST_CASE("NullTest", "[NullTest]") {

@ -0,0 +1,114 @@
/**
* Digital Voice Modem - Host Software (Test Suite)
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / Host Software / Test Suite
*
*/
/*
* Copyright (C) 2023 Bryan Biedenkapp N2PLL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Defines.h"
#include "edac/RS634717.h"
#include "p25/P25Defines.h"
#include "Log.h"
#include "Utils.h"
using namespace edac;
using namespace p25;
#include <catch2/catch_test_macros.hpp>
#include <stdlib.h>
#include <time.h>
TEST_CASE("HDU", "[RS_362017_Test]") {
SECTION("RS_362017_Test") {
bool failed = false;
INFO("P25 HDU RS (36,20,17) FEC Test");
srand((unsigned int)time(NULL));
RS634717 m_rs = RS634717();
uint8_t* random = (uint8_t*)malloc(15U);
for (size_t i = 0; i < 15U; i++) {
random[i] = rand();
}
// HDU Encode
uint8_t rs[P25_HDU_LENGTH_BYTES];
::memset(rs, 0x00U, P25_HDU_LENGTH_BYTES);
for (uint32_t i = 0; i < 15U; i++)
rs[i] = random[i];
rs[14U] = 0xF0U;
Utils::dump(2U, "LC::encodeHDU(), HDU", rs, P25_HDU_LENGTH_BYTES);
// encode RS (36,20,17) FEC
m_rs.encode362017(rs);
Utils::dump(2U, "LC::encodeHDU(), HDU RS", rs, P25_HDU_LENGTH_BYTES);
// HDU Decode
rs[9U] >>= 8;
rs[10U] >>= 8;
rs[11U] >>= 8;
rs[12U] >>= 8;
rs[13U] >>= 8;
Utils::dump(2U, "LC::decodeHDU(), HDU RS (errors injected)", rs, P25_HDU_LENGTH_BYTES);
// decode RS (36,20,17) FEC
try {
bool ret = m_rs.decode362017(rs);
if (!ret) {
fprintf(stdout, "LC::decodeHDU(), failed to decode RS (36,20,17) FEC\n");
failed = true;
goto cleanup;
}
}
catch (...) {
Utils::dump(2U, "P25, RS excepted with input data", rs, P25_HDU_LENGTH_BYTES);
failed = true;
goto cleanup;
}
Utils::dump(2U, "LC::decodeHDU(), HDU", rs, P25_HDU_LENGTH_BYTES);
for (uint32_t i = 0; i < 15U; i++) {
if (i == 14U) {
if (rs[i] != 0xF0U) {
::LogDebug("T", "LC::decodeHDU(), UNCORRECTABLE AT IDX %d\n", i);
failed = true;
}
}
else {
if (rs[i] != random[i]) {
::LogDebug("T", "LC::decodeHDU(), UNCORRECTABLE AT IDX %d\n", i);
failed = true;
}
}
}
cleanup:
delete random;
REQUIRE(failed==false);
}
}

@ -0,0 +1,112 @@
/**
* Digital Voice Modem - Host Software (Test Suite)
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / Host Software / Test Suite
*
*/
/*
* Copyright (C) 2022 by Natalie Moore <https://github.com/jelimoore>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Defines.h"
#include "edac/RS634717.h"
#include "p25/P25Defines.h"
#include "Log.h"
#include "Utils.h"
using namespace edac;
using namespace p25;
#include <catch2/catch_test_macros.hpp>
#include <stdlib.h>
#include <time.h>
TEST_CASE("LDU1", "[RS_241213_Test]") {
SECTION("RS_241213_Test") {
bool failed = false;
INFO("P25 LDU1 RS (24,12,13) FEC Test");
srand((unsigned int)time(NULL));
RS634717 m_rs = RS634717();
uint8_t* random = (uint8_t*)malloc(15U);
for (size_t i = 0; i < 15U; i++) {
random[i] = rand();
}
// LDU1 Encode
uint8_t rs[P25_LDU_LC_LENGTH_BYTES];
::memset(rs, 0x00U, P25_LDU_LC_LENGTH_BYTES);
for (uint32_t i = 0; i < 9U; i++)
rs[i] = random[i];
rs[8U] = 0xF0U;
Utils::dump(2U, "LC::encodeLDU1(), LDU1", rs, P25_LDU_LC_LENGTH_BYTES);
// encode RS (24,12,13) FEC
m_rs.encode241213(rs);
Utils::dump(2U, "LC::encodeLDU1(), LDU1 RS", rs, P25_LDU_LC_LENGTH_BYTES);
// LDU1 Decode
rs[6U] >>= 8;
rs[7U] >>= 8;
rs[8U] >>= 8;
Utils::dump(2U, "LC::encodeLDU1(), LDU RS (errors injected)", rs, P25_LDU_LC_LENGTH_BYTES);
// decode RS (24,12,13) FEC
try {
bool ret = m_rs.decode241213(rs);
if (!ret) {
::LogDebug("T", "LC::decodeLDU1(), failed to decode RS (24,12,13) FEC\n");
failed = true;
goto cleanup;
}
}
catch (...) {
Utils::dump(2U, "P25, RS excepted with input data", rs, P25_LDU_LC_LENGTH_BYTES);
failed = true;
goto cleanup;
}
Utils::dump(2U, "LC::decodeLDU1(), LDU1", rs, P25_LDU_LC_LENGTH_BYTES);
for (uint32_t i = 0; i < 9U; i++) {
if (i == 8U) {
if (rs[i] != 0xF0U) {
::LogDebug("T", "LC::decodeLDU1(), UNCORRECTABLE AT IDX %d\n", i);
failed = true;
}
}
else {
if (rs[i] != random[i]) {
::LogDebug("T", "LC::decodeLDU1(), UNCORRECTABLE AT IDX %d\n", i);
failed = true;
}
}
}
cleanup:
delete random;
REQUIRE(failed==false);
}
}

@ -0,0 +1,111 @@
/**
* Digital Voice Modem - Host Software (Test Suite)
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / Host Software / Test Suite
*
*/
/*
* Copyright (C) 2022 by Natalie Moore <https://github.com/jelimoore>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Defines.h"
#include "edac/RS634717.h"
#include "p25/P25Defines.h"
#include "Log.h"
#include "Utils.h"
using namespace edac;
using namespace p25;
#include <catch2/catch_test_macros.hpp>
#include <stdlib.h>
#include <time.h>
TEST_CASE("LDU2", "[RS_24169_Test]") {
SECTION("RS_24169_Test") {
bool failed = false;
INFO("P25 LDU2 RS (24,16,9) FEC Test");
srand((unsigned int)time(NULL));
RS634717 m_rs = RS634717();
uint8_t* random = (uint8_t*)malloc(15U);
for (size_t i = 0; i < 15U; i++) {
random[i] = rand();
}
// LDU2 Encode
uint8_t rs[P25_LDU_LC_LENGTH_BYTES];
::memset(rs, 0x00U, P25_LDU_LC_LENGTH_BYTES);
for (uint32_t i = 0; i < 12U; i++)
rs[i] = random[i];
rs[11U] = 0xF0U;
Utils::dump(2U, "LC::encodeLDU2(), LDU2", rs, P25_LDU_LC_LENGTH_BYTES);
// encode RS (24,16,9) FEC
m_rs.encode24169(rs);
Utils::dump(2U, "LC::encodeLDU2(), LDU2 RS", rs, P25_LDU_LC_LENGTH_BYTES);
// LDU2 Decode
rs[9U] >>= 4;
rs[10U] >>= 4;
Utils::dump(2U, "LC::decodeLDU2(), LDU RS (errors injected)", rs, P25_LDU_LC_LENGTH_BYTES);
// decode RS (24,16,9) FEC
try {
bool ret = m_rs.decode24169(rs);
if (!ret) {
::LogDebug("T", "LC::decodeLDU2(), failed to decode RS (24,16,9) FEC\n");
failed = true;
goto cleanup;
}
}
catch (...) {
Utils::dump(2U, "P25, RS excepted with input data", rs, P25_LDU_LC_LENGTH_BYTES);
failed = true;
goto cleanup;
}
Utils::dump(2U, "LC::decodeLDU2(), LDU2", rs, P25_LDU_LC_LENGTH_BYTES);
for (uint32_t i = 0; i < 12U; i++) {
if (i == 11U) {
if (rs[i] != 0xF0U) {
::LogDebug("T", "LC::decodeLDU2(), UNCORRECTABLE AT IDX %d\n", i);
failed = true;
}
}
else {
if (rs[i] != random[i]) {
::LogDebug("T", "LC::decodeLDU2(), UNCORRECTABLE AT IDX %d\n", i);
failed = true;
}
}
}
cleanup:
delete random;
REQUIRE(failed==false);
}
}
Loading…
Cancel
Save

Powered by TurnKey Linux.