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; 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) // Broadcast Announcement Type(s)
const uint8_t BCAST_ANNC_ANN_WD_TSCC = 0x00U; // Announce-WD TSCC Channel 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 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: case FID_DMRA:
m_GI = (((csbkValue >> 56) & 0xFFU) & 0x40U) == 0x40U; // Group/Individual Flag 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_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address
m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address
break; break;
@ -165,13 +163,15 @@ bool CSBK::decode(const uint8_t* data)
m_supplementData = (((csbkValue >> 56) & 0xFFU) & 0x20U) == 0x20U; // Supplementary Data Flag m_supplementData = (((csbkValue >> 56) & 0xFFU) & 0x20U) == 0x20U; // Supplementary Data Flag
m_broadcast = (((csbkValue >> 56) & 0xFFU) & 0x10U) == 0x10U; // Broadcast Flag m_broadcast = (((csbkValue >> 56) & 0xFFU) & 0x10U) == 0x10U; // Broadcast Flag
m_priority = (((csbkValue >> 56) & 0xFFU) & 0x03U); // Priority 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_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address
m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address
break; break;
} }
case CSBKO_EXT_FNCT: case CSBKO_EXT_FNCT:
m_dataContent = (((csbkValue >> 56) & 0xFFU) & 0x80U) == 0x80U; // 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_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address
m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address
break; break;
@ -463,6 +463,7 @@ CSBK::CSBK(SiteData siteData) :
m_priority(0U), m_priority(0U),
m_broadcast(false), m_broadcast(false),
m_backoffNo(1U), m_backoffNo(1U),
m_serviceData(0U),
m_serviceType(0U), m_serviceType(0U),
m_targetAddress(TGT_ADRS_TGID), m_targetAddress(TGT_ADRS_TGID),
m_response(0U), m_response(0U),

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

@ -123,99 +123,111 @@ bool ControlSignaling::process(uint8_t* data, uint32_t len)
} }
} }
// Regenerate the CSBK data bool handled = false;
csbk.encode(data + 2U); switch (csbko) {
case CSBKO_UU_V_REQ:
// Regenerate the Slot Type if (m_verbose) {
slotType.encode(data + 2U); 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);
// Convert the Data Sync to be from the BS or MS as needed }
Sync::addDMRDataSync(data + 2U, m_slot->m_duplex); break;
case CSBKO_UU_ANS_RSP:
m_slot->m_rfSeqNo = 0U; 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",
data[0U] = modem::TAG_DATA; m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
data[1U] = 0x00U; }
break;
if (m_slot->m_duplex) case CSBKO_RAND:
m_slot->addFrame(data); if (csbk.getFID() == FID_DMRA) {
m_slot->writeNetwork(data, DT_CSBK, gi ? FLCO_GROUP : FLCO_PRIVATE, srcId, dstId);
if (m_verbose) {
switch (csbko) {
case CSBKO_UU_V_REQ:
if (m_verbose) { 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); 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) { 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", 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, srcId, gi ? "TG " : "", dstId); 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; break;
case CSBKO_NACK_RSP: case DMR_EXT_FNCT_INHIBIT:
if (m_verbose) { ::ActivityLog("DMR", true, "Slot %u radio inhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
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; break;
case CSBKO_RAND: case DMR_EXT_FNCT_UNINHIBIT:
if (csbk.getFID() == FID_DMRA) { ::ActivityLog("DMR", true, "Slot %u radio uninhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
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);
}
break; break;
case CSBKO_ACK_RSP: case DMR_EXT_FNCT_CHECK_ACK:
if (m_verbose) { ::ActivityLog("DMR", true, "Slot %u radio check response from %u to %u", m_slot->m_slotNo, dstId, srcId);
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; break;
case CSBKO_EXT_FNCT: case DMR_EXT_FNCT_INHIBIT_ACK:
if (m_verbose) { ::ActivityLog("DMR", true, "Slot %u radio inhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
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);
}
break; break;
case CSBKO_PRECCSBK: case DMR_EXT_FNCT_UNINHIBIT_ACK:
if (m_verbose) { ::ActivityLog("DMR", true, "Slot %u radio uninhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
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; break;
default: 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;
} }
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; return true;
@ -255,119 +267,131 @@ void ControlSignaling::processNetwork(const data::Data & dmrData)
CHECK_TG_HANG(dstId); CHECK_TG_HANG(dstId);
// Regenerate the CSBK data bool handled = false;
csbk.encode(data + 2U); switch (csbko) {
case CSBKO_UU_V_REQ:
// Regenerate the Slot Type if (m_verbose) {
SlotType slotType; LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_UU_V_REQ (Unit to Unit Voice Service Request), src = %u, dst = %s%u",
slotType.decode(data + 2U); m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
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);
} }
} break;
else case CSBKO_UU_ANS_RSP:
m_slot->addFrame(data, true); 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",
if (m_verbose) { m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId);
switch (csbko) { }
case CSBKO_UU_V_REQ: break;
case CSBKO_RAND:
if (csbk.getFID() == FID_DMRA) {
if (m_verbose) { 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); 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) { 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", 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, srcId, gi ? "TG " : "", dstId); 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; break;
case CSBKO_NACK_RSP: case DMR_EXT_FNCT_INHIBIT:
if (m_verbose) { ::ActivityLog("DMR", false, "Slot %u radio inhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
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; break;
case CSBKO_RAND: case DMR_EXT_FNCT_UNINHIBIT:
if (csbk.getFID() == FID_DMRA) { ::ActivityLog("DMR", false, "Slot %u radio uninhibit request from %u to %u", m_slot->m_slotNo, dstId, srcId);
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);
}
break; break;
case CSBKO_ACK_RSP: case DMR_EXT_FNCT_CHECK_ACK:
if (m_verbose) { ::ActivityLog("DMR", false, "Slot %u radio check response from %u to %u", m_slot->m_slotNo, dstId, srcId);
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; break;
case CSBKO_EXT_FNCT: case DMR_EXT_FNCT_INHIBIT_ACK:
if (m_verbose) { ::ActivityLog("DMR", false, "Slot %u radio inhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
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);
}
break; break;
case CSBKO_PRECCSBK: case DMR_EXT_FNCT_UNINHIBIT_ACK:
if (m_verbose) { ::ActivityLog("DMR", false, "Slot %u radio uninhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId);
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; break;
default: 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;
} }
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 { else {

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

Loading…
Cancel
Save

Powered by TurnKey Linux.