mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-09 15:27:22 -05:00
NCurses Menu
--NCurses Menu (no more tedious CLI options) --Save/Read Capture Bin (WIP!) --Read OP25 Capture Bin (WIP!) --Per Call WAV saving on DMR Stereo --Revampled Data Header and 1/2, 3/4 Data LRRP --Dump LRRP Data to text file, import into QGIS --Included QGIS Map File with layers set up --DMR CACH and Burst FEC --No more Port Audio or OSS...ever. --Switch to 8Khz/1Ch for most decode types due to crisper sound ---DMR Stereo remains at 24/2, will look into revampint upsampe for cleaner sound
This commit is contained in:
90
cmake/FindLibPortAudio.cmake
Normal file
90
cmake/FindLibPortAudio.cmake
Normal file
@@ -0,0 +1,90 @@
|
||||
# - Try to find Portaudio
|
||||
# Once done this will define
|
||||
#
|
||||
# PORTAUDIO_FOUND - system has Portaudio
|
||||
# PORTAUDIO_INCLUDE_DIRS - the Portaudio include directory
|
||||
# PORTAUDIO_LIBRARIES - Link these to use Portaudio
|
||||
# PORTAUDIO_DEFINITIONS - Compiler switches required for using Portaudio
|
||||
# PORTAUDIO_VERSION - Portaudio version
|
||||
#
|
||||
# Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
|
||||
if (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
|
||||
# in cache already
|
||||
set(PORTAUDIO_FOUND TRUE)
|
||||
else (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
|
||||
if (NOT WIN32)
|
||||
include(FindPkgConfig)
|
||||
pkg_check_modules(PORTAUDIO2 portaudio-2.0)
|
||||
endif (NOT WIN32)
|
||||
|
||||
find_path (PORTAUDIO_INCLUDE_DIRS
|
||||
NAMES
|
||||
portaudio.h
|
||||
PATHS
|
||||
${PORTAUDIO2_INCLUDEDIR}
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
)
|
||||
if (NOT PORTAUDIO_INCLUDE_DIRS)
|
||||
set (PORTAUDIO_INCLUDE_DIRS
|
||||
${PORTAUDIO2_INCLUDE_DIRS}
|
||||
)
|
||||
list (APPEND PORTAUDIO_INCLUDE_DIRS ${PORTAUDIO2_INCLUDEDIR})
|
||||
endif (NOT PORTAUDIO_INCLUDE_DIRS)
|
||||
|
||||
find_library (PORTAUDIO_LIBRARIES
|
||||
NAMES
|
||||
portaudio
|
||||
PATHS
|
||||
${PORTAUDIO2_LIBDIR}
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
if (NOT PORTAUDIO_LIBRARIES)
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(PORTAUDIO_LIBRARIES "${PORTAUDIO2_LIBDIR}/lib${PORTAUDIO2_LIBRARIES}.dylib")
|
||||
else (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(PORTAUDIO_LIBRARIES
|
||||
${PORTAUDIO2_LIBRARIES}
|
||||
)
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
endif (NOT PORTAUDIO_LIBRARIES)
|
||||
|
||||
if (PORTAUDIO2_VERSION)
|
||||
set(PORTAUDIO_VERSION
|
||||
${PORTAUDIO2_VERSION}
|
||||
)
|
||||
else (PORTAUDIO2_VERSION)
|
||||
set(PORTAUDIO_VERSION
|
||||
18
|
||||
)
|
||||
endif (PORTAUDIO2_VERSION)
|
||||
|
||||
if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
|
||||
set(PORTAUDIO_FOUND TRUE)
|
||||
endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
|
||||
|
||||
if (PORTAUDIO_FOUND)
|
||||
if (NOT Portaudio_FIND_QUIETLY)
|
||||
message(STATUS "Found Portaudio: ${PORTAUDIO_LIBRARIES}")
|
||||
endif (NOT Portaudio_FIND_QUIETLY)
|
||||
else (PORTAUDIO_FOUND)
|
||||
if (Portaudio_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find Portaudio")
|
||||
endif (Portaudio_FIND_REQUIRED)
|
||||
endif (PORTAUDIO_FOUND)
|
||||
|
||||
# show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view
|
||||
mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES)
|
||||
|
||||
endif (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
|
||||
BIN
dsd-fme.png
BIN
dsd-fme.png
Binary file not shown.
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 212 KiB |
BIN
dsd-fme2.png
BIN
dsd-fme2.png
Binary file not shown.
|
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 153 KiB |
164
include/dsd.h
164
include/dsd.h
@@ -40,12 +40,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#ifdef SOLARIS
|
||||
#include <sys/audioio.h>
|
||||
#endif
|
||||
#if defined(BSD) && !defined(__APPLE__)
|
||||
#include <sys/soundcard.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <mbelib.h>
|
||||
#include <sndfile.h>
|
||||
@@ -54,29 +49,16 @@
|
||||
|
||||
#include <pulse/simple.h> //PULSE AUDIO
|
||||
#include <pulse/error.h> //PULSE AUDIO
|
||||
//#include <pulse/pulseaudio.h> //PUlSE AUDIO
|
||||
|
||||
#define SAMPLE_RATE_IN 48000 //48000
|
||||
#define SAMPLE_RATE_OUT 8000 //8000,
|
||||
|
||||
#ifdef USE_PORTAUDIO
|
||||
#include "portaudio.h"
|
||||
#define PA_FRAMES_PER_BUFFER 64
|
||||
//Buffer needs to be large enough to prevent input buffer overruns while DSD is doing other struff (like outputting voice)
|
||||
//else you get skipped samples which result in incomplete/erronous decodes and a mountain of error messages.
|
||||
#define PA_LATENCY_IN 0.500
|
||||
//Buffer needs to be large enough to prevent output buffer underruns while DSD is doing other stuff (like decoding input)
|
||||
//else you get choppy audio and in 'extreme' cases errors.
|
||||
//Buffer also needs to be as small as possible so we don't have a lot of audio delay.
|
||||
#define PA_LATENCY_OUT 0.100
|
||||
#endif
|
||||
|
||||
#ifdef USE_RTLSDR
|
||||
#include <rtl-sdr.h>
|
||||
#endif
|
||||
//look into making this not required by doing ifdef, make new c file for methods, and CLI case option for ncurses terminal
|
||||
#include <locale.h> //move this stuff to dsd.h
|
||||
#include <ncurses.h> //move this stuff to dsd.h
|
||||
|
||||
#include <locale.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
static volatile int exitflag;
|
||||
|
||||
@@ -153,18 +135,6 @@ typedef struct
|
||||
uint8_t NextIVComputed[8];
|
||||
} NxdnElementsContent_t;
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
MODE_UNENCRYPTED,
|
||||
MODE_BASIC_PRIVACY,
|
||||
MODE_ENHANCED_PRIVACY_ARC4,
|
||||
MODE_ENHANCED_PRIVACY_AES256,
|
||||
MODE_HYTERA_BASIC_40_BIT,
|
||||
MODE_HYTERA_BASIC_128_BIT,
|
||||
MODE_HYTERA_BASIC_256_BIT
|
||||
};
|
||||
|
||||
//Read Solomon (12,9) constant
|
||||
#define RS_12_9_DATASIZE 9
|
||||
#define RS_12_9_CHECKSUMSIZE 3
|
||||
@@ -281,9 +251,7 @@ typedef struct
|
||||
int audio_in_fd;
|
||||
SNDFILE *audio_in_file;
|
||||
SF_INFO *audio_in_file_info;
|
||||
#ifdef USE_PORTAUDIO
|
||||
PaStream* audio_in_pa_stream;
|
||||
#endif
|
||||
|
||||
uint32_t rtlsdr_center_freq;
|
||||
int rtlsdr_ppm_error; //was int, changed to float
|
||||
int audio_in_type; // 0 for device, 1 for file, 2 for portaudio, 3 for rtlsdr
|
||||
@@ -291,9 +259,7 @@ typedef struct
|
||||
int audio_out_fd;
|
||||
SNDFILE *audio_out_file;
|
||||
SF_INFO *audio_out_file_info;
|
||||
#ifdef USE_PORTAUDIO
|
||||
PaStream* audio_out_pa_stream;
|
||||
#endif
|
||||
|
||||
int audio_out_type; // 0 for device, 1 for file, 2 for portaudio
|
||||
int split;
|
||||
int playoffset;
|
||||
@@ -302,11 +268,19 @@ typedef struct
|
||||
char mbe_out_file[1024];
|
||||
char mbe_out_path[1024];
|
||||
FILE *mbe_out_f;
|
||||
FILE *symbol_out_f;
|
||||
float audio_gain;
|
||||
float audio_gainR;
|
||||
int audio_out;
|
||||
int dmr_stereo_wav;
|
||||
char wav_out_file[1024];
|
||||
char wav_out_fileR[1024];
|
||||
char wav_out_file_raw[1024];
|
||||
char symbol_out_file[1024];
|
||||
short int symbol_out;
|
||||
SNDFILE *wav_out_f;
|
||||
SNDFILE *wav_out_fR;
|
||||
SNDFILE *wav_out_raw;
|
||||
//int wav_out_fd;
|
||||
int serial_baud;
|
||||
char serial_dev[1024];
|
||||
@@ -315,6 +289,7 @@ typedef struct
|
||||
int frame_dstar;
|
||||
int frame_x2tdma;
|
||||
int frame_p25p1;
|
||||
int frame_p25p2;
|
||||
int frame_nxdn48;
|
||||
int frame_nxdn96;
|
||||
int frame_dmr;
|
||||
@@ -338,17 +313,16 @@ typedef struct
|
||||
int rtl_volume_multiplier;
|
||||
int rtl_udp_port;
|
||||
int rtl_bandwidth;
|
||||
int rtl_started;
|
||||
int monitor_input_audio;
|
||||
int pulse_raw_rate_in;
|
||||
int pulse_raw_rate_out;
|
||||
int pulse_digi_rate_in;
|
||||
int pulse_digi_rate_out;
|
||||
//int pulse_digi_rate_outR;
|
||||
int pulse_raw_in_channels;
|
||||
int pulse_raw_out_channels;
|
||||
int pulse_digi_in_channels;
|
||||
int pulse_digi_out_channels;
|
||||
//int pulse_digi_out_channelsR;
|
||||
int pulse_flush;
|
||||
pa_simple *pulse_raw_dev_in;
|
||||
pa_simple *pulse_raw_dev_out;
|
||||
@@ -356,23 +330,26 @@ typedef struct
|
||||
pa_simple *pulse_digi_dev_out;
|
||||
pa_simple *pulse_digi_dev_outR;
|
||||
int use_ncurses_terminal;
|
||||
int ncurses_compact;
|
||||
int ncurses_history;
|
||||
int reset_state;
|
||||
int payload;
|
||||
char output_name[1024];
|
||||
|
||||
int EncryptionMode;
|
||||
|
||||
unsigned int dPMR_curr_frame_is_encrypted;
|
||||
int dPMR_next_part_of_superframe;
|
||||
int inverted_dpmr;
|
||||
int frame_dpmr;
|
||||
//
|
||||
short int dmr_stereo;
|
||||
short int lrrp_file_output;
|
||||
|
||||
//
|
||||
int frame_ysf;
|
||||
int inverted_ysf; //not sure if ysf comes in inverted or not, but signal could if IQ flipped
|
||||
short int aggressive_framesync; //set to 1 for more aggressive framesync, 0 for less aggressive
|
||||
int inverted_ysf;
|
||||
short int aggressive_framesync;
|
||||
|
||||
FILE *symbolfile;
|
||||
|
||||
} dsd_opts;
|
||||
|
||||
@@ -380,8 +357,8 @@ typedef struct
|
||||
{
|
||||
int *dibit_buf;
|
||||
int *dibit_buf_p;
|
||||
int *dmr_payload_buf; //try loading up a small amount to buffer, 144 or 288?
|
||||
int *dmr_payload_p; //position for payload buffer
|
||||
int *dmr_payload_buf;
|
||||
int *dmr_payload_p;
|
||||
int repeat;
|
||||
short *audio_out_buf;
|
||||
short *audio_out_buf_p;
|
||||
@@ -415,13 +392,15 @@ typedef struct
|
||||
int maxbuf[1024];
|
||||
int minbuf[1024];
|
||||
int midx;
|
||||
char err_str[64]; //actual error errorbars
|
||||
char err_buf[64]; //make copy of err_str for comparison, only have string print when strcmp is different??
|
||||
char err_str[64];
|
||||
char err_buf[64];
|
||||
char err_strR[64];
|
||||
char err_bufR[64];
|
||||
char fsubtype[16];
|
||||
char ftype[16];
|
||||
int symbolcnt;
|
||||
int symbolc;
|
||||
|
||||
int rf_mod;
|
||||
int numflips;
|
||||
int lastsynctype;
|
||||
@@ -473,12 +452,12 @@ typedef struct
|
||||
int payload_mfid;
|
||||
int payload_mfidR;
|
||||
int payload_mi;
|
||||
int payload_miR; //check to see if anything tied to this still functions appropriately
|
||||
uint64_t payload_miP;
|
||||
int payload_lsfr;
|
||||
int payload_lsfrR;
|
||||
int payload_miR;
|
||||
unsigned long long int payload_miN;
|
||||
unsigned long long int payload_miP;
|
||||
int p25vc;
|
||||
unsigned long long int K;
|
||||
int M;
|
||||
int menuopen;
|
||||
|
||||
unsigned int debug_audio_errors;
|
||||
unsigned int debug_audio_errorsR;
|
||||
@@ -506,7 +485,8 @@ typedef struct
|
||||
unsigned int nxdn_key;
|
||||
char nxdn_call_type[1024];
|
||||
char dmr_callsign[2][6][99]; //plenty of room in case of overflow;
|
||||
char dmr_lrrp[2][6][9999];
|
||||
char dmr_lrrp[2][6][9999]; //memory hog
|
||||
unsigned long long int dmr_lrrp_source[2];
|
||||
|
||||
NxdnSacchRawPart_t NxdnSacchRawPart[4];
|
||||
NxdnFacch1RawPart_t NxdnFacch1RawPart[2];
|
||||
@@ -539,16 +519,21 @@ typedef struct
|
||||
TimeSlotVoiceSuperFrame_t TS2SuperFrame;
|
||||
|
||||
char dmr_branding[25];
|
||||
uint8_t dmr_12_rate_sf[2][60]; //going five frames deep by 12 bytes //[slot][value]
|
||||
uint8_t dmr_34_rate_sf[2][64]; //going four frames deep by 16 bytes //[slot][value]
|
||||
int dmr_stereo_payload[144]; //load up 144 dibit buffer for every single DMR TDMA frame
|
||||
//uint8_t dmr_stereo_payload[144]; //load up 144 dibit buffer for every single DMR TDMA frame
|
||||
uint8_t dmr_12_rate_sf[2][84]; //going seven blocks deep by 12 bytes //[slot][value]
|
||||
uint8_t dmr_34_rate_sf[2][96]; //going six blocks deep by 16 bytes //[slot][value]
|
||||
int dmr_stereo_payload[144]; //load up 144 dibit buffer for every single DMR TDMA frame
|
||||
uint8_t data_header_blocks[2]; //collect number of blocks to follow from data header per slot
|
||||
uint8_t data_header_padding[2]; //collect number of padding octets in last block per slot
|
||||
uint8_t data_header_format[2]; //collect format of data header (conf or unconf) per slot
|
||||
uint8_t data_header_sap[2]; //collect sap info per slot
|
||||
uint8_t data_block_counter[2]; //counter for number of data blocks collected
|
||||
uint8_t data_p_head[2]; //flag for dmr proprietary header to follow
|
||||
|
||||
|
||||
dPMRVoiceFS2Frame_t dPMRVoiceFS2Frame;
|
||||
|
||||
//These flags are used to known the DMR frame
|
||||
//printing format (hex or binary)
|
||||
//printing format (hex or binary)
|
||||
int printDMRRawVoiceFrameHex;
|
||||
int printDMRRawVoiceFrameBin;
|
||||
int printDMRRawDataFrameHex;
|
||||
@@ -557,7 +542,7 @@ typedef struct
|
||||
int printDMRAmbeVoiceSampleBin;
|
||||
|
||||
//These flags are used to known the dPMR frame
|
||||
//orinting format (hex or binary)
|
||||
//orinting format (hex or binary)
|
||||
int printdPMRRawVoiceFrameHex;
|
||||
int printdPMRRawVoiceFrameBin;
|
||||
int printdPMRRawDataFrameHex;
|
||||
@@ -574,9 +559,8 @@ typedef struct
|
||||
short int dmr_ms_mode;
|
||||
unsigned int dmrburstL;
|
||||
unsigned int dmrburstR;
|
||||
int dropL;
|
||||
int dropR;
|
||||
unsigned long long int R;
|
||||
// int block_count;
|
||||
|
||||
//dstar header for ncurses
|
||||
unsigned char dstarradioheader[41];
|
||||
@@ -604,6 +588,21 @@ typedef struct
|
||||
#define INV_P25P1_SYNC "333331331133111131311111"
|
||||
#define P25P1_SYNC "111113113311333313133333"
|
||||
|
||||
//preliminary P2 sync
|
||||
|
||||
// static const uint64_t P25P2_FRAME_SYNC_MAGIC = 0x575D57F7FFLL; // 40 bits
|
||||
// static const uint64_t P25P2_FRAME_SYNC_REV_P = 0x575D57F7FFLL ^ 0xAAAAAAAAAALL;
|
||||
#define P25P2_SYNC "11131131111333133333"
|
||||
#define INV_P25P2_SYNC "33313313333111311111"
|
||||
// static const uint64_t P25P2_FRAME_SYNC_MASK = 0xFFFFFFFFFFLL; //wonder what the mask was for if its all F
|
||||
//
|
||||
// static const uint64_t P25P2_FRAME_SYNC_N1200 = 0x0104015155LL;
|
||||
//#define P25P2_SYNC_N ""
|
||||
// static const uint64_t P25P2_FRAME_SYNC_X2400 = 0xa8a2a8d800LL;
|
||||
//#define P25P2_SYNC_X ""
|
||||
// static const uint64_t P25P2_FRAME_SYNC_P1200 = 0xfefbfeaeaaLL;
|
||||
//#define P25P2_SYNC_P ""
|
||||
|
||||
#define X2TDMA_BS_VOICE_SYNC "113131333331313331113311"
|
||||
#define X2TDMA_BS_DATA_SYNC "331313111113131113331133"
|
||||
#define X2TDMA_MS_DATA_SYNC "313113333111111133333313"
|
||||
@@ -628,9 +627,8 @@ typedef struct
|
||||
#define DMR_MS_DATA_SYNC "311131133313133331131113"
|
||||
#define DMR_MS_VOICE_SYNC "133313311131311113313331"
|
||||
|
||||
//inversion testing on MS
|
||||
//#define DMR_MS_DATA_SYNC "133313311131311113313331"
|
||||
//#define DMR_MS_VOICE_SYNC "311131133313133331131113"
|
||||
//Testing NXDN FSW again
|
||||
#define NXDN_FSW "3131331131"
|
||||
|
||||
#define DMR_RC_DATA_SYNC "131331111133133133311313"
|
||||
|
||||
@@ -670,7 +668,10 @@ void processAudio (dsd_opts * opts, dsd_state * state);
|
||||
void processAudioR (dsd_opts * opts, dsd_state * state);
|
||||
void openPulseInput (dsd_opts * opts); //not sure if we need to just pass opts, or opts and state yet
|
||||
void openPulseOutput (dsd_opts * opts); //not sure if we need to just pass opts, or opts and state yet
|
||||
void closePulseInput (dsd_opts * opts);
|
||||
void closePulseOutput (dsd_opts * opts);
|
||||
void writeSynthesizedVoice (dsd_opts * opts, dsd_state * state);
|
||||
void writeSynthesizedVoiceR (dsd_opts * opts, dsd_state * state);
|
||||
void playSynthesizedVoice (dsd_opts * opts, dsd_state * state);
|
||||
void playSynthesizedVoiceR (dsd_opts * opts, dsd_state * state);
|
||||
void openAudioOutDevice (dsd_opts * opts, int speed);
|
||||
@@ -690,7 +691,17 @@ void openMbeInFile (dsd_opts * opts, dsd_state * state);
|
||||
void closeMbeOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void openMbeOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void openWavOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void openWavOutFileL (dsd_opts * opts, dsd_state * state);
|
||||
void openWavOutFileR (dsd_opts * opts, dsd_state * state);
|
||||
void openWavOutFileRaw (dsd_opts * opts, dsd_state * state);
|
||||
void openSymbolOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void closeSymbolOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void writeSymbolOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void writeRawSample (dsd_opts * opts, dsd_state * state, short sample);
|
||||
void closeWavOutFile (dsd_opts * opts, dsd_state * state);
|
||||
void closeWavOutFileL (dsd_opts * opts, dsd_state * state);
|
||||
void closeWavOutFileR (dsd_opts * opts, dsd_state * state);
|
||||
void closeWavOutFileRaw (dsd_opts * opts, dsd_state * state);
|
||||
void printFrameInfo (dsd_opts * opts, dsd_state * state);
|
||||
void processFrame (dsd_opts * opts, dsd_state * state);
|
||||
void printFrameSync (dsd_opts * opts, dsd_state * state, char *frametype, int offset, char *modulation);
|
||||
@@ -724,22 +735,20 @@ void processX2TDMAdata (dsd_opts * opts, dsd_state * state);
|
||||
void processX2TDMAvoice (dsd_opts * opts, dsd_state * state);
|
||||
void processDSTAR_HD (dsd_opts * opts, dsd_state * state);
|
||||
void processYSF(dsd_opts * opts, dsd_state * state); //YSF
|
||||
void processP2(dsd_opts * opts, dsd_state * state); //P2
|
||||
short dmr_filter(short sample);
|
||||
short nxdn_filter(short sample);
|
||||
|
||||
|
||||
int strncmperr(const char *s1, const char *s2, size_t size, int MaxErr);
|
||||
/* Global functions */ //also borrowed
|
||||
uint32_t ConvertBitIntoBytes(uint8_t * BufferIn, uint32_t BitLength);
|
||||
uint32_t ConvertAsciiToByte(uint8_t AsciiMsbByte, uint8_t AsciiLsbByte, uint8_t * OutputByte);
|
||||
void Convert49BitSampleInto7Bytes(char * InputBit, char * OutputByte);
|
||||
void Convert7BytesInto49BitSample(char * InputByte, char * OutputBit);
|
||||
//
|
||||
//ifdef ncurses
|
||||
void ncursesOpen ();
|
||||
|
||||
void ncursesOpen (dsd_opts * opts, dsd_state * state);
|
||||
void ncursesPrinter (dsd_opts * opts, dsd_state * state);
|
||||
void ncursesClose ();
|
||||
//endif ncurses
|
||||
|
||||
/* NXDN frame decoding functions */
|
||||
void ProcessNXDNFrame(dsd_opts * opts, dsd_state * state, uint8_t Inverted);
|
||||
@@ -763,7 +772,7 @@ uint8_t NXDN_decode_LICH(uint8_t InputLich[8],
|
||||
uint8_t * Option,
|
||||
uint8_t * Direction,
|
||||
uint8_t * CompleteLichBinaryFormat,
|
||||
uint8_t Inverted);
|
||||
uint8_t Inverted);
|
||||
uint8_t NXDN_SACCH_raw_part_decode(uint8_t * Input, uint8_t * Output);
|
||||
void NXDN_SACCH_Full_decode(dsd_opts * opts, dsd_state * state);
|
||||
uint8_t NXDN_FACCH1_decode(uint8_t * Input, uint8_t * Output);
|
||||
@@ -778,12 +787,11 @@ char * NXDN_Cipher_Type_To_Str(uint8_t CipherType);
|
||||
uint16_t CRC15BitNXDN(uint8_t * BufferIn, uint32_t BitLength);
|
||||
uint16_t CRC12BitNXDN(uint8_t * BufferIn, uint32_t BitLength);
|
||||
uint8_t CRC6BitNXDN(uint8_t * BufferIn, uint32_t BitLength);
|
||||
void ScrambledNXDNVoiceBit(int * LfsrValue, char * BufferIn, char * BufferOut, int NbOfBitToScramble);
|
||||
|
||||
|
||||
void dPMRVoiceFrameProcess(dsd_opts * opts, dsd_state * state);
|
||||
void printdPMRAmbeVoiceSample(dsd_opts * opts, dsd_state * state);
|
||||
void printdPMRRawVoiceFrame (dsd_opts * opts, dsd_state * state);
|
||||
|
||||
//dPMR functions
|
||||
void ScrambledPMRBit(uint32_t * LfsrValue, uint8_t * BufferIn, uint8_t * BufferOut, uint32_t NbOfBitToScramble);
|
||||
void DeInterleave6x12DPmrBit(uint8_t * BufferIn, uint8_t * BufferOut);
|
||||
@@ -827,9 +835,9 @@ void ProcessMBCData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8
|
||||
void ProcessMBChData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||
void ProcessWTFData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||
void ProcessUnifiedData(dsd_opts * opts, dsd_state * state, uint8_t info[196], uint8_t syncdata[48], uint8_t SlotType[20]);
|
||||
|
||||
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
||||
int LFSR(dsd_state * state);
|
||||
int LFSRP(dsd_state * state);
|
||||
|
||||
void Hamming_7_4_init();
|
||||
void Hamming_7_4_encode(unsigned char *origBits, unsigned char *encodedBits);
|
||||
@@ -876,7 +884,7 @@ extern "C" {
|
||||
#endif
|
||||
void open_rtlsdr_stream(dsd_opts *opts);
|
||||
void cleanup_rtlsdr_stream();
|
||||
void get_rtlsdr_sample(int16_t *sample);
|
||||
void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state);
|
||||
void rtlsdr_sighandler();
|
||||
|
||||
//TRELLIS
|
||||
@@ -890,8 +898,6 @@ void CDMRTrellisPointsToDibits(const unsigned char* points, signed char* dibits)
|
||||
void CDMRTrellisBitsToTribits(const unsigned char* payload, unsigned char* tribits);
|
||||
bool CDMRTrellisDecode(const unsigned char* data, unsigned char* payload);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -76,7 +76,7 @@ extern const int DSDNXDN_UDCH_m_PunctureList[58];
|
||||
*/
|
||||
const char nxdnpr[145] = { 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1 };
|
||||
//const unsigned char nxdnpr2[384] =
|
||||
const unsigned char nxdnpr2[182] = //is this a problem, should it be 384/2 for dibits?
|
||||
const unsigned char nxdnpr2[182] = //generated from default in manual with the x^9+x^4+1 poly?
|
||||
{
|
||||
0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0,
|
||||
1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0,
|
||||
|
||||
145
src/dmr_bs.c
145
src/dmr_bs.c
@@ -10,13 +10,11 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
char ambe_fr[4][24] = {0};
|
||||
char ambe_fr2[4][24] = {0};
|
||||
char ambe_fr3[4][24] = {0};
|
||||
char t_ambe_fr[4][24] = {9};
|
||||
char t_ambe_fr2[4][24] = {9};
|
||||
char t_ambe_fr3[4][24] = {9};
|
||||
|
||||
const int *w, *x, *y, *z;
|
||||
char sync[25] = {0};
|
||||
char syncdata[48] = {0};
|
||||
char cachdata[13] = {0};
|
||||
//char cachdata[13] = {0};
|
||||
int mutecurrentslot;
|
||||
int msMode;
|
||||
char cc[4];
|
||||
@@ -29,6 +27,11 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
unsigned short int vc1;
|
||||
unsigned short int vc2;
|
||||
|
||||
//cach fec
|
||||
char cachdata[25] = {0}; //increased from 24 to 25 to see if this fixes ubuntu 32 bug
|
||||
int cachInterleave[24] = {0, 7, 8, 9, 1, 10, 11, 12, 2, 13, 14, 15, 3, 16, 4, 17, 18, 19, 5, 20, 21, 22, 6, 23};
|
||||
|
||||
|
||||
//add time to mirror printFrameSync
|
||||
time_t now;
|
||||
char * getTime(void) //get pretty hh:mm:ss timestamp
|
||||
@@ -67,17 +70,34 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
for(i = 0; i < 12; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
cachdata[i] = dibit;
|
||||
state->dmr_stereo_payload[i] = dibit;
|
||||
//fprintf (stderr, "D%X ", dibit);
|
||||
//fprintf (stderr, "P%X ", state->dmr_stereo_payload[i]);
|
||||
if(i == 2)
|
||||
{
|
||||
state->currentslot = (1 & (dibit >> 1));
|
||||
internalslot = (1 & (dibit >> 1));
|
||||
}
|
||||
|
||||
cachdata[cachInterleave[(i*2)]] = (1 & (dibit >> 1)); // bit 1
|
||||
cachdata[cachInterleave[(i*2)+1]] = (1 & dibit); // bit 0
|
||||
}
|
||||
|
||||
cachdata[25] = 0; //setting to see if this fixes ubuntu 32 bit bug
|
||||
|
||||
//decode and correct cach and compare
|
||||
int cach_okay = 69;
|
||||
if ( Hamming_7_4_decode (cachdata) ) //see if we need to de-interleave this...probably do.
|
||||
{
|
||||
cach_okay = 1;
|
||||
}
|
||||
if (cach_okay == 1)
|
||||
{
|
||||
//fprintf (stderr, "CACH Okay ");
|
||||
}
|
||||
if (cach_okay != 1)
|
||||
{
|
||||
//fprintf (stderr, "CACH FEC Error %d", cach_okay);
|
||||
}
|
||||
|
||||
state->currentslot = cachdata[1];
|
||||
internalslot = cachdata[1];
|
||||
|
||||
//this cach fec seems to work quite well, really helps on shaky signals
|
||||
|
||||
//Setup for first AMBE Frame
|
||||
//Interleave Schedule
|
||||
w = rW;
|
||||
@@ -140,19 +160,24 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
//short int l = 0; //do I still use this?
|
||||
// signaling data or sync
|
||||
long long int late_entry_pi[24] = {0};
|
||||
short int m = 0;
|
||||
for(i = 0; i < 24; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
|
||||
state->dmr_stereo_payload[i+66] = dibit;
|
||||
syncdata[(2*i)] = (1 & (dibit >> 1)); // bit 1
|
||||
syncdata[(2*i)+1] = (1 & dibit); // bit 0
|
||||
syncdata[(2*i)+1] = (1 & dibit); // bit 0
|
||||
sync[i] = (dibit | 1) + 48;
|
||||
|
||||
if (i < 4 || i > 19) //
|
||||
if (i < 4 || i > 19)
|
||||
{
|
||||
EmbeddedSignalling[2*i] = (1 & (dibit >> 1)); // bit 1
|
||||
EmbeddedSignalling[2*i+1] = (1 & dibit); // bit 0
|
||||
// fprintf(stderr, "\n EMB = ");
|
||||
EmbeddedSignalling[(2*i)] = (1 & (dibit >> 1)); // bit 1
|
||||
//fprintf (stderr, "%02b", dibit);
|
||||
EmbeddedSignalling[(2*i)+1] = (1 & dibit); // bit 0
|
||||
|
||||
}
|
||||
|
||||
//Used for ProcessVoiceBurstSync
|
||||
@@ -168,6 +193,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
state->TS2SuperFrame.TimeSlotRawVoiceFrame[vc2-1].Sync[i*2] = (1 & (dibit >> 1)); // bit 1
|
||||
state->TS2SuperFrame.TimeSlotRawVoiceFrame[vc2-1].Sync[i*2+1] = (1 & dibit); // bit 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sync[24] = 0;
|
||||
@@ -194,9 +220,20 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
state->LCSS = (unsigned int)((EmbeddedSignalling[5] << 1) + EmbeddedSignalling[6]);
|
||||
state->LCSS_ok = EmbeddedSignallingOk;
|
||||
|
||||
}
|
||||
else skipcount++;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
//fprintf (stderr, " %b", EmbeddedSignalling[i]);
|
||||
}
|
||||
|
||||
}
|
||||
//else skipcount++;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
//fprintf (stderr, " %b", EmbeddedSignalling[i]);
|
||||
}
|
||||
}
|
||||
//Continue Second AMBE Frame, 18 after Sync or EmbeddedSignalling
|
||||
for(i = 0; i < 18; i++)
|
||||
{
|
||||
@@ -248,15 +285,27 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
if (internalslot == 0)
|
||||
{
|
||||
vc1 = 1;
|
||||
state->dropL = 256;
|
||||
}
|
||||
if (internalslot == 1)
|
||||
{
|
||||
vc2 = 1;
|
||||
state->dropR = 256;
|
||||
}
|
||||
}
|
||||
|
||||
// if( strcmp (sync, DMR_DIRECT_MODE_TS1_DATA_SYNC) == 0)
|
||||
// {
|
||||
// fprintf (stderr,"%s ", getTime());
|
||||
// fprintf (stderr, " Sync: DMR TDMA Direct Mode TS 1 \n");
|
||||
// goto SKIP;
|
||||
// }
|
||||
//
|
||||
// if( strcmp (sync, DMR_DIRECT_MODE_TS2_DATA_SYNC) == 0)
|
||||
// {
|
||||
// fprintf (stderr,"%s ", getTime());
|
||||
// fprintf (stderr, " Sync: DMR TDMA Direct Mode TS 2 \n");
|
||||
// goto SKIP;
|
||||
// }
|
||||
|
||||
//check for sync pattern here after collected the rest of the payload, decide what to do with it
|
||||
if ( strcmp (sync, DMR_BS_DATA_SYNC) == 0 )
|
||||
{
|
||||
@@ -273,7 +322,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
else fprintf (stderr,"Sync: -DMR ");
|
||||
//constantly reset the vc counter to 1 each data frame in anticipation of new voice frame
|
||||
vc1 = 1;
|
||||
//state->dropL = 256;
|
||||
|
||||
}
|
||||
if (internalslot == 1)
|
||||
{
|
||||
@@ -287,7 +336,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
else fprintf (stderr,"Sync: -DMR ");
|
||||
//constantly reset the vc counter to 1 each data frame in anticipation of new voice frame
|
||||
vc2 = 1;
|
||||
//state->dropR = 256;
|
||||
|
||||
}
|
||||
processDMRdata (opts, state);
|
||||
skipcount++; //after 2 data frames, drop back to getFrameSync and process subsequent data with processDMRdata
|
||||
@@ -304,6 +353,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
//only play voice on no data sync
|
||||
if (strcmp (sync, DMR_BS_DATA_SYNC) != 0)
|
||||
{
|
||||
|
||||
if (EmbeddedSignallingOk == 0)
|
||||
{
|
||||
//goto END;
|
||||
@@ -314,7 +364,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
if (internalslot == 0)
|
||||
{
|
||||
state->dmrburstL = 16; //use 16 for Voice?
|
||||
//fprintf (stderr,"Sync: +DMR [slot1] slot2 | Color Code=%02d | DMRSTEREO | VC%d \n", state->dmr_color_code, vc1);
|
||||
|
||||
if (opts->inverted_dmr == 0)
|
||||
{
|
||||
fprintf (stderr,"Sync: +DMR [SLOT1] slot2 | | DMRSTEREO | VC%d ",vc1);
|
||||
@@ -324,11 +374,6 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
fprintf(stderr, " BPK %lld", state->K);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
//the condition below should be swapped to vc6 and not on vc1, placement after processMbeFrame
|
||||
if (vc1 == 1 && state->payload_algid != 0 && opts->payload == 1)
|
||||
{
|
||||
//LFSR(state); //placement here causes issues when second slot becomes active as well
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
else
|
||||
@@ -340,11 +385,6 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
fprintf(stderr, " BPK %lld", state->K);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
//the condition below should be swapped to vc6 and not on vc1, placement after processMbeFrame
|
||||
if (vc1 == 1 && state->payload_algid != 0 && opts->payload == 1)
|
||||
{
|
||||
//LFSR(state); //placement here causes issues when second slot becomes active as well
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
}
|
||||
@@ -361,11 +401,6 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
fprintf(stderr, " BPK %lld", state->K);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
//the condition below should be swapped to vc6 and not on vc1, placement after processMbeFrame
|
||||
if (vc2 == 1 && state->payload_algidR != 0 && opts->payload == 1)
|
||||
{
|
||||
//LFSR(state);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
else
|
||||
@@ -377,11 +412,6 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
fprintf(stderr, " BPK %lld", state->K);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
//the condition below should be swapped to vc6 and not on vc1, placement after processMbeFrame
|
||||
if (vc2 == 1 && state->payload_algidR != 0 && opts->payload == 1)
|
||||
{
|
||||
//LFSR(state);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
}
|
||||
@@ -403,29 +433,31 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
|
||||
|
||||
//We only want to run LFSR after processing VC6 frames and before rolling
|
||||
//back to VC1, otherwise we will incur an unwanted LFSR if voice becomes active
|
||||
//in both slots while in this loop
|
||||
if (internalslot == 0 && vc1 == 6)
|
||||
{
|
||||
state->dropL = 256;
|
||||
if (state->payload_algid != 0 ) //&& opts->payload == 1
|
||||
|
||||
if (state->payload_algid >= 0x21)
|
||||
{
|
||||
LFSR(state);
|
||||
//running this as state->payload_mi > 0 apparently causes some problem, don't know why
|
||||
if (state->payload_mi != 0 && state->payload_algid >= 0x21)
|
||||
{
|
||||
LFSR(state);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (internalslot == 1 && vc2 == 6)
|
||||
{
|
||||
state->dropR = 256;
|
||||
if (state->payload_algidR != 0 ) //&& opts->payload == 1
|
||||
|
||||
if (state->payload_algidR >= 0x21)
|
||||
{
|
||||
LFSR(state);
|
||||
if (state->payload_miR != 0 && state->payload_algidR == 0x21)
|
||||
{
|
||||
LFSR(state); //re-enable this one after testing Late Entry MI
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (internalslot == 0)
|
||||
@@ -436,6 +468,7 @@ void dmrBS (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
vc2++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// recalibrate center/umid/lmid, not sure this helps or does anything particularly in this case
|
||||
@@ -677,10 +710,6 @@ void dmrBSBootstrap (dsd_opts * opts, dsd_state * state)
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
//these ambe_fr values are set correctly now!
|
||||
//reset drop values since we don't know which slot (because I'm too lazy to write that part)
|
||||
state->dropL = 256;
|
||||
state->dropR = 256;
|
||||
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
|
||||
|
||||
114
src/dmr_data.c
114
src/dmr_data.c
@@ -25,14 +25,17 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
int *dibit_p;
|
||||
char sync[25];
|
||||
char syncdata[48];
|
||||
char cachdata[13] = {0};
|
||||
char cachdata[25] = {0}; //increased from 24 to 25 to see if this fixes ubuntu 32 bug
|
||||
char cc[5] = {0};
|
||||
char ccAscii[5] = {0};
|
||||
char bursttype[5];
|
||||
unsigned int burst;
|
||||
char info[196];
|
||||
char SlotType[20];
|
||||
// char SlotType[20]; //was char, but I don't think FEC brings back good values when usign that
|
||||
unsigned char SlotType[20]; //was char, but I don't think FEC brings back good values when usign that
|
||||
unsigned int SlotTypeOk;
|
||||
int cachInterleave[24] = {0, 7, 8, 9, 1, 10, 11, 12, 2, 13, 14, 15, 3, 16, 4, 17, 18, 19, 5, 20, 21, 22, 6, 23};
|
||||
|
||||
|
||||
/* Remove warning compiler */
|
||||
//UNUSED_VARIABLE(cachdata[0]);
|
||||
@@ -57,7 +60,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
dibit_p = state->dmr_payload_p - 90;
|
||||
}
|
||||
|
||||
// CACH
|
||||
// CACH, why aren't we running any FEC on this?
|
||||
for (i = 0; i < 12; i++)
|
||||
{
|
||||
dibit = *dibit_p;
|
||||
@@ -71,31 +74,72 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
dibit = (int)state->dmr_stereo_payload[i];
|
||||
}
|
||||
//fprintf(stderr, "%X", dibit);
|
||||
cachdata[i] = dibit;
|
||||
//cachdata[i] = dibit;
|
||||
|
||||
cachdata[cachInterleave[(i*2)]] = (1 & (dibit >> 1)); // bit 1
|
||||
cachdata[cachInterleave[(i*2)+1]] = (1 & dibit); // bit 0
|
||||
// cachdata[(i*2)] = (1 & (dibit >> 1)); // bit 1
|
||||
// cachdata[(i*2)+1] = (1 & dibit); // bit 0
|
||||
|
||||
if (i == 2)
|
||||
{
|
||||
/* Change the current slot only if we are in relayed mode (not in direct mode) */
|
||||
if(state->directmode == 0) state->currentslot = (1 & (dibit >> 1)); // bit 1
|
||||
|
||||
if (state->currentslot == 0 && state->dmr_ms_mode == 0)
|
||||
{
|
||||
state->slot1light[0] = '[';
|
||||
state->slot1light[6] = ']';
|
||||
state->slot2light[0] = ' ';
|
||||
state->slot2light[6] = ' ';
|
||||
}
|
||||
//else
|
||||
if (state->currentslot == 1 && state->dmr_ms_mode == 0)
|
||||
{
|
||||
state->slot2light[0] = '[';
|
||||
state->slot2light[6] = ']';
|
||||
state->slot1light[0] = ' ';
|
||||
state->slot1light[6] = ' ';
|
||||
}
|
||||
// if(state->directmode == 0) state->currentslot = (1 & (dibit >> 1)); //move this until after cach fec performed
|
||||
//
|
||||
// if (state->currentslot == 0 && state->dmr_ms_mode == 0)
|
||||
// {
|
||||
// state->slot1light[0] = '[';
|
||||
// state->slot1light[6] = ']';
|
||||
// state->slot2light[0] = ' ';
|
||||
// state->slot2light[6] = ' ';
|
||||
// }
|
||||
// //else
|
||||
// if (state->currentslot == 1 && state->dmr_ms_mode == 0)
|
||||
// {
|
||||
// state->slot2light[0] = '[';
|
||||
// state->slot2light[6] = ']';
|
||||
// state->slot1light[0] = ' ';
|
||||
// state->slot1light[6] = ' ';
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
cachdata[12] = 0;
|
||||
//cachdata[12] = 0;
|
||||
cachdata[25] = 0; //setting to see if this fixes ubuntu 32 bit bug
|
||||
//decode and correct cach and compare
|
||||
int cach_okay = 69;
|
||||
if ( Hamming_7_4_decode (cachdata) ) //is now de-interleaved appropriately
|
||||
{
|
||||
cach_okay = 1;
|
||||
}
|
||||
if (cach_okay == 1)
|
||||
{
|
||||
//fprintf (stderr, "CACH Okay ");
|
||||
}
|
||||
if (cach_okay != 1)
|
||||
{
|
||||
//fprintf (stderr, "CACH FEC Error %d", cach_okay);
|
||||
goto END;
|
||||
}
|
||||
|
||||
state->currentslot = cachdata[1]; //still bit 2, or somewhere else? is it 8? 1? TC?
|
||||
|
||||
if (state->currentslot == 0 && state->dmr_ms_mode == 0)
|
||||
{
|
||||
state->slot1light[0] = '[';
|
||||
state->slot1light[6] = ']';
|
||||
state->slot2light[0] = ' ';
|
||||
state->slot2light[6] = ' ';
|
||||
}
|
||||
//else
|
||||
if (state->currentslot == 1 && state->dmr_ms_mode == 0)
|
||||
{
|
||||
state->slot2light[0] = '[';
|
||||
state->slot2light[6] = ']';
|
||||
state->slot1light[0] = ' ';
|
||||
state->slot1light[6] = ' ';
|
||||
}
|
||||
//end correct cach and set slot
|
||||
|
||||
#ifdef DMR_DUMP
|
||||
k = 0;
|
||||
@@ -232,7 +276,7 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
syncdata[(2*i)+1] = (1 & dibit); // bit 0
|
||||
sync[i] = (dibit | 1) + 48;
|
||||
}
|
||||
sync[24] = 0;
|
||||
sync[24] = 0; //why?
|
||||
|
||||
#ifdef DMR_DUMP
|
||||
k = 0;
|
||||
@@ -296,8 +340,18 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
|
||||
/* Check and correct the SlotType (apply Golay(20,8) FEC check) */
|
||||
if(Golay_20_8_decode((unsigned char *)SlotType)) SlotTypeOk = 1;
|
||||
else SlotTypeOk = 0;
|
||||
//pretty sure this isn't working correcty, does not apply corrected bits, due to cast type mismatching
|
||||
// if(Golay_20_8_decode((unsigned char *)SlotType)) SlotTypeOk = 1;
|
||||
if( Golay_20_8_decode(SlotType) )
|
||||
{
|
||||
SlotTypeOk = 1;
|
||||
//fprintf (stderr, "Slot Okay ");
|
||||
}
|
||||
else
|
||||
{
|
||||
SlotTypeOk = 0;
|
||||
goto END;
|
||||
}
|
||||
|
||||
/* Slot Type parity checked => Fill the color code */
|
||||
//state->color_code = (unsigned int)((cc[0] << 3) + (cc[1] << 2) + (cc[2] << 1) + cc[3]);
|
||||
@@ -536,5 +590,13 @@ processDMRdata (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
//JUMP:
|
||||
END:
|
||||
if (SlotTypeOk == 0 || cach_okay == 0)
|
||||
{
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr, " **CACH or Burst Type FEC ERR - SKIPPING** ");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
} /* End processDMRdata() */
|
||||
|
||||
143
src/dmr_ms.c
143
src/dmr_ms.c
@@ -33,6 +33,7 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
||||
char redundancyB[36];
|
||||
unsigned short int vc1;
|
||||
unsigned short int vc2;
|
||||
|
||||
//add time to mirror printFrameSync
|
||||
time_t now;
|
||||
char * getTime(void) //get pretty hh:mm:ss timestamp
|
||||
@@ -60,12 +61,15 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
||||
short int skipcount = 0;
|
||||
|
||||
//Hardset variables for MS
|
||||
state->currentslot = 0;
|
||||
state->currentslot = 0; //0
|
||||
internalslot = 0;
|
||||
activeslot = 0;
|
||||
|
||||
//Run Loop while the getting is good
|
||||
while (loop == 1) {
|
||||
|
||||
short int m = 0;
|
||||
|
||||
state->dmrburstL = 16; //Use 16 for Voice?
|
||||
// No CACH in MS Mode?
|
||||
for(i = 0; i < 12; i++)
|
||||
@@ -258,17 +262,9 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
||||
y++;
|
||||
z++;
|
||||
|
||||
//end early to allow next sync without skipping a voice superframe
|
||||
//only use if only doing 6 VC and nothing else, otherwise, will lose sync
|
||||
if (vc1 == 6 && i == 30)
|
||||
{
|
||||
//i = 36;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//if ( (strcmp (sync, DMR_MS_VOICE_SYNC) == 0) )
|
||||
//fixed to compensate for inverted signal
|
||||
if ( ((strcmp (sync, DMR_MS_VOICE_SYNC) == 0) && opts->inverted_dmr == 0) ||
|
||||
((strcmp (sync, DMR_MS_DATA_SYNC) == 0) && opts->inverted_dmr == 1) )
|
||||
|
||||
@@ -276,29 +272,18 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
||||
if (internalslot == 0)
|
||||
{
|
||||
vc1 = 1;
|
||||
state->dropL = 256;
|
||||
fprintf (stderr, "MS Slot 1 Voice Sync \n");
|
||||
//activeslot = 0;
|
||||
|
||||
}
|
||||
|
||||
if (internalslot == 1)
|
||||
{
|
||||
vc2 = 1;
|
||||
state->dropR = 256;
|
||||
//fprintf (stderr, "MS Slot 2 Voice Sync \n");
|
||||
//activeslot = 1;
|
||||
}
|
||||
|
||||
state->dmr_ms_mode = 1; //set to 1 here??
|
||||
}
|
||||
|
||||
state->dmr_ms_mode = 1; //set to 1 here?
|
||||
//testing to see if we need to do something to get MS mode working properly,
|
||||
//get proper sync, skip frames, etc.
|
||||
if (state->dmr_ms_mode == 1 ) //&& vc1 < 7
|
||||
{
|
||||
//do something
|
||||
//fprintf (stderr, "MS MODE ");
|
||||
}
|
||||
|
||||
//don't know if we will catch an RC sync in here or not, should be on VC6 if it occurs
|
||||
if ( (strcmp (rcsync, DMR_RC_DATA_SYNC) == 0) || (strcmp (sync, DMR_RC_DATA_SYNC) == 0) ) //should be in same position as sync
|
||||
@@ -370,9 +355,6 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
||||
goto END;
|
||||
}
|
||||
|
||||
//if( (strcmp (sync, DMR_MS_DATA_SYNC) != 0) && internalslot == activeslot && vc1 < 7)
|
||||
//only play voice no MS Data Sync and vc1 below 6 (no voice resync)
|
||||
//fixed to compensate for inverted signal
|
||||
if( ( ( ((strcmp (sync, DMR_MS_DATA_SYNC) != 0) && opts->inverted_dmr == 0) ||
|
||||
((strcmp (sync, DMR_MS_VOICE_SYNC) != 0) && opts->inverted_dmr == 1) ) )
|
||||
&& internalslot == activeslot && vc1 < 7)
|
||||
@@ -390,10 +372,6 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
||||
fprintf(stderr, " BPK %lld", state->K);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
if (vc1 == 6 && state->payload_algid != 0 && opts->payload == 1)
|
||||
{
|
||||
LFSR(state);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
@@ -406,67 +384,32 @@ void dmrMS (dsd_opts * opts, dsd_state * state)
|
||||
fprintf(stderr, " BPK %lld", state->K);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
if (vc1 == 6 && state->payload_algid != 0 && opts->payload == 1)
|
||||
{
|
||||
LFSR(state);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
if (internalslot == 1 && opts->inverted_dmr == 0)
|
||||
{
|
||||
fprintf (stderr,"Sync: +DMR MS MODE | Color Code=%02d | DMRSTEREO | VC%d ", state->color_code, vc2);
|
||||
if (state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0)
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf(stderr, " BPK %lld", state->K);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
if (vc2 == 6 && state->payload_algidR != 0 && opts->payload == 1)
|
||||
{
|
||||
LFSR(state);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
if (internalslot == 1 && opts->inverted_dmr == 1)
|
||||
{
|
||||
fprintf (stderr,"Sync: -DMR MS MODE | Color Code=%02d | DMRSTEREO | VC%d ", state->color_code, vc2);
|
||||
if (state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0)
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf(stderr, " BPK %lld", state->K);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
if (vc2 == 6 && state->payload_algidR != 0 && opts->payload == 1)
|
||||
{
|
||||
LFSR(state);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
if (internalslot == 0 && vc1 == 6) //presumably when full (and no sync issues)
|
||||
{
|
||||
//process voice burst
|
||||
ProcessVoiceBurstSync(opts, state);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
if (internalslot == 1 && vc2 == 6) //presumably when full (and no sync issues)
|
||||
{
|
||||
//process voice burst
|
||||
//ProcessVoiceBurstSync(opts, state);
|
||||
//fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
state->dmr_ms_mode == 1;
|
||||
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
|
||||
if (internalslot == 0)
|
||||
|
||||
//need to seperate the algs here so we don't run LFSR on 22 and so on
|
||||
if (vc1 == 6 && state->payload_algid >= 21)
|
||||
{
|
||||
//vc1++;
|
||||
}
|
||||
if (internalslot == 1)
|
||||
{
|
||||
vc2++;
|
||||
}
|
||||
//state->currentslot = 0;
|
||||
if (state->payload_mi != 0 && state->payload_algid >= 0x21)
|
||||
{
|
||||
LFSR(state);
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
}
|
||||
vc1++;
|
||||
//6 seems optimal for MS, allows to quickly exit and resync if wonky or something
|
||||
@@ -692,13 +635,13 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
//reset drop values since we don't know which slot (because I'm too lazy to write that part)
|
||||
state->dropL = 256;
|
||||
state->dropR = 256;
|
||||
|
||||
state->dmr_ms_mode = 1;
|
||||
|
||||
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr2, NULL);
|
||||
processMbeFrame (opts, state, NULL, ambe_fr3, NULL);
|
||||
|
||||
skipDibit (opts, state, 144); //skip to next TDMA slot
|
||||
dmrMS (opts, state); //bootstrap into full TDMA frame
|
||||
|
||||
@@ -706,11 +649,17 @@ void dmrMSBootstrap (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
void dmrMSData (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int i;
|
||||
int i, b, c;
|
||||
int dibit;
|
||||
int *dibit_p;
|
||||
unsigned int burst;
|
||||
|
||||
unsigned char MSCach[24] = {0}; //12 dibits = 24 bits
|
||||
unsigned char MSSync[48] = {0}; //24 dibits = 48 bits
|
||||
unsigned char MSSlot[20] = {0}; //10 dibits = 20 bits
|
||||
unsigned char MSBurst[5] = {0};
|
||||
int cachInterleave[24] = {0, 7, 8, 9, 1, 10, 11, 12, 2, 13, 14, 15, 3, 16, 4, 17, 18, 19, 5, 20, 21, 22, 6, 23};
|
||||
//int cachInterleave[24] = {0,}
|
||||
//add time to mirror sync
|
||||
time_t now;
|
||||
char * getTime(void) //get pretty hh:mm:ss timestamp
|
||||
@@ -727,7 +676,8 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
b = 0;
|
||||
c = 0;
|
||||
//CACH + First Half Payload + Sync = 12 + 54 + 24
|
||||
//dibit_p = state->dibit_buf_p - 90;
|
||||
dibit_p = state->dmr_payload_p - 90;
|
||||
@@ -740,14 +690,42 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
|
||||
dibit = (dibit ^ 2);
|
||||
}
|
||||
state->dmr_stereo_payload[i] = dibit;
|
||||
//load cach
|
||||
if (i < 12)
|
||||
{
|
||||
MSCach[cachInterleave[(i*2)]] = (1 & (dibit >> 1)); // bit 1
|
||||
MSCach[cachInterleave[(i*2)+1]] = (1 & dibit); // bit 0
|
||||
}
|
||||
//load slot, first half
|
||||
if (i > 60 && i < 66)
|
||||
{
|
||||
MSSlot[(b*2)] = (1 & (dibit >> 1)); // bit 1
|
||||
MSSlot[(b*2)+1] = (1 & dibit); // bit
|
||||
b++;
|
||||
}
|
||||
//load sync
|
||||
if (i > 66)
|
||||
{
|
||||
MSSync[(c*2)] = (1 & (dibit >> 1)); // bit 1
|
||||
MSSync[(c*2)+1] = (1 & dibit); // bit 0
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 54; i++)
|
||||
{
|
||||
dibit = getDibit(opts, state);
|
||||
state->dmr_stereo_payload[i+90] = dibit;
|
||||
//load slot, second half
|
||||
if (i < 6)
|
||||
{
|
||||
MSSlot[(b*2)] = (1 & (dibit >> 1)); // bit 1
|
||||
MSSlot[(b*2)+1] = (1 & dibit); // bit
|
||||
b++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//hide behind payload due to errs in data in MS mode
|
||||
if (opts->payload == 1)
|
||||
{
|
||||
@@ -775,9 +753,6 @@ void dmrMSData (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
state->dmr_stereo = 0;
|
||||
state->dmr_ms_mode = 0;
|
||||
//reset drop values since we don't know which slot (because I'm too lazy to write that part)
|
||||
state->dropL = 256;
|
||||
state->dropR = 256;
|
||||
|
||||
//get potential first half payload dibits and store them in the payload for the next repitition, MS voice or data.
|
||||
skipDibit (opts, state, 144);
|
||||
|
||||
@@ -19,10 +19,6 @@
|
||||
#include "dmr_const.h"
|
||||
#include "p25p1_check_hdu.h"
|
||||
|
||||
//
|
||||
//A
|
||||
//
|
||||
|
||||
void ProcessDMR (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
uint32_t i, j;
|
||||
@@ -40,7 +36,6 @@ void ProcessDMR (dsd_opts * opts, dsd_state * state)
|
||||
TSVoiceSupFrameL = &state->TS1SuperFrame;
|
||||
TSVoiceSupFrameR = &state->TS2SuperFrame;
|
||||
|
||||
//
|
||||
int BP[256] = {
|
||||
0x0000, 0x1F00, 0xE300, 0xFC00, 0x2503, 0x3A03, 0xC603, 0xD903,
|
||||
0x4A05, 0x5505, 0xA905, 0xB605, 0x6F06, 0x7006, 0x8C06, 0x9306,
|
||||
@@ -75,9 +70,8 @@ int BP[256] = {
|
||||
0x0BF0, 0x14F0, 0xE8F0, 0xF7F0, 0x2EF3, 0x31F3, 0xCDF3, 0xD2F3,
|
||||
0x41F5, 0x5EF5, 0xA2F5, 0xBDF5, 0x64F6, 0x7BF6, 0x87F6, 0x98F6 //255
|
||||
};
|
||||
//
|
||||
//H
|
||||
//
|
||||
|
||||
|
||||
if (state->currentslot == 0 && state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0)
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
@@ -85,12 +79,12 @@ if (state->currentslot == 0 && state->K > 0 && state->dmr_so & 0x40 && state->pa
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
k = BP[state->K];
|
||||
k = ( ((k & 0xFF0F) << 32 ) + (k << 16) + k );
|
||||
|
||||
|
||||
for(Frame = 0; Frame < 6; Frame++)
|
||||
{
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
for(j = 0; j < 49; j++)
|
||||
for(j = 0; j < 48; j++)
|
||||
{
|
||||
x = ( ((k << j) & 0x800000000000) >> 47 );
|
||||
TSVoiceSupFrameL->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i][j] ^= x;
|
||||
@@ -111,7 +105,7 @@ if (state->currentslot == 1 && state->K > 0 && state->dmr_soR & 0x40 && state->p
|
||||
{
|
||||
for(i = 0; i < 3; i++)
|
||||
{
|
||||
for(j = 0; j < 49; j++)
|
||||
for(j = 0; j < 48; j++)
|
||||
{
|
||||
x = ( ((k << j) & 0x800000000000) >> 47 );
|
||||
TSVoiceSupFrameR->TimeSlotAmbeVoiceFrame[Frame].AmbeBit[i][j] ^= x;
|
||||
@@ -119,15 +113,10 @@ if (state->currentslot == 1 && state->K > 0 && state->dmr_soR & 0x40 && state->p
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//B
|
||||
//
|
||||
|
||||
if (state->currentslot == 0)
|
||||
{
|
||||
if (opts->payload == 1 && state->R == 0)
|
||||
{
|
||||
fprintf(stderr, "\n"); //line break for AMBE printer
|
||||
}
|
||||
|
||||
for(Frame = 0; Frame < 6; Frame++) //6
|
||||
{
|
||||
/* 1 DMR frame contains 3 AMBE voice samples */
|
||||
@@ -172,10 +161,7 @@ if (state->currentslot == 0)
|
||||
|
||||
if (state->currentslot == 1)
|
||||
{
|
||||
if (opts->payload == 1)
|
||||
{
|
||||
fprintf(stderr, "\n"); //line break for AMBE printer
|
||||
}
|
||||
|
||||
for(Frame = 0; Frame < 6; Frame++)
|
||||
{
|
||||
/* 1 DMR frame contains 3 AMBE voice samples */
|
||||
|
||||
741
src/dmr_sync.c
741
src/dmr_sync.c
File diff suppressed because it is too large
Load Diff
@@ -646,8 +646,8 @@ void processDMRvoice (dsd_opts * opts, dsd_state * state)
|
||||
ProcessDMR(opts, state);
|
||||
|
||||
//LFSR if required, change condition?
|
||||
if ( (state->currentslot == 0 && state->payload_algid != 0 ) || //&& opts->payload == 1
|
||||
(state->currentslot == 1 && state->payload_algidR != 0 ) ) //&& opts->payload == 1
|
||||
if ( (state->currentslot == 0 && state->payload_algid == 0x21 ) || //&& opts->payload == 1
|
||||
(state->currentslot == 1 && state->payload_algidR == 0x21 ) ) //&& opts->payload == 1
|
||||
{
|
||||
LFSR(state);
|
||||
}
|
||||
|
||||
156
src/dsd_audio.c
156
src/dsd_audio.c
@@ -22,6 +22,20 @@ pa_sample_spec tt;
|
||||
pa_sample_spec zz;
|
||||
pa_sample_spec cc;
|
||||
|
||||
void closePulseOutput (dsd_opts * opts)
|
||||
{
|
||||
pa_simple_free (opts->pulse_digi_dev_out);
|
||||
if (opts->dmr_stereo == 1)
|
||||
{
|
||||
pa_simple_free (opts->pulse_digi_dev_outR);
|
||||
}
|
||||
}
|
||||
|
||||
void closePulseInput (dsd_opts * opts)
|
||||
{
|
||||
pa_simple_free (opts->pulse_digi_dev_in);
|
||||
}
|
||||
|
||||
void openPulseOutput(dsd_opts * opts)
|
||||
{
|
||||
|
||||
@@ -35,7 +49,7 @@ void openPulseOutput(dsd_opts * opts)
|
||||
|
||||
if (opts->monitor_input_audio == 1)
|
||||
{
|
||||
opts->pulse_raw_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, "Raw Audio Out", &ss, NULL, NULL, NULL);
|
||||
opts->pulse_raw_dev_out = pa_simple_new(NULL, "DSD-FME3", PA_STREAM_PLAYBACK, NULL, "Raw Audio Out", &ss, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
//tt
|
||||
@@ -47,10 +61,11 @@ void openPulseOutput(dsd_opts * opts)
|
||||
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD-FME", PA_STREAM_PLAYBACK, NULL, opts->output_name, &tt, left, NULL, NULL);
|
||||
|
||||
}
|
||||
|
||||
if (opts->dmr_stereo == 1)
|
||||
{
|
||||
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD-FME1", PA_STREAM_PLAYBACK, NULL, "DMR/MOTOTRBO SLOT 1", &tt, left, NULL, NULL);
|
||||
opts->pulse_digi_dev_outR = pa_simple_new(NULL, "DSD-FME2", PA_STREAM_PLAYBACK, NULL, "DMR/MOTOTRBO SLOT 2", &tt, right, NULL, NULL);
|
||||
opts->pulse_digi_dev_out = pa_simple_new(NULL, "DSD-FME1", PA_STREAM_PLAYBACK, NULL, "DMR SLOT 1", &tt, left, NULL, NULL);
|
||||
opts->pulse_digi_dev_outR = pa_simple_new(NULL, "DSD-FME2", PA_STREAM_PLAYBACK, NULL, "DMR SLOT 2", &tt, right, NULL, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -348,8 +363,7 @@ processAudioR (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
||||
void writeSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int n;
|
||||
short aout_buf[160];
|
||||
@@ -377,6 +391,50 @@ writeSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
||||
|
||||
}
|
||||
|
||||
void writeSynthesizedVoiceR (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int n;
|
||||
short aout_buf[160];
|
||||
short *aout_buf_p;
|
||||
|
||||
aout_buf_p = aout_buf;
|
||||
state->audio_out_temp_buf_pR = state->audio_out_temp_bufR;
|
||||
|
||||
for (n = 0; n < 160; n++)
|
||||
{
|
||||
if (*state->audio_out_temp_buf_pR > (float) 32767)
|
||||
{
|
||||
*state->audio_out_temp_buf_pR = (float) 32767;
|
||||
}
|
||||
else if (*state->audio_out_temp_buf_pR < (float) -32768)
|
||||
{
|
||||
*state->audio_out_temp_buf_pR = (float) -32768;
|
||||
}
|
||||
*aout_buf_p = (short) *state->audio_out_temp_buf_pR;
|
||||
aout_buf_p++;
|
||||
state->audio_out_temp_buf_pR++;
|
||||
}
|
||||
|
||||
sf_write_short(opts->wav_out_fR, aout_buf, 160);
|
||||
|
||||
}
|
||||
|
||||
void writeRawSample (dsd_opts * opts, dsd_state * state, short sample)
|
||||
{
|
||||
int n;
|
||||
short aout_buf[160];
|
||||
short *aout_buf_p;
|
||||
|
||||
//sf_write_short(opts->wav_out_raw, aout_buf, 160);
|
||||
|
||||
//only write if actual audio, truncate silence
|
||||
if (sample != 0)
|
||||
{
|
||||
sf_write_short(opts->wav_out_raw, &sample, 2); //2 to match pulseaudio input sample read
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
@@ -396,22 +454,6 @@ playSynthesizedVoice (dsd_opts * opts, dsd_state * state)
|
||||
state->audio_out_idx = 0;
|
||||
}
|
||||
|
||||
//most likely don't need this seperation anymore with L and R, just push it out without any condional checks
|
||||
/*
|
||||
if(state->currentslot == 0 && opts->audio_in_type != 3 && opts->dmr_stereo == 1)
|
||||
{
|
||||
pa_simple_write(opts->pulse_digi_dev_out, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2), NULL); //Yay! It works.
|
||||
state->audio_out_idx = 0;
|
||||
}
|
||||
|
||||
//if input type is rtl dongle or no dmr stereo...do I need it this way still?
|
||||
if (opts->audio_in_type == 3 || opts->dmr_stereo == 0)
|
||||
{
|
||||
pa_simple_write(opts->pulse_digi_dev_out, (state->audio_out_buf_p - state->audio_out_idx), (state->audio_out_idx * 2), NULL); //Yay! It works.
|
||||
state->audio_out_idx = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -443,14 +485,6 @@ playSynthesizedVoiceR (dsd_opts * opts, dsd_state * state)
|
||||
pa_simple_write(opts->pulse_digi_dev_outR, (state->audio_out_buf_pR - state->audio_out_idxR), (state->audio_out_idxR * 2), NULL); //Yay! It works.
|
||||
state->audio_out_idxR = 0;
|
||||
}
|
||||
/*
|
||||
//most likely don't need this seperation anymore with L and R, just push it out without any condional checks
|
||||
if(opts->dmr_stereo == 1) //state->currentslot == 1 && opts->audio_in_type != 3 && opts->dmr_stereo == 1
|
||||
{
|
||||
pa_simple_write(opts->pulse_digi_dev_outR, (state->audio_out_buf_pR - state->audio_out_idxR), (state->audio_out_idxR * 2), NULL); //Yay! It works.
|
||||
state->audio_out_idxR = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@@ -467,17 +501,13 @@ playSynthesizedVoiceR (dsd_opts * opts, dsd_state * state)
|
||||
void
|
||||
openAudioOutDevice (dsd_opts * opts, int speed)
|
||||
{
|
||||
//converted to handle any calls to use portaudio
|
||||
if(strncmp(opts->audio_out_dev, "pa:", 3) == 0)
|
||||
{
|
||||
opts->audio_out_type = 2;
|
||||
#ifdef USE_PORTAUDIO
|
||||
int err = getPADevice(opts->audio_out_dev, 0, &opts->audio_out_pa_stream);
|
||||
if(err != 0)
|
||||
exit(err);
|
||||
#else
|
||||
fprintf (stderr,"Error, Portaudio support not compiled.\n");
|
||||
exit(1);
|
||||
#endif
|
||||
opts->audio_out_type = 0;
|
||||
fprintf (stderr,"Error, Port Audio is not supported by FME!\n");
|
||||
fprintf (stderr,"Using Pulse Audio Output Stream Instead! \n");
|
||||
sprintf (opts->audio_out_dev, "pulse");
|
||||
}
|
||||
if(strncmp(opts->audio_in_dev, "pulse", 5) == 0)
|
||||
{
|
||||
@@ -522,25 +552,13 @@ openAudioInDevice (dsd_opts * opts)
|
||||
exit(1); //had this one disabled, re-enabling it now
|
||||
}
|
||||
}
|
||||
//converted to handle any calls to use portaudio
|
||||
else if(strncmp(opts->audio_in_dev, "pa:", 2) == 0)
|
||||
{
|
||||
opts->audio_in_type = 2;
|
||||
#ifdef USE_PORTAUDIO
|
||||
int err = getPADevice(opts->audio_in_dev, 1, &opts->audio_in_pa_stream);
|
||||
if(err != 0)
|
||||
exit(err);
|
||||
|
||||
if (opts->split == 0)
|
||||
{
|
||||
int err = getPADevice(opts->audio_in_dev, 0, &opts->audio_out_pa_stream);
|
||||
if(err != 0)
|
||||
exit(err);
|
||||
}
|
||||
|
||||
#else
|
||||
fprintf (stderr,"Error, Portaudio support not compiled.\n");
|
||||
exit(1);
|
||||
#endif
|
||||
opts->audio_in_type = 0;
|
||||
fprintf (stderr,"Error, Port Audio is not supported by FME!\n");
|
||||
fprintf (stderr,"Using Pulse Audio Input Stream Instead! \n");
|
||||
sprintf (opts->audio_in_dev, "pulse");
|
||||
}
|
||||
else if(strncmp(opts->audio_in_dev, "rtl", 3) == 0)
|
||||
{
|
||||
@@ -550,28 +568,32 @@ openAudioInDevice (dsd_opts * opts)
|
||||
{
|
||||
opts->audio_in_type = 0;
|
||||
}
|
||||
//convert from opening wav files to OP25 symbol capture files since opening wav files is busted
|
||||
else
|
||||
{
|
||||
struct stat stat_buf;
|
||||
if (stat(opts->audio_in_dev, &stat_buf) != 0)
|
||||
struct stat stat_buf;
|
||||
if (stat(opts->audio_in_dev, &stat_buf) != 0)
|
||||
{
|
||||
fprintf (stderr,"Error, couldn't open %s\n", opts->audio_in_dev);
|
||||
exit(1);
|
||||
}
|
||||
if (S_ISREG(stat_buf.st_mode))
|
||||
if (S_ISREG(stat_buf.st_mode))
|
||||
{
|
||||
// is this a regular file? then process with libsndfile.
|
||||
//opts->pulse_digi_rate_out = 8000; //this for wav files input?
|
||||
opts->audio_in_type = 1;
|
||||
opts->audio_in_file_info = calloc(1, sizeof(SF_INFO));
|
||||
opts->audio_in_file_info->channels = 1;
|
||||
opts->audio_in_file = sf_open(opts->audio_in_dev, SFM_READ, opts->audio_in_file_info);
|
||||
// opts->audio_in_type = 1;
|
||||
// opts->audio_in_file_info = calloc(1, sizeof(SF_INFO));
|
||||
// opts->audio_in_file_info->channels = 1;
|
||||
// opts->audio_in_file = sf_open(opts->audio_in_dev, SFM_READ, opts->audio_in_file_info);
|
||||
//
|
||||
// if(opts->audio_in_file == NULL)
|
||||
// {
|
||||
// fprintf (stderr,"Error, couldn't open file %s\n", opts->audio_in_dev);
|
||||
// exit(1);
|
||||
// }
|
||||
|
||||
if(opts->audio_in_file == NULL)
|
||||
{
|
||||
fprintf (stderr,"Error, couldn't open file %s\n", opts->audio_in_dev);
|
||||
exit(1);
|
||||
}
|
||||
opts->symbolfile = fopen(opts->audio_in_dev, "r");
|
||||
opts->audio_in_type = 4; //symbol capture bin files
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -376,6 +376,7 @@ static int digitize (dsd_opts* opts, dsd_state* state, int symbol)
|
||||
*state->dmr_payload_p = dibit;
|
||||
state->dmr_payload_p++;
|
||||
//dmr buffer end
|
||||
|
||||
return dibit;
|
||||
}
|
||||
}
|
||||
@@ -386,6 +387,19 @@ get_dibit_and_analog_signal (dsd_opts* opts, dsd_state* state, int* out_analog_s
|
||||
int symbol;
|
||||
int dibit;
|
||||
|
||||
// if (opts->audio_in_type == 4 && opts->frame_provoice == 1) //
|
||||
// {
|
||||
// //skip processing symbol as dibit and use it as is
|
||||
// if (state->symbolc == 0)
|
||||
// {
|
||||
// symbol = 1;
|
||||
// }
|
||||
// if (state->symbolc == 1)
|
||||
// {
|
||||
// symbol = 3;
|
||||
// }
|
||||
// }
|
||||
|
||||
#ifdef TRACE_DSD
|
||||
unsigned int l, r;
|
||||
#endif
|
||||
@@ -402,7 +416,7 @@ get_dibit_and_analog_signal (dsd_opts* opts, dsd_state* state, int* out_analog_s
|
||||
r = state->debug_sample_index;
|
||||
#endif
|
||||
|
||||
//
|
||||
|
||||
state->sbuf[state->sidx] = symbol;
|
||||
|
||||
if (out_analog_signal != NULL)
|
||||
@@ -414,6 +428,21 @@ get_dibit_and_analog_signal (dsd_opts* opts, dsd_state* state, int* out_analog_s
|
||||
|
||||
dibit = digitize (opts, state, symbol);
|
||||
|
||||
//don't think this is quite right still, but should work, don't know why it doesn't
|
||||
if (opts->audio_in_type == 4 && opts->frame_provoice == 1) //
|
||||
{
|
||||
//skip processing symbol as dibit and use it as is
|
||||
dibit = state->symbolc;
|
||||
}
|
||||
|
||||
//symbol/dibit file capture/writing
|
||||
//need this bit here to capture dibits once sync starts
|
||||
if (opts->symbol_out == 1)
|
||||
{
|
||||
//fprintf (stderr, "%d", dibit);
|
||||
fputc (dibit, opts->symbol_out_f);
|
||||
}
|
||||
|
||||
#ifdef TRACE_DSD
|
||||
{
|
||||
float left, right;
|
||||
|
||||
179
src/dsd_file.c
179
src/dsd_file.c
@@ -146,7 +146,7 @@ PrintAMBEData (dsd_opts * opts, dsd_state * state, char *ambe_d) //For DMR Stere
|
||||
|
||||
err = (unsigned char) state->errs2;
|
||||
k = 0;
|
||||
if (opts->dmr_stereo == 0)
|
||||
if (opts->dmr_stereo == 0) //was 0, switched while working out des
|
||||
{
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
@@ -179,9 +179,9 @@ PrintAMBEData (dsd_opts * opts, dsd_state * state, char *ambe_d) //For DMR Stere
|
||||
}
|
||||
else fprintf(stderr, " err = [%X] [%X] ", state->errsR, state->errs2R);
|
||||
b = ambe_d[48];
|
||||
if (opts->dmr_stereo == 1)
|
||||
if (opts->dmr_stereo == 1) //need to fix the printouts again
|
||||
{
|
||||
fprintf (stderr, "\n");
|
||||
fprintf (stderr, "\n"); //temp disable while I work on DES
|
||||
}
|
||||
|
||||
}
|
||||
@@ -460,74 +460,113 @@ openWavOutFile (dsd_opts * opts, dsd_state * state)
|
||||
// state->wav_out_bytes = 0;
|
||||
|
||||
}
|
||||
void openWavOutFileL (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
|
||||
void
|
||||
closeWavOutFile (dsd_opts * opts, dsd_state * state)
|
||||
SF_INFO info;
|
||||
info.samplerate = 8000; //8000
|
||||
info.channels = 1;
|
||||
info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 | SF_ENDIAN_LITTLE;
|
||||
//opts->wav_out_f = sf_open (opts->wav_out_file, SFM_WRITE, &info);
|
||||
opts->wav_out_f = sf_open (opts->wav_out_file, SFM_RDWR, &info); //RDWR will append to file instead of overwrite file
|
||||
|
||||
if (opts->wav_out_f == NULL)
|
||||
{
|
||||
fprintf (stderr,"Error - could not open wav output file %s\n", opts->wav_out_file);
|
||||
return;
|
||||
}
|
||||
|
||||
// state->wav_out_bytes = 0;
|
||||
|
||||
}
|
||||
|
||||
void openWavOutFileR (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
|
||||
SF_INFO info;
|
||||
info.samplerate = 8000; //8000
|
||||
info.channels = 1;
|
||||
info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 | SF_ENDIAN_LITTLE;
|
||||
//opts->wav_out_f = sf_open (opts->wav_out_file, SFM_WRITE, &info);
|
||||
opts->wav_out_fR = sf_open (opts->wav_out_fileR, SFM_RDWR, &info); //RDWR will append to file instead of overwrite file
|
||||
|
||||
if (opts->wav_out_f == NULL)
|
||||
{
|
||||
fprintf (stderr,"Error - could not open wav output file %s\n", opts->wav_out_fileR);
|
||||
return;
|
||||
}
|
||||
|
||||
// state->wav_out_bytes = 0;
|
||||
|
||||
}
|
||||
|
||||
void openWavOutFileRaw (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
|
||||
SF_INFO info;
|
||||
info.samplerate = 48000; //8000
|
||||
info.channels = 1;
|
||||
info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 | SF_ENDIAN_LITTLE;
|
||||
//opts->wav_out_f = sf_open (opts->wav_out_file, SFM_WRITE, &info);
|
||||
//opts->wav_out_f = sf_open (opts->wav_out_file, SFM_RDWR, &info); //RDWR will append to file instead of overwrite file
|
||||
opts->wav_out_raw = sf_open (opts->wav_out_file_raw, SFM_RDWR, &info);
|
||||
if (opts->wav_out_raw == NULL)
|
||||
{
|
||||
fprintf (stderr,"Error - could not open raw wav output file %s\n", opts->wav_out_file_raw);
|
||||
return;
|
||||
}
|
||||
|
||||
// state->wav_out_bytes = 0;
|
||||
|
||||
}
|
||||
|
||||
void closeWavOutFile (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
sf_close(opts->wav_out_f);
|
||||
|
||||
/*
|
||||
int length;
|
||||
|
||||
if (opts->wav_out_f != NULL)
|
||||
{
|
||||
rewind (opts->wav_out_f);
|
||||
length = state->wav_out_bytes;
|
||||
|
||||
fprintf (stderr,opts->wav_out_f, "RIFF");
|
||||
// total length
|
||||
fputc (((36 + length) & 0xff), opts->≈≈);
|
||||
fputc ((((36 + length) >> 8) & 0xff), opts->wav_out_f);
|
||||
fputc ((((36 + length) >> 16) & 0xff), opts->wav_out_f);
|
||||
fputc ((((36 + length) >> 24) & 0xff), opts->wav_out_f);
|
||||
|
||||
fprintf (stderr,opts->wav_out_f, "WAVE");
|
||||
fprintf (stderr,opts->wav_out_f, "fmt ");
|
||||
|
||||
// length of format chunk
|
||||
fputc (16, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
|
||||
// always 0x1
|
||||
fputc (1, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
|
||||
// channels
|
||||
fputc (1, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
|
||||
// sample rate
|
||||
fputc (64, opts->wav_out_f);
|
||||
fputc (31, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
|
||||
// bytes per second
|
||||
fputc (128, opts->wav_out_f);
|
||||
fputc (62, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
|
||||
// block align
|
||||
fputc (2, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
|
||||
// bits/sample
|
||||
fputc (16, opts->wav_out_f);
|
||||
fputc (0, opts->wav_out_f);
|
||||
|
||||
// data chunk header
|
||||
fprintf (stderr,opts->wav_out_f, "data");
|
||||
|
||||
// length of data
|
||||
fputc ((length & 0xff), opts->wav_out_f);
|
||||
fputc (((length >> 8) & 0xff), opts->wav_out_f);
|
||||
fputc (((length >> 16) & 0xff), opts->wav_out_f);
|
||||
fputc (((length >> 24) & 0xff), opts->wav_out_f);
|
||||
|
||||
fflush (opts->wav_out_f);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void closeWavOutFileL (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
sf_close(opts->wav_out_f);
|
||||
}
|
||||
|
||||
void closeWavOutFileR (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
sf_close(opts->wav_out_fR);
|
||||
}
|
||||
|
||||
void closeWavOutFileRaw (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
sf_close(opts->wav_out_raw);
|
||||
}
|
||||
|
||||
void openSymbolOutFile (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
//Do something
|
||||
opts->symbol_out_f = fopen (opts->symbol_out_file, "w");
|
||||
}
|
||||
|
||||
void writeSymbolOutFile (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
//Do something
|
||||
|
||||
}
|
||||
|
||||
void closeSymbolOutFile (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
//Do something
|
||||
if (opts->symbol_out == 1)
|
||||
{
|
||||
if (opts->symbol_out_file != NULL) //check first, or issuing a second fclose will crash the SOFTWARE
|
||||
{
|
||||
fclose(opts->symbol_out_f); //free(): double free detected in tcache 2 (this is a new one) happens when closing more than once
|
||||
//noCarrier(opts, state); //free(): double free detected in tcache 2 (this is a new one)
|
||||
}
|
||||
|
||||
opts->symbol_out = 0; //set flag to 1
|
||||
//sprintf (opts->symbol_out_file, "fme-capture.bin"); //use fme for the symbol bin ext
|
||||
//openSymbolOutFile (opts, state);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -105,6 +105,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
sprintf (state->fsubtype, " VOICE ");
|
||||
processNXDNVoice (opts, state);
|
||||
//ProcessNXDNFrame (opts, state, 0);
|
||||
return;
|
||||
}
|
||||
else if ((state->synctype == 16) || (state->synctype == 17)) //NXDN Data
|
||||
@@ -128,6 +129,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
sprintf (state->fsubtype, " DATA ");
|
||||
processNXDNData (opts, state);
|
||||
//ProcessNXDNFrame (opts, state, 0);
|
||||
return;
|
||||
}
|
||||
else if ((state->synctype == 6) || (state->synctype == 7))
|
||||
@@ -233,6 +235,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
if (opts->dmr_stereo == 1)
|
||||
{
|
||||
dmrMSData (opts, state);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -243,6 +246,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
state->err_str[0] = 0;
|
||||
sprintf (state->slot1light, " slot1 ");
|
||||
sprintf (state->slot2light, " slot2 ");
|
||||
state->payload_miP = 0; //zero out when switching back to data sync
|
||||
processDMRdata (opts, state);
|
||||
}
|
||||
//switch dmr_stereo to 0 when handling BS data frame syncs with processDMRdata
|
||||
@@ -251,6 +255,7 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
state->dmr_stereo = 0; //set the state to zero for handling pure data frames
|
||||
sprintf (state->slot1light, " slot1 ");
|
||||
sprintf (state->slot2light, " slot2 ");
|
||||
state->payload_miP = 0; //zero out when switching back to data sync
|
||||
processDMRdata (opts, state);
|
||||
}
|
||||
}
|
||||
@@ -314,6 +319,19 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
processYSF(opts, state);
|
||||
return;
|
||||
}
|
||||
//P25 P2
|
||||
else if ((state->synctype == 35) || (state->synctype == 36))
|
||||
{
|
||||
//Do stuff
|
||||
//fprintf(stderr, "YSF Sync! \n");
|
||||
if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL))
|
||||
{
|
||||
//openMbeOutFile (opts, state);
|
||||
}
|
||||
//sprintf(state->fsubtype, " VOICE ");
|
||||
processP2(opts, state);
|
||||
return;
|
||||
}
|
||||
//dPMR
|
||||
else if ((state->synctype == 20) || (state->synctype == 24))
|
||||
{
|
||||
@@ -481,6 +499,12 @@ processFrame (dsd_opts * opts, dsd_state * state)
|
||||
state->lastp25type = 1;
|
||||
sprintf (state->fsubtype, " LDU1 ");
|
||||
state->numtdulc = 0;
|
||||
if (state->payload_algid == 0x81)
|
||||
{
|
||||
fprintf (stderr, "\n");
|
||||
//LFSRP (state); //HERE HERE best placement?
|
||||
}
|
||||
|
||||
processLDU1 (opts, state);
|
||||
}
|
||||
else if (strcmp (duid, "22") == 0)
|
||||
|
||||
@@ -144,12 +144,15 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
* 32 = DMR MS Voice
|
||||
* 33 = DMR MS Data
|
||||
* 34 = DMR RC Data
|
||||
* 35 = +P25 P2
|
||||
* 36 = -P25 P2
|
||||
*/
|
||||
|
||||
|
||||
int i, j, t, o, dibit, sync, symbol, synctest_pos, lastt;
|
||||
char synctest[25];
|
||||
char synctest12[13]; //dPMR
|
||||
char synctest10[11];
|
||||
char synctest18[19];
|
||||
char synctest32[33];
|
||||
char synctest20[21]; //YSF
|
||||
@@ -269,6 +272,22 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
dibit = 51; // '3'
|
||||
}
|
||||
|
||||
//this is needed to capture dibits and convert them to appropriate format for a symbol bin
|
||||
if (opts->symbol_out == 1 && symbol != 0) //is 0 a valid symbol from dsd? //&& symbol != 0
|
||||
{
|
||||
int csymbol = 0;
|
||||
if (dibit == 49)
|
||||
{
|
||||
csymbol = 1; //1
|
||||
}
|
||||
if (dibit == 51)
|
||||
{
|
||||
csymbol = 3; //3
|
||||
}
|
||||
//fprintf (stderr, "%d", dibit);
|
||||
fputc (csymbol, opts->symbol_out_f);
|
||||
}
|
||||
|
||||
//digitize test for storing dibits in buffer correctly for dmr recovery
|
||||
|
||||
if (state->dmr_payload_p > state->dmr_payload_buf + 900000)
|
||||
@@ -597,6 +616,52 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
}
|
||||
//end YSF sync
|
||||
//P25 P2 sync
|
||||
strncpy(synctest20, (synctest_p - 19), 20); //double check make sure this is right
|
||||
if(opts->frame_p25p2 == 1) //(opts->frame_ysf == 1
|
||||
{
|
||||
if (0 == 0) //opts->inverted_ysf == 0
|
||||
{
|
||||
if (strcmp(synctest20, P25P2_SYNC) == 0)
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
state->max = ((state->max) + lmax) / 2;
|
||||
state->min = ((state->min) + lmin) / 2;
|
||||
fprintf (stderr, "\n+P25-P2 Sync");
|
||||
opts->inverted_ysf = 0; //should we set this here?
|
||||
state->lastsynctype = 30;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (35);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(opts->frame_p25p2 == 1) //(opts->frame_p25p2 == 1
|
||||
{
|
||||
if (0 == 0) //inverted p25
|
||||
{
|
||||
if (strcmp(synctest20, INV_P25P2_SYNC) == 0)
|
||||
{
|
||||
state->carrier = 1;
|
||||
state->offset = synctest_pos;
|
||||
state->max = ((state->max) + lmax) / 2;
|
||||
state->min = ((state->min) + lmin) / 2;
|
||||
fprintf (stderr, "\n-P25-P2 Sync");
|
||||
opts->inverted_ysf = 1; //should we set this here?
|
||||
state->lastsynctype = 31;
|
||||
if ( opts->monitor_input_audio == 1)
|
||||
{
|
||||
|
||||
pa_simple_flush(opts->pulse_raw_dev_out, NULL);
|
||||
}
|
||||
return (36);
|
||||
}
|
||||
}
|
||||
}
|
||||
//dPMR sync
|
||||
strncpy(synctest, (synctest_p - 23), 24);
|
||||
strncpy(synctest12, (synctest_p - 11), 12);
|
||||
@@ -1093,6 +1158,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ((opts->frame_nxdn96 == 1) || (opts->frame_nxdn48 == 1))
|
||||
{
|
||||
strncpy (synctest18, (synctest_p - 17), 18);
|
||||
|
||||
440
src/dsd_main.c
440
src/dsd_main.c
@@ -43,20 +43,19 @@ int pretty_colors()
|
||||
|
||||
#include "p25p1_heuristics.h"
|
||||
#include "pa_devs.h"
|
||||
short int butt = 1;
|
||||
short int butt = 0;
|
||||
|
||||
char * FM_banner[9] = {
|
||||
" 2022 Dove Award Winner CTRL + C twice to exit",
|
||||
" ",
|
||||
" ██████╗ ██████╗██████╗ ███████╗███╗ ███╗███████╗",
|
||||
" ██╔══██╗██╔════╝██╔══██╗ ██╔════╝████╗ ████║██╔════╝",
|
||||
" ██║ ██║╚█████╗ ██║ ██║ █████╗ ██╔████╔██║█████╗ ",
|
||||
" ██║ ██║ ╚═══██╗██║ ██║ ██╔══╝ ██║╚██╔╝██║██╔══╝ ",
|
||||
" ██████╔╝██████╔╝██████╔╝ ██║ ██║ ╚═╝ ██║███████╗",
|
||||
" ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚══════╝",
|
||||
"https://github.com/lwvmobile/dsd-fme/tree/pulseaudio "
|
||||
" https://github.com/lwvmobile/dsd-fme/tree/pulseaudio "
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
comp (const void *a, const void *b)
|
||||
{
|
||||
@@ -74,6 +73,7 @@ struct stat st = {0};
|
||||
void
|
||||
noCarrier (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
// state->testcounter = 0;
|
||||
state->dibit_buf_p = state->dibit_buf + 200;
|
||||
memset (state->dibit_buf, 0, sizeof (int) * 200);
|
||||
//dmr buffer
|
||||
@@ -133,8 +133,6 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
||||
mbe_initMbeParms (state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2);
|
||||
|
||||
state->dmr_ms_mode = 0;
|
||||
state->dropL = 256; //drop it like its hot
|
||||
state->dropR = 256; //drop it like its hot
|
||||
|
||||
//not sure if desirable here or not just yet, may need to disable a few of these
|
||||
state->payload_mi = 0;
|
||||
@@ -145,12 +143,46 @@ noCarrier (dsd_opts * opts, dsd_state * state)
|
||||
state->payload_algidR = 0;
|
||||
state->payload_keyid = 0;
|
||||
state->payload_keyidR = 0;
|
||||
//just for a test
|
||||
if (state->M == 0)
|
||||
|
||||
state->payload_miN = 0;
|
||||
state->p25vc = 0;
|
||||
state->payload_miP = 0;
|
||||
|
||||
//initialize dmr data header source
|
||||
state->dmr_lrrp_source[0] = 0;
|
||||
state->dmr_lrrp_source[1] = 0;
|
||||
|
||||
//initialize 12 rate superframe
|
||||
for (short i = 0; i < 84; i++)
|
||||
{
|
||||
state->K = 0;
|
||||
state->dmr_12_rate_sf[0][i] = 0;
|
||||
state->dmr_12_rate_sf[1][i] = 0;
|
||||
}
|
||||
|
||||
//initialize 34 rate superframe
|
||||
for (short i = 0; i < 96; i++)
|
||||
{
|
||||
state->dmr_34_rate_sf[0][i] = 0;
|
||||
state->dmr_34_rate_sf[1][i] = 0;
|
||||
}
|
||||
|
||||
//initialize data header bits
|
||||
state->data_header_blocks[0] = 1; //initialize with 1, otherwise we may end up segfaulting when no/bad data header
|
||||
state->data_header_blocks[1] = 1; //when trying to fill the superframe and 0-1 blocks give us an overflow
|
||||
state->data_header_padding[0] = 0;
|
||||
state->data_header_padding[1] = 0;
|
||||
state->data_header_format[0] = 0;
|
||||
state->data_header_format[1] = 0;
|
||||
state->data_header_sap[0] = 0;
|
||||
state->data_header_sap[1] = 0;
|
||||
state->data_block_counter[0] = 0;
|
||||
state->data_block_counter[1] = 0;
|
||||
state->data_p_head[0] = 0;
|
||||
state->data_p_head[1] = 0;
|
||||
|
||||
state->dmr_so = 0;
|
||||
state->dmr_soR = 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@@ -172,15 +204,15 @@ initOpts (dsd_opts * opts)
|
||||
//sprintf (opts->audio_in_dev, "/dev/audio");
|
||||
sprintf (opts->audio_in_dev, "pulse");
|
||||
opts->audio_in_fd = -1;
|
||||
#ifdef USE_PORTAUDIO
|
||||
opts->audio_in_pa_stream = NULL;
|
||||
#endif
|
||||
// #ifdef USE_PORTAUDIO
|
||||
// opts->audio_in_pa_stream = NULL;
|
||||
// #endif
|
||||
//sprintf (opts->audio_out_dev, "/dev/audio");
|
||||
sprintf (opts->audio_out_dev, "pulse");
|
||||
opts->audio_out_fd = -1;
|
||||
#ifdef USE_PORTAUDIO
|
||||
opts->audio_out_pa_stream = NULL;
|
||||
#endif
|
||||
// #ifdef USE_PORTAUDIO
|
||||
// opts->audio_out_pa_stream = NULL;
|
||||
// #endif
|
||||
opts->split = 0;
|
||||
opts->playoffset = 0;
|
||||
opts->playoffsetR = 0;
|
||||
@@ -192,7 +224,16 @@ initOpts (dsd_opts * opts)
|
||||
opts->audio_gainR = 0;
|
||||
opts->audio_out = 1;
|
||||
opts->wav_out_file[0] = 0;
|
||||
opts->wav_out_fileR[0] = 0;
|
||||
opts->wav_out_file_raw[0] = 0;
|
||||
opts->symbol_out_file[0] = 0;
|
||||
opts->symbol_out_f = NULL;
|
||||
opts->symbol_out = 0;
|
||||
opts->wav_out_f = NULL;
|
||||
opts->wav_out_fR = NULL;
|
||||
opts->wav_out_raw = NULL;
|
||||
|
||||
opts->dmr_stereo_wav = 0; //flag for per call dmr stereo wav recordings
|
||||
//opts->wav_out_fd = -1;
|
||||
opts->serial_baud = 115200;
|
||||
sprintf (opts->serial_dev, "/dev/ttyUSB0");
|
||||
@@ -200,6 +241,7 @@ initOpts (dsd_opts * opts)
|
||||
opts->frame_dstar = 1;
|
||||
opts->frame_x2tdma = 1;
|
||||
opts->frame_p25p1 = 1;
|
||||
opts->frame_p25p2 = 0;
|
||||
opts->frame_nxdn48 = 0;
|
||||
opts->frame_nxdn96 = 0;
|
||||
opts->frame_dmr = 1;
|
||||
@@ -225,10 +267,11 @@ initOpts (dsd_opts * opts)
|
||||
opts->rtl_udp_port = 6020; //set UDP port for RTL remote
|
||||
opts->rtl_bandwidth = 12; //changed recommended default to 12, 24 for ProVoice
|
||||
opts->rtlsdr_ppm_error = 0; //initialize ppm with 0 value; bug reported by N.
|
||||
opts->rtl_started = 0;
|
||||
opts->pulse_raw_rate_in = 48000;
|
||||
opts->pulse_raw_rate_out = 48000; //doing tests with 2 channels at 24000 for 48000 audio default in pulse
|
||||
opts->pulse_raw_rate_out = 48000; //
|
||||
opts->pulse_digi_rate_in = 48000;
|
||||
opts->pulse_digi_rate_out = 48000; //need to copy this to rtl type in and change rate out to 8000
|
||||
opts->pulse_digi_rate_out = 8000; // reverted to 8/1, crisper sound, dmr stereo will switch to 24/2
|
||||
opts->pulse_raw_in_channels = 1;
|
||||
opts->pulse_raw_out_channels = 1;
|
||||
opts->pulse_digi_in_channels = 1; //2
|
||||
@@ -237,9 +280,9 @@ initOpts (dsd_opts * opts)
|
||||
sprintf (opts->output_name, "Auto Detect");
|
||||
opts->pulse_flush = 1; //set 0 to flush, 1 for flushed
|
||||
opts->use_ncurses_terminal = 0;
|
||||
opts->ncurses_compact = 0;
|
||||
opts->ncurses_history = 1;
|
||||
opts->payload = 0;
|
||||
|
||||
opts->EncryptionMode = MODE_UNENCRYPTED;
|
||||
opts->inverted_dpmr = 0;
|
||||
opts->dmr_stereo = 0;
|
||||
opts->aggressive_framesync = 1; //more aggressive to combat wonk wonk voice decoding
|
||||
@@ -247,6 +290,8 @@ initOpts (dsd_opts * opts)
|
||||
opts->audio_in_type = 0; //this was never initialized, causes issues on rPI 64 (bullseye) if not initialized
|
||||
opts->audio_out_type = 0; //this was never initialized, causes issues on rPI 64 (bullseye) if not initialized
|
||||
|
||||
opts->lrrp_file_output = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -255,6 +300,7 @@ initState (dsd_state * state)
|
||||
{
|
||||
|
||||
int i, j;
|
||||
// state->testcounter = 0;
|
||||
state->last_dibit = 0;
|
||||
state->dibit_buf = malloc (sizeof (int) * 1000000);
|
||||
state->dibit_buf_p = state->dibit_buf + 200;
|
||||
@@ -313,6 +359,7 @@ initState (dsd_state * state)
|
||||
sprintf (state->fsubtype, " ");
|
||||
sprintf (state->ftype, " ");
|
||||
state->symbolcnt = 0;
|
||||
state->symbolc = 0; //
|
||||
state->rf_mod = 0;
|
||||
state->numflips = 0;
|
||||
state->lastsynctype = -1;
|
||||
@@ -377,6 +424,7 @@ initState (dsd_state * state)
|
||||
state->nxdn_cipher_type = 0;
|
||||
state->nxdn_key = 0;
|
||||
sprintf (state->nxdn_call_type, " ");
|
||||
state->payload_miN = 0;
|
||||
|
||||
state->dpmr_color_code = -1;
|
||||
state->dpmr_caller_id = 0;
|
||||
@@ -419,7 +467,7 @@ initState (dsd_state * state)
|
||||
|
||||
state->K = 0;
|
||||
state->R = 0;
|
||||
state->M = 0;
|
||||
|
||||
state->dmr_stereo = 0;
|
||||
state->dmrburstL = 17; //initialize at higher value than possible
|
||||
state->dmrburstR = 17; //17 in char array is set for ERR
|
||||
@@ -429,11 +477,46 @@ initState (dsd_state * state)
|
||||
state->dmr_fidR = 0;
|
||||
state->dmr_ms_mode = 0;
|
||||
|
||||
state->dropL = 256; //drop it like its hot
|
||||
state->dropR = 256; //drop it like its hot
|
||||
state->p25vc = 0;
|
||||
|
||||
state->payload_miP = 0;
|
||||
|
||||
memset(state->dstarradioheader, 0, 41);
|
||||
|
||||
//initialize dmr data header source
|
||||
state->dmr_lrrp_source[0] = 0;
|
||||
state->dmr_lrrp_source[1] = 0;
|
||||
|
||||
//initialize 12 rate superframe
|
||||
for (short i = 0; i < 84; i++)
|
||||
{
|
||||
state->dmr_12_rate_sf[0][i] = 0;
|
||||
state->dmr_12_rate_sf[1][i] = 0;
|
||||
}
|
||||
|
||||
//initialize 34 rate superframe
|
||||
for (short i = 0; i < 96; i++)
|
||||
{
|
||||
state->dmr_34_rate_sf[0][i] = 0;
|
||||
state->dmr_34_rate_sf[1][i] = 0;
|
||||
}
|
||||
|
||||
//initialize data header bits
|
||||
state->data_header_blocks[0] = 1; //initialize with 1, otherwise we may end up segfaulting when no/bad data header
|
||||
state->data_header_blocks[1] = 1; //when trying to fill the superframe and 0-1 blocks give us an overflow
|
||||
state->data_header_padding[0] = 0;
|
||||
state->data_header_padding[1] = 0;
|
||||
state->data_header_format[0] = 0;
|
||||
state->data_header_format[1] = 0;
|
||||
state->data_header_sap[0] = 0;
|
||||
state->data_header_sap[1] = 0;
|
||||
state->data_block_counter[0] = 0;
|
||||
state->data_block_counter[1] = 0;
|
||||
state->data_p_head[0] = 0;
|
||||
state->data_p_head[1] = 0;
|
||||
|
||||
state->menuopen = 0; //is the ncurses menu open, if so, don't process frame sync
|
||||
|
||||
#ifdef TRACE_DSD
|
||||
state->debug_sample_index = 0;
|
||||
state->debug_label_file = NULL;
|
||||
@@ -447,14 +530,15 @@ initState (dsd_state * state)
|
||||
void
|
||||
usage ()
|
||||
{
|
||||
//printf ( "Github Build Version: %s \n", GIT_TAG);
|
||||
//printf ( "2022 Dove Award Recipient"); //Thanks, Scott
|
||||
|
||||
printf ("\n");
|
||||
printf ("Usage: dsd [options] Live scanner mode\n");
|
||||
printf (" or: dsd [options] -r <files> Read/Play saved mbe data from file(s)\n");
|
||||
printf (" or: dsd -h Show help\n");
|
||||
printf ("Usage: dsd-fme [options] Live scanner mode\n");
|
||||
printf (" or: dsd-fme [options] -r <files> Read/Play saved mbe data from file(s)\n");
|
||||
printf (" or: dsd-fme -h Show help\n");
|
||||
printf ("\n");
|
||||
printf ("Display Options:\n");
|
||||
printf (" -N Use NCurses Terminal\n");
|
||||
printf (" -use with 2> log.txt at end of command\n");
|
||||
printf (" -e Show Frame Info and errorbars (default)\n");
|
||||
printf (" -pe Show P25 encryption sync bits\n");
|
||||
printf (" -pl Show P25 link control bits\n");
|
||||
@@ -474,7 +558,7 @@ usage ()
|
||||
printf (" -g <num> Audio output gain (default = 0 = auto, disable = -1)\n");
|
||||
printf (" -w <file> Output synthesized speech to a .wav file\n");
|
||||
//printf (" -a Display port audio devices\n");
|
||||
printf (" -W Monitor Source Audio When No Sync Detected (WIP!)\n");
|
||||
//printf (" -W Monitor Source Audio When No Sync Detected (WIP!)\n");
|
||||
printf ("\n");
|
||||
printf ("RTL-SDR options:\n");
|
||||
printf (" -c <hertz> RTL-SDR Frequency\n");
|
||||
@@ -495,43 +579,38 @@ usage ()
|
||||
printf (" -fa Auto-detect frame type (default)\n");
|
||||
printf (" -f1 Decode only P25 Phase 1\n");
|
||||
printf (" -fd Decode only D-STAR\n");
|
||||
printf (" -fr Decode only DMR/MOTOTRBO\n");
|
||||
printf (" -fr Decode only DMR\n");
|
||||
printf (" -fx Decode only X2-TDMA\n");
|
||||
printf (" -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n");
|
||||
printf (" -fn Decode only NXDN96* (12.5 kHz)\n");
|
||||
printf (" -fp Decode only ProVoice*\n");
|
||||
printf (" -fm Decode only dPMR*\n");
|
||||
printf (" -l Disable DMR/MOTOTRBO and NXDN input filtering\n");
|
||||
printf (" -ma Auto-select modulation optimizations (default)\n");
|
||||
printf (" -mc Use only C4FM modulation optimizations\n");
|
||||
printf (" -mg Use only GFSK modulation optimizations\n");
|
||||
printf (" -mq Use only QPSK modulation optimizations\n");
|
||||
printf (" -l Disable DMR and NXDN input filtering\n");
|
||||
printf (" -pu Unmute Encrypted P25\n");
|
||||
printf (" -u <num> Unvoiced speech quality (default=3)\n");
|
||||
printf (" -xx Expect non-inverted X2-TDMA signal\n");
|
||||
printf (" -xr Expect inverted DMR/MOTOTRBO signal\n");
|
||||
printf (" -xr Expect inverted DMR signal\n");
|
||||
printf (" -xd Expect inverted ICOM dPMR signal\n"); //still need to do this
|
||||
printf ("\n");
|
||||
printf (" * denotes frame types that cannot be auto-detected.\n");
|
||||
printf ("\n");
|
||||
printf ("Advanced decoder options:\n");
|
||||
printf (" -A <num> QPSK modulation auto detection threshold (default=26)\n");
|
||||
printf ("Advanced Decoder options:\n");
|
||||
// printf (" -A <num> QPSK modulation auto detection threshold (default=26)\n");
|
||||
printf (" -S <num> Symbol buffer size for QPSK decision point tracking\n");
|
||||
printf (" (default=36)\n");
|
||||
printf (" -M <num> Min/Max buffer size for QPSK decision point tracking\n");
|
||||
printf (" (default=15)\n");
|
||||
printf (" -n Reset P25 Heuristics and initState variables on mixed signal decoding\n");
|
||||
printf (" Helps when decoding mixed signal types (P25P1) at same time\n");
|
||||
printf (" (WiP! May Cause Slow Memory Leak or System Hang - Experimental)\n");
|
||||
// printf (" -n Reset P25 Heuristics and initState variables on mixed signal decoding\n");
|
||||
// printf (" Helps when decoding mixed signal types (P25P1) at same time\n");
|
||||
// printf (" (WiP! May Cause Slow Memory Leak or System Hang - Experimental)\n");
|
||||
printf (" -T Enable DMR TDMA Stereo Voice (Two Slot Dual Voices)\n");
|
||||
printf (" This feature will open two streams for slot 1 voice and slot 2 voice\n");
|
||||
printf (" May Cause Skipping or sync issues if bad signal/errors\n");
|
||||
printf (" -F Enable DMR TDMA Stereo Passive Frame Sync\n");
|
||||
printf (" This feature will attempt to resync less often due to excessive voice errors\n");
|
||||
printf (" Use if skipping occurs, but may cause wonky audio due to loss of good sync\n");
|
||||
printf (" -Z Log MBE Payload to console\n");
|
||||
printf (" -Z Log MBE/Frame Payloads to console\n");
|
||||
printf ("\n");
|
||||
printf ("Report bugs to: https://github.com/lwvmobile/dsd-fme/issues \n");
|
||||
exit (0);
|
||||
}
|
||||
|
||||
@@ -539,8 +618,6 @@ void
|
||||
liveScanner (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
|
||||
//still need this section mostly due the the crackling on the rtl dongle when upsampled
|
||||
//probably need to dig a little deeper, maybe inlvl releated?
|
||||
if (opts->audio_in_type == 1)
|
||||
{
|
||||
opts->pulse_digi_rate_out = 8000; //revert to 8K/1 for STDIN input, sometimes crackles when upsampling
|
||||
@@ -557,19 +634,6 @@ if (opts->audio_in_type == 1)
|
||||
|
||||
}
|
||||
|
||||
#ifdef USE_PORTAUDIO
|
||||
if(opts->audio_in_type == 2)
|
||||
{
|
||||
PaError err = Pa_StartStream( opts->audio_in_pa_stream );
|
||||
if( err != paNoError )
|
||||
{
|
||||
//fprintf (stderr, "An error occured while starting the portaudio input stream\n" );
|
||||
//fprintf (stderr, "Error number: %d\n", err );
|
||||
//fprintf (stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_RTLSDR
|
||||
if(opts->audio_in_type == 3)
|
||||
{
|
||||
@@ -588,28 +652,38 @@ if (opts->audio_in_type == 1)
|
||||
opts->pulse_raw_out_channels = 1;
|
||||
|
||||
open_rtlsdr_stream(opts);
|
||||
opts->rtl_started = 1; //set here so ncurses terminal doesn't attempt to open it again
|
||||
}
|
||||
#endif
|
||||
|
||||
if (opts->use_ncurses_terminal == 1)
|
||||
{
|
||||
ncursesOpen(opts, state);
|
||||
}
|
||||
|
||||
if (opts->audio_in_type == 0)
|
||||
{
|
||||
openPulseInput(opts);
|
||||
}
|
||||
|
||||
if (opts->audio_out_type == 0)
|
||||
{
|
||||
openPulseOutput(opts);
|
||||
}
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
noCarrier (opts, state);
|
||||
if (state->menuopen == 0)
|
||||
{
|
||||
state->synctype = getFrameSync (opts, state);
|
||||
// recalibrate center/umid/lmid
|
||||
state->center = ((state->max) + (state->min)) / 2;
|
||||
state->umid = (((state->max) - state->center) * 5 / 8) + state->center;
|
||||
state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
|
||||
}
|
||||
|
||||
state->synctype = getFrameSync (opts, state);
|
||||
// recalibrate center/umid/lmid
|
||||
state->center = ((state->max) + (state->min)) / 2;
|
||||
state->umid = (((state->max) - state->center) * 5 / 8) + state->center;
|
||||
state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
|
||||
|
||||
|
||||
while (state->synctype != -1)
|
||||
@@ -620,16 +694,24 @@ if (opts->audio_out_type == 0)
|
||||
state->debug_prefix = 'S';
|
||||
#endif
|
||||
|
||||
state->synctype = getFrameSync (opts, state);
|
||||
// state->synctype = getFrameSync (opts, state);
|
||||
|
||||
#ifdef TRACE_DSD
|
||||
state->debug_prefix = '\0';
|
||||
#endif
|
||||
|
||||
// recalibrate center/umid/lmid
|
||||
state->center = ((state->max) + (state->min)) / 2;
|
||||
state->umid = (((state->max) - state->center) * 5 / 8) + state->center;
|
||||
state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
|
||||
// // recalibrate center/umid/lmid
|
||||
// state->center = ((state->max) + (state->min)) / 2;
|
||||
// state->umid = (((state->max) - state->center) * 5 / 8) + state->center;
|
||||
// state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
|
||||
if (state->menuopen == 0)
|
||||
{
|
||||
state->synctype = getFrameSync (opts, state);
|
||||
// recalibrate center/umid/lmid
|
||||
state->center = ((state->max) + (state->min)) / 2;
|
||||
state->umid = (((state->max) - state->center) * 5 / 8) + state->center;
|
||||
state->lmid = (((state->min) - state->center) * 5 / 8) + state->center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -639,59 +721,33 @@ cleanupAndExit (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
noCarrier (opts, state);
|
||||
if (opts->wav_out_f != NULL)
|
||||
{
|
||||
closeWavOutFile (opts, state);
|
||||
}
|
||||
|
||||
#ifdef USE_PORTAUDIO
|
||||
if((opts->audio_in_type == 2) || (opts->audio_out_type == 2))
|
||||
{
|
||||
fprintf (stderr,"Terminating portaudio.\n");
|
||||
PaError err = paNoError;
|
||||
if(opts->audio_in_pa_stream != NULL)
|
||||
{
|
||||
err = Pa_CloseStream( opts->audio_in_pa_stream );
|
||||
if( err != paNoError )
|
||||
{
|
||||
//fprintf (stderr, "An error occured while closing the portaudio input stream\n" );
|
||||
//fprintf (stderr, "Error number: %d\n", err );
|
||||
//fprintf (stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
}
|
||||
}
|
||||
if(opts->audio_out_pa_stream != NULL)
|
||||
{
|
||||
err = Pa_IsStreamActive( opts->audio_out_pa_stream );
|
||||
if(err == 1)
|
||||
err = Pa_StopStream( opts->audio_out_pa_stream );
|
||||
if( err != paNoError )
|
||||
{
|
||||
//fprintf (stderr, "An error occured while closing the portaudio output stream\n" );
|
||||
//fprintf (stderr, "Error number: %d\n", err );
|
||||
//fprintf (stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
}
|
||||
err = Pa_CloseStream( opts->audio_out_pa_stream );
|
||||
if( err != paNoError )
|
||||
{
|
||||
//fprintf (stderr, "An error occured while closing the portaudio output stream\n" );
|
||||
//fprintf (stderr, "Error number: %d\n", err );
|
||||
//fprintf (stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
}
|
||||
}
|
||||
err = Pa_Terminate();
|
||||
if( err != paNoError )
|
||||
{
|
||||
//fprintf (stderr, "An error occured while terminating portaudio\n" );
|
||||
//fprintf (stderr, "Error number: %d\n", err );
|
||||
//fprintf (stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
{
|
||||
closeWavOutFile (opts, state);
|
||||
}
|
||||
if (opts->wav_out_raw != NULL)
|
||||
{
|
||||
closeWavOutFileRaw (opts, state);
|
||||
}
|
||||
if (opts->dmr_stereo_wav == 1)
|
||||
{
|
||||
closeWavOutFileL (opts, state);
|
||||
closeWavOutFileR (opts, state);
|
||||
}
|
||||
if (opts->symbol_out == 1)
|
||||
{
|
||||
closeSymbolOutFile (opts, state);
|
||||
}
|
||||
if (opts->mbe_out_f != NULL)
|
||||
{
|
||||
closeMbeOutFile (opts, state);
|
||||
}
|
||||
|
||||
#ifdef USE_RTLSDR
|
||||
if(opts->audio_in_type == 3)
|
||||
{
|
||||
// TODO: cleanup demod threads
|
||||
cleanup_rtlsdr_stream();
|
||||
//temp disable to see if this corrects issues with closing
|
||||
//cleanup_rtlsdr_stream();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -775,15 +831,15 @@ main (int argc, char **argv)
|
||||
char versionstr[25];
|
||||
mbe_printVersion (versionstr);
|
||||
|
||||
|
||||
for (short int i = 0; i < 7; i++) {
|
||||
fprintf (stderr,"%s%s \n", FM_banner[i], KCYN); //cyan/blue text
|
||||
fprintf (stderr," Digital Speech Decoder: Florida Man Edition\n");
|
||||
for (short int i = 1; i < 7; i++) {
|
||||
//fprintf (stderr,"%s%s \n", FM_banner[i], KGRN); //cyan/blue text
|
||||
fprintf (stderr,"%s\n", FM_banner[i]); //cyan/blue tex
|
||||
}
|
||||
fprintf (stderr,"%s", KNRM); //change back to normal
|
||||
fprintf (stderr, "%s \n", FM_banner[7]);
|
||||
fprintf (stderr,"Digital Speech Decoder: Florida Man Edition\n");
|
||||
//fprintf (stderr,"%s", KNRM); //change back to normal
|
||||
|
||||
fprintf (stderr, "Github Build Version: %s \n", GIT_TAG);
|
||||
fprintf (stderr,"mbelib version %s\n", versionstr);
|
||||
fprintf (stderr,"MBElib version %s\n", versionstr);
|
||||
|
||||
initOpts (&opts);
|
||||
initState (&state);
|
||||
@@ -793,7 +849,7 @@ main (int argc, char **argv)
|
||||
exitflag = 0;
|
||||
signal (SIGINT, sigfun);
|
||||
|
||||
while ((c = getopt (argc, argv, "haep:P:qstv:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:Y:K:NWrlZTF")) != -1)
|
||||
while ((c = getopt (argc, argv, "haep:P:qstv:z:i:o:d:c:g:nw:B:C:R:f:m:u:x:A:S:M:G:D:L:V:U:Y:K:NQWrlZTF")) != -1)
|
||||
{
|
||||
opterr = 0;
|
||||
switch (c)
|
||||
@@ -802,7 +858,7 @@ main (int argc, char **argv)
|
||||
usage ();
|
||||
exit (0);
|
||||
case 'a':
|
||||
printPortAudioDevices();
|
||||
//printPortAudioDevices();
|
||||
exit(0);
|
||||
case 'e':
|
||||
opts.errorbars = 1;
|
||||
@@ -832,7 +888,8 @@ main (int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case 'P':
|
||||
sscanf (optarg, "%i", &opts.rtlsdr_ppm_error);
|
||||
//can't handle negative numbers?
|
||||
//sscanf (optarg, "%d", &opts.rtlsdr_ppm_error);
|
||||
break;
|
||||
case 'q':
|
||||
opts.errorbars = 0;
|
||||
@@ -858,17 +915,12 @@ main (int argc, char **argv)
|
||||
|
||||
case 'K':
|
||||
sscanf (optarg, "%lld", &state.K);
|
||||
state.M = 1;
|
||||
if (state.K > 256)
|
||||
{
|
||||
state.K = 256;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
sscanf (optarg, "%lld", &state.R);
|
||||
break;
|
||||
|
||||
case 'G': //Set rtl device gain
|
||||
sscanf (optarg, "%d", &opts.rtl_gain_value); //multiple value by ten to make it consitent with the way rtl_fm really works
|
||||
break;
|
||||
@@ -877,11 +929,11 @@ main (int argc, char **argv)
|
||||
sscanf (optarg, "%d", &opts.rtl_squelch_level); //set squelch by user to prevent false positives on NXDN and others
|
||||
break;
|
||||
|
||||
case 'V': //Set rtl squelch level
|
||||
case 'V': //Set rtl voltage level
|
||||
sscanf (optarg, "%d", &opts.rtl_volume_multiplier); //set 'volume' multiplier for rtl-sdr samples
|
||||
break;
|
||||
|
||||
case 'U': //Set rtl squelch level
|
||||
case 'U': //Set rtl udp remote port
|
||||
sscanf (optarg, "%d", &opts.rtl_udp_port); //set udp port number for RTL remote
|
||||
break;
|
||||
|
||||
@@ -893,23 +945,20 @@ main (int argc, char **argv)
|
||||
sscanf (optarg, "%d", &opts.rtl_bandwidth);
|
||||
break;
|
||||
|
||||
case 'W': //monitor_input_audio if no sync
|
||||
opts.monitor_input_audio = 1;
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr,"Monitoring Source Audio when carrier present and No Sync Detected.\n");
|
||||
fprintf (stderr," - May cause Pulse Audio Server to crash on some systems.\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
opts.use_ncurses_terminal = 1;
|
||||
fprintf (stderr,"Enabling NCurses Terminal.\n");
|
||||
fprintf (stderr," - may need to issue 'reset' command in terminal after use\n");
|
||||
//fprintf (stderr," - may need to issue 'reset' command in terminal after use\n");
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
opts.payload = 1;
|
||||
fprintf (stderr,"Logging MBE Payload to console\n");
|
||||
fprintf (stderr,"Logging Frame Payload to console\n");
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
opts.lrrp_file_output = 1;
|
||||
fprintf (stderr,"Logging LRRP data to ~/lrrp.txt \n");
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
@@ -917,16 +966,18 @@ main (int argc, char **argv)
|
||||
state.dmr_stereo = 1; //this values toggles on and off depending on voice or data handling
|
||||
opts.pulse_digi_rate_out = 24000;
|
||||
opts.pulse_digi_out_channels = 2;
|
||||
fprintf (stderr, "%s", KRED);
|
||||
sprintf (opts.output_name, "DMR STEREO");
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf (stderr,"DMR Stereo Sync and Functionality Enabled.\n");
|
||||
fprintf (stderr,"DMR Stereo will disable WAV and MBE file saving!\n");
|
||||
fprintf (stderr,"DMR Stereo will disable MBE file saving!\n");
|
||||
fprintf (stderr,"DMR Stereo per call WAV file can be enabled in the NCurses Terminal!\n");
|
||||
fprintf (stderr,"Also consider using -F if playback is too choppy!\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
opts.aggressive_framesync = 0;
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf (stderr,"DMR Stereo Aggressive Resync Disabled!\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
break;
|
||||
@@ -984,32 +1035,28 @@ main (int argc, char **argv)
|
||||
state.aout_gainR = opts.audio_gain;
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
opts.reset_state = 1;
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr,"Enabling Automatic Reset of P25 states\n");
|
||||
//fprintf (stderr," -Helps with multiple signal type decoding\n");
|
||||
//fprintf (stderr," -(WiP! May cause slow memory leak)\n");
|
||||
fprintf (stderr," -(Disabled until memory leak issues can be resolved!)\n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
strncpy(opts.wav_out_file, optarg, 1023);
|
||||
opts.wav_out_file[1023] = '\0';
|
||||
fprintf (stderr,"Writing + Appending audio to file %s\n", opts.wav_out_file);
|
||||
fprintf (stderr,"Writing + Appending decoded audio to file %s\n", opts.wav_out_file);
|
||||
openWavOutFile (&opts, &state);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
sscanf (optarg, "%d", &opts.serial_baud);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
strncpy(opts.serial_dev, optarg, 1023);
|
||||
opts.serial_dev[1023] = '\0';
|
||||
break;
|
||||
//case 'R':
|
||||
// sscanf (optarg, "%d", &opts.resume);
|
||||
// fprintf (stderr,"Enabling scan resume after %i TDULC frames\n", opts.resume);
|
||||
// break;
|
||||
|
||||
case 'R':
|
||||
sscanf (optarg, "%d", &opts.resume);
|
||||
fprintf (stderr,"Enabling scan resume after %i TDULC frames\n", opts.resume);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (optarg[0] == 'a')
|
||||
{
|
||||
@@ -1017,7 +1064,7 @@ main (int argc, char **argv)
|
||||
opts.frame_x2tdma = 1;
|
||||
opts.frame_p25p1 = 1;
|
||||
opts.frame_nxdn48 = 0;
|
||||
opts.frame_nxdn96 = 0; //causes false positives, leave on 0
|
||||
opts.frame_nxdn96 = 0;
|
||||
opts.frame_dmr = 1;
|
||||
opts.frame_dpmr = 0;
|
||||
opts.frame_provoice = 0;
|
||||
@@ -1033,6 +1080,7 @@ main (int argc, char **argv)
|
||||
opts.frame_dmr = 0;
|
||||
opts.frame_dpmr = 0;
|
||||
opts.frame_provoice = 0;
|
||||
state.rf_mod = 0;
|
||||
sprintf (opts.output_name, "D-STAR");
|
||||
fprintf (stderr,"Decoding only D-STAR frames.\n");
|
||||
}
|
||||
@@ -1104,7 +1152,6 @@ main (int argc, char **argv)
|
||||
opts.mod_gfsk = 0;
|
||||
state.rf_mod = 0;
|
||||
sprintf (opts.output_name, "NXDN48");
|
||||
//opts.symboltiming = 2400; //NXDN48 uses 2400 symbol rate
|
||||
fprintf (stderr,"Setting symbol rate to 2400 / second\n");
|
||||
fprintf (stderr,"Decoding only NXDN 4800 baud frames.\n");
|
||||
}
|
||||
@@ -1113,23 +1160,44 @@ main (int argc, char **argv)
|
||||
opts.frame_dstar = 0;
|
||||
opts.frame_x2tdma = 0;
|
||||
opts.frame_p25p1 = 0;
|
||||
opts.frame_p25p2 = 0;
|
||||
opts.frame_nxdn48 = 0;
|
||||
opts.frame_nxdn96 = 0;
|
||||
opts.frame_dmr = 0;
|
||||
opts.frame_dpmr = 0;
|
||||
opts.frame_provoice = 0;
|
||||
opts.frame_ysf = 1;
|
||||
state.samplesPerSymbol = 10;
|
||||
//state.symbolCenter = 10;
|
||||
state.samplesPerSymbol = 20; //10
|
||||
state.symbolCenter = 10;
|
||||
opts.mod_c4fm = 1;
|
||||
opts.mod_qpsk = 0;
|
||||
opts.mod_gfsk = 0;
|
||||
state.rf_mod = 0;
|
||||
sprintf (opts.output_name, "YSF");
|
||||
//opts.symboltiming = 2400; //NXDN48 uses 2400 symbol rate
|
||||
fprintf (stderr,"Setting symbol rate to 2400 / second\n");
|
||||
fprintf (stderr,"Decoding only YSF frames.\nNot working yet!\n");
|
||||
}
|
||||
else if (optarg[0] == '2')
|
||||
{
|
||||
opts.frame_dstar = 0;
|
||||
opts.frame_x2tdma = 0;
|
||||
opts.frame_p25p1 = 0;
|
||||
opts.frame_p25p2 = 1;
|
||||
opts.frame_nxdn48 = 0;
|
||||
opts.frame_nxdn96 = 0;
|
||||
opts.frame_dmr = 0;
|
||||
opts.frame_dpmr = 0;
|
||||
opts.frame_provoice = 0;
|
||||
opts.frame_ysf = 0;
|
||||
state.samplesPerSymbol = 20; //10
|
||||
state.symbolCenter = 10;
|
||||
opts.mod_c4fm = 0;
|
||||
opts.mod_qpsk = 1;
|
||||
opts.mod_gfsk = 0;
|
||||
state.rf_mod = 0;
|
||||
sprintf (opts.output_name, "P25-P2");
|
||||
fprintf (stderr,"Decoding P25-P2 frames.\nNot working yet!\n");
|
||||
}
|
||||
else if (optarg[0] == 'n')
|
||||
{
|
||||
opts.frame_dstar = 0;
|
||||
@@ -1161,9 +1229,9 @@ main (int argc, char **argv)
|
||||
opts.mod_qpsk = 0;
|
||||
opts.mod_gfsk = 0; //
|
||||
state.rf_mod = 0; //
|
||||
sprintf (opts.output_name, "DMR/MOTOTRBO");
|
||||
sprintf (opts.output_name, "DMR LEH");
|
||||
//fprintf(stderr, "Notice: DMR cannot autodetect polarity. \n Use -xr option if Inverted Signal expected.\n");
|
||||
fprintf (stderr,"Decoding only DMR/MOTOTRBO frames.\n");
|
||||
fprintf (stderr,"Decoding only DMR frames.\n");
|
||||
}
|
||||
else if (optarg[0] == 'm')
|
||||
{
|
||||
@@ -1242,7 +1310,7 @@ main (int argc, char **argv)
|
||||
else if (optarg[0] == 'r')
|
||||
{
|
||||
opts.inverted_dmr = 1;
|
||||
fprintf (stderr,"Expecting inverted DMR/MOTOTRBO signals.\n");
|
||||
fprintf (stderr,"Expecting inverted DMR signals.\n");
|
||||
}
|
||||
else if (optarg[0] == 'd')
|
||||
{
|
||||
@@ -1253,7 +1321,6 @@ main (int argc, char **argv)
|
||||
case 'A':
|
||||
sscanf (optarg, "%i", &opts.mod_threshold);
|
||||
fprintf (stderr,"Setting C4FM/QPSK auto detection threshold to %i\n", opts.mod_threshold);
|
||||
break;
|
||||
case 'S':
|
||||
sscanf (optarg, "%i", &opts.ssize);
|
||||
if (opts.ssize > 128)
|
||||
@@ -1294,11 +1361,6 @@ main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.use_ncurses_terminal == 1)
|
||||
{
|
||||
ncursesOpen();
|
||||
}
|
||||
|
||||
if (opts.resume > 0)
|
||||
{
|
||||
openSerial (&opts, &state);
|
||||
@@ -1314,23 +1376,7 @@ main (int argc, char **argv)
|
||||
opts.audio_out_type == 0;
|
||||
}
|
||||
|
||||
#ifdef USE_PORTAUDIO
|
||||
if((strncmp(opts.audio_in_dev, "pa:", 3) == 0)
|
||||
|| (strncmp(opts.audio_out_dev, "pa:", 3) == 0))
|
||||
{
|
||||
fprintf (stderr,"Initializing portaudio.\n");
|
||||
PaError err = Pa_Initialize();
|
||||
if( err != paNoError )
|
||||
{
|
||||
//fprintf (stderr, "An error occured while initializing portaudio\n" );
|
||||
//fprintf (stderr, "Error number: %d\n", err );
|
||||
//fprintf (stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
|
||||
exit(err);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (opts.playfiles == 1)
|
||||
if (opts.playfiles == 1)
|
||||
{
|
||||
opts.split = 1;
|
||||
opts.playoffset = 0;
|
||||
@@ -1345,7 +1391,7 @@ main (int argc, char **argv)
|
||||
openAudioOutDevice (&opts, SAMPLE_RATE_OUT);
|
||||
}
|
||||
}
|
||||
else if (strcmp (opts.audio_in_dev, opts.audio_out_dev) != 0)
|
||||
else if (strcmp (opts.audio_in_dev, opts.audio_out_dev) != 0)
|
||||
{
|
||||
opts.split = 1;
|
||||
opts.playoffset = 0;
|
||||
@@ -1368,16 +1414,15 @@ main (int argc, char **argv)
|
||||
else
|
||||
{
|
||||
opts.split = 0;
|
||||
opts.playoffset = 25; // 38
|
||||
opts.playoffsetR = 25; // 38
|
||||
opts.playoffset = 25;
|
||||
opts.playoffsetR = 25;
|
||||
opts.delay = 0;
|
||||
openAudioInDevice (&opts); //disabled all four instances of openAudio devices, in and out for now
|
||||
openAudioInDevice (&opts);
|
||||
opts.audio_out_fd = opts.audio_in_fd;
|
||||
}
|
||||
|
||||
if (opts.playfiles == 1)
|
||||
{
|
||||
//need set to 8000/1 for amb/imb playback, upsampling seems to cause random crackling
|
||||
opts.pulse_digi_rate_out = 8000;
|
||||
opts.pulse_digi_out_channels = 1;
|
||||
openPulseOutput(&opts); //need to open it up for output
|
||||
@@ -1389,9 +1434,6 @@ main (int argc, char **argv)
|
||||
liveScanner (&opts, &state);
|
||||
}
|
||||
|
||||
if (opts.use_ncurses_terminal == 1){
|
||||
//ncursesClose ();
|
||||
}
|
||||
cleanupAndExit (&opts, &state);
|
||||
|
||||
return (0);
|
||||
|
||||
111
src/dsd_mbe.c
111
src/dsd_mbe.c
@@ -17,10 +17,6 @@
|
||||
|
||||
#include "dsd.h"
|
||||
|
||||
//
|
||||
//C
|
||||
//
|
||||
|
||||
void
|
||||
playMbeFiles (dsd_opts * opts, dsd_state * state, int argc, char **argv)
|
||||
{
|
||||
@@ -117,8 +113,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
};
|
||||
//
|
||||
|
||||
|
||||
int i;
|
||||
int i;
|
||||
char imbe_d[88];
|
||||
char ambe_d[49];
|
||||
char ambe_d_str[50];
|
||||
@@ -141,20 +136,44 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
{
|
||||
// 0 +P25p1
|
||||
// 1 -P25p1
|
||||
state->errs = mbe_eccImbe7200x4400C0 (imbe_fr);
|
||||
state->errs2 = state->errs;
|
||||
mbe_demodulateImbe7200x4400Data (imbe_fr);
|
||||
state->errs2 += mbe_eccImbe7200x4400Data (imbe_fr, imbe_d);
|
||||
|
||||
mbe_processImbe7200x4400Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, imbe_fr, imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
|
||||
mbe_processImbe4400Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
||||
imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
//mbe_processImbe7200x4400Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, imbe_fr, imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
if (opts->payload == 1)
|
||||
{
|
||||
PrintIMBEData (opts, state, imbe_d);
|
||||
}
|
||||
|
||||
//increment vc counter by one.
|
||||
state->p25vc++;
|
||||
|
||||
if (opts->mbe_out_f != NULL)
|
||||
{
|
||||
saveImbe4400Data (opts, state, imbe_d);
|
||||
}
|
||||
}
|
||||
else if ((state->synctype == 14) || (state->synctype == 15))
|
||||
else if ((state->synctype == 14) || (state->synctype == 15)) //pV Sync
|
||||
{
|
||||
mbe_processImbe7100x4400Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, imbe7100_fr, imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
state->errs = mbe_eccImbe7100x4400C0 (imbe7100_fr);
|
||||
state->errs2 = state->errs;
|
||||
mbe_demodulateImbe7100x4400Data (imbe7100_fr);
|
||||
state->errs2 += mbe_eccImbe7100x4400Data (imbe7100_fr, imbe_d);
|
||||
mbe_convertImbe7100to7200(imbe_d); //needs extra conversion step apparently
|
||||
|
||||
mbe_processImbe4400Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
||||
imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
//below line the old way of doing this
|
||||
// mbe_processImbe7100x4400Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, imbe7100_fr, imbe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
if (opts->payload == 1)
|
||||
{
|
||||
PrintIMBEData (opts, state, imbe_d);
|
||||
@@ -176,6 +195,28 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
saveAmbe2450Data (opts, state, ambe_d);
|
||||
}
|
||||
}
|
||||
else if ((state->synctype == 8) || (state->synctype == 9))
|
||||
{
|
||||
state->errs = mbe_eccAmbe3600x2450C0 (ambe_fr);
|
||||
state->errs2 = state->errs;
|
||||
mbe_demodulateAmbe3600x2450Data (ambe_fr);
|
||||
state->errs2 += mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d);
|
||||
|
||||
|
||||
mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
||||
ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
|
||||
if (opts->payload == 1)
|
||||
{
|
||||
PrintAMBEData (opts, state, ambe_d);
|
||||
}
|
||||
|
||||
if (opts->mbe_out_f != NULL)
|
||||
{
|
||||
saveAmbe2450Data (opts, state, ambe_d);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//stereo slots and slot 0 (left slot)
|
||||
@@ -186,28 +227,27 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
state->errs2 = state->errs;
|
||||
mbe_demodulateAmbe3600x2450Data (ambe_fr);
|
||||
state->errs2 += mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d);
|
||||
//
|
||||
//F
|
||||
//
|
||||
|
||||
//
|
||||
if (state->K > 0 && state->dmr_so & 0x40 && state->payload_keyid == 0) //
|
||||
{
|
||||
k = BP[state->K];
|
||||
k = ( ((k & 0xFF0F) << 32 ) + (k << 16) + k );
|
||||
for (short int j = 0; j < 49; j++)
|
||||
for (short int j = 0; j < 48; j++) //49
|
||||
{
|
||||
x = ( ((k << j) & 0x800000000000) >> 47 );
|
||||
ambe_d[j] ^= x;
|
||||
}
|
||||
}
|
||||
//
|
||||
//D
|
||||
//
|
||||
mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
||||
ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
if (1 == 1) //still not quite right //state->payload_algid == 0 || state->K != 0
|
||||
{
|
||||
mbe_processAmbe2450Dataf (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str,
|
||||
ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
}
|
||||
|
||||
//old method for this step below
|
||||
//mbe_processAmbe3600x2450Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, ambe_fr, ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
if (opts->payload == 1)
|
||||
if (opts->payload == 1) // && state->R == 0 this is why slot 1 didn't primt abme, probably had it set during testing
|
||||
{
|
||||
PrintAMBEData (opts, state, ambe_d);
|
||||
}
|
||||
@@ -220,24 +260,23 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
state->errs2R = state->errsR;
|
||||
mbe_demodulateAmbe3600x2450Data (ambe_fr);
|
||||
state->errs2R += mbe_eccAmbe3600x2450Data (ambe_fr, ambe_d);
|
||||
//
|
||||
//G
|
||||
//
|
||||
|
||||
//BP Handling, Slot 2
|
||||
if (state->K > 0 && state->dmr_soR & 0x40 && state->payload_keyidR == 0) //
|
||||
{
|
||||
k = BP[state->K];
|
||||
k = ( ((k & 0xFF0F) << 32 ) + (k << 16) + k );
|
||||
for (short int j = 0; j < 49; j++)
|
||||
for (short int j = 0; j < 48; j++)
|
||||
{
|
||||
x = ( ((k << j) & 0x800000000000) >> 47 );
|
||||
ambe_d[j] ^= x;
|
||||
}
|
||||
}
|
||||
//
|
||||
//E
|
||||
//
|
||||
mbe_processAmbe2450Dataf (state->audio_out_temp_bufR, &state->errsR, &state->errs2R, state->err_strR,
|
||||
ambe_d, state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2, opts->uvquality);
|
||||
if (1 == 1) //state->payload_algidR == 0 || state->K != 0
|
||||
{
|
||||
mbe_processAmbe2450Dataf (state->audio_out_temp_bufR, &state->errsR, &state->errs2R, state->err_strR,
|
||||
ambe_d, state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2, opts->uvquality);
|
||||
}
|
||||
|
||||
//old method for this step below
|
||||
//mbe_processAmbe3600x2450Framef (state->audio_out_temp_bufR, &state->errsR, &state->errs2R, state->err_strR, ambe_fr, ambe_d, state->cur_mp2, state->prev_mp2, state->prev_mp_enhanced2, opts->uvquality);
|
||||
@@ -246,7 +285,7 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
PrintAMBEData (opts, state, ambe_d);
|
||||
}
|
||||
}
|
||||
//if using older DMR method, dPMR, or NXDN
|
||||
//if using ???
|
||||
if (opts->dmr_stereo == 0)
|
||||
{
|
||||
mbe_processAmbe3600x2450Framef (state->audio_out_temp_buf, &state->errs, &state->errs2, state->err_str, ambe_fr, ambe_d, state->cur_mp, state->prev_mp, state->prev_mp_enhanced, opts->uvquality);
|
||||
@@ -294,4 +333,18 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a
|
||||
writeSynthesizedVoice (opts, state);
|
||||
}
|
||||
|
||||
//per call can only be used when ncurses terminal is active since we use its call history matrix for when to record
|
||||
if (opts->use_ncurses_terminal == 1 && opts->dmr_stereo_wav == 1 && opts->dmr_stereo == 1 && state->currentslot == 0)
|
||||
{
|
||||
//write wav to per call on left channel Slot 1
|
||||
writeSynthesizedVoice (opts, state);
|
||||
}
|
||||
//per call can only be used when ncurses terminal is active since we use its call history matrix for when to record
|
||||
if (opts->use_ncurses_terminal == 1 && opts->dmr_stereo_wav == 1 && opts->dmr_stereo == 1 && state->currentslot == 1)
|
||||
{
|
||||
//write wav to per call on right channel Slot 2
|
||||
writeSynthesizedVoiceR (opts, state);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
1338
src/dsd_ncurses.c
1338
src/dsd_ncurses.c
File diff suppressed because it is too large
Load Diff
@@ -8,9 +8,9 @@ resetState (dsd_state * state)
|
||||
|
||||
int i, j;
|
||||
|
||||
state->dibit_buf = malloc (sizeof (int) * 1000000);
|
||||
state->dibit_buf_p = state->dibit_buf + 200;
|
||||
memset (state->dibit_buf, 0, sizeof (int) * 200);
|
||||
// state->dibit_buf = malloc (sizeof (int) * 1000000);
|
||||
// state->dibit_buf_p = state->dibit_buf + 200;
|
||||
// memset (state->dibit_buf, 0, sizeof (int) * 200);
|
||||
state->repeat = 0; //not sure yet
|
||||
//state->audio_out_buf = malloc (sizeof (short) * 1000000);
|
||||
//memset (state->audio_out_buf, 0, 100 * sizeof (short));
|
||||
|
||||
@@ -26,6 +26,7 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
||||
|
||||
sum = 0;
|
||||
count = 0;
|
||||
sample = 0; //init sample with a value of 0...see if this was causing issues with raw audio monitoring
|
||||
|
||||
for (i = 0; i < state->samplesPerSymbol; i++) //right HERE
|
||||
{
|
||||
@@ -81,15 +82,22 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
||||
}
|
||||
|
||||
// Read the new sample from the input
|
||||
if(opts->audio_in_type == 0)
|
||||
if(opts->audio_in_type == 0) // && state->menuopen == 0 still not quite working
|
||||
{
|
||||
pa_simple_read(opts->pulse_digi_dev_in, &sample, 2, NULL );
|
||||
//look into how processAudio handles playback, not sure if latency issues, or garbage sample values crash pulse when written
|
||||
if (opts->monitor_input_audio == 1 && state->lastsynctype == -1 && sample < 32767 && sample > -32767)
|
||||
// if (opts->monitor_input_audio == 1 && state->lastsynctype == -1 && sample < 32767 && sample > -32767)
|
||||
if (opts->monitor_input_audio == 1 && state->lastsynctype == -1 && sample != 0)
|
||||
{
|
||||
state->pulse_raw_out_buffer = sample; //steal raw out buffer sample here?
|
||||
pa_simple_write(opts->pulse_raw_dev_out, (void*)&state->pulse_raw_out_buffer, 2, NULL);
|
||||
}
|
||||
//playback is wrong, depends on samples_per_symbol, maybe make a buffer and store first?
|
||||
//making buffer might also fix raw audio monitoring as well
|
||||
if (opts->wav_out_file_raw[0] != 0) //if set for recording sample raw files
|
||||
{
|
||||
//writeRawSample (opts, state, sample);
|
||||
}
|
||||
|
||||
}
|
||||
else if (opts->audio_in_type == 1) {
|
||||
@@ -122,7 +130,8 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
||||
{
|
||||
#ifdef USE_RTLSDR
|
||||
// TODO: need to read demodulated stream here
|
||||
get_rtlsdr_sample(&sample);
|
||||
// get_rtlsdr_sample(&sample);
|
||||
get_rtlsdr_sample(&sample, opts, state);
|
||||
if (opts->monitor_input_audio == 1 && state->lastsynctype == -1 && sample < 32767 && sample > -32767)
|
||||
{
|
||||
state->pulse_raw_out_buffer = sample; //steal raw out buffer sample here?
|
||||
@@ -131,6 +140,11 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
||||
|
||||
#endif
|
||||
}
|
||||
// //test reading symbol bin files
|
||||
// else if (opts->audio_in_type == 4)
|
||||
// {
|
||||
// //use fopen and read in a sample, check boatbod op25 for clues
|
||||
// }
|
||||
|
||||
#ifdef TRACE_DSD
|
||||
state->debug_sample_index++;
|
||||
@@ -338,6 +352,73 @@ getSymbol (dsd_opts * opts, dsd_state * state, int have_sync)
|
||||
}
|
||||
#endif
|
||||
|
||||
//read op25/fme symbol bin files
|
||||
if (opts->audio_in_type == 4)
|
||||
{
|
||||
//use fopen and read in a symbol, check op25 for clues
|
||||
if(opts->symbolfile == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error Opening File %s\n", opts->symbolfile);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
state->symbolc = fgetc(opts->symbolfile);
|
||||
//fprintf(stderr, "%d", state->symbolc);
|
||||
if( feof(opts->symbolfile) )
|
||||
{
|
||||
opts->audio_in_type = 0; //switch to pulse after playback, ncurses terminal can initiate replay if wanted
|
||||
fclose(opts->symbolfile);
|
||||
openPulseInput(opts);
|
||||
}
|
||||
|
||||
//flipping these to 'positive' produces terrible results in P25 P1, and I tried flopping it every way I could
|
||||
//positive polarity works fine with DMR, but not P25, so may look at reading and storing based on frame type?
|
||||
if (opts->frame_p25p1 == 1) //use inverted polarity for reading P25, but not DMR (or others?)
|
||||
{
|
||||
if (state->symbolc == 0)
|
||||
{
|
||||
symbol = -1; //-1
|
||||
}
|
||||
if (state->symbolc == 1)
|
||||
{
|
||||
symbol = -3; //-3
|
||||
}
|
||||
if (state->symbolc == 2)
|
||||
{
|
||||
symbol = 1; //1
|
||||
}
|
||||
if (state->symbolc == 3)
|
||||
{
|
||||
symbol = 3; //3
|
||||
}
|
||||
}
|
||||
else if (opts->frame_provoice == 1) //syncs fine, but issues with dibit reading
|
||||
{
|
||||
//provoice has issue where sync is okay, but decode isn't working after sync
|
||||
//symbol = state->symbolc;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (state->symbolc == 0)
|
||||
{
|
||||
symbol = 1; //-1
|
||||
}
|
||||
if (state->symbolc == 1)
|
||||
{
|
||||
symbol = 3; //-3
|
||||
}
|
||||
if (state->symbolc == 2)
|
||||
{
|
||||
symbol = -1; //1
|
||||
}
|
||||
if (state->symbolc == 3)
|
||||
{
|
||||
symbol = -3; //3
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
state->symbolcnt++;
|
||||
return (symbol);
|
||||
|
||||
@@ -1224,10 +1224,11 @@ void Golay_24_12_encode(unsigned char *origBits, unsigned char *encodedBits)
|
||||
encodedBits[j] += origBits[i] * Golay_24_12_m_G[24*i + j];
|
||||
}
|
||||
}
|
||||
|
||||
// fprintf (stderr, "\n Inside Golay - Encoded Bits = "); //disable later on
|
||||
for (i = 0; i < 24; i++)
|
||||
{
|
||||
encodedBits[i] %= 2;
|
||||
// fprintf (stderr, "%b", encodedBits[i]); //disable later on
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#include "dsd.h"
|
||||
#include "nxdn_const.h"
|
||||
|
||||
//don't know why this doesn't work right in LEH, need to figure that out for him
|
||||
//works just fien when ripped from his and into mine
|
||||
//must be some random thing, I'll look at his when I have a chance
|
||||
void processNXDNData (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int i, dibit = 0;
|
||||
@@ -24,7 +21,7 @@ void processNXDNData (dsd_opts * opts, dsd_state * state)
|
||||
}
|
||||
|
||||
/* Start pseudo-random NXDN sequence after
|
||||
* LITCH = 16 bit = 8 dibit
|
||||
* LICH = 16 bit = 8 dibit
|
||||
* ==> Index 8 */
|
||||
pr = (unsigned char *)(&nxdnpr2[8]);
|
||||
for (i = 0; i < 30; i++)
|
||||
|
||||
736
src/nxdn_lib.c
736
src/nxdn_lib.c
@@ -60,13 +60,13 @@
|
||||
} /* End ConvertBitIntoBytes() */
|
||||
|
||||
|
||||
uint8_t NXDN_decode_LICH(uint8_t InputLich[8],
|
||||
uint8_t * RFChannelType,
|
||||
uint8_t * FunctionnalChannelType,
|
||||
uint8_t * Option,
|
||||
uint8_t * Direction,
|
||||
uint8_t * CompleteLichBinaryFormat,
|
||||
uint8_t Inverted)
|
||||
uint8_t NXDN_decode_LICH(uint8_t InputLich[8],
|
||||
uint8_t * RFChannelType,
|
||||
uint8_t * FunctionnalChannelType,
|
||||
uint8_t * Option,
|
||||
uint8_t * Direction,
|
||||
uint8_t * CompleteLichBinaryFormat,
|
||||
uint8_t Inverted)
|
||||
{
|
||||
uint8_t GoodParity = 0;
|
||||
uint32_t i;
|
||||
@@ -294,6 +294,7 @@ void NXDN_SACCH_Full_decode(dsd_opts * opts, dsd_state * state)
|
||||
|
||||
/* Check CRC */
|
||||
if(state->NxdnSacchRawPart[i].CrcIsGood == 0) CrcCorrect = 0;
|
||||
//fprintf(stderr, "\n SAACH P# %1d - %05X", i, state->NxdnSacchRawPart[i].Data);
|
||||
}
|
||||
|
||||
/* Decodes the element content */
|
||||
@@ -553,7 +554,7 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
|
||||
uint32_t i;
|
||||
uint8_t MessageType;
|
||||
uint64_t CurrentIV = 0;
|
||||
|
||||
unsigned long long int FullMessage = 0;
|
||||
/* Get the "Message Type" field */
|
||||
MessageType = (ElementsContent[2] & 1) << 5;
|
||||
MessageType |= (ElementsContent[3] & 1) << 4;
|
||||
@@ -562,6 +563,8 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
|
||||
MessageType |= (ElementsContent[6] & 1) << 1;
|
||||
MessageType |= (ElementsContent[7] & 1) << 0;
|
||||
|
||||
//fprintf(stderr, "\nMessage Type = %X ", MessageType);
|
||||
|
||||
/* Save the "F1" and "F2" flags */
|
||||
state->NxdnElementsContent.F1 = ElementsContent[0];
|
||||
state->NxdnElementsContent.F2 = ElementsContent[1];
|
||||
@@ -569,7 +572,16 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state,
|
||||
/* Save the "Message Type" field */
|
||||
state->NxdnElementsContent.MessageType = MessageType;
|
||||
|
||||
//fprintf(stderr, "Message Type = 0x%02X ", MessageType & 0xFF);
|
||||
//fprintf(stderr, "\n Message Type = 0x%02X ", MessageType & 0xFF);
|
||||
|
||||
//Dump the Message into a HEX value for vieweing
|
||||
//FullMessage = (unsigned long long int)ConvertBitIntoBytes(&Message[0], 64);
|
||||
for (short int i = 0; i < 64; i++)
|
||||
{
|
||||
FullMessage = FullMessage << 1;
|
||||
FullMessage |= ElementsContent[i];
|
||||
}
|
||||
//fprintf(stderr, "\nFull Message = %016llX ", FullMessage);
|
||||
|
||||
/* Decode the right "Message Type" */
|
||||
switch(MessageType)
|
||||
@@ -666,6 +678,7 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
uint8_t KeyID = 0;
|
||||
uint8_t DuplexMode[32] = {0};
|
||||
uint8_t TransmissionMode[32] = {0};
|
||||
unsigned long long int FullMessage = 0;
|
||||
|
||||
//UNUSED_VARIABLE(opts);
|
||||
//UNUSED_VARIABLE(state);
|
||||
@@ -712,14 +725,14 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
if(CCOption & 0x40) fprintf(stderr, "Visitor ");
|
||||
if(CCOption & 0x20) fprintf(stderr, "Priority Paging ");
|
||||
|
||||
/* On an AES or DES encrypted frame one IV is used on two
|
||||
* superframe.
|
||||
* The first superframe contains a VCALL message inside
|
||||
* the SACCH and the second superframe contains the next IV
|
||||
* to use.
|
||||
*
|
||||
* Set the correct part of encrypted frame flag.
|
||||
*/
|
||||
//Dump the Message into a HEX value for vieweing
|
||||
//FullMessage = (unsigned long long int)ConvertBitIntoBytes(&Message[0], 64);
|
||||
// for (short int i = 0; i < 64; i++)
|
||||
// {
|
||||
// FullMessage = FullMessage << 1;
|
||||
// FullMessage |= Message[i];
|
||||
// }
|
||||
|
||||
if((CipherType == 2) || (CipherType == 3))
|
||||
{
|
||||
state->NxdnElementsContent.PartOfCurrentEncryptedFrame = 1;
|
||||
@@ -742,11 +755,17 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
NXDN_Voice_Call_Option_To_Str(VoiceCallOption, DuplexMode, TransmissionMode);
|
||||
fprintf(stderr, "%s %s - ", DuplexMode, TransmissionMode);
|
||||
|
||||
/* Print Source ID and Destination ID (Talk Group or Unit ID) */
|
||||
//fprintf (stderr, "%s", KGRN);
|
||||
fprintf(stderr, "Src=%u - Dst/TG=%u ", SourceUnitID & 0xFFFF, DestinationID & 0xFFFF);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
|
||||
//state->nxdn_key = (KeyID & 0xFF);
|
||||
//state->nxdn_cipher_type = CipherType;
|
||||
/* Print the "Cipher Type" */
|
||||
if(CipherType != 0)
|
||||
{
|
||||
fprintf (stderr, "\n %s", KYEL);
|
||||
fprintf(stderr, "%s - ", NXDN_Cipher_Type_To_Str(CipherType));
|
||||
//state->nxdn_cipher_type = CipherType;
|
||||
}
|
||||
@@ -754,17 +773,19 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
/* Print the Key ID */
|
||||
if(CipherType != 0)
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
|
||||
fprintf(stderr, "Key ID %u - ", KeyID & 0xFF);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
//fprintf (stderr, "%s", KNRM);
|
||||
//state->nxdn_key = (KeyID & 0xFF);
|
||||
}
|
||||
|
||||
/* Print Source ID and Destination ID (Talk Group or Unit ID) */
|
||||
|
||||
fprintf(stderr, "Src=%u - Dst/TG=%u ", SourceUnitID & 0xFFFF, DestinationID & 0xFFFF);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
|
||||
//print scrambler key value if manually inserted
|
||||
if (state->nxdn_cipher_type == 0x01 && state->R > 0) //scrambler
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf(stderr, "Value: 0x%04llX", state->R); //use R and not miN
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
if(state->NxdnElementsContent.VCallCrcIsGood)
|
||||
{
|
||||
@@ -784,7 +805,7 @@ void NXDN_decode_VCALL(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
fprintf(stderr, "(CRC ERR) ");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
//fprintf(stderr, "\nFull Message = %016llX ", FullMessage);
|
||||
} /* End NXDN_decode_VCALL() */
|
||||
|
||||
|
||||
@@ -815,21 +836,15 @@ void NXDN_decode_VCALL_IV(dsd_opts * opts, dsd_state * state, uint8_t * Message)
|
||||
*
|
||||
* Message[8..71] contains : The 64 bits IV
|
||||
*/
|
||||
|
||||
state->payload_miN = 0; //zero out
|
||||
/* Extract the IV from the VCALL_IV message */
|
||||
for(i = 0; i < 8; i++)
|
||||
{
|
||||
state->NxdnElementsContent.IV[i] = (uint8_t)ConvertBitIntoBytes(&Message[(i + 1) * 8], 8);
|
||||
//let's load this mother fucker up then lol
|
||||
state->payload_miN = state->payload_miN << 8 | state->NxdnElementsContent.IV[i];
|
||||
}
|
||||
|
||||
/* On an AES or DES encrypted frame one IV is used on two
|
||||
* superframe.
|
||||
* The first superframe contains a VCALL message inside
|
||||
* the SACCH and the second superframe contains the next IV
|
||||
* to use.
|
||||
*
|
||||
* Set the correct part of encrypted frame flag.
|
||||
*/
|
||||
state->NxdnElementsContent.PartOfCurrentEncryptedFrame = 2;
|
||||
state->NxdnElementsContent.PartOfNextEncryptedFrame = 1;
|
||||
|
||||
@@ -1012,35 +1027,640 @@ uint8_t CRC6BitNXDN(uint8_t * BufferIn, uint32_t BitLength)
|
||||
return CRC;
|
||||
} /* End CRC6BitNXDN() */
|
||||
|
||||
|
||||
/* Scrambler used for NXDN transmission (different of the
|
||||
* voice encryption scrambler), see NXDN Part1-A Common Air Interface chapter
|
||||
* 4.6 for the polynomial description.
|
||||
* It is a X^9 + X^4 + 1 polynomial used as pseudo-random generator */
|
||||
void ScrambledNXDNVoiceBit(int * LfsrValue, char * BufferIn, char * BufferOut, int NbOfBitToScramble)
|
||||
//NXDN IDLE
|
||||
void ProcessNXDNIdleData (dsd_opts * opts, dsd_state * state, uint8_t Inverted)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t LFSR;
|
||||
uint8_t bit;
|
||||
int i, dibit = 0;
|
||||
unsigned char sacch_raw[72] = {0};
|
||||
unsigned char sacch_decoded[32] = {0}; /* 26 bit + 6 bit CRC */
|
||||
unsigned char *pr;
|
||||
uint8_t CrcIsGood = 0;
|
||||
uint8_t StructureField = 0;
|
||||
uint8_t RAN = 0;
|
||||
uint8_t PartOfFrame = 0;
|
||||
|
||||
/* Load the initial LFSR value
|
||||
* LFSR = 0x0E4 at starting value */
|
||||
LFSR = (uint32_t)*LfsrValue;
|
||||
|
||||
for(i = 0; i < (uint32_t)NbOfBitToScramble; i++)
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
/* Bit 0 of LFSR is used to scramble data */
|
||||
BufferOut[i] = (BufferIn[i] ^ (LFSR & 1)) & 1;
|
||||
|
||||
/* Compute bit = X^0 + X^4 */
|
||||
bit = ((LFSR & 1) ^ ((LFSR >> 4) & 1)) & 1;
|
||||
|
||||
/* Insert bit on the 9th bit (X^9) */
|
||||
LFSR = ((LFSR >> 1) & 0xFF) | ((bit << 8) & 0x100);
|
||||
fprintf(stderr, "DATA - ");
|
||||
}
|
||||
|
||||
*LfsrValue = (int)LFSR;
|
||||
} /* End ScrambledNXDNVoiceBit() */
|
||||
/* Start pseudo-random NXDN sequence after
|
||||
* LICH = 16 bit = 8 dibit
|
||||
* ==> Index 8 */
|
||||
pr = (unsigned char *)(&nxdnpr[8]);
|
||||
for (i = 0; i < 30; i++)
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
|
||||
/* Store and de-interleave directly SACCH bits */
|
||||
sacch_raw[(2*i)] = ((*pr) & 1) ^ (1 & (dibit >> 1)); // bit 1
|
||||
sacch_raw[(2*i)+1] = (1 & dibit); // bit 0
|
||||
pr++;
|
||||
#ifdef NXDN_DUMP
|
||||
fprintf(stderr, "%c", dibit + 48);
|
||||
#endif
|
||||
}
|
||||
#ifdef NXDN_DUMP
|
||||
fprintf(stderr, " ");
|
||||
#endif
|
||||
|
||||
|
||||
/* Decode the SACCH fields */
|
||||
CrcIsGood = NXDN_SACCH_raw_part_decode(sacch_raw, sacch_decoded);
|
||||
StructureField = (sacch_decoded[0]<<1 | sacch_decoded[1]<<0) & 0x03; /* Compute the Structure Field (remove 2 first bits of the SR Information in the SACCH) */
|
||||
RAN = (sacch_decoded[2]<<5 | sacch_decoded[3]<<4 | sacch_decoded[4]<<3 | sacch_decoded[5]<<2 | sacch_decoded[6]<<1 | sacch_decoded[7]<<0) & 0x3F; /* Compute the RAN (6 last bits of the SR Information in the SACCH) */
|
||||
|
||||
/* Compute the Part of Frame according to the structure field */
|
||||
if (StructureField == 3) PartOfFrame = 0;
|
||||
else if(StructureField == 2) PartOfFrame = 1;
|
||||
else if(StructureField == 1) PartOfFrame = 2;
|
||||
else if(StructureField == 0) PartOfFrame = 3;
|
||||
else PartOfFrame = 0; /* Normally we should never go here */
|
||||
|
||||
/* Fill the SACCH structure */
|
||||
state->NxdnSacchRawPart[PartOfFrame].CrcIsGood = CrcIsGood;
|
||||
state->NxdnSacchRawPart[PartOfFrame].StructureField = StructureField;
|
||||
state->NxdnSacchRawPart[PartOfFrame].RAN = RAN;
|
||||
memcpy(state->NxdnSacchRawPart[PartOfFrame].Data, &sacch_decoded[8], 18); /* Copy the 18 bits of SACCH content */
|
||||
|
||||
fprintf(stderr, "RAN=%02d - Part %d/4 ", RAN, PartOfFrame + 1);
|
||||
if(CrcIsGood) fprintf(stderr, " (OK) - ");
|
||||
else fprintf(stderr, "(CRC ERR) - ");
|
||||
|
||||
|
||||
/* This frame is an idle frame */
|
||||
fprintf(stderr, "Idle");
|
||||
|
||||
|
||||
/* Decode the SACCH only when all 4 voice frame
|
||||
* SACCH spare parts have been received */
|
||||
if(PartOfFrame == 3)
|
||||
{
|
||||
/* Decode the entire SACCH content */
|
||||
NXDN_SACCH_Full_decode(opts, state);
|
||||
}
|
||||
|
||||
for (i = 0; i < 144; i++)
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
#ifdef NXDN_DUMP
|
||||
fprintf(stderr, "%c", dibit + 48);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/* Reset the SACCH CRCs when all 4 voice frame
|
||||
* SACCH spare parts have been received */
|
||||
if(PartOfFrame == 3)
|
||||
{
|
||||
/* Reset all CRCs of the SACCH */
|
||||
for(i = 0; i < 4; i++) state->NxdnSacchRawPart[i].CrcIsGood = 0;
|
||||
}
|
||||
} /* End ProcessNXDNIdleData() */
|
||||
|
||||
void ProcessNXDNFacch1Data (dsd_opts * opts, dsd_state * state, uint8_t Inverted)
|
||||
{
|
||||
int i, j, dibit = 0;
|
||||
unsigned char sacch_raw[72] = {0};
|
||||
unsigned char sacch_decoded[32] = {0}; /* 26 bits + 6 bits CRC */
|
||||
unsigned char facch1_raw[144] = {0};
|
||||
unsigned char facch1_decoded[96] = {0}; /* 80 bits + 12 bits CRC + 4 bits "Tail" (set to "0") */
|
||||
unsigned char *pr;
|
||||
uint8_t CrcIsGood = 0;
|
||||
uint8_t StructureField = 0;
|
||||
uint8_t RAN = 0;
|
||||
uint8_t PartOfFrame = 0;
|
||||
uint8_t Facch1CrcIsGood = 0;
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
fprintf(stderr, "DATA - ");
|
||||
}
|
||||
|
||||
/* Start pseudo-random NXDN sequence after
|
||||
* LITCH = 16 bit = 8 dibit
|
||||
* ==> Index 8 */
|
||||
pr = (unsigned char *)(&nxdnpr[8]);
|
||||
for (i = 0; i < 30; i++)
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
|
||||
/* Store and de-interleave directly SACCH bits */
|
||||
sacch_raw[(2*i)] = ((*pr) & 1) ^ (1 & (dibit >> 1)); // bit 1
|
||||
sacch_raw[(2*i)+1] = (1 & dibit); // bit 0
|
||||
pr++;
|
||||
#ifdef NXDN_DUMP
|
||||
fprintf(stderr, "%c", dibit + 48);
|
||||
#endif
|
||||
}
|
||||
#ifdef NXDN_DUMP
|
||||
fprintf(stderr, " ");
|
||||
#endif
|
||||
|
||||
|
||||
/* Decode the SACCH fields */
|
||||
CrcIsGood = NXDN_SACCH_raw_part_decode(sacch_raw, sacch_decoded);
|
||||
StructureField = (sacch_decoded[0]<<1 | sacch_decoded[1]<<0) & 0x03; /* Compute the Structure Field (remove 2 first bits of the SR Information in the SACCH) */
|
||||
RAN = (sacch_decoded[2]<<5 | sacch_decoded[3]<<4 | sacch_decoded[4]<<3 | sacch_decoded[5]<<2 | sacch_decoded[6]<<1 | sacch_decoded[7]<<0) & 0x3F; /* Compute the RAN (6 last bits of the SR Information in the SACCH) */
|
||||
|
||||
/* Compute the Part of Frame according to the structure field */
|
||||
if (StructureField == 3) PartOfFrame = 0;
|
||||
else if(StructureField == 2) PartOfFrame = 1;
|
||||
else if(StructureField == 1) PartOfFrame = 2;
|
||||
else if(StructureField == 0) PartOfFrame = 3;
|
||||
else PartOfFrame = 0; /* Normally we should never go here */
|
||||
|
||||
/* Fill the SACCH structure */
|
||||
state->NxdnSacchRawPart[PartOfFrame].CrcIsGood = CrcIsGood;
|
||||
state->NxdnSacchRawPart[PartOfFrame].StructureField = StructureField;
|
||||
state->NxdnSacchRawPart[PartOfFrame].RAN = RAN;
|
||||
memcpy(state->NxdnSacchRawPart[PartOfFrame].Data, &sacch_decoded[8], 18); /* Copy the 18 bits of SACCH content */
|
||||
|
||||
fprintf(stderr, "RAN=%02d - Part %d/4 ", RAN, PartOfFrame + 1);
|
||||
if(CrcIsGood) fprintf(stderr, " (OK) - ");
|
||||
else fprintf(stderr, "(CRC ERR) - ");
|
||||
|
||||
|
||||
/* This frame is an FACCH1 frame */
|
||||
fprintf(stderr, "FACCH1 - ");
|
||||
|
||||
|
||||
/* Decode the SACCH only when all 4 voice frame
|
||||
* SACCH spare parts have been received */
|
||||
if(PartOfFrame == 3)
|
||||
{
|
||||
/* Decode the entire SACCH content */
|
||||
//NXDN_SACCH_Full_decode(opts, state);
|
||||
}
|
||||
|
||||
/* Start pseudo-random NXDN sequence after
|
||||
* LITCH = 16 bit = 8 dibit +
|
||||
* SACCH = 60 bit = 30 dibit
|
||||
* = 76 bit = 38 dibit
|
||||
* ==> Index 38 */
|
||||
pr = (unsigned char *)(&nxdnpr[38]);
|
||||
|
||||
/* The frame contains 2 * 144 bits = 2 * 72 dibit */
|
||||
for(j = 0; j < 2; j++)
|
||||
{
|
||||
for (i = 0; i < 72; i++)
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
|
||||
/* Store and FACCH1 bits */
|
||||
facch1_raw[(2*i)] = ((*pr) & 1) ^ (1 & (dibit >> 1)); // bit 1
|
||||
facch1_raw[(2*i)+1] = (1 & dibit); // bit 0
|
||||
pr++;
|
||||
|
||||
#ifdef NXDN_DUMP
|
||||
fprintf(stderr, "%c", dibit + 48);
|
||||
#endif
|
||||
} /* End for (i = 0; i < 72; i++) */
|
||||
|
||||
/* Extract the FACCH1 content */
|
||||
Facch1CrcIsGood = NXDN_FACCH1_decode(facch1_raw, facch1_decoded);
|
||||
|
||||
state->NxdnFacch1RawPart[j].CrcIsGood = Facch1CrcIsGood;
|
||||
memcpy(state->NxdnFacch1RawPart[j].Data, facch1_decoded, 80);
|
||||
|
||||
if(Facch1CrcIsGood) fprintf(stderr, "FACCH1 CRC %d is good - ", j + 1);
|
||||
else fprintf(stderr, "FACCH1 CRC %d is bad - ", j + 1);
|
||||
} /* End for(j = 0; j < 2; j++) */
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/* Reset the SACCH CRCs when all 4 voice frame
|
||||
* SACCH spare parts have been received */
|
||||
if(PartOfFrame == 3)
|
||||
{
|
||||
/* Reset all CRCs of the SACCH */
|
||||
for(i = 0; i < 4; i++) state->NxdnSacchRawPart[i].CrcIsGood = 0;
|
||||
}
|
||||
} /* End ProcessNXDNFacch1Data() */
|
||||
|
||||
void ProcessNXDNUdchData (dsd_opts * opts, dsd_state * state, uint8_t Inverted)
|
||||
{
|
||||
int i, dibit = 0;
|
||||
unsigned char facch2_raw[348] = {0};
|
||||
unsigned char facch2_decoded[203] = {0}; /* 184 bits + 15 bits CRC + 4 bits "Tail" (set to "0") */
|
||||
unsigned char *pr;
|
||||
uint8_t Facch2CrcIsGood = 0;
|
||||
uint8_t StructureField = 0;
|
||||
uint8_t RAN = 0;
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
fprintf(stderr, "DATA - ");
|
||||
}
|
||||
|
||||
/* Start pseudo-random NXDN sequence after
|
||||
* LITCH = 16 bit = 8 dibit
|
||||
* ==> Index 8 */
|
||||
pr = (unsigned char *)(&nxdnpr[8]);
|
||||
for (i = 0; i < 174; i++)
|
||||
{
|
||||
dibit = getDibit (opts, state);
|
||||
|
||||
/* Store and de-interleave directly SACCH bits */
|
||||
facch2_raw[(2*i)] = ((*pr) & 1) ^ (1 & (dibit >> 1)); // bit 1
|
||||
facch2_raw[(2*i)+1] = (1 & dibit); // bit 0
|
||||
pr++;
|
||||
#ifdef NXDN_DUMP
|
||||
fprintf(stderr, "%c", dibit + 48);
|
||||
#endif
|
||||
}
|
||||
#ifdef NXDN_DUMP
|
||||
fprintf(stderr, " ");
|
||||
#endif
|
||||
|
||||
/* Extract the UDCH/FACCH2 content */
|
||||
Facch2CrcIsGood = NXDN_UDCH_decode(facch2_raw, facch2_decoded);
|
||||
|
||||
state->NxdnFacch2RawPart.CrcIsGood = Facch2CrcIsGood;
|
||||
memcpy(state->NxdnFacch2RawPart.Data, facch2_decoded, 184);
|
||||
|
||||
StructureField = (facch2_decoded[0]<<1 | facch2_decoded[1]<<0) & 0x03; /* Compute the Structure Field (remove 2 first bits of the SR Information in the FACCH2) */
|
||||
RAN = (facch2_decoded[2]<<5 | facch2_decoded[3]<<4 | facch2_decoded[4]<<3 | facch2_decoded[5]<<2 | facch2_decoded[6]<<1 | facch2_decoded[7]<<0) & 0x3F; /* Compute the RAN (6 last bits of the SR Information in the FACCH2) */
|
||||
|
||||
fprintf(stderr, "RAN=%02d ", RAN);
|
||||
if(Facch2CrcIsGood) fprintf(stderr, " (OK) - ");
|
||||
else fprintf(stderr, "(CRC ERR) - ");
|
||||
|
||||
/* This frame is an FACCH2 frame */
|
||||
fprintf(stderr, "FACCH2 - ");
|
||||
|
||||
if(Facch2CrcIsGood) fprintf(stderr, "UDCH/FACCH2 CRC is good - ");
|
||||
else fprintf(stderr, "UDCH/FACCH2 CRC is bad - ");
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
} /* End ProcessNXDNUdchData() */
|
||||
|
||||
void ProcessNXDNFrame(dsd_opts * opts, dsd_state * state, uint8_t Inverted)
|
||||
{
|
||||
/* Switch to the correct type of frame */
|
||||
switch(state->NxdnLich.RFChannelType)
|
||||
{
|
||||
/* RCCH */
|
||||
case 0:
|
||||
{
|
||||
ProcessNxdnRCCHFrame(opts, state, Inverted);
|
||||
break;
|
||||
} /* End case 0 */
|
||||
|
||||
/* RTCH */
|
||||
case 1:
|
||||
{
|
||||
ProcessNxdnRTCHFrame(opts, state, Inverted);
|
||||
break;
|
||||
} /* End case 1 */
|
||||
|
||||
/* RDCH */
|
||||
case 2:
|
||||
{
|
||||
ProcessNxdnRDCHFrame(opts, state, Inverted);
|
||||
break;
|
||||
} /* End case 2 */
|
||||
|
||||
/* RTCH_C (Composite Control Channel) */
|
||||
case 3:
|
||||
{
|
||||
ProcessNxdnRTCH_C_Frame(opts, state, Inverted);
|
||||
break;
|
||||
} /* End case 3 */
|
||||
|
||||
default:
|
||||
{
|
||||
fprintf(stderr, "- Unknown NXDN Frame type\n");
|
||||
|
||||
/* Unknown frame type, simply skip the entire frame
|
||||
* 384 bits - 20 bits Frame Sync Word - 16 bits LICH = 348 bits = 174 dibit
|
||||
* Preserve 24 bits (12 dibit) => 174 - 12 = 162 dibit */
|
||||
skipDibit(opts, state, ((384 - 20 - 16) / 2) - 12);
|
||||
break;
|
||||
} /* End default */
|
||||
} /* End switch(state->NxdnLich.RFChannelType) */
|
||||
} /* End NxdnDecodeFrame() */
|
||||
|
||||
void ProcessNxdnRCCHFrame(dsd_opts * opts, dsd_state * state, uint8_t Inverted)
|
||||
{
|
||||
uint8_t SkipEntireFrameFlag = 0;
|
||||
|
||||
/* Remove compiler warning */
|
||||
// UNUSED_VARIABLE(Inverted);
|
||||
|
||||
sprintf(state->fsubtype, " RCCH ");
|
||||
|
||||
switch(state->NxdnLich.CompleteLich)
|
||||
{
|
||||
case 0b0011000:
|
||||
{
|
||||
fprintf(stderr, "- RCCH - CCCH Transmission using Short CAC\n");
|
||||
SkipEntireFrameFlag = 1;
|
||||
break;
|
||||
}
|
||||
case 0b0001000:
|
||||
{
|
||||
fprintf(stderr, "- RCCH - UPCH or CCCH Transmission using Long CAC\n");
|
||||
SkipEntireFrameFlag = 1;
|
||||
break;
|
||||
}
|
||||
case 0b0000001:
|
||||
{
|
||||
fprintf(stderr, "- RCCH - CAC Transmission\n");
|
||||
SkipEntireFrameFlag = 1;
|
||||
break;
|
||||
}
|
||||
case 0b0000011:
|
||||
{
|
||||
fprintf(stderr, "- RCCH - CAC Transmission which has not to be received\n");
|
||||
SkipEntireFrameFlag = 1;
|
||||
break;
|
||||
}
|
||||
case 0b0000101:
|
||||
{
|
||||
fprintf(stderr, "- RCCH - CAC Transmission which can be received arbitrary\n");
|
||||
SkipEntireFrameFlag = 1;
|
||||
break;
|
||||
}
|
||||
case 0b0011001:
|
||||
{
|
||||
fprintf(stderr, "- RCCH - IDAS\n");
|
||||
SkipEntireFrameFlag = 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fprintf(stderr, "- RCCH - Unknown RCCH Frame\n");
|
||||
SkipEntireFrameFlag = 1;
|
||||
break;
|
||||
} /* End default */
|
||||
} /* switch(state->NxdnLich.CompleteLich) */
|
||||
|
||||
if(SkipEntireFrameFlag)
|
||||
{
|
||||
/* Unknown frame type or frame not implemented yet, simply skip the entire frame
|
||||
* 384 bits - 20 bits Frame Sync Word - 16 bits LICH = 348 bits = 174 dibit
|
||||
* Preserve 24 bits (12 dibit) => 174 - 12 = 162 dibit */
|
||||
skipDibit(opts, state, ((384 - 20 - 16) / 2) - 12);
|
||||
}
|
||||
|
||||
} /* End ProcessNxdnRCCHFrame() */
|
||||
|
||||
void ProcessNxdnRDCHFrame(dsd_opts * opts, dsd_state * state, uint8_t Inverted)
|
||||
{
|
||||
uint8_t SkipEntireFrameFlag = 0;
|
||||
|
||||
/* Remove compiler warning */
|
||||
// UNUSED_VARIABLE(Inverted);
|
||||
|
||||
switch(state->NxdnLich.CompleteLich)
|
||||
{
|
||||
/* Voice frame */
|
||||
case 0b1010110: /* Voice call transmission : Superframe SACCH, VCH Only */
|
||||
case 0b1010100: /* Voice call transmission : Superframe SACCH, first half VCH & last half FACCH1 */
|
||||
case 0b1010010: /* Voice call transmission : Superframe SACCH, first half FACCH1 & last half VCH */
|
||||
case 0b1010111: /* Voice call transmission : Superframe SACCH, VCH Only */
|
||||
case 0b1010101: /* Voice call transmission : Superframe SACCH, first half VCH & last half FACCH1 */
|
||||
case 0b1010011: /* Voice call transmission : Superframe SACCH, first half FACCH1 & last half VCH */
|
||||
{
|
||||
fprintf(stderr, "- RDCH - ");
|
||||
processNXDNVoice(opts, state);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b1010000: /* Voice call transmission : Superframe SACCH, two FACCH1s */
|
||||
case 0b1010001: /* Voice call transmission : Superframe SACCH, two FACCH1s */
|
||||
{
|
||||
fprintf(stderr, "- RDCH - ");
|
||||
processNXDNData(opts, state);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b1011000: /* Voice call transmission : Superframe SACCH, Idle State */
|
||||
case 0b1011001: /* Voice call transmission : Superframe SACCH, Idle State */
|
||||
{
|
||||
fprintf(stderr, "- RDCH - ");
|
||||
ProcessNXDNIdleData(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b1000000: /* Voice call transmission : Non-superframe SACCH, two FACCH1s */
|
||||
case 0b1000001: /* Voice call transmission : Non-superframe SACCH, two FACCH1s */
|
||||
{
|
||||
//fprintf(stderr, "- RDCH - Non-superframe SACCH with two FACCH1s\n");
|
||||
fprintf(stderr, "- RDCH - ");
|
||||
ProcessNXDNFacch1Data(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b1001110: /* UDCH Transmission */
|
||||
case 0b1001111: /* UDCH Transmission */
|
||||
{
|
||||
fprintf(stderr, "- RDCH - UDCH Transmission - ");
|
||||
ProcessNXDNUdchData(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b1001000: /* FACCH2 Transmission */
|
||||
case 0b1001001: /* FACCH2 Transmission */
|
||||
{
|
||||
fprintf(stderr, "- RDCH - FACCH2 Transmission - ");
|
||||
ProcessNXDNUdchData(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
fprintf(stderr, "- RDCH - Unknown RDCH Frame\n");
|
||||
SkipEntireFrameFlag = 1;
|
||||
break;
|
||||
} /* End default */
|
||||
} /* End switch(state->NxdnLich.CompleteLich) */
|
||||
|
||||
if(SkipEntireFrameFlag)
|
||||
{
|
||||
/* Unknown frame type or frame not implemented yet, simply skip the entire frame
|
||||
* 384 bits - 20 bits Frame Sync Word - 16 bits LICH = 348 bits = 174 dibit
|
||||
* Preserve 8 bits (4 dibit) => 174 - 4 = 170 dibit */
|
||||
skipDibit(opts, state, ((384 - 20 - 16) / 2) - 4);
|
||||
}
|
||||
} /* End ProcessNxdnRDCHFrame() */
|
||||
|
||||
void ProcessNxdnRTCH_C_Frame(dsd_opts * opts, dsd_state * state, uint8_t Inverted)
|
||||
{
|
||||
uint8_t SkipEntireFrameFlag = 0;
|
||||
|
||||
/* Remove compiler warning */
|
||||
// UNUSED_VARIABLE(Inverted);
|
||||
|
||||
switch(state->NxdnLich.CompleteLich)
|
||||
{
|
||||
/* Voice frame */
|
||||
case 0b1110111: /* Voice call transmission : Superframe SACCH, VCH Only */
|
||||
case 0b1110101: /* Voice call transmission : Superframe SACCH, first half VCH & last half FACCH1 */
|
||||
case 0b1110011: /* Voice call transmission : Superframe SACCH, first half FACCH1 & last half VCH */
|
||||
{
|
||||
fprintf(stderr, "- RTCH_C - ");
|
||||
processNXDNVoice(opts, state);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b1110001: /* Voice call transmission : Superframe SACCH, two FACCH1s */
|
||||
{
|
||||
fprintf(stderr, "- RTCH_C - ");
|
||||
processNXDNData(opts, state);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b1111001: /* Voice call transmission : Superframe SACCH, Idle State */
|
||||
{
|
||||
fprintf(stderr, "- RTCH_C - ");
|
||||
ProcessNXDNIdleData(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b1100001: /* Voice call transmission : Non-superframe SACCH, two FACCH1s */
|
||||
{
|
||||
//fprintf(stderr, "- RTCH_C - Non-superframe SACCH with two FACCH1s\n");
|
||||
fprintf(stderr, "- RTCH_C - ");
|
||||
ProcessNXDNFacch1Data(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b1101111: /* UDCH Transmission */
|
||||
{
|
||||
fprintf(stderr, "- RTCH_C - UDCH Transmission - ");
|
||||
ProcessNXDNUdchData(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b1101001: /* FACCH2 Transmission */
|
||||
{
|
||||
fprintf(stderr, "- RTCH_C - FACCH2 Transmission - ");
|
||||
ProcessNXDNUdchData(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
fprintf(stderr, "- RTCH_C - Unknown RTCH_C Frame\n");
|
||||
SkipEntireFrameFlag = 1;
|
||||
break;
|
||||
} /* End default */
|
||||
} /* End switch(state->NxdnLich.CompleteLich) */
|
||||
|
||||
if(SkipEntireFrameFlag)
|
||||
{
|
||||
/* Unknown frame type or frame not implemented yet, simply skip the entire frame
|
||||
* 384 bits - 20 bits Frame Sync Word - 16 bits LICH = 348 bits = 174 dibit
|
||||
* Preserve 8 bits (4 dibit) => 174 - 4 = 170 dibit */
|
||||
skipDibit(opts, state, ((384 - 20 - 16) / 2) - 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* @brief : This function decodes an NXDN RTCH frame
|
||||
*
|
||||
* @param opts : Options
|
||||
*
|
||||
* @param state : State
|
||||
*
|
||||
* @param Inverted : 1 = Inverted frame ; 0 = Normal frame
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*/
|
||||
void ProcessNxdnRTCHFrame(dsd_opts * opts, dsd_state * state, uint8_t Inverted)
|
||||
{
|
||||
uint8_t SkipEntireFrameFlag = 0;
|
||||
|
||||
/* Remove compiler warning */
|
||||
// UNUSED_VARIABLE(Inverted);
|
||||
|
||||
switch(state->NxdnLich.CompleteLich)
|
||||
{
|
||||
/* Voice frame */
|
||||
case 0b0110110: /* Voice call transmission : Superframe SACCH, VCH Only */
|
||||
case 0b0110100: /* Voice call transmission : Superframe SACCH, first half VCH & last half FACCH1 */
|
||||
case 0b0110010: /* Voice call transmission : Superframe SACCH, first half FACCH1 & last half VCH */
|
||||
case 0b0110111: /* Voice call transmission : Superframe SACCH, VCH Only */
|
||||
case 0b0110101: /* Voice call transmission : Superframe SACCH, first half VCH & last half FACCH1 */
|
||||
case 0b0110011: /* Voice call transmission : Superframe SACCH, first half FACCH1 & last half VCH */
|
||||
{
|
||||
fprintf(stderr, "- RTCH - ");
|
||||
processNXDNVoice(opts, state);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b0110000: /* Voice call transmission : Superframe SACCH, two FACCH1s */
|
||||
case 0b0110001: /* Voice call transmission : Superframe SACCH, two FACCH1s */
|
||||
{
|
||||
fprintf(stderr, "- RTCH - ");
|
||||
processNXDNData(opts, state);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b0111000: /* Voice call transmission : Superframe SACCH, Idle State */
|
||||
case 0b0111001: /* Voice call transmission : Superframe SACCH, Idle State */
|
||||
{
|
||||
fprintf(stderr, "- RTCH - ");
|
||||
ProcessNXDNIdleData(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b0100000: /* Voice call transmission : Non-superframe SACCH, two FACCH1s */
|
||||
case 0b0100001: /* Voice call transmission : Non-superframe SACCH, two FACCH1s */
|
||||
{
|
||||
//fprintf(stderr, "- RTCH - Non-superframe SACCH with two FACCH1s\n");
|
||||
fprintf(stderr, "- RDCH - ");
|
||||
ProcessNXDNFacch1Data(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b0101110: /* UDCH Transmission */
|
||||
case 0b0101111: /* UDCH Transmission */
|
||||
{
|
||||
fprintf(stderr, "- RTCH - UDCH Transmission - ");
|
||||
ProcessNXDNUdchData(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0b0101000: /* FACCH2 Transmission */
|
||||
case 0b0101001: /* FACCH2 Transmission */
|
||||
{
|
||||
fprintf(stderr, "- RTCH - FACCH2 Transmission - ");
|
||||
ProcessNXDNUdchData(opts, state, Inverted);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fprintf(stderr, "- RTCH - Unknown RTCH Frame\n");
|
||||
SkipEntireFrameFlag = 1;
|
||||
break;
|
||||
} /* End default */
|
||||
} /* End switch(state->NxdnLich.CompleteLich) */
|
||||
|
||||
if(SkipEntireFrameFlag)
|
||||
{
|
||||
/* Unknown frame type or frame not implemented yet, simply skip the entire frame
|
||||
* 384 bits - 20 bits Frame Sync Word - 16 bits LICH = 348 bits = 174 dibit
|
||||
* Preserve 8 bits (4 dibit) => 174 - 4 = 170 dibit */
|
||||
skipDibit(opts, state, ((384 - 20 - 16) / 2) - 4);
|
||||
}
|
||||
} /* End ProcessNxdnRTCHFrame() */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#include "dsd.h"
|
||||
#include "nxdn_const.h"
|
||||
|
||||
//don't know why this doesn't work right in LEH, need to figure that out for him
|
||||
//works just fien when ripped from his and into mine
|
||||
//must be some random thing, I'll look at his when I have a chance
|
||||
void processNXDNVoice (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
int i, j, dibit;
|
||||
@@ -143,11 +140,12 @@ void processNXDNVoice (dsd_opts * opts, dsd_state * state)
|
||||
y++;
|
||||
z++;
|
||||
}
|
||||
if (opts->payload == 1 && opts->dmr_stereo == 1)
|
||||
if (opts->payload == 1)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
//fprintf(stderr, "\n");
|
||||
}
|
||||
processMbeFrame (opts, state, NULL, ambe_fr, NULL);
|
||||
state->p25vc++; //increment counter by one here?
|
||||
|
||||
} /* End for (j = 0; j < 4; j++) */
|
||||
|
||||
@@ -162,5 +160,6 @@ void processNXDNVoice (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
/* Reset all CRCs of the SACCH */
|
||||
for(i = 0; i < 4; i++) state->NxdnSacchRawPart[i].CrcIsGood = 0;
|
||||
|
||||
}
|
||||
} /* End processNXDNVoice() */
|
||||
|
||||
30
src/p25_p2.c
Normal file
30
src/p25_p2.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/*-------------------------------------------------------------------------------
|
||||
* p25_p2.c
|
||||
* Phase 2 TDMA Voice handling
|
||||
*
|
||||
* LWVMOBILE
|
||||
* 2022-08 DSD-FME Florida Man Edition
|
||||
*-----------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Copyright (C) 2010 DSD Author
|
||||
* GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0)
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "dsd.h"
|
||||
|
||||
void processP2(dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
//Do Something
|
||||
fprintf (stderr, " Future Development\n"); //obligatory
|
||||
}
|
||||
@@ -467,12 +467,24 @@ processHDU(dsd_opts* opts, dsd_state* state)
|
||||
mihex1 = (unsigned long long int)ConvertBitIntoBytes(&mi[0], 32);
|
||||
mihex2 = (unsigned long long int)ConvertBitIntoBytes(&mi[32], 32);
|
||||
mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8);
|
||||
//only use 64 MSB, trailing 8 bits aren't used, so no mihex3
|
||||
state->payload_miP = (mihex1 << 32) | (mihex2);
|
||||
}
|
||||
|
||||
if (1 == 1) //print on payload == 1
|
||||
//set vc counter to 0
|
||||
state->p25vc = 0;
|
||||
|
||||
if (state->payload_algid != 0x80) //print on payload == 1
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf (stderr, " HDU ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX MFID: 0x%02X \n", algidhex, kidhex, mihex1, mihex2, mihex3, state->payload_mfid);
|
||||
fprintf (stderr, " HDU ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX MFID: 0x%02X", algidhex, kidhex, mihex1, mihex2, mihex3, state->payload_mfid);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
if (state->payload_algid != 0x80) //print on payload == 1
|
||||
{
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr, " ENC \n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
|
||||
state->debug_prefix_2 = '1';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 2
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[11][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[10][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -78,7 +77,6 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
|
||||
state->debug_prefix_2 = '2';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 3
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[ 7][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[ 6][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -91,7 +89,6 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
|
||||
state->debug_prefix_2 = '3';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 4
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[ 3][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[ 2][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -104,7 +101,6 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
|
||||
state->debug_prefix_2 = '4';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 5
|
||||
read_and_correct_hex_word (opts, state, &(hex_parity[11][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_parity[10][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -117,7 +113,6 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
|
||||
state->debug_prefix_2 = '5';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 6
|
||||
read_and_correct_hex_word (opts, state, &(hex_parity[ 7][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_parity[ 6][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -130,7 +125,6 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
|
||||
state->debug_prefix_2 = '6';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 7
|
||||
read_and_correct_hex_word (opts, state, &(hex_parity[ 3][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_parity[ 2][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -174,6 +168,7 @@ processLDU1 (dsd_opts* opts, dsd_state* state)
|
||||
{
|
||||
lsd2[i] = lsd[i] + '0';
|
||||
}
|
||||
//skip two octets since LSD is part of the encryption portion
|
||||
|
||||
// TODO: error correction of the LSD bytes...
|
||||
// TODO: do something useful with the LSD bytes...
|
||||
|
||||
@@ -49,6 +49,8 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
// so we start counter at 36-14-1 = 21
|
||||
status_count = 21;
|
||||
|
||||
state->p25vc = 9;
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
//fprintf (stderr, "e:");
|
||||
@@ -65,7 +67,6 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
state->debug_prefix_2 = '1';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 2
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[15][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[14][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -78,7 +79,6 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
state->debug_prefix_2 = '2';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 3
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[11][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[10][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -91,7 +91,6 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
state->debug_prefix_2 = '3';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 4
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[ 7][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[ 6][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -104,7 +103,6 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
state->debug_prefix_2 = '4';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 5
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[ 3][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_data[ 2][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -117,7 +115,6 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
state->debug_prefix_2 = '5';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 6
|
||||
read_and_correct_hex_word (opts, state, &(hex_parity[ 7][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_parity[ 6][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -130,7 +127,6 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
state->debug_prefix_2 = '6';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 7
|
||||
read_and_correct_hex_word (opts, state, &(hex_parity[ 3][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
read_and_correct_hex_word (opts, state, &(hex_parity[ 2][0]), &status_count, analog_signal_array, &analog_signal_index);
|
||||
@@ -143,7 +139,6 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
state->debug_prefix_2 = '7';
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
// Read data after IMBE 8: LSD (low speed data)
|
||||
{
|
||||
char lsd[8];
|
||||
@@ -174,6 +169,7 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
lsd2[i] = lsd[i] + '0';
|
||||
}
|
||||
//skip two octets since LSD is part of the encryption portion
|
||||
|
||||
// TODO: error correction of the LSD bytes...
|
||||
// TODO: do something useful with the LSD bytes...
|
||||
@@ -185,6 +181,9 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
#endif
|
||||
process_IMBE (opts, state, &status_count);
|
||||
|
||||
//set vc counter to 0
|
||||
state->p25vc = 0;
|
||||
|
||||
if (opts->errorbars == 1)
|
||||
{
|
||||
fprintf (stderr, "\n");
|
||||
@@ -373,48 +372,23 @@ processLDU2 (dsd_opts * opts, dsd_state * state)
|
||||
mihex1 = (unsigned long long int)ConvertBitIntoBytes(&mi[0], 32);
|
||||
mihex2 = (unsigned long long int)ConvertBitIntoBytes(&mi[32], 32);
|
||||
mihex3 = (unsigned long long int)ConvertBitIntoBytes(&mi[64], 8);
|
||||
//need to check this for accuracy, may be incorrect, MI may also be incorrect, I have 72, but LFSR shows 64
|
||||
state->payload_miP = (mihex1 << 40) | (mihex2 << 8) | mihex3;
|
||||
//only use 64 MSB, trailing 8 bits aren't used, so no mihex3
|
||||
state->payload_miP = (mihex1 << 32) | (mihex2);
|
||||
|
||||
}
|
||||
|
||||
if (1 == 1) //print on payload == 1
|
||||
if (state->payload_algid != 0x80) //print on payload == 1
|
||||
{
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf (stderr, " LDU2 ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX\n", algidhex, kidhex, mihex1, mihex2, mihex3);
|
||||
fprintf (stderr, " LDU2 ALG ID: 0x%02X KEY ID: 0x%02X MI: 0x%08llX%08llX%02llX", algidhex, kidhex, mihex1, mihex2, mihex3);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
if (opts->payload == 1)
|
||||
{
|
||||
//LFSRP(state);
|
||||
}
|
||||
//why am I doing this part below again?
|
||||
if (opts->payload == 0)
|
||||
{
|
||||
algidhex = strtol (algid, NULL, 2);
|
||||
kidhex = strtol (kid, NULL, 2);
|
||||
}
|
||||
}
|
||||
|
||||
//needs some work to make mi value fit in there since its a 72 bit value, need to check this over
|
||||
//LFSR code courtesy of https://github.com/mattames/LFSR/
|
||||
int LFSRP(dsd_state * state)
|
||||
{
|
||||
uint64_t lfsr = 0;
|
||||
lfsr = state->payload_miP;
|
||||
uint8_t cnt = 0;
|
||||
|
||||
for(cnt=0;cnt<32;cnt++)
|
||||
if (state->payload_algid != 0x80) //print on payload == 1
|
||||
{
|
||||
// Polynomial is C(x) = x^64 + x^62 + x^46 + x^38 + x^27 + x^15 + 1
|
||||
uint64_t bit = ((lfsr >> 63) ^ (lfsr >> 61) ^ (lfsr >> 45) ^ (lfsr >> 37) ^ (lfsr >> 26) ^ (lfsr >> 14)) & 0x1;
|
||||
lfsr = (lfsr << 1) | (bit);
|
||||
fprintf (stderr, "%s", KRED);
|
||||
fprintf (stderr, " ENC \n");
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
}
|
||||
|
||||
fprintf (stderr, "%s", KYEL);
|
||||
fprintf (stderr, " LDU2 ALG ID: 0x%02X KEY ID: 0x%02X", state->payload_algid, state->payload_keyid);
|
||||
fprintf(stderr, " Next MI: 0x%016llX \n", lfsr);
|
||||
fprintf (stderr, "%s", KNRM);
|
||||
state->payload_miP = lfsr;
|
||||
|
||||
}
|
||||
|
||||
@@ -954,8 +954,10 @@ static void *socket_thread_fn(void *arg) {
|
||||
new_freq = chars_to_int(buffer);
|
||||
dongle.freq = new_freq; //
|
||||
//opts->rtlsdr_center_freq = new_freq; //or dongle.freq, this should update the freq displayed in ncurses terminal hopefully and not do anything naughty
|
||||
|
||||
optimal_settings(new_freq, demod.rate_in);
|
||||
rtlsdr_set_center_freq(dongle.dev, dongle.freq);
|
||||
//verbose_set_frequency (dongle.dev, new_freq);
|
||||
//fprintf (stderr, "Tuning to: %d [Hz] (central freq: %d [Hz])\n", new_freq, new_freq + freq_offset);
|
||||
fprintf (stderr, "Tuning to: %d [Hz] \n", new_freq);
|
||||
}
|
||||
@@ -1042,8 +1044,8 @@ static void *socket_thread_fn(void *arg) {
|
||||
|
||||
void rtlsdr_sighandler()
|
||||
{
|
||||
fprintf (stderr, "Signal caught, exiting!\n");
|
||||
fprintf (stderr, "Press CTRL + C again to close. Thanks. \n"); //Kindly remind user to double tap CTRL + C
|
||||
//fprintf (stderr, "Signal caught, exiting!\n");
|
||||
//fprintf (stderr, "Press CTRL + C again to close. Thanks. \n"); //Kindly remind user to double tap CTRL + C
|
||||
|
||||
rtlsdr_cancel_async(dongle.dev);
|
||||
//cleanup_rtlsdr_stream(); //thank the wraith for this one...if it works...didn't work
|
||||
@@ -1070,6 +1072,7 @@ void open_rtlsdr_stream(dsd_opts *opts)
|
||||
|
||||
if (opts->rtlsdr_ppm_error > 0 || opts->rtlsdr_ppm_error < 0) { //this way will adjust PPM based on negative values as well
|
||||
dongle.ppm_error = opts->rtlsdr_ppm_error;
|
||||
fprintf (stderr, "Setting RTL PPM Error Set to %d\n", opts->rtlsdr_ppm_error);
|
||||
}
|
||||
|
||||
if (opts->audio_in_type == 3) {
|
||||
@@ -1152,6 +1155,8 @@ void cleanup_rtlsdr_stream()
|
||||
safe_cond_signal(&output.ready, &output.ready_m);
|
||||
safe_cond_signal(&controller.hop, &controller.hop_m);
|
||||
pthread_join(controller.thread, NULL);
|
||||
//add socket thread
|
||||
//pthread_join(socket_freq, NULL);
|
||||
|
||||
//dongle_cleanup(&dongle);
|
||||
demod_cleanup(&demod);
|
||||
@@ -1162,16 +1167,29 @@ void cleanup_rtlsdr_stream()
|
||||
|
||||
}
|
||||
|
||||
void get_rtlsdr_sample(int16_t *sample)
|
||||
//void get_rtlsdr_sample(int16_t *sample)
|
||||
void get_rtlsdr_sample(int16_t *sample, dsd_opts * opts, dsd_state * state)
|
||||
{
|
||||
if (output.queue.empty())
|
||||
{
|
||||
if (opts->use_ncurses_terminal == 1)
|
||||
{
|
||||
//ncursesPrinter(opts, state);
|
||||
//printw ("\n\n\n HELP I'M LOCKED!\n");
|
||||
}
|
||||
safe_cond_wait(&output.ready, &output.ready_m);
|
||||
//goto END;
|
||||
}
|
||||
|
||||
pthread_rwlock_wrlock(&output.rw);
|
||||
//*sample = output.queue.front();
|
||||
|
||||
*sample = output.queue.front() * volume_multiplier; //try multiplying by numbers here for 'gain'
|
||||
output.queue.pop();
|
||||
pthread_rwlock_unlock(&output.rw);
|
||||
// END:
|
||||
// if (1 == 2)
|
||||
// {
|
||||
// fprintf (stderr, "This is a dumb thing to fix");
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user