Fix crash in the SACCH and FACCH1 encoders.
This commit is contained in:
parent
3858cf4aec
commit
8e2c6f6583
6 changed files with 162 additions and 158 deletions
286
NXDNControl.cpp
286
NXDNControl.cpp
|
@ -93,7 +93,7 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
|
|||
if (m_rssi != 0U)
|
||||
LogMessage("NXDN, transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||
else
|
||||
LogMessage("NXDN, transmission lost, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
LogMessage("NXDN, transmission lost, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
writeEndRF();
|
||||
return false;
|
||||
}
|
||||
|
@ -174,6 +174,8 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
|||
unsigned char ran = sacch.getRAN();
|
||||
if (ran != m_ran && ran != 0U)
|
||||
return false;
|
||||
} else if (m_rfState == RS_RF_LISTENING) {
|
||||
// return false;
|
||||
}
|
||||
|
||||
// XXX Reconstruct invalid LICH
|
||||
|
@ -184,161 +186,159 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
|
|||
bool valid = facch.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS);
|
||||
if (!valid)
|
||||
valid = facch.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS);
|
||||
|
||||
if (valid) {
|
||||
unsigned char buffer[10U];
|
||||
facch.getData(buffer);
|
||||
|
||||
CNXDNLayer3 layer3;
|
||||
layer3.decode(buffer, NXDN_FACCH1_LENGTH_BITS);
|
||||
|
||||
unsigned char type = layer3.getMessageType();
|
||||
if (type == NXDN_MESSAGE_TYPE_TX_REL) {
|
||||
if (m_rfState != RS_RF_AUDIO) {
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
m_rfMask = 0x00U;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (m_selfOnly) {
|
||||
unsigned short srcId = layer3.getSourceUnitId();
|
||||
if (srcId != m_id) {
|
||||
m_rfState = RS_RF_REJECTED;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data[0U] = type == NXDN_MESSAGE_TYPE_TX_REL ? TAG_EOT : TAG_DATA;
|
||||
data[1U] = 0x00U;
|
||||
|
||||
CSync::addNXDNSync(data + 2U);
|
||||
|
||||
CNXDNLICH lich = m_rfLastLICH;
|
||||
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
|
||||
lich.encode(data + 2U);
|
||||
|
||||
CNXDNSACCH sacch;
|
||||
sacch.setRAN(m_ran);
|
||||
sacch.setStructure(NXDN_SR_SINGLE);
|
||||
sacch.setData(SACCH_IDLE);
|
||||
sacch.encode(data + 2U);
|
||||
|
||||
facch.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS);
|
||||
facch.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS);
|
||||
|
||||
scrambler(data + 2U);
|
||||
|
||||
// writeNetwork(data, m_rfFrames, );
|
||||
|
||||
#if defined(DUMP_NXDN)
|
||||
writeFile(data + 2U);
|
||||
#endif
|
||||
if (m_duplex)
|
||||
writeQueueRF(data);
|
||||
|
||||
if (type == NXDN_MESSAGE_TYPE_TX_REL) {
|
||||
m_rfFrames++;
|
||||
if (m_rssi != 0U)
|
||||
LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||
else
|
||||
LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
writeEndRF();
|
||||
return true;
|
||||
} else {
|
||||
m_rfFrames = 0U;
|
||||
m_rfErrs = 0U;
|
||||
m_rfBits = 1U;
|
||||
m_rfTimeoutTimer.start();
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
|
||||
m_minRSSI = m_rssi;
|
||||
m_maxRSSI = m_rssi;
|
||||
m_aveRSSI = m_rssi;
|
||||
m_rssiCount = 1U;
|
||||
#if defined(DUMP_NXDN)
|
||||
openFile();
|
||||
#endif
|
||||
m_rfLayer3 = layer3;
|
||||
|
||||
unsigned short srcId = m_rfLayer3.getSourceUnitId();
|
||||
unsigned short dstId = m_rfLayer3.getDestinationGroupId();
|
||||
bool grp = m_rfLayer3.getIsGroup();
|
||||
|
||||
std::string source = m_lookup->find(srcId);
|
||||
LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
|
||||
m_display->writeNXDN(source.c_str(), grp, dstId, "R");
|
||||
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
unsigned char message[3U];
|
||||
sacch.getData(message);
|
||||
|
||||
unsigned char structure = sacch.getStructure();
|
||||
switch (structure) {
|
||||
case NXDN_SR_1_4:
|
||||
m_rfMask |= 0x01U;
|
||||
m_rfLayer3.decode(message, 18U, 0U);
|
||||
break;
|
||||
case NXDN_SR_2_4:
|
||||
m_rfMask |= 0x02U;
|
||||
m_rfLayer3.decode(message, 18U, 18U);
|
||||
break;
|
||||
case NXDN_SR_3_4:
|
||||
m_rfMask |= 0x04U;
|
||||
m_rfLayer3.decode(message, 18U, 36U);
|
||||
break;
|
||||
case NXDN_SR_4_4:
|
||||
m_rfMask |= 0x08U;
|
||||
m_rfLayer3.decode(message, 18U, 54U);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// if (m_rfMask != 0x0FU)
|
||||
// if (!valid)
|
||||
// return false;
|
||||
|
||||
unsigned char messageType = m_rfLayer3.getMessageType();
|
||||
if (messageType != NXDN_MESSAGE_TYPE_VCALL)
|
||||
return false;
|
||||
unsigned char buffer[10U];
|
||||
facch.getData(buffer);
|
||||
|
||||
unsigned short srcId = m_rfLayer3.getSourceUnitId();
|
||||
unsigned short dstId = m_rfLayer3.getDestinationGroupId();
|
||||
bool grp = m_rfLayer3.getIsGroup();
|
||||
CNXDNLayer3 layer3;
|
||||
layer3.decode(buffer, NXDN_FACCH1_LENGTH_BITS);
|
||||
|
||||
if (m_selfOnly) {
|
||||
if (srcId != m_id) {
|
||||
m_rfState = RS_RF_REJECTED;
|
||||
unsigned char type = layer3.getMessageType();
|
||||
if (type == NXDN_MESSAGE_TYPE_TX_REL) {
|
||||
if (m_rfState != RS_RF_AUDIO) {
|
||||
m_rfState = RS_RF_LISTENING;
|
||||
m_rfMask = 0x00U;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
bool hasInfo = layer3.getHasInfo();
|
||||
if (m_rfState == RS_RF_LISTENING && m_selfOnly && hasInfo) {
|
||||
unsigned short srcId = layer3.getSourceUnitId();
|
||||
if (srcId != m_id) {
|
||||
m_rfState = RS_RF_REJECTED;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_rfFrames = 0U;
|
||||
m_rfErrs = 0U;
|
||||
m_rfBits = 1U;
|
||||
m_rfTimeoutTimer.start();
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
data[0U] = type == NXDN_MESSAGE_TYPE_TX_REL ? TAG_EOT : TAG_DATA;
|
||||
data[1U] = 0x00U;
|
||||
|
||||
CSync::addNXDNSync(data + 2U);
|
||||
|
||||
CNXDNLICH lich = m_rfLastLICH;
|
||||
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
|
||||
lich.encode(data + 2U);
|
||||
|
||||
CNXDNSACCH sacch;
|
||||
sacch.setRAN(m_ran);
|
||||
sacch.setStructure(NXDN_SR_SINGLE);
|
||||
sacch.setData(SACCH_IDLE);
|
||||
sacch.encode(data + 2U);
|
||||
|
||||
facch.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS);
|
||||
facch.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS);
|
||||
|
||||
scrambler(data + 2U);
|
||||
|
||||
// writeNetwork(data, m_rfFrames, );
|
||||
|
||||
m_minRSSI = m_rssi;
|
||||
m_maxRSSI = m_rssi;
|
||||
m_aveRSSI = m_rssi;
|
||||
m_rssiCount = 1U;
|
||||
#if defined(DUMP_NXDN)
|
||||
openFile();
|
||||
writeFile(data + 2U);
|
||||
#endif
|
||||
std::string source = m_lookup->find(srcId);
|
||||
LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
|
||||
m_display->writeNXDN(source.c_str(), grp, dstId, "R");
|
||||
if (m_duplex)
|
||||
writeQueueRF(data);
|
||||
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
if (type == NXDN_MESSAGE_TYPE_TX_REL) {
|
||||
m_rfFrames++;
|
||||
if (m_rssi != 0U)
|
||||
LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||
else
|
||||
LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
writeEndRF();
|
||||
} else {
|
||||
m_rfFrames = 0U;
|
||||
m_rfErrs = 0U;
|
||||
m_rfBits = 1U;
|
||||
m_rfTimeoutTimer.start();
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
m_minRSSI = m_rssi;
|
||||
m_maxRSSI = m_rssi;
|
||||
m_aveRSSI = m_rssi;
|
||||
m_rssiCount = 1U;
|
||||
#if defined(DUMP_NXDN)
|
||||
openFile();
|
||||
#endif
|
||||
m_rfLayer3 = layer3;
|
||||
|
||||
unsigned short srcId = m_rfLayer3.getSourceUnitId();
|
||||
unsigned short dstId = m_rfLayer3.getDestinationGroupId();
|
||||
bool grp = m_rfLayer3.getIsGroup();
|
||||
|
||||
std::string source = m_lookup->find(srcId);
|
||||
LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
|
||||
m_display->writeNXDN(source.c_str(), grp, dstId, "R");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// if (valid) {
|
||||
unsigned char message[3U];
|
||||
sacch.getData(message);
|
||||
|
||||
unsigned char structure = sacch.getStructure();
|
||||
switch (structure) {
|
||||
case NXDN_SR_1_4:
|
||||
m_rfMask |= 0x01U;
|
||||
m_rfLayer3.decode(message, 18U, 0U);
|
||||
break;
|
||||
case NXDN_SR_2_4:
|
||||
m_rfMask |= 0x02U;
|
||||
m_rfLayer3.decode(message, 18U, 18U);
|
||||
break;
|
||||
case NXDN_SR_3_4:
|
||||
m_rfMask |= 0x04U;
|
||||
m_rfLayer3.decode(message, 18U, 36U);
|
||||
break;
|
||||
case NXDN_SR_4_4:
|
||||
m_rfMask |= 0x08U;
|
||||
m_rfLayer3.decode(message, 18U, 54U);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// if (m_rfMask != 0x0FU)
|
||||
// return false;
|
||||
|
||||
unsigned char messageType = m_rfLayer3.getMessageType();
|
||||
if (messageType != NXDN_MESSAGE_TYPE_VCALL)
|
||||
return false;
|
||||
|
||||
unsigned short srcId = m_rfLayer3.getSourceUnitId();
|
||||
unsigned short dstId = m_rfLayer3.getDestinationGroupId();
|
||||
bool grp = m_rfLayer3.getIsGroup();
|
||||
|
||||
if (m_selfOnly) {
|
||||
if (srcId != m_id) {
|
||||
m_rfState = RS_RF_REJECTED;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_rfFrames = 0U;
|
||||
m_rfErrs = 0U;
|
||||
m_rfBits = 1U;
|
||||
m_rfTimeoutTimer.start();
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
|
||||
m_minRSSI = m_rssi;
|
||||
m_maxRSSI = m_rssi;
|
||||
m_aveRSSI = m_rssi;
|
||||
m_rssiCount = 1U;
|
||||
#if defined(DUMP_NXDN)
|
||||
openFile();
|
||||
#endif
|
||||
std::string source = m_lookup->find(srcId);
|
||||
LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId);
|
||||
m_display->writeNXDN(source.c_str(), grp, dstId, "R");
|
||||
|
||||
m_rfState = RS_RF_AUDIO;
|
||||
}
|
||||
// }
|
||||
|
||||
// if (m_rfState == RS_RF_AUDIO) {
|
||||
// Regenerate the sync
|
||||
|
|
|
@ -42,7 +42,8 @@ const unsigned int INTERLEAVE_TABLE[] = {
|
|||
const unsigned int PUNCTURE_LIST[] = { 1U, 5U, 9U, 13U, 17U, 21U, 25U, 29U, 33U, 37U,
|
||||
41U, 45U, 49U, 53U, 57U, 61U, 65U, 69U, 73U, 77U,
|
||||
81U, 85U, 89U, 93U, 97U, 101U, 105U, 109U, 113U, 117U,
|
||||
121U, 125U, 129U, 133U, 137U, 141U};
|
||||
121U, 125U, 129U, 133U, 137U, 141U, 145U, 149U, 153U, 157U,
|
||||
161U, 165U, 169U, 173U, 177U, 181U, 185U, 189U };
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
||||
|
||||
|
@ -121,11 +122,7 @@ void CNXDNFACCH1::encode(unsigned char* data, unsigned int offset) const
|
|||
|
||||
unsigned char temp1[12U];
|
||||
::memset(temp1, 0x00U, 12U);
|
||||
|
||||
for (unsigned int i = 0U; i < 80U; i++) {
|
||||
bool b = READ_BIT1(m_data, i);
|
||||
WRITE_BIT1(temp1, i, b);
|
||||
}
|
||||
::memcpy(temp1, data, 10U);
|
||||
|
||||
CNXDNCRC::encodeCRC12(temp1, 80U);
|
||||
|
||||
|
|
|
@ -93,6 +93,15 @@ unsigned char CNXDNLayer3::getCallOptions() const
|
|||
return m_data[2U] & 0x1FU;
|
||||
}
|
||||
|
||||
bool CNXDNLayer3::getHasInfo() const
|
||||
{
|
||||
unsigned char type = getMessageType();
|
||||
|
||||
return type != NXDN_MESSAGE_TYPE_IDLE &&
|
||||
type != NXDN_MESSAGE_TYPE_VCALL_IV &&
|
||||
type != NXDN_MESSAGE_TYPE_SDCALL_IV;
|
||||
}
|
||||
|
||||
CNXDNLayer3& CNXDNLayer3::operator=(const CNXDNLayer3& layer3)
|
||||
{
|
||||
if (&layer3 != this)
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
unsigned short getDestinationGroupId() const;
|
||||
bool getIsGroup() const;
|
||||
unsigned char getCallOptions() const;
|
||||
bool getHasInfo() const;
|
||||
|
||||
CNXDNLayer3& operator=(const CNXDNLayer3& layer3);
|
||||
|
||||
|
|
|
@ -123,14 +123,14 @@ void CNXDNSACCH::encode(unsigned char* data) const
|
|||
|
||||
CNXDNCRC::encodeCRC6(temp1, 26U);
|
||||
|
||||
CUtils::dump("NXDN, SACCH encoded with CRC", temp1, 4U);
|
||||
CUtils::dump("NXDN, SACCH encoded with CRC", temp1, 5U);
|
||||
|
||||
unsigned char temp2[8U];
|
||||
unsigned char temp2[9U];
|
||||
|
||||
CNXDNConvolution conv;
|
||||
conv.encode(temp1, temp2, 36U);
|
||||
|
||||
// CUtils::dump("NXDN, SACCH convolved", temp2, 8U);
|
||||
// CUtils::dump("NXDN, SACCH convolved", temp2, 9U);
|
||||
|
||||
unsigned char temp3[8U];
|
||||
|
||||
|
|
|
@ -63,7 +63,8 @@ const unsigned int PUNCTURE_LIST[] = { 3U, 11U, 17U, 25U, 31U, 39U, 45U,
|
|||
73U, 81U, 87U, 95U, 101U, 109U, 115U, 123U, 129U, 137U,
|
||||
143U, 151U, 157U, 165U, 171U, 179U, 185U, 193U, 199U, 207U,
|
||||
213U, 221U, 227U, 235U, 241U, 249U, 255U, 263U, 269U, 277U,
|
||||
283U, 291U, 297U, 305U, 311U, 319U, 325U, 333U, 339U, 347U };
|
||||
283U, 291U, 297U, 305U, 311U, 319U, 325U, 333U, 339U, 347U,
|
||||
353U, 361U, 367U, 375U, 381U, 389U, 395U, 403U };
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
||||
|
||||
|
@ -142,11 +143,7 @@ void CNXDNUDCH::encode(unsigned char* data) const
|
|||
|
||||
unsigned char temp1[25U];
|
||||
::memset(temp1, 0x00U, 25U);
|
||||
|
||||
for (unsigned int i = 0U; i < 184U; i++) {
|
||||
bool b = READ_BIT1(m_data, i);
|
||||
WRITE_BIT1(temp1, i, b);
|
||||
}
|
||||
::memcpy(temp1, data, 23U);
|
||||
|
||||
CNXDNCRC::encodeCRC15(temp1, 184U);
|
||||
|
||||
|
|
Loading…
Reference in a new issue