WIP not decoding the SACCH correctly.

This commit is contained in:
Jonathan Naylor 2018-01-23 20:06:14 +00:00
parent 88b12104d3
commit ee18aa602c
6 changed files with 182 additions and 48 deletions

View file

@ -30,14 +30,14 @@ const uint16_t BIT_MASK_TABLE2[] = { 0x8000U, 0x4000U, 0x2000U, 0x1000U, 0x0800U
#define READ_BIT2(p,i) (p[(i)>>4] & BIT_MASK_TABLE2[(i)&15])
bool CNXDNCRC::checkCRC6(const unsigned char* in, unsigned int offset, unsigned int length)
bool CNXDNCRC::checkCRC6(const unsigned char* in, unsigned int length)
{
assert(in != NULL);
uint8_t crc[1U];
crc[0U] = createCRC6(in, offset, length);
crc[0U] = createCRC6(in, length);
unsigned int n = offset + length;
unsigned int n = length;
for (unsigned int i = 0U; i < 6U; i++, n++) {
bool b1 = READ_BIT1(crc, i);
bool b2 = READ_BIT1(in, n);
@ -48,28 +48,28 @@ bool CNXDNCRC::checkCRC6(const unsigned char* in, unsigned int offset, unsigned
return true;
}
void CNXDNCRC::encodeCRC6(unsigned char* in, unsigned int offset, unsigned int length)
void CNXDNCRC::encodeCRC6(unsigned char* in, unsigned int length)
{
assert(in != NULL);
uint8_t crc[1U];
crc[0U] = createCRC6(in, offset, length);
crc[0U] = createCRC6(in, length);
unsigned int n = offset + length;
unsigned int n = length;
for (unsigned int i = 0U; i < 6U; i++, n++) {
bool b = READ_BIT1(crc, i);
WRITE_BIT1(in, n, b);
}
}
bool CNXDNCRC::checkCRC12(const unsigned char* in, unsigned int offset, unsigned int length)
bool CNXDNCRC::checkCRC12(const unsigned char* in, unsigned int length)
{
assert(in != NULL);
uint16_t crc[1U];
crc[0U] = createCRC12(in, offset, length);
crc[0U] = createCRC12(in, length);
unsigned int n = offset + length;
unsigned int n = length;
for (unsigned int i = 0U; i < 12U; i++, n++) {
bool b1 = READ_BIT2(crc, i);
bool b2 = READ_BIT1(in, n);
@ -80,28 +80,28 @@ bool CNXDNCRC::checkCRC12(const unsigned char* in, unsigned int offset, unsigned
return true;
}
void CNXDNCRC::encodeCRC12(unsigned char* in, unsigned int offset, unsigned int length)
void CNXDNCRC::encodeCRC12(unsigned char* in, unsigned int length)
{
assert(in != NULL);
uint16_t crc[1U];
crc[0U] = createCRC12(in, offset, length);
crc[0U] = createCRC12(in, length);
unsigned int n = offset + length;
unsigned int n = length;
for (unsigned int i = 0U; i < 12U; i++, n++) {
bool b = READ_BIT2(crc, i);
WRITE_BIT1(in, n, b);
}
}
bool CNXDNCRC::checkCRC15(const unsigned char* in, unsigned int offset, unsigned int length)
bool CNXDNCRC::checkCRC15(const unsigned char* in, unsigned int length)
{
assert(in != NULL);
uint16_t crc[1U];
crc[0U] = createCRC15(in, offset, length);
crc[0U] = createCRC15(in, length);
unsigned int n = offset + length;
unsigned int n = length;
for (unsigned int i = 0U; i < 15U; i++, n++) {
bool b1 = READ_BIT2(crc, i);
bool b2 = READ_BIT1(in, n);
@ -112,38 +112,110 @@ bool CNXDNCRC::checkCRC15(const unsigned char* in, unsigned int offset, unsigned
return true;
}
void CNXDNCRC::encodeCRC15(unsigned char* in, unsigned int offset, unsigned int length)
void CNXDNCRC::encodeCRC15(unsigned char* in, unsigned int length)
{
assert(in != NULL);
uint16_t crc[1U];
crc[0U] = createCRC15(in, offset, length);
crc[0U] = createCRC15(in, length);
unsigned int n = offset + length;
unsigned int n = length;
for (unsigned int i = 0U; i < 15U; i++, n++) {
bool b = READ_BIT2(crc, i);
WRITE_BIT1(in, n, b);
}
}
uint8_t CNXDNCRC::createCRC6(const unsigned char* in, unsigned int offset, unsigned int length)
uint8_t CNXDNCRC::createCRC6(const unsigned char* in, unsigned int length)
{
uint8_t crc = 0x3FU;
uint8_t crc = 0x3EU;
return crc;
for (unsigned int i = 0U; i < length; i++) {
bool bit1 = READ_BIT1(in, i) != 0x00U;
bool bit2 = (crc & 0x20U) == 0x20U;
crc <<= 1;
if (bit1)
crc |= 0x01U;
if (bit2)
crc |= 0x27U;
crc &= 0x3FU;
}
for (unsigned int i = 0U; i < 6U; i++) {
bool bit = (crc & 0x20U) == 0x20U;
crc <<= 1;
if (bit)
crc ^= 0x27U;
}
return crc & 0x3FU;
}
uint16_t CNXDNCRC::createCRC12(const unsigned char* in, unsigned int offset, unsigned int length)
uint16_t CNXDNCRC::createCRC12(const unsigned char* in, unsigned int length)
{
uint16_t crc = 0x0FFFU;
uint16_t crc = 0x0D9EU;
return crc;
for (unsigned int i = 0U; i < length; i++) {
bool bit1 = READ_BIT1(in, i) != 0x00U;
bool bit2 = (crc & 0x0800U) == 0x0800U;
crc <<= 1;
if (bit1)
crc |= 0x0001U;
if (bit2)
crc ^= 0x080FU;
crc &= 0x0FFFU;
}
for (unsigned int i = 0U; i < 12U; i++) {
bool bit = (crc & 0x0800U) == 0x0800U;
crc <<= 1;
if (bit)
crc ^= 0x080FU;
}
return crc & 0x0FFFU;
}
uint16_t CNXDNCRC::createCRC15(const unsigned char* in, unsigned int offset, unsigned int length)
uint16_t CNXDNCRC::createCRC15(const unsigned char* in, unsigned int length)
{
uint16_t crc = 0x7FFFU;
uint16_t crc = 0x02E4U;
return crc;
for (unsigned int i = 0U; i < length; i++) {
bool bit1 = READ_BIT1(in, i) != 0x00U;
bool bit2 = (crc & 0x4000U) == 0x4000U;
crc <<= 1;
if (bit1)
crc |= 0x0001U;
if (bit2)
crc ^= 0x4CC5U;
crc &= 0x7FFFU;
}
for (unsigned int i = 0U; i < 15U; i++) {
bool bit = (crc & 0x4000U) == 0x4000U;
crc <<= 1;
if (bit)
crc ^= 0x4CC5U;
}
return crc & 0x7FFFU;
}

View file

@ -24,19 +24,19 @@
class CNXDNCRC
{
public:
static bool checkCRC6(const unsigned char* in, unsigned int offset, unsigned int length);
static void encodeCRC6(unsigned char* in, unsigned int offset, unsigned int length);
static bool checkCRC6(const unsigned char* in, unsigned int length);
static void encodeCRC6(unsigned char* in, unsigned int length);
static bool checkCRC12(const unsigned char* in, unsigned int offset, unsigned int length);
static void encodeCRC12(unsigned char* in, unsigned int offset, unsigned int length);
static bool checkCRC12(const unsigned char* in, unsigned int length);
static void encodeCRC12(unsigned char* in, unsigned int length);
static bool checkCRC15(const unsigned char* in, unsigned int offset, unsigned int length);
static void encodeCRC15(unsigned char* in, unsigned int offset, unsigned int length);
static bool checkCRC15(const unsigned char* in, unsigned int length);
static void encodeCRC15(unsigned char* in, unsigned int length);
private:
static uint8_t createCRC6(const unsigned char* in, unsigned int offser, unsigned int length);
static uint16_t createCRC12(const unsigned char* in, unsigned int offser, unsigned int length);
static uint16_t createCRC15(const unsigned char* in, unsigned int offser, unsigned int length);
static uint8_t createCRC6(const unsigned char* in, unsigned int length);
static uint16_t createCRC12(const unsigned char* in, unsigned int length);
static uint16_t createCRC15(const unsigned char* in, unsigned int length);
};
#endif

View file

@ -125,11 +125,11 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len)
m_rssiCount++;
}
CUtils::dump(2U, "NXDN, raw data", data + 2U, NXDN_FRAME_LENGTH_BYTES);
// CUtils::dump(2U, "NXDN, raw data", data + 2U, NXDN_FRAME_LENGTH_BYTES);
scrambler(data + 2U);
CUtils::dump(2U, "NXDN, after descrambling", data + 2U, NXDN_FRAME_LENGTH_BYTES);
// CUtils::dump(2U, "NXDN, after descrambling", data + 2U, NXDN_FRAME_LENGTH_BYTES);
CNXDNLICH lich;
bool valid = lich.decode(data + 2U);

View file

@ -21,7 +21,7 @@
class CNXDNLICH {
public:
CNXDNLICH(const CNXDNLICH& fich);
CNXDNLICH(const CNXDNLICH& lich);
CNXDNLICH();
~CNXDNLICH();
@ -39,7 +39,7 @@ public:
void setOption(unsigned char option);
void setDirection(unsigned char direction);
CNXDNLICH& operator=(const CNXDNLICH& fich);
CNXDNLICH& operator=(const CNXDNLICH& lich);
private:
unsigned char m_lich;

View file

@ -35,13 +35,20 @@ const unsigned int INTERLEAVE_TABLE[] = {
4U, 9U, 14U, 19U, 24U, 29U, 34U, 39U, 44U, 49U, 54U, 59U
};
const unsigned int PUNCTURE_LIST[] = { 5U, 11U, 17U, 23U, 29U, 35U, 41U, 47U, 53U, 59U };
const unsigned int PUNCTURE_LIST[] = { 5U, 11U, 17U, 23U, 29U, 35U, 41U, 47U, 53U, 59U, 65U, 71U };
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])
CNXDNSACCH::CNXDNSACCH(const CNXDNSACCH& sacch) :
m_data(NULL)
{
m_data = new unsigned char[5U];
::memcpy(m_data, sacch.m_data, 5U);
}
CNXDNSACCH::CNXDNSACCH() :
m_data(NULL)
{
@ -57,15 +64,19 @@ bool CNXDNSACCH::decode(const unsigned char* data)
{
assert(data != NULL);
CUtils::dump("NXDN, SACCH input", data, 12U);
unsigned char temp1[8U];
for (unsigned int i = 0U; i < NXDN_SACCH_LENGTH_BITS; i++) {
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_LICH_LENGTH_BITS;
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
bool b = READ_BIT1(data, n);
WRITE_BIT1(temp1, i, b);
}
unsigned char temp2[8U];
CUtils::dump("NXDN, SACCH de-interleaved", temp1, 8U);
unsigned char temp2[9U];
unsigned int n = 0U;
unsigned int index = 0U;
@ -81,6 +92,8 @@ bool CNXDNSACCH::decode(const unsigned char* data)
n++;
}
CUtils::dump("NXDN, SACCH de-punctured", temp2, 9U);
CNXDNConvolution conv;
conv.start();
@ -88,7 +101,9 @@ bool CNXDNSACCH::decode(const unsigned char* data)
for (unsigned int i = 0U; i < 36U; i++) {
uint8_t s0 = READ_BIT1(temp2, n) ? 1U : 0U;
n++;
uint8_t s1 = READ_BIT1(temp2, n) ? 1U : 0U;
n++;
conv.decode(s0, s1);
}
@ -97,11 +112,47 @@ bool CNXDNSACCH::decode(const unsigned char* data)
CUtils::dump("NXDN, SACCH", m_data, 5U);
bool valid = CNXDNCRC::checkCRC6(m_data, 0U, 32U);
// if (!valid)
// return false;
return CNXDNCRC::checkCRC6(m_data, 26U);
}
return true;
void CNXDNSACCH::encode(unsigned char* data) const
{
assert(data != NULL);
unsigned char temp1[5U];
::memset(temp1, 0x00U, 5U);
for (unsigned int i = 0U; i < 26U; i++) {
bool b = READ_BIT1(m_data, i);
WRITE_BIT1(temp1, i, b);
}
CNXDNCRC::encodeCRC6(temp1, 26U);
unsigned char temp2[9U];
CNXDNConvolution conv;
conv.encode(temp1, temp2, 36U);
unsigned char temp3[8U];
unsigned int n = 0U;
unsigned int index = 0U;
for (unsigned int i = 0U; i < 72U; i++) {
if (i != PUNCTURE_LIST[index]) {
bool b = READ_BIT1(temp2, i);
WRITE_BIT1(temp3, n, b);
n++;
} else {
index++;
}
}
for (unsigned int i = 0U; i < NXDN_SACCH_LENGTH_BITS; i++) {
unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS;
bool b = READ_BIT1(temp3, i);
WRITE_BIT1(data, n, b);
}
}
unsigned char CNXDNSACCH::getRAN() const
@ -139,3 +190,11 @@ void CNXDNSACCH::setData(const unsigned char* data)
::memcpy(m_data + 1U, data, 3U);
}
CNXDNSACCH& CNXDNSACCH::operator=(const CNXDNSACCH& sacch)
{
if (&sacch != this)
::memcpy(m_data, sacch.m_data, 5U);
return *this;
}

View file

@ -21,12 +21,13 @@
class CNXDNSACCH {
public:
CNXDNSACCH(const CNXDNSACCH& sacch);
CNXDNSACCH();
~CNXDNSACCH();
bool decode(const unsigned char* data);
void encode(unsigned char* data);
void encode(unsigned char* data) const;
unsigned char getRAN() const;
unsigned char getStructure() const;
@ -38,6 +39,8 @@ public:
void setData(const unsigned char* data);
CNXDNSACCH& operator=(const CNXDNSACCH& fich);
private:
unsigned char* m_data;
};