add support for the control byte on P25 TDUs, this implements a required remote grant demand request allowing remote network applications to get a channel grant before sending traffic;

pull/39/head
Bryan Biedenkapp 3 years ago
parent 4f6fcd421b
commit ab1c84243e

@ -9,6 +9,7 @@ daemon: true
# #
# Logging Configuration # Logging Configuration
#
# Logging Levels: # Logging Levels:
# 1 - Debug # 1 - Debug
# 2 - Message # 2 - Message
@ -392,6 +393,17 @@ system:
# DMR/P25/NXDN Site ID. # DMR/P25/NXDN Site ID.
siteId: 1 siteId: 1
#
# CW ID Configuration
#
cwId:
# Flag indicating whether or not CWID is enabled.
enable: true
# Amount of time between CWID transmissions. (minutes)
time: 15
# Callsign to be transmitted.
callsign: ABCD123
# #
# Modem Configuration # Modem Configuration
# #
@ -525,17 +537,6 @@ system:
# Flag indicating whether or not debug logging is enabled. # Flag indicating whether or not debug logging is enabled.
debug: false debug: false
#
# CW ID Configuration
#
cwId:
# Flag indicating whether or not CWID is enabled.
enable: true
# Amount of time between CWID transmissions. (minutes)
time: 15
# Callsign to be transmitted.
callsign: ABCD123
# #
# Channel Identity Table Configuration # Channel Identity Table Configuration
# #

@ -645,6 +645,8 @@ UInt8Array BaseNetwork::createDMR_Message(uint32_t& length, const uint32_t strea
uint32_t slotNo = data.getSlotNo(); uint32_t slotNo = data.getSlotNo();
buffer[14U] = 0U; // Control Bits
// Individual slot disabling // Individual slot disabling
if (slotNo == 1U && !m_slot1) if (slotNo == 1U && !m_slot1)
return nullptr; return nullptr;
@ -685,52 +687,54 @@ UInt8Array BaseNetwork::createDMR_Message(uint32_t& length, const uint32_t strea
/// <summary> /// <summary>
/// Creates an P25 frame message header. /// Creates an P25 frame message header.
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="buffer"></param>
/// <param name="duid"></param> /// <param name="duid"></param>
/// <param name="control"></param> /// <param name="control"></param>
/// <param name="lsd"></param> /// <param name="lsd"></param>
/// <param name="frameType"></param> /// <param name="frameType"></param>
void BaseNetwork::createP25_MessageHdr(uint8_t* data, uint8_t duid, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd, void BaseNetwork::createP25_MessageHdr(uint8_t* buffer, uint8_t duid, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd,
uint8_t frameType) uint8_t frameType)
{ {
assert(data != nullptr); assert(buffer != nullptr);
// construct P25 message header // construct P25 message header
::memcpy(data + 0U, TAG_P25_DATA, 4U); ::memcpy(buffer + 0U, TAG_P25_DATA, 4U);
data[4U] = control.getLCO(); // LCO buffer[4U] = control.getLCO(); // LCO
uint32_t srcId = control.getSrcId(); // Source Address uint32_t srcId = control.getSrcId(); // Source Address
__SET_UINT16(srcId, data, 5U); __SET_UINT16(srcId, buffer, 5U);
uint32_t dstId = control.getDstId(); // Target Address uint32_t dstId = control.getDstId(); // Target Address
__SET_UINT16(dstId, data, 8U); __SET_UINT16(dstId, buffer, 8U);
uint16_t sysId = control.getSiteData().sysId(); // System ID uint16_t sysId = control.getSiteData().sysId(); // System ID
data[11U] = (sysId >> 8) & 0xFFU; buffer[11U] = (sysId >> 8) & 0xFFU;
data[12U] = (sysId >> 0) & 0xFFU; buffer[12U] = (sysId >> 0) & 0xFFU;
data[15U] = control.getMFId(); // MFId buffer[14U] = 0U; // Control Bits
buffer[15U] = control.getMFId(); // MFId
uint32_t netId = control.getSiteData().netId(); // Network ID uint32_t netId = control.getSiteData().netId(); // Network ID
__SET_UINT16(netId, data, 16U); __SET_UINT16(netId, buffer, 16U);
data[20U] = lsd.getLSD1(); // LSD 1 buffer[20U] = lsd.getLSD1(); // LSD 1
data[21U] = lsd.getLSD2(); // LSD 2 buffer[21U] = lsd.getLSD2(); // LSD 2
data[22U] = duid; // DUID buffer[22U] = duid; // DUID
if (frameType != p25::P25_FT_TERMINATOR) { if (frameType != p25::P25_FT_TERMINATOR) {
data[180U] = frameType; // DVM Frame Type buffer[180U] = frameType; // DVM Frame Type
} }
// is this the first frame of a call? // is this the first frame of a call?
if (frameType == p25::P25_FT_HDU_VALID) { if (frameType == p25::P25_FT_HDU_VALID) {
data[181U] = control.getAlgId(); // Algorithm ID buffer[181U] = control.getAlgId(); // Algorithm ID
uint32_t kid = control.getKId(); uint32_t kid = control.getKId();
data[182U] = (kid >> 8) & 0xFFU; // Key ID buffer[182U] = (kid >> 8) & 0xFFU; // Key ID
data[183U] = (kid >> 0) & 0xFFU; buffer[183U] = (kid >> 0) & 0xFFU;
// copy MI data // copy MI data
uint8_t mi[p25::P25_MI_LENGTH_BYTES]; uint8_t mi[p25::P25_MI_LENGTH_BYTES];
@ -742,7 +746,7 @@ void BaseNetwork::createP25_MessageHdr(uint8_t* data, uint8_t duid, const p25::l
} }
for (uint8_t i = 0; i < p25::P25_MI_LENGTH_BYTES; i++) { for (uint8_t i = 0; i < p25::P25_MI_LENGTH_BYTES; i++) {
data[184U + i] = mi[i]; // Message Indicator buffer[184U + i] = mi[i]; // Message Indicator
} }
} }
} }
@ -1043,6 +1047,8 @@ UInt8Array BaseNetwork::createNXDN_Message(uint32_t& length, const nxdn::lc::RTC
uint32_t dstId = lc.getDstId(); // Target Address uint32_t dstId = lc.getDstId(); // Target Address
__SET_UINT16(dstId, buffer, 8U); __SET_UINT16(dstId, buffer, 8U);
buffer[14U] = 0U; // Control Bits
buffer[15U] |= lc.getGroup() ? 0x00U : 0x40U; // Group buffer[15U] |= lc.getGroup() ? 0x00U : 0x40U; // Group
// pack raw NXDN message bytes // pack raw NXDN message bytes

@ -275,7 +275,7 @@ namespace network
UInt8Array createDMR_Message(uint32_t& length, const uint32_t streamId, const dmr::data::Data& data); UInt8Array createDMR_Message(uint32_t& length, const uint32_t streamId, const dmr::data::Data& data);
/// <summary>Creates an P25 frame message header.</summary> /// <summary>Creates an P25 frame message header.</summary>
void createP25_MessageHdr(uint8_t* data, uint8_t duid, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd, void createP25_MessageHdr(uint8_t* buffer, uint8_t duid, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd,
uint8_t frameType = p25::P25_FT_DATA_UNIT); uint8_t frameType = p25::P25_FT_DATA_UNIT);
/// <summary>Creates an P25 LDU1 frame message.</summary> /// <summary>Creates an P25 LDU1 frame message.</summary>

@ -1077,6 +1077,8 @@ void Control::processNetwork()
return; return;
} }
bool grantDemand = (buffer[14U] & 0x80U) == 0x80U;
// process network message header // process network message header
uint8_t duid = buffer[22U]; uint8_t duid = buffer[22U];
uint8_t MFId = buffer[15U]; uint8_t MFId = buffer[15U];
@ -1218,11 +1220,30 @@ void Control::processNetwork()
} }
break; break;
} }
ret = m_voice->processNetwork(data.get(), frameLength, control, lsd, duid, frameType);
if (m_dedicatedControl && m_voiceOnControl) {
ret = m_voice->processNetwork(data.get(), frameLength, control, lsd, duid, frameType);
}
break; break;
case P25_DUID_TDU: case P25_DUID_TDU:
case P25_DUID_TDULC: case P25_DUID_TDULC:
// is this an TDU with a grant demand?
if (duid == P25_DUID_TDU && grantDemand) {
uint8_t serviceOptions = (control.getEmergency() ? 0x80U : 0x00U) + // Emergency Flag
(control.getEncrypted() ? 0x40U : 0x00U) + // Encrypted Flag
(control.getPriority() & 0x07U); // Priority
if (m_verbose) {
LogMessage(LOG_NET, P25_TSDU_STR " remote grant demand, srcId = %u, dstId = %u", srcId, dstId);
}
if (!m_trunk->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, true, true)) {
LogError(LOG_NET, P25_TSDU_STR " call failure, network call not granted, dstId = %u", dstId);
return;
}
}
m_voice->processNetwork(data.get(), frameLength, control, lsd, duid, frameType); m_voice->processNetwork(data.get(), frameLength, control, lsd, duid, frameType);
break; break;

Loading…
Cancel
Save

Powered by TurnKey Linux.