From 4e04d99780aeb9230678bbf81b652df963cd3ff7 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Fri, 25 Apr 2025 13:33:17 -0400 Subject: [PATCH] New Event History Setup and Logging to a Log File, part 2; #287 Rework all Per Call Wav files to tie into Event History; Auto Delete Empty Wav files created; Wav Files in progress have no extension and have no hard set name until closing; Delete all OLD patch files that are resolved directly or indirectly by new Event History, or have previously been incorporated into code. --- include/dsd.h | 45 +- patch/DMR_MONO_MODE_20240201.patch | 51 -- patch/MTL_MONO_MODE_20240328.patch | 152 ------ patch/cretu_no_dmr_idle.patch | 277 ---------- ...ice_call_tg_src_persistency_ncurses2.patch | 120 ----- ...ile_fixes_w_custom_wav_dir_20240601b.patch | 499 ------------------ src/dmr_csbk.c | 3 + src/dsd_file.c | 109 ++++ src/dsd_main.c | 80 ++- src/dsd_ncurses.c | 424 ++++++++------- src/dstar.c | 5 + src/edacs-fme.c | 82 +-- src/ysf.c | 52 +- 13 files changed, 495 insertions(+), 1404 deletions(-) delete mode 100644 patch/DMR_MONO_MODE_20240201.patch delete mode 100644 patch/MTL_MONO_MODE_20240328.patch delete mode 100644 patch/cretu_no_dmr_idle.patch delete mode 100644 patch/dmr_data_voice_call_tg_src_persistency_ncurses2.patch delete mode 100644 patch/g_dmr_per_call_wav_file_fixes_w_custom_wav_dir_20240601b.patch diff --git a/include/dsd.h b/include/dsd.h index e145a3c..ae126d9 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -90,23 +90,29 @@ extern volatile uint8_t exitflag; //fix for issue #136 //event history (each item) typedef struct { - uint8_t write; //if this event needs to be written to a log file - int8_t systype; //indentifier of which decoded system type this is from (P25, DMR, etc) - int8_t subtype; //subtype of systpe (VLC, TLC, PDU data, System Event, etc) - uint8_t gi; //group or individual - uint8_t enc; //clear or encrypted - uint8_t enc_alg; //alg if encrypted - uint16_t enc_key; //enc key id value, if encrypted (not key value or key variable) - uint64_t mi; //mi, or iv base value from OTA if provided - uint16_t svc; //other relevant svc opts if applicable - uint32_t source_id;//source radio id or other source value - uint32_t target_id;//group or individual target, or destination value - uint32_t channel; //if this occurs on a trunking channel, which channel - time_t event_time; //time event occurred + uint8_t write; //if this event needs to be written to a log file + int8_t systype; //indentifier of which decoded system type this is from (P25, DMR, etc) + int8_t subtype; //subtype of systpe (VLC, TLC, PDU data, System Event, etc) + uint32_t sys_id1; //sys_id1 through 5 will be a hierarchy of system identifiers + uint32_t sys_id2; //for example, trunked P25 has WACN:SYS:CC:SITE_ID:RFSS_ID + uint32_t sys_id3; //conventional may only use NAC, RAN, or Color Codes + uint32_t sys_id4; // + uint32_t sys_id5; // + uint8_t gi; //group or individual + uint8_t enc; //clear or encrypted + uint8_t enc_alg; //alg if encrypted + uint16_t enc_key; //enc key id value, if encrypted (not key value or key variable) + uint64_t mi; //mi, or iv base value from OTA if provided + uint16_t svc; //other relevant svc opts if applicable + uint32_t source_id; //source radio id or other source value + uint32_t target_id; //group or individual target, or destination value + uint32_t channel; //if this occurs on a trunking channel, which channel + time_t event_time; //time event occurred - uint8_t pdu[128*24]; //relevant link control, or full PDU if data call (in bytes) - char alias[2000]; //if this event has a source radio talker alias or similar - char gps_s[2000]; //gps, if returned, expressed as a string + uint8_t pdu[128*24]; //relevant link control, or full PDU if data call (in bytes) + char sysid_string[200]; //string comprised of system unique identifiers + char alias[2000]; //if this event has a source radio talker alias or similar + char gps_s[2000]; //gps, if returned, expressed as a string char text_message[2000]; //if this event is a decoded text message, then it goes here char event_string[2000]; //user legible and printable string for the event that happened } Event_History; @@ -658,6 +664,7 @@ typedef struct short pulse_raw_out_buffer; //HERE HERE unsigned int dmr_color_code; + unsigned int dmr_t3_syscode; unsigned int nxdn_last_ran; unsigned int nxdn_last_rid; unsigned int nxdn_last_tg; @@ -828,6 +835,8 @@ typedef struct unsigned short esk_mask; unsigned long long int edacs_site_id; + uint32_t edacs_sys_id; + uint32_t edacs_area_code; int edacs_lcn_count; //running tally of lcn's observed on edacs system int edacs_cc_lcn; //current lcn for the edacs control channel int edacs_vc_lcn; //current lcn for any active vc (not the one we are tuned/tuning to) @@ -1141,6 +1150,10 @@ 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); +SNDFILE * open_wav_file (char * dir, char * temp_filename, uint16_t sample_rate, uint8_t ext); +SNDFILE * close_wav_file(SNDFILE * wav_file); +SNDFILE * close_and_rename_wav_file(SNDFILE * wav_file, char * wav_out_filename, char * dir, Event_History_I * event_struct); +SNDFILE * close_and_delete_wav_file(SNDFILE * wav_file, char * wav_out_filename); void openSymbolOutFile (dsd_opts * opts, dsd_state * state); void closeSymbolOutFile (dsd_opts * opts, dsd_state * state); void writeRawSample (dsd_opts * opts, dsd_state * state, short sample); diff --git a/patch/DMR_MONO_MODE_20240201.patch b/patch/DMR_MONO_MODE_20240201.patch deleted file mode 100644 index 5403520..0000000 --- a/patch/DMR_MONO_MODE_20240201.patch +++ /dev/null @@ -1,51 +0,0 @@ -diff --git a/src/dmr_pi.c b/src/dmr_pi.c -index 55dfb83..33fb3ba 100644 ---- a/src/dmr_pi.c -+++ b/src/dmr_pi.c -@@ -14,6 +14,9 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC - { - UNUSED2(opts, CRCCorrect); - -+ //force slot to 0 if using dmr mono handling -+ if (opts->dmr_mono == 1) state->currentslot = 0; -+ - if((IrrecoverableErrors == 0)) - { - -diff --git a/src/dsd_frame.c b/src/dsd_frame.c -index 3b2a3e1..ba32618 100644 ---- a/src/dsd_frame.c -+++ b/src/dsd_frame.c -@@ -160,7 +160,8 @@ processFrame (dsd_opts * opts, dsd_state * state) - sprintf (state->slot2light, " slot2 "); - //we can safely open MBE on any MS or mono handling - if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) openMbeOutFile (opts, state); -- if (opts->p25_trunk == 0) dmrMSBootstrap (opts, state); -+ // if (opts->p25_trunk == 0) //line disabled to allow mono mode while trunking -+ dmrMSBootstrap (opts, state); - } - if (opts->dmr_mono == 1 && state->synctype == 32) - { -diff --git a/src/dsd_main.c b/src/dsd_main.c -index 7be5912..8db6dc3 100644 ---- a/src/dsd_main.c -+++ b/src/dsd_main.c -@@ -2302,13 +2302,13 @@ main (int argc, char **argv) - state.rf_mod = 0; // - opts.pulse_digi_rate_out = 8000; - opts.pulse_digi_out_channels = 2; -- opts.dmr_mono = 0; -- opts.dmr_stereo = 1; -+ opts.dmr_mono = 1; -+ opts.dmr_stereo = 0; //not sure if this will break anything - state.dmr_stereo = 0; //0 - // opts.setmod_bw = 7000; -- sprintf (opts.output_name, "DMR Stereo"); -- fprintf (stderr,"-fr / DMR Mono switch has been deprecated.\n"); -- fprintf (stderr,"Decoding DMR Stereo BS/MS Simplex\n"); -+ sprintf (opts.output_name, "DMR Mono"); -+ // fprintf (stderr,"-fr / DMR Mono switch enabled. \n NOTE: Some ENC options in Slot 2 may not work properly.\n"); -+ fprintf (stderr,"\n Decoding DMR Stereo BS/MS Simplex in Mono Single Slot Only Configuration.\n"); - - } - else if (optarg[0] == 'm') diff --git a/patch/MTL_MONO_MODE_20240328.patch b/patch/MTL_MONO_MODE_20240328.patch deleted file mode 100644 index 31a3f99..0000000 --- a/patch/MTL_MONO_MODE_20240328.patch +++ /dev/null @@ -1,152 +0,0 @@ -diff --git a/src/dmr_pi.c b/src/dmr_pi.c -index 7542c61..d1c8e39 100644 ---- a/src/dmr_pi.c -+++ b/src/dmr_pi.c -@@ -14,6 +14,9 @@ void dmr_pi (dsd_opts * opts, dsd_state * state, uint8_t PI_BYTE[], uint32_t CRC - { - UNUSED2(opts, CRCCorrect); - -+ //force slot to 0 if using dmr mono handling -+ if (opts->dmr_mono == 1) state->currentslot = 0; -+ - if((IrrecoverableErrors == 0)) - { - -diff --git a/src/dsd_audio2.c b/src/dsd_audio2.c -index 756e468..13316df 100644 ---- a/src/dsd_audio2.c -+++ b/src/dsd_audio2.c -@@ -988,6 +988,9 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state) - memset (stereo_samp2, 0, sizeof(stereo_samp2)); - memset (stereo_samp3, 0, sizeof(stereo_samp3)); - -+ if (opts->dmr_mono == 1) -+ memcpy (state->s_r4, state->s_l4, sizeof(state->s_r4)); -+ - //dmr enc checkdown for whether or not to fill the stereo sample or not for playback or writing - encL = encR = 0; - encL = (state->dmr_so >> 6) & 0x1; -@@ -1070,8 +1073,16 @@ void playSynthesizedVoiceSS3 (dsd_opts * opts, dsd_state * state) - } - - //flag either left or right as 'enc' to mute if B -- if (strcmp(modeL, "B") == 0) encL = 1; -- if (strcmp(modeR, "B") == 0) encR = 1; -+ if (strcmp(modeL, "B") == 0) -+ { -+ encL = 1; -+ encR = 1; -+ } -+ if (strcmp(modeR, "B") == 0) -+ { -+ encR = 1; -+ encL = 1; -+ } - - //check to see if we need to enable slot and toggle slot preference here - //this method will always favor slot 2 (this is a patch anyways, so....meh) -diff --git a/src/dsd_frame.c b/src/dsd_frame.c -index 577169c..275abb6 100644 ---- a/src/dsd_frame.c -+++ b/src/dsd_frame.c -@@ -160,7 +160,8 @@ processFrame (dsd_opts * opts, dsd_state * state) - sprintf (state->slot2light, " slot2 "); - //we can safely open MBE on any MS or mono handling - if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) openMbeOutFile (opts, state); -- if (opts->p25_trunk == 0) dmrMSBootstrap (opts, state); -+ // if (opts->p25_trunk == 0) //line disabled to allow mono mode while trunking -+ dmrMSBootstrap (opts, state); - } - if (opts->dmr_mono == 1 && state->synctype == 32) - { -diff --git a/src/dsd_main.c b/src/dsd_main.c -index 3ca7788..22462a0 100644 ---- a/src/dsd_main.c -+++ b/src/dsd_main.c -@@ -1645,9 +1645,9 @@ main (int argc, char **argv) - } - - #ifdef AERO_BUILD -- fprintf (stderr, "Build Version: AW (20231015) \n"); -+ fprintf (stderr, "Build Version: AW MTL (20240201) \n"); - #else -- fprintf (stderr, "Build Version: AW %s \n", GIT_TAG); -+ fprintf (stderr, "Build Version: AW MTL %s \n", GIT_TAG); - #endif - fprintf (stderr,"MBElib Version: %s\n", versionstr); - -@@ -2474,14 +2474,18 @@ main (int argc, char **argv) - opts.mod_qpsk = 0; - opts.mod_gfsk = 0; - state.rf_mod = 0; -- opts.dmr_stereo = 1; -- opts.dmr_mono = 0; -+ // opts.dmr_stereo = 1; -+ // opts.dmr_mono = 0; - // opts.setmod_bw = 7000; - opts.pulse_digi_rate_out = 8000; - opts.pulse_digi_out_channels = 2; -- sprintf (opts.output_name, "DMR"); -- -- fprintf (stderr,"Decoding DMR Stereo BS/MS Simplex\n"); -+ opts.dmr_mono = 1; -+ opts.dmr_stereo = 0; //not sure if this will break anything -+ state.dmr_stereo = 0; //0 -+ // opts.setmod_bw = 7000; -+ sprintf (opts.output_name, "DMR Mono"); -+ // fprintf (stderr,"-fr / DMR Mono switch enabled. \n NOTE: Some ENC options in Slot 2 may not work properly.\n"); -+ fprintf (stderr,"\n Decoding DMR Stereo BS/MS Simplex in Mono Single Slot Only Configuration.\n"); - } - //change ft to only do P25 and DMR (TDMA trunking modes) - else if (optarg[0] == 't') -@@ -2558,13 +2562,13 @@ main (int argc, char **argv) - state.rf_mod = 0; // - opts.pulse_digi_rate_out = 8000; - opts.pulse_digi_out_channels = 2; -- opts.dmr_mono = 0; -- opts.dmr_stereo = 1; -+ opts.dmr_mono = 1; -+ opts.dmr_stereo = 0; //not sure if this will break anything - state.dmr_stereo = 0; //0 - // opts.setmod_bw = 7000; -- sprintf (opts.output_name, "DMR Stereo"); -- fprintf (stderr,"-fr / DMR Mono switch has been deprecated.\n"); -- fprintf (stderr,"Decoding DMR Stereo BS/MS Simplex\n"); -+ sprintf (opts.output_name, "DMR Mono"); -+ // fprintf (stderr,"-fr / DMR Mono switch enabled. \n NOTE: Some ENC options in Slot 2 may not work properly.\n"); -+ fprintf (stderr,"\n Decoding DMR Stereo BS/MS Simplex in Mono Single Slot Only Configuration.\n"); - - } - else if (optarg[0] == 'm') -diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c -index 73965dc..e5b38aa 100644 ---- a/src/dsd_ncurses.c -+++ b/src/dsd_ncurses.c -@@ -2297,8 +2297,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (opts->ncurses_compact == 1) - { - printw ("------------------------------------------------------------------------------\n"); -- printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "AW (20231015)"); -- printw ("------------------------------------------------------------------------------\n"); -+ printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "AW MTL (20240328)"); -+ printw ("------------------------------------------------------------------------------\n"); - } - #elif LIMAZULUTWEAKS - if (opts->ncurses_compact == 1) -@@ -2336,12 +2336,12 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - #endif - #ifdef AERO_BUILD - if (i == 5) printw (" %s ", "Aero Build"); -- if (i == 6) printw (" AW (20231015) \n"); -+ if (i == 6) printw (" AW MTL (20240328) \n"); - #elif ZDEV_BUILD -- if (i == 5) printw (" %s ", "AW "); -+ if (i == 5) printw (" %s ", "AW MTL"); - if (i == 6) printw (" %s \n", GIT_TAG); -- #else -- if (i == 5) printw (" %s ", "AW "); -+ #else -+ if (i == 5) printw (" %s ", "AW MTL"); - if (i == 6) printw (" %s \n", GIT_TAG); - #endif - else printw ("\n"); diff --git a/patch/cretu_no_dmr_idle.patch b/patch/cretu_no_dmr_idle.patch deleted file mode 100644 index 0e0de8e..0000000 --- a/patch/cretu_no_dmr_idle.patch +++ /dev/null @@ -1,277 +0,0 @@ -diff --git a/include/dsd.h b/include/dsd.h -index 9ebf3f1..c5ac68a 100644 ---- a/include/dsd.h -+++ b/include/dsd.h -@@ -18,16 +18,16 @@ - */ - - //defined by CMakeLists.txt -- Disable by using cmake -DCOLORS=OFF .. --#ifdef PRETTY_COLORS --#define KNRM "\x1B[0m" --#define KRED "\x1B[31m" --#define KGRN "\x1B[32m" --#define KYEL "\x1B[33m" --#define KBLU "\x1B[34m" --#define KMAG "\x1B[35m" --#define KCYN "\x1B[36m" --#define KWHT "\x1B[37m" --#else -+// #ifdef PRETTY_COLORS -+// #define KNRM "\x1B[0m" -+// #define KRED "\x1B[31m" -+// #define KGRN "\x1B[32m" -+// #define KYEL "\x1B[33m" -+// #define KBLU "\x1B[34m" -+// #define KMAG "\x1B[35m" -+// #define KCYN "\x1B[36m" -+// #define KWHT "\x1B[37m" -+// #else - #define KNRM "" - #define KRED "" - #define KGRN "" -@@ -36,7 +36,7 @@ - #define KMAG "" - #define KCYN "" - #define KWHT "" --#endif -+// #endif - - #include "config.h" - #include -diff --git a/src/dmr_bs.c b/src/dmr_bs.c -index bdab262..17a9e70 100644 ---- a/src/dmr_bs.c -+++ b/src/dmr_bs.c -@@ -266,14 +266,14 @@ void dmrBS (dsd_opts * opts, dsd_state * state) - if ( strcmp (sync, DMR_BS_DATA_SYNC) == 0 ) - { - -- fprintf (stderr,"%s ", timestr); -+ // fprintf (stderr,"%s ", timestr); - if (internalslot == 0) - { - if (opts->inverted_dmr == 0) - { -- fprintf (stderr,"Sync: +DMR "); -+ // fprintf (stderr,"Sync: +DMR "); - } -- else fprintf (stderr,"Sync: -DMR "); -+ else {}//fprintf (stderr,"Sync: -DMR "); - - vc1 = 7; //set to 7 so we can see that we should not be on a VC unless a framesync comes in for it first - -@@ -284,9 +284,9 @@ void dmrBS (dsd_opts * opts, dsd_state * state) - { - if (opts->inverted_dmr == 0) - { -- fprintf (stderr,"Sync: +DMR "); -+ // fprintf (stderr,"Sync: +DMR "); - } -- else fprintf (stderr,"Sync: -DMR "); -+ else {}//fprintf (stderr,"Sync: -DMR "); - - vc2 = 7; //set to 7 so we can see that we should not be on a VC unless a framesync comes in for it first - -diff --git a/src/dmr_data.c b/src/dmr_data.c -index 87f4dfd..57e5647 100644 ---- a/src/dmr_data.c -+++ b/src/dmr_data.c -@@ -232,10 +232,10 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state) - sprintf(state->slot2light, "[sLoT2]"); - } - -- if (state->dmr_ms_mode == 0) -- { -- fprintf(stderr, "%s %s ", state->slot1light, state->slot2light); -- } -+ // if (state->dmr_ms_mode == 0) -+ // { -+ // fprintf(stderr, "%s %s ", state->slot1light, state->slot2light); -+ // } - - // Slot type - Second part - Parity bit - for (i = 0; i < 5; i++) -@@ -292,6 +292,13 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state) - info[(2*i) + 98] = (1 & (dibit >> 1)); // bit 1 - info[(2*i) + 99] = (1 & dibit); // bit 0 - } -+ -+ // if (state->dmr_ms_mode == 0 && burst != 0x09) -+ if (burst != 0x09) -+ { -+ printFrameSync (opts, state, "+DMR ", 90, NULL); //don't think the values matter -+ fprintf(stderr, "%s %s ", state->slot1light, state->slot2light); -+ } - - //don't run on MS Reverse Channel Data - if (state->dmr_ms_rc == 0) dmr_data_burst_handler(opts, state, (uint8_t *)info, burst); -@@ -303,15 +310,16 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state) - } - - //ending line break -- fprintf(stderr, "\n"); -+ if (burst != 0x09) -+ fprintf(stderr, "\n"); - - END: - if (SlotTypeOk == 0 || cach_okay != 1) - { -- fprintf (stderr, "%s", KRED); -- fprintf (stderr, "| CACH/Burst FEC ERR"); -- fprintf (stderr, "%s", KNRM); -- fprintf (stderr, "\n"); -+ // fprintf (stderr, "%s", KRED); -+ // fprintf (stderr, "| CACH/Burst FEC ERR"); -+ // fprintf (stderr, "%s", KNRM); -+ // fprintf (stderr, "\n"); - dmr_reset_blocks (opts, state); //failsafe to reset all data header and blocks when bad tact or slottype - } - -diff --git a/src/dmr_dburst.c b/src/dmr_dburst.c -index fe81158..078524d 100644 ---- a/src/dmr_dburst.c -+++ b/src/dmr_dburst.c -@@ -205,7 +205,7 @@ void dmr_data_burst_handler(dsd_opts * opts, dsd_state * state, uint8_t info[196 - //flag off prop head when not looking at data blocks - if (databurst != 0x6 && databurst != 0x7 && databurst != 0x8 && databurst != 0xA && databurst != 0xB) state->data_p_head[slot] = 0; - -- if (databurst != 0xEB) -+ if (databurst != 0xEB && databurst != 0x09) - { - if (state->dmr_ms_mode == 0) - { -diff --git a/src/dmr_flco.c b/src/dmr_flco.c -index 839b085..e43b568 100644 ---- a/src/dmr_flco.c -+++ b/src/dmr_flco.c -@@ -790,21 +790,23 @@ uint8_t dmr_cach (dsd_opts * opts, dsd_state * state, uint8_t cach_bits[25]) - crc = crc8_ok(slco_bits, 36); - - //only run SLCO on good everything -- if (h1 && h2 && h3 && crc) dmr_slco (opts, state, slco_bits); -- else -- { -- //this line break issue is wracking on my OCD for clean line breaks -- if (opts->payload == 1 && state->dmrburstL == 16 && state->currentslot == 0) ; //no line break if current slot is voice with payload enabled -- else if (opts->payload == 1 && state->dmrburstR == 16 && state->currentslot == 1) ; //no line break if current slot is voice with payload enabled -- else fprintf (stderr, "\n"); -- fprintf (stderr, "%s", KRED); -- fprintf (stderr, " SLCO CRC ERR"); -- fprintf (stderr, "%s", KNRM); -- if (opts->payload == 1 && state->dmrburstL == 16 && state->currentslot == 0) //if current slot is voice with payload enabled -- fprintf (stderr, "\n"); -- else if (opts->payload == 1 && state->dmrburstR == 16 && state->currentslot == 1) //if current slot is voice with payload enabled -- fprintf (stderr, "\n"); -- } -+ if (h1 && h2 && h3 && crc) {} //dmr_slco (opts, state, slco_bits); -+ // else -+ // { -+ // //this line break issue is wracking on my OCD for clean line breaks -+ // if (opts->payload == 1 && state->dmrburstL == 16 && state->currentslot == 0) {} //no line break if current slot is voice with payload enabled -+ // else if (opts->payload == 1 && state->dmrburstR == 16 && state->currentslot == 1) {} //no line break if current slot is voice with payload enabled -+ // else {} //fprintf (stderr, "\n"); -+ // // fprintf (stderr, "%s", KRED); -+ // // fprintf (stderr, " SLCO CRC ERR"); -+ // // fprintf (stderr, "%s", KNRM); -+ // if (opts->payload == 1 && state->dmrburstL == 16 && state->currentslot == 0) //if current slot is voice with payload enabled -+ // fprintf (stderr, "\n"); -+ // else if (opts->payload == 1 && state->dmrburstR == 16 && state->currentslot == 1) //if current slot is voice with payload enabled -+ // fprintf (stderr, "\n"); -+ // } -+ -+ UNUSED(opts); - - } - return (err); //return err value based on success or failure, even if we aren't checking it -@@ -935,8 +937,11 @@ void dmr_slco (dsd_opts * opts, dsd_state * state, uint8_t slco_bits[]) - uint8_t xpt_hash = (uint8_t)ConvertBitIntoBytes(&slco_bits[20], 8); //priority TG hash - - //initial line break -- fprintf (stderr, "\n"); -- fprintf (stderr, "%s", KYEL); -+ if (slco != 0) -+ { -+ fprintf (stderr, "\n"); -+ fprintf (stderr, "%s", KYEL); -+ } - - if (slco == 0x2) //C_SYS_Parms - { -@@ -973,7 +978,8 @@ void dmr_slco (dsd_opts * opts, dsd_state * state, uint8_t slco_bits[]) - else sprintf (state->dmr_site_parms, "TIII %s:%d-%d;%04X; ", model_str, net, site, syscode); - } - else if (slco == 0x0) //null -- fprintf (stderr, " SLCO NULL "); -+ // fprintf (stderr, " SLCO NULL "); -+ {} - else if (slco == 0x1) - { - fprintf (stderr, " Activity Update"); //102 361-2 7.1.3.2 -diff --git a/src/dsd_frame_sync.c b/src/dsd_frame_sync.c -index 062bb20..f47a447 100644 ---- a/src/dsd_frame_sync.c -+++ b/src/dsd_frame_sync.c -@@ -940,7 +940,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) - sprintf(state->ftype, "DMR "); - if (opts->errorbars == 1) - { -- printFrameSync (opts, state, "+DMR ", synctest_pos + 1, modulation); -+ // printFrameSync (opts, state, "+DMR ", synctest_pos + 1, modulation); - } - state->lastsynctype = 10; - state->last_cc_sync_time = time(NULL); -@@ -1068,7 +1068,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) - sprintf(state->ftype, "DMR "); - if (opts->errorbars == 1) //&& opts->dmr_stereo == 0 - { -- printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation); -+ // printFrameSync (opts, state, "-DMR ", synctest_pos + 1, modulation); - } - state->lastsynctype = 13; - state->last_cc_sync_time = time(NULL); -@@ -1443,7 +1443,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) - { - if ((opts->errorbars == 1) && (opts->verbose > 1) && (state->carrier == 1)) - { -- fprintf (stderr,"Sync: no sync\n"); -+ // fprintf (stderr,"Sync: no sync\n"); - // fprintf (stderr,"Press CTRL + C to close.\n"); - - } -diff --git a/src/dsd_main.c b/src/dsd_main.c -index 98f2ead..b09cb81 100644 ---- a/src/dsd_main.c -+++ b/src/dsd_main.c -@@ -1687,7 +1687,7 @@ main (int argc, char **argv) - } - - #ifdef AERO_BUILD -- fprintf (stderr, "Build Version: AW (20231015) \n"); -+ fprintf (stderr, "Build Version: AW (20240523) \n"); - #else - fprintf (stderr, "Build Version: AW %s \n", GIT_TAG); - #endif -diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c -index a5442af..514b9ae 100644 ---- a/src/dsd_ncurses.c -+++ b/src/dsd_ncurses.c -@@ -2423,7 +2423,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (opts->ncurses_compact == 1) - { - printw ("------------------------------------------------------------------------------\n"); -- printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "AW (20231015)"); -+ printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "AW (20240523)"); - printw ("------------------------------------------------------------------------------\n"); - } - #elif LIMAZULUTWEAKS -@@ -2462,8 +2462,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (i == 4 && opts->frame_m17 == 1) printw (" CODEC2"); - #endif - #ifdef AERO_BUILD -- if (i == 5) printw (" %s ", "Aero Build"); -- if (i == 6) printw (" AW (20231015) \n"); -+ if (i == 5) printw (" %s ", "Cretu Build"); -+ if (i == 6) printw (" AW (20240523) \n"); - #elif ZDEV_BUILD - if (i == 5) printw (" %s ", "AW "); - if (i == 6) printw (" %s \n", GIT_TAG); diff --git a/patch/dmr_data_voice_call_tg_src_persistency_ncurses2.patch b/patch/dmr_data_voice_call_tg_src_persistency_ncurses2.patch deleted file mode 100644 index d96855d..0000000 --- a/patch/dmr_data_voice_call_tg_src_persistency_ncurses2.patch +++ /dev/null @@ -1,120 +0,0 @@ -diff --git a/src/dmr_block.c b/src/dmr_block.c -index 893b0e8..e7f9de7 100644 ---- a/src/dmr_block.c -+++ b/src/dmr_block.c -@@ -783,6 +783,6 @@ void dmr_reset_blocks (dsd_opts * opts, dsd_state * state) - //reset some strings -- resetting call string here causes random blink on ncurses terminal (cap+) - // sprintf (state->call_string[0], "%s", " "); //21 spaces - // sprintf (state->call_string[1], "%s", " "); //21 spaces -- sprintf (state->dmr_lrrp_gps[0], "%s", ""); -- sprintf (state->dmr_lrrp_gps[1], "%s", ""); -+ // sprintf (state->dmr_lrrp_gps[0], "%s", ""); //disabled for dmr data call persistence #174 -+ // sprintf (state->dmr_lrrp_gps[1], "%s", ""); //disabled for dmr data call persistence #174 - } -\ No newline at end of file -diff --git a/src/dmr_data.c b/src/dmr_data.c -index 3541152..3cae906 100644 ---- a/src/dmr_data.c -+++ b/src/dmr_data.c -@@ -267,7 +267,20 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state) - state->color_code_ok = SlotTypeOk; - - //not sure why I still have two variables for this, need to look and see what state->color_code still ties into -- if (SlotTypeOk == 1) state->dmr_color_code = state->color_code; -+ if (SlotTypeOk == 1) -+ { -+ if (state->dmr_color_code != state->color_code) -+ { -+ //Zero out values on color code change #174 -+ state->lasttg = 0; -+ state->lasttgR =0; -+ state->lastsrc = 0; -+ state->lastsrcR = 0; -+ sprintf (state->dmr_lrrp_gps[0], "%s", ""); -+ sprintf (state->dmr_lrrp_gps[1], "%s", ""); -+ state->dmr_color_code = state->color_code; -+ } -+ } - - /* Reconstitute the burst type */ - burst = (uint8_t)((SlotType[4] << 3) + (SlotType[5] << 2) + (SlotType[6] << 1) + SlotType[7]); -diff --git a/src/dsd_main.c b/src/dsd_main.c -index 5531ef3..5598793 100644 ---- a/src/dsd_main.c -+++ b/src/dsd_main.c -@@ -257,10 +257,10 @@ if(opts->frame_m17 == 1) //&& opts->audio_in_type == 5 - //zero out right away if not trunking - if (opts->p25_trunk == 0) - { -- state->lasttg = 0; -- state->lastsrc = 0; -- state->lasttgR = 0; -- state->lastsrcR = 0; -+ // state->lasttg = 0; //disabled for dmr voice call persistence #174 -+ // state->lastsrc = 0; //disabled for dmr voice call persistence #174 -+ // state->lasttgR = 0; //disabled for dmr voice call persistence #174 -+ // state->lastsrcR = 0; //disabled for dmr voice call persistence #174 - - //zero out vc frequencies? - state->p25_vc_freq[0] = 0; -@@ -290,10 +290,10 @@ if(opts->frame_m17 == 1) //&& opts->audio_in_type == 5 - //mainly bugfix for ncurses and per call wavs (edacs) and also signal fade, etc - if (opts->p25_trunk == 1 && opts->p25_is_tuned == 1 && time(NULL) - state->last_cc_sync_time > opts->trunk_hangtime) - { -- state->lasttg = 0; -- state->lastsrc = 0; -- state->lasttgR = 0; -- state->lastsrcR = 0; -+ // state->lasttg = 0; //disabled for dmr voice call persistence #174 -+ // state->lastsrc = 0; //disabled for dmr voice call persistence #174 -+ // state->lasttgR = 0; //disabled for dmr voice call persistence #174 -+ // state->lastsrcR = 0; //disabled for dmr voice call persistence #174 - - } - -@@ -431,7 +431,7 @@ if(opts->frame_m17 == 1) //&& opts->audio_in_type == 5 - memset(state->dmr_alias_len, 0, sizeof(state->dmr_alias_len)); - memset(state->dmr_alias_block_segment, 0, sizeof(state->dmr_alias_block_segment)); - memset(state->dmr_embedded_gps, 0, sizeof(state->dmr_embedded_gps)); -- memset(state->dmr_lrrp_gps, 0, sizeof(state->dmr_lrrp_gps)); -+ // memset(state->dmr_lrrp_gps, 0, sizeof(state->dmr_lrrp_gps)); - - // memset(state->active_channel, 0, sizeof(state->active_channel)); - -diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c -index 4646e77..e9ecab1 100644 ---- a/src/dsd_ncurses.c -+++ b/src/dsd_ncurses.c -@@ -3104,7 +3104,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - } - - //LRRP -- if(state->dmrburstL != 16) //only during data and no trunking -+ // if(state->dmrburstL != 16) //only during data and no trunking //disabled for dmr data call persistence #174 - { - attron(COLOR_PAIR(4)); - printw ("%s", state->dmr_lrrp_gps[0]); -@@ -3298,7 +3298,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - } - - //LRRP -- if(state->dmrburstR != 16) //only during data and no trunking -+ // if(state->dmrburstR != 16) //only during data and no trunking //disabled for dmr data call persistence #174 - { - attron(COLOR_PAIR(4)); - printw ("%s", state->dmr_lrrp_gps[1]); -@@ -3978,10 +3978,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - dmr_reset_blocks (opts, state); - - //zero out additional items -- state->lasttg = 0; -- state->lasttgR = 0; -- state->lastsrc = 0; -- state->lastsrcR = 0; -+ // state->lasttg = 0; //disabled for dmr voice call persistence #174 -+ // state->lasttgR = 0; //disabled for dmr voice call persistence #174 -+ // state->lastsrc = 0; //disabled for dmr voice call persistence #174 -+ // state->lastsrcR = 0; //disabled for dmr voice call persistence #174 - state->payload_algid = 0; - state->payload_algidR = 0; - state->payload_keyid = 0; diff --git a/patch/g_dmr_per_call_wav_file_fixes_w_custom_wav_dir_20240601b.patch b/patch/g_dmr_per_call_wav_file_fixes_w_custom_wav_dir_20240601b.patch deleted file mode 100644 index 2b6f643..0000000 --- a/patch/g_dmr_per_call_wav_file_fixes_w_custom_wav_dir_20240601b.patch +++ /dev/null @@ -1,499 +0,0 @@ -diff --git a/src/dmr_csbk.c b/src/dmr_csbk.c -index 6ee44d6..45502a4 100644 ---- a/src/dmr_csbk.c -+++ b/src/dmr_csbk.c -@@ -520,6 +520,26 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 - //rigctl - if (opts->use_rigctl == 1) - { -+ -+ if (state->currentslot == 0) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } -+ } -+ else if (state->currentslot == 1) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } -+ } -+ - //Guess I forgot to add this condition here - if (GetCurrentFreq(opts->rigctl_sockfd) != state->p25_cc_freq) - dmr_reset_blocks (opts, state); //reset all block gathering since we are tuning away from current frequency -@@ -554,6 +574,26 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 - else if (opts->audio_in_type == 3) - { - #ifdef USE_RTLSDR -+ -+ if (state->currentslot == 0) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } -+ } -+ else if (state->currentslot == 1) -+ { -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } -+ } -+ - //Guess I forgot to add this condition here - uint32_t tempf = (uint32_t)state->p25_cc_freq; - if (opts->rtlsdr_center_freq != tempf) -diff --git a/src/dmr_flco.c b/src/dmr_flco.c -index 839b085..637debf 100644 ---- a/src/dmr_flco.c -+++ b/src/dmr_flco.c -@@ -298,20 +298,7 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - - if (type != 2) //VLC and EMB, set our target, source, so, and fid per channel - { -- if (state->currentslot == 0) -- { -- state->dmr_fid = fid; -- state->dmr_so = so; -- state->lasttg = target; -- state->lastsrc = source; -- } -- if (state->currentslot == 1) -- { -- state->dmr_fidR = fid; -- state->dmr_soR = so; -- state->lasttgR = target; -- state->lastsrcR = source; -- } -+ //moved per call further down past the call_string stuff - - //update cc amd vc sync time for trunking purposes (particularly Con+) - if (opts->p25_is_tuned == 1) -@@ -337,6 +324,12 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - //reset gain - if (opts->floating_point == 1) - state->aout_gain = opts->audio_gain; -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } - } - if (state->currentslot == 1) - { -@@ -350,6 +343,12 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - //reset gain - if (opts->floating_point == 1) - state->aout_gainR = opts->audio_gain; -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } - } - - } -@@ -612,6 +611,69 @@ void dmr_flco (dsd_opts * opts, dsd_state * state, uint8_t lc_bits[], uint32_t C - fprintf (stderr, "Key %010llX ", state->RR); - fprintf (stderr, "%s ", KNRM); - } -+ -+ if (type != 2) -+ { -+ if (state->currentslot == 0) -+ { -+ state->dmr_fid = fid; -+ state->dmr_so = so; -+ state->lasttg = target; -+ state->lastsrc = source; -+ char * timestr = NULL; -+ char * datestr = NULL; -+ timestr = getTime(); -+ datestr = getDate(); -+ -+ //setup a call string for the per call (group/private and/or emergency) -+ char cs[200]; memset (cs, 0, 200*sizeof(char)); -+ int x = 0; -+ for (int i = 0; i < 200; i++) -+ { -+ //copy over non space and non termination values from call string -+ if (i != 0 && state->call_string[0][i] != ' ' && state->call_string[0][i] != 0) -+ cs[x++] = state->call_string[0][i]; -+ } -+ cs[x] = 0; //terminate -+ -+ //open wav file here if not already opened -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f == NULL) -+ { -+ sprintf (opts->wav_out_file, "%s/%s %s CC %d - %s - TG %d - RD %d", opts->wav_out_dir, datestr, timestr, state->dmr_color_code, cs, target, source); -+ openWavOutFileL (opts, state); -+ } -+ free (timestr); free(datestr); -+ } -+ if (state->currentslot == 1) -+ { -+ state->dmr_fidR = fid; -+ state->dmr_soR = so; -+ state->lasttgR = target; -+ state->lastsrcR = source; -+ char * timestr = NULL; -+ char * datestr = NULL; -+ timestr = getTime(); -+ datestr = getDate(); -+ -+ //setup a call string for the per call (group/private and/or emergency) -+ char cs[200]; memset (cs, 0, 200*sizeof(char)); -+ int x = 0; -+ for (int i = 0; i < 200; i++) -+ { -+ //copy over non space and non termination values from call string -+ if (i != 0 && state->call_string[1][i] != ' ' && state->call_string[1][i] != 0) -+ cs[x++] = state->call_string[1][i]; -+ } -+ cs[x] = 0; //terminate -+ -+ //open wav file here if not already opened -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR == NULL) -+ { -+ sprintf (opts->wav_out_fileR, "%s/%s %s CC %d - %s - TG %d - RD %d", opts->wav_out_dir, datestr, timestr, state->dmr_color_code, cs, target, source); -+ openWavOutFileR (opts, state); -+ } -+ } -+ } - - } - -diff --git a/src/dsd_file.c b/src/dsd_file.c -index 6f4ecaa..f4b201d 100644 ---- a/src/dsd_file.c -+++ b/src/dsd_file.c -@@ -555,6 +555,16 @@ void closeWavOutFile (dsd_opts * opts, dsd_state * state) - UNUSED(state); - - sf_close(opts->wav_out_f); -+ char newfilename[1032]; -+ int result; UNUSED(result); -+ sprintf (newfilename, "%s.wav", opts->wav_out_file); -+ result = rename (opts->wav_out_file, newfilename); -+ // fprintf (stderr, "\n Close WAV FileF %s; Result: %d \n", newfilename, result); -+ -+ //copy back to wav_out_file string for ncurses display -+ memcpy (opts->wav_out_file, newfilename, 1023); -+ opts->wav_out_file[1023] = 0; -+ - } - - void closeWavOutFileL (dsd_opts * opts, dsd_state * state) -@@ -562,6 +572,16 @@ void closeWavOutFileL (dsd_opts * opts, dsd_state * state) - UNUSED(state); - - sf_close(opts->wav_out_f); -+ char newfilename[1032]; -+ int result; UNUSED(result); -+ sprintf (newfilename, "%s.wav", opts->wav_out_file); -+ result = rename (opts->wav_out_file, newfilename); -+ // fprintf (stderr, "\n Close WAV FileL %s; Result: %d \n", newfilename, result); -+ -+ //copy back to wav_out_file string for ncurses display -+ memcpy (opts->wav_out_file, newfilename, 1023); -+ opts->wav_out_file[1023] = 0; -+ - } - - void closeWavOutFileR (dsd_opts * opts, dsd_state * state) -@@ -569,6 +589,15 @@ void closeWavOutFileR (dsd_opts * opts, dsd_state * state) - UNUSED(state); - - sf_close(opts->wav_out_fR); -+ char newfilename[1032]; -+ int result; UNUSED(result); -+ sprintf (newfilename, "%s.wav", opts->wav_out_fileR); -+ result = rename (opts->wav_out_fileR, newfilename); -+ // fprintf (stderr, "\n Close WAV FileR %s; Result: %d \n", newfilename, result); -+ -+ //copy back to wav_out_file string for ncurses display -+ memcpy (opts->wav_out_fileR, newfilename, 1023); -+ opts->wav_out_fileR[1023] = 0; - } - - void closeWavOutFileRaw (dsd_opts * opts, dsd_state * state) -diff --git a/src/dsd_main.c b/src/dsd_main.c -index 3fb0893..a6d45e5 100644 ---- a/src/dsd_main.c -+++ b/src/dsd_main.c -@@ -107,6 +107,32 @@ void - noCarrier (dsd_opts * opts, dsd_state * state) - { - -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } -+ //end perCall wav file close -+ -+ //close any perCall wav files that are open -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_f != NULL) -+ { -+ closeWavOutFileL (opts, state); -+ opts->wav_out_f = NULL; -+ } -+ if (opts->dmr_stereo_wav == 1 && opts->wav_out_fR != NULL) -+ { -+ closeWavOutFileR (opts, state); -+ opts->wav_out_fR = NULL; -+ } -+ //end perCall wav file close -+ - // #ifdef AERO_BUILD //NOTE: Blame seems to be synctest8 not being initialized (will continue to test) - // //TODO: Investigate why getSymbol needs to be run first in this context...truly confused here - // if(opts->frame_m17 == 1) //&& opts->audio_in_type == 5 -@@ -1692,9 +1718,9 @@ main (int argc, char **argv) - } - - #ifdef AERO_BUILD -- fprintf (stderr, "Build Version: AW (20231015) \n"); -+ fprintf (stderr, "Build Version: AW (20240601) G Build\n"); - #else -- fprintf (stderr, "Build Version: AW %s \n", GIT_TAG); -+ fprintf (stderr, "Build Version: AW %s G Build\n", GIT_TAG); - #endif - fprintf (stderr,"MBElib Version: %s\n", versionstr); - -diff --git a/src/dsd_mbe.c b/src/dsd_mbe.c -index fe71539..2702b5d 100644 ---- a/src/dsd_mbe.c -+++ b/src/dsd_mbe.c -@@ -1197,7 +1197,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a - if (state->dmr_encL == 0 || opts->dmr_mute_encL == 0) - { - //write wav to per call on left channel Slot 1 -- writeSynthesizedVoice (opts, state); -+ if (opts->wav_out_f != NULL) -+ writeSynthesizedVoice (opts, state); - } - } - -@@ -1207,7 +1208,8 @@ processMbeFrame (dsd_opts * opts, dsd_state * state, char imbe_fr[8][23], char a - if (state->dmr_encR == 0 || opts->dmr_mute_encR == 0) - { - //write wav to per call on right channel Slot 2 -- writeSynthesizedVoiceR (opts, state); -+ if (opts->wav_out_fR != NULL) -+ writeSynthesizedVoiceR (opts, state); - } - } - -diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c -index a5442af..0cd538d 100644 ---- a/src/dsd_ncurses.c -+++ b/src/dsd_ncurses.c -@@ -1071,7 +1071,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) - if (choicec == 12) - { - //flesh out all closewavs and sprint "" wav filenames -- closeWavOutFile (opts, state); -+ // closeWavOutFile (opts, state); - closeWavOutFileL (opts, state); - closeWavOutFileR (opts, state); - //closeWavOutFileRaw (opts, state); -@@ -2153,7 +2153,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - char cs[200]; memcpy (cs, state->call_string[0], 200*sizeof(char)); - - //close old first, assign name based on time and radio, open wav file -- closeWavOutFileL (opts, state); -+ if (opts->wav_out_f != NULL) -+ closeWavOutFileL (opts, state); - - // sprintf (opts->wav_out_file, "%s/%s %s NXDN - RAN %d - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, rn, tgn, src); //original - sprintf (opts->wav_out_file, "%s/%s %s NXDN - RAN %d - %s - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, rn, cs, tgn, src); //with call string -@@ -2198,27 +2199,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - call_matrix[9][5] = time(NULL); - - //open wav file if enabled and both rd and tg are not 0 -- if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -- { -- //setup a call string for the per call (group/private and/or emergency) -- char cs[200]; memset (cs, 0, 200*sizeof(char)); -- int x = 0; -- for (int i = 0; i < 200; i++) -- { -- //copy over non space and non termination values from call string -- if (i != 0 && state->call_string[0][i] != ' ' && state->call_string[0][i] != 0) -- cs[x++] = state->call_string[0][i]; -- } -- cs[x] = 0; //terminate -- -- //close old first, assign name based on time and radio, open wav file -- closeWavOutFileL (opts, state); -- -- // sprintf (opts->wav_out_file, "%s/%s %s MS - CC %d - TG %d - RD %d.wav", opts->wav_out_dir, datestr, timestr, dcc, tg, rd); //original -- sprintf (opts->wav_out_file, "%s/%s %s MS - CC %d - %s - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, dcc, cs, tg, rd); //with cs call string -- -- openWavOutFileL (opts, state); //testing for now, will want to move to per call later -- } -+ // if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -+ // { -+ // //close old first, assign name based on time and radio, open wav file -+ // if (opts->wav_out_f != NULL) -+ // closeWavOutFileL (opts, state); -+ // sprintf (opts->wav_out_file, "./%s/%s %s MS - CC %d - TG %d - RD %d.wav", opts->wav_out_dir, getDateN(), timestr, dcc, tg, rd); -+ // openWavOutFileL (opts, state); //testing for now, will want to move to per call later -+ // } - - if (opts->call_alert == 1 && rd != 0 && tg != 0) - { -@@ -2233,7 +2221,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - } - - //DMR BS Slot 1 - matrix 0-4 -- if ( call_matrix[4][2] != rd && (lls == 11 || lls == 12 || lls == 10 || lls == 13 || lls == 35 || lls == 36) ) -+ if ( call_matrix[4][2] != rd && (lls == 11 || lls == 12 || lls == 10 || lls == 13 ) ) //|| lls == 35 || lls == 36 - { - - for (short int k = 0; k < 4; k++) -@@ -2254,27 +2242,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - call_matrix[4][5] = time(NULL); - - //open wav file if enabled and both rd and tg are not 0 -- if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -- { -- //setup a call string for the per call (group/private and/or emergency) -- char cs[200]; memset (cs, 0, 200*sizeof(char)); -- int x = 0; -- for (int i = 0; i < 200; i++) -- { -- //copy over non space and non termination values from call string -- if (i != 0 && state->call_string[0][i] != ' ' && state->call_string[0][i] != 0) -- cs[x++] = state->call_string[0][i]; -- } -- cs[x] = 0; //terminate -- -- //close old first, assign name based on time and radio, open wav file -- closeWavOutFileL (opts, state); -- -- // sprintf (opts->wav_out_file, "%s/%s %s CC %d - TG %d - RD %d.wav", opts->wav_out_dir, datestr, timestr, dcc, tg, rd); //original -- sprintf (opts->wav_out_file, "%s/%s %s CC %d - %s - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, dcc, cs, tg, rd); //with call string -- -- openWavOutFileL (opts, state); //testing for now, will want to move to per call later -- } -+ // if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) -+ // { -+ // //close old first, assign name based on time and radio, open wav file -+ // if (opts->wav_out_f != NULL) -+ // closeWavOutFileL (opts, state); -+ // sprintf (opts->wav_out_file, "./%s/%s %s CC %d - TG %d - RD %d", opts->wav_out_dir, getDateN(), timestr, dcc, tg, rd); -+ // openWavOutFileL (opts, state); //testing for now, will want to move to per call later -+ // } - - if (opts->call_alert == 1 && rd != 0 && tg != 0) - { -@@ -2310,34 +2285,21 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - call_matrix[9][5] = time(NULL); - - //open wav file if enabled and both rdR and tgR are not 0 -- if (opts->dmr_stereo_wav == 1 && rdR != 0 && tgR != 0) -- { -- //setup a call string for the per call (group/private and/or emergency) -- char cs[200]; memset (cs, 0, 200*sizeof(char)); -- int x = 0; -- for (int i = 0; i < 200; i++) -- { -- //copy over non space and non termination values from call string -- if (i != 0 && state->call_string[1][i] != ' ' && state->call_string[1][i] != 0) -- cs[x++] = state->call_string[1][i]; -- } -- cs[x] = 0; //terminate -- -- //close old first, assign name based on time and radio, open wav file -- closeWavOutFileR (opts, state); -- -- // sprintf (opts->wav_out_fileR, "%s/%s %s CC %d - TG %d - RD %d.wav", opts->wav_out_dir, datestr, timestr, dcc, tgR, rdR); //original -- sprintf (opts->wav_out_fileR, "%s/%s %s CC %d - %s - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, dcc, cs, tgR, rdR); //with call string -- -- openWavOutFileR (opts, state); //testing for now, will want to move to per call later -- } -+ // if (opts->dmr_stereo_wav == 1 && rdR != 0 && tgR != 0) -+ // { -+ // //close old first, assign name based on time and radio, open wav file -+ // if (opts->wav_out_fR != NULL) -+ // closeWavOutFileR (opts, state); -+ // sprintf (opts->wav_out_fileR, "./%s/%s %s CC %d - TG %d - RD %d", opts->wav_out_dir, getDateN(), timestr, dcc, tgR, rdR); -+ // openWavOutFileR (opts, state); //testing for now, will want to move to per call later -+ // } - -- if (opts->call_alert == 1 && rdR != 0 && tgR != 0) -- { -- //fprintf (stderr, "BEEP 1 BS RIGHT\n"); -- beeper (opts, state, 1); -- state->dmr_end_alert[1] = 0; //new voice frame, okay to beep at the end of it -- } -+ // if (opts->call_alert == 1 && rdR != 0 && tgR != 0) -+ // { -+ // //fprintf (stderr, "BEEP 1 BS RIGHT\n"); -+ // beeper (opts, state, 1); -+ // state->dmr_end_alert[1] = 0; //new voice frame, okay to beep at the end of it -+ // } - - memset(state->dmr_alias_block_segment[1], 0, sizeof(state->dmr_alias_block_segment[1])); - sprintf (state->dmr_embedded_gps[1], "%s", ""); -@@ -2423,8 +2385,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (opts->ncurses_compact == 1) - { - printw ("------------------------------------------------------------------------------\n"); -- printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "AW (20231015)"); -- printw ("------------------------------------------------------------------------------\n"); -+ printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "AW (20240601)"); -+ printw ("------------------------------------------------------------------------------\n"); - } - #elif LIMAZULUTWEAKS - if (opts->ncurses_compact == 1) -@@ -2462,13 +2424,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (i == 4 && opts->frame_m17 == 1) printw (" CODEC2"); - #endif - #ifdef AERO_BUILD -- if (i == 5) printw (" %s ", "Aero Build"); -- if (i == 6) printw (" AW (20231015) \n"); -+ if (i == 5) printw (" %s ", "G Build"); -+ if (i == 6) printw (" AW (20240601) \n"); - #elif ZDEV_BUILD -- if (i == 5) printw (" %s ", "AW "); -+ if (i == 5) printw (" %s ", "AW G Build"); - if (i == 6) printw (" %s \n", GIT_TAG); -- #else -- if (i == 5) printw (" %s ", "AW "); -+ #else -+ if (i == 5) printw (" %s ", "AW G Build"); - if (i == 6) printw (" %s \n", GIT_TAG); - #endif - else printw ("\n"); -@@ -4426,7 +4388,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) - if (c == 112) //'p' key - stop all per call wav files - { - //hope this one doesn't cause random crashing or garbage writing -- closeWavOutFile (opts, state); -+ // closeWavOutFile (opts, state); - closeWavOutFileL (opts, state); - closeWavOutFileR (opts, state); - sprintf (opts->wav_out_file, "%s", ""); diff --git a/src/dmr_csbk.c b/src/dmr_csbk.c index 20d4cd1..6a0e70c 100644 --- a/src/dmr_csbk.c +++ b/src/dmr_csbk.c @@ -2371,6 +2371,9 @@ void dmr_decode_syscode(dsd_opts * opts, dsd_state * state, uint8_t * cs_pdu_bit //raw syscode uint16_t syscode = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[40], 14); + if (type == 0) + state->dmr_t3_syscode = syscode; + uint8_t model = (uint8_t)ConvertBitIntoBytes(&cs_pdu_bits[40], 2); uint16_t net = 0; uint16_t site = 0; diff --git a/src/dsd_file.c b/src/dsd_file.c index 43bc13f..34f2664 100644 --- a/src/dsd_file.c +++ b/src/dsd_file.c @@ -439,6 +439,115 @@ void openMbeOutFileR (dsd_opts * opts, dsd_state * state) } } +//temp filename should not have the .wav extension, will be renamed with one after event is closed +SNDFILE * open_wav_file (char * dir, char * temp_filename, uint16_t sample_rate, uint8_t ext) +{ + uint16_t random_number = rand(); + char * datestr = getDate(); + char * timestr = getTime(); + + if (ext == 0) + sprintf (temp_filename, "%s/TEMP_%s_%s_%04X", dir, datestr, timestr, random_number); + else sprintf (temp_filename, "%s/TEMP_%s_%s_%04X.wav", dir, datestr, timestr, random_number); + + if (timestr != NULL) + { + free (timestr); + timestr = NULL; + } + if (datestr != NULL) + { + free (datestr); + datestr = NULL; + } + + SNDFILE * wav; + SF_INFO info; + info.samplerate = sample_rate; + info.channels = 1; + info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 | SF_ENDIAN_LITTLE; + wav = sf_open (temp_filename, SFM_RDWR, &info); //RDWR will append to file instead of overwrite file + + if (wav == NULL) + { + fprintf (stderr,"Error - could not open wav output file %s\n", temp_filename); + return NULL; + } + + return wav; +} + +SNDFILE * close_wav_file(SNDFILE * wav_file) +{ + sf_close(wav_file); + wav_file = NULL; + return wav_file; +} + +SNDFILE * close_and_rename_wav_file(SNDFILE * wav_file, char * wav_out_filename, char * dir, Event_History_I * event_struct) +{ + sf_close(wav_file); + + char * datestr = getDate(); + char * timestr = getTime(); + uint16_t random_number = rand(); + + uint32_t source_id = event_struct->Event_History_Items[0].source_id; + uint32_t target_id = event_struct->Event_History_Items[0].target_id; + + //give extension .wav after closing + char new_filename[2000]; + memset (new_filename, 0, sizeof(new_filename)); + + sprintf (new_filename, "%s/%s_%s_%05d_%s_TGT_%d_SRC_%d.wav", dir, datestr, timestr, random_number, event_struct->Event_History_Items[0].sysid_string, target_id, source_id); + + if (timestr != NULL) + { + free (timestr); + timestr = NULL; + } + if (datestr != NULL) + { + free (datestr); + datestr = NULL; + } + + rename (wav_out_filename, new_filename); + + //WIP: Open File, seek, and if 44 bytes, delete it (empty wav file) + //TODO: May need to move the deletion ahead of renaming, and do a NULL check, + //some software may attempt to injest an empty .wav file first, but this should + //occur so quickly, the watchdog on rdio or similar shouldn't even realize it + //may also consider checking for a larger size, something that's more than a blip + //sometimes if encrypted and no key provided, if signal is marginal, short garbled audio + //could be written to a wav file, so may look into a value >= xx kb in size minimum + FILE *file = fopen(new_filename, "r"); + if (file != NULL) + { + fseek(file, 0, SEEK_END); + long size = ftell(file); + fseek(file, 0, SEEK_SET); // Rewind to beginning + fclose(file); + + //debug + // fprintf (stderr, " Closed Wav File %s; Size: %d; \n", new_filename, size); + + if (size == 44) + remove (new_filename); + } + + wav_file = NULL; + return wav_file; +} + +SNDFILE * close_and_delete_wav_file(SNDFILE * wav_file, char * wav_out_filename) +{ + sf_close(wav_file); + wav_file = NULL; + remove (wav_out_filename); + return wav_file; +} + void openWavOutFile (dsd_opts * opts, dsd_state * state) { UNUSED(state); diff --git a/src/dsd_main.c b/src/dsd_main.c index 94fd3fc..2de8b76 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -196,12 +196,6 @@ opts->p25_is_tuned = 0; state->edacs_tuned_lcn = -1; - //only for EDACS/PV - if (opts->p25_trunk == 1 && opts->frame_provoice == 1 && opts->wav_out_file != NULL) - { - closeWavOutFile(opts, state); - } - state->last_cc_sync_time = time(NULL); //test to switch back to 10/4 P1 QPSK for P25 FDMA CC @@ -1149,6 +1143,8 @@ state->edacs_vc_call_type = 0; state->esk_mask = 0x0; //esk mask value state->edacs_site_id = 0; + state->edacs_sys_id = 0; + state->edacs_area_code = 0; state->edacs_lcn_count = 0; state->edacs_cc_lcn = 0; state->edacs_vc_lcn = 0; @@ -1320,6 +1316,7 @@ #endif state->dmr_color_code = 16; + state->dmr_t3_syscode = 0; state->event_history_s = calloc(1, 10000000000); //TODO: tweak this size later on @@ -1340,7 +1337,7 @@ printf ("\n"); printf ("Display Options:\n"); printf (" -N Use NCurses Terminal\n"); - printf (" dsd-fme -N 2> log.ans \n"); + printf (" dsd-fme -N 2> console_log.txt \n"); printf (" -Z Log MBE/PDU Payloads to console\n"); printf ("\n"); printf ("Device Options:\n"); @@ -1391,7 +1388,7 @@ printf (" -g Audio Digital Output Gain (Default: 0 = Auto; )\n"); printf (" (Manual: 1 = 2%%; 50 = 100%%)\n"); printf (" -n Audio Analog Output Gain (Default: 0 = Auto; 0-100%% )\n"); - printf (" -w Output synthesized speech to a .wav file, FDMA modes only.\n"); + //printf (" -w Output synthesized speech to a .wav file, FDMA modes only.\n"); //disabled printf (" -6 Output raw audio .wav file (48K/1). (WARNING! Large File Sizes 1 Hour ~= 360 MB)\n"); printf (" -7 Create/Use Custom directory for Per Call decoded .wav file saving.\n"); printf (" (Use ./folder for Nested Directory!)\n"); @@ -1681,19 +1678,15 @@ #endif noCarrier (opts, state); - if (opts->wav_out_f != NULL) - { - closeWavOutFile (opts, state); - } - if (opts->wav_out_raw != NULL) - { - closeWavOutFileRaw (opts, state); - } - if (opts->dmr_stereo_wav == 1) //cause of crash on exit, need to check if NULL first, may need to set NULL when turning off in nterm - { - closeWavOutFileL (opts, state); - closeWavOutFileR (opts, state); - } + + if (opts->wav_out_f != NULL) + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, &state->event_history_s[0]); + if (opts->wav_out_fR != NULL) + opts->wav_out_fR = close_and_rename_wav_file(opts->wav_out_fR, opts->wav_out_fileR, opts->wav_out_dir, &state->event_history_s[1]); + if (opts->wav_out_raw != NULL) + opts->wav_out_raw = close_wav_file(opts->wav_out_raw); + + //no if statement first? closeSymbolOutFile (opts, state); #ifdef USE_RTLSDR @@ -2175,22 +2168,21 @@ else fprintf (stderr,"Writing wav decoded audio files to directory %s\n", opts.wav_out_dir); break; - case 'P': //TDMA/NXDN Per Call - was T, now is P - sprintf (wav_file_directory, "%s", opts.wav_out_dir); - wav_file_directory[1023] = '\0'; - if (stat(wav_file_directory, &st) == -1) - { - fprintf (stderr, "-P %s WAV file directory does not exist\n", wav_file_directory); - fprintf (stderr, "Creating directory %s to save decoded wav files\n", wav_file_directory); - mkdir(wav_file_directory, 0700); //user read write execute, needs execute for some reason or segfault - } - fprintf (stderr,"AUTO and NXDN Per Call Wav File Saving Enabled. (NCurses Terminal Only)\n"); - sprintf (opts.wav_out_file, "%s/DSD-FME-X1.wav", opts.wav_out_dir); - sprintf (opts.wav_out_fileR, "%s/DSD-FME-X2.wav", opts.wav_out_dir); - opts.dmr_stereo_wav = 1; - openWavOutFileL (&opts, &state); - openWavOutFileR (&opts, &state); - break; + case 'P': //Per Call Wav Files + sprintf (wav_file_directory, "%s", opts.wav_out_dir); + wav_file_directory[1023] = '\0'; + if (stat(wav_file_directory, &st) == -1) + { + fprintf (stderr, "-P %s WAV file directory does not exist\n", wav_file_directory); + fprintf (stderr, "Creating directory %s to save decoded wav files\n", wav_file_directory); + mkdir(wav_file_directory, 0700); //user read write execute, needs execute for some reason or segfault + } + fprintf (stderr,"Per Call Wav File Enabled.\n"); + srand(time(NULL)); //seed random for filenames (so two filenames aren't the exact same datetime string on initailization) + opts.wav_out_f = open_wav_file(opts.wav_out_dir, opts.wav_out_file, 8000, 0); + opts.wav_out_fR = open_wav_file(opts.wav_out_dir, opts.wav_out_fileR, 8000, 0); + opts.dmr_stereo_wav = 1; + break; case 'F': opts.aggressive_framesync = 0; @@ -2255,13 +2247,13 @@ } break; - case 'w': - strncpy(opts.wav_out_file, optarg, 1023); - opts.wav_out_file[1023] = '\0'; - fprintf (stderr,"Writing + Appending decoded audio to file %s\n", opts.wav_out_file); - opts.dmr_stereo_wav = 0; - openWavOutFile (&opts, &state); - break; + // case 'w': //disabled + // strncpy(opts.wav_out_file, optarg, 1023); + // opts.wav_out_file[1023] = '\0'; + // fprintf (stderr,"Writing + Appending decoded audio to file %s\n", opts.wav_out_file); + // opts.dmr_stereo_wav = 0; + // openWavOutFile (&opts, &state); + // break; case '6': strncpy(opts.wav_out_file_raw, optarg, 1023); diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index d29e77b..5738dfc 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -371,7 +371,7 @@ int starty = 0; char *choicesc[] = { "Return", - "Save Decoded Audio WAV (Legacy Mode)", + " ", //Save Decoded Audio WAV (Legacy Mode) //Disabled "Save Signal to Symbol Capture Bin", "Toggle Muting Encrypted Traffic ", "Save Per Call Decoded WAV", @@ -654,23 +654,23 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) break; } print_menuc(test_win, highlightc); - if (choicec == 2) - { - char * timestr = getTime(); - char * datestr = getDate(); - sprintf (opts->wav_out_file, "%s %s DSD-FME-DECODED.wav", datestr, timestr); - if (timestr != NULL) - { - free (timestr); - timestr = NULL; - } - if (datestr != NULL) - { - free (datestr); - datestr = NULL; - } - openWavOutFile (opts, state); - } + // if (choicec == 2) //Legacy Decode to single wav file is disabled + // { + // char * timestr = getTime(); + // char * datestr = getDate(); + // sprintf (opts->wav_out_file, "%s %s DSD-FME-DECODED.wav", datestr, timestr); + // if (timestr != NULL) + // { + // free (timestr); + // timestr = NULL; + // } + // if (datestr != NULL) + // { + // free (datestr); + // datestr = NULL; + // } + // openWavOutFile (opts, state); + // } if (choicec == 3) { //read in filename for symbol capture bin @@ -718,12 +718,11 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) fprintf (stderr, "Creating directory %s to save decoded wav files\n", wav_file_directory); mkdir(wav_file_directory, 0700); } + fprintf (stderr,"\n Per Call Wav File Enabled to Directory: %s;.\n", opts->wav_out_dir); + srand(time(NULL)); //seed random for filenames (so two filenames aren't the exact same datetime string on initailization) + opts->wav_out_f = open_wav_file(opts->wav_out_dir, opts->wav_out_file, 8000, 0); + opts->wav_out_fR = open_wav_file(opts->wav_out_dir, opts->wav_out_fileR, 8000, 0); opts->dmr_stereo_wav = 1; - //catch all in case of no file name set, won't crash or something - sprintf (opts->wav_out_file, "%s/DSD-FME-X1.wav", opts->wav_out_dir); // - sprintf (opts->wav_out_fileR, "%s/DSD-FME-X2.wav", opts->wav_out_dir); // - openWavOutFileL (opts, state); - openWavOutFileR (opts, state); } @@ -1072,13 +1071,11 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) if (choicec == 12) { - //flesh out all closewavs and sprint "" wav filenames - closeWavOutFile (opts, state); - closeWavOutFileL (opts, state); - closeWavOutFileR (opts, state); - //closeWavOutFileRaw (opts, state); - sprintf (opts->wav_out_file, "%s", ""); - sprintf (opts->wav_out_fileR, "%s", ""); + //TODO: Add Closing of RAW files as well? + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, &state->event_history_s[0]); + opts->wav_out_fR = close_and_rename_wav_file(opts->wav_out_fR, opts->wav_out_fileR, opts->wav_out_dir, &state->event_history_s[1]); + opts->wav_out_file[0] = 0; //Bugfix for decoded wav file display after disabling + opts->wav_out_fileR[0] = 0; opts->dmr_stereo_wav = 0; } @@ -2227,22 +2224,6 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) sprintf (alias_ch[9], "%s", ""); sprintf (state->str50a, "%s", ""); - //open wav file if enabled and both rd and tg are not 0 - if (opts->dmr_stereo_wav == 1 && src != 0 ) //&& tgn != 0, some TG can be 0 on NXDN - { - //setup a call string for the per call (group/private and/or emergency) - //No Space Skips / Truncates Needed on NXDN string variant - char cs[200]; memcpy (cs, state->call_string[0], 200*sizeof(char)); - - //close old first, assign name based on time and radio, open wav file - closeWavOutFileL (opts, state); - - // sprintf (opts->wav_out_file, "%s/%s %s NXDN - RAN %d - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, rn, tgn, src); //original - sprintf (opts->wav_out_file, "%s/%s %s NXDN - RAN %d - %s - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, rn, cs, tgn, src); //with call string - - openWavOutFileL (opts, state); //testing for now, will want to move to per call later - } - if (opts->call_alert == 1) { beeper (opts, state, 0); @@ -2279,29 +2260,6 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) call_matrix[9][4] = dcc; call_matrix[9][5] = time(NULL); - //open wav file if enabled and both rd and tg are not 0 - if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) - { - //setup a call string for the per call (group/private and/or emergency) - char cs[200]; memset (cs, 0, 200*sizeof(char)); - int x = 0; - for (int i = 0; i < 200; i++) - { - //copy over non space and non termination values from call string - if (i != 0 && state->call_string[0][i] != ' ' && state->call_string[0][i] != 0) - cs[x++] = state->call_string[0][i]; - } - cs[x] = 0; //terminate - - //close old first, assign name based on time and radio, open wav file - closeWavOutFileL (opts, state); - - // sprintf (opts->wav_out_file, "%s/%s %s MS - CC %d - TG %d - RD %d.wav", opts->wav_out_dir, datestr, timestr, dcc, tg, rd); //original - sprintf (opts->wav_out_file, "%s/%s %s MS - CC %d - %s - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, dcc, cs, tg, rd); //with cs call string - - openWavOutFileL (opts, state); //testing for now, will want to move to per call later - } - if (opts->call_alert == 1 && rd != 0 && tg != 0) { //fprintf (stderr, "BEEP 0 MS LEFT\n"); @@ -2335,29 +2293,6 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) call_matrix[4][4] = dcc; call_matrix[4][5] = time(NULL); - //open wav file if enabled and both rd and tg are not 0 - if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) - { - //setup a call string for the per call (group/private and/or emergency) - char cs[200]; memset (cs, 0, 200*sizeof(char)); - int x = 0; - for (int i = 0; i < 200; i++) - { - //copy over non space and non termination values from call string - if (i != 0 && state->call_string[0][i] != ' ' && state->call_string[0][i] != 0) - cs[x++] = state->call_string[0][i]; - } - cs[x] = 0; //terminate - - //close old first, assign name based on time and radio, open wav file - closeWavOutFileL (opts, state); - - // sprintf (opts->wav_out_file, "%s/%s %s CC %d - TG %d - RD %d.wav", opts->wav_out_dir, datestr, timestr, dcc, tg, rd); //original - sprintf (opts->wav_out_file, "%s/%s %s CC %d - %s - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, dcc, cs, tg, rd); //with call string - - openWavOutFileL (opts, state); //testing for now, will want to move to per call later - } - if (opts->call_alert == 1 && rd != 0 && tg != 0) { //fprintf (stderr, "BEEP 0 BS LEFT\n"); @@ -2391,29 +2326,6 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) call_matrix[9][4] = dcc; call_matrix[9][5] = time(NULL); - //open wav file if enabled and both rdR and tgR are not 0 - if (opts->dmr_stereo_wav == 1 && rdR != 0 && tgR != 0) - { - //setup a call string for the per call (group/private and/or emergency) - char cs[200]; memset (cs, 0, 200*sizeof(char)); - int x = 0; - for (int i = 0; i < 200; i++) - { - //copy over non space and non termination values from call string - if (i != 0 && state->call_string[1][i] != ' ' && state->call_string[1][i] != 0) - cs[x++] = state->call_string[1][i]; - } - cs[x] = 0; //terminate - - //close old first, assign name based on time and radio, open wav file - closeWavOutFileR (opts, state); - - // sprintf (opts->wav_out_fileR, "%s/%s %s CC %d - TG %d - RD %d.wav", opts->wav_out_dir, datestr, timestr, dcc, tgR, rdR); //original - sprintf (opts->wav_out_fileR, "%s/%s %s CC %d - %s - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, dcc, cs, tgR, rdR); //with call string - - openWavOutFileR (opts, state); //testing for now, will want to move to per call later - } - if (opts->call_alert == 1 && rdR != 0 && tgR != 0) { //fprintf (stderr, "BEEP 1 BS RIGHT\n"); @@ -2446,29 +2358,6 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) call_matrix[9][4] = nc; call_matrix[9][5] = time(NULL); - //open wav file if enabled and both rd and tg are not 0 - if (opts->dmr_stereo_wav == 1 && rd != 0 && tg != 0) - { - //setup a call string for the per call (group/private and/or emergency) - char cs[200]; memset (cs, 0, 200*sizeof(char)); - int x = 0; - for (int i = 0; i < 200; i++) - { - //copy over non space and non termination values from call string - if (i != 0 && state->call_string[0][i] != ' ' && state->call_string[0][i] != 0) - cs[x++] = state->call_string[0][i]; - } - cs[x] = 0; //terminate - - //close old first, assign name based on time and radio, open wav file - closeWavOutFileL (opts, state); - - // sprintf (opts->wav_out_file, "%s/%s %s P1 - NAC %X - TGT %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, nc, tg, rd); //original - sprintf (opts->wav_out_file, "%s/%s %s P1 - NAC %X - %s - DST %d - SRC %d.wav", opts->wav_out_dir, datestr, timestr, nc, cs, tg, rd); //with call string - - openWavOutFileL (opts, state); //testing for now, will want to move to per call later - } - if (opts->call_alert == 1) { beeper (opts, state, 0); @@ -2716,11 +2605,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) printw ("| Decoded WAV Output: %s\n", opts->wav_out_file); } - if (opts->dmr_stereo_wav == 1) //opts->wav_out_file[0] != 0 && - { - printw ("| Per Call - %s\n", opts->wav_out_file); - if (opts->dmr_stereo == 1) printw ("| Per Call - %s\n", opts->wav_out_fileR); - } + //new Per Call setup would just be random names until closed, + //so no need to show, and will be in the event history anyways + if (opts->dmr_stereo_wav == 1) + printw ("| Per Call Wav File Enabled to Directory: %s \n", opts->wav_out_dir); #ifdef PRETTY_COLORS if (opts->p25_trunk == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3) ) @@ -4325,36 +4213,31 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) } #endif - - - if (c == 80) //'P' key - start per call wav files + if (c == 80) //'P' key - start per call wav files //TODO: Fix { char wav_file_directory[1024]; sprintf (wav_file_directory, "%s", opts->wav_out_dir); wav_file_directory[1023] = '\0'; if (stat(wav_file_directory, &st_wav) == -1) { - fprintf (stderr, "-T %s wav file directory does not exist\n", wav_file_directory); + fprintf (stderr, "%s wav file directory does not exist\n", wav_file_directory); fprintf (stderr, "Creating directory %s to save decoded wav files\n", wav_file_directory); mkdir(wav_file_directory, 0700); } + fprintf (stderr,"\n Per Call Wav File Enabled to Directory: %s;.\n", opts->wav_out_dir); + srand(time(NULL)); //seed random for filenames (so two filenames aren't the exact same datetime string on initailization) + opts->wav_out_f = open_wav_file(opts->wav_out_dir, opts->wav_out_file, 8000, 0); + opts->wav_out_fR = open_wav_file(opts->wav_out_dir, opts->wav_out_fileR, 8000, 0); opts->dmr_stereo_wav = 1; - //catch all in case of no file name set, won't crash or something - sprintf (opts->wav_out_file, "%s/DSD-FME-T1.wav", opts->wav_out_dir); - sprintf (opts->wav_out_fileR, "%s/DSD-FME-T2.wav", opts->wav_out_dir); - openWavOutFileL (opts, state); - openWavOutFileR (opts, state); } - //this one could cause issues, but seems okay - if (c == 112) //'p' key - stop all per call wav files + if (c == 112) //'p' key - stop all per call wav files //TODO: Fix { - //hope this one doesn't cause random crashing or garbage writing - closeWavOutFile (opts, state); - closeWavOutFileL (opts, state); - closeWavOutFileR (opts, state); - sprintf (opts->wav_out_file, "%s", ""); - sprintf (opts->wav_out_fileR, "%s", ""); + //TODO: Add Closing of RAW files as well? + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, &state->event_history_s[0]); + opts->wav_out_fR = close_and_rename_wav_file(opts->wav_out_fR, opts->wav_out_fileR, opts->wav_out_dir, &state->event_history_s[1]); + opts->wav_out_file[0] = 0; //Bugfix for decoded wav file display after disabling + opts->wav_out_fileR[0] = 0; opts->dmr_stereo_wav = 0; } @@ -4906,6 +4789,11 @@ void init_event_history (Event_History_I * event_struct, uint8_t start, uint8_t event_struct->Event_History_Items[i].write = 0; event_struct->Event_History_Items[i].systype = -1; event_struct->Event_History_Items[i].subtype = -1; + event_struct->Event_History_Items[i].sys_id1 = 0; + event_struct->Event_History_Items[i].sys_id2 = 0; + event_struct->Event_History_Items[i].sys_id3 = 0; + event_struct->Event_History_Items[i].sys_id4 = 0; + event_struct->Event_History_Items[i].sys_id5 = 0; event_struct->Event_History_Items[i].gi = 0; event_struct->Event_History_Items[i].enc = 0; event_struct->Event_History_Items[i].enc_alg = 0; @@ -4918,6 +4806,7 @@ void init_event_history (Event_History_I * event_struct, uint8_t start, uint8_t event_struct->Event_History_Items[i].event_time = 0; memset (event_struct->Event_History_Items[i].pdu, 0, sizeof(event_struct->Event_History_Items[0].pdu)); + sprintf (event_struct->Event_History_Items[i].sysid_string, "%s", ""); sprintf (event_struct->Event_History_Items[i].alias, "%s", "BUMBLEBEETUNA"); sprintf (event_struct->Event_History_Items[i].gps_s, "%s", "BUMBLEBEETUNA"); sprintf (event_struct->Event_History_Items[i].text_message, "%s", "BUMBLEBEETUNA"); @@ -4934,6 +4823,11 @@ void push_event_history (Event_History_I * event_struct) event_struct->Event_History_Items[i].write = event_struct->Event_History_Items[i-1].write; event_struct->Event_History_Items[i].systype = event_struct->Event_History_Items[i-1].systype; event_struct->Event_History_Items[i].subtype = event_struct->Event_History_Items[i-1].subtype; + event_struct->Event_History_Items[i].sys_id1 = event_struct->Event_History_Items[i-1].sys_id1; + event_struct->Event_History_Items[i].sys_id2 = event_struct->Event_History_Items[i-1].sys_id2; + event_struct->Event_History_Items[i].sys_id3 = event_struct->Event_History_Items[i-1].sys_id3; + event_struct->Event_History_Items[i].sys_id4 = event_struct->Event_History_Items[i-1].sys_id4; + event_struct->Event_History_Items[i].sys_id5 = event_struct->Event_History_Items[i-1].sys_id5; event_struct->Event_History_Items[i].gi = event_struct->Event_History_Items[i-1].gi; event_struct->Event_History_Items[i].enc = event_struct->Event_History_Items[i-1].enc; event_struct->Event_History_Items[i].enc_alg = event_struct->Event_History_Items[i-1].enc_alg; @@ -4946,6 +4840,7 @@ void push_event_history (Event_History_I * event_struct) event_struct->Event_History_Items[i].event_time = event_struct->Event_History_Items[i+1].event_time; memcpy (event_struct->Event_History_Items[i].pdu, event_struct->Event_History_Items[i-1].pdu, sizeof(event_struct->Event_History_Items[0].pdu)); + sprintf (event_struct->Event_History_Items[i].sysid_string, "%s", event_struct->Event_History_Items[i-1].sysid_string); sprintf (event_struct->Event_History_Items[i].alias, "%s", event_struct->Event_History_Items[i-1].alias); sprintf (event_struct->Event_History_Items[i].gps_s, "%s", event_struct->Event_History_Items[i-1].gps_s); sprintf (event_struct->Event_History_Items[i].text_message, "%s", event_struct->Event_History_Items[i-1].text_message); @@ -5004,11 +4899,9 @@ void watchdog_event_history (dsd_opts * opts, dsd_state * state, uint8_t slot) source_id += state->ysf_src[i]; //convert to sum value to make a distinct enough src value } - if (state->lastsynctype == 16 || state->lastsynctype == 17) //M17 STR + if (state->lastsynctype == 8 || state->lastsynctype == 9 || state->lastsynctype == 16 || state->lastsynctype == 17) //M17 STR { - source_id = 0; - for (uint8_t i = 0; i < 9; i++) - source_id += state->m17_src_csd[i]; //convert to sum value to make a distinct enough src value + source_id = (uint32_t)state->m17_src; } if (state->lastsynctype == 6 || state->lastsynctype == 7 || state->lastsynctype == 18 || state->lastsynctype == 19) //DSTAR @@ -5022,7 +4915,7 @@ void watchdog_event_history (dsd_opts * opts, dsd_state * state, uint8_t slot) source_id = 0; } - if (state->lastsynctype == 16 || state->lastsynctype == 17 || state->lastsynctype == 20 || state->lastsynctype == 24 || state->lastsynctype == 21 || state->lastsynctype == 25 || state->lastsynctype == 22 || state->lastsynctype == 26 || state->lastsynctype == 23 || state->lastsynctype == 27) //dPMR + if (state->lastsynctype == 20 || state->lastsynctype == 24 || state->lastsynctype == 21 || state->lastsynctype == 25 || state->lastsynctype == 22 || state->lastsynctype == 26 || state->lastsynctype == 23 || state->lastsynctype == 27) //dPMR { source_id = 0; for (uint8_t i = 0; i < 20; i++) @@ -5042,14 +4935,31 @@ void watchdog_event_history (dsd_opts * opts, dsd_state * state, uint8_t slot) } - if (source_id != last_source_id && last_source_id != 0) //test without != 0 if we want to constantly update the current event + if (source_id != last_source_id && last_source_id != 0) { if (opts->event_out_file[0] != 0) write_event_to_log_file(opts, state, event_struct->Event_History_Items[0].event_string); + if (slot == 0 && opts->wav_out_f != NULL) + { + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, event_struct); + opts->wav_out_f = open_wav_file(opts->wav_out_dir, opts->wav_out_file, 8000, 0); + } + + else if (slot == 1 && opts->wav_out_fR != NULL) + { + opts->wav_out_fR = close_and_rename_wav_file(opts->wav_out_fR, opts->wav_out_fileR, opts->wav_out_dir, event_struct); + opts->wav_out_fR = open_wav_file(opts->wav_out_dir, opts->wav_out_fileR, 8000, 0); + } + push_event_history (event_struct); init_event_history (event_struct, 0, 1); + + //clear out some strings and things + memset(state->ysf_txt, 0, sizeof(state->ysf_txt)); + memset(state->dstar_gps, 0, sizeof(state->dstar_gps)); + memset(state->dstar_txt, 0, sizeof(state->dstar_txt)); } } @@ -5069,11 +4979,22 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) uint16_t svc_opts = 0; uint8_t subtype = 0; + uint32_t sys_id1 = 0; + uint32_t sys_id2 = 0; + uint32_t sys_id3 = 0; + uint32_t sys_id4 = 0; + uint32_t sys_id5 = 0; + + uint32_t channel = 0; + uint8_t enc = 0; uint8_t alg_id = 0; uint16_t key_id = 0; unsigned long long int mi; + char sysid_string[200]; memset(sysid_string, 0, sizeof(sysid_string)); + sprintf (sysid_string, "%s", ""); + if (slot == 0) { source_id = state->lastsrc; @@ -5102,6 +5023,30 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) mi = state->payload_miR; } + //if P25 (if not P25, then these will all be zero anyways) + sys_id1 = state->p2_wacn; + sys_id2 = state->p2_sysid; + if (state->nac != 0) + sys_id3 = state->nac; //same as state->p2_cc, but zeroes out when no signal or error + else sys_id3 = state->p2_cc; + sys_id4 = state->p2_rfssid; + sys_id5 = state->p2_siteid; + + if (sys_id1) + sprintf (sysid_string, "P25_%05X%03X%03X_%d_%d", sys_id1, sys_id2, sys_id3, sys_id4, sys_id5); + else sprintf (sysid_string, "P25_%03X", sys_id3); + + if (state->lastsynctype == 10 || state->lastsynctype == 11 || state->lastsynctype == 12 || state->lastsynctype == 13 || + state->lastsynctype == 32 || state->lastsynctype == 33 || state->lastsynctype == 34 ) + { + sys_id1 = state->dmr_t3_syscode; + sys_id2 = state->dmr_color_code; + + if (sys_id1) + sprintf (sysid_string, "DMR_%X_CC_%d", sys_id1, sys_id2); + else sprintf (sysid_string, "DMR_CC_%d", sys_id2); + } + if (slot == 0) //BUGFIX: generic catch on FDMA systems so that we don't write duplicate data to slot 2 event history { //NXDN RID (TODO: Changeover to lastsrc and lasttg later on) @@ -5112,6 +5057,14 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) if (state->nxdn_cipher_type != 0) enc = 1; alg_id = state->nxdn_cipher_type; + + sys_id1 = state->nxdn_location_site_code; + sys_id2 = state->nxdn_location_sys_code; + sys_id3 = state->nxdn_last_ran; //might be an issue on conventional systems that have a different RAN on the tx_rel or idle data bursts + + if (sys_id1) + sprintf (sysid_string, "NXDN_%d_%d_RAN_%d", sys_id2, sys_id1, sys_id3); + else sprintf (sysid_string, "NXDN_RAN_%d", sys_id3); } if (state->lastsynctype == 30 || state->lastsynctype == 30) //YSF Fusion @@ -5120,14 +5073,33 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) for (uint8_t i = 0; i < 11; i++) source_id += state->ysf_src[i]; //convert to sum value to make a distinct enough src value - //TODO: Add src and dst as aliases? + //WIP: If Text, compile it here (still having issues with an empty txt string making a line break) + uint8_t k = 0; char ysf_emp[21][21]; memset(ysf_emp, 0, sizeof(ysf_emp)); + if (memcmp(ysf_emp, state->ysf_txt, sizeof(state->ysf_txt)) != 0) + { + for (uint8_t i = 4; i < 8; i++) + { + for (uint8_t j = 0; j < 20; j++) + { + if (state->ysf_txt[i][j] != 0x2A) + event_struct->Event_History_Items[0].text_message[k++] = state->ysf_txt[i][j]; + else event_struct->Event_History_Items[0].text_message[k++] = 0x20; //space + + } + event_struct->Event_History_Items[0].text_message[k] = 0; //terminate + } + } + else sprintf (event_struct->Event_History_Items[0].text_message, "%s", "BUMBLEBEETUNA"); + + sprintf (sysid_string, "%s", "YSF"); } - if (state->lastsynctype == 16 || state->lastsynctype == 17) //M17 STR + if (state->lastsynctype == 8 || state->lastsynctype == 9 || state->lastsynctype == 16 || state->lastsynctype == 17) //M17 STR { - source_id = 0; - for (uint8_t i = 0; i < 9; i++) - source_id += state->m17_src_csd[i]; //convert to sum value to make a distinct enough src value + target_id = (uint32_t)state->m17_dst; + source_id = (uint32_t)state->m17_src; + sys_id1 = state->m17_can; + sprintf (sysid_string, "M17_CAN_%d", sys_id1); } if (state->lastsynctype == 6 || state->lastsynctype == 7 || state->lastsynctype == 18 || state->lastsynctype == 19) //DSTAR @@ -5139,9 +5111,11 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) //need a strncmp here for 8 spaces in this field first so we don't blip a blank into the event history if (strncmp(state->dstar_src, " ", 8) == 0) source_id = 0; + + sprintf (sysid_string, "%s", "DSTAR"); } - if (state->lastsynctype == 16 || state->lastsynctype == 17 || state->lastsynctype == 20 || state->lastsynctype == 24 || state->lastsynctype == 21 || state->lastsynctype == 25 || state->lastsynctype == 22 || state->lastsynctype == 26 || state->lastsynctype == 23 || state->lastsynctype == 27) //dPMR + if (state->lastsynctype == 20 || state->lastsynctype == 24 || state->lastsynctype == 21 || state->lastsynctype == 25 || state->lastsynctype == 22 || state->lastsynctype == 26 || state->lastsynctype == 23 || state->lastsynctype == 27) //dPMR { source_id = 0; for (uint8_t i = 0; i < 20; i++) @@ -5150,19 +5124,59 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) //need a strncmp here for 8 spaces in this field first so we don't blip a blank into the event history if (strncmp(state->dpmr_caller_id, " ", 6) == 0) source_id = 0; + + sprintf (sysid_string, "DPMR_CC_%d", state->dpmr_color_code); } if (state->lastsynctype == 14 || state->lastsynctype == 15 || state->lastsynctype == 37 || state->lastsynctype == 38) //EDACS Calls { source_id = 0; if (opts->p25_is_tuned == 1) + { source_id = state->lastsrc; + channel = state->edacs_tuned_lcn; + } + + sys_id1 = state->edacs_site_id; + sys_id2 = state->edacs_area_code; + sys_id3 = state->edacs_sys_id; + svc_opts = state->edacs_vc_call_type; + char sup_str[200]; memset (sup_str, 0, sizeof(sup_str)); + sprintf (sup_str, "%s", "_"); + if (svc_opts & 0x02) + strcat (sup_str, "Digital_"); + else strcat (sup_str, "Analog_"); + if (svc_opts & 0x04) + strcat (sup_str, "Emergency_"); + if (svc_opts & 0x08) + strcat (sup_str, "Group_"); + if (svc_opts & 0x10) + strcat (sup_str, "I_"); + if (svc_opts & 0x20) + strcat (sup_str, "ALL_"); + if (svc_opts & 0x40) + strcat (sup_str, "INTER_"); + if (svc_opts & 0x80) + strcat (sup_str, "TEST_"); + if (svc_opts & 0x100) + strcat (sup_str, "AGENCY_"); + if (svc_opts & 0x200) + strcat (sup_str, "FLEET_"); + if (svc_opts & 0x01) + strcat (sup_str, "Voice_"); + strcat (sup_str, "Call"); + + sprintf (sysid_string, "EDACS_SITE_%03d", sys_id1); + strcat (sysid_string, sup_str); + } } //system type string (P25, DMR, etc) - char * sys_string = SyncTypes[state->lastsynctype]; + char * sys_string = "Digital"; + if (state->lastsynctype != -1) + sys_string = SyncTypes[state->lastsynctype]; //date and time strings char * timestr = getTimeN(time(NULL)); @@ -5176,6 +5190,11 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) else event_struct->Event_History_Items[0].systype = 39; //generic digital call event_struct->Event_History_Items[0].subtype = subtype; //voice event_struct->Event_History_Items[0].gi = state->gi[slot]; //need this add this to link control messages + event_struct->Event_History_Items[0].sys_id1 = sys_id1; + event_struct->Event_History_Items[0].sys_id2 = sys_id2; + event_struct->Event_History_Items[0].sys_id3 = sys_id3; + event_struct->Event_History_Items[0].sys_id4 = sys_id4; + event_struct->Event_History_Items[0].sys_id5 = sys_id5; event_struct->Event_History_Items[0].enc = enc; event_struct->Event_History_Items[0].enc_alg = alg_id; event_struct->Event_History_Items[0].enc_key = key_id; @@ -5183,8 +5202,9 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) event_struct->Event_History_Items[0].svc = svc_opts; event_struct->Event_History_Items[0].source_id = source_id; event_struct->Event_History_Items[0].target_id = target_id; - event_struct->Event_History_Items[0].channel = 0; //need to add this to trunking messages, if tuned from call grant + event_struct->Event_History_Items[0].channel = channel; //need to add this to trunking messages, if tuned from call grant event_struct->Event_History_Items[0].event_time = time(NULL); + sprintf (event_struct->Event_History_Items[0].sysid_string, "%s", sysid_string); } //Craft an event string for ncurses event history, and a more complex string for logging @@ -5192,25 +5212,28 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) //WIP: Seperate Voice Call Event Strings when SRC/TGT values are numerical, //and a seperate one for when they are string values (M17, YSF, DSTAR, and dPMR, or use special formatting) - if (state->lastsynctype == 30 || state->lastsynctype == 30) //YSF Fusion (may need to use uplink instead of src, unsure for this) + if (state->lastsynctype == 30 || state->lastsynctype == 30) //YSF Fusion //TODO: Data calls dumping a lot of events as VOICE { //TODO: See if we can add some decoded data as well in the future to an event string - sprintf (event_string, "%s %s %s Voice TGT: %s SRC: %s ", datestr, timestr, sys_string, state->ysf_tgt, state->ysf_src); + sprintf (event_string, "%s %s %s TGT: %s SRC: %s ", datestr, timestr, sys_string, state->ysf_tgt, state->ysf_src); } else if (state->lastsynctype == 16 || state->lastsynctype == 17) //M17 { //TODO: See if we can add some decoded data as well in the future to an event string - sprintf (event_string, "%s %s %s Voice TGT: %s SRC: %s ", datestr, timestr, sys_string, state->m17_dst_str, state->m17_src_str); + if (state->m17_dst == 0xFFFFFFFFFFFF) + sprintf (event_string, "%s %s %s TGT: %s SRC: %s CAN: %02d;", datestr, timestr, sys_string, "BROADCAST", state->m17_src_str, state->m17_can); + else + sprintf (event_string, "%s %s %s TGT: %s SRC: %s CAN: %02d;", datestr, timestr, sys_string, state->m17_dst_str, state->m17_src_str, state->m17_can); } else if (state->lastsynctype == 6 || state->lastsynctype == 7 || state->lastsynctype == 18 || state->lastsynctype == 19) //DSTAR { //TODO: See if we can add some decoded data as well in the future to an event string - sprintf (event_string, "%s %s %s Voice TGT: %s SRC: %s ", datestr, timestr, sys_string, state->dstar_dst, state->dstar_src); + sprintf (event_string, "%s %s %s TGT: %s SRC: %s ", datestr, timestr, sys_string, state->dstar_dst, state->dstar_src); } - else if (state->lastsynctype == 16 || state->lastsynctype == 17 || state->lastsynctype == 20 || state->lastsynctype == 24 || state->lastsynctype == 21 || state->lastsynctype == 25 || state->lastsynctype == 22 || state->lastsynctype == 26 || state->lastsynctype == 23 || state->lastsynctype == 27) //dPMR + else if (state->lastsynctype == 20 || state->lastsynctype == 24 || state->lastsynctype == 21 || state->lastsynctype == 25 || state->lastsynctype == 22 || state->lastsynctype == 26 || state->lastsynctype == 23 || state->lastsynctype == 27) //dPMR { //TODO: See if we can add some decoded data as well in the future to an event string - sprintf (event_string, "%s %s %s Voice TGT: %s SRC: %s ", datestr, timestr, sys_string, state->dpmr_target_id, state->dpmr_caller_id); + sprintf (event_string, "%s %s %s TGT: %s SRC: %s ", datestr, timestr, sys_string, state->dpmr_target_id, state->dpmr_caller_id); } //TODO: Find out why EDACS is also placing items into Slot 2 Event History with valid src, but invalid tg (not a problem, just odd) else if (state->lastsynctype == 14 || state->lastsynctype == 15 || state->lastsynctype == 37 || state->lastsynctype == 38) //EDACS Calls @@ -5218,7 +5241,7 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) //is this AFS format, or EA format, also, need to re-add Ilya's other decoded call elements into this somehow if (state->ea_mode == 1) { - sprintf (event_string, "%s %s %s Voice TGT: %05d; SRC: %05d; ", datestr, timestr, sys_string, target_id, source_id); + sprintf (event_string, "%s %s %s TGT: %07d; SRC: %07d; LCN: %02d; SITE: %d:%d.%04X; ", datestr, timestr, sys_string, target_id, source_id, channel, sys_id1, sys_id2, sys_id3); } else { @@ -5232,15 +5255,48 @@ void watchdog_event_current (dsd_opts * opts, dsd_state * state, uint8_t slot) sprintf (event_string, "%s %s %s Voice AFS: %s ", datestr, timestr, sys_string, afs_str); } } - else //any numerical based src and tgt values + else if (state->lastsynctype == 10 || state->lastsynctype == 11 || state->lastsynctype == 12 || state->lastsynctype == 13 || + state->lastsynctype == 32 || state->lastsynctype == 33 || state->lastsynctype == 34 ) //DMR { - sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; ", datestr, timestr, sys_string, target_id, source_id); + if (sys_id1) + sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; CC: %02d; SYS: %X; ", datestr, timestr, sys_string, target_id, source_id, sys_id2, sys_id1); + else + sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; CC: %02d; ", datestr, timestr, sys_string, target_id, source_id, sys_id2); if (enc) strcat(event_string, "ENC; "); + if (alg_id != 0) + { + char ess_str[30]; + sprintf (ess_str, "ALG: %02X; KID: %02X;", alg_id, key_id); + strcat(event_string, ess_str); + } + } + else if (state->lastsynctype == 0 || state->lastsynctype == 1 || state->lastsynctype == 35 || state->lastsynctype == 36) + { + if (sys_id1) + sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; NAC: %03X; SYS: %05X:%03X:%d.%d; ", datestr, timestr, sys_string, target_id, source_id, sys_id3, sys_id1, sys_id2, sys_id4, sys_id5); + else + sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; NAC: %03X; ", datestr, timestr, sys_string, target_id, source_id, sys_id3); if (alg_id != 0 && alg_id != 0x80) { char ess_str[30]; - sprintf (ess_str, "ALG: %02X; KID: %04X;", alg_id, key_id); //KID overflow? + sprintf (ess_str, "ENC; ALG: %02X; KID: %04X;", alg_id, key_id); + strcat(event_string, ess_str); + } + } + + else if (state->lastsynctype == 28 || state->lastsynctype == 29) + { + if (sys_id1) + sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; RAN: %02d; SYS: %d.%d; ", datestr, timestr, sys_string, target_id, source_id, sys_id3, sys_id1, sys_id2); + else + sprintf (event_string, "%s %s %s Voice TGT: %08d; SRC: %08d; RAN: %02d; ", datestr, timestr, sys_string, target_id, source_id, sys_id3); + if (enc) + strcat(event_string, "ENC; "); + if (alg_id != 0) + { + char ess_str[30]; + sprintf (ess_str, "ALG: %d; KID: %02X;", alg_id, key_id); strcat(event_string, ess_str); } } diff --git a/src/dstar.c b/src/dstar.c index 3eb0941..8b66f69 100644 --- a/src/dstar.c +++ b/src/dstar.c @@ -338,6 +338,9 @@ void processDSTAR_SD(dsd_opts * opts, dsd_state * state, uint8_t * sd) //this seems to work okay with a few samples, but wouldn't be surprised if it broke down //randomly on different users, depending on location and what else in in $$CRC + + sprintf (state->event_history_s[0].Event_History_Items[0].text_message, "%s", state->dstar_gps); //disable this later + sprintf (state->event_history_s[0].Event_History_Items[0].gps_s, "%s", state->dstar_gps); } else { @@ -355,6 +358,7 @@ void processDSTAR_SD(dsd_opts * opts, dsd_state * state, uint8_t * sd) } strt[59] = '\0'; memcpy (state->dstar_txt, strt, sizeof(strt)); + sprintf (state->event_history_s[0].Event_History_Items[0].text_message, "%s", state->dstar_txt); } } @@ -374,6 +378,7 @@ void processDSTAR_SD(dsd_opts * opts, dsd_state * state, uint8_t * sd) } strt[59] = '\0'; memcpy (state->dstar_txt, strt, sizeof(strt)); + sprintf (state->event_history_s[0].Event_History_Items[0].text_message, "%s", state->dstar_txt); } //anything else else //print entire thing diff --git a/src/edacs-fme.c b/src/edacs-fme.c index 2a28bd6..3bef92e 100644 --- a/src/edacs-fme.c +++ b/src/edacs-fme.c @@ -374,10 +374,6 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn if (opts->use_ncurses_terminal == 1) ncursesPrinter(opts, state); - //slot 1 - watchdog_event_history(opts, state, 0); - watchdog_event_current(opts, state, 0); - //write to wav file if opened if (opts->wav_out_f != NULL) { @@ -421,6 +417,7 @@ void edacs_analog(dsd_opts * opts, dsd_state * state, int afs, unsigned char lcn if (count > 0) fprintf (stderr, "\n"); } + } void edacs(dsd_opts * opts, dsd_state * state) @@ -654,6 +651,9 @@ void edacs(dsd_opts * opts, dsd_state * state) } fprintf (stderr, " :: System ID [%04X] CC LCN [%02d]%s", system, state->edacs_cc_lcn, getLcnStatusString(lcn)); + if (system != 0) + state->edacs_sys_id = system; + //check for control channel lcn frequency if not provided in channel map or in the lcn list if (state->trunk_lcn_freq[state->edacs_cc_lcn-1] == 0) { @@ -690,6 +690,7 @@ void edacs(dsd_opts * opts, dsd_state * state) fprintf (stderr, " Extended Addressing :: Site ID [%02llX][%03lld] Area [%02X][%03d]", site_id, site_id, area, area); fprintf (stderr, "%s", KNRM); state->edacs_site_id = site_id; + state->edacs_area_code = area; } //System Dynamic Regroup Plan Bitmap else if (mt2 == 0xB) @@ -967,6 +968,9 @@ void edacs(dsd_opts * opts, dsd_state * state) } } + //debug for analog testing + // is_digital = 0; + //TG hold on EDACS EA -- block non-matching target, allow matching group if (state->tg_hold != 0 && state->tg_hold != group) sprintf (mode, "%s", "B"); if (state->tg_hold != 0 && state->tg_hold == group) sprintf (mode, "%s", "A"); @@ -979,11 +983,12 @@ void edacs(dsd_opts * opts, dsd_state * state) //openwav file and do per call right here, should probably check as well to make sure we have a valid trunking method active (rigctl, rtl) if (opts->dmr_stereo_wav == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3)) { - sprintf (opts->wav_out_file, "./WAV/%s %s EDACS Site %lld TG %d SRC %d.wav", datestr, timestr, state->edacs_site_id, group, source); - if (is_digital == 1) - openWavOutFile (opts, state); - else - openWavOutFile48k (opts, state); + if (is_digital == 1) {} //just write to already open temp file to be renamed later + else //close the temp 8k wav file and open as 48k + { + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, &state->event_history_s[0]); + opts->wav_out_f = open_wav_file(opts->wav_out_dir, opts->wav_out_file, 48000, 0); + } } //do condition here, in future, will allow us to use tuning methods as well, or rtl_udp as well @@ -1094,11 +1099,12 @@ void edacs(dsd_opts * opts, dsd_state * state) //openwav file and do per call right here, should probably check as well to make sure we have a valid trunking method active (rigctl, rtl) if (opts->dmr_stereo_wav == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3)) { - sprintf (opts->wav_out_file, "./WAV/%s %s EDACS Site %lld TGT %d SRC %d I-Call.wav", datestr, timestr, state->edacs_site_id, target, source); - if (is_digital == 1) - openWavOutFile (opts, state); - else - openWavOutFile48k (opts, state); + if (is_digital == 1) {} //just write to already open temp file to be renamed later + else //close the temp 8k wav file and open as 48k + { + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, &state->event_history_s[0]); + opts->wav_out_f = open_wav_file(opts->wav_out_dir, opts->wav_out_file, 48000, 0); + } } //do condition here, in future, will allow us to use tuning methods as well, or rtl_udp as well @@ -1200,11 +1206,12 @@ void edacs(dsd_opts * opts, dsd_state * state) //openwav file and do per call right here, should probably check as well to make sure we have a valid trunking method active (rigctl, rtl) if (opts->dmr_stereo_wav == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3)) { - sprintf (opts->wav_out_file, "./WAV/%s %s EDACS Site %lld SRC %d All-Call.wav", datestr, timestr, state->edacs_site_id, source); - if (is_digital == 1) - openWavOutFile (opts, state); - else - openWavOutFile48k (opts, state); + if (is_digital == 1) {} //just write to already open temp file to be renamed later + else //close the temp 8k wav file and open as 48k + { + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, &state->event_history_s[0]); + opts->wav_out_f = open_wav_file(opts->wav_out_dir, opts->wav_out_file, 48000, 0); + } } //do condition here, in future, will allow us to use tuning methods as well, or rtl_udp as well @@ -1379,9 +1386,12 @@ void edacs(dsd_opts * opts, dsd_state * state) //openwav file and do per call right here if (opts->dmr_stereo_wav == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3)) { - sprintf (opts->wav_out_file, "./WAV/%s %s EDACS Site %lld TG %04d SRC %05d.wav", datestr, timestr, state->edacs_site_id, group, lid); - if (is_digital == 0) openWavOutFile48k (opts, state); //analog at 48k - else openWavOutFile (opts, state); //digital + if (is_digital == 1) {} //just write to already open temp file to be renamed later + else //close the temp 8k wav file and open as 48k + { + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, &state->event_history_s[0]); + opts->wav_out_f = open_wav_file(opts->wav_out_dir, opts->wav_out_file, 48000, 0); + } } if (opts->use_rigctl == 1) @@ -1632,10 +1642,12 @@ void edacs(dsd_opts * opts, dsd_state * state) //openwav file and do per call right here if (opts->dmr_stereo_wav == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3)) { - if (is_individual == 0) sprintf (opts->wav_out_file, "./WAV/%s %s EDACS Site %lld TG %04d SRC %05d.wav", datestr, timestr, state->edacs_site_id, target, state->lastsrc); - else sprintf (opts->wav_out_file, "./WAV/%s %s EDACS Site %lld TGT %05d SRC %05d I-Call.wav", datestr, timestr, state->edacs_site_id, target, state->lastsrc); - if (is_digital == 0) openWavOutFile48k (opts, state); //analog at 48k - else openWavOutFile (opts, state); //digital + if (is_digital == 1) {} //just write to already open temp file to be renamed later + else //close the temp 8k wav file and open as 48k + { + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, &state->event_history_s[0]); + opts->wav_out_f = open_wav_file(opts->wav_out_dir, opts->wav_out_file, 48000, 0); + } } if (opts->use_rigctl == 1) @@ -1743,9 +1755,12 @@ void edacs(dsd_opts * opts, dsd_state * state) //openwav file and do per call right here if (opts->dmr_stereo_wav == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3)) { - sprintf (opts->wav_out_file, "./WAV/%s %s EDACS Site %lld TGT %05d SRC %05d I-Call.wav", datestr, timestr, state->edacs_site_id, target, state->lastsrc); - if (is_digital == 0) openWavOutFile48k (opts, state); //analog at 48k - else openWavOutFile (opts, state); //digital + if (is_digital == 1) {} //just write to already open temp file to be renamed later + else //close the temp 8k wav file and open as 48k + { + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, &state->event_history_s[0]); + opts->wav_out_f = open_wav_file(opts->wav_out_dir, opts->wav_out_file, 48000, 0); + } } if (opts->use_rigctl == 1) @@ -2036,9 +2051,12 @@ void edacs(dsd_opts * opts, dsd_state * state) //openwav file and do per call right here if (opts->dmr_stereo_wav == 1 && (opts->use_rigctl == 1 || opts->audio_in_type == 3)) { - sprintf (opts->wav_out_file, "./WAV/%s %s EDACS Site %lld SRC %05d All-Call.wav", datestr, timestr, state->edacs_site_id, state->lastsrc); - if (is_digital == 0) openWavOutFile48k (opts, state); //analog at 48k - else openWavOutFile (opts, state); //digital + if (is_digital == 1) {} //just write to already open temp file to be renamed later + else //close the temp 8k wav file and open as 48k + { + opts->wav_out_f = close_and_rename_wav_file(opts->wav_out_f, opts->wav_out_file, opts->wav_out_dir, &state->event_history_s[0]); + opts->wav_out_f = open_wav_file(opts->wav_out_dir, opts->wav_out_file, 48000, 0); + } } if (opts->use_rigctl == 1) diff --git a/src/ysf.c b/src/ysf.c index 023eae6..a6f3c0b 100644 --- a/src/ysf.c +++ b/src/ysf.c @@ -143,7 +143,7 @@ void ysf_dch_decode (dsd_state * state, uint8_t bn, uint8_t bt, uint8_t fn, uint char rem1[6]; char rem2[6]; - UNUSED3(bt, fn, ft); + UNUSED(bt); for (i = 0; i < 20; i++) dch_bytes[i] = (char)ConvertBitIntoBytes(&input[i*8], 8); @@ -179,9 +179,11 @@ void ysf_dch_decode (dsd_state * state, uint8_t bn, uint8_t bt, uint8_t fn, uint fprintf (stderr, "%s ", string2); //Copy both to Ncurses Call String + memset (state->ysf_tgt, 0, sizeof(state->ysf_tgt)); memcpy (state->ysf_tgt, dch_bytes, 10); state->ysf_tgt[10] = '\0'; + memset (state->ysf_src, 0, sizeof(state->ysf_src)); memcpy (state->ysf_src, dch_bytes+10, 10); state->ysf_src[10] = '\0'; @@ -209,27 +211,24 @@ void ysf_dch_decode (dsd_state * state, uint8_t bn, uint8_t bt, uint8_t fn, uint break; case 2: - for (i = 0; i < 20; i++) - { - if (dch_bytes[i] > 0x19 && dch_bytes[i] < 0x7F) - fprintf (stderr, "%c", dch_bytes[i]); - else fprintf (stderr, "."); - } - fprintf (stderr, " "); - // if (fn == 0) memset (state->ysf_txt, 0, sizeof(state->ysf_txt)); - //copy text to txt storage -- works now (had to expand storage space), but is cumbersome in ncurses (too long) - // if (fn < 20) - // { - // //switch to checking each byte for a 'nice' ASCII character and - // //not a 'naughty' del/rem/break/garbled non ASCII/ALPHANUMERIC type character - // for (i = 0; i < 20; i++) - // { - // C = dch_bytes[i]; //skipping 0x20 space key - // if (C > 0x20 && C < 0x7F) state->ysf_txt[fn][i] = C; - // else state->ysf_txt[fn][i] = 0; //NULL - // } - // } + if (fn == 0) + memset (state->ysf_txt, 0, sizeof(state->ysf_txt)); + + if (fn < 20) + { + //load ascii set characters only + for (i = 0; i < 20; i++) + { + char C = dch_bytes[i]; + if (C > 0x19 && C < 0x7F) + state->ysf_txt[fn][i] = C; + else state->ysf_txt[fn][i] = 0x20; //Space + } + } + + if (fn == ft) //last frame + fprintf (stderr, " %s", state->event_history_s[0].Event_History_Items[0].text_message); break; @@ -452,7 +451,7 @@ int ysf_conv_dch2 (dsd_opts * opts, dsd_state * state, uint8_t bn, uint8_t bt, u else { fprintf (stderr, "%s", KRED); - fprintf (stderr, "DCH (CRC ERR) "); + fprintf (stderr, "DCH2 (CRC ERR) "); fprintf (stderr, "%s", KNRM); } @@ -874,8 +873,7 @@ void processYSF(dsd_opts * opts, dsd_state * state) if (st && sc != 69) fprintf (stderr, "CODE: %03d ", sc); //simplified version - if (err == 0 && opts->payload == 1) - fprintf (stderr, "FN:%d-%d ", fn, ft); + fprintf (stderr, "FN: %d/%d ", fn+1, ft+1); if (err != 0) { @@ -914,7 +912,6 @@ void processYSF(dsd_opts * opts, dsd_state * state) memset (temp, 0, sizeof(temp)); //bit buffers - // uint8_t dch_bits[6][72]; uint8_t dch_bits[160]; uint8_t vch_bits[6][72]; uint8_t vech_bits[104]; @@ -1185,16 +1182,13 @@ void processYSF(dsd_opts * opts, dsd_state * state) dbufFR[i % 2][((i/2)*36)+j] = getDibit(opts, state); } - //clear old txt data - // if (fi == 0) memset (state->ysf_txt, 0, sizeof(state->ysf_txt)); - fprintf (stderr, "\n "); for (i = 0; i < 2; i++) { //process completed DCH -- use i to for bn to switch CSD1 and CSD2 on HC and TC if (fi == 0 || fi == 2) ysf_conv_dch (opts, state, i, bt, fn, ft, cm, dbufFR[i]); //using bn == 2 for full rate data and fn*2+1 for easier frame storage - else ysf_conv_dch (opts, state, 2, bt, fn*2+i, ft, cm, dbufFR[i]); + else ysf_conv_dch (opts, state, 2, bt, fn*2+i, ft*2, cm, dbufFR[i]); //had to fix ft so that it would equal the same in storage }