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.
713 lines
22 KiB
713 lines
22 KiB
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Digital Voice Modem - Modem Host Software
|
|
* GPLv2 Open Source. Use is subject to license terms.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright (C) 2024-2025 Bryan Biedenkapp, N2PLL
|
|
*
|
|
*/
|
|
/**
|
|
* @file ModemV24.h
|
|
* @ingroup modem
|
|
* @file ModemV24.cpp
|
|
* @ingroup modem
|
|
*/
|
|
#if !defined(__MODEM_V24_H__)
|
|
#define __MODEM_V24_H__
|
|
|
|
#include "Defines.h"
|
|
#include "common/edac/RS634717.h"
|
|
#include "common/p25/data/DataHeader.h"
|
|
#include "common/p25/data/DataBlock.h"
|
|
#include "common/p25/lc/LC.h"
|
|
#include "common/p25/Audio.h"
|
|
#include "common/p25/NID.h"
|
|
#include "modem/Modem.h"
|
|
|
|
namespace modem
|
|
{
|
|
// ---------------------------------------------------------------------------
|
|
// Constants
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @addtogroup modem
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief DFSI serial tx flags used to determine proper jitter handling of data in ringbuffer.
|
|
* @ingroup modem
|
|
*/
|
|
enum SERIAL_TX_TYPE {
|
|
STT_NO_DATA, //!< No Data
|
|
STT_START_STOP, //!< Start/Stop Signalling Frame
|
|
STT_START_STOP_NO_JITTER, //!< Start/Stop Signalling Frame with Jitter Disabled
|
|
STT_DATA, //!< Paced Data/Signalling Frame or IMBE Voice Frame
|
|
STT_DATA_FAST //!< Fast Paced Data/Signalling Frame
|
|
};
|
|
|
|
/** @} */
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Class Declaration
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @brief Represents DFSI call data.
|
|
* @ingroup modem
|
|
*/
|
|
class HOST_SW_API DFSICallData {
|
|
public:
|
|
auto operator=(DFSICallData&) -> DFSICallData& = delete;
|
|
auto operator=(DFSICallData&&) -> DFSICallData& = delete;
|
|
DFSICallData(DFSICallData&) = delete;
|
|
|
|
/**
|
|
* @brief Initializes a new instance of the DFSICallData class.
|
|
*/
|
|
DFSICallData() :
|
|
srcId(0U),
|
|
dstId(0U),
|
|
lco(0U),
|
|
mfId(P25DEF::MFG_STANDARD),
|
|
serviceOptions(0U),
|
|
lsd1(0U),
|
|
lsd2(0U),
|
|
MI(nullptr),
|
|
algoId(P25DEF::ALGO_UNENCRYPT),
|
|
kId(0U),
|
|
VHDR1(nullptr),
|
|
VHDR2(nullptr),
|
|
LDULC(nullptr),
|
|
seqNo(0U),
|
|
n(0U),
|
|
netLDU1(nullptr),
|
|
netLDU2(nullptr),
|
|
pduUserData(nullptr),
|
|
dataHeader(nullptr),
|
|
dataCall(false),
|
|
pduUserDataOffset(0U),
|
|
pduTotalBlocks(0U),
|
|
errors(0U)
|
|
{
|
|
MI = new uint8_t[P25DEF::MI_LENGTH_BYTES];
|
|
VHDR1 = new uint8_t[P25DFSIDEF::DFSI_MOT_VHDR_1_LEN];
|
|
VHDR2 = new uint8_t[P25DFSIDEF::DFSI_MOT_VHDR_2_LEN];
|
|
LDULC = new uint8_t[P25DEF::P25_LDU_LC_FEC_LENGTH_BYTES];
|
|
|
|
netLDU1 = new uint8_t[9U * 25U];
|
|
netLDU2 = new uint8_t[9U * 25U];
|
|
|
|
::memset(netLDU1, 0x00U, 9U * 25U);
|
|
::memset(netLDU2, 0x00U, 9U * 25U);
|
|
|
|
pduUserData = new uint8_t[P25DEF::P25_MAX_PDU_BLOCKS * P25DEF::P25_PDU_CONFIRMED_LENGTH_BYTES + 2U];
|
|
::memset(pduUserData, 0x00U, P25DEF::P25_MAX_PDU_BLOCKS * P25DEF::P25_PDU_CONFIRMED_LENGTH_BYTES + 2U);
|
|
|
|
resetCallData();
|
|
}
|
|
/**
|
|
* @brief Finalizes a instance of the DFSICallData class.
|
|
*/
|
|
~DFSICallData()
|
|
{
|
|
if (MI != nullptr) {
|
|
delete[] MI;
|
|
MI = nullptr;
|
|
}
|
|
if (VHDR1 != nullptr) {
|
|
delete[] VHDR1;
|
|
VHDR1 = nullptr;
|
|
}
|
|
if (VHDR2 != nullptr) {
|
|
delete[] VHDR2;
|
|
VHDR2 = nullptr;
|
|
}
|
|
if (LDULC != nullptr) {
|
|
delete[] LDULC;
|
|
LDULC = nullptr;
|
|
}
|
|
if (netLDU1 != nullptr) {
|
|
delete[] netLDU1;
|
|
netLDU1 = nullptr;
|
|
}
|
|
if (netLDU2 != nullptr) {
|
|
delete[] netLDU2;
|
|
netLDU2 = nullptr;
|
|
}
|
|
if (pduUserData != nullptr) {
|
|
delete[] pduUserData;
|
|
pduUserData = nullptr;
|
|
}
|
|
if (dataHeader != nullptr) {
|
|
delete dataHeader;
|
|
dataHeader = nullptr;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Helper to reset the call data associated with this connection.
|
|
*/
|
|
void resetCallData()
|
|
{
|
|
srcId = 0U;
|
|
dstId = 0U;
|
|
|
|
lco = 0U;
|
|
mfId = P25DEF::MFG_STANDARD;
|
|
serviceOptions = 0U;
|
|
|
|
lsd1 = 0U;
|
|
lsd2 = 0U;
|
|
|
|
if (MI != nullptr)
|
|
::memset(MI, 0x00U, P25DEF::MI_LENGTH_BYTES);
|
|
algoId = P25DEF::ALGO_UNENCRYPT;
|
|
kId = 0U;
|
|
|
|
if (VHDR1 != nullptr)
|
|
::memset(VHDR1, 0x00U, P25DFSIDEF::DFSI_MOT_VHDR_1_LEN);
|
|
if (VHDR2 != nullptr)
|
|
::memset(VHDR2, 0x00U, P25DFSIDEF::DFSI_MOT_VHDR_2_LEN);
|
|
|
|
if (LDULC != nullptr)
|
|
::memset(LDULC, 0x00U, P25DEF::P25_LDU_LC_FEC_LENGTH_BYTES);
|
|
|
|
if (netLDU1 != nullptr)
|
|
::memset(netLDU1, 0x00U, 9U * 25U);
|
|
if (netLDU2 != nullptr)
|
|
::memset(netLDU2, 0x00U, 9U * 25U);
|
|
|
|
n = 0U;
|
|
seqNo = 0U;
|
|
|
|
if (pduUserData != nullptr)
|
|
::memset(pduUserData, 0x00U, P25DEF::P25_MAX_PDU_BLOCKS * P25DEF::P25_PDU_CONFIRMED_LENGTH_BYTES + 2U);
|
|
if (dataHeader != nullptr)
|
|
dataHeader->reset();
|
|
|
|
dataCall = false;
|
|
pduUserDataOffset = 0U;
|
|
pduTotalBlocks = 0U;
|
|
|
|
errors = 0U;
|
|
}
|
|
|
|
public:
|
|
/** @name Call Data */
|
|
/**
|
|
* @brief Source Radio ID.
|
|
*/
|
|
uint32_t srcId;
|
|
/**
|
|
* @brief Destination ID.
|
|
*/
|
|
uint32_t dstId;
|
|
|
|
/**
|
|
* @brief Link Control Opcode.
|
|
*/
|
|
uint8_t lco;
|
|
/**
|
|
* @brief Manufacturer ID.
|
|
*/
|
|
uint8_t mfId;
|
|
/**
|
|
* @brief Call Service Options.
|
|
*/
|
|
uint8_t serviceOptions;
|
|
|
|
/**
|
|
* @brief Low Speed Data 1.
|
|
*/
|
|
uint8_t lsd1;
|
|
/**
|
|
* @brief Low Speed Data 2.
|
|
*/
|
|
uint8_t lsd2;
|
|
|
|
/**
|
|
* @brief Encryption Message Indicator.
|
|
*/
|
|
uint8_t* MI;
|
|
/**
|
|
* @brief Encryption Algorithm ID.
|
|
*/
|
|
uint8_t algoId;
|
|
/**
|
|
* @brief Encryption Key ID.
|
|
*/
|
|
uint32_t kId;
|
|
|
|
/**
|
|
* @brief Voice Header 1.
|
|
*/
|
|
uint8_t* VHDR1;
|
|
/**
|
|
* @brief Voice Header 2.
|
|
*/
|
|
uint8_t* VHDR2;
|
|
|
|
/**
|
|
* @brief LDU LC.
|
|
*/
|
|
uint8_t* LDULC;
|
|
|
|
/**
|
|
* @brief Sequence Number.
|
|
*/
|
|
uint32_t seqNo;
|
|
/**
|
|
* @brief
|
|
*/
|
|
uint8_t n;
|
|
|
|
/**
|
|
* @brief LDU1 Buffer.
|
|
*/
|
|
uint8_t* netLDU1;
|
|
/**
|
|
* @brief LDU2 Buffer.
|
|
*/
|
|
uint8_t* netLDU2;
|
|
|
|
/**
|
|
* @brief User data associated with this call.
|
|
*/
|
|
uint8_t* pduUserData;
|
|
/**
|
|
* @brief Data call header.
|
|
*/
|
|
p25::data::DataHeader* dataHeader;
|
|
|
|
/**
|
|
* @brief Flag indicating the current call is a data call.
|
|
*/
|
|
bool dataCall;
|
|
/**
|
|
* @brief Offset index when populating the user data buffer.
|
|
*/
|
|
uint32_t pduUserDataOffset;
|
|
/**
|
|
* @brief Total count of PDU blocks.
|
|
*/
|
|
uint32_t pduTotalBlocks;
|
|
|
|
/**
|
|
* @brief Total errors for a given call sequence.
|
|
*/
|
|
uint32_t errors;
|
|
/** @} */
|
|
};
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Class Declaration
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/**
|
|
* @brief Implements the core interface to the V.24 modem hardware.
|
|
* \code{.unparsed}
|
|
* This is the format of the Motorola V.24 DFSI Voice Headers:
|
|
*
|
|
* Voice Header 1 (VHDR1):
|
|
* Bit 7 6 5 4 3 2 1 0
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | FT | 0
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | Start of Strm | 1 - 9
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S0 | G0 | 10
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S1 | G1 | 11
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S2 | G2 | 12
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S3 | G3 | 13
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S4 | G4 | 14
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S5 | G5 | 15
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S6 | G6 | 16
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S7 | G7 | 17
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | S7...S0 | 18
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S8 | G8 | 19
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S9 | G9 | 20
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S10| G10 | 21
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S11| G11 | 22
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S12| G12 | 23
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S13| G13 | 24
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S14| G14 | 25
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S15| G15 | 26
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | S15...S8 | 27
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S16| G16 | 26
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S17| G17 | 28
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |7|6| Rsvd |Bsy| 29
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | Rsvd | 30
|
|
* +-+-+-+-+-+-+-+-+
|
|
*
|
|
* Voice Header 2 (VHDR2):
|
|
* Bit 7 6 5 4 3 2 1 0
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | FT | 0
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S18| G18 | 1
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S19| G19 | 2
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S20| G20 | 3
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S21| G21 | 4
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S22| G22 | 5
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S23| G23 | 6
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S24| G24 | 7
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S25| G25 | 8
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | S25...S18 | 9
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S26| G26 | 10
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S27| G27 | 11
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S28| G28 | 12
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S29| G29 | 13
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S30| G30 | 14
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S31| G31 | 15
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S32| G32 | 16
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S33| G33 | 17
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | S33...S26 | 18
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S34| G34 | 19
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S35| G35 | 20
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |5|4| Rsvd |Bsy| 21
|
|
* +-+-+-+-+-+-+-+-+
|
|
*
|
|
* This is the format of the TIA-102.BAHA DFSI Voice Headers:
|
|
*
|
|
* TIA-102.BAHA Voice Header 1 (VHDR1):
|
|
* Bit 7 6 5 4 3 2 1 0
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | FT | 0
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S0 | G0 | 1
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S1 | G1 | 2
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S2 | G2 | 3
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S3 | G3 | 4
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S4 | G4 | 5
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S5 | G5 | 6
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S6 | G6 | 7
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S7 | G7 | 8
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S8 | G8 | 9
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S9 | G9 | 10
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S10| G10 | 11
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S11| G11 | 12
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S12| G12 | 13
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S13| G13 | 14
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S14| G14 | 15
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S15| G15 | 16
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S16| G16 | 17
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S17| G17 | 18
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | Rsvd |7|6| 19
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | S15...S0 | 20
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | S15...S0 | 21
|
|
* +-+-+-+-+-+-+-+-+
|
|
*
|
|
* TIA-102.BAHA Voice Header 2 (VHDR2):
|
|
* Bit 7 6 5 4 3 2 1 0
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | FT | 0
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S18| G18 | 1
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S19| G19 | 2
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S20| G20 | 3
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S21| G21 | 4
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S22| G22 | 5
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S23| G23 | 6
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S24| G24 | 7
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S25| G25 | 8
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S26| G26 | 9
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S27| G27 | 10
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S28| G28 | 11
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S29| G29 | 12
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S30| G30 | 13
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S31| G31 | 14
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S32| G32 | 15
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S33| G33 | 16
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S34| G34 | 17
|
|
* +-+-+-+-+-+-+-+-+
|
|
* |S35| G35 | 18
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | Rsvd |5|4| 19
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | S33...S18 | 20
|
|
* +-+-+-+-+-+-+-+-+
|
|
* | S33...S18 | 21
|
|
* +-+-+-+-+-+-+-+-+
|
|
* \endcode
|
|
* @ingroup modem
|
|
*/
|
|
class HOST_SW_API ModemV24 : public Modem {
|
|
public:
|
|
/**
|
|
* @brief Initializes a new instance of the ModemV24 class.
|
|
* @param port Port the air interface modem is connected to.
|
|
* @param duplex Flag indicating the modem is operating in duplex mode.
|
|
* @param p25QueueSize Modem P25 Rx frame buffer queue size (bytes).
|
|
* @param p25TxQueueSize Modem P25 Tx frame buffer queue size (bytes).
|
|
* @param rtrt Flag indicating whether or not RT/RT is enabled.
|
|
* @param diu Flag indicating whether or not V.24 communications are to a DIU.
|
|
* @param jitter
|
|
* @param dumpModemStatus Flag indicating whether the modem status is dumped to the log.
|
|
* @param displayDebugMessages Flag indicating whether or not modem debug messages are displayed in the log.
|
|
* @param trace Flag indicating whether air interface modem trace is enabled.
|
|
* @param debug Flag indicating whether air interface modem debug is enabled.
|
|
*/
|
|
ModemV24(port::IModemPort* port, bool duplex, uint32_t p25QueueSize, uint32_t p25TxQueueSize,
|
|
bool rtrt, uint16_t jitter, bool dumpModemStatus, bool displayDebugMessages, bool trace, bool debug);
|
|
/**
|
|
* @brief Finalizes a instance of the ModemV24 class.
|
|
*/
|
|
~ModemV24();
|
|
|
|
/**
|
|
* @brief Sets the call timeout.
|
|
* @param timeout Timeout.
|
|
*/
|
|
void setCallTimeout(uint16_t timeout);
|
|
/**
|
|
* @brief Sets the P25 NAC.
|
|
* @param nac NAC.
|
|
*/
|
|
void setP25NAC(uint32_t nac) override;
|
|
|
|
/**
|
|
* @brief Helper to set the TIA-102 format DFSI frame flag.
|
|
* @param set
|
|
*/
|
|
void setTIAFormat(bool set);
|
|
|
|
/**
|
|
* @brief Opens connection to the air interface modem.
|
|
* @returns bool True, if connection to modem is made, otherwise false.
|
|
*/
|
|
bool open() override;
|
|
|
|
/**
|
|
* @brief Updates the modem by the passed number of milliseconds.
|
|
* @param ms Number of milliseconds.
|
|
*/
|
|
void clock(uint32_t ms) override;
|
|
|
|
/**
|
|
* @brief Closes connection to the air interface modem.
|
|
*/
|
|
void close() override;
|
|
|
|
/**
|
|
* @brief Helper to test if the P25 ring buffer has free space.
|
|
* @returns bool True, if the P25 ring buffer has free space, otherwise false.
|
|
*/
|
|
bool hasP25Space(uint32_t length) const override;
|
|
|
|
/**
|
|
* @brief Writes raw data to the air interface modem.
|
|
* @param data Data to write to modem.
|
|
* @param length Length of data to write.
|
|
* @param imm Flag indicating whether the frame is immediate.
|
|
* @returns int Actual length of data written.
|
|
*/
|
|
int write(const uint8_t* data, uint32_t length, bool imm = false) override;
|
|
|
|
private:
|
|
bool m_rtrt;
|
|
|
|
uint8_t m_superFrameCnt;
|
|
|
|
p25::Audio m_audio;
|
|
|
|
p25::NID* m_nid;
|
|
|
|
RingBuffer<uint8_t> m_txP25Queue;
|
|
RingBuffer<uint8_t> m_txImmP25Queue;
|
|
|
|
DFSICallData* m_txCall;
|
|
DFSICallData* m_rxCall;
|
|
bool m_txCallInProgress;
|
|
bool m_rxCallInProgress;
|
|
uint64_t m_txLastFrameTime;
|
|
uint64_t m_rxLastFrameTime;
|
|
|
|
uint16_t m_callTimeout;
|
|
|
|
uint16_t m_jitter;
|
|
uint64_t m_lastP25Tx;
|
|
|
|
edac::RS634717 m_rs;
|
|
|
|
bool m_useTIAFormat;
|
|
|
|
std::mutex m_txP25QueueLock;
|
|
|
|
/**
|
|
* @brief Helper to write data from the P25 Tx queue to the serial interface.
|
|
* @param[in] queue Pointer to the ring buffer containing data to write.
|
|
* @return int Actual number of bytes written to the serial interface.
|
|
*/
|
|
int writeSerial(RingBuffer<uint8_t>* queue);
|
|
|
|
/**
|
|
* @brief Helper to store converted Rx frames.
|
|
* @param buffer Buffer containing converted Rx frame.
|
|
* @param length Length of buffer.
|
|
*/
|
|
void storeConvertedRx(const uint8_t* buffer, uint32_t length);
|
|
/**
|
|
* @brief Internal helper to store converted PDU Rx frames.
|
|
* @param dataHeader Instance of a PDU data header.
|
|
* @param pduUserData Buffer containing user data to transmit.
|
|
*/
|
|
void storeConvertedRxPDU(p25::data::DataHeader* dataHeader, uint8_t* pduUserData);
|
|
/**
|
|
* @brief Helper to generate a P25 TDU packet.
|
|
* @param buffer Buffer to create TDU.
|
|
*/
|
|
void create_TDU(uint8_t* buffer);
|
|
|
|
/**
|
|
* @brief Internal helper to convert from V.24/DFSI to TIA-102 air interface.
|
|
* @param data Buffer containing data to convert.
|
|
* @param length Length of buffer.
|
|
*/
|
|
void convertToAirV24(const uint8_t *data, uint32_t length);
|
|
/**
|
|
* @brief Internal helper to convert from TIA-102 DFSI to TIA-102 air interface.
|
|
* @param data Buffer containing data to convert.
|
|
* @param length Length of buffer.
|
|
*/
|
|
void convertToAirTIA(const uint8_t *data, uint32_t length);
|
|
|
|
/**
|
|
* @brief Helper to add a V.24 data frame to the P25 Tx queue with the proper timestamp and formatting.
|
|
* @param data Buffer containing V.24 data frame to send.
|
|
* @param len Length of buffer.
|
|
* @param msgType Type of message to send (used for proper jitter clocking).
|
|
* @param imm Flag indicating whether the frame is immediate.
|
|
* @returns bool True, if data is queued, otherwise false.
|
|
*/
|
|
bool queueP25Frame(uint8_t* data, uint16_t length, SERIAL_TX_TYPE msgType, bool imm = false);
|
|
|
|
/**
|
|
* @brief Send a start of stream sequence (HDU, etc) to the connected serial V24 device.
|
|
* @param[in] control Instance of p25::lc::LC containing link control data.
|
|
*/
|
|
void startOfStreamV24(const p25::lc::LC& control);
|
|
/**
|
|
* @brief Send an end of stream sequence (TDU, etc) to the connected serial V24 device.
|
|
*/
|
|
void endOfStreamV24();
|
|
|
|
/**
|
|
* @brief Helper to generate the NID value.
|
|
* @param duid P25 DUID.
|
|
* @returns uint16_t P25 NID.
|
|
*/
|
|
uint16_t generateNID(P25DEF::DUID::E duid = P25DEF::DUID::LDU1);
|
|
|
|
/**
|
|
* @brief Send a start of stream sequence (HDU, etc) to the connected UDP TIA-102 device.
|
|
* @param[in] control Instance of p25::lc::LC containing link control data.
|
|
*/
|
|
void startOfStreamTIA(const p25::lc::LC& control);
|
|
/**
|
|
* @brief Send an end of stream sequence (TDU, etc) to the connected UDP TIA-102 device.
|
|
*/
|
|
void endOfStreamTIA();
|
|
/**
|
|
* @brief Send a start of stream ACK.
|
|
*/
|
|
void ackStartOfStreamTIA();
|
|
|
|
/**
|
|
* @brief Internal helper to convert from TIA-102 air interface to V.24/DFSI.
|
|
* @param data Buffer containing data to convert.
|
|
* @param length Length of buffer.
|
|
* @param imm Flag indicating whether the frame is immediate.
|
|
*/
|
|
void convertFromAirV24(uint8_t* data, uint32_t length, bool imm);
|
|
/**
|
|
* @brief Internal helper to convert from TIA-102 air interface to TIA-102 DFSI.
|
|
* @param data Buffer containing data to convert.
|
|
* @param length Length of buffer.
|
|
* @param imm Flag indicating whether the frame is immediate.
|
|
*/
|
|
void convertFromAirTIA(uint8_t* data, uint32_t length, bool imm);
|
|
};
|
|
} // namespace modem
|
|
|
|
#endif // __MODEM_V24_H__
|