remove affiliated flag from local talkgroup_rules (this is not used locally); refactor how P25 network message frames are made (mostly just a code cleanup); refactor out some magic numbers used in some places for code clarity;

pull/32/head
Bryan Biedenkapp 3 years ago
parent 702293b416
commit cdce663a55

@ -16,9 +16,6 @@ groupVoice:
config: config:
# Flag indicating whether this talkgroup is active or not. # Flag indicating whether this talkgroup is active or not.
active: true 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). # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic).
inclusion: [] inclusion: []
# List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic). # List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic).
@ -40,11 +37,8 @@ groupVoice:
config: config:
# Flag indicating whether this talkgroup is active or not. # Flag indicating whether this talkgroup is active or not.
active: true 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. # Flag indicating whether or not this talkgroup is a parrot talkgroup.
parrot: true parrot: true
# List of peer IDs included for this talkgroup (peers listed here will be selected for traffic). # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic).
inclusion: [] inclusion: []
# List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic). # List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic).
@ -66,9 +60,6 @@ groupVoice:
config: config:
# Flag indicating whether this talkgroup is active or not. # Flag indicating whether this talkgroup is active or not.
active: true 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). # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic).
inclusion: [] inclusion: []
# List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic). # List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic).
@ -90,9 +81,6 @@ groupVoice:
config: config:
# Flag indicating whether this talkgroup is active or not. # Flag indicating whether this talkgroup is active or not.
active: true 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). # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic).
inclusion: [] inclusion: []
# List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic). # List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic).
@ -114,9 +102,6 @@ groupVoice:
config: config:
# Flag indicating whether this talkgroup is active or not. # Flag indicating whether this talkgroup is active or not.
active: true 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). # List of peer IDs included for this talkgroup (peers listed here will be selected for traffic).
inclusion: [] inclusion: []
# List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic). # List of peer IDs excluded for this talkgroup (peers listed here will be ignored for traffic).

@ -652,6 +652,7 @@ void Control::processNetwork()
data::Data data; data::Data data;
// process network message header
uint8_t seqNo = buffer[4U]; uint8_t seqNo = buffer[4U];
uint32_t srcId = __GET_UINT16(buffer, 5U); 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); 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) { if (dataSync) {
uint8_t dataType = buffer[15U] & 0x0FU; uint8_t dataType = buffer[15U] & 0x0FU;
data.setData(buffer.get() + 20U); data.setData(buffer.get() + 20U);
@ -713,6 +715,7 @@ void Control::processNetwork()
data.setN(n); data.setN(n);
} }
// forward onto the specific slot for final processing and delivery
switch (slotNo) { switch (slotNo) {
case 1U: case 1U:
m_slot1->processNetwork(data); m_slot1->processNetwork(data);

@ -319,7 +319,6 @@ bool TalkgroupRulesLookup::load()
uint32_t tgId = groupVoice.source().tgId(); uint32_t tgId = groupVoice.source().tgId();
uint8_t tgSlot = groupVoice.source().tgSlot(); uint8_t tgSlot = groupVoice.source().tgSlot();
bool active = groupVoice.config().active(); bool active = groupVoice.config().active();
bool affiliated = groupVoice.config().affiliated();
bool parrot = groupVoice.config().parrot(); bool parrot = groupVoice.config().parrot();
uint32_t incCount = groupVoice.config().inclusion().size(); 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()); ::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(); m_mutex.unlock();

@ -89,7 +89,6 @@ namespace lookups
/// <summary>Initializes a new insatnce of the TalkgroupRuleConfig class.</summary> /// <summary>Initializes a new insatnce of the TalkgroupRuleConfig class.</summary>
TalkgroupRuleConfig() : TalkgroupRuleConfig() :
m_active(false), m_active(false),
m_affiliated(false),
m_parrot(false), m_parrot(false),
m_inclusion(), m_inclusion(),
m_exclusion() m_exclusion()
@ -102,7 +101,6 @@ namespace lookups
TalkgroupRuleConfig() TalkgroupRuleConfig()
{ {
m_active = node["active"].as<bool>(false); m_active = node["active"].as<bool>(false);
m_affiliated = node["affiliated"].as<bool>(false);
m_parrot = node["parrot"].as<bool>(false); m_parrot = node["parrot"].as<bool>(false);
yaml::Node& inclusionList = node["inclusion"]; yaml::Node& inclusionList = node["inclusion"];
@ -127,7 +125,6 @@ namespace lookups
{ {
if (this != &data) { if (this != &data) {
m_active = data.m_active; m_active = data.m_active;
m_affiliated = data.m_affiliated;
m_parrot = data.m_parrot; m_parrot = data.m_parrot;
m_inclusion = data.m_inclusion; m_inclusion = data.m_inclusion;
m_exclusion = data.m_exclusion; m_exclusion = data.m_exclusion;
@ -139,8 +136,6 @@ namespace lookups
public: public:
/// <summary>Flag indicating whether the rule is active.</summary> /// <summary>Flag indicating whether the rule is active.</summary>
__PROPERTY_PLAIN(bool, active, active); __PROPERTY_PLAIN(bool, active, active);
/// <summary>Flag indicating whether or not affiliations are requires to repeat traffic.</summary>
__PROPERTY_PLAIN(bool, affiliated, affiliated);
/// <summary>Flag indicating whether or not the talkgroup is a parrot.</summary> /// <summary>Flag indicating whether or not the talkgroup is a parrot.</summary>
__PROPERTY_PLAIN(bool, parrot, parrot); __PROPERTY_PLAIN(bool, parrot, parrot);
/// <summary>List of peer IDs included by this rule.</summary> /// <summary>List of peer IDs included by this rule.</summary>

@ -645,6 +645,7 @@ UInt8Array BaseNetwork::createDMR_Message(uint32_t& length, const uint32_t strea
uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH]; uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH); ::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
// construct DMR message header
::memcpy(buffer + 0U, TAG_DMR_DATA, 4U); ::memcpy(buffer + 0U, TAG_DMR_DATA, 4U);
uint32_t srcId = data.getSrcId(); // Source Address 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 buffer[4U] = data.getSeqNo(); // Sequence Number
data.getData(buffer + 20U);
buffer[53U] = data.getBER(); // Bit Error Rate buffer[53U] = data.getBER(); // Bit Error Rate
buffer[54U] = data.getRSSI(); // RSSI buffer[54U] = data.getRSSI(); // RSSI
// pack raw DMR message bytes
data.getData(buffer + 20U);
if (m_debug) if (m_debug)
Utils::dump(1U, "Network Message, DMR", buffer, (DMR_PACKET_SIZE + PACKET_PAD)); 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
} }
/// <summary> /// <summary>
/// Creates an P25 LDU1 frame message. /// Creates an P25 frame message header.
/// </summary> /// </summary>
/// <param name="length"></param> /// <param name="data"></param>
/// <param name="duid"></param>
/// <param name="control"></param> /// <param name="control"></param>
/// <param name="lsd"></param> /// <param name="lsd"></param>
/// <param name="data"></param>
/// <param name="frameType"></param> /// <param name="frameType"></param>
/// <returns></returns> void BaseNetwork::createP25_MessageHdr(uint8_t* data, uint8_t duid, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd,
UInt8Array BaseNetwork::createP25_LDU1Message(uint32_t& length, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd, uint8_t frameType)
const uint8_t* data, uint8_t frameType)
{ {
assert(data != nullptr); 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]; data[4U] = control.getLCO(); // LCO
::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 uint32_t srcId = control.getSrcId(); // Source Address
__SET_UINT16(srcId, buffer, 5U); __SET_UINT16(srcId, data, 5U);
uint32_t dstId = control.getDstId(); // Target Address 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 data[20U] = lsd.getLSD1(); // LSD 1
buffer[21U] = lsd.getLSD2(); // LSD 2 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? // is this the first frame of a call?
if (frameType == p25::P25_FT_HDU_VALID) { if (frameType == p25::P25_FT_HDU_VALID) {
buffer[180U] = 0x01U; // First LDU1 Marker data[180U] = 0x01U; // First LDU1 Marker
buffer[181U] = control.getAlgId(); // Algorithm ID data[181U] = control.getAlgId(); // Algorithm ID
uint32_t kid = control.getKId(); uint32_t kid = control.getKId();
buffer[182U] = (kid >> 8) & 0xFFU; // Key ID data[182U] = (kid >> 8) & 0xFFU; // Key ID
buffer[183U] = (kid >> 0) & 0xFFU; data[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];
@ -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++) { 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
} }
} }
}
/// <summary>
/// Creates an P25 LDU1 frame message.
/// </summary>
/// <param name="length"></param>
/// <param name="control"></param>
/// <param name="lsd"></param>
/// <param name="data"></param>
/// <param name="frameType"></param>
/// <returns></returns>
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]; uint8_t imbe[p25::P25_RAW_IMBE_LENGTH_BYTES];
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE1); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE1);
m_audio.decode(data, imbe, 0U); m_audio.decode(data, imbe, 0U);
dfsiLC.encodeLDU1(buffer + 24U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE2);
m_audio.decode(data, imbe, 1U); m_audio.decode(data, imbe, 1U);
dfsiLC.encodeLDU1(buffer + 46U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE3);
m_audio.decode(data, imbe, 2U); m_audio.decode(data, imbe, 2U);
dfsiLC.encodeLDU1(buffer + 60U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE4);
m_audio.decode(data, imbe, 3U); m_audio.decode(data, imbe, 3U);
dfsiLC.encodeLDU1(buffer + 77U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE5);
m_audio.decode(data, imbe, 4U); m_audio.decode(data, imbe, 4U);
dfsiLC.encodeLDU1(buffer + 94U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE6);
m_audio.decode(data, imbe, 5U); m_audio.decode(data, imbe, 5U);
dfsiLC.encodeLDU1(buffer + 111U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE7);
m_audio.decode(data, imbe, 6U); m_audio.decode(data, imbe, 6U);
dfsiLC.encodeLDU1(buffer + 128U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE8);
m_audio.decode(data, imbe, 7U); m_audio.decode(data, imbe, 7U);
dfsiLC.encodeLDU1(buffer + 145U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU1_VOICE9);
m_audio.decode(data, imbe, 8U); m_audio.decode(data, imbe, 8U);
dfsiLC.encodeLDU1(buffer + 162U, imbe); dfsiLC.encodeLDU1(buffer + 162U, imbe);
count += 16U; count += p25::dfsi::P25_DFSI_LDU1_VOICE9_FRAME_LENGTH_BYTES;
buffer[23U] = count; 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]; uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH); ::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
::memcpy(buffer + 0U, TAG_P25_DATA, 4U); // construct P25 message header
createP25_MessageHdr(buffer, p25::P25_DUID_LDU2, control, lsd, p25::P25_FT_DATA_UNIT);
buffer[4U] = control.getLCO(); // LCO
uint32_t srcId = control.getSrcId(); // Source Address // pack DFSI data
__SET_UINT16(srcId, buffer, 5U); uint32_t count = P25_MSG_HDR_SIZE;
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;
uint8_t imbe[p25::P25_RAW_IMBE_LENGTH_BYTES]; uint8_t imbe[p25::P25_RAW_IMBE_LENGTH_BYTES];
dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE10); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE10);
m_audio.decode(data, imbe, 0U); m_audio.decode(data, imbe, 0U);
dfsiLC.encodeLDU2(buffer + 24U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE11);
m_audio.decode(data, imbe, 1U); m_audio.decode(data, imbe, 1U);
dfsiLC.encodeLDU2(buffer + 46U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE12);
m_audio.decode(data, imbe, 2U); m_audio.decode(data, imbe, 2U);
dfsiLC.encodeLDU2(buffer + 60U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE13);
m_audio.decode(data, imbe, 3U); m_audio.decode(data, imbe, 3U);
dfsiLC.encodeLDU2(buffer + 77U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE14);
m_audio.decode(data, imbe, 4U); m_audio.decode(data, imbe, 4U);
dfsiLC.encodeLDU2(buffer + 94U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE15);
m_audio.decode(data, imbe, 5U); m_audio.decode(data, imbe, 5U);
dfsiLC.encodeLDU2(buffer + 111U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE16);
m_audio.decode(data, imbe, 6U); m_audio.decode(data, imbe, 6U);
dfsiLC.encodeLDU2(buffer + 128U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE17);
m_audio.decode(data, imbe, 7U); m_audio.decode(data, imbe, 7U);
dfsiLC.encodeLDU2(buffer + 145U, imbe); 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); dfsiLC.setFrameType(p25::dfsi::P25_DFSI_LDU2_VOICE18);
m_audio.decode(data, imbe, 8U); m_audio.decode(data, imbe, 8U);
dfsiLC.encodeLDU2(buffer + 162U, imbe); dfsiLC.encodeLDU2(buffer + 162U, imbe);
count += 16U; count += p25::dfsi::P25_DFSI_LDU2_VOICE18_FRAME_LENGTH_BYTES;
buffer[23U] = count; 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]; uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH); ::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
::memcpy(buffer + 0U, TAG_P25_DATA, 4U); // construct P25 message header
createP25_MessageHdr(buffer, p25::P25_DUID_TDU, control, lsd, p25::P25_FT_DATA_UNIT);
buffer[4U] = control.getLCO(); // LCO
uint32_t srcId = control.getSrcId(); // Source Address
__SET_UINT16(srcId, buffer, 5U);
uint32_t dstId = control.getDstId(); // Target Address uint32_t count = P25_MSG_HDR_SIZE;
__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;
buffer[23U] = count; buffer[23U] = count;
if (m_debug) 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]; uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH); ::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
::memcpy(buffer + 0U, TAG_P25_DATA, 4U); // construct P25 message header
p25::data::LowSpeedData lsd = p25::data::LowSpeedData();
buffer[4U] = control.getLCO(); // LCO createP25_MessageHdr(buffer, p25::P25_DUID_TSDU, 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 // pack raw P25 TSDU bytes
uint32_t count = P25_MSG_HDR_SIZE;
buffer[20U] = 0U; // Reserved (LSD 1)
buffer[21U] = 0U; // Reserved (LSD 2)
buffer[22U] = p25::P25_DUID_TSDU; // DUID
uint32_t count = 24U;
::memcpy(buffer + 24U, data, p25::P25_TSDU_FRAME_LENGTH_BYTES); ::memcpy(buffer + 24U, data, p25::P25_TSDU_FRAME_LENGTH_BYTES);
count += 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]; uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, 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); ::memcpy(buffer + 0U, TAG_P25_DATA, 4U);
buffer[4U] = header.getSAP(); // Service Access Point 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 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); ::memcpy(buffer + 24U, data, len);
count += 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]; uint8_t* buffer = new uint8_t[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH); ::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
// construct NXDN message header
::memcpy(buffer + 0U, TAG_NXDN_DATA, 4U); ::memcpy(buffer + 0U, TAG_NXDN_DATA, 4U);
buffer[4U] = lc.getMessageType(); // Message Type 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 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); ::memcpy(buffer + 24U, data, len);
count += len; count += len;

@ -95,6 +95,8 @@ namespace network
const uint32_t DMR_PACKET_SIZE = 55U; const uint32_t DMR_PACKET_SIZE = 55U;
const uint32_t PACKET_PAD = 8U; 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 const uint8_t NET_SUBFUNC_NOP = 0xFFU; // No Operation Sub-Function
@ -277,6 +279,10 @@ namespace network
/// <summary>Creates an DMR frame message.</summary> /// <summary>Creates an DMR frame message.</summary>
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>
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);
/// <summary>Creates an P25 LDU1 frame message.</summary> /// <summary>Creates an P25 LDU1 frame message.</summary>
UInt8Array createP25_LDU1Message(uint32_t& length, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd, UInt8Array createP25_LDU1Message(uint32_t& length, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd,
const uint8_t* data, uint8_t frameType); const uint8_t* data, uint8_t frameType);

@ -516,8 +516,7 @@ void FNENetwork::clock(uint32_t ms)
// validate peer (simple validation really) // validate peer (simple validation really)
if (connection.connected() && connection.address() == ip) { if (connection.connected() && connection.address() == ip) {
// TODO TODO TODO /* ignored */
// TODO: handle repeater grant request
} }
else { else {
writePeerNAK(peerId, TAG_REPEATER_GRANT); writePeerNAK(peerId, TAG_REPEATER_GRANT);

@ -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; return true;
@ -338,9 +335,6 @@ bool TagDMRData::validate(uint32_t peerId, dmr::data::Data& data, uint32_t strea
if (!tg.config().active()) { if (!tg.config().active()) {
return false; return false;
} }
// TODO TODO TODO
// TODO: handle checking group affiliations if affiliation option is enabled
} }
return true; return true;

@ -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; return true;
@ -307,8 +304,5 @@ bool TagNXDNData::validate(uint32_t peerId, nxdn::lc::RTCH& lc, uint8_t messageT
return false; return false;
} }
// TODO TODO TODO
// TODO: handle checking group affiliations if affiliation option is enabled
return true; return true;
} }

@ -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; return true;
} }
@ -356,8 +353,5 @@ bool TagP25Data::validate(uint32_t peerId, p25::lc::LC& control, uint8_t duid, u
return false; return false;
} }
// TODO TODO TODO
// TODO: handle checking group affiliations if affiliation option is enabled
return true; return true;
} }

@ -835,6 +835,7 @@ void Control::processNetwork()
return; return;
} }
// process network message header
uint8_t messageType = buffer[4U]; uint8_t messageType = buffer[4U];
uint32_t srcId = __GET_UINT16(buffer, 5U); uint32_t srcId = __GET_UINT16(buffer, 5U);
@ -852,6 +853,7 @@ void Control::processNetwork()
bool group = (buffer[15U] & 0x40U) == 0x40U ? false : true; bool group = (buffer[15U] & 0x40U) == 0x40U ? false : true;
lc.setGroup(group); lc.setGroup(group);
// process raw NXDN data bytes
UInt8Array data; UInt8Array data;
uint8_t frameLength = buffer[23U]; uint8_t frameLength = buffer[23U];
if (frameLength <= 24) { if (frameLength <= 24) {
@ -881,6 +883,7 @@ void Control::processNetwork()
uint8_t usc = m_rfLastLICH.getFCT(); uint8_t usc = m_rfLastLICH.getFCT();
uint8_t option = m_rfLastLICH.getOption(); uint8_t option = m_rfLastLICH.getOption();
// forward onto the specific processor for final processing and delivery
switch (usc) { switch (usc) {
case NXDN_LICH_USC_UDCH: case NXDN_LICH_USC_UDCH:
ret = m_data->processNetwork(option, lc, data.get(), frameLength); ret = m_data->processNetwork(option, lc, data.get(), frameLength);

@ -1132,6 +1132,7 @@ void Control::processNetwork()
return; return;
} }
// process network message header
uint8_t lco = buffer[4U]; uint8_t lco = buffer[4U];
uint32_t srcId = __GET_UINT16(buffer, 5U); uint32_t srcId = __GET_UINT16(buffer, 5U);
@ -1191,6 +1192,7 @@ void Control::processNetwork()
lsd.setLSD1(lsd1); lsd.setLSD1(lsd1);
lsd.setLSD2(lsd2); lsd.setLSD2(lsd2);
// process raw P25 data bytes
UInt8Array data; UInt8Array data;
uint8_t frameLength = buffer[23U]; uint8_t frameLength = buffer[23U];
if (duid == p25::P25_DUID_PDU) { if (duid == p25::P25_DUID_PDU) {
@ -1217,6 +1219,7 @@ void Control::processNetwork()
Utils::dump(2U, "!!! *P25 Network Frame", data.get(), frameLength); Utils::dump(2U, "!!! *P25 Network Frame", data.get(), frameLength);
} }
// forward onto the specific processor for final processing and delivery
switch (duid) { switch (duid) {
case P25_DUID_HDU: case P25_DUID_HDU:
case P25_DUID_LDU1: case P25_DUID_LDU1:

@ -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.setFrameType(dfsi::P25_DFSI_LDU1_VOICE1);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 10U); 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.setFrameType(dfsi::P25_DFSI_LDU1_VOICE2);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 26U); 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.setFrameType(dfsi::P25_DFSI_LDU1_VOICE3);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 55U); 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.setFrameType(dfsi::P25_DFSI_LDU1_VOICE4);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 80U); 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.setFrameType(dfsi::P25_DFSI_LDU1_VOICE5);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 105U); 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.setFrameType(dfsi::P25_DFSI_LDU1_VOICE6);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 130U); 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.setFrameType(dfsi::P25_DFSI_LDU1_VOICE7);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 155U); 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.setFrameType(dfsi::P25_DFSI_LDU1_VOICE8);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 180U); 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.setFrameType(dfsi::P25_DFSI_LDU1_VOICE9);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 204U); m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 204U);
count += 16U; count += dfsi::P25_DFSI_LDU1_VOICE9_FRAME_LENGTH_BYTES;
m_netLastLDU1 = control; m_netLastLDU1 = control;
m_netLastFrameType = frameType; 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)) { (data[138U] == dfsi::P25_DFSI_LDU2_VOICE18)) {
m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE10); m_dfsiLC.setFrameType(dfsi::P25_DFSI_LDU2_VOICE10);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 10U); 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.setFrameType(dfsi::P25_DFSI_LDU2_VOICE11);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 26U); 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.setFrameType(dfsi::P25_DFSI_LDU2_VOICE12);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 55U); 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.setFrameType(dfsi::P25_DFSI_LDU2_VOICE13);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 80U); 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.setFrameType(dfsi::P25_DFSI_LDU2_VOICE14);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 105U); 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.setFrameType(dfsi::P25_DFSI_LDU2_VOICE15);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 130U); 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.setFrameType(dfsi::P25_DFSI_LDU2_VOICE16);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 155U); 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.setFrameType(dfsi::P25_DFSI_LDU2_VOICE17);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 180U); 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.setFrameType(dfsi::P25_DFSI_LDU2_VOICE18);
m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 204U); m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 204U);
count += 16U; count += dfsi::P25_DFSI_LDU2_VOICE18_FRAME_LENGTH_BYTES;
if (m_p25->m_control) { if (m_p25->m_control) {
lc::LC control = lc::LC(*m_dfsiLC.control()); lc::LC control = lc::LC(*m_dfsiLC.control());

Loading…
Cancel
Save

Powered by TurnKey Linux.