implement parrot grant demand support for FNE conference bridge; correct issue with grant demands appearing as U2U instead of GROUP;

pull/41/head
Bryan Biedenkapp 2 years ago
parent 31fae83b3d
commit 3b3bc884a4

@ -55,6 +55,8 @@ master:
# Delay from when a call on a parrot TG ends to when the playback starts (in milliseconds).
parrotDelay: 2000
# Flag indicating whether or not a parrot TG call will generate a grant demand.
parrotGrantDemand: true
#
# Talkgroup Rules Configuration

@ -333,6 +333,7 @@ bool HostFNE::createMasterNetwork()
LogWarning(LOG_HOST, "Parrot delay cannot be longer then the ping time of a peer. Reducing parrot delay to half the ping time.");
parrotDelay = (m_pingTime * 1000U) / 2U;
}
bool parrotGrantDemand = masterConf["parrotGrantDemand"].as<bool>(true);
LogInfo("Network Parameters");
LogInfo(" Peer ID: %u", id);
@ -342,6 +343,7 @@ bool HostFNE::createMasterNetwork()
LogInfo(" Allow P25 Traffic: %s", m_p25Enabled ? "yes" : "no");
LogInfo(" Allow NXDN Traffic: %s", m_nxdnEnabled ? "yes" : "no");
LogInfo(" Parrot Repeat Delay: %u ms", parrotDelay);
LogInfo(" Parrot Grant Demand: %s", parrotGrantDemand ? "yes" : "no");
if (verbose) {
LogInfo(" Verbose: yes");
@ -352,8 +354,8 @@ bool HostFNE::createMasterNetwork()
}
// initialize networking
m_network = new FNENetwork(this, address, port, id, password, debug, verbose, m_dmrEnabled, m_p25Enabled, m_nxdnEnabled, parrotDelay,
m_allowActivityTransfer, m_allowDiagnosticTransfer, m_pingTime, m_updateLookupTime);
m_network = new FNENetwork(this, address, port, id, password, debug, verbose, m_dmrEnabled, m_p25Enabled, m_nxdnEnabled,
parrotDelay, parrotGrantDemand, m_allowActivityTransfer, m_allowDiagnosticTransfer, m_pingTime, m_updateLookupTime);
m_network->setLookups(m_ridLookup, m_tidLookup);

@ -438,8 +438,9 @@ bool BaseNetwork::writeP25LDU2(const p25::lc::LC& control, const p25::data::LowS
/// </summary>
/// <param name="control"></param>
/// <param name="lsd"></param>
/// <param name="controlByte"></param>
/// <returns></returns>
bool BaseNetwork::writeP25TDU(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd)
bool BaseNetwork::writeP25TDU(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd, const uint8_t controlByte)
{
if (m_status != NET_STAT_RUNNING && m_status != NET_STAT_MST_RUNNING)
return false;
@ -451,7 +452,7 @@ bool BaseNetwork::writeP25TDU(const p25::lc::LC& control, const p25::data::LowSp
}
uint32_t messageLength = 0U;
UInt8Array message = createP25_TDUMessage(messageLength, control, lsd);
UInt8Array message = createP25_TDUMessage(messageLength, control, lsd, controlByte);
if (message == nullptr) {
return false;
}
@ -916,8 +917,9 @@ UInt8Array BaseNetwork::createP25_LDU2Message(uint32_t& length, const p25::lc::L
/// <param name="length"></param>
/// <param name="control"></param>
/// <param name="lsd"></param>
/// <param name="controlByte"></param>
/// <returns></returns>
UInt8Array BaseNetwork::createP25_TDUMessage(uint32_t& length, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd)
UInt8Array BaseNetwork::createP25_TDUMessage(uint32_t& length, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd, const uint8_t controlByte)
{
uint8_t* buffer = new uint8_t[MSG_HDR_SIZE + PACKET_PAD];
::memset(buffer, 0x00U, MSG_HDR_SIZE + PACKET_PAD);
@ -925,6 +927,7 @@ UInt8Array BaseNetwork::createP25_TDUMessage(uint32_t& length, const p25::lc::LC
// construct P25 message header
createP25_MessageHdr(buffer, p25::P25_DUID_TDU, control, lsd, p25::P25_FT_TERMINATOR);
buffer[14U] = controlByte;
buffer[23U] = MSG_HDR_SIZE;
if (m_debug)

@ -212,7 +212,7 @@ namespace network
/// <summary>Writes P25 LDU2 frame data to the network.</summary>
bool writeP25LDU2(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd, const uint8_t* data);
/// <summary>Writes P25 TDU frame data to the network.</summary>
bool writeP25TDU(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd);
bool writeP25TDU(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd, const uint8_t controlByte = 0U);
/// <summary>Writes P25 TSDU frame data to the network.</summary>
bool writeP25TSDU(const p25::lc::LC& control, const uint8_t* data);
/// <summary>Writes P25 PDU frame data to the network.</summary>
@ -286,7 +286,8 @@ namespace network
const uint8_t* data);
/// <summary>Creates an P25 TDU frame message.</summary>
UInt8Array createP25_TDUMessage(uint32_t& length, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd);
UInt8Array createP25_TDUMessage(uint32_t& length, const p25::lc::LC& control, const p25::data::LowSpeedData& lsd,
const uint8_t controlByte);
/// <summary>Creates an P25 TSDU frame message.</summary>
UInt8Array createP25_TSDUMessage(uint32_t& length, const p25::lc::LC& control, const uint8_t* data);

@ -61,14 +61,15 @@ using namespace network::fne;
/// <param name="p25">Flag indicating whether P25 is enabled.</param>
/// <param name="nxdn">Flag indicating whether NXDN is enabled.</param>
/// <param name="parrotDelay">Delay for end of call to parrot TG playback.</param>
/// <param name="parrotGrantDemand">Flag indicating whether a parrot TG will generate a grant demand.</param>
/// <param name="allowActivityTransfer">Flag indicating that the system activity logs will be sent to the network.</param>
/// <param name="allowDiagnosticTransfer">Flag indicating that the system diagnostic logs will be sent to the network.</param>
/// <param name="trafficRepeat">Flag indicating if traffic should be repeated from this master.</param>
/// <param name="pingTime"></param>
/// <param name="updateLookupTime"></param>
FNENetwork::FNENetwork(HostFNE* host, const std::string& address, uint16_t port, uint32_t peerId, const std::string& password,
bool debug, bool verbose, bool dmr, bool p25, bool nxdn, uint32_t parrotDelay, bool allowActivityTransfer, bool allowDiagnosticTransfer,
uint32_t pingTime, uint32_t updateLookupTime) :
bool debug, bool verbose, bool dmr, bool p25, bool nxdn, uint32_t parrotDelay, bool parrotGrantDemand,
bool allowActivityTransfer, bool allowDiagnosticTransfer, uint32_t pingTime, uint32_t updateLookupTime) :
BaseNetwork(peerId, true, debug, true, true, allowActivityTransfer, allowDiagnosticTransfer),
m_tagDMR(nullptr),
m_tagP25(nullptr),
@ -81,6 +82,7 @@ FNENetwork::FNENetwork(HostFNE* host, const std::string& address, uint16_t port,
m_p25Enabled(p25),
m_nxdnEnabled(nxdn),
m_parrotDelay(parrotDelay),
m_parrotGrantDemand(parrotGrantDemand),
m_ridLookup(nullptr),
m_tidLookup(nullptr),
m_status(NET_STAT_INVALID),

@ -177,8 +177,8 @@ namespace network
public:
/// <summary>Initializes a new instance of the FNENetwork class.</summary>
FNENetwork(HostFNE* host, const std::string& address, uint16_t port, uint32_t peerId, const std::string& password,
bool debug, bool verbose, bool dmr, bool p25, bool nxdn, uint32_t parrotDelay, bool allowActivityTransfer,
bool allowDiagnosticTransfer, uint32_t pingTime, uint32_t updateLookupTime);
bool debug, bool verbose, bool dmr, bool p25, bool nxdn, uint32_t parrotDelay, bool parrotGrantDemand,
bool allowActivityTransfer, bool allowDiagnosticTransfer, uint32_t pingTime, uint32_t updateLookupTime);
/// <summary>Finalizes a instance of the FNENetwork class.</summary>
~FNENetwork();
@ -224,6 +224,7 @@ namespace network
bool m_nxdnEnabled;
uint32_t m_parrotDelay;
bool m_parrotGrantDemand;
lookups::RadioIdLookup* m_ridLookup;
lookups::TalkgroupRulesLookup* m_tidLookup;

@ -36,6 +36,7 @@
using namespace system_clock;
using namespace network;
using namespace network::fne;
using namespace p25;
#include <cstdio>
#include <cassert>
@ -55,6 +56,7 @@ TagP25Data::TagP25Data(FNENetwork* network, bool debug) :
m_network(network),
m_parrotFrames(),
m_parrotFramesReady(false),
m_parrotFirstFrame(true),
m_status(),
m_debug(debug)
{
@ -160,6 +162,7 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId
if (tg.config().parrot()) {
if (m_parrotFrames.size() > 0) {
m_parrotFramesReady = true;
m_parrotFirstFrame = true;
Thread::sleep(m_network->m_parrotDelay);
LogMessage(LOG_NET, "P25, Parrot Playback will Start, peer = %u, srcId = %u", peerId, srcId);
}
@ -213,7 +216,7 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId
if (tg.config().parrot()) {
uint8_t *copy = new uint8_t[len];
::memcpy(copy, data, len);
m_parrotFrames.push_back(std::make_tuple(copy, len, pktSeq, streamId));
m_parrotFrames.push_back(std::make_tuple(copy, len, pktSeq, streamId, srcId, dstId));
}
// repeat traffic to the connected peers
@ -253,11 +256,42 @@ void TagP25Data::playbackParrot()
{
if (m_parrotFrames.size() == 0) {
m_parrotFramesReady = false;
m_parrotFirstFrame = true;
return;
}
auto& pkt = m_parrotFrames[0];
if (std::get<0>(pkt) != nullptr) {
if (m_parrotFirstFrame) {
if (m_network->m_parrotGrantDemand) {
uint32_t srcId = std::get<4>(pkt);
uint32_t dstId = std::get<5>(pkt);
// create control data
lc::LC control = lc::LC();
control.setSrcId(srcId);
control.setDstId(dstId);
// create empty LSD
data::LowSpeedData lsd = data::LowSpeedData();
uint8_t controlByte = 0x80U;
// send grant demand
uint32_t messageLength = 0U;
UInt8Array message = m_network->createP25_TDUMessage(messageLength, control, lsd, controlByte);
if (message != nullptr) {
// repeat traffic to the connected peers
for (auto peer : m_network->m_peers) {
LogMessage(LOG_NET, "P25, Parrot Grant Demand, peer = %u, srcId = %u, dstId = %u", peer.first, srcId, dstId);
m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, message.get(), messageLength, 0U, false);
}
}
}
m_parrotFirstFrame = false;
}
// repeat traffic to the connected peers
for (auto peer : m_network->m_peers) {
m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, std::get<0>(pkt), std::get<1>(pkt), std::get<2>(pkt), std::get<3>(pkt), false);

@ -67,8 +67,9 @@ namespace network
private:
FNENetwork* m_network;
std::deque<std::tuple<uint8_t*, uint32_t, uint16_t, uint32_t>> m_parrotFrames;
std::deque<std::tuple<uint8_t*, uint32_t, uint16_t, uint32_t, uint32_t, uint32_t>> m_parrotFrames;
bool m_parrotFramesReady;
bool m_parrotFirstFrame;
class RxStatus {
public:

@ -1282,7 +1282,7 @@ void Control::processNetwork()
(control.getPriority() & 0x07U); // Priority
if (m_verbose) {
LogMessage(LOG_NET, P25_TSDU_STR " remote grant demand, srcId = %u, dstId = %u", srcId, dstId);
LogMessage(LOG_NET, P25_TSDU_STR " remote grant demand, srcId = %u, dstId = %u, unitToUnit = %u", srcId, dstId, unitToUnit);
}
// are we denying the grant?
@ -1292,7 +1292,7 @@ void Control::processNetwork()
}
// perform grant response logic
if (!m_control->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, unitToUnit, true))
if (!m_control->writeRF_TSDU_Grant(srcId, dstId, serviceOptions, !unitToUnit, true))
{
LogError(LOG_NET, P25_TSDU_STR " call failure, network call not granted, dstId = %u", dstId);
return;

Loading…
Cancel
Save

Powered by TurnKey Linux.