From 718093aea3a5a6c80f7fceb1bbbc940168b8d98c Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Wed, 5 Mar 2025 21:39:46 -0500 Subject: [PATCH] handle serial buffer overflow condition (while the modem protocol *can* send frames >512 bytes the serial port handler can only handle frames up to 512 bytes); better handle transmitting double length (512 byte) P25 PDU frames; --- SerialPort.cpp | 13 +++++++++++-- SerialPort.h | 5 +++-- p25/P25TX.cpp | 30 ++++++++++++++++++++++++------ p25/P25TX.h | 2 +- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/SerialPort.cpp b/SerialPort.cpp index 3e3c0b5..2e5d296 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -78,8 +78,10 @@ void SerialPort::process() if (m_dblFrame) { m_buffer[m_ptr] = c; m_len = ((c & 0xFFU) << 8); + // DEBUG3("long frame, len msb", m_len, c); } else { m_len = m_buffer[m_ptr] = c; + // DEBUG2("short frame, len", m_len); } m_ptr = 2U; } @@ -87,6 +89,9 @@ void SerialPort::process() // Handle the frame length m_buffer[m_ptr] = c; m_len = (m_len + (c & 0xFFU)); + if (m_len > SERIAL_FB_LEN) + m_len = SERIAL_FB_LEN; // don't allow length to be longer then the buffer + // DEBUG3("long frame, len lsb", m_len, c); m_ptr = 3U; } else { @@ -350,8 +355,12 @@ void SerialPort::process() /** Project 25 */ case CMD_P25_DATA: if (m_p25Enable) { - if (m_modemState == STATE_IDLE || m_modemState == STATE_P25) - err = p25TX.writeData(m_buffer + 3U, m_len - 3U); + if (m_modemState == STATE_IDLE || m_modemState == STATE_P25) { + if (m_dblFrame) + err = p25TX.writeData(m_buffer + 4U, m_len - 4U); + else + err = p25TX.writeData(m_buffer + 3U, m_len - 3U); + } } if (err == RSN_OK) { if (m_modemState == STATE_IDLE) diff --git a/SerialPort.h b/SerialPort.h index f3a6d55..005160a 100644 --- a/SerialPort.h +++ b/SerialPort.h @@ -155,6 +155,7 @@ enum CMD_REASON_CODE { const uint8_t DVM_SHORT_FRAME_START = 0xFEU; const uint8_t DVM_LONG_FRAME_START = 0xFDU; +#define SERIAL_FB_LEN 518U #define SERIAL_SPEED 115200 /** @} */ @@ -287,8 +288,8 @@ public: void writeDump(const uint8_t* data, uint16_t length); private: - uint8_t m_buffer[518U]; - uint8_t m_ptr; + uint8_t m_buffer[SERIAL_FB_LEN]; + uint16_t m_ptr; uint16_t m_len; bool m_dblFrame; diff --git a/p25/P25TX.cpp b/p25/P25TX.cpp index ad39ded..2ed41ac 100644 --- a/p25/P25TX.cpp +++ b/p25/P25TX.cpp @@ -96,7 +96,7 @@ void P25TX::process() /* Write data to the local buffer. */ -uint8_t P25TX::writeData(const uint8_t* data, uint8_t length) +uint8_t P25TX::writeData(const uint8_t* data, uint16_t length) { if (length < (P25_TDU_FRAME_LENGTH_BYTES + 1U)) return RSN_ILLEGAL_LENGTH; @@ -108,8 +108,16 @@ uint8_t P25TX::writeData(const uint8_t* data, uint8_t length) return RSN_RINGBUFF_FULL; } - m_fifo.put(length - 1U); - for (uint8_t i = 0U; i < (length - 1U); i++) + if (length <= 255U) { + m_fifo.put(DVM_SHORT_FRAME_START); + m_fifo.put(length - 1U); + } else { + m_fifo.put(DVM_LONG_FRAME_START); + m_fifo.put(((length - 1U) >> 8U) & 0xFFU); + m_fifo.put((length - 1U) & 0xFFU); + } + + for (uint16_t i = 0U; i < (length - 1U); i++) m_fifo.put(data[i + 1U]); return RSN_OK; @@ -182,9 +190,19 @@ void P25TX::createData() m_poBuffer[m_poLen++] = P25_START_SYNC; } else { - uint8_t length = m_fifo.get(); + uint8_t frameType = m_fifo.get(); + uint16_t length = 0U; + switch (frameType) { + case DVM_SHORT_FRAME_START: + length = m_fifo.get(); + break; + case DVM_LONG_FRAME_START: + length = ((m_fifo.get() & 0xFFU) << 8) + (m_fifo.get()); + break; + } + DEBUG3("P25TX::createData() dataLength/fifoSpace", length, m_fifo.getSpace()); - for (uint8_t i = 0U; i < length; i++) { + for (uint16_t i = 0U; i < length; i++) { m_poBuffer[m_poLen++] = m_fifo.get(); } } @@ -198,7 +216,7 @@ void P25TX::createCal() { // 1.2 kHz sine wave generation if (m_modemState == STATE_P25_CAL) { - for (unsigned int i = 0U; i < P25_LDU_FRAME_LENGTH_BYTES; i++) { + for (uint8_t i = 0U; i < P25_LDU_FRAME_LENGTH_BYTES; i++) { m_poBuffer[i] = P25_START_SYNC; } diff --git a/p25/P25TX.h b/p25/P25TX.h index 162e54d..9121177 100644 --- a/p25/P25TX.h +++ b/p25/P25TX.h @@ -65,7 +65,7 @@ namespace p25 * @param length Length of buffer. * @returns uint8_t Reason code. */ - uint8_t writeData(const uint8_t* data, uint8_t length); + uint8_t writeData(const uint8_t* data, uint16_t length); /** * @brief Clears the local buffer.