add preliminary work for eventual FNE STC (Site Trunk Controller) support;

pull/12/head
Bryan Biedenkapp 4 years ago
parent 170424e44c
commit f22f1e76d1

@ -22,6 +22,7 @@ network:
updateLookups: false updateLookups: false
allowActivityTransfer: false allowActivityTransfer: false
allowDiagnosticTransfer: false allowDiagnosticTransfer: false
handleChGrants: false
debug: false debug: false
protocols: protocols:
dmr: dmr:

@ -1750,6 +1750,7 @@ bool Host::createNetwork()
bool allowActivityTransfer = networkConf["allowActivityTransfer"].as<bool>(false); bool allowActivityTransfer = networkConf["allowActivityTransfer"].as<bool>(false);
bool allowDiagnosticTransfer = networkConf["allowDiagnosticTransfer"].as<bool>(false); bool allowDiagnosticTransfer = networkConf["allowDiagnosticTransfer"].as<bool>(false);
bool updateLookup = networkConf["updateLookups"].as<bool>(false); bool updateLookup = networkConf["updateLookups"].as<bool>(false);
bool handleChGrants = networkConf["handleChGrants"].as<bool>(false);
bool debug = networkConf["debug"].as<bool>(false); bool debug = networkConf["debug"].as<bool>(false);
if (rconPassword.length() > 64) { if (rconPassword.length() > 64) {
@ -1784,12 +1785,13 @@ bool Host::createNetwork()
LogInfo(" Allow Activity Log Transfer: %s", allowActivityTransfer ? "yes" : "no"); LogInfo(" Allow Activity Log Transfer: %s", allowActivityTransfer ? "yes" : "no");
LogInfo(" Allow Diagnostic Log Transfer: %s", allowDiagnosticTransfer ? "yes" : "no"); LogInfo(" Allow Diagnostic Log Transfer: %s", allowDiagnosticTransfer ? "yes" : "no");
LogInfo(" Update Lookups: %s", updateLookup ? "yes" : "no"); LogInfo(" Update Lookups: %s", updateLookup ? "yes" : "no");
LogInfo(" Handle Channel Grants: %s", handleChGrants ? "yes" : "no");
if (debug) { if (debug) {
LogInfo(" Debug: yes"); LogInfo(" Debug: yes");
} }
m_network = new Network(address, port, local, id, password, m_duplex, debug, m_dmrEnabled, m_p25Enabled, slot1, slot2, allowActivityTransfer, allowDiagnosticTransfer, updateLookup); m_network = new Network(address, port, local, id, password, m_duplex, debug, m_dmrEnabled, m_p25Enabled, slot1, slot2, allowActivityTransfer, allowDiagnosticTransfer, updateLookup, handleChGrants);
m_network->setLookups(m_ridLookup, m_tidLookup); m_network->setLookups(m_ridLookup, m_tidLookup);
m_network->setMetadata(m_identity, m_rxFrequency, m_txFrequency, entry.txOffsetMhz(), entry.chBandwidthKhz(), m_channelId, m_channelNo, m_network->setMetadata(m_identity, m_rxFrequency, m_txFrequency, entry.txOffsetMhz(), entry.chBandwidthKhz(), m_channelId, m_channelNo,

@ -54,12 +54,14 @@ using namespace network;
/// <param name="slot2">Flag indicating whether DMR slot 2 is enabled for network traffic.</param> /// <param name="slot2">Flag indicating whether DMR slot 2 is enabled for network traffic.</param>
/// <param name="allowActivityTransfer">Flag indicating that the system activity logs will be sent to the network.</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="allowDiagnosticTransfer">Flag indicating that the system diagnostic logs will be sent to the network.</param>
BaseNetwork::BaseNetwork(uint16_t localPort, uint32_t id, bool duplex, bool debug, bool slot1, bool slot2, bool allowActivityTransfer, bool allowDiagnosticTransfer) : /// <param name="handleChGrants">Flag indicating that the system will handle channel grants from the network.</param>
BaseNetwork::BaseNetwork(uint16_t localPort, uint32_t id, bool duplex, bool debug, bool slot1, bool slot2, bool allowActivityTransfer, bool allowDiagnosticTransfer, bool handleChGrants) :
m_id(id), m_id(id),
m_slot1(slot1), m_slot1(slot1),
m_slot2(slot2), m_slot2(slot2),
m_allowActivityTransfer(allowActivityTransfer), m_allowActivityTransfer(allowActivityTransfer),
m_allowDiagnosticTransfer(allowDiagnosticTransfer), m_allowDiagnosticTransfer(allowDiagnosticTransfer),
m_handleChGrants(handleChGrants),
m_duplex(duplex), m_duplex(duplex),
m_debug(debug), m_debug(debug),
m_addr(), m_addr(),
@ -74,6 +76,7 @@ BaseNetwork::BaseNetwork(uint16_t localPort, uint32_t id, bool duplex, bool debu
m_p25StreamId(0U), m_p25StreamId(0U),
m_rxDMRData(4000U, "DMR Net Buffer"), m_rxDMRData(4000U, "DMR Net Buffer"),
m_rxP25Data(4000U, "P25 Net Buffer"), m_rxP25Data(4000U, "P25 Net Buffer"),
m_rxGrantData(4000U, "Grant Net Buffer"),
m_audio(), m_audio(),
m_random() m_random()
{ {
@ -247,6 +250,39 @@ uint8_t* BaseNetwork::readP25(bool& ret, p25::lc::LC& control, p25::data::LowSpe
return data; return data;
} }
/// <summary>
/// Reads a channel grant request from the network.
/// </summary>
/// <param name="grp"></param>
/// <param name="srcId"></param>
/// <param name="dstId"></param>
/// <param name="grpVchNo"></param>
/// <returns></returns>
bool BaseNetwork::readGrantRsp(bool& grp, uint32_t& srcId, uint32_t& dstId, uint32_t& grpVchNo)
{
if (!m_handleChGrants)
return false;
if (m_status != NET_STAT_RUNNING && m_status != NET_STAT_MST_RUNNING)
return false;
if (m_rxGrantData.isEmpty())
return false;
uint8_t length = 0U;
m_rxGrantData.getData(&length, 1U);
m_rxGrantData.getData(m_buffer, length);
srcId = (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
dstId = (m_buffer[8U] << 16) | (m_buffer[9U] << 8) | (m_buffer[10U] << 0);
grp = m_buffer[11U] == 1U;
grpVchNo = (m_buffer[12U] << 16) | (m_buffer[13U] << 8) | (m_buffer[14U] << 0);
return true;
}
/// <summary> /// <summary>
/// Writes DMR frame data to the network. /// Writes DMR frame data to the network.
/// </summary> /// </summary>
@ -387,6 +423,40 @@ bool BaseNetwork::writeP25PDU(const p25::data::DataHeader& header, const p25::da
return writeP25PDU(m_id, m_p25StreamId, header, secHeader, currentBlock, data, len); return writeP25PDU(m_id, m_p25StreamId, header, secHeader, currentBlock, data, len);
} }
/// <summary>
/// Writes a channel grant request to the network.
/// </summary>
/// <param name="grp"></param>
/// <param name="srcId"></param>
/// <param name="dstId"></param>
/// <returns></returns>
bool BaseNetwork::writeGrantReq(const bool grp, const uint32_t srcId, const uint32_t dstId)
{
if (!m_handleChGrants)
return false;
if (m_status != NET_STAT_RUNNING && m_status != NET_STAT_MST_RUNNING)
return false;
uint8_t buffer[DATA_PACKET_LENGTH];
::memset(buffer, 0x00U, DATA_PACKET_LENGTH);
::memcpy(buffer + 0U, TAG_REPEATER_GRANT, 7U);
__SET_UINT16(srcId, buffer, 5U); // Source Address
__SET_UINT16(dstId, buffer, 8U); // Target Address
buffer[11U] = (grp) ? 1U : 0U; // Group/Individual Grant
__SET_UINT32(m_id, buffer, 12U); // Peer ID
if (m_debug)
Utils::dump(1U, "Network Transmitted, DMR", buffer, (32U + PACKET_PAD));
return write(buffer, (32U + PACKET_PAD));
}
/// <summary> /// <summary>
/// Writes the local activity log to the network. /// Writes the local activity log to the network.
/// </summary> /// </summary>

@ -68,6 +68,8 @@
#define TAG_MASTER_CLOSING "MSTCL" #define TAG_MASTER_CLOSING "MSTCL"
#define TAG_MASTER_PONG "MSTPONG" #define TAG_MASTER_PONG "MSTPONG"
#define TAG_MASTER_GRANT "MSTGRNT"
#define TAG_REPEATER_LOGIN "RPTL" #define TAG_REPEATER_LOGIN "RPTL"
#define TAG_REPEATER_AUTH "RPTK" #define TAG_REPEATER_AUTH "RPTK"
#define TAG_REPEATER_CONFIG "RPTC" #define TAG_REPEATER_CONFIG "RPTC"
@ -76,6 +78,8 @@
#define TAG_REPEATER_CLOSING "RPTCL" #define TAG_REPEATER_CLOSING "RPTCL"
#define TAG_REPEATER_PING "RPTPING" #define TAG_REPEATER_PING "RPTPING"
#define TAG_REPEATER_GRANT "RPTGRNT"
#define TAG_TRANSFER_ACT_LOG "TRNSLOG" #define TAG_TRANSFER_ACT_LOG "TRNSLOG"
#define TAG_TRANSFER_DIAG_LOG "TRNSDIAG" #define TAG_TRANSFER_DIAG_LOG "TRNSDIAG"
@ -118,18 +122,24 @@ namespace network
class HOST_SW_API BaseNetwork { class HOST_SW_API BaseNetwork {
public: public:
/// <summary>Initializes a new instance of the BaseNetwork class.</summary> /// <summary>Initializes a new instance of the BaseNetwork class.</summary>
BaseNetwork(uint16_t localPort, uint32_t id, bool duplex, bool debug, bool slot1, bool slot2, bool transferActivityLog, bool transferDiagnosticLog); BaseNetwork(uint16_t localPort, uint32_t id, bool duplex, bool debug, bool slot1, bool slot2, bool allowActivityTransfer, bool allowDiagnosticTransfer, bool handleChGrants);
/// <summary>Finalizes a instance of the BaseNetwork class.</summary> /// <summary>Finalizes a instance of the BaseNetwork class.</summary>
virtual ~BaseNetwork(); virtual ~BaseNetwork();
/// <summary>Gets the current status of the network.</summary> /// <summary>Gets the current status of the network.</summary>
NET_CONN_STATUS getStatus() { return m_status; } NET_CONN_STATUS getStatus() { return m_status; }
/// <summary>Gets the flag indicating if the network is handling channel grants.</summary>
bool isHandlingChGrants() { return m_handleChGrants; }
/// <summary>Reads DMR frame data from the DMR ring buffer.</summary> /// <summary>Reads DMR frame data from the DMR ring buffer.</summary>
virtual bool readDMR(dmr::data::Data& data); virtual bool readDMR(dmr::data::Data& data);
/// <summary>Reads P25 frame data from the P25 ring buffer.</summary> /// <summary>Reads P25 frame data from the P25 ring buffer.</summary>
virtual uint8_t* readP25(bool& ret, p25::lc::LC& control, p25::data::LowSpeedData& lsd, uint8_t& duid, uint32_t& len); virtual uint8_t* readP25(bool& ret, p25::lc::LC& control, p25::data::LowSpeedData& lsd, uint8_t& duid, uint32_t& len);
/// <summary>Reads a channel grant request from the network.</summary>
virtual bool readGrantRsp(bool& grp, uint32_t& srcId, uint32_t& dstId, uint32_t& grpVchNo);
/// <summary>Writes DMR frame data to the network.</summary> /// <summary>Writes DMR frame data to the network.</summary>
virtual bool writeDMR(const dmr::data::Data& data); virtual bool writeDMR(const dmr::data::Data& data);
/// <summary>Writes P25 LDU1 frame data to the network.</summary> /// <summary>Writes P25 LDU1 frame data to the network.</summary>
@ -144,6 +154,9 @@ namespace network
virtual bool writeP25PDU(const p25::data::DataHeader& header, const p25::data::DataHeader& secHeader, const uint8_t currentBlock, virtual bool writeP25PDU(const p25::data::DataHeader& header, const p25::data::DataHeader& secHeader, const uint8_t currentBlock,
const uint8_t* data, const uint32_t len); const uint8_t* data, const uint32_t len);
/// <summary>Writes a channel grant request to the network.</summary>
virtual bool writeGrantReq(const bool grp, const uint32_t srcId, const uint32_t dstId);
/// <summary>Writes the local activity log to the network.</summary> /// <summary>Writes the local activity log to the network.</summary>
virtual bool writeActLog(const char* message); virtual bool writeActLog(const char* message);
@ -172,6 +185,7 @@ namespace network
bool m_allowActivityTransfer; bool m_allowActivityTransfer;
bool m_allowDiagnosticTransfer; bool m_allowDiagnosticTransfer;
bool m_handleChGrants;
bool m_duplex; bool m_duplex;
bool m_debug; bool m_debug;
@ -193,6 +207,8 @@ namespace network
RingBuffer<uint8_t> m_rxDMRData; RingBuffer<uint8_t> m_rxDMRData;
RingBuffer<uint8_t> m_rxP25Data; RingBuffer<uint8_t> m_rxP25Data;
RingBuffer<uint8_t> m_rxGrantData;
p25::Audio m_audio; p25::Audio m_audio;
std::mt19937 m_random; std::mt19937 m_random;

@ -61,9 +61,10 @@ using namespace network;
/// <param name="allowActivityTransfer">Flag indicating that the system activity logs will be sent to the network.</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="allowDiagnosticTransfer">Flag indicating that the system diagnostic logs will be sent to the network.</param>
/// <param name="updateLookup">Flag indicating that the system will accept radio ID and talkgroup ID lookups from the network.</param> /// <param name="updateLookup">Flag indicating that the system will accept radio ID and talkgroup ID lookups from the network.</param>
/// <param name="handleChGrants">Flag indicating that the system will handle channel grants from the network.</param>
Network::Network(const std::string& address, uint16_t port, uint16_t local, uint32_t id, const std::string& password, Network::Network(const std::string& address, uint16_t port, uint16_t local, uint32_t id, const std::string& password,
bool duplex, bool debug, bool dmr, bool p25, bool slot1, bool slot2, bool allowActivityTransfer, bool allowDiagnosticTransfer, bool updateLookup) : bool duplex, bool debug, bool dmr, bool p25, bool slot1, bool slot2, bool allowActivityTransfer, bool allowDiagnosticTransfer, bool updateLookup, bool handleChGrants) :
BaseNetwork(local, id, duplex, debug, slot1, slot2, allowActivityTransfer, allowDiagnosticTransfer), BaseNetwork(local, id, duplex, debug, slot1, slot2, allowActivityTransfer, allowDiagnosticTransfer, handleChGrants),
m_address(address), m_address(address),
m_port(port), m_port(port),
m_password(password), m_password(password),
@ -351,6 +352,16 @@ void Network::clock(uint32_t ms)
else if (::memcmp(m_buffer, TAG_MASTER_PONG, 7U) == 0) { else if (::memcmp(m_buffer, TAG_MASTER_PONG, 7U) == 0) {
m_timeoutTimer.start(); m_timeoutTimer.start();
} }
else if (::memcmp(m_buffer, TAG_MASTER_GRANT, 7U) == 0) {
if (m_enabled && m_handleChGrants) {
if (m_debug)
Utils::dump(1U, "Network Received, Channel Grant", m_buffer, length);
uint8_t len = length;
m_rxGrantData.addData(&len, 1U);
m_rxGrantData.addData(m_buffer, len);
}
}
else { else {
Utils::dump("Unknown packet from the master", m_buffer, length); Utils::dump("Unknown packet from the master", m_buffer, length);
} }

@ -50,7 +50,7 @@ namespace network
public: public:
/// <summary>Initializes a new instance of the Network class.</summary> /// <summary>Initializes a new instance of the Network class.</summary>
Network(const std::string& address, uint16_t port, uint16_t local, uint32_t id, const std::string& password, Network(const std::string& address, uint16_t port, uint16_t local, uint32_t id, const std::string& password,
bool duplex, bool debug, bool dmr, bool p25, bool slot1, bool slot2, bool transferActivityLog, bool transferDiagnosticLog, bool updateLookup); bool duplex, bool debug, bool dmr, bool p25, bool slot1, bool slot2, bool transferActivityLog, bool transferDiagnosticLog, bool updateLookup, bool handleChGrants);
/// <summary>Finalizes a instance of the Network class.</summary> /// <summary>Finalizes a instance of the Network class.</summary>
~Network(); ~Network();

@ -1054,6 +1054,24 @@ void TrunkPacket::clearGrpAff(uint32_t dstId, bool releaseAll)
void TrunkPacket::clock(uint32_t ms) void TrunkPacket::clock(uint32_t ms)
{ {
if (m_p25->m_control) { if (m_p25->m_control) {
if (m_p25->m_network != NULL) {
if (m_p25->m_network->isHandlingChGrants() && m_p25->m_siteData.netActive()) {
bool grp = true;
uint32_t srcId = 0U;
uint32_t dstId = 0U;
uint32_t grpVchNo = 0U;
// do we have a grant response?
if (m_p25->m_network->readGrantRsp(grp, srcId, dstId, grpVchNo)) {
m_rfTSBK.setSrcId(srcId);
m_rfTSBK.setDstId(dstId);
m_rfTSBK.setGrpVchNo(grpVchNo);
writeRF_TSDU_Grant(grp, true, true, true);
}
}
}
// clock all the grant timers // clock all the grant timers
std::vector<uint32_t> gntsToRel = std::vector<uint32_t>(); std::vector<uint32_t> gntsToRel = std::vector<uint32_t>();
for (auto it = m_grantChTable.begin(); it != m_grantChTable.end(); ++it) { for (auto it = m_grantChTable.begin(); it != m_grantChTable.end(); ++it) {
@ -2021,8 +2039,9 @@ void TrunkPacket::queueRF_TSBK_Ctrl(uint8_t lco)
/// <param name="grp"></param> /// <param name="grp"></param>
/// <param name="skip"></param> /// <param name="skip"></param>
/// <param name="net"></param> /// <param name="net"></param>
/// <param name="skipNetCheck"></param>
/// <returns></returns> /// <returns></returns>
bool TrunkPacket::writeRF_TSDU_Grant(bool grp, bool skip, bool net) bool TrunkPacket::writeRF_TSDU_Grant(bool grp, bool skip, bool net, bool skipNetCheck)
{ {
uint8_t lco = m_rfTSBK.getLCO(); uint8_t lco = m_rfTSBK.getLCO();
@ -2030,6 +2049,13 @@ bool TrunkPacket::writeRF_TSDU_Grant(bool grp, bool skip, bool net)
return true; // do not generate grant packets for $FFFF (All Call) TGID return true; // do not generate grant packets for $FFFF (All Call) TGID
} }
// do we have a network connection and are we handling grants at the network?
if (m_p25->m_network != NULL) {
if (m_p25->m_network->isHandlingChGrants() && m_p25->m_siteData.netActive() && !skipNetCheck) {
return m_p25->m_network->writeGrantReq(grp, m_rfTSBK.getSrcId(), m_rfTSBK.getDstId());
}
}
// are we skipping checking? // are we skipping checking?
if (!skip) { if (!skip) {
if (m_p25->m_rfState != RS_RF_LISTENING && m_p25->m_rfState != RS_RF_DATA) { if (m_p25->m_rfState != RS_RF_LISTENING && m_p25->m_rfState != RS_RF_DATA) {

@ -198,7 +198,7 @@ namespace p25
void queueRF_TSBK_Ctrl(uint8_t lco); void queueRF_TSBK_Ctrl(uint8_t lco);
/// <summary>Helper to write a grant packet.</summary> /// <summary>Helper to write a grant packet.</summary>
bool writeRF_TSDU_Grant(bool grp, bool skip = false, bool net = false); bool writeRF_TSDU_Grant(bool grp, bool skip = false, bool net = false, bool skipNetCheck = false);
/// <summary>Helper to write a SNDCP grant packet.</summary> /// <summary>Helper to write a SNDCP grant packet.</summary>
bool writeRF_TSDU_SNDCP_Grant(bool skip = false, bool net = false); bool writeRF_TSDU_SNDCP_Grant(bool skip = false, bool net = false);
/// <summary>Helper to write a unit to unit answer request packet.</summary> /// <summary>Helper to write a unit to unit answer request packet.</summary>

Loading…
Cancel
Save

Powered by TurnKey Linux.