diff --git a/NXDNControl.cpp b/NXDNControl.cpp index bf98c4d..a089b45 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -22,12 +22,18 @@ #include const unsigned char SCRAMBLER[] = { - 0x00U, 0x00U, 0x02U, 0x72U, 0xACU, 0x37U, 0xA6U, 0xE4U, 0x50U, 0xADU, 0x3FU, 0x64U, 0x96U, 0xFCU, 0x9AU, 0x99U, - 0x80U, 0xC6U, 0x51U, 0xA5U, 0xFDU, 0x16U, 0x3AU, 0xCBU, 0x3CU, 0x7DU, 0xD0U, 0x6BU, 0x6EU, 0xC1U, 0x6BU, 0xEAU, - 0xA0U, 0x52U, 0xBCU, 0xBBU, 0x81U, 0xCEU, 0x93U, 0xD7U, 0x51U, 0x21U, 0x9CU, 0x2FU, 0x6CU, 0xD0U, 0xEFU, 0x0FU}; + 0x00U, 0x09U, 0xCAU, 0xB0U, 0xDEU, 0x9BU, 0x91U, 0x42U, + 0xB4U, 0xFDU, 0x92U, 0x5BU, 0xF2U, 0x6AU, 0x66U, 0x03U, + 0x19U, 0x46U, 0x97U, 0xF4U, 0x58U, 0xEBU, 0x2CU, 0xF1U, + 0xF7U}; // #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) : m_ran(ran), m_id(id), @@ -118,11 +124,11 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len) 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); - CUtils::dump(2U, "NXDN, after descrambling", data, len); + CUtils::dump(2U, "NXDN, after descrambling", data + 2U, NXDN_FRAME_LENGTH_BYTES); CNXDNLICH lich; 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 if (m_remoteGateway) { unsigned char direction = m_lastLICH.getDirection(); - if (direction != NXDN_LICH_DIRECTION_INBOUND) + if (direction == NXDN_LICH_DIRECTION_INBOUND) return false; } else { unsigned char direction = m_lastLICH.getDirection(); @@ -146,41 +152,10 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len) bool ret = false; #ifdef notdef - if (usc == NXDN_LICH_USC_SACCH_NS || usc == NXDN_LICH_USC_SACCH_SS) { - switch (option) { - case NXDN_LICH_STEAL_NONE: - ret = processVCHOnly(valid, 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; - } - } + if (usc == NXDN_LICH_USC_UDCH) { + ret = processData(option, data); + else + ret = processVoice(usc, option, data); #endif return ret; } @@ -1100,8 +1075,35 @@ void CNXDNControl::scrambler(unsigned char* data) const { assert(data != NULL); - for (unsigned int i = 0U; i < NXDN_FRAME_LENGTH_BYTES; i++) - data[i] ^= SCRAMBLER[i]; + unsigned int offset = 0U; + 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() diff --git a/NXDNControl.h b/NXDNControl.h index aaeb1dc..da2fd12 100644 --- a/NXDNControl.h +++ b/NXDNControl.h @@ -78,12 +78,8 @@ private: unsigned int m_rssiCount; FILE* m_fp; - bool processVCHOnly(bool valid, unsigned char *data); - bool processFACCH11(bool valid, 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); + bool processVoice(unsigned char usc, unsigned char option, unsigned char *data); + bool processData(unsigned char option, unsigned char *data); void writeQueueRF(const unsigned char* data); void writeQueueNet(const unsigned char* data); diff --git a/NXDNDefines.h b/NXDNDefines.h index 487923b..190fe01 100644 --- a/NXDNDefines.h +++ b/NXDNDefines.h @@ -21,7 +21,9 @@ 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_SYMBOLS = NXDN_FSW_LENGTH_BITS / 2U; diff --git a/NXDNLICH.cpp b/NXDNLICH.cpp index 9014328..4b7bbfc 100644 --- a/NXDNLICH.cpp +++ b/NXDNLICH.cpp @@ -50,43 +50,20 @@ bool CNXDNLICH::decode(const unsigned char* bytes) unsigned char lich[1U]; lich[0U] = 0x00U; - unsigned int offset = NXDN_FSW_LENGTH_BITS; - bool b7 = READ_BIT1(bytes, offset); - WRITE_BIT1(lich, 7U, b7); + bool b[8U]; - offset++; - bool b6 = READ_BIT1(bytes, offset); - WRITE_BIT1(lich, 6U, b6); + unsigned int offset1 = NXDN_FSW_LENGTH_BITS; + unsigned int offset2 = 7U; + 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 b5 = READ_BIT1(bytes, offset); - WRITE_BIT1(lich, 5U, b5); + bool parity = b[7U] ^ b[6U] ^ b[5U] ^ b[4U]; - offset++; - bool b4 = READ_BIT1(bytes, offset); - WRITE_BIT1(lich, 4U, b4); + // 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); - offset++; - 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) + if (parity != b[0U]) return false; m_lich = lich[0U] >> 1; @@ -102,58 +79,22 @@ void CNXDNLICH::encode(unsigned char* bytes) lich[0U] = m_lich << 1; - bool b7 = READ_BIT1(lich, 7U); - 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 b[8U]; - 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; - WRITE_BIT1(bytes, offset, b7); - offset++; - WRITE_BIT1(bytes, offset, true); - offset++; - - WRITE_BIT1(bytes, offset, b6); - 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 int offset1 = NXDN_FSW_LENGTH_BITS; + unsigned int offset2 = 7U; + for (unsigned int i = 0U; i < (NXDN_LICH_LENGTH_BITS / 2U); i++, offset2--) { + WRITE_BIT1(bytes, offset1, b[offset2]); + offset1++; + WRITE_BIT1(bytes, offset1, true); + offset1++; + } } unsigned char CNXDNLICH::getRFCT() const