diff --git a/configs/config.example.yml b/configs/config.example.yml
index 6484d1ef..a933b111 100644
--- a/configs/config.example.yml
+++ b/configs/config.example.yml
@@ -473,7 +473,7 @@ system:
# Size (in bytes) of the DMR transmit FIFO buffer.
dmrFifoLength: 505
# Size (in bytes) of the P25 transmit FIFO buffer.
- p25FifoLength: 442
+ p25FifoLength: 522
# Size (in bytes) of the NXDN transmit FIFO buffer.
nxdnFifoLength: 538
diff --git a/src/common/edac/CRC.cpp b/src/common/edac/CRC.cpp
index a72de316..760f6582 100644
--- a/src/common/edac/CRC.cpp
+++ b/src/common/edac/CRC.cpp
@@ -9,7 +9,7 @@
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
-* Copyright (C) 2018,2022 Bryan Biedenkapp, N2PLL
+* Copyright (C) 2018,2022,2024 Bryan Biedenkapp, N2PLL
*
*/
#include "Defines.h"
@@ -49,22 +49,6 @@ const uint8_t CRC8_TABLE[] = {
0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF,
0xFA, 0xFD, 0xF4, 0xF3, 0x01 };
-const uint16_t CRC9_TABLE[] = {
- 0x1E7U, 0x1F3U, 0x1F9U, 0x1FCU, 0x0D2U, 0x045U, 0x122U, 0x0BDU, 0x15EU, 0x083,
- 0x141U, 0x1A0U, 0x0FCU, 0x052U, 0x005U, 0x102U, 0x0ADU, 0x156U, 0x087U, 0x143,
- 0x1A1U, 0x1D0U, 0x0C4U, 0x04EU, 0x00BU, 0x105U, 0x182U, 0x0EDU, 0x176U, 0x097,
- 0x14BU, 0x1A5U, 0x1D2U, 0x0C5U, 0x162U, 0x09DU, 0x14EU, 0x08BU, 0x145U, 0x1A2,
- 0x0FDU, 0x17EU, 0x093U, 0x149U, 0x1A4U, 0x0FEU, 0x053U, 0x129U, 0x194U, 0x0E6,
- 0x05FU, 0x12FU, 0x197U, 0x1CBU, 0x1E5U, 0x1F2U, 0x0D5U, 0x16AU, 0x099U, 0x14C,
- 0x08AU, 0x069U, 0x134U, 0x0B6U, 0x077U, 0x13BU, 0x19DU, 0x1CEU, 0x0CBU, 0x165,
- 0x1B2U, 0x0F5U, 0x17AU, 0x091U, 0x148U, 0x088U, 0x068U, 0x018U, 0x020U, 0x03C,
- 0x032U, 0x035U, 0x11AU, 0x0A1U, 0x150U, 0x084U, 0x06EU, 0x01BU, 0x10DU, 0x186,
- 0x0EFU, 0x177U, 0x1BBU, 0x1DDU, 0x1EEU, 0x0DBU, 0x16DU, 0x1B6U, 0x0F7U, 0x17B,
- 0x1BDU, 0x1DEU, 0x0C3U, 0x161U, 0x1B0U, 0x0F4U, 0x056U, 0x007U, 0x103U, 0x181,
- 0x1C0U, 0x0CCU, 0x04AU, 0x009U, 0x104U, 0x0AEU, 0x07BU, 0x13DU, 0x19EU, 0x0E3,
- 0x171U, 0x1B8U, 0x0F0U, 0x054U, 0x006U, 0x02FU, 0x117U, 0x18BU, 0x1C5U, 0x1E2,
- 0x0DDU, 0x16EU, 0x09BU, 0x14DU, 0x1A6U };
-
const uint16_t CCITT16_TABLE1[] = {
0x0000U, 0x1189U, 0x2312U, 0x329BU, 0x4624U, 0x57ADU, 0x6536U, 0x74BFU,
0x8C48U, 0x9DC1U, 0xAF5AU, 0xBED3U, 0xCA6CU, 0xDBE5U, 0xE97EU, 0xF8F7U,
@@ -427,38 +411,6 @@ uint8_t CRC::crc8(const uint8_t *in, uint32_t length)
return crc;
}
-///
-/// Generate 9-bit CRC.
-///
-/// Input byte array.
-/// Length of byte array in bits.
-/// Calculated 9-bit CRC value.
-uint16_t CRC::crc9(const uint8_t* in, uint32_t bitLength)
-{
- assert(in != nullptr);
-
- uint16_t crc = 0x00U;
-
- for (uint32_t i = 0; i < bitLength; i++) {
- bool b = READ_BIT(in, i);
- if (b) {
- if (i < 7U) {
- crc ^= CRC9_TABLE[i];
- } else if (i > 15) {
- crc ^= CRC9_TABLE[i - 9];
- }
- }
- }
-
- crc &= 0x1FFU;
-
-#if DEBUG_CRC_CHECK
- LogDebug(LOG_HOST, "CRC::crc9(), crc = $%03X, bitlen = %u", crc, bitLength);
-#endif
-
- return crc;
-}
-
///
/// Check 6-bit CRC.
///
@@ -694,7 +646,31 @@ uint16_t CRC::addCRC16(uint8_t* in, uint32_t bitLength)
}
///
-///
+/// Generate 9-bit CRC.
+///
+/// Input byte array.
+/// Length of byte array in bits.
+///
+uint16_t CRC::createCRC9(const uint8_t* in, uint32_t bitLength)
+{
+ uint16_t crc = 0U;
+
+ for (uint32_t i = 0U; i < bitLength; i++) {
+ bool bit1 = READ_BIT(in, i) != 0x00U;
+ bool bit2 = (crc & 0x100U) == 0x100U;
+
+ crc <<= 1;
+
+ if (bit1 ^ bit2)
+ crc ^= 0x59U;
+ }
+
+ crc = ~crc;
+ return crc & 0x1FFU;
+}
+
+///
+/// Generate 16-bit CRC.
///
/// Input byte array.
/// Length of byte array in bits.
diff --git a/src/common/edac/CRC.h b/src/common/edac/CRC.h
index 8a8cc223..541c6f51 100644
--- a/src/common/edac/CRC.h
+++ b/src/common/edac/CRC.h
@@ -9,7 +9,7 @@
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2015,2016 Jonathan Naylor, G4KLX
-* Copyright (C) 2018,2022 Bryan Biedenkapp, N2PLL
+* Copyright (C) 2018,2022,2024 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__CRC_H__)
@@ -49,9 +49,6 @@ namespace edac
/// Generate 8-bit CRC.
static uint8_t crc8(const uint8_t* in, uint32_t length);
- /// Generate 9-bit CRC.
- static uint16_t crc9(const uint8_t* in, uint32_t bitLength);
-
/// Check 6-bit CRC.
static bool checkCRC6(const uint8_t* in, uint32_t bitLength);
/// Encode 6-bit CRC.
@@ -72,7 +69,9 @@ namespace edac
/// Encode 16-bit CRC CCITT-162 w/ initial generator of 1.
static uint16_t addCRC16(uint8_t* in, uint32_t bitLength);
- ///
+ /// Generate 9-bit CRC.
+ static uint16_t createCRC9(const uint8_t* in, uint32_t bitLength);
+ /// Generate 16-bit CRC.
static uint16_t createCRC16(const uint8_t* in, uint32_t bitLength);
private:
diff --git a/src/common/p25/P25Defines.h b/src/common/p25/P25Defines.h
index 4157685d..43a0dcc0 100644
--- a/src/common/p25/P25Defines.h
+++ b/src/common/p25/P25Defines.h
@@ -41,6 +41,9 @@ namespace p25
const uint32_t P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES = 90U;
const uint32_t P25_TSDU_TRIPLE_FRAME_LENGTH_BITS = P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES * 8U;
+ const uint32_t P25_PDU_FRAME_LENGTH_BYTES = 512U;
+ const uint32_t P25_PDU_FRAME_LENGTH_BITS = P25_PDU_FRAME_LENGTH_BYTES * 8U;
+
const uint32_t P25_TDULC_FRAME_LENGTH_BYTES = 54U;
const uint32_t P25_TDULC_FRAME_LENGTH_BITS = P25_TDULC_FRAME_LENGTH_BYTES * 8U;
@@ -68,8 +71,8 @@ namespace p25
const uint32_t P25_TSBK_FEC_LENGTH_BITS = P25_TSBK_FEC_LENGTH_BYTES * 8U - 4U; // Trellis is actually 196 bits
const uint32_t P25_TSBK_LENGTH_BYTES = 12U;
- const uint32_t P25_MAX_PDU_COUNT = 32U;
- const uint32_t P25_MAX_PDU_LENGTH = 512U;
+ const uint32_t P25_MAX_PDU_BLOCKS = 42U;
+
const uint32_t P25_PDU_HEADER_LENGTH_BYTES = 12U;
const uint32_t P25_PDU_CONFIRMED_LENGTH_BYTES = 18U;
const uint32_t P25_PDU_CONFIRMED_DATA_LENGTH_BYTES = 16U;
diff --git a/src/common/p25/data/DataBlock.cpp b/src/common/p25/data/DataBlock.cpp
index 2a367412..7da5d75e 100644
--- a/src/common/p25/data/DataBlock.cpp
+++ b/src/common/p25/data/DataBlock.cpp
@@ -100,11 +100,24 @@ bool DataBlock::decode(const uint8_t* data, const DataHeader& header)
}
else {
::memcpy(m_data, buffer + 2U, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES); // Payload Data
- }
+ }
+
+ uint8_t crcBuffer[18U];
+ ::memset(crcBuffer, 0x00U, 18U);
+
+ // generate CRC buffer
+ for (uint32_t i = 0; i < 144U; i++) {
+ bool b = READ_BIT(buffer, i);
+ if (i < 7U) {
+ WRITE_BIT(crcBuffer, i, b);
+ } else if (i > 15U) {
+ WRITE_BIT(crcBuffer, i - 9U, b);
+ }
+ }
// compute CRC-9 for the packet
- uint16_t calculated = edac::CRC::crc9(buffer, 144U);
- if (((crc ^ calculated) != 0) && ((crc ^ calculated) != 0x1FFU)) {
+ uint16_t calculated = edac::CRC::createCRC9(crcBuffer, 135U);
+ if ((crc ^ calculated) != 0) {
LogWarning(LOG_P25, "P25_DUID_PDU, fmt = $%02X, invalid crc = $%04X != $%04X (computed)", m_fmt, crc, calculated);
}
@@ -176,7 +189,20 @@ void DataBlock::encode(uint8_t* data)
::memcpy(buffer + 2U, m_data, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
}
- uint16_t crc = edac::CRC::crc9(buffer, 144U);
+ uint8_t crcBuffer[18U];
+ ::memset(crcBuffer, 0x00U, 18U);
+
+ // generate CRC buffer
+ for (uint32_t i = 0; i < 144U; i++) {
+ bool b = READ_BIT(buffer, i);
+ if (i < 7U) {
+ WRITE_BIT(crcBuffer, i, b);
+ } else if (i > 15U) {
+ WRITE_BIT(crcBuffer, i - 9U, b);
+ }
+ }
+
+ uint16_t crc = edac::CRC::createCRC9(crcBuffer, 135U);
buffer[0U] = buffer[0U] + ((crc >> 8) & 0x01U); // CRC-9 Check Sum (b8)
buffer[1U] = (crc & 0xFFU); // CRC-9 Check Sum (b0 - b7)
diff --git a/src/fw/hotspot b/src/fw/hotspot
index 07ec4612..88224479 160000
--- a/src/fw/hotspot
+++ b/src/fw/hotspot
@@ -1 +1 @@
-Subproject commit 07ec4612fc6e7c018b77a880c59154bd88e80492
+Subproject commit 882244795b9bec1f2c86d596d4ab4ecd4346c8b9
diff --git a/src/fw/modem b/src/fw/modem
index 93a59264..98d3bb1c 160000
--- a/src/fw/modem
+++ b/src/fw/modem
@@ -1 +1 @@
-Subproject commit 93a59264ff2e8515d11aa259577ee106287fd51d
+Subproject commit 98d3bb1cd9bd1bdfa8d723c15f8847841739e9ca
diff --git a/src/host/Host.Config.cpp b/src/host/Host.Config.cpp
index 20fca540..b0755227 100644
--- a/src/host/Host.Config.cpp
+++ b/src/host/Host.Config.cpp
@@ -454,6 +454,22 @@ bool Host::createModem()
uint16_t p25FifoLength = (uint16_t)modemConf["p25FifoLength"].as(P25_TX_BUFFER_LEN);
uint16_t nxdnFifoLength = (uint16_t)modemConf["nxdnFifoLength"].as(NXDN_TX_BUFFER_LEN);
+ // clamp fifo sizes
+ if (dmrFifoLength < DMR_TX_BUFFER_LEN) {
+ LogWarning(LOG_HOST, "DMR FIFO size must be greater then %u bytes, defaulting to %u bytes!", DMR_TX_BUFFER_LEN, DMR_TX_BUFFER_LEN);
+ dmrFifoLength = DMR_TX_BUFFER_LEN;
+ }
+
+ if (p25FifoLength < 442U/*P25_TX_BUFFER_LEN*/) {
+ LogWarning(LOG_HOST, "P25 FIFO size must be greater then %u bytes, defaulting to %u bytes!", 442U/*P25_TX_BUFFER_LEN*/, 442U/*P25_TX_BUFFER_LEN*/);
+ p25FifoLength = 442U/*P25_TX_BUFFER_LEN*/;
+ }
+
+ if (nxdnFifoLength < NXDN_TX_BUFFER_LEN) {
+ LogWarning(LOG_HOST, "NXDN FIFO size must be greater then %u frames, defaulting to %u frames!", NXDN_TX_BUFFER_LEN, NXDN_TX_BUFFER_LEN);
+ nxdnFifoLength = NXDN_TX_BUFFER_LEN;
+ }
+
float rxLevel = modemConf["rxLevel"].as(50.0F);
float cwIdTXLevel = modemConf["cwIdTxLevel"].as(50.0F);
float dmrTXLevel = modemConf["dmrTxLevel"].as(50.0F);
diff --git a/src/host/Host.P25.cpp b/src/host/Host.P25.cpp
index 96a55dd0..9a1e9c32 100644
--- a/src/host/Host.P25.cpp
+++ b/src/host/Host.P25.cpp
@@ -43,7 +43,7 @@ void Host::interruptP25Control(p25::Control* control)
///
void Host::readFramesP25(p25::Control* control, std::function&& afterReadCallback)
{
- uint8_t data[p25::P25_LDU_FRAME_LENGTH_BYTES * 2U];
+ uint8_t data[p25::P25_PDU_FRAME_LENGTH_BYTES * 2U];
// read P25 frames from modem, and if there are frames
// write those frames to the P25 controller
diff --git a/src/host/modem/Modem.cpp b/src/host/modem/Modem.cpp
index 810463fe..4a163674 100644
--- a/src/host/modem/Modem.cpp
+++ b/src/host/modem/Modem.cpp
@@ -9,7 +9,7 @@
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2011-2021 Jonathan Naylor, G4KLX
-* Copyright (C) 2017-2022 Bryan Biedenkapp, N2PLL
+* Copyright (C) 2017-2024 Bryan Biedenkapp, N2PLL
* Copyright (C) 2021 Nat Moore
*
*/
@@ -377,7 +377,7 @@ void Modem::setRXLevel(float rxLevel)
uint8_t buffer[4U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 4U;
buffer[2U] = CMD_SET_RXLEVEL;
@@ -437,7 +437,7 @@ void Modem::setFifoLength(uint16_t dmrLength, uint16_t p25Length, uint16_t nxdnL
uint8_t buffer[9U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 9U;
buffer[2U] = CMD_SET_BUFFERS;
@@ -628,7 +628,12 @@ void Modem::clock(uint32_t ms)
}
else {
// type == RTM_OK
- switch (m_buffer[2U]) {
+ uint8_t cmdOffset = 2U;
+ if (m_rspDoubleLength) {
+ cmdOffset = 3U;
+ }
+
+ switch (m_buffer[cmdOffset]) {
/** Digital Mobile Radio */
case CMD_DMR_DATA1:
{
@@ -727,18 +732,15 @@ void Modem::clock(uint32_t ms)
//if (m_trace)
// Utils::dump(1U, "RX P25 Data", m_buffer, m_length);
- if (m_rspDoubleLength) {
- LogError(LOG_MODEM, "CMD_P25_DATA double length?; len = %u", m_length);
- break;
- }
+ uint8_t length[2U];
+ length[0U] = ((m_length - cmdOffset) >> 8U) & 0xFFU;
+ length[1U] = (m_length - cmdOffset) & 0xFFU;
+ m_rxP25Queue.addData(length, 2U);
- uint8_t data = m_length - 2U;
+ uint8_t data = TAG_DATA;
m_rxP25Queue.addData(&data, 1U);
- data = TAG_DATA;
- m_rxP25Queue.addData(&data, 1U);
-
- m_rxP25Queue.addData(m_buffer + 3U, m_length - 3U);
+ m_rxP25Queue.addData(m_buffer + (cmdOffset + 1U), m_length - (cmdOffset + 1U));
}
}
break;
@@ -1036,10 +1038,14 @@ uint32_t Modem::readP25Frame(uint8_t* data)
if (m_rxP25Queue.isEmpty())
return 0U;
- uint8_t len = 0U;
- m_rxP25Queue.peek(&len, 1U);
+ uint8_t length[2U];
+ ::memset(length, 0x00U, 2U);
+ m_rxP25Queue.peek(length, 2U);
+
+ uint16_t len = 0U;
+ len = (length[0U] << 8) + length[1U];
if (m_rxP25Queue.dataSize() >= len) {
- m_rxP25Queue.get(&len, 1U); // ensure we pop the length off
+ m_rxP25Queue.get(length, 2U); // ensure we pop the length off
m_rxP25Queue.get(data, len);
return len;
@@ -1161,7 +1167,7 @@ void Modem::clearDMRFrame1()
{
uint8_t buffer[3U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_DMR_CLEAR1;
#if DEBUG_MODEM
@@ -1178,7 +1184,7 @@ void Modem::clearDMRFrame2()
{
uint8_t buffer[3U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_DMR_CLEAR2;
#if DEBUG_MODEM
@@ -1195,7 +1201,7 @@ void Modem::clearP25Frame()
{
uint8_t buffer[3U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_P25_CLEAR;
#if DEBUG_MODEM
@@ -1212,7 +1218,7 @@ void Modem::clearNXDNFrame()
{
uint8_t buffer[3U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_NXDN_CLEAR;
#if DEBUG_MODEM
@@ -1350,7 +1356,7 @@ bool Modem::writeDMRFrame1(const uint8_t* data, uint32_t length)
uint8_t buffer[MAX_LENGTH];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = length + 2U;
buffer[2U] = CMD_DMR_DATA1;
@@ -1408,7 +1414,7 @@ bool Modem::writeDMRFrame2(const uint8_t* data, uint32_t length)
uint8_t buffer[MAX_LENGTH];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = length + 2U;
buffer[2U] = CMD_DMR_DATA2;
@@ -1454,7 +1460,7 @@ bool Modem::writeP25Frame(const uint8_t* data, uint32_t length)
assert(length > 0U);
if (m_p25Enabled) {
- const uint8_t MAX_LENGTH = 250U;
+ const uint16_t MAX_LENGTH = 520U;
if (data[0U] != TAG_DATA && data[0U] != TAG_EOT)
return false;
@@ -1466,11 +1472,19 @@ bool Modem::writeP25Frame(const uint8_t* data, uint32_t length)
uint8_t buffer[MAX_LENGTH];
- buffer[0U] = DVM_FRAME_START;
- buffer[1U] = length + 2U;
- buffer[2U] = CMD_P25_DATA;
-
- ::memcpy(buffer + 3U, data + 1U, length - 1U);
+ if (length < 252U) {
+ buffer[0U] = DVM_SHORT_FRAME_START;
+ buffer[1U] = length + 2U;
+ buffer[2U] = CMD_P25_DATA;
+ ::memcpy(buffer + 3U, data + 1U, length - 1U);
+ } else {
+ length += 3U;
+ buffer[0U] = DVM_LONG_FRAME_START;
+ buffer[1U] = (length >> 8U) & 0xFFU;
+ buffer[2U] = (length & 0xFFU);
+ buffer[3U] = CMD_P25_DATA;
+ ::memcpy(buffer + 4U, data + 1U, length - 1U);
+ }
uint8_t len = length + 2U;
@@ -1524,7 +1538,7 @@ bool Modem::writeNXDNFrame(const uint8_t* data, uint32_t length)
uint8_t buffer[MAX_LENGTH];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = length + 2U;
buffer[2U] = CMD_NXDN_DATA;
@@ -1573,7 +1587,7 @@ bool Modem::writeDMRStart(bool tx)
uint8_t buffer[4U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 4U;
buffer[2U] = CMD_DMR_START;
buffer[3U] = tx ? 0x01U : 0x00U;
@@ -1599,7 +1613,7 @@ bool Modem::writeDMRShortLC(const uint8_t* lc)
if (m_dmrEnabled) {
uint8_t buffer[12U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 12U;
buffer[2U] = CMD_DMR_SHORTLC;
buffer[3U] = lc[0U];
@@ -1631,7 +1645,7 @@ bool Modem::writeDMRAbort(uint32_t slotNo)
if (m_dmrEnabled) {
uint8_t buffer[4U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 4U;
buffer[2U] = CMD_DMR_ABORT;
buffer[3U] = slotNo;
@@ -1655,7 +1669,7 @@ bool Modem::setDMRIgnoreCACH_AT(uint8_t slotNo)
if (m_dmrEnabled) {
uint8_t buffer[4U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 4U;
buffer[2U] = CMD_DMR_CACH_AT_CTRL;
buffer[3U] = slotNo;
@@ -1705,7 +1719,7 @@ bool Modem::setState(DVM_STATE state)
{
uint8_t buffer[4U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 4U;
buffer[2U] = CMD_SET_MODE;
buffer[3U] = state;
@@ -1730,7 +1744,7 @@ bool Modem::sendCWId(const std::string& callsign)
uint8_t buffer[205U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = length + 3U;
buffer[2U] = CMD_SEND_CWID;
@@ -1790,7 +1804,7 @@ bool Modem::getFirmwareVersion()
for (uint32_t i = 0U; i < 6U; i++) {
uint8_t buffer[3U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_GET_VERSION;
@@ -1800,7 +1814,7 @@ bool Modem::getFirmwareVersion()
for (uint32_t count = 0U; count < MAX_RESPONSES; count++) {
Thread::sleep(10U);
- RESP_TYPE_DVM resp = getResponse(true);
+ RESP_TYPE_DVM resp = getResponse();
if (resp == RTM_ERROR)
continue;
@@ -1858,7 +1872,7 @@ bool Modem::getStatus()
{
uint8_t buffer[3U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_GET_STATUS;
@@ -1877,7 +1891,7 @@ bool Modem::writeConfig()
::memset(buffer, 0x00U, 25U);
uint8_t lengthToWrite = 17U;
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[2U] = CMD_SET_CONFIG;
buffer[3U] = 0x00U;
@@ -1993,7 +2007,7 @@ bool Modem::writeSymbolAdjust()
::memset(buffer, 0x00U, 20U);
uint8_t lengthToWrite = 7U;
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[2U] = CMD_SET_SYMLVLADJ;
buffer[3U] = (uint8_t)(m_dmrSymLevel3Adj + 128);
@@ -2049,7 +2063,7 @@ bool Modem::writeRFParams()
::memset(buffer, 0x00U, 22U);
uint8_t lengthToWrite = 18U;
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[2U] = CMD_SET_RFPARAMS;
buffer[3U] = 0x00U;
@@ -2130,7 +2144,7 @@ bool Modem::readFlash()
for (uint32_t i = 0U; i < 6U; i++) {
uint8_t buffer[3U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_FLSH_READ;
@@ -2140,7 +2154,7 @@ bool Modem::readFlash()
for (uint32_t count = 0U; count < MAX_RESPONSES; count++) {
Thread::sleep(10U);
- RESP_TYPE_DVM resp = getResponse(true);
+ RESP_TYPE_DVM resp = getResponse();
if (resp == RTM_ERROR)
continue;
@@ -2368,9 +2382,8 @@ void Modem::printDebug(const uint8_t* buffer, uint16_t len)
///
/// Helper to get the raw response packet from modem.
///
-/// Ignores invalid frame start and does not report as error.
/// Response type from modem.
-RESP_TYPE_DVM Modem::getResponse(bool noReportInvalid)
+RESP_TYPE_DVM Modem::getResponse()
{
m_rspDoubleLength = false;
@@ -2390,22 +2403,23 @@ RESP_TYPE_DVM Modem::getResponse(bool noReportInvalid)
return RTM_TIMEOUT;
}
- if (m_buffer[0U] != DVM_FRAME_START) {
- if (!noReportInvalid) {
- LogError(LOG_MODEM, "Modem::getResponse(), illegal response, first byte not a frame start; byte = %02X", m_buffer[0U]);
- Utils::dump(1U, "Modem Invalid Frame", m_buffer, 250U);
- }
-
+ if (m_buffer[0U] != DVM_SHORT_FRAME_START &&
+ m_buffer[0U] != DVM_LONG_FRAME_START) {
+ //LogError(LOG_MODEM, "Modem::getResponse(), illegal response, first byte not a frame start; byte = %02X", m_buffer[0U]);
::memset(m_buffer, 0x00U, BUFFER_LENGTH);
return RTM_ERROR;
}
+ if (m_buffer[0U] == DVM_LONG_FRAME_START) {
+ m_rspDoubleLength = true;
+ }
+
//LogDebug(LOG_MODEM, "getResponse(), RESP_START");
m_rspState = RESP_LENGTH1;
}
- //LogDebug(LOG_MODEM, "getResponse(), getting frame length 1/2");
+ //LogDebug(LOG_MODEM, "getResponse(), getting frame length 1/2, rspDoubleLength = %u", m_rspDoubleLength);
// get the length of the frame, 1/2
if (m_rspState == RESP_LENGTH1) {
int ret = m_port->read(m_buffer + 1U, 1U);
@@ -2418,21 +2432,21 @@ RESP_TYPE_DVM Modem::getResponse(bool noReportInvalid)
if (ret == 0)
return RTM_TIMEOUT;
- if (m_buffer[1U] >= 250U) {
+ if (m_buffer[1U] >= 250U && !m_rspDoubleLength) {
LogError(LOG_MODEM, "Invalid length received from the modem, len = %u", m_buffer[1U]);
return RTM_ERROR;
}
- m_length = m_buffer[1U];
-
- if (m_length == 0U)
+ if (m_rspDoubleLength) {
m_rspState = RESP_LENGTH2;
- else
+ m_length = ((m_buffer[1U] & 0xFFU) << 8);
+ } else {
m_rspState = RESP_TYPE;
+ m_length = m_buffer[1U];
+ }
//LogDebug(LOG_MODEM, "getResponse(), RESP_LENGTH1, len = %u", m_length);
- m_rspDoubleLength = false;
m_rspOffset = 2U;
}
@@ -2449,7 +2463,7 @@ RESP_TYPE_DVM Modem::getResponse(bool noReportInvalid)
if (ret == 0)
return RTM_TIMEOUT;
- m_length = m_buffer[2U] + 255U;
+ m_length = (m_length + (m_buffer[2U] & 0xFFU));
m_rspState = RESP_TYPE;
//LogDebug(LOG_MODEM, "getResponse(), RESP_LENGTH2, len = %u", m_length);
diff --git a/src/host/modem/Modem.h b/src/host/modem/Modem.h
index 9680259a..8521d4e2 100644
--- a/src/host/modem/Modem.h
+++ b/src/host/modem/Modem.h
@@ -9,7 +9,7 @@
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2011-2021 Jonathan Naylor, G4KLX
-* Copyright (C) 2017-2022 Bryan Biedenkapp, N2PLL
+* Copyright (C) 2017-2024 Bryan Biedenkapp, N2PLL
* Copyright (C) 2021 Nat Moore
*
*/
@@ -35,8 +35,8 @@
// 505 = DMR_FRAME_LENGTH_BYTES * 15 + 10 (BUFFER_LEN = DMR_FRAME_LENGTH_BYTES * NO_OF_FRAMES + 10)
#define DMR_TX_BUFFER_LEN 505U // 15 frames + pad
-// 442 = P25_LDU_FRAME_LENGTH_BYTES * 2 + 10 (BUFFER_LEN = P25_LDU_FRAME_LENGTH_BYTES * NO_OF_FRAMES + 10)
-#define P25_TX_BUFFER_LEN 442U // 2 frames + pad
+// 522 = P25_PDU_FRAME_LENGTH_BYTES + 10 (BUFFER_LEN = P25_PDU_FRAME_LENGTH_BYTES + 10)
+#define P25_TX_BUFFER_LEN 522U // 1 PDU frame + pad
// 538 = NXDN_FRAME_LENGTH_BYTES * 11 + 10 (BUFFER_LEN = NXDN_FRAME_LENGTH_BYTES * NO_OF_FRAMES)
#define NXDN_TX_BUFFER_LEN 538U // 11 frames + pad
@@ -211,7 +211,8 @@ namespace modem
ADF_GAIN_HIGH = 3U
};
- const uint8_t DVM_FRAME_START = 0xFEU;
+ const uint8_t DVM_SHORT_FRAME_START = 0xFEU;
+ const uint8_t DVM_LONG_FRAME_START = 0xFDU;
const uint8_t DVM_CONF_AREA_VER = 0x02U;
const uint8_t DVM_CONF_AREA_LEN = 246U;
@@ -513,7 +514,7 @@ namespace modem
void printDebug(const uint8_t* buffer, uint16_t len);
/// Helper to get the raw response packet from modem.
- RESP_TYPE_DVM getResponse(bool noReportInvalid = false);
+ RESP_TYPE_DVM getResponse();
/// Helper to convert a serial opcode to a string.
std::string cmdToString(uint8_t opcode);
diff --git a/src/host/modem/port/ModemNullPort.cpp b/src/host/modem/port/ModemNullPort.cpp
index 9498dfc6..ed6ae145 100644
--- a/src/host/modem/port/ModemNullPort.cpp
+++ b/src/host/modem/port/ModemNullPort.cpp
@@ -9,7 +9,7 @@
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2021 Jonathan Naylor, G4KLX
-* Copyright (C) 2021 Bryan Biedenkapp, N2PLL
+* Copyright (C) 2021,2024 Bryan Biedenkapp, N2PLL
*
*/
#include "modem/port/ModemNullPort.h"
@@ -115,7 +115,7 @@ void ModemNullPort::getVersion()
{
unsigned char reply[200U];
- reply[0U] = DVM_FRAME_START;
+ reply[0U] = DVM_SHORT_FRAME_START;
reply[1U] = 0U;
reply[2U] = CMD_GET_VERSION;
@@ -142,7 +142,7 @@ void ModemNullPort::getStatus()
unsigned char reply[15U];
// Send all sorts of interesting internal values
- reply[0U] = DVM_FRAME_START;
+ reply[0U] = DVM_SHORT_FRAME_START;
reply[1U] = 11U;
reply[2U] = CMD_GET_STATUS;
@@ -172,7 +172,7 @@ void ModemNullPort::writeAck(uint8_t type)
{
unsigned char reply[4U];
- reply[0U] = DVM_FRAME_START;
+ reply[0U] = DVM_SHORT_FRAME_START;
reply[1U] = 4U;
reply[2U] = CMD_ACK;
reply[3U] = type;
@@ -189,7 +189,7 @@ void ModemNullPort::writeNAK(uint8_t opcode, uint8_t err)
{
uint8_t reply[5U];
- reply[0U] = DVM_FRAME_START;
+ reply[0U] = DVM_SHORT_FRAME_START;
reply[1U] = 5U;
reply[2U] = CMD_NAK;
reply[3U] = opcode;
diff --git a/src/host/p25/packet/ControlSignaling.cpp b/src/host/p25/packet/ControlSignaling.cpp
index 5b97340a..00b910f2 100644
--- a/src/host/p25/packet/ControlSignaling.cpp
+++ b/src/host/p25/packet/ControlSignaling.cpp
@@ -1260,8 +1260,8 @@ ControlSignaling::ControlSignaling(Control* p25, bool dumpTSBKData, bool debug,
m_verbose(verbose),
m_debug(debug)
{
- m_rfMBF = new uint8_t[P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U];
- ::memset(m_rfMBF, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
+ m_rfMBF = new uint8_t[P25_PDU_FRAME_LENGTH_BYTES + 2U];
+ ::memset(m_rfMBF, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
m_adjSiteTable.clear();
m_adjSiteUpdateCnt.clear();
@@ -1549,7 +1549,7 @@ void ControlSignaling::writeNet_TSDU(lc::TSBK* tsbk)
void ControlSignaling::writeRF_TSDU_MBF(lc::TSBK* tsbk)
{
if (!m_p25->m_enableControl) {
- ::memset(m_rfMBF, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
+ ::memset(m_rfMBF, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
m_mbfCnt = 0U;
return;
}
@@ -1563,7 +1563,7 @@ void ControlSignaling::writeRF_TSDU_MBF(lc::TSBK* tsbk)
// trunking data is unsupported in simplex operation
if (!m_p25->m_duplex) {
- ::memset(m_rfMBF, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
+ ::memset(m_rfMBF, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
m_mbfCnt = 0U;
return;
}
@@ -1636,7 +1636,7 @@ void ControlSignaling::writeRF_TSDU_MBF(lc::TSBK* tsbk)
m_p25->addFrame(data, P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES + 2U);
- ::memset(m_rfMBF, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
+ ::memset(m_rfMBF, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
m_mbfCnt = 0U;
return;
}
@@ -1669,8 +1669,8 @@ void ControlSignaling::writeRF_TSDU_AMBT(lc::AMBT* ambt)
assert(ambt != nullptr);
DataHeader header = DataHeader();
- uint8_t pduUserData[P25_PDU_UNCONFIRMED_LENGTH_BYTES * P25_MAX_PDU_COUNT];
- ::memset(pduUserData, 0x00U, P25_PDU_UNCONFIRMED_LENGTH_BYTES * P25_MAX_PDU_COUNT);
+ uint8_t pduUserData[P25_MAX_PDU_BLOCKS * P25_PDU_UNCONFIRMED_LENGTH_BYTES];
+ ::memset(pduUserData, 0x00U, P25_MAX_PDU_BLOCKS * P25_PDU_UNCONFIRMED_LENGTH_BYTES);
// Generate TSBK block
ambt->setLastBlock(true); // always set last block -- this a Single Block TSDU
diff --git a/src/host/p25/packet/Data.cpp b/src/host/p25/packet/Data.cpp
index 32e83bed..5925331e 100644
--- a/src/host/p25/packet/Data.cpp
+++ b/src/host/p25/packet/Data.cpp
@@ -87,26 +87,22 @@ bool Data::process(uint8_t* data, uint32_t len)
m_rfPDUCount = 0U;
m_rfPDUBits = 0U;
- ::memset(m_rfPDU, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
+ ::memset(m_rfPDU, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
m_p25->m_rfState = RS_RF_DATA;
- ::memset(m_pduUserData, 0x00U, P25_MAX_PDU_COUNT * P25_PDU_CONFIRMED_LENGTH_BYTES + 2U);
+ ::memset(m_pduUserData, 0x00U, P25_MAX_PDU_BLOCKS * P25_PDU_CONFIRMED_LENGTH_BYTES + 2U);
m_pduUserDataLength = 0U;
}
- uint32_t start = m_rfPDUCount * P25_LDU_FRAME_LENGTH_BITS;
+ uint32_t start = m_rfPDUCount * P25_PDU_FRAME_LENGTH_BITS;
- uint8_t buffer[P25_MAX_PDU_LENGTH];
- ::memset(buffer, 0x00U, P25_MAX_PDU_LENGTH);
+ uint8_t buffer[P25_PDU_FRAME_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, P25_PDU_FRAME_LENGTH_BYTES);
- // Utils::dump(2U, "* !!! P25_DUID_PDU - data", data + 2U, len - 2U);
-
- uint32_t bits = P25Utils::decode(data + 2U, buffer, start, start + P25_LDU_FRAME_LENGTH_BITS);
+ uint32_t bits = P25Utils::decode(data + 2U, buffer, start, start + P25_PDU_FRAME_LENGTH_BITS);
m_rfPDUBits = Utils::getBits(buffer, m_rfPDU, 0U, bits);
- // Utils::dump(2U, "* !!! P25_DUID_PDU - m_rfPDU", m_rfPDU, P25_LDU_FRAME_LENGTH_BYTES * 2U);
-
uint32_t offset = P25_PREAMBLE_LENGTH_BITS + P25_PDU_FEC_LENGTH_BITS;
if (m_rfPDUCount == 0U) {
::memset(buffer, 0x00U, P25_PDU_FEC_LENGTH_BYTES);
@@ -133,8 +129,8 @@ bool Data::process(uint8_t* data, uint32_t len)
}
// make sure we don't get a PDU with more blocks then we support
- if (m_rfDataHeader.getBlocksToFollow() >= P25_MAX_PDU_COUNT) {
- LogError(LOG_RF, P25_PDU_STR ", ISP, too many PDU blocks to process, %u > %u", m_rfDataHeader.getBlocksToFollow(), P25_MAX_PDU_COUNT);
+ if (m_rfDataHeader.getBlocksToFollow() >= P25_MAX_PDU_BLOCKS) {
+ LogError(LOG_RF, P25_PDU_STR ", ISP, too many PDU blocks to process, %u > %u", m_rfDataHeader.getBlocksToFollow(), P25_MAX_PDU_BLOCKS);
m_rfDataHeader.reset();
m_rfSecondHeader.reset();
@@ -254,10 +250,10 @@ bool Data::process(uint8_t* data, uint32_t len)
m_rfData[i].getSerialNo(), m_rfData[i].getFormat(), m_rfData[i].getLastBlock(), m_rfData[i].getSAP(), m_rfData[i].getLLId());
if (m_dumpPDUData) {
- uint8_t dataBlock[P25_PDU_CONFIRMED_LENGTH_BYTES];
- ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ uint8_t dataBlock[P25_PDU_CONFIRMED_DATA_LENGTH_BYTES];
+ ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
m_rfData[i].getData(dataBlock);
- Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
}
}
@@ -276,10 +272,10 @@ bool Data::process(uint8_t* data, uint32_t len)
m_rfData[i].getLastBlock());
if (m_dumpPDUData) {
- uint8_t dataBlock[P25_PDU_CONFIRMED_LENGTH_BYTES];
- ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ uint8_t dataBlock[P25_PDU_CONFIRMED_DATA_LENGTH_BYTES];
+ ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
m_rfData[i].getData(dataBlock);
- Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
}
}
}
@@ -460,6 +456,8 @@ bool Data::processNetwork(uint8_t* data, uint32_t len, uint32_t blockLength)
m_netDataBlockCnt = 0U;
m_netPDUCount = 0U;
+ ::memset(m_netPDU, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
+
m_p25->m_netState = RS_NET_DATA;
uint8_t buffer[P25_PDU_FEC_LENGTH_BYTES];
@@ -487,8 +485,8 @@ bool Data::processNetwork(uint8_t* data, uint32_t len, uint32_t blockLength)
}
// make sure we don't get a PDU with more blocks then we support
- if (m_netDataHeader.getBlocksToFollow() >= P25_MAX_PDU_COUNT) {
- LogError(LOG_NET, P25_PDU_STR ", too many PDU blocks to process, %u > %u", m_netDataHeader.getBlocksToFollow(), P25_MAX_PDU_COUNT);
+ if (m_netDataHeader.getBlocksToFollow() >= P25_MAX_PDU_BLOCKS) {
+ LogError(LOG_NET, P25_PDU_STR ", too many PDU blocks to process, %u > %u", m_netDataHeader.getBlocksToFollow(), P25_MAX_PDU_BLOCKS);
m_netDataHeader.reset();
m_netSecondHeader.reset();
@@ -820,18 +818,18 @@ Data::Data(Control* p25, bool dumpPDUData, bool repeatPDU, bool debug, bool verb
m_verbose(verbose),
m_debug(debug)
{
- m_rfData = new data::DataBlock[P25_MAX_PDU_COUNT];
+ m_rfData = new data::DataBlock[P25_MAX_PDU_BLOCKS];
- m_rfPDU = new uint8_t[P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U];
- ::memset(m_rfPDU, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
+ m_rfPDU = new uint8_t[P25_PDU_FRAME_LENGTH_BYTES + 2U];
+ ::memset(m_rfPDU, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
- m_netData = new data::DataBlock[P25_MAX_PDU_COUNT];
+ m_netData = new data::DataBlock[P25_MAX_PDU_BLOCKS];
- m_netPDU = new uint8_t[P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U];
- ::memset(m_netPDU, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
+ m_netPDU = new uint8_t[P25_PDU_FRAME_LENGTH_BYTES + 2U];
+ ::memset(m_netPDU, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
- m_pduUserData = new uint8_t[P25_MAX_PDU_COUNT * P25_PDU_CONFIRMED_LENGTH_BYTES + 2U];
- ::memset(m_pduUserData, 0x00U, P25_MAX_PDU_COUNT * P25_PDU_CONFIRMED_LENGTH_BYTES + 2U);
+ m_pduUserData = new uint8_t[P25_MAX_PDU_BLOCKS * P25_PDU_CONFIRMED_LENGTH_BYTES + 2U];
+ ::memset(m_pduUserData, 0x00U, P25_MAX_PDU_BLOCKS * P25_PDU_CONFIRMED_LENGTH_BYTES + 2U);
m_fneRegTable.clear();
m_connQueueTable.clear();
@@ -876,16 +874,13 @@ void Data::writeNetwork(const uint8_t currentBlock, const uint8_t *data, uint32_
///
///
///
-/// This simply takes data packed into m_rfPDU and transmits it.
void Data::writeRF_PDU(const uint8_t* pdu, uint32_t bitLength, bool noNulls)
{
assert(pdu != nullptr);
assert(bitLength > 0U);
- uint8_t data[P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U];
- ::memset(data, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
-
- // Utils::dump(2U, "!!! *Raw PDU Frame Data - pdu", pdu, bitLength / 8U);
+ uint8_t data[P25_PDU_FRAME_LENGTH_BYTES + 2U];
+ ::memset(data, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
// Add the data
uint32_t newBitLength = P25Utils::encode(pdu, data + 2U, bitLength);
@@ -905,8 +900,6 @@ void Data::writeRF_PDU(const uint8_t* pdu, uint32_t bitLength, bool noNulls)
// Add idle bits
P25Utils::addIdleBits(data + 2U, newBitLength, true, true);
- // Utils::dump(2U, "!!! *P25_DUID_PDU - data", data + 2U, newByteLength);
-
if (m_p25->m_duplex) {
data[0U] = modem::TAG_DATA;
data[1U] = 0x00U;
@@ -991,10 +984,10 @@ void Data::writeNet_PDU_Buffered()
m_netData[i].getSerialNo(), m_netData[i].getFormat(), m_netData[i].getLastBlock(), m_netData[i].getSAP(), m_netData[i].getLLId());
if (m_dumpPDUData) {
- uint8_t dataBlock[P25_PDU_CONFIRMED_LENGTH_BYTES];
- ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ uint8_t dataBlock[P25_PDU_CONFIRMED_DATA_LENGTH_BYTES];
+ ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
m_netData[i].getData(dataBlock);
- Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
}
}
}
@@ -1005,10 +998,10 @@ void Data::writeNet_PDU_Buffered()
m_netData[i].getLastBlock());
if (m_dumpPDUData) {
- uint8_t dataBlock[P25_PDU_CONFIRMED_LENGTH_BYTES];
- ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ uint8_t dataBlock[P25_PDU_CONFIRMED_DATA_LENGTH_BYTES];
+ ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
m_netData[i].getData(dataBlock);
- Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
}
}
}
@@ -1087,10 +1080,10 @@ void Data::writeRF_PDU_Buffered()
m_rfData[i].getSerialNo(), m_rfData[i].getFormat(), m_rfData[i].getLastBlock(), m_rfData[i].getSAP(), m_rfData[i].getLLId());
if (m_dumpPDUData) {
- uint8_t dataBlock[P25_PDU_CONFIRMED_LENGTH_BYTES];
- ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ uint8_t dataBlock[P25_PDU_CONFIRMED_DATA_LENGTH_BYTES];
+ ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
m_rfData[i].getData(dataBlock);
- Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
}
}
}
@@ -1101,10 +1094,10 @@ void Data::writeRF_PDU_Buffered()
m_rfData[i].getLastBlock());
if (m_dumpPDUData) {
- uint8_t dataBlock[P25_PDU_CONFIRMED_LENGTH_BYTES];
- ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ uint8_t dataBlock[P25_PDU_CONFIRMED_DATA_LENGTH_BYTES];
+ ::memset(dataBlock, 0xAAU, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
m_rfData[i].getData(dataBlock);
- Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_LENGTH_BYTES);
+ Utils::dump(2U, "Data Block", dataBlock, P25_PDU_CONFIRMED_DATA_LENGTH_BYTES);
}
}
}
@@ -1198,7 +1191,7 @@ void Data::writeRF_PDU_Ack_Response(uint8_t ackClass, uint8_t ackType, uint8_t a
if (ackClass == PDU_ACK_CLASS_ACK && ackType != PDU_ACK_TYPE_ACK)
return;
- uint32_t bitLength = (2U * P25_PDU_FEC_LENGTH_BITS) + P25_PREAMBLE_LENGTH_BITS;
+ uint32_t bitLength = (1U * P25_PDU_FEC_LENGTH_BITS) + P25_PREAMBLE_LENGTH_BITS;
uint32_t offset = P25_PREAMBLE_LENGTH_BITS;
uint8_t data[bitLength / 8U];
diff --git a/src/host/setup/HostSetup.cpp b/src/host/setup/HostSetup.cpp
index 475b7033..976f97cb 100644
--- a/src/host/setup/HostSetup.cpp
+++ b/src/host/setup/HostSetup.cpp
@@ -339,7 +339,7 @@ bool HostSetup::portModemHandler(Modem* modem, uint32_t ms, RESP_TYPE_DVM rspTyp
uint8_t buffer[250U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = dataLen + 2U;
buffer[2U] = CMD_P25_DATA;
@@ -362,9 +362,20 @@ bool HostSetup::portModemHandler(Modem* modem, uint32_t ms, RESP_TYPE_DVM rspTyp
}
if (rspType == RTM_OK && len > 0) {
- switch (buffer[2U]) {
+ uint8_t cmdOffset = 2U;
+ if (rspDblLen) {
+ cmdOffset = 3U;
+ }
+
+ switch (buffer[cmdOffset]) {
+ /** Calibration */
case CMD_CAL_DATA:
{
+ if (rspDblLen) {
+ LogError(LOG_MODEM, "CMD_CAL_DATA double length?; len = %u", len);
+ break;
+ }
+
bool inverted = (buffer[3U] == 0x80U);
short high = buffer[4U] << 8 | buffer[5U];
short low = buffer[6U] << 8 | buffer[7U];
@@ -375,6 +386,11 @@ bool HostSetup::portModemHandler(Modem* modem, uint32_t ms, RESP_TYPE_DVM rspTyp
break;
case CMD_RSSI_DATA:
{
+ if (rspDblLen) {
+ LogError(LOG_MODEM, "CMD_RSSI_DATA double length?; len = %u", len);
+ break;
+ }
+
uint16_t max = buffer[3U] << 8 | buffer[4U];
uint16_t min = buffer[5U] << 8 | buffer[6U];
uint16_t ave = buffer[7U] << 8 | buffer[8U];
@@ -382,14 +398,27 @@ bool HostSetup::portModemHandler(Modem* modem, uint32_t ms, RESP_TYPE_DVM rspTyp
}
break;
+ /** Digital Mobile Radio */
case CMD_DMR_DATA1:
case CMD_DMR_DATA2:
+ {
+ if (rspDblLen) {
+ LogError(LOG_MODEM, "CMD_DMR_DATA double length?; len = %u", len);
+ break;
+ }
+
processDMRBER(buffer + 4U, buffer[3]);
- break;
+ }
+ break;
case CMD_DMR_LOST1:
case CMD_DMR_LOST2:
{
+ if (rspDblLen) {
+ LogError(LOG_MODEM, "CMD_DMR_LOST double length?; len = %u", len);
+ break;
+ }
+
LogMessage(LOG_CAL, "DMR Transmission lost, total frames: %d, bits: %d, uncorrectable frames: %d, undecodable LC: %d, errors: %d, BER: %.4f%%", m_berFrames, m_berBits, m_berUncorrectable, m_berUndecodableLC, m_berErrs, float(m_berErrs * 100U) / float(m_berBits));
if (m_dmrEnabled) {
@@ -402,12 +431,18 @@ bool HostSetup::portModemHandler(Modem* modem, uint32_t ms, RESP_TYPE_DVM rspTyp
}
break;
+ /** Project 25 */
case CMD_P25_DATA:
processP25BER(buffer + 4U);
break;
case CMD_P25_LOST:
{
+ if (rspDblLen) {
+ LogError(LOG_MODEM, "CMD_P25_LOST double length?; len = %u", len);
+ break;
+ }
+
LogMessage(LOG_CAL, "P25 Transmission lost, total frames: %d, bits: %d, uncorrectable frames: %d, undecodable LC: %d, errors: %d, BER: %.4f%%", m_berFrames, m_berBits, m_berUncorrectable, m_berUndecodableLC, m_berErrs, float(m_berErrs * 100U) / float(m_berBits));
if (m_p25Enabled) {
@@ -420,12 +455,25 @@ bool HostSetup::portModemHandler(Modem* modem, uint32_t ms, RESP_TYPE_DVM rspTyp
}
break;
+ /** Next Generation Digital Narrowband */
case CMD_NXDN_DATA:
+ {
+ if (rspDblLen) {
+ LogError(LOG_MODEM, "CMD_NXDN_DATA double length?; len = %u", len);
+ break;
+ }
+
processNXDNBER(buffer + 4U);
- break;
+ }
+ break;
case CMD_NXDN_LOST:
{
+ if (rspDblLen) {
+ LogError(LOG_MODEM, "CMD_NXDN_DATA double length?; len = %u", len);
+ break;
+ }
+
LogMessage(LOG_CAL, "NXDN Transmission lost, total frames: %d, bits: %d, uncorrectable frames: %d, undecodable LC: %d, errors: %d, BER: %.4f%%", m_berFrames, m_berBits, m_berUncorrectable, m_berUndecodableLC, m_berErrs, float(m_berErrs * 100U) / float(m_berBits));
if (m_nxdnEnabled) {
@@ -438,6 +486,7 @@ bool HostSetup::portModemHandler(Modem* modem, uint32_t ms, RESP_TYPE_DVM rspTyp
}
break;
+ /** General */
case CMD_GET_STATUS:
{
m_isHotspot = (buffer[3U] & 0x01U) == 0x01U;
@@ -870,7 +919,7 @@ bool HostSetup::setTransmit()
uint8_t buffer[50U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 4U;
buffer[2U] = CMD_CAL_DATA;
buffer[3U] = m_transmit ? 0x01U : 0x00U;
@@ -1236,8 +1285,8 @@ void HostSetup::processP25BER(const uint8_t* buffer)
uint8_t pduBuffer[P25_LDU_FRAME_LENGTH_BYTES];
uint32_t bits = P25Utils::decode(buffer, pduBuffer, 0, P25_LDU_FRAME_LENGTH_BITS);
- uint8_t* rfPDU = new uint8_t[P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U];
- ::memset(rfPDU, 0x00U, P25_MAX_PDU_COUNT * P25_LDU_FRAME_LENGTH_BYTES + 2U);
+ uint8_t* rfPDU = new uint8_t[P25_MAX_PDU_BLOCKS * P25_PDU_CONFIRMED_LENGTH_BYTES + 2U];
+ ::memset(rfPDU, 0x00U, P25_MAX_PDU_BLOCKS * P25_PDU_CONFIRMED_LENGTH_BYTES + 2U);
uint32_t rfPDUBits = 0U;
for (uint32_t i = 0U; i < bits; i++, rfPDUBits++) {
@@ -1481,7 +1530,7 @@ bool HostSetup::writeConfig(uint8_t modeOverride)
::memset(buffer, 0x00U, 25U);
uint8_t lengthToWrite = 17U;
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[2U] = CMD_SET_CONFIG;
buffer[3U] = 0x00U;
@@ -1591,7 +1640,7 @@ bool HostSetup::writeRFParams()
::memset(buffer, 0x00U, 22U);
uint8_t lengthToWrite = 18U;
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[2U] = CMD_SET_RFPARAMS;
buffer[3U] = 0x00U;
@@ -1661,7 +1710,7 @@ bool HostSetup::writeSymbolAdjust()
::memset(buffer, 0x00U, 20U);
uint8_t lengthToWrite = 7U;
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[2U] = CMD_SET_SYMLVLADJ;
m_conf["system"]["modem"]["repeater"]["dmrSymLvl3Adj"] = __INT_STR(m_modem->m_dmrSymLevel3Adj);
@@ -1705,7 +1754,7 @@ bool HostSetup::writeFifoLength()
uint8_t buffer[9U];
::memset(buffer, 0x00U, 9U);
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 9U;
buffer[2U] = CMD_SET_BUFFERS;
@@ -1750,7 +1799,7 @@ bool HostSetup::readFlash()
uint8_t buffer[3U];
::memset(buffer, 0x00U, 3U);
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 3U;
buffer[2U] = CMD_FLSH_READ;
@@ -1892,7 +1941,7 @@ bool HostSetup::eraseFlash()
uint8_t buffer[249U];
::memset(buffer, 0x00U, 249U);
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 249U;
buffer[2U] = CMD_FLSH_WRITE;
@@ -1926,7 +1975,7 @@ bool HostSetup::writeFlash()
uint8_t buffer[249U];
::memset(buffer, 0x00U, 249U);
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 249U;
buffer[2U] = CMD_FLSH_WRITE;
@@ -2070,7 +2119,7 @@ void HostSetup::getStatus()
{
uint8_t buffer[50U];
- buffer[0U] = DVM_FRAME_START;
+ buffer[0U] = DVM_SHORT_FRAME_START;
buffer[1U] = 4U;
buffer[2U] = CMD_GET_STATUS;