Changes to fix the scrambler and LICH based on first RF tests.
This commit is contained in:
parent
5291a6427c
commit
7745e9cf1d
|
@ -22,12 +22,18 @@
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
const unsigned char SCRAMBLER[] = {
|
const unsigned char SCRAMBLER[] = {
|
||||||
0x00U, 0x00U, 0x02U, 0x72U, 0xACU, 0x37U, 0xA6U, 0xE4U, 0x50U, 0xADU, 0x3FU, 0x64U, 0x96U, 0xFCU, 0x9AU, 0x99U,
|
0x00U, 0x09U, 0xCAU, 0xB0U, 0xDEU, 0x9BU, 0x91U, 0x42U,
|
||||||
0x80U, 0xC6U, 0x51U, 0xA5U, 0xFDU, 0x16U, 0x3AU, 0xCBU, 0x3CU, 0x7DU, 0xD0U, 0x6BU, 0x6EU, 0xC1U, 0x6BU, 0xEAU,
|
0xB4U, 0xFDU, 0x92U, 0x5BU, 0xF2U, 0x6AU, 0x66U, 0x03U,
|
||||||
0xA0U, 0x52U, 0xBCU, 0xBBU, 0x81U, 0xCEU, 0x93U, 0xD7U, 0x51U, 0x21U, 0x9CU, 0x2FU, 0x6CU, 0xD0U, 0xEFU, 0x0FU};
|
0x19U, 0x46U, 0x97U, 0xF4U, 0x58U, 0xEBU, 0x2CU, 0xF1U,
|
||||||
|
0xF7U};
|
||||||
|
|
||||||
// #define DUMP_NXDN
|
// #define DUMP_NXDN
|
||||||
|
|
||||||
|
const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U };
|
||||||
|
|
||||||
|
#define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i)&7])
|
||||||
|
#define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE[(i)&7])
|
||||||
|
|
||||||
CNXDNControl::CNXDNControl(unsigned int ran, unsigned int id, bool selfOnly, CNXDNNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CNXDNLookup* lookup, CRSSIInterpolator* rssiMapper) :
|
CNXDNControl::CNXDNControl(unsigned int ran, unsigned int id, bool selfOnly, CNXDNNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CNXDNLookup* lookup, CRSSIInterpolator* rssiMapper) :
|
||||||
m_ran(ran),
|
m_ran(ran),
|
||||||
m_id(id),
|
m_id(id),
|
||||||
|
@ -118,11 +124,11 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
m_rssiCount++;
|
m_rssiCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
CUtils::dump(2U, "NXDN, raw data", data, len);
|
CUtils::dump(2U, "NXDN, raw data", data + 2U, NXDN_FRAME_LENGTH_BYTES);
|
||||||
|
|
||||||
scrambler(data + 2U);
|
scrambler(data + 2U);
|
||||||
|
|
||||||
CUtils::dump(2U, "NXDN, after descrambling", data, len);
|
CUtils::dump(2U, "NXDN, after descrambling", data + 2U, NXDN_FRAME_LENGTH_BYTES);
|
||||||
|
|
||||||
CNXDNLICH lich;
|
CNXDNLICH lich;
|
||||||
bool valid = lich.decode(data + 2U);
|
bool valid = lich.decode(data + 2U);
|
||||||
|
@ -133,7 +139,7 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
// Stop repeater packets coming through, unless we're acting as a remote gateway
|
// Stop repeater packets coming through, unless we're acting as a remote gateway
|
||||||
if (m_remoteGateway) {
|
if (m_remoteGateway) {
|
||||||
unsigned char direction = m_lastLICH.getDirection();
|
unsigned char direction = m_lastLICH.getDirection();
|
||||||
if (direction != NXDN_LICH_DIRECTION_INBOUND)
|
if (direction == NXDN_LICH_DIRECTION_INBOUND)
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
unsigned char direction = m_lastLICH.getDirection();
|
unsigned char direction = m_lastLICH.getDirection();
|
||||||
|
@ -146,41 +152,10 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
if (usc == NXDN_LICH_USC_SACCH_NS || usc == NXDN_LICH_USC_SACCH_SS) {
|
if (usc == NXDN_LICH_USC_UDCH) {
|
||||||
switch (option) {
|
ret = processData(option, data);
|
||||||
case NXDN_LICH_STEAL_NONE:
|
else
|
||||||
ret = processVCHOnly(valid, data);
|
ret = processVoice(usc, option, data);
|
||||||
break;
|
|
||||||
|
|
||||||
case NXDN_LICH_STEAL_FACCH1_1:
|
|
||||||
ret = processFACCH11(valid, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NXDN_LICH_STEAL_FACCH1_2:
|
|
||||||
ret = processFACCH12(valid, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NXDN_LICH_STEAL_FACCH:
|
|
||||||
ret = processFACCH1(valid, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (usc == NXDN_LICH_USC_UDCH) {
|
|
||||||
switch (option) {
|
|
||||||
case NXDN_LICH_STEAL_NONE:
|
|
||||||
ret = processUDCH(valid, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NXDN_LICH_STEAL_FACCH:
|
|
||||||
ret = processFACCH2(valid, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1100,8 +1075,35 @@ void CNXDNControl::scrambler(unsigned char* data) const
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++)
|
unsigned int offset = 0U;
|
||||||
data[i] ^= SCRAMBLER[i];
|
for (unsigned int i = 0U; i < NXDN_FRAME_LENGTH_SYMBOLS; i++, offset += 2U) {
|
||||||
|
bool invert = READ_BIT1(SCRAMBLER, i);
|
||||||
|
if (invert) {
|
||||||
|
unsigned int offset1 = offset + 0U;
|
||||||
|
unsigned int offset2 = offset + 1U;
|
||||||
|
|
||||||
|
bool b1 = READ_BIT1(data, offset1);
|
||||||
|
bool b2 = READ_BIT1(data, offset2);
|
||||||
|
|
||||||
|
if (b1 && b2) {
|
||||||
|
// -3 to +3, 11 to 01
|
||||||
|
WRITE_BIT1(data, offset1, false);
|
||||||
|
WRITE_BIT1(data, offset2, true);
|
||||||
|
} else if (b1 && !b2) {
|
||||||
|
// -1 to +1, 10 to 00
|
||||||
|
WRITE_BIT1(data, offset1, false);
|
||||||
|
WRITE_BIT1(data, offset2, false);
|
||||||
|
} else if (!b1 && b2) {
|
||||||
|
// +3 to -3, 01 to 11
|
||||||
|
WRITE_BIT1(data, offset1, true);
|
||||||
|
WRITE_BIT1(data, offset2, true);
|
||||||
|
} else {
|
||||||
|
// +1 to -1, 00 to 10
|
||||||
|
WRITE_BIT1(data, offset1, true);
|
||||||
|
WRITE_BIT1(data, offset2, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNXDNControl::openFile()
|
bool CNXDNControl::openFile()
|
||||||
|
|
|
@ -78,12 +78,8 @@ private:
|
||||||
unsigned int m_rssiCount;
|
unsigned int m_rssiCount;
|
||||||
FILE* m_fp;
|
FILE* m_fp;
|
||||||
|
|
||||||
bool processVCHOnly(bool valid, unsigned char *data);
|
bool processVoice(unsigned char usc, unsigned char option, unsigned char *data);
|
||||||
bool processFACCH11(bool valid, unsigned char *data);
|
bool processData(unsigned char option, unsigned char *data);
|
||||||
bool processFACCH12(bool valid, unsigned char *data);
|
|
||||||
bool processFACCH1(bool valid, unsigned char *data);
|
|
||||||
bool processUDCH(bool valid, unsigned char *data);
|
|
||||||
bool processFACCH2(bool valid, unsigned char *data);
|
|
||||||
|
|
||||||
void writeQueueRF(const unsigned char* data);
|
void writeQueueRF(const unsigned char* data);
|
||||||
void writeQueueNet(const unsigned char* data);
|
void writeQueueNet(const unsigned char* data);
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
|
|
||||||
const unsigned int NXDN_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
|
const unsigned int NXDN_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
|
||||||
|
|
||||||
const unsigned int NXDN_FRAME_LENGTH_BYTES = 48U;
|
const unsigned int NXDN_FRAME_LENGTH_BITS = 384U;
|
||||||
|
const unsigned int NXDN_FRAME_LENGTH_BYTES = NXDN_FRAME_LENGTH_BITS / 8U;
|
||||||
|
const unsigned int NXDN_FRAME_LENGTH_SYMBOLS = NXDN_FRAME_LENGTH_BITS / 2U;
|
||||||
|
|
||||||
const unsigned int NXDN_FSW_LENGTH_BITS = 20U;
|
const unsigned int NXDN_FSW_LENGTH_BITS = 20U;
|
||||||
const unsigned int NXDN_FSW_LENGTH_SYMBOLS = NXDN_FSW_LENGTH_BITS / 2U;
|
const unsigned int NXDN_FSW_LENGTH_SYMBOLS = NXDN_FSW_LENGTH_BITS / 2U;
|
||||||
|
|
105
NXDNLICH.cpp
105
NXDNLICH.cpp
|
@ -50,43 +50,20 @@ bool CNXDNLICH::decode(const unsigned char* bytes)
|
||||||
unsigned char lich[1U];
|
unsigned char lich[1U];
|
||||||
lich[0U] = 0x00U;
|
lich[0U] = 0x00U;
|
||||||
|
|
||||||
unsigned int offset = NXDN_FSW_LENGTH_BITS;
|
bool b[8U];
|
||||||
bool b7 = READ_BIT1(bytes, offset);
|
|
||||||
WRITE_BIT1(lich, 7U, b7);
|
|
||||||
|
|
||||||
offset++;
|
unsigned int offset1 = NXDN_FSW_LENGTH_BITS;
|
||||||
bool b6 = READ_BIT1(bytes, offset);
|
unsigned int offset2 = 7U;
|
||||||
WRITE_BIT1(lich, 6U, b6);
|
for (unsigned int i = 0U; i < (NXDN_LICH_LENGTH_BITS / 2U); i++, offset1 += 2U, offset2--) {
|
||||||
|
b[offset2] = READ_BIT1(bytes, offset1);
|
||||||
|
WRITE_BIT1(lich, offset2, b[offset2]);
|
||||||
|
}
|
||||||
|
|
||||||
offset++;
|
bool parity = b[7U] ^ b[6U] ^ b[5U] ^ b[4U];
|
||||||
bool b5 = READ_BIT1(bytes, offset);
|
|
||||||
WRITE_BIT1(lich, 5U, b5);
|
|
||||||
|
|
||||||
offset++;
|
// LogMessage("NXDN, LICH bits: %d%d %d%d %d%d %d - %d, parity: %d", b[7U] ? 1 : 0, b[6U] ? 1 : 0, b[5U] ? 1 : 0, b[4U] ? 1 : 0, b[3U] ? 1 : 0, b[2U] ? 1 : 0, b[1U] ? 1 : 0, b[0U] ? 1 : 0, parity ? 1 : 0);
|
||||||
bool b4 = READ_BIT1(bytes, offset);
|
|
||||||
WRITE_BIT1(lich, 4U, b4);
|
|
||||||
|
|
||||||
offset++;
|
if (parity != b[0U])
|
||||||
bool b3 = READ_BIT1(bytes, offset);
|
|
||||||
WRITE_BIT1(lich, 3U, b3);
|
|
||||||
|
|
||||||
offset++;
|
|
||||||
bool b2 = READ_BIT1(bytes, offset);
|
|
||||||
WRITE_BIT1(lich, 2U, b2);
|
|
||||||
|
|
||||||
offset++;
|
|
||||||
bool b1 = READ_BIT1(bytes, offset);
|
|
||||||
WRITE_BIT1(lich, 1U, b1);
|
|
||||||
|
|
||||||
offset++;
|
|
||||||
bool b0 = READ_BIT1(bytes, offset);
|
|
||||||
WRITE_BIT1(lich, 0U, b0);
|
|
||||||
|
|
||||||
bool parity = b7 ^ b6 ^ b5 ^ b4;
|
|
||||||
|
|
||||||
LogMessage("NXDN, LICH bits: %d%d %d%d %d%d %d - %d, parity: %d", b7 ? 1 : 0, b6 ? 1 : 0, b5 ? 1 : 0, b4 ? 1 : 0, b3 ? 1 : 0, b2 ? 1 : 0, b1 ? 1 : 0, b0 ? 1 : 0, parity ? 1 : 0);
|
|
||||||
|
|
||||||
if (parity != b0)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_lich = lich[0U] >> 1;
|
m_lich = lich[0U] >> 1;
|
||||||
|
@ -102,58 +79,22 @@ void CNXDNLICH::encode(unsigned char* bytes)
|
||||||
|
|
||||||
lich[0U] = m_lich << 1;
|
lich[0U] = m_lich << 1;
|
||||||
|
|
||||||
bool b7 = READ_BIT1(lich, 7U);
|
bool b[8U];
|
||||||
bool b6 = READ_BIT1(lich, 6U);
|
|
||||||
bool b5 = READ_BIT1(lich, 5U);
|
|
||||||
bool b4 = READ_BIT1(lich, 4U);
|
|
||||||
bool b3 = READ_BIT1(lich, 3U);
|
|
||||||
bool b2 = READ_BIT1(lich, 2U);
|
|
||||||
bool b1 = READ_BIT1(lich, 1U);
|
|
||||||
bool b0 = READ_BIT1(lich, 0U);
|
|
||||||
|
|
||||||
bool parity = b7 ^ b6 ^ b5 ^ b4;
|
unsigned int offset = 7U;
|
||||||
|
for (unsigned int i = 0U; i < (NXDN_LICH_LENGTH_BITS / 2U); i++, offset--)
|
||||||
|
b[offset] = READ_BIT1(lich, offset);
|
||||||
|
|
||||||
WRITE_BIT1(lich, 0U, parity);
|
b[0U] = b[7U] ^ b[6U] ^ b[5U] ^ b[4U];
|
||||||
|
|
||||||
unsigned int offset = NXDN_FSW_LENGTH_BITS;
|
unsigned int offset1 = NXDN_FSW_LENGTH_BITS;
|
||||||
WRITE_BIT1(bytes, offset, b7);
|
unsigned int offset2 = 7U;
|
||||||
offset++;
|
for (unsigned int i = 0U; i < (NXDN_LICH_LENGTH_BITS / 2U); i++, offset2--) {
|
||||||
WRITE_BIT1(bytes, offset, true);
|
WRITE_BIT1(bytes, offset1, b[offset2]);
|
||||||
offset++;
|
offset1++;
|
||||||
|
WRITE_BIT1(bytes, offset1, true);
|
||||||
WRITE_BIT1(bytes, offset, b6);
|
offset1++;
|
||||||
offset++;
|
}
|
||||||
WRITE_BIT1(bytes, offset, true);
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
WRITE_BIT1(bytes, offset, b5);
|
|
||||||
offset++;
|
|
||||||
WRITE_BIT1(bytes, offset, true);
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
WRITE_BIT1(bytes, offset, b4);
|
|
||||||
offset++;
|
|
||||||
WRITE_BIT1(bytes, offset, true);
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
WRITE_BIT1(bytes, offset, b3);
|
|
||||||
offset++;
|
|
||||||
WRITE_BIT1(bytes, offset, true);
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
WRITE_BIT1(bytes, offset, b2);
|
|
||||||
offset++;
|
|
||||||
WRITE_BIT1(bytes, offset, true);
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
WRITE_BIT1(bytes, offset, b1);
|
|
||||||
offset++;
|
|
||||||
WRITE_BIT1(bytes, offset, true);
|
|
||||||
offset++;
|
|
||||||
|
|
||||||
WRITE_BIT1(bytes, offset, b0);
|
|
||||||
offset++;
|
|
||||||
WRITE_BIT1(bytes, offset, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char CNXDNLICH::getRFCT() const
|
unsigned char CNXDNLICH::getRFCT() const
|
||||||
|
|
Loading…
Reference in a new issue