From abbe6cd41c7f516c7b15631c7a9102860a1c0cce Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Wed, 10 Jan 2024 12:47:05 -0500 Subject: [PATCH] properly queue FNE peer messages (these are distinct from peers connected *to* the FNE, FNE peer messages are messages sent to FNE masters that are "ISSI"ed); better handle logging activity logging; --- src/common/network/BaseNetwork.cpp | 5 +- src/common/network/BaseNetwork.h | 2 +- src/fne/ActivityLog.cpp | 161 ++++++++++++++++++++++++++++ src/fne/ActivityLog.h | 44 ++++++++ src/fne/FNEMain.cpp | 2 + src/fne/HostFNE.cpp | 6 ++ src/fne/network/FNENetwork.cpp | 8 +- src/fne/network/fne/TagDMRData.cpp | 5 +- src/fne/network/fne/TagNXDNData.cpp | 5 +- src/fne/network/fne/TagP25Data.cpp | 5 +- 10 files changed, 230 insertions(+), 13 deletions(-) create mode 100644 src/fne/ActivityLog.cpp create mode 100644 src/fne/ActivityLog.h diff --git a/src/common/network/BaseNetwork.cpp b/src/common/network/BaseNetwork.cpp index c8c89f78..079a5510 100644 --- a/src/common/network/BaseNetwork.cpp +++ b/src/common/network/BaseNetwork.cpp @@ -252,9 +252,12 @@ uint32_t BaseNetwork::getDMRStreamId(uint32_t slotNo) const /// Length of buffer to write. /// /// -bool BaseNetwork::writeMaster(FrameQueue::OpcodePair opcode, const uint8_t* data, uint32_t length, uint16_t pktSeq, uint32_t streamId) +/// +bool BaseNetwork::writeMaster(FrameQueue::OpcodePair opcode, const uint8_t* data, uint32_t length, uint16_t pktSeq, uint32_t streamId, bool queueOnly) { m_frameQueue->enqueueMessage(data, length, streamId, m_peerId, opcode, pktSeq, m_addr, m_addrLen); + if (queueOnly) + return true; return m_frameQueue->flushQueue(); } diff --git a/src/common/network/BaseNetwork.h b/src/common/network/BaseNetwork.h index 96dd06df..4b55de86 100644 --- a/src/common/network/BaseNetwork.h +++ b/src/common/network/BaseNetwork.h @@ -192,7 +192,7 @@ namespace network /// Helper to send a data message to the master. bool writeMaster(FrameQueue::OpcodePair opcode, const uint8_t* data, uint32_t length, - uint16_t pktSeq, uint32_t streamId); + uint16_t pktSeq, uint32_t streamId, bool queueOnly = false); /** Digital Mobile Radio */ /// Reads DMR raw frame data from the DMR ring buffer. diff --git a/src/fne/ActivityLog.cpp b/src/fne/ActivityLog.cpp new file mode 100644 index 00000000..0ee95111 --- /dev/null +++ b/src/fne/ActivityLog.cpp @@ -0,0 +1,161 @@ +/** +* Digital Voice Modem - Conference FNE Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Conference FNE Software +* +*/ +/* +* Copyright (C) 2024 by Bryan Biedenkapp N2PLL +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#include "ActivityLog.h" +#include "common/network/BaseNetwork.h" +#include "common/Log.h" // for CurrentLogFileLevel() and LogGetNetwork() + +#include + +#if defined(CATCH2_TEST_COMPILATION) +#include +#endif + +#include +#include +#include +#include +#include +#include + +// --------------------------------------------------------------------------- +// Constants +// --------------------------------------------------------------------------- + +#define EOL "\r\n" + +const uint32_t ACT_LOG_BUFFER_LEN = 501U; + +// --------------------------------------------------------------------------- +// Global Variables +// --------------------------------------------------------------------------- + +static std::string m_actFilePath; +static std::string m_actFileRoot; + +static FILE* m_actFpLog = nullptr; + +static struct tm m_actTm; + +// --------------------------------------------------------------------------- +// Global Functions +// --------------------------------------------------------------------------- + +/// +/// Helper to open the activity log file, file handle. +/// +/// True, if log file is opened, otherwise false. +static bool ActivityLogOpen() +{ + if (CurrentLogFileLevel() == 0U) + return true; + + time_t now; + ::time(&now); + + struct tm* tm = ::gmtime(&now); + + if (tm->tm_mday == m_actTm.tm_mday && tm->tm_mon == m_actTm.tm_mon && tm->tm_year == m_actTm.tm_year) { + if (m_actFpLog != nullptr) + return true; + } + else { + if (m_actFpLog != nullptr) + ::fclose(m_actFpLog); + } + + char filename[200U]; + ::sprintf(filename, "%s/%s-%04d-%02d-%02d.activity.log", LogGetFilePath().c_str(), LogGetFileRoot().c_str(), tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); + + m_actFpLog = ::fopen(filename, "a+t"); + m_actTm = *tm; + + return m_actFpLog != nullptr; +} + +/// +/// Initializes the activity log. +/// +/// Full-path to the activity log file. +/// Prefix of the activity log file name. +bool ActivityLogInitialise(const std::string& filePath, const std::string& fileRoot) +{ +#if defined(CATCH2_TEST_COMPILATION) + return true; +#endif + m_actFilePath = filePath; + m_actFileRoot = fileRoot; + + return ::ActivityLogOpen(); +} + +/// +/// Finalizes the activity log. +/// +void ActivityLogFinalise() +{ +#if defined(CATCH2_TEST_COMPILATION) + return; +#endif + if (m_actFpLog != nullptr) + ::fclose(m_actFpLog); +} + +/// +/// Writes a new entry to the activity log. +/// +/// This is a variable argument function. +/// Formatted string to write to activity log. +void ActivityLog(const char* msg, ...) +{ +#if defined(CATCH2_TEST_COMPILATION) + return; +#endif + assert(msg != nullptr); + + char buffer[ACT_LOG_BUFFER_LEN]; + + va_list vl; + va_start(vl, msg); + + ::vsnprintf(buffer, ACT_LOG_BUFFER_LEN - 1U, msg, vl); + + va_end(vl); + + bool ret = ::ActivityLogOpen(); + if (!ret) + return; + + if (CurrentLogFileLevel() == 0U) + return; + + ::fprintf(m_actFpLog, "%s\n", buffer); + ::fflush(m_actFpLog); + + if (2U >= g_logDisplayLevel && g_logDisplayLevel != 0U) { + ::fprintf(stdout, "%s" EOL, buffer); + ::fflush(stdout); + } +} diff --git a/src/fne/ActivityLog.h b/src/fne/ActivityLog.h new file mode 100644 index 00000000..3d5282f3 --- /dev/null +++ b/src/fne/ActivityLog.h @@ -0,0 +1,44 @@ +/** +* Digital Voice Modem - Conference FNE Software +* GPLv2 Open Source. Use is subject to license terms. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* @package DVM / Conference FNE Software +* +*/ +/* +* Copyright (C) 2024 by Bryan Biedenkapp N2PLL +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if !defined(__ACTIVITY_LOG_H__) +#define __ACTIVITY_LOG_H__ + +#include "Defines.h" + +#include + +// --------------------------------------------------------------------------- +// Global Functions +// --------------------------------------------------------------------------- + +/// Initializes the activity log. +extern HOST_SW_API bool ActivityLogInitialise(const std::string& filePath, const std::string& fileRoot); +/// Finalizes the activity log. +extern HOST_SW_API void ActivityLogFinalise(); +/// Writes a new entry to the activity log. +extern HOST_SW_API void ActivityLog(const char* msg, ...); + +#endif // __ACTIVITY_LOG_H__ diff --git a/src/fne/FNEMain.cpp b/src/fne/FNEMain.cpp index 86bddc30..0c6e2d9f 100644 --- a/src/fne/FNEMain.cpp +++ b/src/fne/FNEMain.cpp @@ -30,6 +30,7 @@ */ #include "Defines.h" #include "common/Log.h" +#include "ActivityLog.h" #include "FNEMain.h" #include "HostFNE.h" @@ -248,6 +249,7 @@ int main(int argc, char** argv) } while (g_signal == 1); ::LogFinalise(); + ::ActivityLogFinalise(); return ret; } diff --git a/src/fne/HostFNE.cpp b/src/fne/HostFNE.cpp index 3021448a..18f1b6da 100644 --- a/src/fne/HostFNE.cpp +++ b/src/fne/HostFNE.cpp @@ -32,6 +32,7 @@ #include "network/fne/TagDMRData.h" #include "network/fne/TagP25Data.h" #include "network/fne/TagNXDNData.h" +#include "ActivityLog.h" #include "HostFNE.h" #include "FNEMain.h" @@ -121,6 +122,11 @@ int HostFNE::run() ::fatal("unable to open the log file\n"); } + ret = ::ActivityLogInitialise(logConf["activityFilePath"].as(), logConf["fileRoot"].as()); + if (!ret) { + ::fatal("unable to open the activity log file\n"); + } + // handle POSIX process forking if (m_daemon) { // create new process diff --git a/src/fne/network/FNENetwork.cpp b/src/fne/network/FNENetwork.cpp index 033b0415..8265a27f 100644 --- a/src/fne/network/FNENetwork.cpp +++ b/src/fne/network/FNENetwork.cpp @@ -7,7 +7,7 @@ * */ /* -* Copyright (C) 2023 by Bryan Biedenkapp N2PLL +* Copyright (C) 2023-2024 by Bryan Biedenkapp N2PLL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +33,7 @@ #include "network/fne/TagDMRData.h" #include "network/fne/TagP25Data.h" #include "network/fne/TagNXDNData.h" +#include "fne/ActivityLog.h" #include "HostFNE.h" using namespace network; @@ -539,10 +540,7 @@ void FNENetwork::clock(uint32_t ms) ::memcpy(rawPayload, buffer.get() + 11U, length - 11U); std::string payload(rawPayload, rawPayload + (length - 11U)); - std::stringstream ss; - ss << peerId << " " << payload; - - ::Log(9999U, nullptr, "%s", ss.str().c_str()); + ::ActivityLog("%u %s", peerId, payload.c_str()); } else { writePeerNAK(peerId, TAG_TRANSFER_ACT_LOG); diff --git a/src/fne/network/fne/TagDMRData.cpp b/src/fne/network/fne/TagDMRData.cpp index f5c4b0f7..91382b17 100644 --- a/src/fne/network/fne/TagDMRData.cpp +++ b/src/fne/network/fne/TagDMRData.cpp @@ -239,6 +239,7 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId m_network->m_callInProgress = true; } } + m_network->m_frameQueue->flushQueue(); // repeat traffic to upstream peers if (m_network->m_host->m_peerNetworks.size() > 0 && !tg.config().parrot()) { @@ -257,11 +258,11 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId // perform TGID route rewrites if configured routeRewrite(outboundPeerBuffer, peerId, dmrData, dataType, dstId, slotNo); - peer.second->writeMaster({ NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_DMR }, outboundPeerBuffer, len, pktSeq, streamId); + peer.second->writeMaster({ NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_DMR }, outboundPeerBuffer, len, pktSeq, streamId, true); } } - m_network->m_frameQueue->flushQueue(); + return true; } diff --git a/src/fne/network/fne/TagNXDNData.cpp b/src/fne/network/fne/TagNXDNData.cpp index 5c6e0883..cf4d80b4 100644 --- a/src/fne/network/fne/TagNXDNData.cpp +++ b/src/fne/network/fne/TagNXDNData.cpp @@ -209,6 +209,7 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI m_network->m_callInProgress = true; } } + m_network->m_frameQueue->flushQueue(); // repeat traffic to upstream peers if (m_network->m_host->m_peerNetworks.size() > 0 && !tg.config().parrot()) { @@ -227,11 +228,11 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI // perform TGID route rewrites if configured routeRewrite(outboundPeerBuffer, peerId, messageType, dstId); - peer.second->writeMaster({ NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_NXDN }, outboundPeerBuffer, len, pktSeq, streamId); + peer.second->writeMaster({ NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_NXDN }, outboundPeerBuffer, len, pktSeq, streamId, true); } } - m_network->m_frameQueue->flushQueue(); + return true; } diff --git a/src/fne/network/fne/TagP25Data.cpp b/src/fne/network/fne/TagP25Data.cpp index 38c41f7f..05f35431 100644 --- a/src/fne/network/fne/TagP25Data.cpp +++ b/src/fne/network/fne/TagP25Data.cpp @@ -252,6 +252,7 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId m_network->m_callInProgress = true; } } + m_network->m_frameQueue->flushQueue(); // repeat traffic to upstream peers if (m_network->m_host->m_peerNetworks.size() > 0 && !tg.config().parrot()) { @@ -270,11 +271,11 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId // perform TGID route rewrites if configured routeRewrite(outboundPeerBuffer, peerId, duid, dstId); - peer.second->writeMaster({ NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, outboundPeerBuffer, len, pktSeq, streamId); + peer.second->writeMaster({ NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, outboundPeerBuffer, len, pktSeq, streamId, true); } } - m_network->m_frameQueue->flushQueue(); + return true; }