|
|
|
|
@ -39,6 +39,25 @@ TEST_CASE("DMR Tier III maintenance preserves 24-bit addresses", "[dmr][tier3][c
|
|
|
|
|
CHECK(decoded.getSrcId() == 0xABCDEFU);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("DMR Tier III maintenance round trip preserves field boundaries", "[dmr][tier3][csbk]")
|
|
|
|
|
{
|
|
|
|
|
CSBK_MAINT encoded;
|
|
|
|
|
encoded.setLastBlock(true);
|
|
|
|
|
encoded.setMaintKind(7U);
|
|
|
|
|
encoded.setDstId(0xFFFFFFU);
|
|
|
|
|
encoded.setSrcId(0x000001U);
|
|
|
|
|
|
|
|
|
|
uint8_t burst[DMR_FRAME_LENGTH_BYTES] = { 0U };
|
|
|
|
|
encoded.encode(burst);
|
|
|
|
|
|
|
|
|
|
CSBK_MAINT decoded;
|
|
|
|
|
decoded.setDataType(DataType::CSBK);
|
|
|
|
|
REQUIRE(decoded.decode(burst));
|
|
|
|
|
CHECK(decoded.getMaintKind() == 7U);
|
|
|
|
|
CHECK(decoded.getDstId() == 0xFFFFFFU);
|
|
|
|
|
CHECK(decoded.getSrcId() == 0x000001U);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("DMR Tier III payload clear round trip carries TSCC return fields", "[dmr][tier3][csbk]")
|
|
|
|
|
{
|
|
|
|
|
CSBK_P_CLEAR encoded;
|
|
|
|
|
@ -60,6 +79,27 @@ TEST_CASE("DMR Tier III payload clear round trip carries TSCC return fields", "[
|
|
|
|
|
CHECK(decoded.getSrcId() == WUID_TSI);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("DMR Tier III individual payload clear preserves maximum channel and addresses", "[dmr][tier3][csbk]")
|
|
|
|
|
{
|
|
|
|
|
CSBK_P_CLEAR encoded;
|
|
|
|
|
encoded.setLastBlock(true);
|
|
|
|
|
encoded.setLogicalCh1(0xFFFU);
|
|
|
|
|
encoded.setGI(false);
|
|
|
|
|
encoded.setDstId(0xFFFFFFU);
|
|
|
|
|
encoded.setSrcId(0x000001U);
|
|
|
|
|
|
|
|
|
|
uint8_t burst[DMR_FRAME_LENGTH_BYTES] = { 0U };
|
|
|
|
|
encoded.encode(burst);
|
|
|
|
|
|
|
|
|
|
CSBK_P_CLEAR decoded;
|
|
|
|
|
decoded.setDataType(DataType::CSBK);
|
|
|
|
|
REQUIRE(decoded.decode(burst));
|
|
|
|
|
CHECK(decoded.getLogicalCh1() == 0xFFFU);
|
|
|
|
|
CHECK_FALSE(decoded.getGI());
|
|
|
|
|
CHECK(decoded.getDstId() == 0xFFFFFFU);
|
|
|
|
|
CHECK(decoded.getSrcId() == 0x000001U);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("DMR Tier III grants account for both slots without changing ChannelLookup", "[dmr][tier3][grant]")
|
|
|
|
|
{
|
|
|
|
|
::lookups::ChannelLookup channels;
|
|
|
|
|
@ -94,3 +134,118 @@ TEST_CASE("DMR Tier III does not double-grant one slot", "[dmr][tier3][grant]")
|
|
|
|
|
REQUIRE(affiliations.grantChSlot(2001U, 1001U, 1U, 15U, true, false));
|
|
|
|
|
CHECK_FALSE(affiliations.grantChSlot(2002U, 1002U, 1U, 15U, true, false));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("DMR Tier III rejects grants without a valid destination or RF resource", "[dmr][tier3][grant]")
|
|
|
|
|
{
|
|
|
|
|
::lookups::ChannelLookup channels;
|
|
|
|
|
dmr::lookups::DMRAffiliationLookup affiliations(&channels, false);
|
|
|
|
|
|
|
|
|
|
CHECK_FALSE(affiliations.grantChSlot(0U, 1001U, 1U, 15U, true, false));
|
|
|
|
|
CHECK_FALSE(affiliations.grantChSlot(2001U, 1001U, 1U, 15U, true, false));
|
|
|
|
|
CHECK(affiliations.getGrantedRFChCnt() == 0U);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("DMR Tier III spills an occupied slot onto another physical channel", "[dmr][tier3][grant]")
|
|
|
|
|
{
|
|
|
|
|
::lookups::ChannelLookup channels;
|
|
|
|
|
REQUIRE(channels.initializeRFCh(101U));
|
|
|
|
|
REQUIRE(channels.initializeRFCh(102U));
|
|
|
|
|
|
|
|
|
|
dmr::lookups::DMRAffiliationLookup affiliations(&channels, false);
|
|
|
|
|
REQUIRE(affiliations.grantChSlot(2001U, 1001U, 1U, 15U, true, false));
|
|
|
|
|
REQUIRE(affiliations.grantChSlot(2002U, 1002U, 1U, 15U, true, false));
|
|
|
|
|
|
|
|
|
|
CHECK(affiliations.getGrantedCh(2001U) == 101U);
|
|
|
|
|
CHECK(affiliations.getGrantedCh(2002U) == 102U);
|
|
|
|
|
CHECK(affiliations.getGrantedSlot(2001U) == 1U);
|
|
|
|
|
CHECK(affiliations.getGrantedSlot(2002U) == 1U);
|
|
|
|
|
CHECK_FALSE(channels.isRFChAvailable());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("DMR Tier III can recreate a grant on an exact remote payload channel", "[dmr][tier3][grant]")
|
|
|
|
|
{
|
|
|
|
|
::lookups::ChannelLookup channels;
|
|
|
|
|
REQUIRE(channels.initializeRFCh(101U));
|
|
|
|
|
REQUIRE(channels.initializeRFCh(102U));
|
|
|
|
|
|
|
|
|
|
dmr::lookups::DMRAffiliationLookup affiliations(&channels, false);
|
|
|
|
|
affiliations.setSlotForChannelTSCC(101U, 1U);
|
|
|
|
|
|
|
|
|
|
REQUIRE(affiliations.grantChSlot(2001U, 1001U, 2U, 15U, true, true, 102U));
|
|
|
|
|
CHECK(affiliations.getGrantedCh(2001U) == 102U);
|
|
|
|
|
CHECK(affiliations.getGrantedSlot(2001U) == 2U);
|
|
|
|
|
CHECK_FALSE(affiliations.grantChSlot(2002U, 1002U, 2U, 15U, true, true, 102U));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("DMR Tier III reserves the TSCC slot and permits its opposing payload slot", "[dmr][tier3][grant]")
|
|
|
|
|
{
|
|
|
|
|
::lookups::ChannelLookup channels;
|
|
|
|
|
REQUIRE(channels.initializeRFCh(101U));
|
|
|
|
|
|
|
|
|
|
dmr::lookups::DMRAffiliationLookup affiliations(&channels, false);
|
|
|
|
|
affiliations.setSlotForChannelTSCC(101U, 1U);
|
|
|
|
|
|
|
|
|
|
CHECK_FALSE(channels.isRFChAvailable());
|
|
|
|
|
CHECK(affiliations.getAvailableSlotForChannel(101U) == 2U);
|
|
|
|
|
CHECK(affiliations.getAvailableChannelForSlot(1U) == 0U);
|
|
|
|
|
CHECK(affiliations.getAvailableChannelForSlot(2U) == 101U);
|
|
|
|
|
CHECK_FALSE(affiliations.isChBusy(101U));
|
|
|
|
|
|
|
|
|
|
REQUIRE(affiliations.grantChSlot(2001U, 1001U, 2U, 15U, true, false));
|
|
|
|
|
CHECK(affiliations.isChBusy(101U));
|
|
|
|
|
CHECK(affiliations.getAvailableSlotForChannel(101U) == 0U);
|
|
|
|
|
|
|
|
|
|
REQUIRE(affiliations.releaseGrant(2001U, false));
|
|
|
|
|
CHECK_FALSE(affiliations.isChBusy(101U));
|
|
|
|
|
CHECK_FALSE(channels.isRFChAvailable());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("DMR Tier III release callback reports physical channel and slot", "[dmr][tier3][grant]")
|
|
|
|
|
{
|
|
|
|
|
::lookups::ChannelLookup channels;
|
|
|
|
|
REQUIRE(channels.initializeRFCh(101U));
|
|
|
|
|
|
|
|
|
|
dmr::lookups::DMRAffiliationLookup affiliations(&channels, false);
|
|
|
|
|
uint32_t releasedCh = 0U;
|
|
|
|
|
uint32_t releasedSrc = 0U;
|
|
|
|
|
uint32_t releasedDst = 0U;
|
|
|
|
|
uint8_t releasedSlot = 0U;
|
|
|
|
|
affiliations.setReleaseGrantCallback(
|
|
|
|
|
[&](uint32_t chNo, uint32_t srcId, uint32_t dstId, uint8_t slot) {
|
|
|
|
|
releasedCh = chNo;
|
|
|
|
|
releasedSrc = srcId;
|
|
|
|
|
releasedDst = dstId;
|
|
|
|
|
releasedSlot = slot;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
REQUIRE(affiliations.grantChSlot(2001U, 1001U, 2U, 15U, false, true));
|
|
|
|
|
CHECK_FALSE(affiliations.isGroup(2001U));
|
|
|
|
|
CHECK(affiliations.isNetGranted(2001U));
|
|
|
|
|
REQUIRE(affiliations.releaseGrant(2001U, false));
|
|
|
|
|
|
|
|
|
|
CHECK(releasedCh == 101U);
|
|
|
|
|
CHECK(releasedSrc == 1001U);
|
|
|
|
|
CHECK(releasedDst == 2001U);
|
|
|
|
|
CHECK(releasedSlot == 2U);
|
|
|
|
|
CHECK(affiliations.getGrantedRFChCnt() == 0U);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_CASE("DMR Tier III bulk release clears grants across carriers", "[dmr][tier3][grant]")
|
|
|
|
|
{
|
|
|
|
|
::lookups::ChannelLookup channels;
|
|
|
|
|
REQUIRE(channels.initializeRFCh(101U));
|
|
|
|
|
REQUIRE(channels.initializeRFCh(102U));
|
|
|
|
|
|
|
|
|
|
dmr::lookups::DMRAffiliationLookup affiliations(&channels, false);
|
|
|
|
|
REQUIRE(affiliations.grantChSlot(2001U, 1001U, 1U, 15U, true, false));
|
|
|
|
|
REQUIRE(affiliations.grantChSlot(2002U, 1002U, 1U, 15U, true, false));
|
|
|
|
|
CHECK(affiliations.getGrantedRFChCnt() == 2U);
|
|
|
|
|
|
|
|
|
|
REQUIRE(affiliations.releaseGrant(0U, true));
|
|
|
|
|
CHECK_FALSE(affiliations.isGranted(2001U));
|
|
|
|
|
CHECK_FALSE(affiliations.isGranted(2002U));
|
|
|
|
|
CHECK(affiliations.getGrantedSlot(2001U) == 0U);
|
|
|
|
|
CHECK(affiliations.getGrantedSlot(2002U) == 0U);
|
|
|
|
|
CHECK(affiliations.getGrantedRFChCnt() == 0U);
|
|
|
|
|
CHECK(channels.isRFChAvailable());
|
|
|
|
|
}
|
|
|
|
|
|