implement call collision timeouts; fix GRP_VCH_GRANT_UPD allow it to carry 2 channels per spec;

pull/69/head
Bryan Biedenkapp 2 years ago
parent b3efca77fa
commit a880d2734e

@ -23,7 +23,10 @@ using namespace p25::lc::tsbk;
/* Initializes a new instance of the OSP_GRP_VCH_GRANT_UPD class. */
OSP_GRP_VCH_GRANT_UPD::OSP_GRP_VCH_GRANT_UPD() : TSBK()
OSP_GRP_VCH_GRANT_UPD::OSP_GRP_VCH_GRANT_UPD() : TSBK(),
m_grpVchIdB(0U),
m_grpVchNoB(0U),
m_dstIdB(0U)
{
m_lco = TSBKO::OSP_GRP_VCH_GRANT_UPD;
}
@ -43,9 +46,12 @@ bool OSP_GRP_VCH_GRANT_UPD::decode(const uint8_t* data, bool rawTSBK)
ulong64_t tsbkValue = TSBK::toValue(tsbk);
m_grpVchId = (uint8_t)((tsbkValue >> 60) & 0xFU); // Channel ID
m_grpVchNo = (uint32_t)((tsbkValue >> 48) & 0xFFFU); // Channel Number
m_dstId = (uint32_t)((tsbkValue >> 32) & 0xFFFFU); // Talkgroup Address
m_grpVchId = (uint8_t)((tsbkValue >> 60) & 0xFU); // Channel ID (A)
m_grpVchNo = (uint32_t)((tsbkValue >> 48) & 0xFFFU); // Channel Number (A)
m_dstId = (uint32_t)((tsbkValue >> 32) & 0xFFFFU); // Talkgroup Address (A)
m_grpVchIdB = (uint8_t)((tsbkValue >> 28) & 0xFU); // Channel ID (B)
m_grpVchNoB = (uint32_t)((tsbkValue >> 16) & 0xFFFU); // Channel Number (B)
m_dstIdB = (uint32_t)(tsbkValue & 0xFFFFU); // Talkgroup Address (B)
return true;
}
@ -59,14 +65,22 @@ void OSP_GRP_VCH_GRANT_UPD::encode(uint8_t* data, bool rawTSBK, bool noTrellis)
ulong64_t tsbkValue = 0U;
if (m_grpVchId != 0U) {
tsbkValue = m_grpVchId; // Channel ID
tsbkValue = m_grpVchId; // Channel ID (A)
}
else {
tsbkValue = m_siteData.channelId(); // Channel ID
tsbkValue = m_siteData.channelId(); // Channel ID (Site)
}
tsbkValue = (tsbkValue << 12) + m_grpVchNo; // Channel Number
tsbkValue = (tsbkValue << 16) + m_dstId; // Talkgroup Address
tsbkValue = (tsbkValue << 32) + 0;
tsbkValue = (tsbkValue << 12) + m_grpVchNo; // Channel Number (A)
tsbkValue = (tsbkValue << 16) + m_dstId; // Talkgroup Address (A)
if (m_grpVchIdB != 0U) {
tsbkValue = (tsbkValue << 4) + m_grpVchIdB; // Channel ID (B)
}
else {
tsbkValue = (tsbkValue << 4) + m_siteData.channelId(); // Channel ID (Site)
}
tsbkValue = (tsbkValue << 12) + m_grpVchNoB; // Channel Number (A)
tsbkValue = (tsbkValue << 16) + m_dstIdB; // Talkgroup Address (B)
std::unique_ptr<uint8_t[]> tsbk = TSBK::fromValue(tsbkValue);
TSBK::encode(data, tsbk.get(), rawTSBK, noTrellis);

@ -60,6 +60,20 @@ namespace p25
* @returns std::string String representation of the TSBK.
*/
std::string toString(bool isp = false) override;
public:
/**
* @brief Voice channel ID.
*/
__PROPERTY(uint8_t, grpVchIdB, GrpVchIdB);
/**
* @brief Voice channel number.
*/
__PROPERTY(uint32_t, grpVchNoB, GrpVchNoB);
/**
* @brief Destination ID.
*/
__PROPERTY(uint32_t, dstIdB, DstIdB);
};
} // namespace tsbk
} // namespace lc

@ -30,6 +30,12 @@ using namespace dmr::defines;
#include <cassert>
#include <chrono>
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const uint32_t CALL_COLL_TIMEOUT = 10U;
// ---------------------------------------------------------------------------
// Public Class Members
// ---------------------------------------------------------------------------
@ -193,6 +199,13 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId
RxStatus status = it->second;
if (streamId != status.streamId) {
if (status.srcId != 0U && status.srcId != srcId) {
uint64_t lastPktDuration = hrc::diff(hrc::now(), status.lastPacket);
if ((lastPktDuration / 1000) > CALL_COLL_TIMEOUT) {
LogWarning(LOG_NET, "DMR, Call Collision, lasted more then %us with no further updates, forcibly ending call");
m_status.erase(dstId);
m_network->m_callInProgress = false;
}
LogWarning(LOG_NET, "DMR, Call Collision, peer = %u, srcId = %u, dstId = %u, slotNo = %u, streamId = %u, rxPeer = %u, rxSrcId = %u, rxDstId = %u, rxSlotNo = %u, rxStreamId = %u, external = %u",
peerId, srcId, dstId, slotNo, streamId, status.peerId, status.srcId, status.dstId, status.slotNo, status.streamId, external);
return false;
@ -261,6 +274,8 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId
return false;
}
m_status[dstId].lastPacket = hrc::now();
// repeat traffic to the connected peers
if (m_network->m_peers.size() > 0U) {
uint32_t i = 0U;

@ -132,6 +132,7 @@ namespace network
class RxStatus {
public:
system_clock::hrc::hrc_t callStartTime;
system_clock::hrc::hrc_t lastPacket;
uint32_t srcId;
uint32_t dstId;
uint8_t slotNo;

@ -31,6 +31,12 @@ using namespace nxdn::defines;
#include <cassert>
#include <chrono>
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const uint32_t CALL_COLL_TIMEOUT = 10U;
// ---------------------------------------------------------------------------
// Public Class Members
// ---------------------------------------------------------------------------
@ -153,6 +159,13 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI
RxStatus status = m_status[dstId];
if (streamId != status.streamId) {
if (status.srcId != 0U && status.srcId != srcId) {
uint64_t lastPktDuration = hrc::diff(hrc::now(), status.lastPacket);
if ((lastPktDuration / 1000) > CALL_COLL_TIMEOUT) {
LogWarning(LOG_NET, "NXDN, Call Collision, lasted more then %us with no further updates, forcibly ending call");
m_status.erase(dstId);
m_network->m_callInProgress = false;
}
LogWarning(LOG_NET, "NXDN, Call Collision, peer = %u, srcId = %u, dstId = %u, streamId = %u, rxPeer = %u, rxSrcId = %u, rxDstId = %u, rxStreamId = %u, external = %u",
peerId, srcId, dstId, streamId, status.peerId, status.srcId, status.dstId, status.streamId, external);
return false;
@ -214,6 +227,8 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI
}
}
m_status[dstId].lastPacket = hrc::now();
// repeat traffic to the connected peers
if (m_network->m_peers.size() > 0U) {
uint32_t i = 0U;

@ -110,6 +110,7 @@ namespace network
class RxStatus {
public:
system_clock::hrc::hrc_t callStartTime;
system_clock::hrc::hrc_t lastPacket;
uint32_t srcId;
uint32_t dstId;
uint32_t streamId;

@ -33,6 +33,7 @@ using namespace p25::defines;
// ---------------------------------------------------------------------------
const uint32_t GRANT_TIMER_TIMEOUT = 15U;
const uint32_t CALL_COLL_TIMEOUT = 10U;
// ---------------------------------------------------------------------------
// Public Class Members
@ -224,6 +225,13 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId
RxStatus status = m_status[dstId];
if (streamId != status.streamId && ((duid != DUID::TDU) && (duid != DUID::TDULC))) {
if (status.srcId != 0U && status.srcId != srcId) {
uint64_t lastPktDuration = hrc::diff(hrc::now(), status.lastPacket);
if ((lastPktDuration / 1000) > CALL_COLL_TIMEOUT) {
LogWarning(LOG_NET, "P25, Call Collision, lasted more then %us with no further updates, forcibly ending call");
m_status.erase(dstId);
m_network->m_callInProgress = false;
}
LogWarning(LOG_NET, "P25, Call Collision, peer = %u, srcId = %u, dstId = %u, streamId = %u, rxPeer = %u, rxSrcId = %u, rxDstId = %u, rxStreamId = %u, external = %u",
peerId, srcId, dstId, streamId, status.peerId, status.srcId, status.dstId, status.streamId, external);
return false;
@ -290,6 +298,8 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId
return false;
}
m_status[dstId].lastPacket = hrc::now();
// repeat traffic to the connected peers
if (m_network->m_peers.size() > 0U) {
uint32_t i = 0U;

@ -160,6 +160,7 @@ namespace network
class RxStatus {
public:
system_clock::hrc::hrc_t callStartTime;
system_clock::hrc::hrc_t lastPacket;
uint32_t srcId;
uint32_t dstId;
uint32_t streamId;

Loading…
Cancel
Save

Powered by TurnKey Linux.