You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dvmhost/src/patch/HostPatch.h

227 lines
6.0 KiB

// SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - TG Patch
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
*
*/
/**
* @file HostPatch.h
* @ingroup patch
* @file HostPatch.cpp
* @ingroup patch
*/
#if !defined(__HOST_PATCH_H__)
#define __HOST_PATCH_H__
#include "Defines.h"
#include "common/dmr/data/EmbeddedData.h"
#include "common/dmr/lc/LC.h"
#include "common/dmr/lc/PrivacyLC.h"
#include "common/p25/lc/LC.h"
#include "common/p25/Crypto.h"
#include "common/network/udp/Socket.h"
#include "common/yaml/Yaml.h"
#include "common/Timer.h"
#include "network/PeerNetwork.h"
#include "mmdvm/P25Network.h"
#include <string>
#include <mutex>
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const uint8_t TX_MODE_DMR = 1U;
const uint8_t TX_MODE_P25 = 2U;
// ---------------------------------------------------------------------------
// Class Declaration
// ---------------------------------------------------------------------------
/**
* @brief This class implements the core service logic.
* @ingroup bridge
*/
class HOST_SW_API HostPatch {
public:
/**
* @brief Initializes a new instance of the HostPatch class.
* @param confFile Full-path to the configuration file.
*/
HostPatch(const std::string& confFile);
/**
* @brief Finalizes a instance of the HostPatch class.
*/
~HostPatch();
/**
* @brief Executes the main host processing loop.
* @returns int Zero if successful, otherwise error occurred.
*/
int run();
private:
const std::string& m_confFile;
yaml::Node m_conf;
network::PeerNetwork* m_network;
uint32_t m_srcTGId;
uint8_t m_srcSlot;
uint32_t m_dstTGId;
uint8_t m_dstSlot;
bool m_twoWayPatch;
bool m_mmdvmP25Reflector;
mmdvm::P25Network* m_mmdvmP25Net;
uint16_t m_dropTimeMS;
Timer m_callDropTime;
RPT_NET_STATE m_netState;
p25::lc::LC m_netLC;
bool m_gotNetLDU1;
uint8_t* m_netLDU1;
bool m_gotNetLDU2;
uint8_t* m_netLDU2;
std::string m_identity;
uint8_t m_digiMode;
dmr::data::EmbeddedData m_dmrEmbeddedData;
bool m_grantDemand;
bool m_callInProgress;
uint32_t m_callDstId;
uint8_t m_callSlotNo;
uint8_t m_callAlgoId;
uint64_t m_rxStartTime;
uint32_t m_rxStreamId;
bool m_tekSrcEnable;
uint8_t m_tekSrcAlgoId;
uint16_t m_tekSrcKeyId;
bool m_tekDstEnable;
uint8_t m_tekDstAlgoId;
uint16_t m_tekDstKeyId;
bool m_requestedSrcTek;
bool m_requestedDstTek;
p25::crypto::P25Crypto* m_p25SrcCrypto;
p25::crypto::P25Crypto* m_p25DstCrypto;
uint32_t m_netId;
uint32_t m_sysId;
bool m_running;
bool m_trace;
bool m_debug;
static std::mutex s_networkMutex;
/**
* @brief Reads basic configuration parameters from the INI.
* @returns bool True, if configuration was read successfully, otherwise false.
*/
bool readParams();
/**
* @brief Initializes network connectivity.
* @returns bool True, if network connectivity was initialized, otherwise false.
*/
bool createNetwork();
/**
* @brief Initializes MMDVM network connectivity.
* @returns bool True, if network connectivity was initialized, otherwise false.
*/
bool createMMDVMP25Network();
/**
* @brief Helper to process DMR network traffic.
* @param buffer
* @param length
*/
void processDMRNetwork(uint8_t* buffer, uint32_t length);
/**
* @brief Helper to process P25 network traffic.
* @param buffer
* @param length
*/
void processP25Network(uint8_t* buffer, uint32_t length);
/**
* @brief Helper to reset DMR call state.
* @param srcId Source ID.
* @param slotNo DMR slot.
*/
void resetDMRCall(uint32_t srcId, uint8_t slotNo);
/**
* @brief Helper to reset P25 call state.
* @param srcId Source ID.
*/
void resetP25Call(uint32_t srcId);
/**
* @brief Helper to cross encrypt P25 network traffic audio frames.
* @param ldu
* @param reverseEncrypt Flag indicating whether or not to reverse the encryption (i.e. use destination TEK vs source TEK).
* @param p25N
*/
void cryptP25AudioFrame(uint8_t* ldu, bool reverseEncrypt, uint8_t p25N);
/**
* @brief Helper to process a FNE KMM TEK response.
* @param ki Key Item.
* @param algId Algorithm ID.
* @param keyLength Length of key in bytes.
*/
void processTEKResponse(p25::kmm::KeyItem* ki, uint8_t algId, uint8_t keyLength);
/**
* @brief Helper to check for an unflushed LDU1 packet.
*/
void checkNet_LDU1();
/**
* @brief Helper to write a network P25 LDU1 packet.
* @param toFNE Flag indicating whether or not the packet is being written to the DVM FNE.
*/
void writeNet_LDU1(bool toFNE);
/**
* @brief Helper to check for an unflushed LDU2 packet.
*/
void checkNet_LDU2();
/**
* @brief Helper to write a network P25 LDU2 packet.
* @param toFNE Flag indicating whether or not the packet is being written to the DVM FNE.
*/
void writeNet_LDU2(bool toFNE);
/**
* @brief Entry point to network processing thread.
* @param arg Instance of the thread_t structure.
* @returns void* (Ignore)
*/
static void* threadNetworkProcess(void* arg);
/**
* @brief Entry point to MMDVM network processing thread.
* @param arg Instance of the thread_t structure.
* @returns void* (Ignore)
*/
static void* threadMMDVMProcess(void* arg);
/**
* @brief Helper to reset IMBE buffer with null frames.
* @param data Buffer containing frame data.
* @param encrypted Flag indicating whether or not the data is encrypted.
*/
void resetWithNullAudio(uint8_t* data, bool encrypted);
};
#endif // __HOST_PATCH_H__

Powered by TurnKey Linux.