/* -*- c++ -*- */ /* * NXDN Encoder/Decoder (C) Copyright 2019 Max H. Parke KA1RBI * * This file is part of OP25 * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3, or (at your option) * any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ #include #include #include #include #include "bit_utils.h" #include "nxdn.h" #include "nxdn_const.h" static const uint8_t scramble_t[] = { 2, 5, 6, 7, 10, 12, 14, 16, 17, 22, 23, 25, 26, 27, 28, 30, 33, 34, 36, 37, 38, 41, 45, 47, 52, 54, 56, 57, 59, 62, 63, 64, 65, 66, 67, 69, 70, 73, 76, 79, 81, 82, 84, 85, 86, 87, 88, 89, 92, 95, 96, 98, 100, 103, 104, 107, 108, 116, 117, 121, 122, 125, 127, 131, 132, 134, 137, 139, 140, 141, 142, 143, 144, 145, 147, 151, 153, 154, 158, 159, 160, 162, 164, 165, 168, 170, 171, 174, 175, 176, 177, 181}; static const int PARITY[] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1}; static inline uint16_t crc16(const uint8_t buf[], int len, uint32_t crc) { uint32_t poly = (1<<12) + (1<<5) + (1<<0); for(int i=0; i>1]; result[i] = PARITY[reg & 0x19]; result[i+1] = PARITY[reg & 0x17]; } } // simplified trellis 2:1 decode; source and result in bits // assumes that encoding was done with NTEST trailing zero bits // result_len should be set to the actual number of data bits // in the original unencoded message (excl. these trailing bits) static inline void trellis_decode(uint8_t result[], const uint8_t source[], int result_len) { int reg = 0; int min_d; int min_bt; static const int NTEST = 4; static const int NTESTC = 1 << NTEST; uint8_t bt[NTEST]; uint8_t tt[NTEST*2]; int dstats[4]; int sum; for (int p=0; p < 4; p++) dstats[p] = 0; for (int p=0; p < result_len; p++) { for (int i=0; i>3; bt[1] = (i&4)>>2; bt[2] = (i&2)>>1; bt[3] = (i&1); trellis_encode(tt, bt, NTEST*2, reg); sum=0; for (int j=0; j 3) ? 3 : min_d] += 1; } // fprintf (stderr, "stats\t%d %d %d %d\n", dstats[0], dstats[1], dstats[2], dstats[3]); } void nxdn_descramble(uint8_t dibits[], int len) { for (int i=0; i= len) break; dibits[scramble_t[i]] ^= 0x2; // invert sign of scrambled dibits } } static inline void cfill(uint8_t result[], const uint8_t src[], int len) { for (int i=0; i