improvement to the DFSI code, handle TDU end-of-traffic;

pull/12/head
Bryan Biedenkapp 4 years ago
parent ea3be21cb2
commit 270208432f

@ -79,9 +79,11 @@ namespace p25
const uint8_t P25_DFSI_RT_DISABLED = 0x04U; //
const uint8_t P25_DFSI_START_FLAG = 0x0CU; //
const uint8_t P25_DFSI_STOP_FLAG = 0x00U; //
const uint8_t P25_DFSI_STOP_FLAG = 0x25U; //
const uint8_t P25_DFSI_TYPE_DATA_PAYLOAD = 0x06U; //
const uint8_t P25_DFSI_TYPE_VOICE = 0x0BU; //
const uint8_t P25_DFSI_TYPE_DATA = 0x0CU; //
const uint8_t P25_DFSI_TYPE_TSBK = 0x0FU; //
const uint8_t P25_DFSI_DEF_ICW_SOURCE = 0x00U; // Infrastructure Source - Default Source

@ -137,9 +137,14 @@ void DFSITrunkPacket::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite, bo
if (!m_p25->m_control)
return;
writeRF_DFSI_Start(P25_DFSI_TYPE_TSBK);
uint8_t data[P25_TSDU_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
m_rfDFSILC.setFrameType(P25_DFSI_TSBK);
m_rfDFSILC.setStartStop(P25_DFSI_START_FLAG);
m_rfDFSILC.setType(P25_DFSI_TYPE_TSBK);
m_rfDFSILC.tsbk(m_rfTSBK);
// Generate Sync
@ -181,12 +186,12 @@ void DFSITrunkPacket::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite, bo
// Generate DFSI TSBK block
m_rfDFSILC.encodeTSBK(data + 2U);
if (m_p25->m_duplex) {
data[0U] = modem::TAG_DATA;
data[1U] = 0x00U;
data[0U] = modem::TAG_DATA;
data[1U] = 0x00U;
m_p25->writeQueueRF(data, P25_DFSI_TSBK_FRAME_LENGTH_BYTES + 2U);
}
m_p25->writeQueueRF(data, P25_DFSI_TSBK_FRAME_LENGTH_BYTES + 2U);
writeRF_DSFI_Stop(P25_DFSI_TYPE_TSBK);
}
/// <summary>
@ -209,3 +214,52 @@ void DFSITrunkPacket::writeNet_TSDU()
if (m_network != NULL)
m_network->resetP25();
}
/// <summary>
/// Helper to write start DFSI data.
/// </summary>
/// <param name="type"></param>
void DFSITrunkPacket::writeRF_DFSI_Start(uint8_t type)
{
uint8_t buffer[P25_DFSI_SS_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_DFSI_SS_FRAME_LENGTH_BYTES + 2U);
// Generate Start/Stop
m_rfDFSILC.setFrameType(P25_DFSI_START_STOP);
m_rfDFSILC.setStartStop(P25_DFSI_START_FLAG);
m_rfDFSILC.setType(type);
// Generate Identifier Data
m_rfDFSILC.encodeNID(buffer + 2U);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;
m_p25->writeQueueRF(buffer, P25_DFSI_SS_FRAME_LENGTH_BYTES + 2U);
}
/// <suimmary>
/// Helper to write stop DFSI data.
/// </summary>
/// <param name="type"></param>
void DFSITrunkPacket::writeRF_DSFI_Stop(uint8_t type)
{
uint8_t buffer[P25_DFSI_SS_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_DFSI_SS_FRAME_LENGTH_BYTES + 2U);
// Generate Start/Stop
m_rfDFSILC.setFrameType(P25_DFSI_START_STOP);
m_rfDFSILC.setStartStop(P25_DFSI_STOP_FLAG);
m_rfDFSILC.setType(type);
// Generate Identifier Data
m_rfDFSILC.encodeNID(buffer + 2U);
buffer[0U] = modem::TAG_EOT;
buffer[1U] = 0x00U;
// for whatever reason this is almost always sent twice
for (uint8_t i = 0; i < 2;i ++) {
m_p25->writeQueueRF(buffer, P25_DFSI_SS_FRAME_LENGTH_BYTES + 2U);
}
}

@ -78,6 +78,11 @@ namespace p25
/// <summary>Helper to write a network single-block P25 TSDU packet.</summary>
virtual void writeNet_TSDU();
/// <suimmary>Helper to write start DFSI data.</summary>
void writeRF_DFSI_Start(uint8_t type);
/// <suimmary>Helper to write stop DFSI data.</summary>
void writeRF_DSFI_Stop(uint8_t type);
private:
friend class DFSIVoicePacket;
friend class p25::Control;

@ -559,6 +559,60 @@ bool DFSIVoicePacket::process(uint8_t* data, uint32_t len)
}
}
}
else if (frameType == P25_DFSI_START_STOP) {
if (m_rfDFSILC.getType() == P25_DFSI_TYPE_VOICE && m_rfDFSILC.getStartStop() == P25_DFSI_STOP_FLAG) {
if (m_p25->m_control) {
m_p25->m_trunk->releaseDstIdGrant(m_rfLC.getDstId(), false);
}
uint8_t data[P25_TDU_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TDU_FRAME_LENGTH_BYTES);
// Generate Sync
Sync::addP25Sync(data + 2U);
// Generate NID
m_p25->m_nid.encode(data + 2U, P25_DUID_TDU);
// Add busy bits
m_p25->addBusyBits(data + 2U, P25_TDU_FRAME_LENGTH_BITS, true, true);
writeNetworkRF(data + 2U, P25_DUID_TDU);
m_lastDUID = P25_DUID_TDU;
m_p25->m_rfTimeout.stop();
if (m_p25->m_rfState == RS_RF_AUDIO) {
if (m_p25->m_rssi != 0U) {
::ActivityLog("P25", true, "RF end of transmission, %.1f seconds, BER: %.1f%%, RSSI : -%u / -%u / -%u dBm",
float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits), m_p25->m_minRSSI, m_p25->m_maxRSSI,
m_p25->m_aveRSSI / m_p25->m_rssiCount);
}
else {
::ActivityLog("P25", true, "RF end of transmission, %.1f seconds, BER: %.1f%%",
float(m_rfFrames) / 5.56F, float(m_rfErrs * 100U) / float(m_rfBits));
}
LogMessage(LOG_RF, P25_TDU_STR " DFSI, total frames: %d, bits: %d, undecodable LC: %d, errors: %d, BER: %.4f%%",
m_rfFrames, m_rfBits, m_rfUndecodableLC, m_rfErrs, float(m_rfErrs * 100U) / float(m_rfBits));
if (m_p25->m_dedicatedControl) {
m_p25->m_tailOnIdle = false;
writeRF_EndOfVoice();
}
else {
m_p25->m_tailOnIdle = true;
}
}
m_p25->m_rfState = RS_RF_LISTENING;
return true;
}
}
else {
LogError(LOG_RF, "P25 unhandled DFSI frame type, frameType = $%02X", frameType);
}
return false;
}
@ -743,6 +797,7 @@ bool DFSIVoicePacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& contro
/// <param name="verbose">Flag indicating whether P25 verbose logging is enabled.</param>
DFSIVoicePacket::DFSIVoicePacket(Control* p25, network::BaseNetwork* network, bool debug, bool verbose) :
VoicePacket(p25, network, debug, verbose),
m_trunk(NULL),
m_rfDFSILC(),
m_netDFSILC(),
m_dfsiLDU1(NULL),
@ -753,6 +808,9 @@ DFSIVoicePacket::DFSIVoicePacket(Control* p25, network::BaseNetwork* network, bo
::memset(m_dfsiLDU1, 0x00U, 9U * 25U);
::memset(m_dfsiLDU2, 0x00U, 9U * 25U);
// hmmm...this should hopefully be a safe cast...right?
m_trunk = (DFSITrunkPacket *)p25->m_trunk;
}
/// <summary>
@ -773,21 +831,7 @@ void DFSIVoicePacket::writeNet_TDU()
m_p25->m_trunk->releaseDstIdGrant(m_netLC.getDstId(), false);
}
m_rfDFSILC.setFrameType(P25_DFSI_START_STOP);
uint8_t buffer[P25_DFSI_SS_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_DFSI_SS_FRAME_LENGTH_BYTES + 2U);
buffer[0U] = modem::TAG_EOT;
buffer[1U] = 0x00U;
// Generate DFSI NID
m_rfDFSILC.encodeNID(buffer + 2U);
// stop writes the NID twice...
for (uint8_t i = 0; i < 2; i++) {
m_p25->writeQueueNet(buffer, P25_DFSI_SS_FRAME_LENGTH_BYTES + 2U);
}
m_trunk->writeRF_DSFI_Stop(P25_DFSI_TYPE_VOICE);
if (m_verbose) {
LogMessage(LOG_NET, P25_TDU_STR ", srcId = %u", m_netLC.getSrcId());
@ -998,42 +1042,29 @@ void DFSIVoicePacket::writeNet_LDU1()
m_netDFSILC.control(m_netLC);
m_netDFSILC.lsd(lsd);
if (!m_p25->m_disableNetworkHDU) {
uint8_t buffer[P25_DFSI_VHDR1_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_DFSI_VHDR1_FRAME_LENGTH_BYTES + 2U);
// Generate Start/Stop
m_netDFSILC.setFrameType(P25_DFSI_START_STOP);
m_netDFSILC.encodeNID(buffer + 2U);
m_trunk->writeRF_DFSI_Start(P25_DFSI_TYPE_VOICE);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;
m_p25->writeQueueNet(buffer, P25_DFSI_SS_FRAME_LENGTH_BYTES + 2U);
uint8_t buffer[P25_DFSI_VHDR1_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_DFSI_VHDR1_FRAME_LENGTH_BYTES + 2U);
// Generate Voice Header 1
m_netDFSILC.setFrameType(P25_DFSI_VHDR1);
m_netDFSILC.encodeVHDR1(buffer + 2U);
// Generate Voice Header 1
m_netDFSILC.setFrameType(P25_DFSI_VHDR1);
m_netDFSILC.encodeVHDR1(buffer + 2U);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;
m_p25->writeQueueNet(buffer, P25_DFSI_VHDR1_FRAME_LENGTH_BYTES + 2U);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;
m_p25->writeQueueNet(buffer, P25_DFSI_VHDR1_FRAME_LENGTH_BYTES + 2U);
// Generate Voice Header 2
m_netDFSILC.setFrameType(P25_DFSI_VHDR2);
m_netDFSILC.encodeVHDR2(buffer + 2U);
// Generate Voice Header 2
m_netDFSILC.setFrameType(P25_DFSI_VHDR2);
m_netDFSILC.encodeVHDR2(buffer + 2U);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;
m_p25->writeQueueNet(buffer, P25_DFSI_VHDR2_FRAME_LENGTH_BYTES + 2U);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;
m_p25->writeQueueNet(buffer, P25_DFSI_VHDR2_FRAME_LENGTH_BYTES + 2U);
if (m_verbose) {
LogMessage(LOG_NET, P25_HDU_STR " DFSI, dstId = %u, algo = $%02X, kid = $%04X", m_netLC.getDstId(), m_netLC.getAlgId(), m_netLC.getKId());
}
}
else {
if (m_verbose) {
LogMessage(LOG_NET, P25_HDU_STR " DFSI, not transmitted; network HDU disabled, dstId = %u, algo = $%02X, kid = $%04X", m_netLC.getDstId(), m_netLC.getAlgId(), m_netLC.getKId());
}
if (m_verbose) {
LogMessage(LOG_NET, P25_HDU_STR " DFSI, dstId = %u, algo = $%02X, kid = $%04X", m_netLC.getDstId(), m_netLC.getAlgId(), m_netLC.getKId());
}
}

@ -32,6 +32,7 @@
#include "Defines.h"
#include "p25/dfsi/LC.h"
#include "p25/dfsi/DFSITrunkPacket.h"
#include "p25/TrunkPacket.h"
#include "p25/Control.h"
#include "network/BaseNetwork.h"
@ -65,6 +66,8 @@ namespace p25
virtual bool processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::LowSpeedData& lsd, uint8_t& duid);
protected:
DFSITrunkPacket* m_trunk;
LC m_rfDFSILC;
LC m_netDFSILC;

@ -817,8 +817,8 @@ void LC::encodeStart(uint8_t* data)
uint8_t rawFrame[P25_DFSI_START_LENGTH_BYTES];
::memset(rawFrame, 0x00U, P25_DFSI_START_LENGTH_BYTES);
rawFrame[0U] = 0x02U;
rawFrame[1U] = m_rtModeFlag; // RT Mode Flag
rawFrame[0U] = 0x02U; //
rawFrame[1U] = m_rtModeFlag; // RT/RT Mode Flag
rawFrame[2U] = m_startStopFlag; // Start/Stop Flag
rawFrame[3U] = m_typeFlag; // Type flag

Loading…
Cancel
Save

Powered by TurnKey Linux.