implement fix for CSBK verbosity not being set; during CC stream hide CSBK/TSBK/RCCH verbosity; implement CSBKO_MAINT CSBK; correct missing behavior to perform DMR payload activation; add CRC handling for MBC;

3.56-maint
Bryan Biedenkapp 2 years ago
parent a64dfa38fd
commit b3c803e918

@ -97,6 +97,7 @@ Control::Control(bool authoritative, uint32_t colorCode, uint32_t callHang, uint
acl::AccessControl::init(m_ridLookup, m_tidLookup);
Slot::init(this, authoritative, colorCode, SiteData(), embeddedLCOnly, dumpTAData, callHang, modem, network, duplex, m_ridLookup, m_tidLookup, m_idenTable, rssiMapper, jitter, verbose);
lc::CSBK::setVerbose(m_dumpCSBKData);
m_slot1 = new Slot(1U, timeout, tgHang, queueSize, dumpDataPacket, repeatDataPacket, dumpCSBKData, debug, verbose);
m_slot2 = new Slot(2U, timeout, tgHang, queueSize, dumpDataPacket, repeatDataPacket, dumpCSBKData, debug, verbose);
@ -297,7 +298,7 @@ bool Control::processWakeup(const uint8_t* data)
return false;
// generate a new CSBK and check validity
std::unique_ptr<lc::CSBK> csbk = lc::csbk::CSBKFactory::createCSBK(data + 2U);
std::unique_ptr<lc::CSBK> csbk = lc::csbk::CSBKFactory::createCSBK(data + 2U, DT_CSBK);
if (csbk == nullptr)
return false;

@ -99,6 +99,7 @@ namespace dmr
const uint8_t PI_HEADER_CRC_MASK[] = { 0x69U, 0x69U };
const uint8_t DATA_HEADER_CRC_MASK[] = { 0xCCU, 0xCCU };
const uint8_t CSBK_CRC_MASK[] = { 0xA5U, 0xA5U };
const uint8_t CSBK_MBC_CRC_MASK[] = { 0xAAU, 0xAAU };
const uint16_t TSCC_MAX_CSC_CNT = 511U;
@ -193,6 +194,8 @@ namespace dmr
const uint8_t DT_TERMINATOR_WITH_LC = 0x02U;
#define DMR_DT_TERMINATOR_WITH_LC "DMR_DT_TERMINATOR_WITH_LC (Terminator with Link Control)"
const uint8_t DT_CSBK = 0x03U;
const uint8_t DT_MBC_HEADER = 0x04U;
const uint8_t DT_MBC_DATA = 0x05U;
const uint8_t DT_DATA_HEADER = 0x06U;
#define DMR_DT_DATA_HEADER "DMR_DT_DATA_HEADER (Data Header)"
const uint8_t DT_RATE_12_DATA = 0x07U;
@ -303,6 +306,7 @@ namespace dmr
const uint8_t CSBKO_EXT_FNCT = 0x24U; // (DMRA) EXT FNCT - Extended Function
const uint8_t CSBKO_NACK_RSP = 0x26U; // NACK RSP - Negative Acknowledgement Response
const uint8_t CSBKO_BROADCAST = 0x28U; // BCAST - Announcement PDU
const uint8_t CSBKO_MAINT = 0x2AU; // MAINT - Call Maintainence PDU
const uint8_t CSBKO_P_CLEAR = 0x2EU; // P_CLEAR - Payload Channel Clear
const uint8_t CSBKO_PV_GRANT = 0x30U; // PV_GRANT - Private Voice Channel Grant
const uint8_t CSBKO_TV_GRANT = 0x31U; // TV_GRANT - Talkgroup Voice Channel Grant

@ -751,6 +751,13 @@ void Slot::setTSCCActivated(uint32_t dstId, uint32_t srcId, bool group, bool voi
m_tsccPayloadDstId = dstId;
m_tsccPayloadGroup = group;
m_tsccPayloadVoice = voice;
// start payload channel transmit
if (!m_modem->hasTX()) {
m_modem->writeDMRStart(true);
}
m_control->writeRF_CSBK_Payload_Activate(dstId, srcId, group, voice);
}
/// <summary>
@ -1312,6 +1319,11 @@ void Slot::writeRF_ControlData(uint16_t frameCnt, uint8_t n)
if (!m_enableTSCC)
return;
// disable verbose CSBK dumping during control data writes (if necessary)
bool csbkVerbose = lc::CSBK::getVerbose();
if (csbkVerbose)
lc::CSBK::setVerbose(false);
// don't add any frames if the queue is full
uint8_t len = DMR_FRAME_LENGTH_BYTES + 2U;
uint32_t space = m_txQueue.freeSpace();
@ -1393,6 +1405,8 @@ void Slot::writeRF_ControlData(uint16_t frameCnt, uint8_t n)
n++;
i++;
} while (i <= seqCnt);
lc::CSBK::setVerbose(csbkVerbose);
}
/// <summary>

@ -13,7 +13,7 @@
/*
* Copyright (C) 2012 by Ian Wraith
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2021 Bryan Biedenkapp N2PLL
* Copyright (C) 2021,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
@ -371,15 +371,26 @@ void DataHeader::encode(uint8_t* data) const
break;
}
// compute CRC-CCITT 16
m_data[10U] ^= DATA_HEADER_CRC_MASK[0U];
m_data[11U] ^= DATA_HEADER_CRC_MASK[1U];
if (m_DPF == DPF_UDT) {
m_data[9U] &= 0xFEU;
edac::CRC::addCCITT162(m_data, DMR_LC_HEADER_LENGTH_BYTES);
edac::CRC::addCCITT162(m_data, DMR_LC_HEADER_LENGTH_BYTES);
// restore the checksum
m_data[10U] ^= DATA_HEADER_CRC_MASK[0U];
m_data[11U] ^= DATA_HEADER_CRC_MASK[1U];
}
else {
// compute CRC-CCITT 16
m_data[10U] ^= DATA_HEADER_CRC_MASK[0U];
m_data[11U] ^= DATA_HEADER_CRC_MASK[1U];
edac::CRC::addCCITT162(m_data, DMR_LC_HEADER_LENGTH_BYTES);
// restore the checksum
m_data[10U] ^= DATA_HEADER_CRC_MASK[0U];
m_data[11U] ^= DATA_HEADER_CRC_MASK[1U];
// restore the checksum
m_data[10U] ^= DATA_HEADER_CRC_MASK[0U];
m_data[11U] ^= DATA_HEADER_CRC_MASK[1U];
}
// encode BPTC (196,96) FEC
edac::BPTC19696 bptc;

@ -12,7 +12,7 @@
//
/*
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
* Copyright (C) 2019-2021 by Bryan Biedenkapp N2PLL
* Copyright (C) 2019-2023 by 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
@ -76,6 +76,7 @@ CSBK::CSBK() :
m_dstId(0U),
m_dataContent(false),
m_CBF(0U),
m_dataType(DT_CSBK),
m_emergency(false),
m_privacy(false),
m_supplementData(false),
@ -114,8 +115,9 @@ std::string CSBK::toString()
/// Regenerate a DMR CSBK without decoding.
/// </summary>
/// <param name="data"></param>
/// <param name="dataType"></param>
/// <returns>True, if TSBK was decoded, otherwise false.</returns>
bool CSBK::regenerate(uint8_t* data)
bool CSBK::regenerate(uint8_t* data, uint8_t dataType)
{
uint8_t csbk[DMR_CSBK_LENGTH_BYTES];
::memset(csbk, 0x00U, DMR_CSBK_LENGTH_BYTES);
@ -125,8 +127,16 @@ bool CSBK::regenerate(uint8_t* data)
bptc.decode(data, csbk);
// validate the CRC-CCITT 16
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
switch (dataType) {
case DT_CSBK:
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
break;
case DT_MBC_HEADER:
csbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
csbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break;
}
bool valid = edac::CRC::checkCCITT162(csbk, DMR_CSBK_LENGTH_BYTES);
if (!valid) {
@ -135,17 +145,41 @@ bool CSBK::regenerate(uint8_t* data)
}
// restore the checksum
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
switch (dataType) {
case DT_CSBK:
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
break;
case DT_MBC_HEADER:
csbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
csbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break;
}
// calculate checksum
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
switch (dataType) {
case DT_CSBK:
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
break;
case DT_MBC_HEADER:
csbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
csbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break;
}
edac::CRC::addCCITT162(csbk, 12U);
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
switch (dataType) {
case DT_CSBK:
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
break;
case DT_MBC_HEADER:
csbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
csbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break;
}
// encode BPTC (196,96) FEC
bptc.encode(csbk, data);
@ -217,8 +251,16 @@ bool CSBK::decode(const uint8_t* data, uint8_t* csbk)
bptc.decode(data, csbk);
// validate the CRC-CCITT 16
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
switch (m_dataType) {
case DT_CSBK:
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
break;
case DT_MBC_HEADER:
csbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
csbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break;
}
bool valid = edac::CRC::checkCCITT162(csbk, DMR_CSBK_LENGTH_BYTES);
if (!valid) {
@ -227,8 +269,16 @@ bool CSBK::decode(const uint8_t* data, uint8_t* csbk)
}
// restore the checksum
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
switch (m_dataType) {
case DT_CSBK:
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
break;
case DT_MBC_HEADER:
csbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
csbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break;
}
if (m_verbose) {
Utils::dump(2U, "Decoded CSBK", csbk, DMR_CSBK_LENGTH_BYTES);
@ -269,13 +319,29 @@ void CSBK::encode(uint8_t* data, const uint8_t* csbk)
outCsbk[1U] = m_colorCode & 0x0FU; // Cdef uses Color Code
}
outCsbk[10U] ^= CSBK_CRC_MASK[0U];
outCsbk[11U] ^= CSBK_CRC_MASK[1U];
switch (m_dataType) {
case DT_CSBK:
outCsbk[10U] ^= CSBK_CRC_MASK[0U];
outCsbk[11U] ^= CSBK_CRC_MASK[1U];
break;
case DT_MBC_HEADER:
outCsbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
outCsbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break;
}
edac::CRC::addCCITT162(outCsbk, 12U);
outCsbk[10U] ^= CSBK_CRC_MASK[0U];
outCsbk[11U] ^= CSBK_CRC_MASK[1U];
switch (m_dataType) {
case DT_CSBK:
outCsbk[10U] ^= CSBK_CRC_MASK[0U];
outCsbk[11U] ^= CSBK_CRC_MASK[1U];
break;
case DT_MBC_HEADER:
outCsbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
outCsbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break;
}
if (m_verbose) {
Utils::dump(2U, "Encoded CSBK", outCsbk, DMR_CSBK_LENGTH_BYTES);

@ -12,7 +12,7 @@
//
/*
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
* Copyright (C) 2019-2021 by Bryan Biedenkapp N2PLL
* Copyright (C) 2019-2023 by 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
@ -64,8 +64,10 @@ namespace dmr
/// <summary>Regenerate a DMR CSBK without decoding.</summary>
/// <remarks>This is because the DMR archeticture allows fall-thru of unsupported CSBKs.</remarks>
static bool regenerate(uint8_t* data);
static bool regenerate(uint8_t* data, uint8_t dataType);
/// <summary>Gets the flag indicating verbose log output.</summary>
static bool getVerbose() { return m_verbose; }
/// <summary>Sets the flag indicating verbose log output.</summary>
static void setVerbose(bool verbose) { m_verbose = verbose; }
@ -104,6 +106,9 @@ namespace dmr
/// <summary>Number of blocks to follow.</summary>
__PROTECTED_PROPERTY(uint8_t, CBF, CBF);
/// <summary>Data type for this CSBK.</summary>
__PROTECTED_PROPERTY(uint8_t, dataType, DataType);
/** Common Service Options */
/// <summary>Flag indicating the emergency bits are set.</summary>
__PROTECTED_PROPERTY(bool, emergency, Emergency);

@ -60,8 +60,9 @@ CSBKFactory::~CSBKFactory()
/// Create an instance of a CSBK.
/// </summary>
/// <param name="data"></param>
/// <param name="dataType"></param>
/// <returns>True, if CSBK was decoded, otherwise false.</returns>
std::unique_ptr<CSBK> CSBKFactory::createCSBK(const uint8_t* data)
std::unique_ptr<CSBK> CSBKFactory::createCSBK(const uint8_t* data, uint8_t dataType)
{
assert(data != nullptr);
@ -72,8 +73,16 @@ std::unique_ptr<CSBK> CSBKFactory::createCSBK(const uint8_t* data)
bptc.decode(data, csbk);
// validate the CRC-CCITT 16
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
switch (dataType) {
case DT_CSBK:
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
break;
case DT_MBC_HEADER:
csbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
csbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break;
}
bool valid = edac::CRC::checkCCITT162(csbk, DMR_CSBK_LENGTH_BYTES);
if (!valid) {
@ -82,8 +91,16 @@ std::unique_ptr<CSBK> CSBKFactory::createCSBK(const uint8_t* data)
}
// restore the checksum
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
switch (dataType) {
case DT_CSBK:
csbk[10U] ^= CSBK_CRC_MASK[0U];
csbk[11U] ^= CSBK_CRC_MASK[1U];
break;
case DT_MBC_HEADER:
csbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
csbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break;
}
uint8_t CSBKO = csbk[0U] & 0x3FU; // CSBKO
uint8_t FID = csbk[1U]; // Feature ID
@ -114,6 +131,8 @@ std::unique_ptr<CSBK> CSBKFactory::createCSBK(const uint8_t* data)
/** Tier 3 */
case CSBKO_ACK_RSP:
return decode(new CSBK_ACK_RSP(), data);
case CSBKO_MAINT:
return decode(new CSBK_MAINT(), data);
default:
LogError(LOG_DMR, "CSBKFactory::create(), unknown CSBK type, csbko = $%02X", CSBKO);

@ -36,6 +36,7 @@
#include "dmr/lc/csbk/CSBK_CALL_ALRT.h"
#include "dmr/lc/csbk/CSBK_DVM_GIT_HASH.h"
#include "dmr/lc/csbk/CSBK_EXT_FNCT.h"
#include "dmr/lc/csbk/CSBK_MAINT.h"
#include "dmr/lc/csbk/CSBK_NACK_RSP.h"
#include "dmr/lc/csbk/CSBK_P_CLEAR.h"
#include "dmr/lc/csbk/CSBK_P_GRANT.h"
@ -68,7 +69,7 @@ namespace dmr
~CSBKFactory();
/// <summary>Create an instance of a CSBK.</summary>
static std::unique_ptr<CSBK> createCSBK(const uint8_t* data);
static std::unique_ptr<CSBK> createCSBK(const uint8_t* data, uint8_t dataType);
private:
/// <summary></summary>

@ -0,0 +1,98 @@
/**
* Digital Voice Modem - Host Software
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / Host Software
*
*/
/*
* Copyright (C) 2023 by 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 "dmr/lc/csbk/CSBK_MAINT.h"
#include "Log.h"
#include "Utils.h"
using namespace dmr::lc::csbk;
using namespace dmr::lc;
using namespace dmr;
#include <cassert>
#include <cmath>
// ---------------------------------------------------------------------------
// Public Class Members
// ---------------------------------------------------------------------------
/// <summary>
/// Initializes a new instance of the CSBK_MAINT class.
/// </summary>
CSBK_MAINT::CSBK_MAINT() : CSBK()
{
m_CSBKO = CSBKO_MAINT;
}
/// <summary>
/// Decode a control signalling block.
/// </summary>
/// <param name="data"></param>
/// <returns>True, if CSBK was decoded, otherwise false.</returns>
bool CSBK_MAINT::decode(const uint8_t* data)
{
assert(data != NULL);
uint8_t csbk[DMR_CSBK_LENGTH_BYTES];
::memset(csbk, 0x00U, DMR_CSBK_LENGTH_BYTES);
bool ret = CSBK::decode(data, csbk);
if (!ret)
return false;
ulong64_t csbkValue = CSBK::toValue(csbk);
m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address
m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address
return true;
}
/// <summary>
/// Encode a control signalling block.
/// </summary>
/// <param name="data"></param>
void CSBK_MAINT::encode(uint8_t* data)
{
assert(data != NULL);
ulong64_t csbkValue = 0U;
csbkValue = (csbkValue << 25) + m_dstId; // Target Radio Address
csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address
std::unique_ptr<uint8_t[]> csbk = CSBK::fromValue(csbkValue);
CSBK::encode(data, csbk.get());
}
/// <summary>
/// Returns a string that represents the current CSBK.
/// </summary>
/// <returns></returns>
std::string CSBK_MAINT::toString()
{
return std::string("CSBKO_MAINT (Call Maintainence)");
}

@ -0,0 +1,60 @@
/**
* Digital Voice Modem - Host Software
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / Host Software
*
*/
/*
* Copyright (C) 2023 by 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.
*/
#if !defined(__DMR_LC_CSBK__CSBK_MAINT_H__)
#define __DMR_LC_CSBK__CSBK_MAINT_H__
#include "Defines.h"
#include "dmr/lc/CSBK.h"
namespace dmr
{
namespace lc
{
namespace csbk
{
// ---------------------------------------------------------------------------
// Class Declaration
// Implements MAINT - Call Maintainence
// ---------------------------------------------------------------------------
class HOST_SW_API CSBK_MAINT : public CSBK {
public:
/// <summary>Initializes a new instance of the CSBK_MAINT class.</summary>
CSBK_MAINT();
/// <summary>Decode a control signalling block.</summary>
bool decode(const uint8_t* data);
/// <summary>Encode a control signalling block.</summary>
void encode(uint8_t* data);
/// <summary>Returns a string that represents the current CSBK.</summary>
virtual std::string toString() override;
};
} // namespace csbk
} // namespace lc
} // namespace dmr
#endif // __DMR_LC_CSBK__CSBK_MAINT_H__

@ -161,7 +161,7 @@ bool ControlSignaling::process(uint8_t* data, uint32_t len)
if (dataType == DT_CSBK) {
// generate a new CSBK and check validity
std::unique_ptr<lc::CSBK> csbk = CSBKFactory::createCSBK(data + 2U);
std::unique_ptr<lc::CSBK> csbk = CSBKFactory::createCSBK(data + 2U, dataType);
if (csbk == nullptr)
return false;
@ -367,7 +367,7 @@ bool ControlSignaling::process(uint8_t* data, uint32_t len)
if (!handled) {
// regenerate the CSBK data
lc::CSBK::regenerate(data + 2U);
lc::CSBK::regenerate(data + 2U, dataType);
// regenerate the Slot Type
slotType.encode(data + 2U);
@ -404,7 +404,7 @@ void ControlSignaling::processNetwork(const data::Data & dmrData)
dmrData.getData(data + 2U);
if (dataType == DT_CSBK) {
std::unique_ptr<lc::CSBK> csbk = CSBKFactory::createCSBK(data + 2U);
std::unique_ptr<lc::CSBK> csbk = CSBKFactory::createCSBK(data + 2U, dataType);
if (csbk == nullptr) {
LogError(LOG_NET, "DMR Slot %u, DT_CSBK, unable to decode the network CSBK", m_slot->m_slotNo);
return;
@ -555,7 +555,7 @@ void ControlSignaling::processNetwork(const data::Data & dmrData)
if (!handled) {
// regenerate the CSBK data
lc::CSBK::regenerate(data + 2U);
lc::CSBK::regenerate(data + 2U, dataType);
// regenerate the Slot Type
SlotType slotType;
@ -1341,11 +1341,13 @@ void ControlSignaling::writeRF_CSBK_Grant_LateEntry(uint32_t dstId, uint32_t src
}
/// <summary>
/// Helper to write a payload grant to a TSCC payload channel on the RF interface.
/// Helper to write a payload random access to a TSCC payload channel on the RF interface.
/// </summary>
/// <param name="dstId"></param>
/// <param name="srcId"></param>
void ControlSignaling::writeRF_CSBK_Payload_Grant(uint32_t dstId, uint32_t srcId, bool grp, bool voice)
/// <param name="grp"></param>
/// <param name="voice"></param>
void ControlSignaling::writeRF_CSBK_Payload_Activate(uint32_t dstId, uint32_t srcId, bool grp, bool voice)
{
std::unique_ptr<CSBK_P_GRANT> csbk = new_unique(CSBK_P_GRANT);
if (voice) {
@ -1365,6 +1367,8 @@ void ControlSignaling::writeRF_CSBK_Payload_Grant(uint32_t dstId, uint32_t srcId
}
}
csbk->setLastBlock(true);
csbk->setLogicalCh1(m_slot->m_channelNo);
csbk->setSlotNo(m_slot->m_slotNo);
@ -1372,11 +1376,16 @@ void ControlSignaling::writeRF_CSBK_Payload_Grant(uint32_t dstId, uint32_t srcId
csbk->setDstId(dstId);
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, %s, chNo = %u, slot = %u, srcId = %u, dstId = %u",
m_slot->m_slotNo, csbk->toString().c_str(), csbk->getLogicalCh1(), csbk->getSlotNo(), srcId, dstId);
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, %s, csbko = $%02X, chNo = %u, slot = %u, srcId = %u, dstId = %u",
m_slot->m_slotNo, csbk->toString().c_str(), csbk->getCSBKO(), csbk->getLogicalCh1(), csbk->getSlotNo(), srcId, dstId);
}
writeRF_CSBK(csbk.get());
m_slot->setShortLC_Payload(m_slot->m_siteData, 1U);
for (int i = 0; i < 3; i++) {
writeRF_CSBK(csbk.get(), false, true);
for (int i = 0; i < 3; i++)
writeRF_CSBK(csbk.get());
}
}
/// <summary>

@ -111,8 +111,8 @@ namespace dmr
/// <summary>Helper to write a TSCC late entry channel grant packet on the RF interface.</summary>
void writeRF_CSBK_Grant_LateEntry(uint32_t dstId, uint32_t srcId);
/// <summary>Helper to write a payload grant to a TSCC payload channel on the RF interface.</summary>
void writeRF_CSBK_Payload_Grant(uint32_t dstId, uint32_t srcId, bool grp, bool voice);
/// <summary>Helper to write a payload random access to a TSCC payload channel on the RF interface.</summary>
void writeRF_CSBK_Payload_Activate(uint32_t dstId, uint32_t srcId, bool grp, bool voice);
/// <summary>Helper to write a TSCC Aloha broadcast packet on the RF interface.</summary>
void writeRF_TSCC_Aloha();

@ -61,6 +61,8 @@ namespace nxdn
/// <summary>Returns a string that represents the current RCCH.</summary>
virtual std::string toString(bool isp = false);
/// <summary>Gets the flag indicating verbose log output.</summary>
static bool getVerbose() { return m_verbose; }
/// <summary>Sets the flag indicating verbose log output.</summary>
static void setVerbose(bool verbose) { m_verbose = verbose; }

@ -451,6 +451,11 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
if (!m_nxdn->m_enableControl)
return;
// disable verbose RCCH dumping during control data writes (if necessary)
bool rcchVerbose = lc::RCCH::getVerbose();
if (rcchVerbose)
lc::RCCH::setVerbose(false);
// don't add any frames if the queue is full
uint8_t len = NXDN_FRAME_LENGTH_BYTES + 2U;
uint32_t space = m_nxdn->m_txQueue.freeSpace();
@ -478,6 +483,8 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
n++;
i++;
} while (i <= seqCnt);
lc::RCCH::setVerbose(rcchVerbose);
}
/// <summary>

@ -80,6 +80,8 @@ namespace p25
/// <summary>Returns a string that represents the current TSBK.</summary>
virtual std::string toString(bool isp = false);
/// <summary>Gets the flag indicating verbose log output.</summary>
static bool getVerbose() { return m_verbose; }
/// <summary>Sets the flag indicating verbose log output.</summary>
static void setVerbose(bool verbose) { m_verbose = verbose; }
/// <summary>Sets the flag indicating CRC-errors should be warnings and not errors.</summary>

@ -1795,6 +1795,11 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
if (!m_p25->m_enableControl)
return;
// disable verbose tSBK dumping during control data writes (if necessary)
bool tsbkVerbose = lc::TSBK::getVerbose();
if (tsbkVerbose)
lc::TSBK::setVerbose(false);
if (m_convFallback) {
bool fallbackTx = (frameCnt % 253U) == 0U;
if (fallbackTx && n == 8U) {
@ -1935,6 +1940,8 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
// reset MBF count
m_mbfCnt = 0U;
}
lc::TSBK::setVerbose(tsbkVerbose);
}
/// <summary>

Loading…
Cancel
Save

Powered by TurnKey Linux.