diff --git a/NXDNCRC.cpp b/NXDNCRC.cpp index 1233cb6..6170b85 100644 --- a/NXDNCRC.cpp +++ b/NXDNCRC.cpp @@ -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; } diff --git a/NXDNCRC.h b/NXDNCRC.h index d8b10ef..12e2e40 100644 --- a/NXDNCRC.h +++ b/NXDNCRC.h @@ -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 diff --git a/NXDNControl.cpp b/NXDNControl.cpp index e18a7ae..742f34f 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -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); diff --git a/NXDNLICH.h b/NXDNLICH.h index e5ecd2b..cd3d53e 100644 --- a/NXDNLICH.h +++ b/NXDNLICH.h @@ -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; diff --git a/NXDNSACCH.cpp b/NXDNSACCH.cpp index 4259b9a..073f764 100644 --- a/NXDNSACCH.cpp +++ b/NXDNSACCH.cpp @@ -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; +} diff --git a/NXDNSACCH.h b/NXDNSACCH.h index e209e60..d421fa9 100644 --- a/NXDNSACCH.h +++ b/NXDNSACCH.h @@ -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; };