add defines for various DMR service kinds; properly decode service kind and service data for a CSBKO_RAND; implement support logic to handle implementing logic to handle CSBKs; fix issue where DMR was not being set as the fixed state when DMR dedicated control was enabled; fix issue for DMR slot 2 where a NULL reference check was not performed for P25;

2.0-maint
Bryan Biedenkapp 3 years ago
parent 76a011c574
commit cbd3895490

@ -237,6 +237,21 @@ namespace dmr
const uint8_t MS_DENY_RSN_UNSUPPORTED_SVC = 0x00U;
// Random Access Service Kind
const uint8_t SVC_KIND_IND_VOICE_CALL = 0x00U; // Individual Voice Call
const uint8_t SVC_KIND_GRP_VOICE_CALL = 0x01U; // Group Voice Call
const uint8_t SVC_KIND_IND_DATA_CALL = 0x02U; // Individual Data Call
const uint8_t SVC_KIND_GRP_DATA_CALL = 0x03U; // Group Data Call
const uint8_t SVC_KIND_IND_UDT_DATA_CALL = 0x04U; // Individual UDT Short Data Call
const uint8_t SVC_KIND_GRP_UDT_DATA_CALL = 0x05U; // Group UDT Short Data Call
const uint8_t SVC_KIND_UDT_SHORT_POLL = 0x06U; // UDT Short Data Polling Service
const uint8_t SVC_KIND_STATUS_TRANSPORT = 0x07U; // Status Transport Service
const uint8_t SVC_KIND_CALL_DIVERSION = 0x08U; // Call Diversion Service
const uint8_t SVC_KIND_CALL_ANSWER = 0x09U; // Call Answer Service
const uint8_t SVC_KIND_SUPPLEMENTARY_SVC = 0x0DU; // Supplementary Service
const uint8_t SVC_KIND_REG_SVC = 0x0EU; // Registration Service
const uint8_t SVC_KIND_CANCEL_CALL = 0x0FU; // Cancel Call Service
// Broadcast Announcement Type(s)
const uint8_t BCAST_ANNC_ANN_WD_TSCC = 0x00U; // Announce-WD TSCC Channel
const uint8_t BCAST_ANNC_CALL_TIMER_PARMS = 0x01U; // Specify Call Timer Parameters

@ -153,8 +153,6 @@ bool CSBK::decode(const uint8_t* data)
{
case FID_DMRA:
m_GI = (((csbkValue >> 56) & 0xFFU) & 0x40U) == 0x40U; // Group/Individual Flag
m_dataContent = (((csbkValue >> 56) & 0xFFU) & 0x80U) == 0x80U; //
m_CBF = (uint8_t)((csbkValue >> 48) & 0xFFU); // Blocks to Follow
m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address
m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address
break;
@ -165,13 +163,15 @@ bool CSBK::decode(const uint8_t* data)
m_supplementData = (((csbkValue >> 56) & 0xFFU) & 0x20U) == 0x20U; // Supplementary Data Flag
m_broadcast = (((csbkValue >> 56) & 0xFFU) & 0x10U) == 0x10U; // Broadcast Flag
m_priority = (((csbkValue >> 56) & 0xFFU) & 0x03U); // Priority
m_serviceData = (uint8_t)((csbkValue >> 52U) & 0x0FU); // Service Data
m_serviceType = (uint8_t)((csbkValue >> 48U) & 0x0FU); // Service Type
m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address
m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address
break;
}
case CSBKO_EXT_FNCT:
m_dataContent = (((csbkValue >> 56) & 0xFFU) & 0x80U) == 0x80U; //
m_CBF = (uint8_t)((csbkValue >> 48) & 0xFFU); // Blocks to Follow
m_serviceType = (uint8_t)((csbkValue >> 48) & 0xFFU); // Service Type
m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address
m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address
break;
@ -463,6 +463,7 @@ CSBK::CSBK(SiteData siteData) :
m_priority(0U),
m_broadcast(false),
m_backoffNo(1U),
m_serviceData(0U),
m_serviceType(0U),
m_targetAddress(TGT_ADRS_TGID),
m_response(0U),

@ -109,8 +109,10 @@ namespace dmr
/// <summary>Backoff Number.</summary>
__PROPERTY(uint8_t, backoffNo, BackoffNo);
/// <summary>Service Data.</summary>
__PROPERTY(uint8_t, serviceData, ServiceData);
/// <summary>Service Type.</summary>
__PROPERTY(uint8_t, serviceType, serviceType);
__PROPERTY(uint8_t, serviceType, ServiceType);
/// <summary>Destination/Target address type.</summary>
__PROPERTY(uint8_t, targetAddress, TargetAddress);

@ -123,99 +123,111 @@ bool ControlSignaling::process(uint8_t* data, uint32_t len)
}
}
// Regenerate the CSBK data
csbk.encode(data + 2U);
// Regenerate the Slot Type
slotType.encode(data + 2U);
// Convert the Data Sync to be from the BS or MS as needed
Sync::addDMRDataSync(data + 2U, m_slot->m_duplex);
m_slot->m_rfSeqNo = 0U;
data[0U] = modem::TAG_DATA;
data[1U] = 0x00U;
if (m_slot->m_duplex)
m_slot->addFrame(data);
m_slot->writeNetwork(data, DT_CSBK, gi ? FLCO_GROUP : FLCO_PRIVATE, srcId, dstId);
if (m_verbose) {
switch (csbko) {
case CSBKO_UU_V_REQ:
bool handled = false;
switch (csbko) {
case CSBKO_UU_V_REQ:
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_UU_V_REQ (Unit to Unit Voice Service Request), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
break;
case CSBKO_UU_ANS_RSP:
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_UU_ANS_RSP (Unit to Unit Voice Service Answer Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
break;
case CSBKO_RAND:
if (csbk.getFID() == FID_DMRA) {
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_UU_V_REQ (Unit to Unit Voice Service Request), src = %u, dst = %s%u",
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_CALL_ALRT (Call Alert), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
break;
case CSBKO_UU_ANS_RSP:
::ActivityLog("DMR", true, "Slot %u call alert request from %u to %u", m_slot->m_slotNo, srcId, dstId);
} else {
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_UU_ANS_RSP (Unit to Unit Voice Service Answer Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), emerg = %u, prio = %u, serviceType = %02X, serviceData = %02X, srcId = %u, dstId = %u",
m_slot->m_slotNo, csbk.getEmergency(), csbk.getPriority(), csbk.getServiceType(), csbk.getServiceData(), csbk.getSrcId(), csbk.getDstId());
}
}
break;
case CSBKO_ACK_RSP:
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_ACK_RSP (Acknowledge Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
::ActivityLog("DMR", true, "Slot %u ack response from %u to %u", m_slot->m_slotNo, srcId, dstId);
break;
case CSBKO_EXT_FNCT:
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), op = $%02X, arg = %u, tgt = %u",
m_slot->m_slotNo, csbk.getServiceType(), dstId, srcId);
}
// generate activity log entry
switch (csbk.getServiceType()) {
case DMR_EXT_FNCT_CHECK:
::ActivityLog("DMR", true, "Slot %u radio check request from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
case CSBKO_NACK_RSP:
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_NACK_RSP (Negative Acknowledgment Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
case DMR_EXT_FNCT_INHIBIT:
::ActivityLog("DMR", true, "Slot %u radio inhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
case CSBKO_RAND:
if (csbk.getFID() == FID_DMRA) {
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_CALL_ALRT (Call Alert), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
::ActivityLog("DMR", true, "Slot %u call alert request from %u to %u", m_slot->m_slotNo, srcId, dstId);
}
case DMR_EXT_FNCT_UNINHIBIT:
::ActivityLog("DMR", true, "Slot %u radio uninhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
case CSBKO_ACK_RSP:
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_ACK_RSP (Acknowledge Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
::ActivityLog("DMR", true, "Slot %u ack response from %u to %u", m_slot->m_slotNo, srcId, dstId);
case DMR_EXT_FNCT_CHECK_ACK:
::ActivityLog("DMR", true, "Slot %u radio check response from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
case CSBKO_EXT_FNCT:
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), op = $%02X, arg = %u, tgt = %u",
m_slot->m_slotNo, csbk.getCBF(), dstId, srcId);
}
// generate activity log entry
if (csbk.getCBF() == DMR_EXT_FNCT_CHECK) {
::ActivityLog("DMR", true, "Slot %u radio check request from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
else if (csbk.getCBF() == DMR_EXT_FNCT_INHIBIT) {
::ActivityLog("DMR", true, "Slot %u radio inhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
else if (csbk.getCBF() == DMR_EXT_FNCT_UNINHIBIT) {
::ActivityLog("DMR", true, "Slot %u radio uninhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
else if (csbk.getCBF() == DMR_EXT_FNCT_CHECK_ACK) {
::ActivityLog("DMR", true, "Slot %u radio check response from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
else if (csbk.getCBF() == DMR_EXT_FNCT_INHIBIT_ACK) {
::ActivityLog("DMR", true, "Slot %u radio inhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
else if (csbk.getCBF() == DMR_EXT_FNCT_UNINHIBIT_ACK) {
::ActivityLog("DMR", true, "Slot %u radio uninhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
case DMR_EXT_FNCT_INHIBIT_ACK:
::ActivityLog("DMR", true, "Slot %u radio inhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
case CSBKO_PRECCSBK:
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_PRECCSBK (%s Preamble CSBK), toFollow = %u, src = %u, dst = %s%u",
m_slot->m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), srcId, gi ? "TG " : "", dstId);
}
case DMR_EXT_FNCT_UNINHIBIT_ACK:
::ActivityLog("DMR", true, "Slot %u radio uninhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
default:
LogWarning(LOG_RF, "DMR Slot %u, DT_CSBK, unhandled CSBK, csbko = $%02X, fid = $%02X", m_slot->m_slotNo, csbko, csbk.getFID());
LogWarning(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), unhandled op, op = $%02X", m_slot->m_slotNo, csbk.getServiceType());
break;
}
break;
case CSBKO_NACK_RSP:
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_NACK_RSP (Negative Acknowledgment Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
break;
case CSBKO_PRECCSBK:
if (m_verbose) {
LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_PRECCSBK (%s Preamble CSBK), toFollow = %u, src = %u, dst = %s%u",
m_slot->m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), srcId, gi ? "TG " : "", dstId);
}
break;
default:
LogWarning(LOG_RF, "DMR Slot %u, DT_CSBK, unhandled CSBK, csbko = $%02X, fid = $%02X", m_slot->m_slotNo, csbko, csbk.getFID());
// should we drop the CSBK and not repeat it?
break;
}
if (!handled) {
// Regenerate the CSBK data
csbk.encode(data + 2U);
// Regenerate the Slot Type
slotType.encode(data + 2U);
// Convert the Data Sync to be from the BS or MS as needed
Sync::addDMRDataSync(data + 2U, m_slot->m_duplex);
m_slot->m_rfSeqNo = 0U;
data[0U] = modem::TAG_DATA;
data[1U] = 0x00U;
if (m_slot->m_duplex)
m_slot->addFrame(data);
m_slot->writeNetwork(data, DT_CSBK, gi ? FLCO_GROUP : FLCO_PRIVATE, srcId, dstId);
}
return true;
@ -255,119 +267,131 @@ void ControlSignaling::processNetwork(const data::Data & dmrData)
CHECK_TG_HANG(dstId);
// Regenerate the CSBK data
csbk.encode(data + 2U);
// Regenerate the Slot Type
SlotType slotType;
slotType.decode(data + 2U);
slotType.setColorCode(m_slot->m_colorCode);
slotType.encode(data + 2U);
// Convert the Data Sync to be from the BS or MS as needed
Sync::addDMRDataSync(data + 2U, m_slot->m_duplex);
data[0U] = modem::TAG_DATA;
data[1U] = 0x00U;
if (csbko == CSBKO_PRECCSBK && csbk.getDataContent()) {
uint32_t cbf = NO_PREAMBLE_CSBK + csbk.getCBF() - 1U;
for (uint32_t i = 0U; i < NO_PREAMBLE_CSBK; i++, cbf--) {
// Change blocks to follow
csbk.setCBF(cbf);
// Regenerate the CSBK data
csbk.encode(data + 2U);
// Regenerate the Slot Type
SlotType slotType;
slotType.decode(data + 2U);
slotType.setColorCode(m_slot->m_colorCode);
slotType.encode(data + 2U);
// Convert the Data Sync to be from the BS or MS as needed
Sync::addDMRDataSync(data + 2U, m_slot->m_duplex);
m_slot->addFrame(data, true);
bool handled = false;
switch (csbko) {
case CSBKO_UU_V_REQ:
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_UU_V_REQ (Unit to Unit Voice Service Request), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
}
else
m_slot->addFrame(data, true);
if (m_verbose) {
switch (csbko) {
case CSBKO_UU_V_REQ:
break;
case CSBKO_UU_ANS_RSP:
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_UU_ANS_RSP (Unit to Unit Voice Service Answer Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
break;
case CSBKO_RAND:
if (csbk.getFID() == FID_DMRA) {
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_UU_V_REQ (Unit to Unit Voice Service Request), src = %u, dst = %s%u",
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_CALL_ALRT (Call Alert), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
break;
case CSBKO_UU_ANS_RSP:
::ActivityLog("DMR", false, "Slot %u call alert request from %u to %u", m_slot->m_slotNo, srcId, dstId);
} else {
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_UU_ANS_RSP (Unit to Unit Voice Service Answer Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), emerg = %u, prio = %u, serviceType = %02X, serviceData = %02X, srcId = %u, dstId = %u",
m_slot->m_slotNo, csbk.getEmergency(), csbk.getPriority(), csbk.getServiceType(), csbk.getServiceData(), csbk.getSrcId(), csbk.getDstId());
}
}
break;
case CSBKO_ACK_RSP:
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_ACK_RSP (Acknowledge Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
::ActivityLog("DMR", false, "Slot %u ack response from %u to %u", m_slot->m_slotNo, srcId, dstId);
break;
case CSBKO_EXT_FNCT:
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), op = $%02X, arg = %u, tgt = %u",
m_slot->m_slotNo, csbk.getCBF(), dstId, srcId);
}
// generate activity log entry
switch (csbk.getServiceType()) {
case DMR_EXT_FNCT_CHECK:
::ActivityLog("DMR", false, "Slot %u radio check request from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
case CSBKO_NACK_RSP:
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_NACK_RSP (Negative Acknowledgment Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
case DMR_EXT_FNCT_INHIBIT:
::ActivityLog("DMR", false, "Slot %u radio inhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
case CSBKO_RAND:
if (csbk.getFID() == FID_DMRA) {
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_CALL_ALRT (Call Alert), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
::ActivityLog("DMR", false, "Slot %u call alert request from %u to %u", m_slot->m_slotNo, srcId, dstId);
}
case DMR_EXT_FNCT_UNINHIBIT:
::ActivityLog("DMR", false, "Slot %u radio uninhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
case CSBKO_ACK_RSP:
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_ACK_RSP (Acknowledge Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
::ActivityLog("DMR", false, "Slot %u ack response from %u to %u", m_slot->m_slotNo, srcId, dstId);
case DMR_EXT_FNCT_CHECK_ACK:
::ActivityLog("DMR", false, "Slot %u radio check response from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
case CSBKO_EXT_FNCT:
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), op = $%02X, arg = %u, tgt = %u",
m_slot->m_slotNo, csbk.getCBF(), dstId, srcId);
}
// generate activity log entry
if (csbk.getCBF() == DMR_EXT_FNCT_CHECK) {
::ActivityLog("DMR", false, "Slot %u radio check request from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
else if (csbk.getCBF() == DMR_EXT_FNCT_INHIBIT) {
::ActivityLog("DMR", false, "Slot %u radio inhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
else if (csbk.getCBF() == DMR_EXT_FNCT_UNINHIBIT) {
::ActivityLog("DMR", false, "Slot %u radio uninhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
else if (csbk.getCBF() == DMR_EXT_FNCT_CHECK_ACK) {
::ActivityLog("DMR", false, "Slot %u radio check response from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
else if (csbk.getCBF() == DMR_EXT_FNCT_INHIBIT_ACK) {
::ActivityLog("DMR", false, "Slot %u radio inhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
else if (csbk.getCBF() == DMR_EXT_FNCT_UNINHIBIT_ACK) {
::ActivityLog("DMR", false, "Slot %u radio uninhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
}
case DMR_EXT_FNCT_INHIBIT_ACK:
::ActivityLog("DMR", false, "Slot %u radio inhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
case CSBKO_PRECCSBK:
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_PRECCSBK (%s Preamble CSBK), toFollow = %u, src = %u, dst = %s%u",
m_slot->m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), srcId, gi ? "TG " : "", dstId);
}
case DMR_EXT_FNCT_UNINHIBIT_ACK:
::ActivityLog("DMR", false, "Slot %u radio uninhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
break;
default:
LogWarning(LOG_NET, "DMR Slot %u, DT_CSBK, unhandled network CSBK, csbko = $%02X, fid = $%02X", m_slot->m_slotNo, csbko, csbk.getFID());
LogWarning(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), unhandled op, op = $%02X", m_slot->m_slotNo, csbk.getServiceType());
break;
}
break;
case CSBKO_NACK_RSP:
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_NACK_RSP (Negative Acknowledgment Response), src = %u, dst = %s%u",
m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
}
break;
case CSBKO_PRECCSBK:
if (m_verbose) {
LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_PRECCSBK (%s Preamble CSBK), toFollow = %u, src = %u, dst = %s%u",
m_slot->m_slotNo, csbk.getDataContent() ? "Data" : "CSBK", csbk.getCBF(), srcId, gi ? "TG " : "", dstId);
}
break;
default:
LogWarning(LOG_NET, "DMR Slot %u, DT_CSBK, unhandled network CSBK, csbko = $%02X, fid = $%02X", m_slot->m_slotNo, csbko, csbk.getFID());
// should we drop the CSBK and not repeat it?
break;
}
if (!handled) {
// Regenerate the CSBK data
csbk.encode(data + 2U);
// Regenerate the Slot Type
SlotType slotType;
slotType.decode(data + 2U);
slotType.setColorCode(m_slot->m_colorCode);
slotType.encode(data + 2U);
// Convert the Data Sync to be from the BS or MS as needed
Sync::addDMRDataSync(data + 2U, m_slot->m_duplex);
data[0U] = modem::TAG_DATA;
data[1U] = 0x00U;
if (csbko == CSBKO_PRECCSBK && csbk.getDataContent()) {
uint32_t cbf = NO_PREAMBLE_CSBK + csbk.getCBF() - 1U;
for (uint32_t i = 0U; i < NO_PREAMBLE_CSBK; i++, cbf--) {
// Change blocks to follow
csbk.setCBF(cbf);
// Regenerate the CSBK data
csbk.encode(data + 2U);
// Regenerate the Slot Type
SlotType slotType;
slotType.decode(data + 2U);
slotType.setColorCode(m_slot->m_colorCode);
slotType.encode(data + 2U);
// Convert the Data Sync to be from the BS or MS as needed
Sync::addDMRDataSync(data + 2U, m_slot->m_duplex);
m_slot->addFrame(data, true);
}
}
else
m_slot->addFrame(data, true);
}
}
else {

@ -411,6 +411,11 @@ int Host::run()
LogInfo(" TX Hang: %us", txHang);
LogInfo(" Queue Size: %u (%u bytes)", queueSize, queueSizeBytes);
// forcibly enable beacons when TSCC is enabled but not in dedicated mode
if (m_dmrTSCCData && !dmrCtrlChannel && !m_dmrBeacons) {
m_dmrBeacons = true;
}
LogInfo(" Roaming Beacons: %s", m_dmrBeacons ? "yes" : "no");
if (m_dmrBeacons) {
uint32_t dmrBeaconInterval = dmrProtocol["beacons"]["interval"].as<uint32_t>(60U);
@ -566,17 +571,17 @@ int Host::run()
bool nxdnVerbose = nxdnProtocol["verbose"].as<bool>(true);
bool nxdnDebug = nxdnProtocol["debug"].as<bool>(false);
// clamp queue size to no less then 24 and no greater the 100
if (queueSize <= 24U) {
LogWarning(LOG_HOST, "NXDN queue size must be greater then 24 frames, defaulting to 24 frames!");
queueSize = 24U;
// clamp queue size to no less then 5 and no greater the 100 frames
if (queueSize <= 10U) {
LogWarning(LOG_HOST, "NXDN queue size must be greater then 10 frames, defaulting to 10 frames!");
queueSize = 10U;
}
if (queueSize > 100U) {
LogWarning(LOG_HOST, "NXDN queue size must be less then 100 frames, defaulting to 100 frames!");
queueSize = 100U;
}
if (queueSize > 60U) {
LogWarning(LOG_HOST, "NXDN queue size is excessive, >60 frames!");
if (queueSize > 30U) {
LogWarning(LOG_HOST, "NXDN queue size is excessive, >30 frames!");
}
uint32_t queueSizeBytes = queueSize * (nxdn::NXDN_FRAME_LENGTH_BYTES * 5U);
@ -725,21 +730,8 @@ int Host::run()
bool killed = false;
if (!g_killed) {
// fixed more or P25 control channel will force a state change
if (m_fixedMode || m_p25CtrlChannel) {
#if defined(ENABLE_P25)
if (m_p25CtrlChannel) {
m_fixedMode = true;
setState(STATE_P25);
}
#endif // defined(ENABLE_P25)
#if defined(ENABLE_NXDN)
if (m_nxdnCtrlChannel) {
m_fixedMode = true;
setState(STATE_NXDN);
}
#endif // defined(ENABLE_NXDN)
// fixed mode will force a state change
if (m_fixedMode) {
#if defined(ENABLE_DMR)
if (dmr != NULL)
setState(STATE_DMR);
@ -754,6 +746,12 @@ int Host::run()
#endif // defined(ENABLE_NXDN)
}
else {
#if defined(ENABLE_DMR)
if (m_dmrCtrlChannel) {
m_fixedMode = true;
setState(STATE_DMR);
}
#endif // defined(ENABLE_DMR)
#if defined(ENABLE_P25)
if (m_p25CtrlChannel) {
m_fixedMode = true;
@ -976,9 +974,11 @@ int Host::run()
}
// if there is a P25 CC running; halt the CC
if (p25->getCCRunning() && !p25->getCCHalted()) {
p25->setCCHalted(true);
INTERRUPT_P25_CONTROL;
if (p25 != NULL) {
if (p25->getCCRunning() && !p25->getCCHalted()) {
p25->setCCHalted(true);
INTERRUPT_P25_CONTROL;
}
}
// if there is a NXDN CC running; halt the CC

Loading…
Cancel
Save

Powered by TurnKey Linux.