diff --git a/configs/talkgroup_rules.example.yml b/configs/talkgroup_rules.example.yml
index e112281d..ed827ef2 100644
--- a/configs/talkgroup_rules.example.yml
+++ b/configs/talkgroup_rules.example.yml
@@ -16,9 +16,6 @@ groupVoice:
config:
# Flag indicating whether this talkgroup is active or not.
active: true
- # Flag indicating whether this talkgroup requires affiliations to repeat traffic.
- affiliated: false
-
# List of peer IDs included for this talkgroup (peers listed here will be selected for traffic).
inclusion: []
# List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic).
@@ -40,11 +37,8 @@ groupVoice:
config:
# Flag indicating whether this talkgroup is active or not.
active: true
- # Flag indicating whether this talkgroup requires affiliations to repeat traffic.
- affiliated: false
# Flag indicating whether or not this talkgroup is a parrot talkgroup.
parrot: true
-
# List of peer IDs included for this talkgroup (peers listed here will be selected for traffic).
inclusion: []
# List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic).
@@ -66,9 +60,6 @@ groupVoice:
config:
# Flag indicating whether this talkgroup is active or not.
active: true
- # Flag indicating whether this talkgroup requires affiliations to repeat traffic.
- affiliated: false
-
# List of peer IDs included for this talkgroup (peers listed here will be selected for traffic).
inclusion: []
# List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic).
@@ -90,9 +81,6 @@ groupVoice:
config:
# Flag indicating whether this talkgroup is active or not.
active: true
- # Flag indicating whether this talkgroup requires affiliations to repeat traffic.
- affiliated: false
-
# List of peer IDs included for this talkgroup (peers listed here will be selected for traffic).
inclusion: []
# List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic).
@@ -114,9 +102,6 @@ groupVoice:
config:
# Flag indicating whether this talkgroup is active or not.
active: true
- # Flag indicating whether this talkgroup requires affiliations to repeat traffic.
- affiliated: false
-
# List of peer IDs included for this talkgroup (peers listed here will be selected for traffic).
inclusion: []
# List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic).
diff --git a/src/dmr/Control.cpp b/src/dmr/Control.cpp
index f729d481..9c19a9f2 100644
--- a/src/dmr/Control.cpp
+++ b/src/dmr/Control.cpp
@@ -652,6 +652,7 @@ void Control::processNetwork()
data::Data data;
+ // process network message header
uint8_t seqNo = buffer[4U];
uint32_t srcId = __GET_UINT16(buffer, 5U);
@@ -695,6 +696,7 @@ void Control::processNetwork()
LogDebug(LOG_NET, "DMR, seqNo = %u, srcId = %u, dstId = %u, flco = $%02X, slotNo = %u, len = %u", seqNo, srcId, dstId, flco, slotNo, length);
}
+ // process raw DMR data bytes
if (dataSync) {
uint8_t dataType = buffer[15U] & 0x0FU;
data.setData(buffer.get() + 20U);
@@ -713,6 +715,7 @@ void Control::processNetwork()
data.setN(n);
}
+ // forward onto the specific slot for final processing and delivery
switch (slotNo) {
case 1U:
m_slot1->processNetwork(data);
diff --git a/src/lookups/TalkgroupRulesLookup.cpp b/src/lookups/TalkgroupRulesLookup.cpp
index 47f2d9f8..a2e6a08f 100644
--- a/src/lookups/TalkgroupRulesLookup.cpp
+++ b/src/lookups/TalkgroupRulesLookup.cpp
@@ -319,7 +319,6 @@ bool TalkgroupRulesLookup::load()
uint32_t tgId = groupVoice.source().tgId();
uint8_t tgSlot = groupVoice.source().tgSlot();
bool active = groupVoice.config().active();
- bool affiliated = groupVoice.config().affiliated();
bool parrot = groupVoice.config().parrot();
uint32_t incCount = groupVoice.config().inclusion().size();
@@ -329,7 +328,7 @@ bool TalkgroupRulesLookup::load()
::LogWarning(LOG_HOST, "Talkgroup (%s) defines both inclusions and exclusions! Inclusions take precedence and exclusions will be ignored.", groupName.c_str());
}
- ::LogInfoEx(LOG_HOST, "Talkgroup NAME: %s SRC_TGID: %u SRC_TS: %u ACTIVE: %u AFFILIATED: %u PARROT: %u INCLUSIONS: %u EXCLUSIONS: %u", groupName.c_str(), tgId, tgSlot, active, affiliated, parrot, incCount, excCount);
+ ::LogInfoEx(LOG_HOST, "Talkgroup NAME: %s SRC_TGID: %u SRC_TS: %u ACTIVE: %u PARROT: %u INCLUSIONS: %u EXCLUSIONS: %u", groupName.c_str(), tgId, tgSlot, active, parrot, incCount, excCount);
}
}
m_mutex.unlock();
diff --git a/src/lookups/TalkgroupRulesLookup.h b/src/lookups/TalkgroupRulesLookup.h
index f87eb3d0..77bdb500 100644
--- a/src/lookups/TalkgroupRulesLookup.h
+++ b/src/lookups/TalkgroupRulesLookup.h
@@ -89,7 +89,6 @@ namespace lookups
/// Initializes a new insatnce of the TalkgroupRuleConfig class.
TalkgroupRuleConfig() :
m_active(false),
- m_affiliated(false),
m_parrot(false),
m_inclusion(),
m_exclusion()
@@ -102,7 +101,6 @@ namespace lookups
TalkgroupRuleConfig()
{
m_active = node["active"].as(false);
- m_affiliated = node["affiliated"].as(false);
m_parrot = node["parrot"].as(false);
yaml::Node& inclusionList = node["inclusion"];
@@ -127,7 +125,6 @@ namespace lookups
{
if (this != &data) {
m_active = data.m_active;
- m_affiliated = data.m_affiliated;
m_parrot = data.m_parrot;
m_inclusion = data.m_inclusion;
m_exclusion = data.m_exclusion;
@@ -139,8 +136,6 @@ namespace lookups
public:
/// Flag indicating whether the rule is active.
__PROPERTY_PLAIN(bool, active, active);
- /// Flag indicating whether or not affiliations are requires to repeat traffic.
- __PROPERTY_PLAIN(bool, affiliated, affiliated);
/// Flag indicating whether or not the talkgroup is a parrot.
__PROPERTY_PLAIN(bool, parrot, parrot);
/// List of peer IDs included by this rule.
diff --git a/src/network/BaseNetwork.cpp b/src/network/BaseNetwork.cpp
index f4318671..33c0c21c 100644
--- a/src/network/BaseNetwork.cpp
+++ b/src/network/BaseNetwork.cpp
@@ -645,6 +645,7 @@ UInt8Array BaseNetwork::createDMR_Message(uint32_t& length, const uint32_t strea
uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
+ // construct DMR message header
::memcpy(buffer + 0U, TAG_DMR_DATA, 4U);
uint32_t srcId = data.getSrcId(); // Source Address
@@ -679,11 +680,12 @@ UInt8Array BaseNetwork::createDMR_Message(uint32_t& length, const uint32_t strea
buffer[4U] = data.getSeqNo(); // Sequence Number
- data.getData(buffer + 20U);
-
buffer[53U] = data.getBER(); // Bit Error Rate
buffer[54U] = data.getRSSI(); // RSSI
+ // pack raw DMR message bytes
+ data.getData(buffer + 20U);
+
if (m_debug)
Utils::dump(1U, "Network Message, DMR", buffer, (DMR_PACKET_SIZE + PACKET_PAD));
@@ -692,51 +694,46 @@ UInt8Array BaseNetwork::createDMR_Message(uint32_t& length, const uint32_t strea
}
///
-/// Creates an P25 LDU1 frame message.
+/// Creates an P25 frame message header.
///
-///
+///
+///
///
///
-///
///
-///
-UInt8Array BaseNetwork::createP25_LDU1Message(uint32_t& length, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd,
- const uint8_t* data, uint8_t frameType)
+void BaseNetwork::createP25_MessageHdr(uint8_t* data, uint8_t duid, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd,
+ uint8_t frameType)
{
assert(data != nullptr);
- p25::dfsi::LC dfsiLC = p25::dfsi::LC(control, lsd);
+ // construct P25 message header
+ ::memcpy(data + 0U, TAG_P25_DATA, 4U);
- uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
- ::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
-
- ::memcpy(buffer + 0U, TAG_P25_DATA, 4U);
-
- buffer[4U] = control.getLCO(); // LCO
+ data[4U] = control.getLCO(); // LCO
uint32_t srcId = control.getSrcId(); // Source Address
- __SET_UINT16(srcId, buffer, 5U);
+ __SET_UINT16(srcId, data, 5U);
uint32_t dstId = control.getDstId(); // Target Address
- __SET_UINT16(dstId, buffer, 8U);
+ __SET_UINT16(dstId, data, 8U);
- buffer[15U] = control.getMFId(); // MFId
+ data[15U] = control.getMFId(); // MFId
- buffer[20U] = lsd.getLSD1(); // LSD 1
- buffer[21U] = lsd.getLSD2(); // LSD 2
+ data[20U] = lsd.getLSD1(); // LSD 1
+ data[21U] = lsd.getLSD2(); // LSD 2
- buffer[22U] = p25::P25_DUID_LDU1; // DUID
+ data[22U] = duid; // DUID
- buffer[180U] = frameType; // DVM Frame Type
+ data[180U] = frameType; // DVM Frame Type
// is this the first frame of a call?
if (frameType == p25::P25_FT_HDU_VALID) {
- buffer[180U] = 0x01U; // First LDU1 Marker
- buffer[181U] = control.getAlgId(); // Algorithm ID
+ data[180U] = 0x01U; // First LDU1 Marker
+ data[181U] = control.getAlgId(); // Algorithm ID
uint32_t kid = control.getKId();
- buffer[182U] = (kid >> 8) & 0xFFU; // Key ID
- buffer[183U] = (kid >> 0) & 0xFFU;
+ data[182U] = (kid >> 8) & 0xFFU; // Key ID
+ data[183U] = (kid >> 0) & 0xFFU;
// copy MI data
uint8_t mi[p25::P25_MI_LENGTH_BYTES];
@@ -748,57 +745,81 @@ UInt8Array BaseNetwork::createP25_LDU1Message(uint32_t& length, const p25::lc::L
}
for (uint8_t i = 0; i < p25::P25_MI_LENGTH_BYTES; i++) {
- buffer[184U + i] = mi[i]; // Message Indicator
+ data[184U + i] = mi[i]; // Message Indicator
}
}
+}
+
+///
+/// Creates an P25 LDU1 frame message.
+///
+///
+///
+///
+///
+///
+///
+UInt8Array BaseNetwork::createP25_LDU1Message(uint32_t& length, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd,
+ const uint8_t* data, uint8_t frameType)
+{
+ assert(data != nullptr);
+
+ p25::dfsi::LC dfsiLC = p25::dfsi::LC(control, lsd);
+
+ uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
+ ::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
+
+ // construct P25 message header
+ createP25_MessageHdr(buffer, p25::P25_DUID_LDU1, control, lsd, frameType);
- uint32_t count = 24U;
+ // pack DFSI data
+ uint32_t count = P25_MSG_HDR_SIZE;
uint8_t imbe[p25::P25_RAW_IMBE_LENGTH_BYTES];
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE1);
m_audio.decode(data, imbe, 0U);
dfsiLC.encodeLDU1(buffer + 24U, imbe);
- count += 22U;
+ count += p25::dfsi::P25_DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE2);
m_audio.decode(data, imbe, 1U);
dfsiLC.encodeLDU1(buffer + 46U, imbe);
- count += 14U;
+ count += p25::dfsi::P25_DFSI_LDU1_VOICE2_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE3);
m_audio.decode(data, imbe, 2U);
dfsiLC.encodeLDU1(buffer + 60U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU1_VOICE3_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE4);
m_audio.decode(data, imbe, 3U);
dfsiLC.encodeLDU1(buffer + 77U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU1_VOICE4_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE5);
m_audio.decode(data, imbe, 4U);
dfsiLC.encodeLDU1(buffer + 94U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU1_VOICE5_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE6);
m_audio.decode(data, imbe, 5U);
dfsiLC.encodeLDU1(buffer + 111U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU1_VOICE6_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE7);
m_audio.decode(data, imbe, 6U);
dfsiLC.encodeLDU1(buffer + 128U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU1_VOICE7_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE8);
m_audio.decode(data, imbe, 7U);
dfsiLC.encodeLDU1(buffer + 145U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU1_VOICE8_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE9);
m_audio.decode(data, imbe, 8U);
dfsiLC.encodeLDU1(buffer + 162U, imbe);
- count += 16U;
+ count += p25::dfsi::P25_DFSI_LDU1_VOICE9_FRAME_LENGTH_BYTES;
buffer[23U] = count;
@@ -827,70 +848,57 @@ UInt8Array BaseNetwork::createP25_LDU2Message(uint32_t& length, const p25::lc::L
uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
- ::memcpy(buffer + 0U, TAG_P25_DATA, 4U);
-
- buffer[4U] = control.getLCO(); // LCO
+ // construct P25 message header
+ createP25_MessageHdr(buffer, p25::P25_DUID_LDU2, control, lsd, p25::P25_FT_DATA_UNIT);
- uint32_t srcId = control.getSrcId(); // Source Address
- __SET_UINT16(srcId, buffer, 5U);
-
- uint32_t dstId = control.getDstId(); // Target Address
- __SET_UINT16(dstId, buffer, 8U);
-
- buffer[15U] = control.getMFId(); // MFId
-
- buffer[20U] = lsd.getLSD1(); // LSD 1
- buffer[21U] = lsd.getLSD2(); // LSD 2
-
- buffer[22U] = p25::P25_DUID_LDU2; // DUID
-
- uint32_t count = 24U;
+ // pack DFSI data
+ uint32_t count = P25_MSG_HDR_SIZE;
uint8_t imbe[p25::P25_RAW_IMBE_LENGTH_BYTES];
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE10);
m_audio.decode(data, imbe, 0U);
dfsiLC.encodeLDU2(buffer + 24U, imbe);
- count += 22U;
+ count += p25::dfsi::P25_DFSI_LDU2_VOICE10_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE11);
m_audio.decode(data, imbe, 1U);
dfsiLC.encodeLDU2(buffer + 46U, imbe);
- count += 14U;
+ count += p25::dfsi::P25_DFSI_LDU2_VOICE11_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE12);
m_audio.decode(data, imbe, 2U);
dfsiLC.encodeLDU2(buffer + 60U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU2_VOICE12_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE13);
m_audio.decode(data, imbe, 3U);
dfsiLC.encodeLDU2(buffer + 77U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU2_VOICE13_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE14);
m_audio.decode(data, imbe, 4U);
dfsiLC.encodeLDU2(buffer + 94U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU2_VOICE14_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE15);
m_audio.decode(data, imbe, 5U);
dfsiLC.encodeLDU2(buffer + 111U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU2_VOICE15_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE16);
m_audio.decode(data, imbe, 6U);
dfsiLC.encodeLDU2(buffer + 128U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU2_VOICE16_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE17);
m_audio.decode(data, imbe, 7U);
dfsiLC.encodeLDU2(buffer + 145U, imbe);
- count += 17U;
+ count += p25::dfsi::P25_DFSI_LDU2_VOICE17_FRAME_LENGTH_BYTES;
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE18);
m_audio.decode(data, imbe, 8U);
dfsiLC.encodeLDU2(buffer + 162U, imbe);
- count += 16U;
+ count += p25::dfsi::P25_DFSI_LDU2_VOICE18_FRAME_LENGTH_BYTES;
buffer[23U] = count;
@@ -913,24 +921,10 @@ UInt8Array BaseNetwork::createP25_TDUMessage(uint32_t& length, const p25::lc::LC
uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
- ::memcpy(buffer + 0U, TAG_P25_DATA, 4U);
-
- buffer[4U] = control.getLCO(); // LCO
-
- uint32_t srcId = control.getSrcId(); // Source Address
- __SET_UINT16(srcId, buffer, 5U);
+ // construct P25 message header
+ createP25_MessageHdr(buffer, p25::P25_DUID_TDU, control, lsd, p25::P25_FT_DATA_UNIT);
- uint32_t dstId = control.getDstId(); // Target Address
- __SET_UINT16(dstId, buffer, 8U);
-
- buffer[15U] = control.getMFId(); // MFId
-
- buffer[20U] = lsd.getLSD1(); // LSD 1
- buffer[21U] = lsd.getLSD2(); // LSD 2
-
- buffer[22U] = p25::P25_DUID_TDU; // DUID
-
- uint32_t count = 24U;
+ uint32_t count = P25_MSG_HDR_SIZE;
buffer[23U] = count;
if (m_debug)
@@ -954,24 +948,12 @@ UInt8Array BaseNetwork::createP25_TSDUMessage(uint32_t& length, const p25::lc::L
uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
- ::memcpy(buffer + 0U, TAG_P25_DATA, 4U);
-
- buffer[4U] = control.getLCO(); // LCO
-
- uint32_t srcId = control.getSrcId(); // Source Address
- __SET_UINT16(srcId, buffer, 5U);
-
- uint32_t dstId = control.getDstId(); // Target Address
- __SET_UINT16(dstId, buffer, 8U);
+ // construct P25 message header
+ p25::data::LowSpeedData lsd = p25::data::LowSpeedData();
+ createP25_MessageHdr(buffer, p25::P25_DUID_TSDU, control, lsd, p25::P25_FT_DATA_UNIT);
- buffer[15U] = control.getMFId(); // MFId
-
- buffer[20U] = 0U; // Reserved (LSD 1)
- buffer[21U] = 0U; // Reserved (LSD 2)
-
- buffer[22U] = p25::P25_DUID_TSDU; // DUID
-
- uint32_t count = 24U;
+ // pack raw P25 TSDU bytes
+ uint32_t count = P25_MSG_HDR_SIZE;
::memcpy(buffer + 24U, data, p25::P25_TSDU_FRAME_LENGTH_BYTES);
count += p25::P25_TSDU_FRAME_LENGTH_BYTES;
@@ -1011,6 +993,12 @@ UInt8Array BaseNetwork::createP25_PDUMessage(uint32_t& length, const p25::data::
uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
+ // construct P25 message header
+ /*
+ ** PDU packs different bytes into the P25 message header space from the rest of the
+ ** P25 DUIDs
+ */
+
::memcpy(buffer + 0U, TAG_P25_DATA, 4U);
buffer[4U] = header.getSAP(); // Service Access Point
@@ -1030,7 +1018,8 @@ UInt8Array BaseNetwork::createP25_PDUMessage(uint32_t& length, const p25::data::
buffer[22U] = p25::P25_DUID_PDU; // DUID
- uint32_t count = 24U;
+ // pack raw P25 PDU bytes
+ uint32_t count = P25_MSG_HDR_SIZE;
::memcpy(buffer + 24U, data, len);
count += len;
@@ -1059,6 +1048,7 @@ UInt8Array BaseNetwork::createNXDN_Message(uint32_t& length, const nxdn::lc::RTC
uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
+ // construct NXDN message header
::memcpy(buffer + 0U, TAG_NXDN_DATA, 4U);
buffer[4U] = lc.getMessageType(); // Message Type
@@ -1071,7 +1061,8 @@ UInt8Array BaseNetwork::createNXDN_Message(uint32_t& length, const nxdn::lc::RTC
buffer[15U] |= lc.getGroup() ? 0x00U : 0x40U; // Group
- uint32_t count = 24U;
+ // pack raw NXDN message bytes
+ uint32_t count = NXDN_MSG_HDR_SIZE;
::memcpy(buffer + 24U, data, len);
count += len;
diff --git a/src/network/BaseNetwork.h b/src/network/BaseNetwork.h
index 65b296dc..a8def202 100644
--- a/src/network/BaseNetwork.h
+++ b/src/network/BaseNetwork.h
@@ -93,8 +93,10 @@ namespace network
// Constants
// ---------------------------------------------------------------------------
- const uint32_t DMR_PACKET_SIZE = 55U;
- const uint32_t PACKET_PAD = 8U;
+ const uint32_t DMR_PACKET_SIZE = 55U;
+ const uint32_t PACKET_PAD = 8U;
+ const uint32_t P25_MSG_HDR_SIZE = 24U;
+ const uint32_t NXDN_MSG_HDR_SIZE = 24U;
const uint8_t NET_SUBFUNC_NOP = 0xFFU; // No Operation Sub-Function
@@ -277,6 +279,10 @@ namespace network
/// Creates an DMR frame message.
UInt8Array createDMR_Message(uint32_t& length, const uint32_t streamId, const dmr::data::Data& data);
+ /// Creates an P25 frame message header.
+ void createP25_MessageHdr(uint8_t* data, uint8_t duid, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd,
+ uint8_t frameType = p25::P25_FT_DATA_UNIT);
+
/// Creates an P25 LDU1 frame message.
UInt8Array createP25_LDU1Message(uint32_t& length, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd,
const uint8_t* data, uint8_t frameType);
diff --git a/src/network/FNENetwork.cpp b/src/network/FNENetwork.cpp
index 632a03b8..cff5bd0c 100644
--- a/src/network/FNENetwork.cpp
+++ b/src/network/FNENetwork.cpp
@@ -516,8 +516,7 @@ void FNENetwork::clock(uint32_t ms)
// validate peer (simple validation really)
if (connection.connected() && connection.address() == ip) {
- // TODO TODO TODO
- // TODO: handle repeater grant request
+ /* ignored */
}
else {
writePeerNAK(peerId, TAG_REPEATER_GRANT);
diff --git a/src/network/fne/TagDMRData.cpp b/src/network/fne/TagDMRData.cpp
index 64205801..08900d1a 100644
--- a/src/network/fne/TagDMRData.cpp
+++ b/src/network/fne/TagDMRData.cpp
@@ -286,9 +286,6 @@ bool TagDMRData::isPeerPermitted(uint32_t peerId, dmr::data::Data& data, uint32_
}
}
}
-
- // TODO TODO TODO
- // TODO: handle checking group affiliations if affiliation option is enabled
}
return true;
@@ -338,9 +335,6 @@ bool TagDMRData::validate(uint32_t peerId, dmr::data::Data& data, uint32_t strea
if (!tg.config().active()) {
return false;
}
-
- // TODO TODO TODO
- // TODO: handle checking group affiliations if affiliation option is enabled
}
return true;
diff --git a/src/network/fne/TagNXDNData.cpp b/src/network/fne/TagNXDNData.cpp
index 8bd29851..c34fcbaf 100644
--- a/src/network/fne/TagNXDNData.cpp
+++ b/src/network/fne/TagNXDNData.cpp
@@ -259,9 +259,6 @@ bool TagNXDNData::isPeerPermitted(uint32_t peerId, nxdn::lc::RTCH& lc, uint8_t m
}
}
}
-
- // TODO TODO TODO
- // TODO: handle checking group affiliations if affiliation option is enabled
}
return true;
@@ -307,8 +304,5 @@ bool TagNXDNData::validate(uint32_t peerId, nxdn::lc::RTCH& lc, uint8_t messageT
return false;
}
- // TODO TODO TODO
- // TODO: handle checking group affiliations if affiliation option is enabled
-
return true;
}
\ No newline at end of file
diff --git a/src/network/fne/TagP25Data.cpp b/src/network/fne/TagP25Data.cpp
index 7ac8e715..36ede8cd 100644
--- a/src/network/fne/TagP25Data.cpp
+++ b/src/network/fne/TagP25Data.cpp
@@ -306,9 +306,6 @@ bool TagP25Data::isPeerPermitted(uint32_t peerId, p25::lc::LC& control, uint8_t
}
}
- // TODO TODO TODO
- // TODO: handle checking group affiliations if affiliation option is enabled
-
return true;
}
@@ -356,8 +353,5 @@ bool TagP25Data::validate(uint32_t peerId, p25::lc::LC& control, uint8_t duid, u
return false;
}
- // TODO TODO TODO
- // TODO: handle checking group affiliations if affiliation option is enabled
-
return true;
}
\ No newline at end of file
diff --git a/src/nxdn/Control.cpp b/src/nxdn/Control.cpp
index 588d29f7..cb0f3f3b 100644
--- a/src/nxdn/Control.cpp
+++ b/src/nxdn/Control.cpp
@@ -835,6 +835,7 @@ void Control::processNetwork()
return;
}
+ // process network message header
uint8_t messageType = buffer[4U];
uint32_t srcId = __GET_UINT16(buffer, 5U);
@@ -852,6 +853,7 @@ void Control::processNetwork()
bool group = (buffer[15U] & 0x40U) == 0x40U ? false : true;
lc.setGroup(group);
+ // process raw NXDN data bytes
UInt8Array data;
uint8_t frameLength = buffer[23U];
if (frameLength <= 24) {
@@ -881,6 +883,7 @@ void Control::processNetwork()
uint8_t usc = m_rfLastLICH.getFCT();
uint8_t option = m_rfLastLICH.getOption();
+ // forward onto the specific processor for final processing and delivery
switch (usc) {
case NXDN_LICH_USC_UDCH:
ret = m_data->processNetwork(option, lc, data.get(), frameLength);
diff --git a/src/p25/Control.cpp b/src/p25/Control.cpp
index cefab0bc..eddec0c4 100644
--- a/src/p25/Control.cpp
+++ b/src/p25/Control.cpp
@@ -1132,6 +1132,7 @@ void Control::processNetwork()
return;
}
+ // process network message header
uint8_t lco = buffer[4U];
uint32_t srcId = __GET_UINT16(buffer, 5U);
@@ -1191,6 +1192,7 @@ void Control::processNetwork()
lsd.setLSD1(lsd1);
lsd.setLSD2(lsd2);
+ // process raw P25 data bytes
UInt8Array data;
uint8_t frameLength = buffer[23U];
if (duid == p25::P25_DUID_PDU) {
@@ -1217,6 +1219,7 @@ void Control::processNetwork()
Utils::dump(2U, "!!! *P25 Network Frame", data.get(), frameLength);
}
+ // forward onto the specific processor for final processing and delivery
switch (duid) {
case P25_DUID_HDU:
case P25_DUID_LDU1:
diff --git a/src/p25/packet/Voice.cpp b/src/p25/packet/Voice.cpp
index 4485d6ec..ae173e7e 100644
--- a/src/p25/packet/Voice.cpp
+++ b/src/p25/packet/Voice.cpp
@@ -771,39 +771,39 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE1);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 10U);
- count += 22U;
+ count += dfsi::P25_DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE2);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 26U);
- count += 14U;
+ count += dfsi::P25_DFSI_LDU1_VOICE2_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE3);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 55U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU1_VOICE3_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE4);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 80U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU1_VOICE4_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE5);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 105U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU1_VOICE5_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE6);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 130U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU1_VOICE6_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE7);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 155U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU1_VOICE7_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE8);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 180U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU1_VOICE8_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU1_VOICE9);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 204U);
- count += 16U;
+ count += dfsi::P25_DFSI_LDU1_VOICE9_FRAME_LENGTH_BYTES;
m_netLastLDU1 = control;
m_netLastFrameType = frameType;
@@ -845,39 +845,39 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
(data[138U] == dfsi::P25_DFSI_LDU2_VOICE18)) {
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE10);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 10U);
- count += 22U;
+ count += dfsi::P25_DFSI_LDU2_VOICE10_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE11);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 26U);
- count += 14U;
+ count += dfsi::P25_DFSI_LDU2_VOICE11_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE12);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 55U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU2_VOICE12_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE13);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 80U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU2_VOICE13_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE14);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 105U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU2_VOICE14_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE15);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 130U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU2_VOICE15_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE16);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 155U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU2_VOICE16_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE17);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 180U);
- count += 17U;
+ count += dfsi::P25_DFSI_LDU2_VOICE17_FRAME_LENGTH_BYTES;
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE18);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 204U);
- count += 16U;
+ count += dfsi::P25_DFSI_LDU2_VOICE18_FRAME_LENGTH_BYTES;
if (m_p25->m_control) {
lc::LC control = lc::LC(*m_dfsiLC.control());