/** * Digital Voice Modem - Host Software * GPLv2 Open Source. Use is subject to license terms. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * @package DVM / Host Software * */ // // Based on code from the MMDVMHost project. (https://github.com/g4klx/MMDVMHost) // Licensed under the GPLv2 License (https://opensource.org/licenses/GPL-2.0) // /* * Copyright (C) 2016,2017 by Jonathan Naylor G4KLX * Copyright (C) 2017-2022 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(__P25_CONTROL_H__) #define __P25_CONTROL_H__ #include "Defines.h" #include "p25/packet/Trunk.h" #include "p25/packet/Data.h" #include "p25/packet/Voice.h" #include "p25/NID.h" #include "p25/SiteData.h" #include "network/BaseNetwork.h" #include "network/RemoteControl.h" #include "lookups/RSSIInterpolator.h" #include "lookups/IdenTableLookup.h" #include "lookups/RadioIdLookup.h" #include "lookups/TalkgroupIdLookup.h" #include "modem/Modem.h" #include "RingBuffer.h" #include "Timer.h" #include "yaml/Yaml.h" #include namespace p25 { // --------------------------------------------------------------------------- // Class Prototypes // --------------------------------------------------------------------------- namespace packet { class HOST_SW_API Voice; } namespace dfsi { namespace packet { class HOST_SW_API DFSIVoice; } } namespace packet { class HOST_SW_API Data; } namespace packet { class HOST_SW_API Trunk; } namespace dfsi { namespace packet { class HOST_SW_API DFSITrunk; } } // --------------------------------------------------------------------------- // Class Declaration // This class implements core logic for handling P25. // --------------------------------------------------------------------------- class HOST_SW_API Control { public: /// Initializes a new instance of the Control class. Control(uint32_t nac, uint32_t callHang, uint32_t queueSize, modem::Modem* modem, network::BaseNetwork* network, uint32_t timeout, uint32_t tgHang, bool duplex, lookups::RadioIdLookup* ridLookup, lookups::TalkgroupIdLookup* tidLookup, lookups::IdenTableLookup* idenTable, lookups::RSSIInterpolator* rssiMapper, bool dumpPDUData, bool repeatPDU, bool dumpTSBKData, bool debug, bool verbose); /// Finalizes a instance of the Control class. ~Control(); /// Resets the data states for the RF interface. void reset(); /// Helper to set P25 configuration options. void setOptions(yaml::Node& conf, const std::string cwCallsign, const std::vector voiceChNo, uint32_t pSuperGroup, uint32_t netId, uint32_t sysId, uint8_t rfssId, uint8_t siteId, uint8_t channelId, uint32_t channelNo, bool printOptions); /// Gets a flag indicating whether the P25 control channel is running. bool getCCRunning() { return m_ccRunning; } /// Sets a flag indicating whether the P25 control channel is running. void setCCRunning(bool ccRunning) { m_ccPrevRunning = m_ccRunning; m_ccRunning = ccRunning; } /// Gets a flag indicating whether the P25 control channel is running. bool getCCHalted() { return m_ccHalted; } /// Sets a flag indicating whether the P25 control channel is halted. void setCCHalted(bool ccHalted) { m_ccHalted = ccHalted; } /// Process a data frame from the RF interface. bool processFrame(uint8_t* data, uint32_t len); /// Get frame data from data ring buffer. uint32_t getFrame(uint8_t* data); /// Helper to write P25 adjacent site information to the network. void writeAdjSSNetwork(); /// Helper to write end of voice call frame data. bool writeRF_VoiceEnd(); /// Updates the processor by the passed number of milliseconds. void clock(uint32_t ms); /// Gets instance of the NID class. NID nid() { return m_nid; } /// Gets instance of the Trunk class. packet::Trunk* trunk() { return m_trunk; } /// Helper to change the debug and verbose state. void setDebugVerbose(bool debug, bool verbose); private: friend class packet::Voice; friend class dfsi::packet::DFSIVoice; packet::Voice* m_voice; friend class packet::Data; packet::Data* m_data; friend class packet::Trunk; friend class dfsi::packet::DFSITrunk; packet::Trunk* m_trunk; uint32_t m_nac; uint32_t m_txNAC; uint32_t m_timeout; modem::Modem* m_modem; network::BaseNetwork* m_network; bool m_inhibitIllegal; bool m_legacyGroupGrnt; bool m_legacyGroupReg; bool m_duplex; bool m_control; bool m_dedicatedControl; bool m_voiceOnControl; bool m_ackTSBKRequests; bool m_disableNetworkHDU; lookups::IdenTableLookup* m_idenTable; lookups::RadioIdLookup* m_ridLookup; lookups::TalkgroupIdLookup* m_tidLookup; lookups::IdenTable m_idenEntry; RingBuffer m_queue; RPT_RF_STATE m_rfState; uint32_t m_rfLastDstId; RPT_NET_STATE m_netState; uint32_t m_netLastDstId; bool m_tailOnIdle; bool m_ccRunning; bool m_ccPrevRunning; bool m_ccHalted; Timer m_rfTimeout; Timer m_rfTGHang; Timer m_netTimeout; Timer m_networkWatchdog; Timer m_ccPacketInterval; uint32_t m_hangCount; uint32_t m_tduPreambleCount; uint8_t m_ccFrameCnt; uint8_t m_ccSeq; NID m_nid; SiteData m_siteData; lookups::RSSIInterpolator* m_rssiMapper; uint8_t m_rssi; uint8_t m_maxRSSI; uint8_t m_minRSSI; uint32_t m_aveRSSI; uint32_t m_rssiCount; bool m_writeImmediate; // This is essentially a "latch" that will auto-reset after a writeRF_Queue() call. bool m_verbose; bool m_debug; /// Add data frame to the data ring buffer. void addFrame(const uint8_t* data, uint32_t length, bool net = false); #if ENABLE_DFSI_SUPPORT /// Process a DFSI data frame from the RF interface. bool processDFSI(uint8_t* data, uint32_t len); #endif /// Process a data frames from the network. void processNetwork(); /// Helper to write control channel frame data. bool writeRF_ControlData(); /// Helper to write end of control channel frame data. bool writeRF_ControlEnd(); /// Helper to write data nulls. void writeRF_Nulls(); /// Helper to write TDU preamble packet burst. void writeRF_Preamble(uint32_t preambleCount = 0, bool force = false); /// Helper to write a P25 TDU packet. void writeRF_TDU(bool noNetwork); /// Helper to set the busy status bits on P25 frame data. void setBusyBits(uint8_t* data, uint32_t ssOffset, bool b1, bool b2); /// Helper to add the busy status bits on P25 frame data. void addBusyBits(uint8_t* data, uint32_t length, bool b1, bool b2); }; } // namespace p25 #endif // __P25_CONTROL_H__