diff --git a/Utils.cpp b/Utils.cpp
index 281209fa..249bd564 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -212,7 +212,7 @@ void Utils::symbols(const std::string& title, const uint8_t* data, uint32_t leng
}
for (unsigned i = 0U; i < 9U; i++) {
- if (symOffset + i > length) {
+ if (symOffset + i >= length) {
break;
}
diff --git a/edac/CRC.cpp b/edac/CRC.cpp
index f16c4084..9a9e22de 100644
--- a/edac/CRC.cpp
+++ b/edac/CRC.cpp
@@ -660,7 +660,7 @@ bool CRC::checkCRC16(const uint8_t* in, uint32_t bitLength)
{
assert(in != NULL);
- uint16_t crc = createCRC15(in, bitLength);
+ uint16_t crc = createCRC16(in, bitLength);
uint8_t temp1[2U];
temp1[0U] = (crc >> 8) & 0xFFU;
temp1[1U] = (crc >> 0) & 0xFFU;
@@ -669,7 +669,7 @@ bool CRC::checkCRC16(const uint8_t* in, uint32_t bitLength)
temp2[0U] = 0x00U;
temp2[1U] = 0x00U;
uint32_t j = bitLength;
- for (uint32_t i = 1U; i < 16U; i++, j++) {
+ for (uint32_t i = 0U; i < 16U; i++, j++) {
bool b = READ_BIT(in, j);
WRITE_BIT(temp2, i, b);
}
@@ -692,14 +692,14 @@ void CRC::addCRC16(uint8_t* in, uint32_t bitLength)
{
assert(in != NULL);
- uint16_t crc = createCRC15(in, bitLength);
+ uint16_t crc = createCRC16(in, bitLength);
uint8_t temp[2U];
temp[0U] = (crc >> 8) & 0xFFU;
temp[1U] = (crc >> 0) & 0xFFU;
uint32_t n = bitLength;
- for (uint32_t i = 1U; i < 16U; i++, n++) {
+ for (uint32_t i = 0U; i < 16U; i++, n++) {
bool b = READ_BIT(temp, i);
WRITE_BIT(in, n, b);
}
@@ -790,7 +790,7 @@ uint16_t CRC::createCRC15(const uint8_t* in, uint32_t bitLength)
///
uint16_t CRC::createCRC16(const uint8_t* in, uint32_t bitLength)
{
- uint16_t crc = 0xFFFFU;
+ uint16_t crc = 0x0000U;
for (uint32_t i = 0U; i < bitLength; i++) {
bool bit1 = READ_BIT(in, i) != 0x00U;
@@ -802,5 +802,6 @@ uint16_t CRC::createCRC16(const uint8_t* in, uint32_t bitLength)
crc ^= 0x1021U;
}
+ crc = ~crc;
return crc & 0xFFFFU;
}
diff --git a/host/Host.cpp b/host/Host.cpp
index 11f68488..ee087c52 100644
--- a/host/Host.cpp
+++ b/host/Host.cpp
@@ -2138,7 +2138,8 @@ bool Host::createModem()
LogInfo(" UDP Address: %s", g_remoteAddress.c_str());
LogInfo(" UDP Port: %u", g_remotePort);
}
- else {
+
+ if (!m_modemRemote) {
LogInfo(" RX Invert: %s", rxInvert ? "yes" : "no");
LogInfo(" TX Invert: %s", txInvert ? "yes" : "no");
LogInfo(" PTT Invert: %s", pttInvert ? "yes" : "no");
diff --git a/nxdn/Control.cpp b/nxdn/Control.cpp
index e8b1bae0..412e250f 100644
--- a/nxdn/Control.cpp
+++ b/nxdn/Control.cpp
@@ -117,7 +117,7 @@ Control::Control(uint32_t ran, uint32_t callHang, uint32_t queueSize, uint32_t t
m_rfTGHang(1000U, tgHang),
m_netTimeout(1000U, timeout),
m_networkWatchdog(1000U, 0U, 1500U),
- m_ccPacketInterval(1000U, 0U, 25U),
+ m_ccPacketInterval(1000U, 0U, 10U),
m_ccFrameCnt(0U),
m_ccSeq(0U),
m_siteData(),
@@ -709,14 +709,14 @@ void Control::writeRF_Message_Tx_Rel(bool noNetwork)
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_UDCH);
lich.setOption(NXDN_LICH_USC_UDCH);
- lich.setDirection(NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(true);
lich.encode(data + 2U);
- uint8_t buffer[NXDN_UDCH_LENGTH_BYTES];
- ::memset(buffer, 0x00U, NXDN_UDCH_LENGTH_BYTES);
+ uint8_t buffer[NXDN_RTCH_LC_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, NXDN_RTCH_LC_LENGTH_BYTES);
m_rfLC.setMessageType(RTCH_MESSAGE_TYPE_TX_REL);
- m_rfLC.encode(buffer, NXDH_UDCH_CRC_BITS);
+ m_rfLC.encode(buffer, NXDN_UDCH_LENGTH_BITS);
channel::UDCH udch;
udch.setRAN(m_ran);
@@ -778,6 +778,10 @@ void Control::scrambler(uint8_t* data) const
{
assert(data != NULL);
+ if (m_debug) {
+ Utils::symbols("!!! *Tx NXDN (Unscrambled)", data, NXDN_FRAME_LENGTH_BYTES);
+ }
+
for (uint32_t i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++)
data[i] ^= SCRAMBLER[i];
}
diff --git a/nxdn/NXDNDefines.h b/nxdn/NXDNDefines.h
index 487c9fd4..5eab24f1 100644
--- a/nxdn/NXDNDefines.h
+++ b/nxdn/NXDNDefines.h
@@ -84,59 +84,51 @@ namespace nxdn
const uint32_t NXDN_SACCH_FEC_LENGTH_BYTES = (NXDN_SACCH_FEC_LENGTH_BITS / 8U) + 1U;
const uint32_t NXDN_SACCH_FEC_CONV_LENGTH_BITS = 72U; // Convolution Length
const uint32_t NXDN_SACCH_FEC_CONV_LENGTH_BYTES = NXDN_SACCH_FEC_CONV_LENGTH_BITS / 8U;
- const uint32_t NXDN_SACCH_LENGTH_BITS = 36U; // Data + CRC-6 + 4-bit NULL
- const uint32_t NXDN_SACCH_LENGTH_BYTES = (NXDN_SACCH_LENGTH_BITS / 8U) + 1U;
- const uint32_t NXDN_SACCH_CRC_BITS = 26U; // Data
+ const uint32_t NXDN_SACCH_CRC_LENGTH_BITS = 36U; // Data + CRC-6 + 4-bit NULL
+ const uint32_t NXDN_SACCH_CRC_LENGTH_BYTES = (NXDN_SACCH_CRC_LENGTH_BITS / 8U) + 1U;
+ const uint32_t NXDN_SACCH_LENGTH_BITS = 26U;
const uint32_t NXDN_FACCH1_FEC_LENGTH_BITS = 144U; // Puncture and Interleave Length
const uint32_t NXDN_FACCH1_FEC_LENGTH_BYTES = NXDN_FACCH1_FEC_LENGTH_BITS / 8U;
const uint32_t NXDN_FACCH1_FEC_CONV_LENGTH_BITS = 192U; // Convolution Length
const uint32_t NXDN_FACCH1_FEC_CONV_LENGTH_BYTES = NXDN_FACCH1_FEC_CONV_LENGTH_BITS / 8U;
- const uint32_t NXDN_FACCH1_LENGTH_BITS = 96U; // Data + CRC-12 + 4-bit NULL
- const uint32_t NXDN_FACCH1_LENGTH_BYTES = NXDN_FACCH1_LENGTH_BITS / 8U;
- const uint32_t NXDN_FACCH1_CRC_BITS = 80U; // Data
+ const uint32_t NXDN_FACCH1_CRC_LENGTH_BITS = 96U; // Data + CRC-12 + 4-bit NULL
+ const uint32_t NXDN_FACCH1_CRC_LENGTH_BYTES = NXDN_FACCH1_CRC_LENGTH_BITS / 8U;
+ const uint32_t NXDN_FACCH1_LENGTH_BITS = 80U;
const uint32_t NXDN_UDCH_FEC_LENGTH_BITS = 348U; // Puncture and Interleave Length
const uint32_t NXDN_UDCH_FEC_LENGTH_BYTES = (NXDN_UDCH_FEC_LENGTH_BITS / 8U) + 1U;
const uint32_t NXDN_UDCH_FEC_CONV_LENGTH_BITS = 406U; // Convolution Length
const uint32_t NXDN_UDCH_FEC_CONV_LENGTH_BYTES = (NXDN_UDCH_FEC_CONV_LENGTH_BITS / 8U) + 1U;
- const uint32_t NXDN_UDCH_LENGTH_BITS = 203U; // Data + CRC-15 + 4-bit NULL
- const uint32_t NXDN_UDCH_LENGTH_BYTES = (NXDN_UDCH_LENGTH_BITS / 8U) + 1U;
- const uint32_t NXDH_UDCH_CRC_BITS = 184U; // Data
- const uint32_t NXDH_UDCH_CRC_BYTES = NXDH_UDCH_CRC_BITS / 8U;
-
- const uint32_t NXDN_CAC_LENGTH_BITS = 384U;
- const uint32_t NXDN_CAC_LENGTH_BYTES = (NXDN_CAC_LENGTH_BITS / 8U);
-
- const uint32_t NXDN_CAC_OUT_FEC_LENGTH_BITS = 300U; // Puncture and Interleave Length
- const uint32_t NXDN_CAC_OUT_FEC_LENGTH_BYTES = (NXDN_CAC_OUT_FEC_LENGTH_BITS / 8U) + 1U;
- const uint32_t NXDN_CAC_OUT_FEC_CONV_LENGTH_BITS = 350U; // Convolution Length
- const uint32_t NXDN_CAC_OUT_FEC_CONV_LENGTH_BYTES = (NXDN_CAC_OUT_FEC_CONV_LENGTH_BITS / 8U) + 1U;
- const uint32_t NXDN_CAC_OUT_LENGTH_BITS = 175U; // Data + CRC-16 + 4-bit NULL
- const uint32_t NXDN_CAC_OUT_LENGTH_BYTES = (NXDN_CAC_OUT_LENGTH_BITS / 8U) + 1U;
- const uint32_t NXDN_CAC_OUT_CRC_BITS = 155U; // Data
+ const uint32_t NXDN_UDCH_CRC_LENGTH_BITS = 203U; // Data + CRC-15 + 4-bit NULL
+ const uint32_t NXDN_UDCH_CRC_LENGTH_BYTES = (NXDN_UDCH_CRC_LENGTH_BITS / 8U) + 1U;
+ const uint32_t NXDN_UDCH_LENGTH_BITS = 184U;
+
+ const uint32_t NXDN_CAC_FRAME_LENGTH_BITS = 348U;
+ const uint32_t NXDN_CAC_FRAME_LENGTH_BYTES = (NXDN_CAC_FRAME_LENGTH_BITS / 8U) + 1U;
+ const uint32_t NXDN_CAC_FEC_LENGTH_BITS = 300U; // Puncture and Interleave Length
+ const uint32_t NXDN_CAC_FEC_LENGTH_BYTES = (NXDN_CAC_FEC_LENGTH_BITS / 8U) + 1U;
+ const uint32_t NXDN_CAC_FEC_CONV_LENGTH_BITS = 350U; // Convolution Length
+ const uint32_t NXDN_CAC_FEC_CONV_LENGTH_BYTES = (NXDN_CAC_FEC_CONV_LENGTH_BITS / 8U) + 1U;
+ const uint32_t NXDN_CAC_CRC_LENGTH_BITS = 175U; // Data + CRC-16 + 4-bit NULL
+ const uint32_t NXDN_CAC_LENGTH_BITS = 155U;
+ const uint32_t NXDN_CAC_E_POST_FIELD_BITS = 24U;
const uint32_t NXDN_CAC_IN_FEC_LENGTH_BITS = 252U; // Puncture and Interleave Length
const uint32_t NXDN_CAC_IN_FEC_LENGTH_BYTES = (NXDN_CAC_IN_FEC_LENGTH_BITS / 8U) + 1U;
+ const uint32_t NXDN_CAC_LONG_FEC_CONV_LENGTH_BITS = 312U; // Convolution Length
+ const uint32_t NXDN_CAC_LONG_FEC_CONV_LENGTH_BYTES = NXDN_CAC_LONG_FEC_CONV_LENGTH_BITS / 8U;
+ const uint32_t NXDN_CAC_LONG_CRC_LENGTH_BITS = 156U; // Data + CRC-16 + 4-bit NULL
+ const uint32_t NXDN_CAC_LONG_LENGTH_BITS = 136U;
+ const uint32_t NXDN_CAC_SHORT_CRC_LENGTH_BITS = 126U; // Data + CRC-16 + 4-bit NULL
+ const uint32_t NXDN_CAC_SHORT_LENGTH_BITS = 106U;
- const uint32_t NXDN_CAC_LONG_IN_FEC_CONV_LENGTH_BITS = 312U; // Convolution Length
- const uint32_t NXDN_CAC_LONG_IN_FEC_CONV_LENGTH_BYTES = NXDN_CAC_LONG_IN_FEC_CONV_LENGTH_BITS / 8U;
- const uint32_t NXDN_CAC_LONG_IN_LENGTH_BITS = 156U; // Data + CRC-16 + 4-bit NULL
- const uint32_t NXDN_CAC_LONG_IN_LENGTH_BYTES = (NXDN_CAC_LONG_IN_LENGTH_BITS / 8U) + 1U;
- const uint32_t NXDN_CAC_LONG_IN_CRC_BITS = 136U; // Data
- const uint32_t NXDN_CAC_LONG_IN_CRC_BYTES = NXDN_CAC_LONG_IN_CRC_BITS / 8U;
+ const uint32_t NXDN_RTCH_LC_LENGTH_BYTES = 22U; // this is really the UDCH size...
- const uint32_t NXDN_CAC_SHORT_IN_FEC_LENGTH_BITS = 252U; // Interleave Length
- const uint32_t NXDN_CAC_SHORT_IN_FEC_LENGTH_BYTES = (NXDN_CAC_SHORT_IN_FEC_LENGTH_BITS / 8U) + 1U;
- const uint32_t NXDN_CAC_SHORT_IN_LENGTH_BITS = 126U; // Data + CRC-16 + 4-bit NULL
- const uint32_t NXDN_CAC_SHORT_IN_LENGTH_BYTES = (NXDN_CAC_SHORT_IN_LENGTH_BITS / 8U) + 1U;
- const uint32_t NXDN_CAC_SHORT_IN_CRC_BITS = 106U; // Data
- const uint32_t NXDN_CAC_SHORT_IN_CRC_BYTES = (NXDN_CAC_SHORT_IN_CRC_BITS / 8U) + 1U;
-
- const uint32_t NXDN_RTCH_LC_LENGTH_BYTES = 22U;
- const uint32_t NXDN_RCCH_LC_LENGTH_BYTES = 22U;
-
- const uint32_t NXDN_E_POST_FIELD_BITS = 24U;
+ const uint32_t NXDN_RCCH_LC_LENGTH_BITS = 144U;
+ const uint32_t NXDN_RCCH_LC_LENGTH_BYTES = (NXDN_RCCH_LC_LENGTH_BITS / 8U);
+ const uint32_t NXDN_RCCH_CAC_LC_LONG_LENGTH_BITS = 128U;
+ const uint32_t NXDN_RCCH_CAC_LC_SHORT_LENGTH_BITS = 96U;
const uint8_t POST_FIELD[] = { 0x57U, 0x75U, 0xFDU };
@@ -166,8 +158,10 @@ namespace nxdn
const uint8_t NXDN_LICH_STEAL_FACCH1_1 = 1U;
const uint8_t NXDN_LICH_STEAL_FACCH = 0U;
- const uint8_t NXDN_LICH_DIRECTION_INBOUND = 0U;
- const uint8_t NXDN_LICH_DIRECTION_OUTBOUND = 1U;
+ const uint8_t NXDN_SR_RCCH_SINGLE = 0x00U;
+ const uint8_t NXDN_SR_RCCH_DUAL = 0x01U;
+ const uint8_t NXDN_SR_RCCH_HEAD_SINGLE = 0x02U;
+ const uint8_t NXDN_SR_RCCH_HEAD_DUAL = 0x03U;
const uint8_t NXDN_SR_SINGLE = 0U;
const uint8_t NXDN_SR_4_4 = 0U;
diff --git a/nxdn/channel/CAC.cpp b/nxdn/channel/CAC.cpp
index 2e32af77..3b1e1e2b 100644
--- a/nxdn/channel/CAC.cpp
+++ b/nxdn/channel/CAC.cpp
@@ -120,10 +120,16 @@ const uint32_t PUNCTURE_LIST_OUT[] = {
///
CAC::CAC() :
m_verbose(false),
- m_ran(0U),
- m_data(NULL)
+ m_ran(1U),
+ m_structure(NXDN_SR_RCCH_SINGLE),
+ m_idleBusy(true),
+ m_txContinuous(false),
+ m_receive(true),
+ m_data(NULL),
+ m_rxCRC(0U)
{
- m_data = new uint8_t[NXDN_CAC_OUT_LENGTH_BYTES];
+ m_data = new uint8_t[NXDN_CAC_FRAME_LENGTH_BYTES];
+ ::memset(m_data, 0x00U, NXDN_CAC_FRAME_LENGTH_BYTES);
}
///
@@ -132,8 +138,13 @@ CAC::CAC() :
///
CAC::CAC(const CAC& data) :
m_verbose(false),
- m_ran(0U),
- m_data(NULL)
+ m_ran(1U),
+ m_structure(NXDN_SR_RCCH_SINGLE),
+ m_idleBusy(true),
+ m_txContinuous(false),
+ m_receive(true),
+ m_data(NULL),
+ m_rxCRC(0U)
{
copy(data);
}
@@ -154,11 +165,18 @@ CAC::~CAC()
CAC& CAC::operator=(const CAC& data)
{
if (&data != this) {
- ::memcpy(m_data, data.m_data, NXDN_CAC_OUT_LENGTH_BYTES);
+ ::memcpy(m_data, data.m_data, NXDN_CAC_FRAME_LENGTH_BYTES);
m_verbose = data.m_verbose;
m_ran = m_data[0U] & 0x3FU;
+ m_structure = (m_data[0U] >> 6) & 0x03U;
+
+ m_idleBusy = data.m_idleBusy;
+ m_txContinuous = data.m_txContinuous;
+ m_receive = data.m_receive;
+
+ m_rxCRC = data.m_rxCRC;
}
return *this;
@@ -173,7 +191,8 @@ bool CAC::decode(const uint8_t* data)
{
assert(data != NULL);
- uint8_t buffer[NXDN_CAC_IN_FEC_LENGTH_BYTES + 1U];
+ uint8_t buffer[NXDN_CAC_IN_FEC_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, NXDN_CAC_IN_FEC_LENGTH_BYTES);
// deinterleave
for (uint32_t i = 0U; i < NXDN_CAC_IN_FEC_LENGTH_BITS; i++) {
@@ -193,21 +212,21 @@ bool CAC::decode(const uint8_t* data)
conv.start();
uint32_t n = 0U;
- for (uint32_t i = 0U; i < (NXDN_CAC_SHORT_IN_LENGTH_BITS + 4U); i++) {
+ for (uint32_t i = 0U; i < (NXDN_CAC_SHORT_CRC_LENGTH_BITS + 4U); i++) {
uint8_t s0 = buffer[n++];
uint8_t s1 = buffer[n++];
conv.decode(s0, s1);
}
- conv.chainback(m_data, NXDN_CAC_SHORT_IN_LENGTH_BITS);
+ conv.chainback(m_data, NXDN_CAC_SHORT_CRC_LENGTH_BITS);
if (m_verbose) {
- Utils::dump(2U, "Decoded CAC", m_data, NXDN_CAC_SHORT_IN_LENGTH_BYTES);
+ Utils::dump(2U, "Decoded CAC", m_data, (NXDN_CAC_SHORT_CRC_LENGTH_BITS / 8U) + 1U);
}
// check CRC-16
- bool ret = CRC::checkCRC16(m_data, NXDN_CAC_SHORT_IN_CRC_BITS);
+ bool ret = CRC::checkCRC16(m_data, NXDN_CAC_SHORT_LENGTH_BITS);
if (!ret) {
LogError(LOG_NXDN, "SACCH::decode(), failed CRC-6 check");
return false;
@@ -217,16 +236,22 @@ bool CAC::decode(const uint8_t* data)
uint8_t crc[2U];
::memset(crc, 0x00U, 2U);
- uint32_t j = NXDN_CAC_SHORT_IN_CRC_BITS;
- for (uint32_t i = 1U; i < 16U; i++, j++) {
- bool b = READ_BIT(m_data, j);
+ m_ran = m_data[0U] & 0x3FU;
+ m_structure = (m_data[0U] >> 6) & 0x03U;
+
+ uint32_t offset = NXDN_CAC_SHORT_CRC_LENGTH_BITS - 20U;
+ for (uint32_t i = 0U; i < 16U; i++, offset++) {
+ bool b = READ_BIT(m_data, offset);
WRITE_BIT(crc, i, b);
}
m_rxCRC = (crc[0U] << 8) | (crc[1U] << 0);
- m_ran = m_data[0U] & 0x3FU;
-
+#if DEBUG_NXDN_CAC
+ if (m_verbose) {
+ Utils::dump(2U, "Raw CAC Buffer", m_data, NXDN_CAC_FEC_LENGTH_BYTES);
+ }
+#endif
return true;
}
@@ -238,36 +263,43 @@ void CAC::encode(uint8_t* data) const
{
assert(data != NULL);
- m_data[0U] &= 0xC0U;
- m_data[0U] |= m_ran;
+ m_data[0U] &= 0xC0U;
+ m_data[0U] |= m_ran;
- uint8_t buffer[NXDN_CAC_OUT_LENGTH_BYTES];
- ::memset(buffer, 0x00U, NXDN_CAC_OUT_LENGTH_BYTES);
+ m_data[0U] &= 0x3FU;
+ m_data[0U] |= (m_structure << 6) & 0xC0U;
- for (uint32_t i = 0U; i < NXDN_CAC_OUT_CRC_BITS; i++) {
+ uint8_t buffer[NXDN_CAC_FEC_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, NXDN_CAC_FEC_LENGTH_BYTES);
+
+ for (uint32_t i = 0U; i < NXDN_CAC_LENGTH_BITS; i++) {
bool b = READ_BIT(m_data, i);
WRITE_BIT(buffer, i, b);
}
- CRC::addCRC16(buffer, NXDN_CAC_OUT_CRC_BITS);
+ CRC::addCRC16(buffer, NXDN_CAC_LENGTH_BITS);
if (m_verbose) {
- Utils::dump(2U, "Encoded CAC", buffer, NXDN_CAC_OUT_LENGTH_BYTES);
+ Utils::dump(2U, "Encoded CAC", buffer, NXDN_CAC_FEC_LENGTH_BYTES);
}
// encode convolution
- uint8_t convolution[NXDN_CAC_OUT_FEC_CONV_LENGTH_BYTES];
+ uint8_t convolution[NXDN_CAC_FEC_CONV_LENGTH_BYTES];
+ ::memset(convolution, 0x00U, NXDN_CAC_FEC_CONV_LENGTH_BYTES);
+
Convolution conv;
- conv.encode(buffer, convolution, NXDN_CAC_OUT_LENGTH_BITS);
+ conv.encode(buffer, convolution, NXDN_CAC_CRC_LENGTH_BITS);
#if DEBUG_NXDN_CAC
- Utils::dump(2U, "CAC::encode(), CAC Convolution", convolution, NXDN_CAC_OUT_FEC_CONV_LENGTH_BYTES);
+ Utils::dump(2U, "CAC::encode(), CAC Convolution", convolution, NXDN_CAC_FEC_CONV_LENGTH_BYTES);
#endif
// puncture
- uint8_t puncture[NXDN_CAC_OUT_FEC_LENGTH_BYTES];
+ uint8_t puncture[NXDN_CAC_FEC_LENGTH_BYTES];
+ ::memset(puncture, 0x00U, NXDN_CAC_FEC_LENGTH_BYTES);
+
uint32_t n = 0U, index = 0U;
- for (uint32_t i = 0U; i < NXDN_CAC_OUT_FEC_CONV_LENGTH_BITS; i++) {
+ for (uint32_t i = 0U; i < NXDN_CAC_FEC_CONV_LENGTH_BITS; i++) {
if (i != PUNCTURE_LIST_OUT[index]) {
bool b = READ_BIT(convolution, i);
WRITE_BIT(puncture, n, b);
@@ -278,41 +310,45 @@ void CAC::encode(uint8_t* data) const
}
// interleave
- for (uint32_t i = 0U; i < NXDN_CAC_OUT_FEC_LENGTH_BITS; i++) {
+ for (uint32_t i = 0U; i < NXDN_CAC_FEC_LENGTH_BITS; i++) {
uint32_t n = INTERLEAVE_TABLE_OUT[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
bool b = READ_BIT(puncture, i);
WRITE_BIT(data, n, b);
}
#if DEBUG_NXDN_CAC
- Utils::dump(2U, "CAC::encode(), CAC Puncture and Interleave", data, NXDN_CAC_OUT_FEC_LENGTH_BYTES);
+ Utils::dump(2U, "CAC::encode(), CAC Puncture and Interleave", data, NXDN_CAC_FRAME_LENGTH_BYTES);
#endif
// apply control field
uint8_t control[3U];
::memset(control, 0x00U, 3U);
- uint8_t parity = 0x01U;
+ uint8_t parity = 0x03U;
if (m_idleBusy && m_txContinuous)
- parity = 0x03U;
+ parity = 0x01U;
- control[0U] = ((m_idleBusy ? 0x03U : 0x01U) << 22) + ((m_txContinuous ? 0x03U : 0x01U) << 20) +
- (parity << 18) + ((m_receive ? 0x03U : 0x01U) << 16);
- control[1U] = (m_rxCRC >> 8U);
- control[2U] = (m_rxCRC >> 0U);
+ control[0U] = ((m_idleBusy ? 0x03U : 0x01U) << 6) + ((m_txContinuous ? 0x03U : 0x01U) << 4) +
+ (parity << 2) + ((m_receive ? 0x03U : 0x01U));
+ control[1U] = (m_rxCRC >> 8U) & 0xFFU;
+ control[2U] = (m_rxCRC >> 0U) & 0xFFU;
- uint32_t offset = NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_CAC_OUT_FEC_LENGTH_BITS;
- for (uint32_t i = 0U; i < NXDN_E_POST_FIELD_BITS; i++, offset++) {
+ for (uint32_t i = 0U; i < NXDN_CAC_E_POST_FIELD_BITS; i++) {
+ uint32_t n = i + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_CAC_FEC_LENGTH_BITS;
bool b = READ_BIT(control, i);
- WRITE_BIT(data, offset, b);
+ WRITE_BIT(data, n, b);
}
// post field
- offset = NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_CAC_OUT_FEC_LENGTH_BITS + NXDN_E_POST_FIELD_BITS;
- for (uint32_t i = 0U; i < NXDN_E_POST_FIELD_BITS; i++, offset++) {
+ for (uint32_t i = 0U; i < NXDN_CAC_E_POST_FIELD_BITS; i++) {
+ uint32_t n = i + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_CAC_FEC_LENGTH_BITS + NXDN_CAC_E_POST_FIELD_BITS;
bool b = READ_BIT(POST_FIELD, i);
- WRITE_BIT(data, offset, b);
+ WRITE_BIT(data, n, b);
}
+
+#if DEBUG_NXDN_CAC
+ Utils::dump(2U, "CAC::encode(), CAC + E + Post", data, NXDN_FRAME_LENGTH_BYTES);
+#endif
}
///
@@ -324,7 +360,7 @@ void CAC::getData(uint8_t* data) const
assert(data != NULL);
uint32_t offset = 8U;
- for (uint32_t i = 0U; i < (NXDN_CAC_SHORT_IN_CRC_BITS - 8); i++, offset++) {
+ for (uint32_t i = 0U; i < (NXDN_CAC_SHORT_LENGTH_BITS - 10); i++, offset++) {
bool b = READ_BIT(m_data, offset);
WRITE_BIT(data, i, b);
}
@@ -338,8 +374,10 @@ void CAC::setData(const uint8_t* data)
{
assert(data != NULL);
+ ::memset(m_data, 0x00U, NXDN_CAC_FRAME_LENGTH_BYTES);
+
uint32_t offset = 8U;
- for (uint32_t i = 0U; i < (NXDN_CAC_OUT_CRC_BITS - 8); i++, offset++) {
+ for (uint32_t i = 0U; i < (NXDN_CAC_CRC_LENGTH_BITS - 31); i++, offset++) {
bool b = READ_BIT(data, i);
WRITE_BIT(m_data, offset, b);
}
@@ -355,8 +393,15 @@ void CAC::setData(const uint8_t* data)
///
void CAC::copy(const CAC& data)
{
- m_data = new uint8_t[NXDN_CAC_OUT_LENGTH_BYTES];
- ::memcpy(m_data, data.m_data, NXDN_CAC_OUT_LENGTH_BYTES);
+ m_data = new uint8_t[NXDN_CAC_FRAME_LENGTH_BYTES];
+ ::memcpy(m_data, data.m_data, NXDN_CAC_FRAME_LENGTH_BYTES);
m_ran = m_data[0U] & 0x3FU;
+ m_structure = (m_data[0U] >> 6) & 0x03U;
+
+ m_idleBusy = data.m_idleBusy;
+ m_txContinuous = data.m_txContinuous;
+ m_receive = data.m_receive;
+
+ m_rxCRC = data.m_rxCRC;
}
diff --git a/nxdn/channel/CAC.h b/nxdn/channel/CAC.h
index 3b771052..1f9a1be1 100644
--- a/nxdn/channel/CAC.h
+++ b/nxdn/channel/CAC.h
@@ -70,6 +70,8 @@ namespace nxdn
/** Common Data */
/// Radio Access Number
__PROPERTY(uint8_t, ran, RAN);
+ ///
+ __PROPERTY(uint8_t, structure, Structure);
/** Collision Control Field */
/// Idle/Busy.
diff --git a/nxdn/channel/FACCH1.cpp b/nxdn/channel/FACCH1.cpp
index fae4d773..e40fa49a 100644
--- a/nxdn/channel/FACCH1.cpp
+++ b/nxdn/channel/FACCH1.cpp
@@ -75,7 +75,8 @@ FACCH1::FACCH1() :
m_verbose(false),
m_data(NULL)
{
- m_data = new uint8_t[NXDN_FACCH1_LENGTH_BYTES];
+ m_data = new uint8_t[NXDN_FACCH1_CRC_LENGTH_BYTES];
+ ::memset(m_data, 0x00U, NXDN_FACCH1_CRC_LENGTH_BYTES);
}
///
@@ -105,7 +106,7 @@ FACCH1::~FACCH1()
FACCH1& FACCH1::operator=(const FACCH1& data)
{
if (&data != this) {
- ::memcpy(m_data, data.m_data, NXDN_FACCH1_LENGTH_BYTES);
+ ::memcpy(m_data, data.m_data, NXDN_FACCH1_CRC_LENGTH_BYTES);
m_verbose = data.m_verbose;
}
@@ -123,6 +124,7 @@ bool FACCH1::decode(const uint8_t* data, uint32_t offset)
assert(data != NULL);
uint8_t buffer[NXDN_FACCH1_FEC_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, NXDN_FACCH1_FEC_LENGTH_BYTES);
// deinterleave
for (uint32_t i = 0U; i < NXDN_FACCH1_FEC_LENGTH_BITS; i++) {
@@ -157,21 +159,21 @@ bool FACCH1::decode(const uint8_t* data, uint32_t offset)
conv.start();
n = 0U;
- for (uint32_t i = 0U; i < (NXDN_FACCH1_LENGTH_BITS + 4U); i++) {
+ for (uint32_t i = 0U; i < (NXDN_FACCH1_CRC_LENGTH_BITS + 4U); i++) {
uint8_t s0 = puncture[n++];
uint8_t s1 = puncture[n++];
conv.decode(s0, s1);
}
- conv.chainback(m_data, NXDN_FACCH1_LENGTH_BITS);
+ conv.chainback(m_data, NXDN_FACCH1_CRC_LENGTH_BITS);
if (m_verbose) {
- Utils::dump(2U, "Decoded FACCH1", m_data, NXDN_FACCH1_LENGTH_BYTES);
+ Utils::dump(2U, "Decoded FACCH1", m_data, NXDN_FACCH1_CRC_LENGTH_BYTES);
}
// check CRC-12
- bool ret = CRC::checkCRC12(m_data, NXDN_FACCH1_CRC_BITS);
+ bool ret = CRC::checkCRC12(m_data, NXDN_FACCH1_LENGTH_BITS);
if (!ret) {
LogError(LOG_NXDN, "FACCH1::decode(), failed CRC-12 check");
return false;
@@ -189,32 +191,36 @@ void FACCH1::encode(uint8_t* data, uint32_t offset) const
{
assert(data != NULL);
- uint8_t buffer[NXDN_FACCH1_LENGTH_BYTES];
- ::memset(buffer, 0x00U, NXDN_FACCH1_LENGTH_BYTES);
- ::memcpy(buffer, m_data, NXDN_FACCH1_LENGTH_BYTES - 2U);
+ uint8_t buffer[NXDN_FACCH1_CRC_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, NXDN_FACCH1_CRC_LENGTH_BYTES);
+ ::memcpy(buffer, m_data, NXDN_FACCH1_CRC_LENGTH_BYTES - 2U);
- CRC::addCRC12(buffer, NXDN_FACCH1_CRC_BITS);
+ CRC::addCRC12(buffer, NXDN_FACCH1_LENGTH_BITS);
if (m_verbose) {
- Utils::dump(2U, "Encoded FACCH1", buffer, NXDN_FACCH1_LENGTH_BYTES);
+ Utils::dump(2U, "Encoded FACCH1", buffer, NXDN_FACCH1_CRC_LENGTH_BYTES);
}
// encode convolution
uint8_t convolution[NXDN_FACCH1_FEC_CONV_LENGTH_BYTES];
+ ::memset(convolution, 0x00U, NXDN_FACCH1_FEC_CONV_LENGTH_BYTES);
+
Convolution conv;
- conv.encode(buffer, convolution, NXDN_FACCH1_LENGTH_BITS);
+ conv.encode(buffer, convolution, NXDN_FACCH1_CRC_LENGTH_BITS);
#if DEBUG_NXDN_FACCH1
Utils::dump(2U, "FACCH1::encode(), FACCH1 Convolution", convolution, NXDN_FACCH1_FEC_CONV_LENGTH_BYTES);
#endif
// puncture
- uint8_t raw[NXDN_FACCH1_FEC_LENGTH_BYTES];
+ uint8_t puncture[NXDN_FACCH1_FEC_LENGTH_BYTES];
+ ::memset(puncture, 0x00U, NXDN_FACCH1_FEC_LENGTH_BYTES);
+
uint32_t n = 0U, index = 0U;
for (uint32_t i = 0U; i < NXDN_FACCH1_FEC_CONV_LENGTH_BITS; i++) {
if (i != PUNCTURE_LIST[index]) {
bool b = READ_BIT(convolution, i);
- WRITE_BIT(raw, n, b);
+ WRITE_BIT(puncture, n, b);
n++;
} else {
index++;
@@ -224,7 +230,7 @@ void FACCH1::encode(uint8_t* data, uint32_t offset) const
// interleave
for (uint32_t i = 0U; i < NXDN_FACCH1_FEC_LENGTH_BITS; i++) {
uint32_t n = INTERLEAVE_TABLE[i] + offset;
- bool b = READ_BIT(raw, i);
+ bool b = READ_BIT(puncture, i);
WRITE_BIT(data, n, b);
}
@@ -241,7 +247,7 @@ void FACCH1::getData(uint8_t* data) const
{
assert(data != NULL);
- ::memcpy(data, m_data, NXDN_FACCH1_LENGTH_BYTES - 2U);
+ ::memcpy(data, m_data, NXDN_FACCH1_CRC_LENGTH_BYTES - 2U);
}
///
@@ -252,7 +258,7 @@ void FACCH1::setData(const uint8_t* data)
{
assert(data != NULL);
- ::memcpy(m_data, data, NXDN_FACCH1_LENGTH_BYTES - 2U);
+ ::memcpy(m_data, data, NXDN_FACCH1_CRC_LENGTH_BYTES - 2U);
}
// ---------------------------------------------------------------------------
@@ -265,8 +271,8 @@ void FACCH1::setData(const uint8_t* data)
///
void FACCH1::copy(const FACCH1& data)
{
- m_data = new uint8_t[NXDN_FACCH1_LENGTH_BYTES];
- ::memcpy(m_data, data.m_data, NXDN_FACCH1_LENGTH_BYTES);
+ m_data = new uint8_t[NXDN_FACCH1_CRC_LENGTH_BYTES];
+ ::memcpy(m_data, data.m_data, NXDN_FACCH1_CRC_LENGTH_BYTES);
m_verbose = data.m_verbose;
}
diff --git a/nxdn/channel/LICH.cpp b/nxdn/channel/LICH.cpp
index 7be5b6e0..f59565b3 100644
--- a/nxdn/channel/LICH.cpp
+++ b/nxdn/channel/LICH.cpp
@@ -30,6 +30,7 @@
*/
#include "nxdn/NXDNDefines.h"
#include "nxdn/channel/LICH.h"
+#include "Log.h"
using namespace nxdn;
using namespace nxdn::channel;
@@ -49,10 +50,10 @@ LICH::LICH() :
m_rfct(NXDN_LICH_RFCT_RCCH),
m_fct(NXDN_LICH_USC_SACCH_NS),
m_option(0U),
- m_direction(NXDN_LICH_DIRECTION_OUTBOUND),
- m_data(NULL)
+ m_outbound(true),
+ m_lich(0U)
{
- m_data = new uint8_t[1U];
+ /* stub */
}
///
@@ -63,8 +64,8 @@ LICH::LICH(const LICH& data) :
m_rfct(NXDN_LICH_RFCT_RCCH),
m_fct(NXDN_LICH_USC_SACCH_NS),
m_option(0U),
- m_direction(NXDN_LICH_DIRECTION_OUTBOUND),
- m_data(NULL)
+ m_outbound(true),
+ m_lich(0U)
{
copy(data);
}
@@ -74,7 +75,7 @@ LICH::LICH(const LICH& data) :
///
LICH::~LICH()
{
- delete[] m_data;
+ /* stub */
}
///
@@ -85,12 +86,12 @@ LICH::~LICH()
LICH& LICH::operator=(const LICH& data)
{
if (&data != this) {
- m_data[0U] = data.m_data[0U];
+ m_lich = data.m_lich;
m_rfct = data.m_rfct;
m_fct = data.m_fct;
m_option = data.m_option;
- m_direction = data.m_direction;
+ m_outbound = data.m_outbound;
}
return *this;
@@ -108,16 +109,20 @@ bool LICH::decode(const uint8_t* data)
uint32_t offset = NXDN_FSW_LENGTH_BITS;
for (uint32_t i = 0U; i < (NXDN_LICH_LENGTH_BITS / 2U); i++, offset += 2U) {
bool b = READ_BIT(data, offset);
- WRITE_BIT(m_data, i, b);
+ m_lich = (b) ? (m_lich | BIT_MASK_TABLE[(i) & 7]) : (m_lich & ~BIT_MASK_TABLE[(i) & 7]);
}
+#if DEBUG_NXDN_LICH
+ LogDebug(LOG_NXDN, "LICH::decode(), m_lich = %02X", m_lich);
+#endif
+
bool newParity = getParity();
- bool origParity = (m_data[0U] & 0x01U) == 0x01U;
+ bool origParity = (m_lich & 0x01U) == 0x01U;
- m_rfct = (m_data[0U] >> 6) & 0x03U;
- m_fct = (m_data[0U] >> 4) & 0x03U;
- m_option = (m_data[0U] >> 2) & 0x03U;
- m_direction = (m_data[0U] >> 1) & 0x01U;
+ m_rfct = (m_lich >> 6) & 0x03U;
+ m_fct = (m_lich >> 4) & 0x03U;
+ m_option = (m_lich >> 2) & 0x03U;
+ m_outbound = ((m_lich >> 1) & 0x01U) == 0x01U;
return origParity == newParity;
}
@@ -130,27 +135,33 @@ void LICH::encode(uint8_t* data)
{
assert(data != NULL);
- m_data[0U] &= 0x3FU;
- m_data[0U] |= (m_rfct << 6) & 0xC0U;
+ m_lich = 0U;
+
+ m_lich &= 0x3FU;
+ m_lich |= (m_rfct & 0x03U) << 6;
+
+ m_lich &= 0xCFU;
+ m_lich |= (m_fct & 0x03U) << 4;
- m_data[0U] &= 0xCFU;
- m_data[0U] |= (m_fct << 4) & 0x30U;
+ m_lich &= 0xF3U;
+ m_lich |= (m_option & 0x03U) << 2;
- m_data[0U] &= 0xF3U;
- m_data[0U] |= (m_option << 2) & 0x0CU;
+ m_lich &= 0xFDU;
+ m_lich |= (m_outbound ? 0x01U : 0x00U) << 1;
- m_data[0U] &= 0xFDU;
- m_data[0U] |= (m_direction << 1) & 0x02U;
+#if DEBUG_NXDN_LICH
+ LogDebug(LOG_NXDN, "LICH::encode(), m_lich = %02X", m_lich);
+#endif
bool parity = getParity();
if (parity)
- m_data[0U] |= 0x01U;
+ m_lich |= 0x01U;
else
- m_data[0U] &= 0xFEU;
+ m_lich &= 0xFEU;
uint32_t offset = NXDN_FSW_LENGTH_BITS;
for (uint32_t i = 0U; i < (NXDN_LICH_LENGTH_BITS / 2U); i++) {
- bool b = READ_BIT(m_data, i);
+ bool b = (m_lich & BIT_MASK_TABLE[(i) & 7]);
WRITE_BIT(data, offset, b);
offset++;
WRITE_BIT(data, offset, true);
@@ -168,13 +179,12 @@ void LICH::encode(uint8_t* data)
///
void LICH::copy(const LICH& data)
{
- m_data = new uint8_t[1U];
- m_data[0U] = data.m_data[0U];
+ m_lich = data.m_lich;
- m_rfct = (m_data[0U] >> 6) & 0x03U;
- m_fct = (m_data[0U] >> 4) & 0x03U;
- m_option = (m_data[0U] >> 2) & 0x03U;
- m_direction = (m_data[0U] >> 1) & 0x01U;
+ m_rfct = (m_lich >> 6) & 0x03U;
+ m_fct = (m_lich >> 4) & 0x03U;
+ m_option = (m_lich >> 2) & 0x03U;
+ m_outbound = ((m_lich >> 1) & 0x01U) == 0x01U;
}
///
@@ -183,7 +193,7 @@ void LICH::copy(const LICH& data)
///
bool LICH::getParity() const
{
- switch (m_data[0U] & 0xF0U) {
+ switch (m_lich & 0xF0U) {
case 0x80U:
case 0xB0U:
return true;
diff --git a/nxdn/channel/LICH.h b/nxdn/channel/LICH.h
index 72b877c5..08a9d0db 100644
--- a/nxdn/channel/LICH.h
+++ b/nxdn/channel/LICH.h
@@ -67,11 +67,11 @@ namespace nxdn
__PROPERTY(uint8_t, fct, FCT);
/// Channel Options
__PROPERTY(uint8_t, option, Option);
- /// Channel Direction
- __PROPERTY(uint8_t, direction, Direction);
+ /// Flag indicating outbound traffic direction
+ __PROPERTY(bool, outbound, Outbound);
private:
- uint8_t* m_data;
+ uint8_t m_lich;
/// Internal helper to copy the class.
void copy(const LICH& data);
diff --git a/nxdn/channel/SACCH.cpp b/nxdn/channel/SACCH.cpp
index 5484417e..42e2427e 100644
--- a/nxdn/channel/SACCH.cpp
+++ b/nxdn/channel/SACCH.cpp
@@ -66,11 +66,12 @@ const uint32_t PUNCTURE_LIST[] = { 5U, 11U, 17U, 23U, 29U, 35U, 41U, 47U, 53U, 5
///
SACCH::SACCH() :
m_verbose(false),
- m_ran(0U),
- m_structure(0U),
+ m_ran(1U),
+ m_structure(NXDN_SR_SINGLE),
m_data(NULL)
{
- m_data = new uint8_t[NXDN_SACCH_LENGTH_BYTES];
+ m_data = new uint8_t[NXDN_SACCH_CRC_LENGTH_BYTES];
+ ::memset(m_data, 0x00U, NXDN_SACCH_CRC_LENGTH_BYTES);
}
///
@@ -79,8 +80,8 @@ SACCH::SACCH() :
///
SACCH::SACCH(const SACCH& data) :
m_verbose(false),
- m_ran(0U),
- m_structure(0U),
+ m_ran(1U),
+ m_structure(NXDN_SR_SINGLE),
m_data(NULL)
{
copy(data);
@@ -102,7 +103,7 @@ SACCH::~SACCH()
SACCH& SACCH::operator=(const SACCH& data)
{
if (&data != this) {
- ::memcpy(m_data, data.m_data, NXDN_SACCH_LENGTH_BYTES);
+ ::memcpy(m_data, data.m_data, NXDN_SACCH_CRC_LENGTH_BYTES);
m_verbose = data.m_verbose;
@@ -123,6 +124,7 @@ bool SACCH::decode(const uint8_t* data)
assert(data != NULL);
uint8_t buffer[NXDN_SACCH_FEC_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, NXDN_SACCH_FEC_LENGTH_BYTES);
// deinterleave
for (uint32_t i = 0U; i < NXDN_SACCH_FEC_LENGTH_BITS; i++) {
@@ -157,21 +159,21 @@ bool SACCH::decode(const uint8_t* data)
conv.start();
n = 0U;
- for (uint32_t i = 0U; i < (NXDN_SACCH_LENGTH_BITS + 4U); i++) {
+ for (uint32_t i = 0U; i < (NXDN_SACCH_CRC_LENGTH_BITS + 4U); i++) {
uint8_t s0 = puncture[n++];
uint8_t s1 = puncture[n++];
conv.decode(s0, s1);
}
- conv.chainback(m_data, NXDN_SACCH_LENGTH_BITS);
+ conv.chainback(m_data, NXDN_SACCH_CRC_LENGTH_BITS);
if (m_verbose) {
- Utils::dump(2U, "Decoded SACCH", m_data, NXDN_SACCH_LENGTH_BYTES);
+ Utils::dump(2U, "Decoded SACCH", m_data, NXDN_SACCH_CRC_LENGTH_BYTES);
}
// check CRC-6
- bool ret = CRC::checkCRC6(m_data, NXDN_SACCH_CRC_BITS);
+ bool ret = CRC::checkCRC6(m_data, NXDN_SACCH_LENGTH_BITS);
if (!ret) {
LogError(LOG_NXDN, "SACCH::decode(), failed CRC-6 check");
return false;
@@ -191,30 +193,32 @@ void SACCH::encode(uint8_t* data) const
{
assert(data != NULL);
- m_data[0U] &= 0xC0U;
- m_data[0U] |= m_ran;
+ m_data[0U] &= 0xC0U;
+ m_data[0U] |= m_ran;
- m_data[0U] &= 0x3FU;
- m_data[0U] |= (m_structure << 6) & 0xC0U;
+ m_data[0U] &= 0x3FU;
+ m_data[0U] |= (m_structure << 6) & 0xC0U;
- uint8_t buffer[NXDN_SACCH_LENGTH_BYTES];
- ::memset(buffer, 0x00U, NXDN_SACCH_LENGTH_BYTES);
+ uint8_t buffer[NXDN_SACCH_CRC_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, NXDN_SACCH_CRC_LENGTH_BYTES);
- for (uint32_t i = 0U; i < NXDN_SACCH_CRC_BITS; i++) {
+ for (uint32_t i = 0U; i < NXDN_SACCH_LENGTH_BITS; i++) {
bool b = READ_BIT(m_data, i);
WRITE_BIT(buffer, i, b);
}
- CRC::addCRC6(buffer, NXDN_SACCH_CRC_BITS);
+ CRC::addCRC6(buffer, NXDN_SACCH_LENGTH_BITS);
if (m_verbose) {
- Utils::dump(2U, "Encoded SACCH", buffer, NXDN_SACCH_LENGTH_BYTES);
+ Utils::dump(2U, "Encoded SACCH", buffer, NXDN_SACCH_CRC_LENGTH_BYTES);
}
// encode convolution
uint8_t convolution[NXDN_SACCH_FEC_CONV_LENGTH_BYTES];
+ ::memset(convolution, 0x00U, NXDN_SACCH_FEC_CONV_LENGTH_BYTES);
+
Convolution conv;
- conv.encode(buffer, convolution, NXDN_SACCH_LENGTH_BITS);
+ conv.encode(buffer, convolution, NXDN_SACCH_CRC_LENGTH_BITS);
#if DEBUG_NXDN_SACCH
Utils::dump(2U, "SACCH::encode(), SACCH Convolution", convolution, NXDN_SACCH_FEC_CONV_LENGTH_BYTES);
@@ -222,6 +226,8 @@ void SACCH::encode(uint8_t* data) const
// puncture
uint8_t puncture[NXDN_SACCH_FEC_LENGTH_BYTES];
+ ::memset(puncture, 0x00U, NXDN_SACCH_FEC_LENGTH_BYTES);
+
uint32_t n = 0U, index = 0U;
for (uint32_t i = 0U; i < NXDN_SACCH_FEC_CONV_LENGTH_BITS; i++) {
if (i != PUNCTURE_LIST[index]) {
@@ -254,7 +260,7 @@ void SACCH::getData(uint8_t* data) const
assert(data != NULL);
uint32_t offset = 8U;
- for (uint32_t i = 0U; i < (NXDN_SACCH_CRC_BITS - 8); i++, offset++) {
+ for (uint32_t i = 0U; i < (NXDN_SACCH_LENGTH_BITS - 8); i++, offset++) {
bool b = READ_BIT(m_data, offset);
WRITE_BIT(data, i, b);
}
@@ -269,7 +275,7 @@ void SACCH::setData(const uint8_t* data)
assert(data != NULL);
uint32_t offset = 8U;
- for (uint32_t i = 0U; i < (NXDN_SACCH_CRC_BITS - 8); i++, offset++) {
+ for (uint32_t i = 0U; i < (NXDN_SACCH_LENGTH_BITS - 8); i++, offset++) {
bool b = READ_BIT(data, i);
WRITE_BIT(m_data, offset, b);
}
@@ -285,8 +291,8 @@ void SACCH::setData(const uint8_t* data)
///
void SACCH::copy(const SACCH& data)
{
- m_data = new uint8_t[NXDN_SACCH_LENGTH_BYTES];
- ::memcpy(m_data, data.m_data, NXDN_SACCH_LENGTH_BYTES);
+ m_data = new uint8_t[NXDN_SACCH_CRC_LENGTH_BYTES];
+ ::memcpy(m_data, data.m_data, NXDN_SACCH_CRC_LENGTH_BYTES);
m_ran = m_data[0U] & 0x3FU;
m_structure = (m_data[0U] >> 6) & 0x03U;
diff --git a/nxdn/channel/UDCH.cpp b/nxdn/channel/UDCH.cpp
index 0f470a1f..61bd769e 100644
--- a/nxdn/channel/UDCH.cpp
+++ b/nxdn/channel/UDCH.cpp
@@ -98,7 +98,8 @@ UDCH::UDCH() :
m_ran(0U),
m_data(NULL)
{
- m_data = new uint8_t[NXDN_UDCH_LENGTH_BYTES];
+ m_data = new uint8_t[NXDN_UDCH_CRC_LENGTH_BYTES];
+ ::memset(m_data, 0x00U, NXDN_UDCH_CRC_LENGTH_BYTES);
}
///
@@ -129,7 +130,7 @@ UDCH::~UDCH()
UDCH& UDCH::operator=(const UDCH& data)
{
if (&data != this) {
- ::memcpy(m_data, data.m_data, NXDN_UDCH_LENGTH_BYTES);
+ ::memcpy(m_data, data.m_data, NXDN_UDCH_CRC_LENGTH_BYTES);
m_verbose = data.m_verbose;
@@ -149,6 +150,7 @@ bool UDCH::decode(const uint8_t* data)
assert(data != NULL);
uint8_t buffer[NXDN_UDCH_FEC_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, NXDN_UDCH_FEC_LENGTH_BYTES);
// deinterleave
for (uint32_t i = 0U; i < NXDN_UDCH_FEC_LENGTH_BITS; i++) {
@@ -183,21 +185,21 @@ bool UDCH::decode(const uint8_t* data)
conv.start();
n = 0U;
- for (uint32_t i = 0U; i < (NXDN_UDCH_LENGTH_BITS + 4U); i++) {
+ for (uint32_t i = 0U; i < (NXDN_UDCH_CRC_LENGTH_BITS + 4U); i++) {
uint8_t s0 = puncture[n++];
uint8_t s1 = puncture[n++];
conv.decode(s0, s1);
}
- conv.chainback(m_data, NXDN_UDCH_LENGTH_BITS);
+ conv.chainback(m_data, NXDN_UDCH_CRC_LENGTH_BITS);
if (m_verbose) {
- Utils::dump(2U, "Decoded UDCH", m_data, NXDN_UDCH_LENGTH_BYTES);
+ Utils::dump(2U, "Decoded UDCH", m_data, NXDN_UDCH_CRC_LENGTH_BYTES);
}
// check CRC-15
- bool ret = CRC::checkCRC15(m_data, NXDH_UDCH_CRC_BITS);
+ bool ret = CRC::checkCRC15(m_data, NXDN_UDCH_LENGTH_BITS);
if (!ret) {
LogError(LOG_NXDN, "UDCH::decode(), failed CRC-15 check");
return false;
@@ -218,20 +220,22 @@ void UDCH::encode(uint8_t* data) const
m_data[0U] = m_ran;
- uint8_t buffer[NXDN_UDCH_LENGTH_BYTES];
- ::memset(buffer, 0x00U, NXDN_UDCH_LENGTH_BYTES);
+ uint8_t buffer[NXDN_UDCH_CRC_LENGTH_BYTES];
+ ::memset(buffer, 0x00U, NXDN_UDCH_CRC_LENGTH_BYTES);
::memcpy(buffer, m_data, 23U);
- CRC::addCRC15(buffer, NXDH_UDCH_CRC_BITS);
+ CRC::addCRC15(buffer, NXDN_UDCH_LENGTH_BITS);
if (m_verbose) {
- Utils::dump(2U, "Encoded UDCH", m_data, NXDN_UDCH_LENGTH_BYTES);
+ Utils::dump(2U, "Encoded UDCH", m_data, NXDN_UDCH_CRC_LENGTH_BYTES);
}
// encode convolution
uint8_t convolution[NXDN_UDCH_FEC_CONV_LENGTH_BYTES];
+ ::memset(convolution, 0x00U, NXDN_UDCH_FEC_CONV_LENGTH_BYTES);
+
Convolution conv;
- conv.encode(buffer, convolution, NXDN_UDCH_LENGTH_BITS);
+ conv.encode(buffer, convolution, NXDN_UDCH_CRC_LENGTH_BITS);
#if DEBUG_NXDN_UDCH
Utils::dump(2U, "UDCH::encode(), UDCH Convolution", convolution, NXDN_UDCH_FEC_CONV_LENGTH_BYTES);
@@ -239,6 +243,8 @@ void UDCH::encode(uint8_t* data) const
// puncture
uint8_t puncture[NXDN_UDCH_FEC_LENGTH_BYTES];
+ ::memset(puncture, 0x00U, NXDN_UDCH_FEC_LENGTH_BYTES);
+
uint32_t n = 0U, index = 0U;
for (uint32_t i = 0U; i < NXDN_UDCH_FEC_CONV_LENGTH_BITS; i++) {
if (i != PUNCTURE_LIST[index]) {
@@ -270,7 +276,7 @@ void UDCH::getData(uint8_t* data) const
{
assert(data != NULL);
- ::memcpy(data, m_data + 1U, 22U);
+ ::memcpy(data, m_data + 1U, NXDN_RTCH_LC_LENGTH_BYTES);
}
///
@@ -281,7 +287,7 @@ void UDCH::setData(const uint8_t* data)
{
assert(data != NULL);
- ::memcpy(m_data + 1U, data, 22U);
+ ::memcpy(m_data + 1U, data, NXDN_RTCH_LC_LENGTH_BYTES);
}
// ---------------------------------------------------------------------------
@@ -294,8 +300,8 @@ void UDCH::setData(const uint8_t* data)
///
void UDCH::copy(const UDCH& data)
{
- m_data = new uint8_t[26U];
- ::memcpy(m_data, data.m_data, 26U);
+ m_data = new uint8_t[NXDN_UDCH_CRC_LENGTH_BYTES];
+ ::memcpy(m_data, data.m_data, NXDN_UDCH_CRC_LENGTH_BYTES);
m_ran = m_data[0U] & 0x3FU;
}
diff --git a/nxdn/lc/RCCH.cpp b/nxdn/lc/RCCH.cpp
index 399fb828..5ffd2e6a 100644
--- a/nxdn/lc/RCCH.cpp
+++ b/nxdn/lc/RCCH.cpp
@@ -91,7 +91,13 @@ RCCH& RCCH::operator=(const RCCH& data)
{
if (&data != this) {
::memcpy(m_data, data.m_data, NXDN_RCCH_LC_LENGTH_BYTES);
- decodeLC(m_data);
+
+ m_verbose = data.m_verbose;
+ if (m_data != NULL) {
+ if ((m_data[0] & 0x3FU) != 0U) {
+ decodeLC(m_data);
+ }
+ }
}
return *this;
@@ -101,6 +107,8 @@ RCCH& RCCH::operator=(const RCCH& data)
/// Decode call link control data.
///
///
+///
+///
/// True, if RCCH was decoded, otherwise false.
void RCCH::decode(const uint8_t* data, uint32_t length, uint32_t offset)
{
@@ -111,10 +119,6 @@ void RCCH::decode(const uint8_t* data, uint32_t length, uint32_t offset)
WRITE_BIT(m_data, offset, b);
}
- if (m_verbose) {
- Utils::dump(2U, "Decoded RCCH Data", m_data, NXDN_RCCH_LC_LENGTH_BYTES);
- }
-
decodeLC(m_data);
}
@@ -134,10 +138,6 @@ void RCCH::encode(uint8_t* data, uint32_t length, uint32_t offset)
bool b = READ_BIT(m_data, offset);
WRITE_BIT(data, i, b);
}
-
- if (m_verbose) {
- Utils::dump(2U, "Encoded RCCH Data", data, length);
- }
}
///
diff --git a/nxdn/lc/RTCH.cpp b/nxdn/lc/RTCH.cpp
index 248e58bf..62f7ad3e 100644
--- a/nxdn/lc/RTCH.cpp
+++ b/nxdn/lc/RTCH.cpp
@@ -123,7 +123,13 @@ RTCH& RTCH::operator=(const RTCH& data)
{
if (&data != this) {
::memcpy(m_data, data.m_data, NXDN_RTCH_LC_LENGTH_BYTES);
- decodeLC(m_data);
+
+ m_verbose = data.m_verbose;
+ if (m_data != NULL) {
+ if ((m_data[0] & 0x3FU) != 0U) {
+ decodeLC(m_data);
+ }
+ }
}
return *this;
diff --git a/nxdn/packet/Data.cpp b/nxdn/packet/Data.cpp
index a4ef32cb..d252400e 100644
--- a/nxdn/packet/Data.cpp
+++ b/nxdn/packet/Data.cpp
@@ -193,11 +193,11 @@ bool Data::process(uint8_t option, uint8_t* data, uint32_t len)
}
// the layer 3 LC data will only be correct if valid is true
- uint8_t buffer[NXDN_UDCH_LENGTH_BYTES];
+ uint8_t buffer[NXDN_RTCH_LC_LENGTH_BYTES];
udch.getData(buffer);
lc::RTCH lc;
- lc.decode(buffer, NXDH_UDCH_CRC_BITS);
+ lc.decode(buffer, NXDN_UDCH_LENGTH_BITS);
uint16_t dstId = lc.getDstId();
uint16_t srcId = lc.getSrcId();
bool group = lc.getGroup();
@@ -237,10 +237,10 @@ bool Data::process(uint8_t option, uint8_t* data, uint32_t len)
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_UDCH);
lich.setOption(option);
- lich.setDirection(!m_nxdn->m_duplex ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(!m_nxdn->m_duplex ? false : true);
lich.encode(data + 2U);
- lich.setDirection(NXDN_LICH_DIRECTION_INBOUND);
+ lich.setOutbound(false);
uint8_t type = RTCH_MESSAGE_TYPE_DCALL_DATA;
if (validUDCH) {
@@ -301,11 +301,11 @@ bool Data::processNetwork(uint8_t option, lc::RTCH& netLC, uint8_t* data, uint32
return false;
// The layer3 data will only be correct if valid is true
- uint8_t buffer[NXDN_UDCH_LENGTH_BYTES];
+ uint8_t buffer[NXDN_RTCH_LC_LENGTH_BYTES];
udch.getData(buffer);
lc::RTCH lc;
- lc.decode(buffer, NXDH_UDCH_CRC_BITS);
+ lc.decode(buffer, NXDN_UDCH_LENGTH_BITS);
uint16_t dstId = lc.getDstId();
uint16_t srcId = lc.getSrcId();
bool group = lc.getGroup();
@@ -345,7 +345,7 @@ bool Data::processNetwork(uint8_t option, lc::RTCH& netLC, uint8_t* data, uint32
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_UDCH);
lich.setOption(option);
- lich.setDirection(NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(true);
lich.encode(data + 2U);
uint8_t type = RTCH_MESSAGE_TYPE_DCALL_DATA;
diff --git a/nxdn/packet/Trunk.cpp b/nxdn/packet/Trunk.cpp
index 040ed55c..b9f0db0f 100644
--- a/nxdn/packet/Trunk.cpp
+++ b/nxdn/packet/Trunk.cpp
@@ -163,10 +163,10 @@ bool Trunk::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
m_nxdn->m_queue.clear();
// the layer3 data will only be correct if valid is true
- uint8_t buffer[NXDN_CAC_LENGTH_BYTES];
+ uint8_t buffer[NXDN_CAC_FRAME_LENGTH_BYTES];
cac.getData(buffer);
- m_rfLC.decode(buffer, NXDN_CAC_SHORT_IN_CRC_BITS);
+ m_rfLC.decode(buffer, NXDN_RCCH_CAC_LC_SHORT_LENGTH_BITS);
uint16_t srcId = m_rfLC.getSrcId();
uint16_t dstId = m_rfLC.getDstId();
@@ -388,15 +388,16 @@ void Trunk::writeRF_Message(bool noNetwork, bool clearBeforeWrite)
lich.setRFCT(NXDN_LICH_RFCT_RCCH);
lich.setFCT(NXDN_LICH_CAC_OUTBOUND);
lich.setOption(NXDN_LICH_DATA_NORMAL);
- lich.setDirection(NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(true);
lich.encode(data + 2U);
uint8_t buffer[NXDN_RCCH_LC_LENGTH_BYTES];
::memset(buffer, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES);
- m_rfLC.encode(buffer, NXDN_CAC_OUT_CRC_BITS);
+ m_rfLC.encode(buffer, NXDN_RCCH_LC_LENGTH_BITS);
channel::CAC cac;
+ cac.setVerbose(m_dumpRCCH);
cac.setRAN(m_nxdn->m_ran);
cac.setData(buffer);
cac.encode(data + 2U);
@@ -687,18 +688,20 @@ void Trunk::writeRF_CC_Message_Site_Info()
channel::LICH lich;
lich.setRFCT(NXDN_LICH_RFCT_RCCH);
lich.setFCT(NXDN_LICH_CAC_OUTBOUND);
- lich.setOption(NXDN_LICH_DATA_NORMAL);
- lich.setDirection(NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOption(NXDN_LICH_DATA_COMMON);
+ lich.setOutbound(true);
lich.encode(data + 2U);
uint8_t buffer[NXDN_RCCH_LC_LENGTH_BYTES];
::memset(buffer, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES);
m_rfLC.setMessageType(RCCH_MESSAGE_TYPE_SITE_INFO);
- m_rfLC.encode(buffer, NXDN_CAC_OUT_CRC_BITS);
+ m_rfLC.encode(buffer, NXDN_RCCH_LC_LENGTH_BITS);
channel::CAC cac;
+ cac.setVerbose(m_dumpRCCH);
cac.setRAN(m_nxdn->m_ran);
+ cac.setStructure(NXDN_SR_RCCH_HEAD_SINGLE);
cac.setData(buffer);
cac.encode(data + 2U);
@@ -730,17 +733,19 @@ void Trunk::writeRF_CC_Message_Service_Info()
lich.setRFCT(NXDN_LICH_RFCT_RCCH);
lich.setFCT(NXDN_LICH_CAC_OUTBOUND);
lich.setOption(NXDN_LICH_DATA_NORMAL);
- lich.setDirection(NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(true);
lich.encode(data + 2U);
uint8_t buffer[NXDN_RCCH_LC_LENGTH_BYTES];
::memset(buffer, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES);
m_rfLC.setMessageType(MESSAGE_TYPE_SRV_INFO);
- m_rfLC.encode(buffer, NXDN_CAC_OUT_CRC_BITS);
+ m_rfLC.encode(buffer, NXDN_RCCH_LC_LENGTH_BITS);
channel::CAC cac;
+ cac.setVerbose(m_dumpRCCH);
cac.setRAN(m_nxdn->m_ran);
+ cac.setStructure(NXDN_SR_RCCH_SINGLE);
cac.setData(buffer);
cac.encode(data + 2U);
diff --git a/nxdn/packet/Voice.cpp b/nxdn/packet/Voice.cpp
index 8565a66c..76e44a55 100644
--- a/nxdn/packet/Voice.cpp
+++ b/nxdn/packet/Voice.cpp
@@ -247,7 +247,7 @@ bool Voice::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_SACCH_NS);
lich.setOption(NXDN_LICH_STEAL_FACCH);
- lich.setDirection(!m_nxdn->m_duplex ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(!m_nxdn->m_duplex ? false : true);
lich.encode(data + 2U);
// generate the SACCH
@@ -424,10 +424,10 @@ bool Voice::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_SACCH_NS);
lich.setOption(NXDN_LICH_STEAL_FACCH);
- lich.setDirection(!m_nxdn->m_duplex ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(!m_nxdn->m_duplex ? false : true);
lich.encode(start + 2U);
- lich.setDirection(NXDN_LICH_DIRECTION_INBOUND);
+ lich.setOutbound(false);
// generate the SACCH
channel::SACCH sacch;
@@ -436,7 +436,7 @@ bool Voice::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
sacch.setStructure(NXDN_SR_SINGLE);
sacch.encode(start + 2U);
- uint8_t message[22U];
+ uint8_t message[NXDN_RTCH_LC_LENGTH_BYTES];
m_nxdn->m_rfLC.getData(message);
facch.setData(message);
@@ -465,10 +465,10 @@ bool Voice::process(uint8_t fct, uint8_t option, uint8_t* data, uint32_t len)
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_SACCH_SS);
lich.setOption(option);
- lich.setDirection(!m_nxdn->m_duplex ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(!m_nxdn->m_duplex ? false : true);
lich.encode(data + 2U);
- lich.setDirection(NXDN_LICH_DIRECTION_INBOUND);
+ lich.setOutbound(false);
// regenerate SACCH if it's valid
channel::SACCH sacch;
@@ -672,7 +672,7 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_SACCH_NS);
lich.setOption(NXDN_LICH_STEAL_FACCH);
- lich.setDirection(NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(true);
lich.encode(data + 2U);
// generate the SACCH
@@ -827,7 +827,7 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_SACCH_NS);
lich.setOption(NXDN_LICH_STEAL_FACCH);
- lich.setDirection(NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(true);
lich.encode(start + 2U);
// generate the SACCH
@@ -837,7 +837,7 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t
sacch.setStructure(NXDN_SR_SINGLE);
sacch.encode(start + 2U);
- uint8_t message[22U];
+ uint8_t message[NXDN_RTCH_LC_LENGTH_BYTES];
m_nxdn->m_rfLC.getData(message);
facch.setData(message);
@@ -864,7 +864,7 @@ bool Voice::processNetwork(uint8_t fct, uint8_t option, lc::RTCH& netLC, uint8_t
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_SACCH_SS);
lich.setOption(option);
- lich.setDirection(NXDN_LICH_DIRECTION_OUTBOUND);
+ lich.setOutbound(true);
lich.encode(data + 2U);
// regenerate SACCH if it's valid