diff --git a/DVMHost.vcxproj b/DVMHost.vcxproj index 2f218a70..24635be7 100644 --- a/DVMHost.vcxproj +++ b/DVMHost.vcxproj @@ -212,6 +212,8 @@ + + @@ -242,6 +244,7 @@ + diff --git a/DVMHost.vcxproj.filters b/DVMHost.vcxproj.filters index b5ff3973..8feda304 100644 --- a/DVMHost.vcxproj.filters +++ b/DVMHost.vcxproj.filters @@ -72,6 +72,9 @@ {ac8d97b8-a9bd-48e3-9fb9-08e997d055d4} + + {c53673fd-d7d5-49f2-a8e4-5a92e379f436} + {94f78cbc-78b5-454e-972d-89ff595eca17} @@ -84,6 +87,9 @@ {d742b2cf-71b2-45a1-afbd-753128c38f66} + + {7c4122c6-5105-4c86-ac60-3a9873921535} + {07a6e6a8-699e-41a9-9e0f-0a8a064b2331} @@ -365,6 +371,12 @@ Header Files\dmr + + Header Files\p25\dfsi + + + Header Files\p25\dfsi + @@ -583,6 +595,9 @@ Source Files\host\setup + + Source Files\p25\dfsi + diff --git a/Makefile b/Makefile index 887aeefc..06fe2697 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ OBJECTS = \ p25/data/DataHeader.o \ p25/data/DataRspHeader.o \ p25/data/LowSpeedData.o \ + p25/dfsi/LC.o \ p25/edac/Trellis.o \ p25/lc/LC.o \ p25/lc/TDULC.o \ diff --git a/Makefile.arm b/Makefile.arm index effff533..81c93670 100644 --- a/Makefile.arm +++ b/Makefile.arm @@ -43,6 +43,7 @@ OBJECTS = \ p25/data/DataHeader.o \ p25/data/DataRspHeader.o \ p25/data/LowSpeedData.o \ + p25/dfsi/LC.o \ p25/edac/Trellis.o \ p25/lc/LC.o \ p25/lc/TDULC.o \ diff --git a/Makefile.rpi-arm b/Makefile.rpi-arm index 09dd4dde..8df53560 100644 --- a/Makefile.rpi-arm +++ b/Makefile.rpi-arm @@ -43,6 +43,7 @@ OBJECTS = \ p25/data/DataHeader.o \ p25/data/DataRspHeader.o \ p25/data/LowSpeedData.o \ + p25/dfsi/LC.o \ p25/edac/Trellis.o \ p25/lc/LC.o \ p25/lc/TDULC.o \ diff --git a/p25/dfsi/DFSIDefines.h b/p25/dfsi/DFSIDefines.h new file mode 100644 index 00000000..77210b9e --- /dev/null +++ b/p25/dfsi/DFSIDefines.h @@ -0,0 +1,117 @@ +/** +* 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 +* +*/ +/* +* Copyright (C) 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_DFSI_DEFINES_H__) +#define __P25_DFSI_DEFINES_H__ + +#include "Defines.h" + +// Frame Type String(s) +#define P25_DFSI_VHDR1_STR "P25_DFSI_START_STOP (Start/Stop)" +#define P25_DFSI_VHDR1_STR "P25_DFSI_VHDR1 (Voice Header 1)" +#define P25_DFSI_VHDR2_STR "P25_DFSI_VHDR2 (Voice Header 2)" +#define P25_DFSI_LDU1_STR "P25_DFSI_LDU1 (Logical Link Data Unit 1)" +#define P25_DFSI_LDU2_STR "P25_DFSI_LDU2 (Logical Link Data Unit 2)" +#define P25_DFSI_LDU2_STR "P25_DFSI_TSBK (Trunking System Block)" + +namespace p25 +{ + namespace dfsi + { + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + const uint32_t P25_DFSI_START_LENGTH_BYTES = 4U; + + const uint32_t P25_DFSI_SS_FRAME_LENGTH_BYTES = 10U; + + const uint32_t P25_DFSI_VHDR1_FRAME_LENGTH_BYTES = 30U; + const uint32_t P25_DFSI_VHDR2_FRAME_LENGTH_BYTES = 22U; + + const uint32_t P25_DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES = 22U; + const uint32_t P25_DFSI_LDU1_VOICE2_FRAME_LENGTH_BYTES = 14U; + const uint32_t P25_DFSI_LDU1_VOICE3_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU1_VOICE4_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU1_VOICE5_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU1_VOICE6_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU1_VOICE7_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU1_VOICE8_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU1_VOICE9_FRAME_LENGTH_BYTES = 16U; + + const uint32_t P25_DFSI_LDU2_VOICE10_FRAME_LENGTH_BYTES = 22U; + const uint32_t P25_DFSI_LDU2_VOICE11_FRAME_LENGTH_BYTES = 14U; + const uint32_t P25_DFSI_LDU2_VOICE12_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU2_VOICE13_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU2_VOICE14_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU2_VOICE15_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU2_VOICE16_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU2_VOICE17_FRAME_LENGTH_BYTES = 17U; + const uint32_t P25_DFSI_LDU2_VOICE18_FRAME_LENGTH_BYTES = 16U; + + const uint32_t P25_DFSI_TSBK_FRAME_LENGTH_BYTES = 25U; + + const uint8_t P25_DFSI_RT_ENABLED = 0x02U; // + const uint8_t P25_DFSI_RT_DISABLED = 0x04U; // + + const uint8_t P25_DFSI_START_FLAG = 0x0CU; // + const uint8_t P25_DFSI_STOP_FLAG = 0x00U; // + + const uint8_t P25_DFSI_TYPE_VOICE = 0x0BU; // + const uint8_t P25_DFSI_TYPE_TSBK = 0x0FU; // + + const uint8_t P25_DFSI_ICW_SOURCE = 0x00U; // Infrastructure Source - Default Source + + // Frame Type(s) + const uint8_t P25_DFSI_START_STOP = 0x00U; // Start/Stop + + const uint8_t P25_DFSI_VHDR1 = 0x60U; // Voice Header 1 + const uint8_t P25_DFSI_VHDR2 = 0x61U; // Voice Header 2 + + const uint8_t P25_DFSI_LDU1_VOICE1 = 0x62U; // IMBE LDU1 - Voice 1 + const uint8_t P25_DFSI_LDU1_VOICE2 = 0x63U; // IMBE LDU1 - Voice 2 + const uint8_t P25_DFSI_LDU1_VOICE3 = 0x64U; // IMBE LDU1 - Voice 3 + Link Control + const uint8_t P25_DFSI_LDU1_VOICE4 = 0x65U; // IMBE LDU1 - Voice 4 + Link Control + const uint8_t P25_DFSI_LDU1_VOICE5 = 0x66U; // IMBE LDU1 - Voice 5 + Link Control + const uint8_t P25_DFSI_LDU1_VOICE6 = 0x67U; // IMBE LDU1 - Voice 6 + Link Control + const uint8_t P25_DFSI_LDU1_VOICE7 = 0x68U; // IMBE LDU1 - Voice 7 + Link Control + const uint8_t P25_DFSI_LDU1_VOICE8 = 0x69U; // IMBE LDU1 - Voice 8 + Link Control + const uint8_t P25_DFSI_LDU1_VOICE9 = 0x6AU; // IMBE LDU1 - Voice 9 + Low Speed Data + + const uint8_t P25_DFSI_LDU2_VOICE10 = 0x6BU; // IMBE LDU2 - Voice 10 + const uint8_t P25_DFSI_LDU2_VOICE11 = 0x6CU; // IMBE LDU2 - Voice 11 + const uint8_t P25_DFSI_LDU2_VOICE12 = 0x6DU; // IMBE LDU2 - Voice 12 + Encryption Sync + const uint8_t P25_DFSI_LDU2_VOICE13 = 0x6EU; // IMBE LDU2 - Voice 13 + Encryption Sync + const uint8_t P25_DFSI_LDU2_VOICE14 = 0x6FU; // IMBE LDU2 - Voice 14 + Encryption Sync + const uint8_t P25_DFSI_LDU2_VOICE15 = 0x70U; // IMBE LDU2 - Voice 15 + Encryption Sync + const uint8_t P25_DFSI_LDU2_VOICE16 = 0x71U; // IMBE LDU2 - Voice 16 + Encryption Sync + const uint8_t P25_DFSI_LDU2_VOICE17 = 0x72U; // IMBE LDU2 - Voice 17 + Encryption Sync + const uint8_t P25_DFSI_LDU2_VOICE18 = 0x73U; // IMBE LDU2 - Voice 18 + Low Speed Data + + const uint8_t P25_DFSI_TSBK = 0xA1U; // TSBK + } // namespace dfsi +} // namespace p25 + +#endif // __P25_DFSI_DEFINES_H__ diff --git a/p25/dfsi/LC.cpp b/p25/dfsi/LC.cpp new file mode 100644 index 00000000..da3bbdec --- /dev/null +++ b/p25/dfsi/LC.cpp @@ -0,0 +1,156 @@ +/** +* 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-2019 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 "Defines.h" +#include "p25/P25Defines.h" +#include "p25/dfsi/DFSIDefines.h" +#include "p25/dfsi/LC.h" +#include "p25/P25Utils.h" +#include "Log.h" +#include "Utils.h" + +using namespace p25::dfsi; +using namespace p25; + +#include +#include +#include + +// --------------------------------------------------------------------------- +// Public Class Members +// --------------------------------------------------------------------------- +/// +/// Initializes a new instance of the LC class. +/// +/// +LC::LC() : + m_rtModeFlag(P25_DFSI_RT_ENABLED), + m_startStopFlag(P25_DFSI_START_FLAG), + m_typeFlag(P25_DFSI_TYPE_VOICE), + m_control(), + m_lsd() +{ + /* stub */ +} + +/// +/// Finalizes a instance of LC class. +/// +LC::~LC() +{ + /* stub */ +} + +/// +/// Equals operator. +/// +/// +/// +LC& LC::operator=(const LC& data) +{ + if (this != &data) { + m_frameType = data.m_frameType; + m_rtModeFlag = data.m_rtModeFlag; + m_startStopFlag = data.m_startStopFlag; + m_typeFlag = data.m_typeFlag; + + m_control = data.m_control; + m_lsd = data.m_lsd; + } + + return *this; +} + +/// +/// Decode a NID start/stop. +/// +/// +/// True, if decoded, otherwise false. +bool LC::decodeNID(const uint8_t* data) +{ + assert(data != NULL); + + m_frameType = data[0U]; // Frame Type + + return decodeStart(data); +} + +/// +/// Encode a NID start/stop. +/// +/// +void LC::encodeNID(uint8_t* data) +{ + assert(data != NULL); + + uint8_t raw[P25_DFSI_SS_FRAME_LENGTH_BYTES]; + ::memset(raw, 0x00U, P25_DFSI_SS_FRAME_LENGTH_BYTES); + + raw[0U] = m_frameType; // Frame Type + encodeStart(raw + 1U); +} + +// --------------------------------------------------------------------------- +// Private Class Members +// --------------------------------------------------------------------------- +/// +/// Decode start data. +/// +/// +/// True, if decoded, otherwise false. +bool LC::decodeStart(const uint8_t* data) +{ + assert(data != NULL); + + m_rtModeFlag = data[1U]; // RT Mode Flag + m_startStopFlag = data[2U]; // Start/Stop Flag + m_typeFlag = data[3U]; // Type Flag + + return true; +} + +/// +/// Encode start data. +/// +/// +void LC::encodeStart(uint8_t* data) +{ + assert(data != NULL); + + uint8_t raw[P25_DFSI_START_LENGTH_BYTES]; + ::memset(raw, 0x00U, P25_DFSI_START_LENGTH_BYTES); + + raw[0U] = 0x02U; + raw[1U] = m_rtModeFlag; // RT Mode Flag + raw[2U] = m_startStopFlag; // Start/Stop Flag + raw[3U] = m_typeFlag; // Type flag + + ::memcpy(data, raw, P25_DFSI_START_LENGTH_BYTES); +} diff --git a/p25/dfsi/LC.h b/p25/dfsi/LC.h new file mode 100644 index 00000000..9b0d8488 --- /dev/null +++ b/p25/dfsi/LC.h @@ -0,0 +1,104 @@ +/** +* 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 +* +*/ +/* +* Copyright (C) 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_DFSI__LC_H__) +#define __P25_DFSI__LC_H__ + +#include "Defines.h" +#include "p25/data/LowSpeedData.h" +#include "p25/lc/LC.h" + +#include + +namespace p25 +{ + namespace dfsi + { + // --------------------------------------------------------------------------- + // Class Declaration + // Represents link control data for DFSI VHDR, LDU1 and 2 packets. + // --------------------------------------------------------------------------- + + class HOST_SW_API LC { + public: + /// Initializes a new instance of the LC class. + LC(); + /// Finalizes a instance of the LC class. + ~LC(); + + /// Equals operator. + LC& operator=(const LC& data); + + /// Decode a NID start/stop. + bool decodeNID(const uint8_t* data); + /// Encode a NID start/stop. + void encodeNID(uint8_t* data); + + /// Decode a voice header 1. + bool decodeVHDR1(const uint8_t* data); + /// Encode a voice header 1. + void encodeVHDR1(uint8_t* data); + + /// Decode a voice header 2. + bool decodeVHDR2(const uint8_t* data); + /// Encode a voice header 2. + void encodeVHDR2(uint8_t* data); + + /// Decode a logical link data unit 1. + bool decodeLDU1(const uint8_t* data); + /// Encode a logical link data unit 1. + void encodeLDU1(uint8_t* data); + + /// Decode a logical link data unit 2. + bool decodeLDU2(const uint8_t* data); + /// Encode a logical link data unit 2. + void encodeLDU2(uint8_t* data); + + public: + /** Common Data */ + /// Frame Type. + __PROPERTY(uint8_t, frameType, FrameType); + /// RT Mode Flag. + __PROPERTY(uint8_t, rtModeFlag, RTMode); + /// Start/Stop Flag. + __PROPERTY(uint8_t, startStopFlag, StartStop); + /// Type Flag. + __PROPERTY(uint8_t, typeFlag, Type); + + /// Link control data. + __PROPERTY(p25::lc::LC, control, Control); + /// Low speed data. + __PROPERTY(p25::data::LowSpeedData, lsd, LSD); + + private: + /// Decode start data. + bool decodeStart(const uint8_t* data); + /// Encode start data. + void encodeStart(uint8_t* data); + }; + } // namespace dfsi +} // namespace p25 + +#endif // __P25_DFSI__LC_H__