mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-09 15:27:22 -05:00
Remove ITPP Dependencies; #331
Rework P25p1 NID code from KA1RBI's OP25 code; Remove ITPP Cmake, build config scripts, docs, etc.
This commit is contained in:
@@ -52,14 +52,13 @@ git_describe(GIT_TAG)
|
|||||||
|
|
||||||
find_package(LibSndFile REQUIRED)
|
find_package(LibSndFile REQUIRED)
|
||||||
find_package(MBE REQUIRED)
|
find_package(MBE REQUIRED)
|
||||||
find_package(ITPP REQUIRED)
|
|
||||||
find_package(RTLSDR)
|
find_package(RTLSDR)
|
||||||
find_package(Curses REQUIRED)
|
find_package(Curses REQUIRED)
|
||||||
find_package(PulseAudio REQUIRED)
|
find_package(PulseAudio REQUIRED)
|
||||||
find_package(CODEC2)
|
find_package(CODEC2)
|
||||||
|
|
||||||
include_directories(SYSTEM ${LIBSNDFILE_INCLUDE_DIR} ${MBE_INCLUDE_DIR} ${ITPP_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIRS} ${CURSES_INCLUDE_DIRS})
|
include_directories(SYSTEM ${LIBSNDFILE_INCLUDE_DIR} ${MBE_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIRS} ${CURSES_INCLUDE_DIRS})
|
||||||
set(LIBS ${MBE_LIBRARY} ${LIBSNDFILE_LIBRARY} ${ITPP_LIBRARY} ${PULSEAUDIO_SIMPLE_LIBRARY} ${PULSEAUDIO_LIBRARY} ${CURSES_LIBRARIES})
|
set(LIBS ${MBE_LIBRARY} ${LIBSNDFILE_LIBRARY} ${PULSEAUDIO_SIMPLE_LIBRARY} ${PULSEAUDIO_LIBRARY} ${CURSES_LIBRARIES})
|
||||||
|
|
||||||
if(RTLSDR_FOUND)
|
if(RTLSDR_FOUND)
|
||||||
find_package(Threads)
|
find_package(Threads)
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
# - Try to find ITPP
|
|
||||||
# Once done this will define
|
|
||||||
#
|
|
||||||
# ITPP_FOUND - System has ITPP
|
|
||||||
# ITPP_INCLUDE_DIR - The ITPP include directory
|
|
||||||
# ITPP_LIBRARY - The library needed to use ITPP
|
|
||||||
#
|
|
||||||
|
|
||||||
find_path(ITPP_INCLUDE_DIR itpp/itcomm.h)
|
|
||||||
|
|
||||||
set(ITPP_NAMES ${ITPP_NAMES} itpp libitpp libitpp.dll)
|
|
||||||
FIND_LIBRARY(ITPP_LIBRARY NAMES ${ITPP_NAMES})
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(ITPP DEFAULT_MSG ITPP_LIBRARY ITPP_INCLUDE_DIR)
|
|
||||||
@@ -98,7 +98,6 @@ if [ "$RELEASE" = "y" ]; then
|
|||||||
|
|
||||||
#compiled items into release dsd-fme folder
|
#compiled items into release dsd-fme folder
|
||||||
cp codec2/build/src/cygcodec2* dsd-fme-portable/dsd-fme/
|
cp codec2/build/src/cygcodec2* dsd-fme-portable/dsd-fme/
|
||||||
cp itpp-4.3.1/build/itpp/cygitpp* dsd-fme-portable/dsd-fme/
|
|
||||||
cp rtl-sdr/build/src/cyg* dsd-fme-portable/dsd-fme/
|
cp rtl-sdr/build/src/cyg* dsd-fme-portable/dsd-fme/
|
||||||
cp mbelib/build/cygmbe* dsd-fme-portable/dsd-fme/
|
cp mbelib/build/cygmbe* dsd-fme-portable/dsd-fme/
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,6 @@ if [ "$ANSWER" = "y" ]; then
|
|||||||
sudo pacman -Syu #always run a full update first, partial upgrades aren't supported in Arch -- including downloading dependencies, that may require an updated dependency, and breaks same dependency on another package, a.k.a, dependency hell
|
sudo pacman -Syu #always run a full update first, partial upgrades aren't supported in Arch -- including downloading dependencies, that may require an updated dependency, and breaks same dependency on another package, a.k.a, dependency hell
|
||||||
sudo pacman -S libpulse cmake ncurses lapack perl fftw rtl-sdr codec2 base-devel libsndfile git wget
|
sudo pacman -S libpulse cmake ncurses lapack perl fftw rtl-sdr codec2 base-devel libsndfile git wget
|
||||||
|
|
||||||
printf "Installing itpp 4.3.1 from Arch Strike --Tested on Arch 2023.08.01 and Manjaro XFCE 22.1.3 Minimal\n"
|
|
||||||
wget https://mirror.archstrike.org/x86_64/archstrike/itpp-4.3.1-3-x86_64.pkg.tar.xz
|
|
||||||
sudo pacman -U itpp-4.3.1-3-x86_64.pkg.tar.xz
|
|
||||||
sudo rm -R itpp-4.3.1-3-x86_64.pkg.tar.xz
|
|
||||||
|
|
||||||
git clone https://github.com/lwvmobile/mbelib
|
git clone https://github.com/lwvmobile/mbelib
|
||||||
cd mbelib
|
cd mbelib
|
||||||
git checkout ambe_tones
|
git checkout ambe_tones
|
||||||
|
|||||||
@@ -19,22 +19,6 @@ if [ "$ANSWER" = "y" ]; then
|
|||||||
export LD_LIBRARY_PATH
|
export LD_LIBRARY_PATH
|
||||||
echo $LD_LIBRARY_PATH
|
echo $LD_LIBRARY_PATH
|
||||||
|
|
||||||
#ITPP
|
|
||||||
cd $cdir
|
|
||||||
printf "Installing itpp 4.3.1 from source http://sourceforge.net/projects/itpp/files/latest/download?source=files\n Please wait!\n"
|
|
||||||
wget -O itpp-latest.tar.bz2 http://sourceforge.net/projects/itpp/files/latest/download?source=files
|
|
||||||
tar xjf itpp-latest.tar.bz2
|
|
||||||
cd itpp-4.3.1/
|
|
||||||
#newer Cygwin has Cmake 4.1.3 (or newer) so we need to replace the line with cmake_minimum_required to a newer version
|
|
||||||
#this doesn't seem to break anything, its just that cmake will refuse to run properly without a newer min version in it
|
|
||||||
#I'm just going to use the version that is used for most all my other cmake projects, seems to still be okay with new cmake
|
|
||||||
sed -i '/^cmake_minimum_required *( *VERSION *2\.8\.6 *)$/c\cmake_minimum_required(VERSION 3.10.2)' CMakeLists.txt
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake ..
|
|
||||||
make -j $(nproc)
|
|
||||||
make install
|
|
||||||
|
|
||||||
#MBELIB
|
#MBELIB
|
||||||
cd $cdir
|
cd $cdir
|
||||||
printf "Installing mbelib\n Please wait!\n"
|
printf "Installing mbelib\n Please wait!\n"
|
||||||
|
|||||||
@@ -12,13 +12,7 @@ read -p "Have you viewed the patent notice? y/N " ANSWER
|
|||||||
ANSWER=$(printf "$ANSWER"|tr '[:upper:]' '[:lower:]')
|
ANSWER=$(printf "$ANSWER"|tr '[:upper:]' '[:lower:]')
|
||||||
if [ "$ANSWER" = "y" ]; then
|
if [ "$ANSWER" = "y" ]; then
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install libpulse-dev libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libitpp-dev libncurses-dev libncurses6 libcodec2-dev
|
sudo apt install libpulse-dev libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libncurses-dev libncurses6 libcodec2-dev
|
||||||
chkitpp=$(dpkg -l libitpp-dev 2>/dev/null | awk '/^ii/ {print 1} END {if (NR == 0) print 0}')
|
|
||||||
if [ "$chkitpp" -lt "1" ];then
|
|
||||||
printf "\nFor some reason, ITPP did NOT install!\nYou may have to manually install it.\n\n"
|
|
||||||
read -p "Press Enter to exit..." x
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
git clone https://github.com/lwvmobile/mbelib
|
git clone https://github.com/lwvmobile/mbelib
|
||||||
cd mbelib
|
cd mbelib
|
||||||
git checkout ambe_tones
|
git checkout ambe_tones
|
||||||
|
|||||||
@@ -12,13 +12,7 @@ read -p "Have you viewed the patent notice? y/N " ANSWER
|
|||||||
ANSWER=$(printf "$ANSWER"|tr '[:upper:]' '[:lower:]')
|
ANSWER=$(printf "$ANSWER"|tr '[:upper:]' '[:lower:]')
|
||||||
if [ "$ANSWER" = "y" ]; then
|
if [ "$ANSWER" = "y" ]; then
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install libpulse-dev libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev libncurses5 libncurses5-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libitpp-dev libncursesw5-dev libcodec2-dev
|
sudo apt install libpulse-dev libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev libncurses5 libncurses5-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libncursesw5-dev libcodec2-dev
|
||||||
chkitpp=$(dpkg -l libitpp-dev 2>/dev/null | awk '/^ii/ {print 1} END {if (NR == 0) print 0}')
|
|
||||||
if [ "$chkitpp" -lt "1" ];then
|
|
||||||
printf "\nFor some reason, ITPP did NOT install!\nYou may have to manually install it.\n\n"
|
|
||||||
read -p "Press Enter to exit..." x
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
git clone https://github.com/lwvmobile/mbelib
|
git clone https://github.com/lwvmobile/mbelib
|
||||||
cd mbelib
|
cd mbelib
|
||||||
git checkout ambe_tones
|
git checkout ambe_tones
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ Debian/Mint/Ubuntu/Pi
|
|||||||
```
|
```
|
||||||
sudo apt update
|
sudo apt update
|
||||||
#Ubuntu 22.04 lts / Debian 11 and lower
|
#Ubuntu 22.04 lts / Debian 11 and lower
|
||||||
sudo apt install libpulse-dev pavucontrol libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev libncurses5 libncurses5-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libitpp-dev libcodec2-dev
|
sudo apt install libpulse-dev pavucontrol libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev libncurses5 libncurses5-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libcodec2-dev
|
||||||
#Ubuntu 24.04 lts / Debian 12
|
#Ubuntu 24.04 lts / Debian 12
|
||||||
#sudo apt install libpulse-dev pavucontrol libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libitpp-dev libncurses-dev libncurses6 libcodec2-dev
|
#sudo apt install libpulse-dev pavucontrol libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libncurses-dev libncurses6 libcodec2-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Fedora 36/37 -- from https://github.com/lwvmobile/dsd-fme/issues/99
|
Fedora 36/37 -- from https://github.com/lwvmobile/dsd-fme/issues/99
|
||||||
@@ -60,8 +60,6 @@ Arch -- https://github.com/lwvmobile/dsd-fme/issues/153 and https://github.com/l
|
|||||||
```
|
```
|
||||||
sudo pacman -Syu
|
sudo pacman -Syu
|
||||||
sudo pacman -S libpulse cmake ncurses lapack perl fftw rtl-sdr codec2 base-devel libsndfile git wget rtl-sdr
|
sudo pacman -S libpulse cmake ncurses lapack perl fftw rtl-sdr codec2 base-devel libsndfile git wget rtl-sdr
|
||||||
wget https://mirror.archstrike.org/x86_64/archstrike/itpp-4.3.1-3-x86_64.pkg.tar.xz
|
|
||||||
sudo pacman -U itpp-4.3.1-3-x86_64.pkg.tar.xz
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Headless Ubuntu Server/Pi
|
## Headless Ubuntu Server/Pi
|
||||||
@@ -69,24 +67,7 @@ sudo pacman -U itpp-4.3.1-3-x86_64.pkg.tar.xz
|
|||||||
If running headless, swap out pavucontrol for pulsemixer, and also install pulseaudio as well. Attempting to install pavucontrol in a headless environment may attempt to install a minimal desktop environment. Note: Default behavior of pulseaudio in a headless environment may be to be muted, so check by opening pulsemixer and unmuting and routing audio appropriately.
|
If running headless, swap out pavucontrol for pulsemixer, and also install pulseaudio as well. Attempting to install pavucontrol in a headless environment may attempt to install a minimal desktop environment. Note: Default behavior of pulseaudio in a headless environment may be to be muted, so check by opening pulsemixer and unmuting and routing audio appropriately.
|
||||||
|
|
||||||
```
|
```
|
||||||
sudo apt install libpulse-dev libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev libncurses5 libncurses5-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libitpp-dev libncursesw5-dev pulsemixer pulseaudio libcodec2-dev
|
sudo apt install libpulse-dev libsndfile1-dev libfftw3-dev liblapack-dev socat libusb-1.0-0-dev libncurses5 libncurses5-dev rtl-sdr librtlsdr-dev libusb-1.0-0-dev cmake git wget make build-essential libncursesw5-dev pulsemixer pulseaudio libcodec2-dev
|
||||||
```
|
|
||||||
|
|
||||||
### Build and Install ITPP - ONLY IF NOT IN REPO!!
|
|
||||||
|
|
||||||
```
|
|
||||||
wget -O itpp-latest.tar.bz2 http://sourceforge.net/projects/itpp/files/latest/download?source=files
|
|
||||||
tar xjf itpp*
|
|
||||||
#if you can't cd into this folder, double check folder name first
|
|
||||||
cd itpp-4.3.1
|
|
||||||
mkdir build
|
|
||||||
cd build
|
|
||||||
cmake ..
|
|
||||||
make -j `nproc`
|
|
||||||
sudo make install
|
|
||||||
sudo ldconfig
|
|
||||||
cd ..
|
|
||||||
cd ..
|
|
||||||
```
|
```
|
||||||
|
|
||||||
MBELib is considered a requirement in this build. You must read this notice prior to continuing. [MBElib Patent Notice](https://github.com/lwvmobile/mbelib#readme "MBElib Patent Notice")
|
MBELib is considered a requirement in this build. You must read this notice prior to continuing. [MBElib Patent Notice](https://github.com/lwvmobile/mbelib#readme "MBElib Patent Notice")
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
*
|
*
|
||||||
* Code adapted from http://www.aqdi.com/golay.htm
|
* Code adapted from http://www.aqdi.com/golay.htm
|
||||||
*
|
*
|
||||||
* Tried before with the implementation from ITPP library but couldn't make it produce the same outputs
|
|
||||||
* expected from the P25 transmissions that I have tested. This implementation does work.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|||||||
@@ -5,9 +5,6 @@
|
|||||||
/**
|
/**
|
||||||
* Code taken and adapted from www.eccpage.com/rs.c
|
* Code taken and adapted from www.eccpage.com/rs.c
|
||||||
* Credit goes to Mr Simon Rockliff.
|
* Credit goes to Mr Simon Rockliff.
|
||||||
*
|
|
||||||
* Tried before with the implementation from ITPP library but couldn't make it produce the same outputs
|
|
||||||
* expected from the P25 transmissions that I have tested. This implementation does work.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This program is an encoder/decoder for Reed-Solomon codes. Encoding is in
|
/* This program is an encoder/decoder for Reed-Solomon codes. Encoding is in
|
||||||
|
|||||||
@@ -1671,6 +1671,9 @@ int ez_rs28_facch (int payload[156], int parity[114]); //ezpwd bridge for FME
|
|||||||
int ez_rs28_sacch (int payload[180], int parity[132]); //ezpwd bridge for FME
|
int ez_rs28_sacch (int payload[180], int parity[132]); //ezpwd bridge for FME
|
||||||
int isch_lookup (uint64_t isch); //isch map lookup
|
int isch_lookup (uint64_t isch); //isch map lookup
|
||||||
|
|
||||||
|
//Phase 1 NID Check
|
||||||
|
int check_NID(char* bch_code, int* new_nac, char* new_duid, unsigned char parity);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
|
|
||||||
#ifndef P25P1_CHECK_NID_H_3af071e917ea43fdb51326e2cbfbde0a
|
|
||||||
#define P25P1_CHECK_NID_H_3af071e917ea43fdb51326e2cbfbde0a
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks a NID value, returns the fixed NAC, DUID and also an indication if it failed to decode the NID.
|
|
||||||
* \param bch_code Input. An array to the 63 bytes, each containing one bit of the NID. This includes the
|
|
||||||
* NAC (12 bits), DUID (4 bits) and 47 bits of BCH parity.
|
|
||||||
* \param new_nac Output. An address where to store the calculated NAC value after error correction. Should
|
|
||||||
* be large enough to accommodate for an integer.
|
|
||||||
* \param new_duid Output. An address where to store the calculated DUID value after error correction. Should
|
|
||||||
* be able to accommodate 3 chars.
|
|
||||||
* \param parity Input. The parity value read.
|
|
||||||
* \return 0 if there were errors processing the NID.
|
|
||||||
*/
|
|
||||||
int check_NID(char* bch_code, int* new_nac, char* new_duid, unsigned char parity);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // P25P1_CHECK_NID_H_3af071e917ea43fdb51326e2cbfbde0a
|
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
, ncurses
|
, ncurses
|
||||||
, pulseaudio
|
, pulseaudio
|
||||||
, rtl-sdr
|
, rtl-sdr
|
||||||
, itpp
|
|
||||||
, codec2
|
, codec2
|
||||||
, portaudioSupport ? true
|
, portaudioSupport ? true
|
||||||
, portaudio ? null
|
, portaudio ? null
|
||||||
@@ -23,7 +22,6 @@ stdenv.mkDerivation {
|
|||||||
buildInputs = [
|
buildInputs = [
|
||||||
mbelib
|
mbelib
|
||||||
libsndfile
|
libsndfile
|
||||||
itpp
|
|
||||||
rtl-sdr
|
rtl-sdr
|
||||||
ncurses.dev
|
ncurses.dev
|
||||||
pulseaudio.dev
|
pulseaudio.dev
|
||||||
@@ -39,7 +37,7 @@ stdenv.mkDerivation {
|
|||||||
tap audio and synthesize the decoded speech. Speech synthesis requires
|
tap audio and synthesize the decoded speech. Speech synthesis requires
|
||||||
mbelib, which is a separate package.
|
mbelib, which is a separate package.
|
||||||
'';
|
'';
|
||||||
homepage = "https://github.com/szechyjs/dsd";
|
homepage = "https://github.com/lwvmobile/dsd-fme";
|
||||||
license = licenses.mit;
|
license = licenses.mit;
|
||||||
platforms = platforms.unix;
|
platforms = platforms.unix;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,8 +20,6 @@
|
|||||||
#define NULL 0
|
#define NULL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "p25p1_check_nid.h"
|
|
||||||
|
|
||||||
void
|
void
|
||||||
printFrameInfo (dsd_opts * opts, dsd_state * state)
|
printFrameInfo (dsd_opts * opts, dsd_state * state)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,17 +1,138 @@
|
|||||||
#include <itpp/itcomm.h>
|
// BCH decoder implementation from OP25 (Copyright 2010, KA1RBI, GPL license)
|
||||||
|
#include "dsd.h"
|
||||||
|
|
||||||
#include "p25p1_check_nid.h"
|
#include <vector>
|
||||||
|
typedef std::vector<bool> bit_vector;
|
||||||
|
|
||||||
|
static const int bchGFexp[64] = {
|
||||||
|
1, 2, 4, 8, 16, 32, 3, 6, 12, 24, 48, 35, 5, 10, 20, 40,
|
||||||
|
19, 38, 15, 30, 60, 59, 53, 41, 17, 34, 7, 14, 28, 56, 51, 37,
|
||||||
|
9, 18, 36, 11, 22, 44, 27, 54, 47, 29, 58, 55, 45, 25, 50, 39,
|
||||||
|
13, 26, 52, 43, 21, 42, 23, 46, 31, 62, 63, 61, 57, 49, 33, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int bchGFlog[64] = {
|
||||||
|
-1, 0, 1, 6, 2, 12, 7, 26, 3, 32, 13, 35, 8, 48, 27, 18,
|
||||||
|
4, 24, 33, 16, 14, 52, 36, 54, 9, 45, 49, 38, 28, 41, 19, 56,
|
||||||
|
5, 62, 25, 11, 34, 31, 17, 47, 15, 23, 53, 51, 37, 44, 55, 40,
|
||||||
|
10, 61, 46, 30, 50, 22, 39, 43, 29, 60, 42, 21, 20, 59, 57, 58
|
||||||
|
};
|
||||||
|
|
||||||
using namespace itpp;
|
int bchDec(bit_vector& Codeword)
|
||||||
|
{
|
||||||
|
int elp[24][22], S[23];
|
||||||
|
int D[23], L[24], uLu[24];
|
||||||
|
int locn[11], reg[12];
|
||||||
|
int i, j, U, q, count;
|
||||||
|
int SynError, CantDecode;
|
||||||
|
|
||||||
// Ideas taken from http://op25.osmocom.org/trac/wiki.png/browser/op25/gr-op25/lib/decoder_ff_impl.cc
|
SynError = 0; CantDecode = 0;
|
||||||
// See also p25_training_guide.pdf page 48.
|
|
||||||
// See also tia-102-baaa-a-project_25-fdma-common_air_interface.pdf page 40.
|
|
||||||
// BCH encoder/decoder implementation from IT++. GNU GPL 3 license.
|
|
||||||
|
|
||||||
itpp::BCH bch(63, 16, 11, "6 3 3 1 1 4 1 3 6 7 2 3 5 4 5 3", true);
|
for (i = 1; i <= 22; i++) {
|
||||||
|
S[i] = 0;
|
||||||
|
for (j = 0; j <= 62; j++) {
|
||||||
|
if (Codeword[j]) {
|
||||||
|
S[i] = S[i] ^ bchGFexp[(i * j) % 63];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (S[i]) { SynError = 1; }
|
||||||
|
S[i] = bchGFlog[S[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SynError) { // if there are errors, try to correct them
|
||||||
|
L[0] = 0; uLu[0] = -1; D[0] = 0; elp[0][0] = 0;
|
||||||
|
L[1] = 0; uLu[1] = 0; D[1] = S[1]; elp[1][0] = 1;
|
||||||
|
for (i = 1; i <= 21; i++) {
|
||||||
|
elp[0][i] = -1; elp[1][i] = 0;
|
||||||
|
}
|
||||||
|
U = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
U = U + 1;
|
||||||
|
if (D[U] == -1) {
|
||||||
|
L[U + 1] = L[U];
|
||||||
|
for (i = 0; i <= L[U]; i++) {
|
||||||
|
elp[U + 1][i] = elp[U][i];
|
||||||
|
elp[U][i] = bchGFlog[elp[U][i]];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
q = U - 1;
|
||||||
|
while ((D[q] == -1) && (q > 0)) { q = q - 1; }
|
||||||
|
if (q > 0) {
|
||||||
|
j = q;
|
||||||
|
do { j = j - 1; if ((D[j] != -1) && (uLu[q] < uLu[j])) { q = j; }
|
||||||
|
} while (j > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (L[U] > L[q] + U - q) {
|
||||||
|
L[U + 1] = L[U];
|
||||||
|
} else {
|
||||||
|
L[U + 1] = L[q] + U - q;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i <= 21; i++) {
|
||||||
|
elp[U + 1][i] = 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i <= L[q]; i++) {
|
||||||
|
if (elp[q][i] != -1) {
|
||||||
|
elp[U + 1][i + U - q] = bchGFexp[(D[U] + 63 - D[q] + elp[q][i]) % 63];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i <= L[U]; i++) {
|
||||||
|
elp[U + 1][i] = elp[U + 1][i] ^ elp[U][i];
|
||||||
|
elp[U][i] = bchGFlog[elp[U][i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uLu[U + 1] = U - L[U + 1];
|
||||||
|
|
||||||
|
if (U < 22) {
|
||||||
|
if (S[U + 1] != -1) { D[U + 1] = bchGFexp[S[U + 1]]; } else { D[U + 1] = 0; }
|
||||||
|
for (i = 1; i <= L[U + 1]; i++) {
|
||||||
|
if ((S[U + 1 - i] != -1) && (elp[U + 1][i] != 0)) {
|
||||||
|
D[U + 1] = D[U + 1] ^ bchGFexp[(S[U + 1 - i] + bchGFlog[elp[U + 1][i]]) % 63];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
D[U + 1] = bchGFlog[D[U + 1]];
|
||||||
|
}
|
||||||
|
} while ((U < 22) && (L[U + 1] <= 11));
|
||||||
|
|
||||||
|
U = U + 1;
|
||||||
|
if (L[U] <= 11) {
|
||||||
|
for (i = 0; i <= L[U]; i++) {
|
||||||
|
elp[U][i] = bchGFlog[elp[U][i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i <= L[U]; i++) {
|
||||||
|
reg[i] = elp[U][i];
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
for (i = 1; i <= 63; i++) {
|
||||||
|
q = 1;
|
||||||
|
for (j = 1; j <= L[U]; j++) {
|
||||||
|
if (reg[j] != -1) {
|
||||||
|
reg[j] = (reg[j] + j) % 63;
|
||||||
|
q = q ^ bchGFexp[reg[j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (q == 0) {
|
||||||
|
locn[count] = 63 - i;
|
||||||
|
count = count + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count == L[U]) {
|
||||||
|
for (i = 0; i <= L[U] - 1; i++) {
|
||||||
|
Codeword[locn[i]] = Codeword[locn[i]] ^ 1;
|
||||||
|
}
|
||||||
|
CantDecode = count;
|
||||||
|
} else {
|
||||||
|
CantDecode = -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CantDecode = -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CantDecode;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience class to calculate the parity of the DUID values. Keeps a table with the expected outcomes
|
* Convenience class to calculate the parity of the DUID values. Keeps a table with the expected outcomes
|
||||||
@@ -24,13 +145,13 @@ private:
|
|||||||
|
|
||||||
unsigned char get_index(unsigned char x, unsigned char y)
|
unsigned char get_index(unsigned char x, unsigned char y)
|
||||||
{
|
{
|
||||||
return (x<<2) + y;
|
return (x << 2) + y;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ParityTable()
|
ParityTable()
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<sizeof(table); i++) {
|
for (unsigned int i = 0; i < sizeof(table); i++) {
|
||||||
table[i] = 0;
|
table[i] = 0;
|
||||||
}
|
}
|
||||||
table[get_index(1,1)] = 1;
|
table[get_index(1,1)] = 1;
|
||||||
@@ -39,9 +160,8 @@ public:
|
|||||||
|
|
||||||
unsigned char get_value(unsigned char x, unsigned char y)
|
unsigned char get_value(unsigned char x, unsigned char y)
|
||||||
{
|
{
|
||||||
return table[get_index(x,y)];
|
return table[get_index(x, y)];
|
||||||
}
|
}
|
||||||
|
|
||||||
} parity_table;
|
} parity_table;
|
||||||
|
|
||||||
int check_NID(char* bch_code, int* new_nac, char* new_duid, unsigned char parity)
|
int check_NID(char* bch_code, int* new_nac, char* new_duid, unsigned char parity)
|
||||||
@@ -49,31 +169,38 @@ int check_NID(char* bch_code, int* new_nac, char* new_duid, unsigned char parity
|
|||||||
int result;
|
int result;
|
||||||
|
|
||||||
// Fill up with the given input
|
// Fill up with the given input
|
||||||
bvec input(63);
|
bit_vector codeword(63);
|
||||||
for(unsigned int i=0; i<63; i++) {
|
for (unsigned int i = 0; i < 63; i++) {
|
||||||
input[i] = bch_code[i];
|
codeword[i] = bch_code[62-i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode it
|
// Decode it
|
||||||
bvec decoded, cw_isvalid;
|
int errors = bchDec(codeword);
|
||||||
bool ok = bch.decode(input, decoded, cw_isvalid);
|
bool ok = (errors >= 0);
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
// Decode failed
|
// Decode failed
|
||||||
|
// fprintf (stderr, "NID ERR: %d; ", errors);
|
||||||
result = 0;
|
result = 0;
|
||||||
} else {
|
} else {
|
||||||
|
//reload the codeword back into correct bit order
|
||||||
|
for (unsigned int i = 0; i < 63; i++) {
|
||||||
|
bch_code[i] = codeword[62-i];
|
||||||
|
}
|
||||||
|
for (unsigned int i = 0; i < 63; i++) {
|
||||||
|
codeword[i] = bch_code[i];
|
||||||
|
}
|
||||||
// Take the NAC from the decoded output. It's a 12 bit number starting from position 0.
|
// Take the NAC from the decoded output. It's a 12 bit number starting from position 0.
|
||||||
// Just convert the output from a binary sequence to an integer.
|
|
||||||
int nac = 0;
|
int nac = 0;
|
||||||
for (int i=0; i<12; i++) {
|
for (int i = 0; i < 12; i++) {
|
||||||
nac <<= 1;
|
nac <<= 1;
|
||||||
nac |= (int)decoded[i];
|
nac |= (int)codeword[i];
|
||||||
}
|
}
|
||||||
*new_nac = nac;
|
*new_nac = nac;
|
||||||
|
|
||||||
// Take the fixed DUID from the encoded output. 4 bit value starting at position 12.
|
// Take the fixed DUID from the encoded output. 4 bit value starting at position 12.
|
||||||
unsigned char new_duid_0 = (((int)decoded[12])<<1) + ((int)decoded[13]);
|
unsigned char new_duid_0 = (((int)codeword[12]) << 1) + ((int)codeword[13]);
|
||||||
unsigned char new_duid_1 = (((int)decoded[14])<<1) + ((int)decoded[15]);
|
unsigned char new_duid_1 = (((int)codeword[14]) << 1) + ((int)codeword[15]);
|
||||||
new_duid[0] = new_duid_0 + '0';
|
new_duid[0] = new_duid_0 + '0';
|
||||||
new_duid[1] = new_duid_1 + '0';
|
new_duid[1] = new_duid_1 + '0';
|
||||||
new_duid[2] = 0; // Null terminate
|
new_duid[2] = 0; // Null terminate
|
||||||
@@ -82,12 +209,12 @@ int check_NID(char* bch_code, int* new_nac, char* new_duid, unsigned char parity
|
|||||||
unsigned char expected_parity = parity_table.get_value(new_duid_0, new_duid_1);
|
unsigned char expected_parity = parity_table.get_value(new_duid_0, new_duid_1);
|
||||||
|
|
||||||
if (expected_parity != parity) {
|
if (expected_parity != parity) {
|
||||||
// Ignore, not sure what to do
|
// Parity mismatch – optional handling
|
||||||
//fprintf (stderr, "Error in parity detected?");
|
// fprintf(stderr, "Error in parity detected?\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user