(lets see if this breaks things and W3AXL yells at me) refactor some of the frame classes to use the __PROPERTY mechanism for building get/set based properties for some class fields vs raw variables; cleanup some cases where we may run afoul heap allocations and get memory leaks;

pull/61/head
Bryan Biedenkapp 2 years ago
parent 26f733d8ff
commit ad4aa9ac1f

@ -24,8 +24,8 @@ file(GLOB dvmdfsi_SRC
"src/dfsi/network/*.h" "src/dfsi/network/*.h"
"src/dfsi/network/*.cpp" "src/dfsi/network/*.cpp"
# DFSI rtp libs # DFSI rtp libs
"src/dfsi/rtp/*.h" "src/dfsi/frames/*.h"
"src/dfsi/rtp/*.cpp" "src/dfsi/frames/*.cpp"
# Core DFSI # Core DFSI
"src/dfsi/*.h" "src/dfsi/*.h"
"src/dfsi/*.cpp" "src/dfsi/*.cpp"

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -12,8 +12,8 @@
* Copyright (C) 2024 Bryan Biedenkapp, N2PLL * Copyright (C) 2024 Bryan Biedenkapp, N2PLL
* *
*/ */
#if !defined(__RTP_DEFINES_H__) #if !defined(__FRAME_DEFINES_H__)
#define __RTP_DEFINES_H__ #define __FRAME_DEFINES_H__
#include "common/Defines.h" #include "common/Defines.h"
@ -74,4 +74,4 @@ namespace p25
} // namespace dfsi } // namespace dfsi
} // namespace p25 } // namespace p25
#endif // __RTP_DEFINES_H__ #endif // __FRAME_DEFINES_H__

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Modem Host Software * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -12,15 +12,17 @@
* Copyright (C) 2024 Bryan Biedenkapp, N2PLL * Copyright (C) 2024 Bryan Biedenkapp, N2PLL
* *
*/ */
#if !defined(__RTP_FRAMES_H__) #if !defined(__DFSI_FRAMES_H__)
#define __RTP_FRAMES_H__ #define __DFSI_FRAMES_H__
#include "Defines.h" #include "Defines.h"
#include "rtp/MotFullRateVoice.h" #include "frames/StartOfStream.h"
#include "rtp/MotStartOfStream.h"
#include "rtp/MotStartVoiceFrame.h"
#include "rtp/MotVoiceHeader1.h"
#include "rtp/MotVoiceHeader2.h"
#endif // __RTP_FRAMES_H__ #include "frames/MotFullRateVoice.h"
#include "frames/MotStartOfStream.h"
#include "frames/MotStartVoiceFrame.h"
#include "frames/MotVoiceHeader1.h"
#include "frames/MotVoiceHeader2.h"
#endif // __DFSI_FRAMES_H__

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -13,7 +13,7 @@
* *
*/ */
#include "rtp/MotFullRateVoice.h" #include "frames/MotFullRateVoice.h"
#include "common/p25/dfsi/DFSIDefines.h" #include "common/p25/dfsi/DFSIDefines.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "common/Log.h" #include "common/Log.h"
@ -31,11 +31,12 @@ using namespace dfsi;
/// <summary> /// <summary>
/// Initializes a instance of the MotFullRateVoice class. /// Initializes a instance of the MotFullRateVoice class.
/// </summary> /// </summary>
MotFullRateVoice::MotFullRateVoice() MotFullRateVoice::MotFullRateVoice() :
imbeData(nullptr),
additionalData(nullptr),
m_frameType(P25_DFSI_LDU1_VOICE1),
m_source(SOURCE_QUANTAR)
{ {
frameType = P25_DFSI_LDU1_VOICE1;
additionalData = nullptr;
source = SOURCE_QUANTAR;
imbeData = new uint8_t[IMBE_BUF_LEN]; imbeData = new uint8_t[IMBE_BUF_LEN];
::memset(imbeData, 0x00U, IMBE_BUF_LEN); ::memset(imbeData, 0x00U, IMBE_BUF_LEN);
} }
@ -54,8 +55,10 @@ MotFullRateVoice::MotFullRateVoice(uint8_t* data)
/// </summary> /// </summary>
MotFullRateVoice::~MotFullRateVoice() MotFullRateVoice::~MotFullRateVoice()
{ {
delete[] imbeData; if (imbeData != nullptr)
delete[] additionalData; delete[] imbeData;
if (additionalData != nullptr)
delete[] additionalData;
} }
/// <summary> /// <summary>
@ -66,14 +69,14 @@ uint32_t MotFullRateVoice::size()
{ {
uint32_t length = 0; uint32_t length = 0;
// Set length appropriately based on frame type // set length appropriately based on frame type
if (isVoice1or2or10or11()) { if (isVoice1or2or10or11()) {
length += SHORTENED_LENGTH; length += SHORTENED_LENGTH;
} else { } else {
length += LENGTH; length += LENGTH;
} }
// These are weird // these are weird
if (isVoice9or18()) { if (isVoice9or18()) {
length -= 1; length -= 1;
} }
@ -91,19 +94,20 @@ bool MotFullRateVoice::decode(const uint8_t* data, bool shortened)
{ {
assert(data != nullptr); assert(data != nullptr);
if (imbeData != nullptr)
delete imbeData;
imbeData = new uint8_t[IMBE_BUF_LEN]; imbeData = new uint8_t[IMBE_BUF_LEN];
::memset(imbeData, 0x00U, IMBE_BUF_LEN); ::memset(imbeData, 0x00U, IMBE_BUF_LEN);
frameType = data[0U]; m_frameType = data[0U];
if (isVoice2or11()) { if (isVoice2or11()) {
shortened = true; shortened = true;
} }
if (shortened) { if (shortened) {
::memcpy(imbeData, data + 1U, IMBE_BUF_LEN); ::memcpy(imbeData, data + 1U, IMBE_BUF_LEN);
source = (SourceFlag)data[12U]; m_source = (SourceFlag)data[12U];
// Forgot to set this originally and left additionalData uninitialized, whoops! // Forgot to set this originally and left additionalData uninitialized, whoops!
additionalData = nullptr; additionalData = nullptr;
} else { } else {
@ -113,14 +117,16 @@ bool MotFullRateVoice::decode(const uint8_t* data, bool shortened)
imbeStart = 4U; imbeStart = 4U;
} }
if (additionalData != nullptr)
delete[] additionalData;
additionalData = new uint8_t[ADDITIONAL_LENGTH]; additionalData = new uint8_t[ADDITIONAL_LENGTH];
::memset(additionalData, 0x00U, ADDITIONAL_LENGTH); ::memset(additionalData, 0x00U, ADDITIONAL_LENGTH);
::memcpy(additionalData, data + 1U, ADDITIONAL_LENGTH); ::memcpy(additionalData, data + 1U, ADDITIONAL_LENGTH);
// Copy IMBE data based on our imbe start position // copy IMBE data based on our imbe start position
::memcpy(imbeData, data + imbeStart, IMBE_BUF_LEN); ::memcpy(imbeData, data + imbeStart, IMBE_BUF_LEN);
source = (SourceFlag)data[IMBE_BUF_LEN + imbeStart]; m_source = (SourceFlag)data[IMBE_BUF_LEN + imbeStart];
} }
return true; return true;
@ -134,19 +140,20 @@ bool MotFullRateVoice::decode(const uint8_t* data, bool shortened)
void MotFullRateVoice::encode(uint8_t* data, bool shortened) void MotFullRateVoice::encode(uint8_t* data, bool shortened)
{ {
assert(data != nullptr); assert(data != nullptr);
assert(imbeData != nullptr);
// Check if we're a shortened frame // check if we're a shortened frame
data[0U] = frameType; data[0U] = m_frameType;
if (isVoice2or11()) { if (isVoice2or11()) {
shortened = true; shortened = true;
} }
// Copy based on shortened frame or not // copy based on shortened frame or not
if (shortened) { if (shortened) {
::memcpy(data + 1U, imbeData, IMBE_BUF_LEN); ::memcpy(data + 1U, imbeData, IMBE_BUF_LEN);
data[12U] = (uint8_t)source; data[12U] = (uint8_t)m_source;
} }
// If not shortened, our IMBE data start position depends on frame type // if not shortened, our IMBE data start position depends on frame type
else { else {
// Starting index for the IMBE data // Starting index for the IMBE data
uint8_t imbeStart = 5U; uint8_t imbeStart = 5U;
@ -163,7 +170,7 @@ void MotFullRateVoice::encode(uint8_t* data, bool shortened)
::memcpy(data + imbeStart, imbeData, IMBE_BUF_LEN); ::memcpy(data + imbeStart, imbeData, IMBE_BUF_LEN);
// Source byte at the end // Source byte at the end
data[11U + imbeStart] = (uint8_t)source; data[11U + imbeStart] = (uint8_t)m_source;
} }
} }
@ -177,7 +184,7 @@ void MotFullRateVoice::encode(uint8_t* data, bool shortened)
/// <returns></returns> /// <returns></returns>
bool MotFullRateVoice::isVoice1or2or10or11() bool MotFullRateVoice::isVoice1or2or10or11()
{ {
if ( (frameType == P25_DFSI_LDU1_VOICE1) || (frameType == P25_DFSI_LDU1_VOICE2) || (frameType == P25_DFSI_LDU2_VOICE10) || (frameType == P25_DFSI_LDU2_VOICE11) ) { if ( (m_frameType == P25_DFSI_LDU1_VOICE1) || (m_frameType == P25_DFSI_LDU1_VOICE2) || (m_frameType == P25_DFSI_LDU2_VOICE10) || (m_frameType == P25_DFSI_LDU2_VOICE11) ) {
return true; return true;
} else { } else {
return false; return false;
@ -190,7 +197,7 @@ bool MotFullRateVoice::isVoice1or2or10or11()
/// <returns></returns> /// <returns></returns>
bool MotFullRateVoice::isVoice2or11() bool MotFullRateVoice::isVoice2or11()
{ {
if ( (frameType == P25_DFSI_LDU1_VOICE2) || (frameType == P25_DFSI_LDU2_VOICE11) ) { if ( (m_frameType == P25_DFSI_LDU1_VOICE2) || (m_frameType == P25_DFSI_LDU2_VOICE11) ) {
return true; return true;
} else { } else {
return false; return false;
@ -203,7 +210,7 @@ bool MotFullRateVoice::isVoice2or11()
/// <returns></returns> /// <returns></returns>
bool MotFullRateVoice::isVoice9or18() bool MotFullRateVoice::isVoice9or18()
{ {
if ( (frameType == P25_DFSI_LDU1_VOICE9) || (frameType == P25_DFSI_LDU2_VOICE18) ) { if ( (m_frameType == P25_DFSI_LDU1_VOICE9) || (m_frameType == P25_DFSI_LDU2_VOICE18) ) {
return true; return true;
} else { } else {
return false; return false;

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -19,7 +19,7 @@
#include "common/Defines.h" #include "common/Defines.h"
#include "common/Log.h" #include "common/Log.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "rtp/RtpDefines.h" #include "frames/FrameDefines.h"
namespace p25 namespace p25
{ {
@ -52,11 +52,6 @@ namespace p25
static const uint8_t ADDITIONAL_LENGTH = 4; static const uint8_t ADDITIONAL_LENGTH = 4;
static const uint8_t IMBE_BUF_LEN = 11; static const uint8_t IMBE_BUF_LEN = 11;
uint8_t frameType;
uint8_t* imbeData;
uint8_t* additionalData;
SourceFlag source;
/// <summary>Initializes a copy instance of the MotFullRateVoice class.</summary> /// <summary>Initializes a copy instance of the MotFullRateVoice class.</summary>
MotFullRateVoice(); MotFullRateVoice();
/// <summary>Initializes a copy instance of the MotFullRateVoice class.</summary> /// <summary>Initializes a copy instance of the MotFullRateVoice class.</summary>
@ -70,7 +65,16 @@ namespace p25
bool decode(const uint8_t* data, bool shortened = false); bool decode(const uint8_t* data, bool shortened = false);
/// <summary>Encode a full rate voice frame.</summary> /// <summary>Encode a full rate voice frame.</summary>
void encode(uint8_t* data, bool shortened = false); void encode(uint8_t* data, bool shortened = false);
public:
uint8_t* imbeData; // ?? - this should probably be private with getters/setters
uint8_t* additionalData; // ?? - this should probably be private with getters/setters
/// <summary></summary>
__PROPERTY(uint8_t, frameType, FrameType);
/// <summary></summary>
__PROPERTY(uint8_t, source, Source);
private: private:
/// <summary></summary> /// <summary></summary>
bool isVoice1or2or10or11(); bool isVoice1or2or10or11();

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -13,7 +13,7 @@
* *
*/ */
#include "rtp/MotStartOfStream.h" #include "frames/MotStartOfStream.h"
#include "common/p25/dfsi/DFSIDefines.h" #include "common/p25/dfsi/DFSIDefines.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "common/Log.h" #include "common/Log.h"
@ -31,11 +31,13 @@ using namespace dfsi;
/// <summary> /// <summary>
/// Initializes a instance of the MotStartOfStream class. /// Initializes a instance of the MotStartOfStream class.
/// </summary> /// </summary>
MotStartOfStream::MotStartOfStream() MotStartOfStream::MotStartOfStream() :
m_marker(FIXED_MARKER),
m_rt(DISABLED),
m_startStop(START),
m_streamType(VOICE)
{ {
rt = DISABLED; /* stub */
startStop = START;
streamType = VOICE;
} }
/// <summary> /// <summary>
@ -56,10 +58,9 @@ bool MotStartOfStream::decode(const uint8_t* data)
{ {
assert(data != nullptr); assert(data != nullptr);
// Get parameters m_rt = (RTFlag)data[2U];
rt = (RTFlag)data[2U]; m_startStop = (StartStopFlag)data[3U];
startStop = (StartStopFlag)data[3U]; m_streamType = (StreamTypeFlag)data[4U];
streamType = (StreamTypeFlag)data[4U];
return true; return true;
} }
@ -72,10 +73,9 @@ void MotStartOfStream::encode(uint8_t* data)
{ {
assert(data != nullptr); assert(data != nullptr);
// Copy data
data[0U] = P25_DFSI_MOT_START_STOP; data[0U] = P25_DFSI_MOT_START_STOP;
data[1U] = FIXED_MARKER; data[1U] = FIXED_MARKER;
data[2U] = rt; data[2U] = (uint8_t)m_rt;
data[3U] = startStop; data[3U] = (uint8_t)m_startStop;
data[4U] = streamType; data[4U] = (uint8_t)m_streamType;
} }

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -19,7 +19,7 @@
#include "common/Defines.h" #include "common/Defines.h"
#include "common/Log.h" #include "common/Log.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "rtp/RtpDefines.h" #include "frames/FrameDefines.h"
namespace p25 namespace p25
{ {
@ -45,12 +45,6 @@ namespace p25
static const uint8_t LENGTH = 10; static const uint8_t LENGTH = 10;
static const uint8_t FIXED_MARKER = 0x02; static const uint8_t FIXED_MARKER = 0x02;
uint8_t marker = FIXED_MARKER;
RTFlag rt;
StartStopFlag startStop;
StreamTypeFlag streamType;
/// <summary>Initializes a copy instance of the MotStartOfStream class.</summary> /// <summary>Initializes a copy instance of the MotStartOfStream class.</summary>
MotStartOfStream(); MotStartOfStream();
/// <summary>Initializes a copy instance of the MotStartOfStream class.</summary> /// <summary>Initializes a copy instance of the MotStartOfStream class.</summary>
@ -60,6 +54,16 @@ namespace p25
bool decode(const uint8_t* data); bool decode(const uint8_t* data);
/// <summary>Encode a start of stream frame.</summary> /// <summary>Encode a start of stream frame.</summary>
void encode(uint8_t* data); void encode(uint8_t* data);
public:
/// <summary></summary>
__PROPERTY(uint8_t, marker, Marker);
/// <summary></summary>
__PROPERTY(RTFlag, rt, RT);
/// <summary></summary>
__PROPERTY(StartStopFlag, startStop, StartStop);
/// <summary></summary>
__PROPERTY(StreamTypeFlag, streamType, StreamType);
}; };
} // namespace dfsi } // namespace dfsi
} // namespace p25 } // namespace p25

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -13,7 +13,7 @@
* *
*/ */
#include "rtp/MotStartVoiceFrame.h" #include "frames/MotStartVoiceFrame.h"
#include "common/p25/dfsi/DFSIDefines.h" #include "common/p25/dfsi/DFSIDefines.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "common/Log.h" #include "common/Log.h"
@ -31,16 +31,17 @@ using namespace dfsi;
/// <summary> /// <summary>
/// Initializes a instance of the MotStartVoiceFrame class. /// Initializes a instance of the MotStartVoiceFrame class.
/// </summary> /// </summary>
MotStartVoiceFrame::MotStartVoiceFrame() MotStartVoiceFrame::MotStartVoiceFrame() :
startOfStream(nullptr),
fullRateVoice(nullptr),
m_icw(ICW_DIU),
m_rssi(0U),
m_rssiValidity(INVALID),
m_nRssi(0U),
m_adjMM(0U)
{ {
icw = ICW_DIU; startOfStream = new MotStartOfStream();
rssi = 0; fullRateVoice = new MotFullRateVoice();
rssiValidity = INVALID;
nRssi = 0;
adjMM = 0;
startOfStream = nullptr;
fullRateVoice = nullptr;
} }
/// <summary> /// <summary>
@ -57,8 +58,10 @@ MotStartVoiceFrame::MotStartVoiceFrame(uint8_t* data)
/// </summary> /// </summary>
MotStartVoiceFrame::~MotStartVoiceFrame() MotStartVoiceFrame::~MotStartVoiceFrame()
{ {
delete startOfStream; if (startOfStream != nullptr)
delete fullRateVoice; delete startOfStream;
if (fullRateVoice != nullptr)
delete fullRateVoice;
} }
/// <summary> /// <summary>
@ -70,31 +73,36 @@ bool MotStartVoiceFrame::decode(const uint8_t* data)
{ {
assert(data != nullptr); assert(data != nullptr);
// Create a new startOfStream // create a new start of stream
if (startOfStream != nullptr)
delete startOfStream;
startOfStream = new MotStartOfStream(); startOfStream = new MotStartOfStream();
// Create a buffer to decode the start record skipping the 10th byte (adjMM) // create a buffer to decode the start record skipping the 10th byte (adjMM)
uint8_t startBuffer[startOfStream->LENGTH]; uint8_t startBuffer[MotStartOfStream::LENGTH];
::memset(startBuffer, 0x00U, startOfStream->LENGTH); ::memset(startBuffer, 0x00U, MotStartOfStream::LENGTH);
::memcpy(startBuffer, data, 9U); ::memcpy(startBuffer, data, 9U);
// Decode start of stream // decode start of stream
startOfStream->decode(startBuffer); startOfStream->decode(startBuffer);
// Decode the full rate voice frames // decode the full rate voice frames
if (fullRateVoice != nullptr)
delete fullRateVoice;
fullRateVoice = new MotFullRateVoice(); fullRateVoice = new MotFullRateVoice();
uint8_t voiceBuffer[fullRateVoice->SHORTENED_LENGTH];
::memset(voiceBuffer, 0x00U, fullRateVoice->SHORTENED_LENGTH); uint8_t voiceBuffer[MotFullRateVoice::SHORTENED_LENGTH];
::memset(voiceBuffer, 0x00U, MotFullRateVoice::SHORTENED_LENGTH);
voiceBuffer[0U] = data[0U]; voiceBuffer[0U] = data[0U];
::memcpy(voiceBuffer + 1U, data + 10U, fullRateVoice->SHORTENED_LENGTH - 1); ::memcpy(voiceBuffer + 1U, data + 10U, MotFullRateVoice::SHORTENED_LENGTH - 1);
fullRateVoice->decode(voiceBuffer, true); fullRateVoice->decode(voiceBuffer, true);
// Get rest of data // get rest of data
icw = (ICWFlag)data[5U]; m_icw = (ICWFlag)data[5U];
rssi = data[6U]; m_rssi = data[6U];
rssiValidity = (RssiValidityFlag)data[7U]; m_rssiValidity = (RssiValidityFlag)data[7U];
nRssi = data[8U]; m_nRssi = data[8U];
adjMM = data[9U]; m_adjMM = data[9U];
return true; return true;
} }
@ -109,26 +117,28 @@ void MotStartVoiceFrame::encode(uint8_t* data)
assert(startOfStream != nullptr); assert(startOfStream != nullptr);
assert(fullRateVoice != nullptr); assert(fullRateVoice != nullptr);
// Encode start of stream // encode start of stream - scope is intentional
if (startOfStream != nullptr) { {
uint8_t buffer[startOfStream->LENGTH]; uint8_t buffer[MotStartOfStream::LENGTH];
startOfStream->encode(buffer); startOfStream->encode(buffer);
// Copy to data array (skipping first and last bytes)
::memcpy(data + 1U, buffer + 1U, startOfStream->LENGTH - 2); // copy to data array (skipping first and last bytes)
::memcpy(data + 1U, buffer + 1U, MotStartOfStream::LENGTH - 2);
} }
// Encode full rate voice // encode full rate voice - scope is intentional
if (fullRateVoice != nullptr) { {
uint8_t buffer[fullRateVoice->SHORTENED_LENGTH]; uint8_t buffer[MotFullRateVoice::SHORTENED_LENGTH];
fullRateVoice->encode(buffer, true); fullRateVoice->encode(buffer, true);
data[0U] = fullRateVoice->frameType;
::memcpy(data + 10U, buffer + 1U, fullRateVoice->SHORTENED_LENGTH - 1); data[0U] = fullRateVoice->getFrameType();
::memcpy(data + 10U, buffer + 1U, MotFullRateVoice::SHORTENED_LENGTH - 1);
} }
// Copy the rest // Copy the rest
data[5U] = icw; data[5U] = (uint8_t)m_icw;
data[6U] = rssi; data[6U] = m_rssi;
data[7U] = rssiValidity; data[7U] = (uint8_t)m_rssiValidity;
data[8U] = nRssi; data[8U] = m_nRssi;
data[9U] = adjMM; data[9U] = m_adjMM;
} }

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -19,9 +19,9 @@
#include "common/Defines.h" #include "common/Defines.h"
#include "common/Log.h" #include "common/Log.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "rtp/RtpDefines.h" #include "frames/FrameDefines.h"
#include "rtp/MotStartOfStream.h" #include "frames/MotStartOfStream.h"
#include "rtp/MotFullRateVoice.h" #include "frames/MotFullRateVoice.h"
namespace p25 namespace p25
{ {
@ -52,15 +52,6 @@ namespace p25
public: public:
static const uint8_t LENGTH = 22; static const uint8_t LENGTH = 22;
ICWFlag icw;
uint8_t rssi;
RssiValidityFlag rssiValidity;
uint8_t nRssi;
uint8_t adjMM;
MotStartOfStream* startOfStream;
MotFullRateVoice* fullRateVoice;
/// <summary>Initializes a copy instance of the MotStartVoiceFrame class.</summary> /// <summary>Initializes a copy instance of the MotStartVoiceFrame class.</summary>
MotStartVoiceFrame(); MotStartVoiceFrame();
/// <summary>Initializes a copy instance of the MotStartVoiceFrame class.</summary> /// <summary>Initializes a copy instance of the MotStartVoiceFrame class.</summary>
@ -72,6 +63,21 @@ namespace p25
bool decode(const uint8_t* data); bool decode(const uint8_t* data);
/// <summary>Encode a start voice frame.</summary> /// <summary>Encode a start voice frame.</summary>
void encode(uint8_t* data); void encode(uint8_t* data);
public:
MotStartOfStream* startOfStream; // ?? - this should probably be private with getters/setters
MotFullRateVoice* fullRateVoice; // ?? - this should probably be private with getters/setters
/// <summary></summary>
__PROPERTY(ICWFlag, icw, ICW);
/// <summary></summary>
__PROPERTY(uint8_t, rssi, RSSI);
/// <summary></summary>
__PROPERTY(RssiValidityFlag, rssiValidity, RSSIValidity);
/// <summary></summary>
__PROPERTY(uint8_t, nRssi, NRSSI);
/// <summary></summary>
__PROPERTY(uint8_t, adjMM, AdjMM);
}; };
} // namespace dfsi } // namespace dfsi
} // namespace p25 } // namespace p25

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -13,7 +13,7 @@
* *
*/ */
#include "rtp/MotVoiceHeader1.h" #include "frames/MotVoiceHeader1.h"
#include "common/p25/dfsi/DFSIDefines.h" #include "common/p25/dfsi/DFSIDefines.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "common/Log.h" #include "common/Log.h"
@ -31,14 +31,16 @@ using namespace dfsi;
/// <summary> /// <summary>
/// Initializes a instance of the MotVoiceHeader1 class. /// Initializes a instance of the MotVoiceHeader1 class.
/// </summary> /// </summary>
MotVoiceHeader1::MotVoiceHeader1() MotVoiceHeader1::MotVoiceHeader1() :
header(nullptr),
startOfStream(nullptr),
m_icw(ICW_DIU),
m_rssi(0U),
m_rssiValidity(INVALID),
m_nRssi(0U)
{ {
icw = ICW_DIU; startOfStream = new MotStartOfStream();
rssi = 0;
rssiValidity = INVALID;
nRssi = 0;
startOfStream = nullptr;
header = new uint8_t[HCW_LENGTH]; header = new uint8_t[HCW_LENGTH];
::memset(header, 0x00U, HCW_LENGTH); ::memset(header, 0x00U, HCW_LENGTH);
} }
@ -57,8 +59,10 @@ MotVoiceHeader1::MotVoiceHeader1(uint8_t* data)
/// </summary> /// </summary>
MotVoiceHeader1::~MotVoiceHeader1() MotVoiceHeader1::~MotVoiceHeader1()
{ {
delete startOfStream; if (startOfStream != nullptr)
delete[] header; delete startOfStream;
if (header != nullptr)
delete[] header;
} }
/// <summary> /// <summary>
@ -70,21 +74,27 @@ bool MotVoiceHeader1::decode(const uint8_t* data)
{ {
assert(data != nullptr); assert(data != nullptr);
// Create a start of stream // create a start of stream
if (startOfStream != nullptr)
delete startOfStream;
startOfStream = new MotStartOfStream(); startOfStream = new MotStartOfStream();
uint8_t buffer[startOfStream->LENGTH];
::memset(buffer, 0x00U, startOfStream->LENGTH); uint8_t buffer[MotStartOfStream::LENGTH];
// We copy the bytes from [1:4] ::memset(buffer, 0x00U, MotStartOfStream::LENGTH);
// we copy the bytes from [1:4]
::memcpy(buffer + 1U, data + 1U, 4); ::memcpy(buffer + 1U, data + 1U, 4);
startOfStream->decode(buffer); startOfStream->decode(buffer);
// Decode the other stuff // decode the other stuff
icw = (ICWFlag)data[5U]; m_icw = (ICWFlag)data[5U];
rssi = data[6U]; m_rssi = data[6U];
rssiValidity = (RssiValidityFlag)data[7U]; m_rssiValidity = (RssiValidityFlag)data[7U];
nRssi = data[8U]; m_nRssi = data[8U];
// Our header includes the trailing source and check bytes // our header includes the trailing source and check bytes
if (header != nullptr)
delete[] header;
header = new uint8_t[HCW_LENGTH]; header = new uint8_t[HCW_LENGTH];
::memset(header, 0x00U, HCW_LENGTH); ::memset(header, 0x00U, HCW_LENGTH);
::memcpy(header, data + 9U, HCW_LENGTH); ::memcpy(header, data + 9U, HCW_LENGTH);
@ -103,20 +113,22 @@ void MotVoiceHeader1::encode(uint8_t* data)
data[0U] = P25_DFSI_MOT_VHDR_1; data[0U] = P25_DFSI_MOT_VHDR_1;
if (startOfStream != nullptr) { // scope is intentional
uint8_t buffer[startOfStream->LENGTH]; {
::memset(buffer, 0x00U, startOfStream->LENGTH); uint8_t buffer[MotStartOfStream::LENGTH];
::memset(buffer, 0x00U, MotStartOfStream::LENGTH);
startOfStream->encode(buffer); startOfStream->encode(buffer);
// Copy the 4 start record bytes from the start of stream frame
// copy the 4 start record bytes from the start of stream frame
::memcpy(data + 1U, buffer + 1U, 4U); ::memcpy(data + 1U, buffer + 1U, 4U);
} }
data[5U] = icw; data[5U] = (uint8_t)m_icw;
data[6U] = rssi; data[6U] = m_rssi;
data[7U] = (uint8_t)rssiValidity; data[7U] = (uint8_t)m_rssiValidity;
data[8U] = nRssi; data[8U] = m_nRssi;
// Our header includes the trailing source and check bytes // our header includes the trailing source and check bytes
if (header != nullptr) { if (header != nullptr) {
::memcpy(data + 9U, header, HCW_LENGTH); ::memcpy(data + 9U, header, HCW_LENGTH);
} }

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -19,8 +19,8 @@
#include "common/Defines.h" #include "common/Defines.h"
#include "common/Log.h" #include "common/Log.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "rtp/RtpDefines.h" #include "frames/FrameDefines.h"
#include "rtp/MotStartOfStream.h" #include "frames/MotStartOfStream.h"
namespace p25 namespace p25
{ {
@ -56,14 +56,6 @@ namespace p25
static const uint8_t LENGTH = 30; static const uint8_t LENGTH = 30;
static const uint8_t HCW_LENGTH = 21; static const uint8_t HCW_LENGTH = 21;
ICWFlag icw;
uint8_t rssi;
RssiValidityFlag rssiValidity;
uint8_t nRssi;
uint8_t* header;
MotStartOfStream* startOfStream;
/// <summary>Initializes a copy instance of the MotVoiceHeader1 class.</summary> /// <summary>Initializes a copy instance of the MotVoiceHeader1 class.</summary>
MotVoiceHeader1(); MotVoiceHeader1();
/// <summary>Initializes a copy instance of the MotVoiceHeader1 class.</summary> /// <summary>Initializes a copy instance of the MotVoiceHeader1 class.</summary>
@ -75,6 +67,19 @@ namespace p25
bool decode(const uint8_t* data); bool decode(const uint8_t* data);
/// <summary>Encode a voice header 1 frame.</summary> /// <summary>Encode a voice header 1 frame.</summary>
void encode(uint8_t* data); void encode(uint8_t* data);
public:
uint8_t* header; // ?? - this should probably be private with getters/setters
MotStartOfStream* startOfStream; // ?? - this should probably be private with getters/setters
/// <summary></summary>
__PROPERTY(ICWFlag, icw, ICW);
/// <summary></summary>
__PROPERTY(uint8_t, rssi, RSSI);
/// <summary></summary>
__PROPERTY(RssiValidityFlag, rssiValidity, RSSIValidity);
/// <summary></summary>
__PROPERTY(uint8_t, nRssi, NRSSI);
}; };
} // namespace dfsi } // namespace dfsi
} // namespace p25 } // namespace p25

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -13,7 +13,7 @@
* *
*/ */
#include "rtp/MotVoiceHeader2.h" #include "frames/MotVoiceHeader2.h"
#include "common/p25/dfsi/DFSIDefines.h" #include "common/p25/dfsi/DFSIDefines.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "common/Log.h" #include "common/Log.h"
@ -31,10 +31,10 @@ using namespace dfsi;
/// <summary> /// <summary>
/// Initializes a instance of the MotVoiceHeader2 class. /// Initializes a instance of the MotVoiceHeader2 class.
/// </summary> /// </summary>
MotVoiceHeader2::MotVoiceHeader2() MotVoiceHeader2::MotVoiceHeader2() :
header(nullptr),
m_source(SOURCE_QUANTAR)
{ {
source = SOURCE_QUANTAR;
header = new uint8_t[HCW_LENGTH]; header = new uint8_t[HCW_LENGTH];
::memset(header, 0x00U, HCW_LENGTH); ::memset(header, 0x00U, HCW_LENGTH);
} }
@ -53,7 +53,8 @@ MotVoiceHeader2::MotVoiceHeader2(uint8_t* data)
/// </summary> /// </summary>
MotVoiceHeader2::~MotVoiceHeader2() MotVoiceHeader2::~MotVoiceHeader2()
{ {
delete[] header; if (header != nullptr)
delete[] header;
} }
/// <summary> /// <summary>
@ -65,7 +66,11 @@ bool MotVoiceHeader2::decode(const uint8_t* data)
{ {
assert(data != nullptr); assert(data != nullptr);
source = (SourceFlag)data[21]; m_source = (SourceFlag)data[21];
if (header != nullptr) {
delete[] header;
}
header = new uint8_t[HCW_LENGTH]; header = new uint8_t[HCW_LENGTH];
::memset(header, 0x00U, HCW_LENGTH); ::memset(header, 0x00U, HCW_LENGTH);
@ -88,5 +93,5 @@ void MotVoiceHeader2::encode(uint8_t* data)
::memcpy(data + 1U, header, HCW_LENGTH); ::memcpy(data + 1U, header, HCW_LENGTH);
} }
data[LENGTH - 1U] = (uint8_t)source; data[LENGTH - 1U] = (uint8_t)m_source;
} }

@ -1,10 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/** /**
* Digital Voice Modem - Common Library * Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* @package DVM / DFSI peer application * @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost) * @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0) * @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
* *
@ -19,8 +19,8 @@
#include "common/Defines.h" #include "common/Defines.h"
#include "common/Log.h" #include "common/Log.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "rtp/RtpDefines.h" #include "frames/FrameDefines.h"
#include "rtp/MotStartOfStream.h" #include "frames/MotStartOfStream.h"
namespace p25 namespace p25
{ {
@ -52,15 +52,6 @@ namespace p25
static const uint8_t LENGTH = 22; static const uint8_t LENGTH = 22;
static const uint8_t HCW_LENGTH = 20; static const uint8_t HCW_LENGTH = 20;
ICWFlag icw;
uint8_t rssi;
RssiValidityFlag rssiValidity;
uint8_t nRssi;
MotStartOfStream startOfStream;
SourceFlag source;
uint8_t* header;
/// <summary>Initializes a copy instance of the MotVoiceHeader2 class.</summary> /// <summary>Initializes a copy instance of the MotVoiceHeader2 class.</summary>
MotVoiceHeader2(); MotVoiceHeader2();
/// <summary>Initializes a copy instance of the MotVoiceHeader2 class.</summary> /// <summary>Initializes a copy instance of the MotVoiceHeader2 class.</summary>
@ -72,6 +63,12 @@ namespace p25
bool decode(const uint8_t* data); bool decode(const uint8_t* data);
/// <summary>Encode a voice header 2 frame.</summary> /// <summary>Encode a voice header 2 frame.</summary>
void encode(uint8_t* data); void encode(uint8_t* data);
public:
uint8_t* header; // ?? - this should probably be a private with getters/setters
/// <summary></summary>
__PROPERTY(SourceFlag, source, Source);
}; };
} // namespace dfsi } // namespace dfsi
} // namespace p25 } // namespace p25

@ -0,0 +1,76 @@
// SPDX-License-Identifier: GPL-2.0-only
/**
* Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2024 Bryan Biedenkapp, N2PLL
*
*/
#include "frames/StartOfStream.h"
#include "common/p25/dfsi/DFSIDefines.h"
#include "common/Utils.h"
#include "common/Log.h"
#include <cassert>
#include <cstring>
using namespace p25;
using namespace dfsi;
// ---------------------------------------------------------------------------
// Public Class Members
// ---------------------------------------------------------------------------
/// <summary>
/// Initializes a instance of the StartOfStream class.
/// </summary>
StartOfStream::StartOfStream() :
m_nid(0U),
m_errorCount(0U)
{
/* stub */
}
/// <summary>
/// Initializes a instance of the StartOfStream class.
/// </summary>
/// <param name="data"></param>
StartOfStream::StartOfStream(uint8_t* data) :
m_nid(0U),
m_errorCount(0U)
{
decode(data);
}
/// <summary>
/// Decode a start of stream frame.
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
bool StartOfStream::decode(const uint8_t* data)
{
assert(data != nullptr);
m_nid = __GET_UINT16(data, 0U); // Network Identifier
m_errorCount = (data[2U] & 0x0FU); // Error Count
return true;
}
/// <summary>
/// Encode a start of stream frame.
/// </summary>
/// <param name="data"></param>
void StartOfStream::encode(uint8_t* data)
{
assert(data != nullptr);
__SET_UINT16(m_nid, data, 0U); // Network Identifier
data[2U] = m_errorCount & 0x0FU; // Error Count
}

@ -0,0 +1,62 @@
// SPDX-License-Identifier: GPL-2.0-only
/**
* Digital Voice Modem - DFSI Peer Application
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* @package DVM / DFSI Peer Application
* @derivedfrom MMDVMHost (https://github.com/g4klx/MMDVMHost)
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2024 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__START_OF_STREAM_H__)
#define __START_OF_STREAM_H__
#include "Defines.h"
#include "common/Defines.h"
#include "common/Log.h"
#include "common/Utils.h"
#include "frames/FrameDefines.h"
namespace p25
{
namespace dfsi
{
// ---------------------------------------------------------------------------
// Class Declaration
// Implements a P25 DFSI start of stream packet.
// </summary>
//
// Byte 0 1 2
// Bit 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | NID | Rsvd | Err C |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// ---------------------------------------------------------------------------
class HOST_SW_API StartOfStream {
public:
static const uint8_t LENGTH = 4;
/// <summary>Initializes a copy instance of the StartOfStream class.</summary>
StartOfStream();
/// <summary>Initializes a copy instance of the StartOfStream class.</summary>
StartOfStream(uint8_t* data);
/// <summary>Decode a start of stream frame.</summary>
bool decode(const uint8_t* data);
/// <summary>Encode a start of stream frame.</summary>
void encode(uint8_t* data);
public:
/// <summary></summary>
__PROPERTY(uint16_t, nid, NID);
/// <summary></summary>
__PROPERTY(uint8_t, errorCount, ErrorCount);
};
} // namespace dfsi
} // namespace p25
#endif // __START_OF_STREAM_H__

@ -29,7 +29,7 @@
#include "common/yaml/Yaml.h" #include "common/yaml/Yaml.h"
#include "common/RingBuffer.h" #include "common/RingBuffer.h"
#include "network/DfsiPeerNetwork.h" #include "network/DfsiPeerNetwork.h"
#include "rtp/RtpFrames.h" #include "frames/Frames.h"
#include "host/modem/Modem.h" #include "host/modem/Modem.h"
#include "host/modem/port/IModemPort.h" #include "host/modem/port/IModemPort.h"
#include "host/modem/port/UARTPort.h" #include "host/modem/port/UARTPort.h"

@ -558,7 +558,7 @@ void SerialService::processP25ToNet()
// Decode the frame // Decode the frame
MotStartOfStream start = MotStartOfStream(dfsiData); MotStartOfStream start = MotStartOfStream(dfsiData);
// Handle start/stop // Handle start/stop
if (start.startStop == StartStopFlag::START) { if (start.getStartStop() == StartStopFlag::START) {
// Flag we have a local call (i.e. from V24) in progress // Flag we have a local call (i.e. from V24) in progress
m_lclCallInProgress = true; m_lclCallInProgress = true;
// Reset the call data (just in case) // Reset the call data (just in case)
@ -657,7 +657,7 @@ void SerialService::processP25ToNet()
// Decode // Decode
MotStartVoiceFrame svf = MotStartVoiceFrame(dfsiData); MotStartVoiceFrame svf = MotStartVoiceFrame(dfsiData);
// Copy // Copy
::memcpy(m_rxVoiceCallData->netLDU1 + 10U, svf.fullRateVoice->imbeData, svf.fullRateVoice->IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU1 + 10U, svf.fullRateVoice->imbeData, MotFullRateVoice::IMBE_BUF_LEN);
// Increment our voice frame counter // Increment our voice frame counter
m_rxVoiceCallData->n++; m_rxVoiceCallData->n++;
} }
@ -667,7 +667,7 @@ void SerialService::processP25ToNet()
// Decode // Decode
MotStartVoiceFrame svf = MotStartVoiceFrame(dfsiData); MotStartVoiceFrame svf = MotStartVoiceFrame(dfsiData);
// Copy // Copy
::memcpy(m_rxVoiceCallData->netLDU2 + 10U, svf.fullRateVoice->imbeData, svf.fullRateVoice->IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU2 + 10U, svf.fullRateVoice->imbeData, MotFullRateVoice::IMBE_BUF_LEN);
// Increment our voice frame counter // Increment our voice frame counter
m_rxVoiceCallData->n++; m_rxVoiceCallData->n++;
} }
@ -682,13 +682,13 @@ void SerialService::processP25ToNet()
// VOICE2 // VOICE2
case P25_DFSI_LDU1_VOICE2: case P25_DFSI_LDU1_VOICE2:
{ {
::memcpy(m_rxVoiceCallData->netLDU1 + 26U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU1 + 26U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
} }
break; break;
// VOICE3 // VOICE3
case P25_DFSI_LDU1_VOICE3: case P25_DFSI_LDU1_VOICE3:
{ {
::memcpy(m_rxVoiceCallData->netLDU1 + 55U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU1 + 55U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
if (voice.additionalData != nullptr) { if (voice.additionalData != nullptr) {
m_rxVoiceCallData->lco = voice.additionalData[0U]; m_rxVoiceCallData->lco = voice.additionalData[0U];
m_rxVoiceCallData->mfId = voice.additionalData[1U]; m_rxVoiceCallData->mfId = voice.additionalData[1U];
@ -701,7 +701,7 @@ void SerialService::processP25ToNet()
// VOICE4 // VOICE4
case P25_DFSI_LDU1_VOICE4: case P25_DFSI_LDU1_VOICE4:
{ {
::memcpy(m_rxVoiceCallData->netLDU1 + 80U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU1 + 80U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
if (voice.additionalData != nullptr) { if (voice.additionalData != nullptr) {
m_rxVoiceCallData->dstId = __GET_UINT16(voice.additionalData, 0U); m_rxVoiceCallData->dstId = __GET_UINT16(voice.additionalData, 0U);
} else { } else {
@ -712,7 +712,7 @@ void SerialService::processP25ToNet()
// VOICE5 // VOICE5
case P25_DFSI_LDU1_VOICE5: case P25_DFSI_LDU1_VOICE5:
{ {
::memcpy(m_rxVoiceCallData->netLDU1 + 105U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU1 + 105U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
if (voice.additionalData != nullptr) { if (voice.additionalData != nullptr) {
m_rxVoiceCallData->srcId = __GET_UINT16(voice.additionalData, 0U); m_rxVoiceCallData->srcId = __GET_UINT16(voice.additionalData, 0U);
} else { } else {
@ -723,25 +723,25 @@ void SerialService::processP25ToNet()
// VOICE6 // VOICE6
case P25_DFSI_LDU1_VOICE6: case P25_DFSI_LDU1_VOICE6:
{ {
::memcpy(m_rxVoiceCallData->netLDU1 + 130U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU1 + 130U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
} }
break; break;
// VOICE7 // VOICE7
case P25_DFSI_LDU1_VOICE7: case P25_DFSI_LDU1_VOICE7:
{ {
::memcpy(m_rxVoiceCallData->netLDU1 + 155U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU1 + 155U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
} }
break; break;
// VOICE8 // VOICE8
case P25_DFSI_LDU1_VOICE8: case P25_DFSI_LDU1_VOICE8:
{ {
::memcpy(m_rxVoiceCallData->netLDU1 + 180U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU1 + 180U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
} }
break; break;
// VOICE9 // VOICE9
case P25_DFSI_LDU1_VOICE9: case P25_DFSI_LDU1_VOICE9:
{ {
::memcpy(m_rxVoiceCallData->netLDU1 + 204U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU1 + 204U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
if (voice.additionalData != nullptr) { if (voice.additionalData != nullptr) {
m_rxVoiceCallData->lsd1 = voice.additionalData[0U]; m_rxVoiceCallData->lsd1 = voice.additionalData[0U];
m_rxVoiceCallData->lsd2 = voice.additionalData[1U]; m_rxVoiceCallData->lsd2 = voice.additionalData[1U];
@ -753,13 +753,13 @@ void SerialService::processP25ToNet()
// VOICE11 // VOICE11
case P25_DFSI_LDU2_VOICE11: case P25_DFSI_LDU2_VOICE11:
{ {
::memcpy(m_rxVoiceCallData->netLDU2 + 26U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU2 + 26U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
} }
break; break;
// VOICE12 // VOICE12
case P25_DFSI_LDU2_VOICE12: case P25_DFSI_LDU2_VOICE12:
{ {
::memcpy(m_rxVoiceCallData->netLDU2 + 55U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU2 + 55U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
if (voice.additionalData != nullptr) { if (voice.additionalData != nullptr) {
::memcpy(m_rxVoiceCallData->mi, voice.additionalData, 3U); ::memcpy(m_rxVoiceCallData->mi, voice.additionalData, 3U);
} else { } else {
@ -770,7 +770,7 @@ void SerialService::processP25ToNet()
// VOICE13 // VOICE13
case P25_DFSI_LDU2_VOICE13: case P25_DFSI_LDU2_VOICE13:
{ {
::memcpy(m_rxVoiceCallData->netLDU2 + 80U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU2 + 80U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
if (voice.additionalData != nullptr) { if (voice.additionalData != nullptr) {
::memcpy(m_rxVoiceCallData->mi + 3U, voice.additionalData, 3U); ::memcpy(m_rxVoiceCallData->mi + 3U, voice.additionalData, 3U);
} else { } else {
@ -781,7 +781,7 @@ void SerialService::processP25ToNet()
// VOICE14 // VOICE14
case P25_DFSI_LDU2_VOICE14: case P25_DFSI_LDU2_VOICE14:
{ {
::memcpy(m_rxVoiceCallData->netLDU2 + 105U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU2 + 105U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
if (voice.additionalData != nullptr) { if (voice.additionalData != nullptr) {
::memcpy(m_rxVoiceCallData->mi + 6U, voice.additionalData, 3U); ::memcpy(m_rxVoiceCallData->mi + 6U, voice.additionalData, 3U);
} else { } else {
@ -792,7 +792,7 @@ void SerialService::processP25ToNet()
// VOICE15 // VOICE15
case P25_DFSI_LDU2_VOICE15: case P25_DFSI_LDU2_VOICE15:
{ {
::memcpy(m_rxVoiceCallData->netLDU2 + 130U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU2 + 130U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
if (voice.additionalData != nullptr) { if (voice.additionalData != nullptr) {
m_rxVoiceCallData->algoId = voice.additionalData[0U]; m_rxVoiceCallData->algoId = voice.additionalData[0U];
m_rxVoiceCallData->kId = __GET_UINT16B(voice.additionalData, 1U); m_rxVoiceCallData->kId = __GET_UINT16B(voice.additionalData, 1U);
@ -804,19 +804,19 @@ void SerialService::processP25ToNet()
// VOICE16 // VOICE16
case P25_DFSI_LDU2_VOICE16: case P25_DFSI_LDU2_VOICE16:
{ {
::memcpy(m_rxVoiceCallData->netLDU2 + 155U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU2 + 155U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
} }
break; break;
// VOICE17 // VOICE17
case P25_DFSI_LDU2_VOICE17: case P25_DFSI_LDU2_VOICE17:
{ {
::memcpy(m_rxVoiceCallData->netLDU2 + 180U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU2 + 180U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
} }
break; break;
// VOICE18 // VOICE18
case P25_DFSI_LDU2_VOICE18: case P25_DFSI_LDU2_VOICE18:
{ {
::memcpy(m_rxVoiceCallData->netLDU2 + 204U, voice.imbeData, voice.IMBE_BUF_LEN); ::memcpy(m_rxVoiceCallData->netLDU2 + 204U, voice.imbeData, MotFullRateVoice::IMBE_BUF_LEN);
if (voice.additionalData != nullptr) { if (voice.additionalData != nullptr) {
m_rxVoiceCallData->lsd1 = voice.additionalData[0U]; m_rxVoiceCallData->lsd1 = voice.additionalData[0U];
m_rxVoiceCallData->lsd2 = voice.additionalData[1U]; m_rxVoiceCallData->lsd2 = voice.additionalData[1U];
@ -1317,21 +1317,19 @@ void SerialService::writeP25Frame(uint8_t duid, dfsi::LC& lc, uint8_t* ldu)
case 0: // VOICE1/10 case 0: // VOICE1/10
{ {
// Set frametype // Set frametype
voice.frameType = (duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE1 : P25_DFSI_LDU2_VOICE10; voice.setFrameType((duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE1 : P25_DFSI_LDU2_VOICE10);
// Create the new frame objects // Create the new frame objects
MotStartVoiceFrame svf = MotStartVoiceFrame(); MotStartVoiceFrame svf = MotStartVoiceFrame();
svf.startOfStream = new MotStartOfStream();
svf.fullRateVoice = new MotFullRateVoice();
// Set values appropriately // Set values appropriately
svf.startOfStream->startStop = StartStopFlag::START; svf.startOfStream->setStartStop(StartStopFlag::START);
svf.startOfStream->rt = m_rtrt ? RTFlag::ENABLED : RTFlag::DISABLED; svf.startOfStream->setRT(m_rtrt ? RTFlag::ENABLED : RTFlag::DISABLED);
// Set frame type // Set frame type
svf.fullRateVoice->frameType = voice.frameType; svf.fullRateVoice->setFrameType(voice.getFrameType());
// Set source flag & ICW flag // Set source flag & ICW flag
svf.fullRateVoice->source = m_diu ? SOURCE_DIU : SOURCE_QUANTAR; svf.fullRateVoice->setSource(m_diu ? SOURCE_DIU : SOURCE_QUANTAR);
svf.icw = m_diu ? ICW_DIU : ICW_QUANTAR; svf.setICW(m_diu ? ICW_DIU : ICW_QUANTAR);
// Copy data // Copy data
::memcpy(svf.fullRateVoice->imbeData, ldu + 10U, svf.fullRateVoice->IMBE_BUF_LEN); ::memcpy(svf.fullRateVoice->imbeData, ldu + 10U, MotFullRateVoice::IMBE_BUF_LEN);
// Encode // Encode
buffer = new uint8_t[svf.LENGTH]; buffer = new uint8_t[svf.LENGTH];
::memset(buffer, 0x00U, svf.LENGTH); ::memset(buffer, 0x00U, svf.LENGTH);
@ -1341,21 +1339,21 @@ void SerialService::writeP25Frame(uint8_t duid, dfsi::LC& lc, uint8_t* ldu)
break; break;
case 1: // VOICE2/11 case 1: // VOICE2/11
{ {
voice.frameType = (duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE2 : P25_DFSI_LDU2_VOICE11; voice.setFrameType((duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE2 : P25_DFSI_LDU2_VOICE11);
// Set source flag // Set source flag
voice.source = m_diu ? SOURCE_DIU : SOURCE_QUANTAR; voice.setSource(m_diu ? SOURCE_DIU : SOURCE_QUANTAR);
::memcpy(voice.imbeData, ldu + 26U, voice.IMBE_BUF_LEN); ::memcpy(voice.imbeData, ldu + 26U, voice.IMBE_BUF_LEN);
} }
break; break;
case 2: // VOICE3/12 case 2: // VOICE3/12
{ {
voice.frameType = (duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE3 : P25_DFSI_LDU2_VOICE12; voice.setFrameType((duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE3 : P25_DFSI_LDU2_VOICE12);
::memcpy(voice.imbeData, ldu + 55U, voice.IMBE_BUF_LEN); ::memcpy(voice.imbeData, ldu + 55U, voice.IMBE_BUF_LEN);
// Create the additional data array // Create the additional data array
voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH]; voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH];
::memset(voice.additionalData, 0x00U, voice.ADDITIONAL_LENGTH); ::memset(voice.additionalData, 0x00U, voice.ADDITIONAL_LENGTH);
// Copy additional data // Copy additional data
if (voice.frameType == P25_DUID_LDU1) { if (voice.getFrameType() == P25_DUID_LDU1) {
voice.additionalData[0U] = control.getLCO(); voice.additionalData[0U] = control.getLCO();
voice.additionalData[1U] = control.getMFId(); voice.additionalData[1U] = control.getMFId();
voice.additionalData[2U] = serviceOptions; voice.additionalData[2U] = serviceOptions;
@ -1368,7 +1366,7 @@ void SerialService::writeP25Frame(uint8_t duid, dfsi::LC& lc, uint8_t* ldu)
break; break;
case 3: // VOICE4/13 case 3: // VOICE4/13
{ {
voice.frameType = (duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE4 : P25_DFSI_LDU2_VOICE13; voice.setFrameType((duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE4 : P25_DFSI_LDU2_VOICE13);
::memcpy(voice.imbeData, ldu + 80U, voice.IMBE_BUF_LEN); ::memcpy(voice.imbeData, ldu + 80U, voice.IMBE_BUF_LEN);
// Create the additional data array // Create the additional data array
voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH]; voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH];
@ -1394,7 +1392,7 @@ void SerialService::writeP25Frame(uint8_t duid, dfsi::LC& lc, uint8_t* ldu)
break; break;
case 4: // VOICE5/14 case 4: // VOICE5/14
{ {
voice.frameType = (duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE5 : P25_DFSI_LDU2_VOICE14; voice.setFrameType((duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE5 : P25_DFSI_LDU2_VOICE14);
::memcpy(voice.imbeData, ldu + 105U, voice.IMBE_BUF_LEN); ::memcpy(voice.imbeData, ldu + 105U, voice.IMBE_BUF_LEN);
// Create the additional data array // Create the additional data array
voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH]; voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH];
@ -1420,7 +1418,7 @@ void SerialService::writeP25Frame(uint8_t duid, dfsi::LC& lc, uint8_t* ldu)
break; break;
case 5: // VOICE6/15 case 5: // VOICE6/15
{ {
voice.frameType = (duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE6 : P25_DFSI_LDU2_VOICE15; voice.setFrameType((duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE6 : P25_DFSI_LDU2_VOICE15);
::memcpy(voice.imbeData, ldu + 130U, voice.IMBE_BUF_LEN); ::memcpy(voice.imbeData, ldu + 130U, voice.IMBE_BUF_LEN);
// Create the additional data array // Create the additional data array
voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH]; voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH];
@ -1446,7 +1444,7 @@ void SerialService::writeP25Frame(uint8_t duid, dfsi::LC& lc, uint8_t* ldu)
break; break;
case 6: // VOICE7/16 case 6: // VOICE7/16
{ {
voice.frameType = (duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE7 : P25_DFSI_LDU2_VOICE16; voice.setFrameType((duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE7 : P25_DFSI_LDU2_VOICE16);
::memcpy(voice.imbeData, ldu + 155U, voice.IMBE_BUF_LEN); ::memcpy(voice.imbeData, ldu + 155U, voice.IMBE_BUF_LEN);
// Create the additional data array // Create the additional data array
voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH]; voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH];
@ -1459,7 +1457,7 @@ void SerialService::writeP25Frame(uint8_t duid, dfsi::LC& lc, uint8_t* ldu)
break; break;
case 7: // VOICE8/17 case 7: // VOICE8/17
{ {
voice.frameType = (duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE8 : P25_DFSI_LDU2_VOICE17; voice.setFrameType((duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE8 : P25_DFSI_LDU2_VOICE17);
::memcpy(voice.imbeData, ldu + 180U, voice.IMBE_BUF_LEN); ::memcpy(voice.imbeData, ldu + 180U, voice.IMBE_BUF_LEN);
// Create the additional data array // Create the additional data array
voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH]; voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH];
@ -1472,7 +1470,7 @@ void SerialService::writeP25Frame(uint8_t duid, dfsi::LC& lc, uint8_t* ldu)
break; break;
case 8: // VOICE9/18 case 8: // VOICE9/18
{ {
voice.frameType = (duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE9 : P25_DFSI_LDU2_VOICE18; voice.setFrameType((duid == P25_DUID_LDU1) ? P25_DFSI_LDU1_VOICE9 : P25_DFSI_LDU2_VOICE18);
::memcpy(voice.imbeData, ldu + 204U, voice.IMBE_BUF_LEN); ::memcpy(voice.imbeData, ldu + 204U, voice.IMBE_BUF_LEN);
// Create the additional data array // Create the additional data array
voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH]; voice.additionalData = new uint8_t[voice.ADDITIONAL_LENGTH];
@ -1516,8 +1514,8 @@ void SerialService::startOfStream(const LC& lc)
// Create new start of stream // Create new start of stream
MotStartOfStream start = MotStartOfStream(); MotStartOfStream start = MotStartOfStream();
start.startStop = StartStopFlag::START; start.setStartStop(StartStopFlag::START);
start.rt = m_rtrt ? RTFlag::ENABLED : RTFlag::DISABLED; start.setRT(m_rtrt ? RTFlag::ENABLED : RTFlag::DISABLED);
// Create buffer for bytes and encode // Create buffer for bytes and encode
uint8_t buffer[start.LENGTH]; uint8_t buffer[start.LENGTH];
@ -1567,10 +1565,9 @@ void SerialService::startOfStream(const LC& lc)
// Prepare VHDR1 // Prepare VHDR1
MotVoiceHeader1 vhdr1 = MotVoiceHeader1(); MotVoiceHeader1 vhdr1 = MotVoiceHeader1();
vhdr1.startOfStream = new MotStartOfStream(); vhdr1.startOfStream->setStartStop(StartStopFlag::START);
vhdr1.startOfStream->startStop = StartStopFlag::START; vhdr1.startOfStream->setRT(m_rtrt ? RTFlag::ENABLED : RTFlag::DISABLED);
vhdr1.startOfStream->rt = m_rtrt ? RTFlag::ENABLED : RTFlag::DISABLED; vhdr1.setICW(m_diu ? ICW_DIU : ICW_QUANTAR);
vhdr1.icw = m_diu ? ICW_DIU : ICW_QUANTAR;
::memcpy(vhdr1.header, raw, 8U); ::memcpy(vhdr1.header, raw, 8U);
::memcpy(vhdr1.header + 9U, raw + 8U, 8U); ::memcpy(vhdr1.header + 9U, raw + 8U, 8U);
::memcpy(vhdr1.header + 18U, raw + 16U, 2U); ::memcpy(vhdr1.header + 18U, raw + 16U, 2U);
@ -1614,7 +1611,7 @@ void SerialService::endOfStream()
{ {
// Create the new end of stream (which looks like a start of stream with the stop flag) // Create the new end of stream (which looks like a start of stream with the stop flag)
MotStartOfStream end = MotStartOfStream(); MotStartOfStream end = MotStartOfStream();
end.startStop = StartStopFlag::STOP; end.setStartStop(StartStopFlag::STOP);
// Create buffer and encode // Create buffer and encode
uint8_t buffer[end.LENGTH]; uint8_t buffer[end.LENGTH];

@ -29,7 +29,7 @@
#include "common/RingBuffer.h" #include "common/RingBuffer.h"
#include "network/DfsiPeerNetwork.h" #include "network/DfsiPeerNetwork.h"
#include "network/CallData.h" #include "network/CallData.h"
#include "rtp/RtpFrames.h" #include "frames/Frames.h"
#include "host/modem/Modem.h" #include "host/modem/Modem.h"
#include "host/modem/port/IModemPort.h" #include "host/modem/port/IModemPort.h"
#include "host/modem/port/UARTPort.h" #include "host/modem/port/UARTPort.h"

Loading…
Cancel
Save

Powered by TurnKey Linux.