Squashed commit of the following:

commit a5c5be3b95
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Tue Mar 26 17:28:35 2024 -0400

    EDACS: Standard display rewrite, parsing/RE fixes, tune i-calls and all-calls (#246)

    * EDACS EA: Fix reversed TDMA/data calls

    * EDACS: deduplicate ncurses printing logic

    * EDACS: pass call state via new state struct field

    * EDACS: RE some differences from Standard spec

    * EDACS: show state for data calls

    * EDACS: tune individual calls on Standard

    * EDACS: tune all-calls on Standard

    * EDACS: properly identify emergency on channel updates

    * EDACS: fix build break

    * EDACS: fix conditions for refreshing the display source

    * EDACS EA: Identify calls as voice for display

    * EDACS: voice channel update emergency refactor

    * EDACS: Show interconnect calls in call log

    * EDACS EA: show unknown data channel assignments in log

    * EDACS: check LCN is not 0 before assigning it

    * EDACS: C operator precedence is dumb

    * Initialize edacs_vc_call_type

    * use j and not i in call_matrix for call history;

    ---------

    Co-authored-by: lwvmobile <lwvmobile@gmail.com>

commit c8d00846b1
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sun Mar 24 17:48:46 2024 -0400

    EDACS: Display cached call source on Standard, tune group calls on assignment (#241)

    * Trim trailing whitespace

    * EDACS: Display cached call source on Standard

    The logic in `edacs-fme.c` didn't work, in retrospect, because it would have depended on getting back-to-back messages for the same call. In practice, that is unlikely even on an idle system as system state gets displayed.

    Instead, cache on the display end, for a "better" user experience.

    * EDACS: Pad channel freq to "000.000000 MHz"

    * EDACS: Process/tune group calls on assignment

commit 8d432e8b3e
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sun Mar 24 12:29:22 2024 -0400

    EDACS: ESK fixes, RE of standard channel assignments, cleanups (#238)

    * EDACS: Make i-calls very obvious on standard

    * EDACS: abstract target for Interconnect Channel Assignment

    * EDACS: little shortcut example updates

    * EDACS: Apply ESK to both FR1 and FR4

    * EDACS: Group channel assignment by mode

    * EDACS: Merge MT-A 0/1 and 2/3 cases

commit 0440dea1de
Author: lwvmobile <lwvmobile@gmail.com>
Date:   Sun Mar 24 02:47:09 2024 -0400

    EDACS: Fix Call History For Standard Maybe;

commit 208f188e55
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sat Mar 23 21:35:42 2024 -0400

    EDACS: Speculative RE of MT-A value 0, pretty colours (#231)

    * EDACS: fix log formatting

    * EDACS: Speculative RE of MT-A value 0

    * EDACS: CC message pretty colours

    * EDACS: little formatting

    * EDACS: eh make interconnect magenta

commit 36f76a7e21
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sat Mar 23 17:35:45 2024 -0400

    EDACS: Fix copy/paste error (#230)

    I went through by hand and I'm confident this is the last of the `get_lcn_status_string()` errors.

commit 4bc73d8c68
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sat Mar 23 17:24:32 2024 -0400

    EDACS: Rewrite Standard/Networked parsing per TIA/EIA TSB 69.3 (#229)

    * EDACS EA: refactor log messages for consistency

    * EDACS: Log LCN status values

    * EDACS EA: channel assignment vs update

    * EDACS: Implement TIA/EIA TSB 69.3

    * EDACS: clean up Site ID message

    * EDACS: Actually process call for Channel Update

    * EDACS: Update display for Standard calls

    * EDACS: Format of Voice Group Channel Assignment

    * EDACS Standard: Log LCN status values

    * EDACS: Rebase and fix some issues

    * EDACS: Fix copy/paste error

commit 03507055a4
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sat Mar 23 16:05:09 2024 -0400

    EDACS: add EA messages / start mass Standard refactor (#226)

    * EDACS EA: refactor log messages for consistency

    * EDACS EA: channel assignment command (unknown data)

    * EDACS EA: status/message command

    * EDACS Standard: Refactor variable declarations

    * EDACS Standard: log raw payloads for debugging

    * EDACS: Fix typing

    * EDACS EA: update status/message CC command

    * EDACS: Log LCN status values

    * EDACS: String format

    * EDACS EA: channel assignment vs update

    * EDACS: fix syntax error

    * EDACS: change string for reserved LCN status

commit fbe5fd2093
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Fri Mar 22 15:26:50 2024 -0400

    EDACS EA: emergency calls, MT1 fixes, logging improvements (#221)

    * EDACS EA: Fix i-call MT1 after ESK changes

    * EDACS EA: Fix all-call ncurses display

    * EDACS EA: Make detailed log slightly more readable

    * EDACS EA: Improve colours in logs

    * EDACS EA: Space in logs for consistency

    * EDACS EA: Fix MT1 for analog group voice after ESK change

    * EDACS EA: add parsing for emergency calls

commit 413e5f76a2
Merge: de9127c 388a57d
Author: lwvmobile <59371473+lwvmobile@users.noreply.github.com>
Date:   Fri Mar 22 06:59:31 2024 -0400

    Merge pull request #220 from lwvmobile/edacs_manual_modes

    Edacs manual modes

commit 388a57d8fc
Author: lwvmobile <lwvmobile@gmail.com>
Date:   Fri Mar 22 05:28:11 2024 -0400

    EDACS: Re-enable the -9 switch to maintain user compatability; Fix Missing Bracket on non color mode;

commit 058099f1aa
Author: lwvmobile <lwvmobile@gmail.com>
Date:   Fri Mar 22 03:24:57 2024 -0400

    EDACS: Tweak Mode Toggle Display; Add Frame Dump on No Mode Set;

commit 68aa6b018e
Author: lwvmobile <lwvmobile@gmail.com>
Date:   Fri Mar 22 02:19:38 2024 -0400

    EDACS: Update Docs to Reflect Changes;

commit c404f3c48c
Author: lwvmobile <lwvmobile@gmail.com>
Date:   Fri Mar 22 02:01:09 2024 -0400

    EDACS: Ncurses Display Working Mode Tweaks;

commit b2d1608eb7
Author: lwvmobile <lwvmobile@gmail.com>
Date:   Fri Mar 22 01:08:28 2024 -0400

    EDACS: Toggle Keys A and S for Mode Selection;

commit a4553a0a0a
Author: lwvmobile <lwvmobile@gmail.com>
Date:   Fri Mar 22 00:45:37 2024 -0400

    EDACS: Remove Auto Detect Code; Make CLI Switches;

commit de9127cfb4
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Thu Mar 21 21:02:53 2024 -0400

    EDACS: support for EA system all-calls (#214)

    * Refactor debug printing a bit

    * Clean up group call logic

    * Minor changes to debug printing

    * EDACS EA: support for system all-calls

    * EDACS: split out MT1 for TDMA call since we can't decode it anyway

    * Refactor identifying call mode (digital/analog)

    * Maintain consistent indentation for all MT1

    * EDACS: Fix Compiler Error.

    Had an extra right bracket on line 383

    ---------

    Co-authored-by: lwvmobile <59371473+lwvmobile@users.noreply.github.com>

commit c85dd60399
Author: lwvmobile <lwvmobile@gmail.com>
Date:   Tue Mar 19 17:38:30 2024 -0400

    EDACS: NET/STD LCN > 0 Check;

commit bed766a86e
Author: lwvmobile <lwvmobile@gmail.com>
Date:   Tue Mar 19 09:34:10 2024 -0400

    EDACS: STD/NET Don't Tune Unless CC LCN Set;

commit 69f532a022
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Mon Mar 18 11:41:58 2024 -0400

    EDACS: EA I-Call decoding improvements (#205)

    * EDACS: formatting nit

    * EDACS: add name to credits

    * EDACS: Handle initial grant vs grant update for i-call

    * EDACS: consistency for group vs i-call

    * EDACS: file naming for i-call recordings

    * EDACS: EA refactor when MT1 is 0x1F

    * EDACS: check we know CC LCN before leaving it

    * EDACS: fix breaking change for Standard

    Revert mistake in f68367c4f3

    * Fix patent number

    * EDACS: Fix Compiler Error 1;

    Fix Rogue Copy Paste

    * EDACS: Add MT1, MT2, and FR1 and FR4 Dumps on Payload;

    ---------

    Co-authored-by: lwvmobile <59371473+lwvmobile@users.noreply.github.com>

commit a7de24c47b
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Mon Mar 18 07:47:34 2024 -0400

    EDACS: fixes and improvements to EA analog and i-call parsing (#204)

    * Fix MT1 math given esk_mask value is 0xA0

    * EDACS: Clean up formatting for I-Calls

    * EDACS: typo, fix the TGID for group calls

    Fix copy-pasta

    * EDACS: Fix MT2 for I-Calls

    Incorrectly copied decimal values as hex - obviously MT2 is only 4 bits so it cannot be greater than 15.

    * EDACS: check LCN is > 0 before trying to tune

    An EA CC sometimes includes commands that parse as LCN 0 - but otherwise valid - analog call voice grants for TG 1. Since LCN 0 is not valid, ensure that we don't try to tune to them while we try to figure out what they're about.

    * EDACS: Process "login" message on CC

    Log "login" messages sent on the CC. Verified behaviour against UniTrunker.

commit 10eacd99cc
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sun Mar 17 18:56:41 2024 -0400

    EDACS: Clean up formatting for I-Calls (#203)

    * Fix MT1 math given esk_mask value is 0xA0

    * EDACS: Clean up formatting for I-Calls

commit ebe6e8fc65
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sun Mar 17 18:02:12 2024 -0400

    Fix MT1 math given esk_mask value is 0xA0 (#202)

commit 8619612b76
Author: lwvmobile <lwvmobile@gmail.com>
Date:   Sat Mar 16 22:42:44 2024 -0400

    EDACS: Setup Analog Calls and WAVs on EA and ICALL;

commit 9ac1573f0b
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sat Mar 16 17:17:14 2024 -0400

    EDACS: Add MT1 value / logging for analog group calls (#198)

    * Add MT1 value / logging for analog group calls

    * Respect user preference for tuning to group calls

    * Revert "Respect user preference for tuning to group calls"

    This reverts commit 83ac8feab7.

commit 0aa01a45ef
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sat Mar 16 17:16:52 2024 -0400

    EDACS: Respect user preference for tuning to group calls (#201)

commit f68367c4f3
Author: ilyacodes <33097525+ilyacodes@users.noreply.github.com>
Date:   Sat Mar 16 17:16:20 2024 -0400

    EDACS: Add parsing for individual calls (#200)

    * EDACS: Add parsing for individual calls

    This change adds parsing for I-Calls on EA systems. Both analog and ProVoice modes are parsed and processed. See related issue for discussion.

    * Respect user preference for tuning to private calls

    * EDACS: Respect user preference for tuning to private calls

    * EDACS: Handle i-call target in ProVoice logging

    * EDACS: Show i-calls distinctly from group calls
This commit is contained in:
lwvmobile 2024-03-26 17:33:34 -04:00
parent f05ddf8fcd
commit 3b9f9f5a3b
8 changed files with 1789 additions and 410 deletions

View File

@ -4,7 +4,7 @@
DSD-FME is an evolution of the original DSD project from 'DSD Author' using the base code of [szechyjs](https://github.com/szechyjs/dsd "szechyjs"), some code and ideas from [LouisErigHerve](https://github.com/LouisErigHerve/dsd "LouisErigHerve"), [Boatbod OP25](https://github.com/boatbod/op25 "Boatbod OP25") and
[Osmocom OP25](https://gitea.osmocom.org/op25/op25 "Osmocom OP25"), along with other snippets of code, information, and inspirations from other projects including [DSDcc](https://github.com/f4exb/dsdcc "DSDcc"), [SDRTRunk](https://github.com/DSheirer/sdrtrunk "SDRTrunk"), [MMDVMHost](https://github.com/g4klx/MMDVMHost "MMDVMHost"), [LFSR](https://github.com/mattames/LFSR "LFSR"), [OK-DMRlib](https://github.com/OK-DMR/ok-dmrlib "OK-DMRlib"), and [EZPWD-Reed-Solomon](https://github.com/pjkundert/ezpwd-reed-solomon "EZPWD"), Eric Cottrell, SP5WWP and others. Finally, this is all brought together with original code to extend the fuctionality and add new features including NCurses Terminal and Menu system, Pulse Audio, TCP Direct Link Audio, RIGCTL, Trunking Features, LRRP/GPS Mapping, P25 Phase 2, EDACS, YSF, M17, OP25 Capture Bin compatability, etc. DSD-FME is primarily focused with Linux Desktop users in mind, so please understand that this version may not compile, compile easily, or run correctly in other environments.
This project wouldn't be possible without a few good people providing me plenty of sample audio files to run over and over again. Special thanks to jurek1111, KrisMar, noamlivne, racingfan360, iScottyBotty, LimaZulu, Forts, thewraithe2008, RayAir, Cretu, and others for the many hours of wav samples and information provided by them. Most importantly, HRH17, whose insight, information, samples, and willingness to let me remote into a computer half-way across the globe in order to test trunking features are what make DSD-FME what it has become. I'd also like to thank mrscanner2008 for providing an additional remote where additional NXDN Type-C, 'Idas' Type-D, and XPT decoding and trunking could be sorted out. Thanks to volo-zyko for cleaning up a lot of code. Thank you everybody.
This project wouldn't be possible without a few good people providing me plenty of sample audio files to run over and over again. Special thanks to jurek1111, KrisMar, noamlivne, racingfan360, iScottyBotty, LimaZulu, Forts, thewraithe2008, RayAir, Cretu, ilyacodes, and others for the many hours of wav samples and information provided by them. Most importantly, HRH17, whose insight, information, samples, and willingness to let me remote into a computer half-way across the globe in order to test trunking features are what make DSD-FME what it has become. I'd also like to thank mrscanner2008 for providing an additional remote where additional NXDN Type-C, 'Idas' Type-D, and XPT decoding and trunking could be sorted out. Thanks to volo-zyko for cleaning up a lot of code. Thank you everybody.
![DSD-FME](https://github.com/lwvmobile/dsd-fme/blob/audio_work/dsd-fme2.png)

View File

@ -8,7 +8,11 @@
-fa Legacy Auto (not recommended)
-fi NXDN48
-fn NXDN96
-fp EDACS/Provoice
-fp Provoice
-fh EDACS Standard / Network
-fH EDACS Standard / Network with ESK
-fe EDACS Extended Addresssing
-fE EDACS Extended Addressing with ESK
-fm dPMR, also may need to use -xd if inverted dPMR.
-f1 P25P1
-f2 P25P2 (may need to specify wacn/sys/nac manually if traffic channel)
@ -100,11 +104,11 @@ and in a second terminal tab, same folder, run
EDACS Trunking (w/ channel map import)
--EDACS/PV Trunking using RIGCTL and TCP Direct Link Audio inside of SDR++ (Tested and Working on EDACS/EDACS-EA with Provoice, Analog Voice Monitoring and Per Call is Experimental)
--EDACS/PV Trunking using RIGCTL and TCP Direct Link Audio inside of SDR++ (see switches above for STD/NET, EA, and ESK modes)
`dsd-fme -i tcp -fp -C channel_map.csv -G group.csv -T -U 4532 -N 2> log.ans`
`dsd-fme -i tcp -fE -C channel_map.csv -G group.csv -T -U 4532 -N 2> log.ans`
--NXDN48 Trunking (standard band plan) with SDR++ (untested for frequency accuracy)
--NXDN48 Trunking (Direct Frequency Assignment) with SDR++ (untested for frequency accuracy)
`dsd-fme -fi -i tcp -T -U 4532 -N 2> log.ans`
@ -176,9 +180,9 @@ M - toggle c4fm/qpsk 8/3 (phase 2 tdma control channel)
R - start capturing symbol capture bin (date/time name file)
r - stop capturing symbol capture bin
spacebar - replay last symbol capture bin (captures must be stopped first)
s - stop playing symbol capture bin or wav input file
s - stop playing symbol capture bin or wav input file (lower s)
P - start per call decoded wav files (Capital P)
p - stop per call decoded wav files (Lower p)
p - stop per call decoded wav files (lower p)
t - toggle trunking (needs either rtl input, or rigctl connection)
y - toggle scanner (needs either rtl input, or rigctl connection)
1 - Toggle Voice Synthesis in TDMA Slot 1 or FDMA Conventional Voice
@ -202,6 +206,9 @@ l - Hold TG in Slot 2 on TDMA Systems, or clear current hold
C - Drop Call and Return to CC during trunking operation
L - Manual Cycle Forward Channel Tuned when RIGCTL or using RTL input and channel csv loaded
S - Toggle between EDACS Standard/Network and Extended Addressing mode (Capital S)
A - Toggle EDACS ESK Mask (none vs A0)
```
## Sending Audio to a Icecast 2 Server via FFmpeg (Windows)

View File

@ -17,9 +17,21 @@
dsd-fme -fs -i tcp -U 4532 -T -C dmr_t3_chan.csv -G group.csv -N 2> log.ans
#dsd-fme -fs -i rtl:0:450M:44:-2:8 -T -C connect_plus_chan.csv -G group.csv -N 2> log.ans
#EDACS/EDACS-EA Digital Only
#dsd-fme -fp -i tcp:192.168.7.5:7355 -U 4532 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
#dsd-fme -fp -i rtl:0:850M:44:-2:24 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
#EDACS Standard Network Analog and Digital
#dsd-fme -fh -i tcp:192.168.7.5:7355 -U 4532 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
#dsd-fme -fh -i rtl:0:850M:44:-2:24 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
#EDACS Standard Network Analog and Digital (with ESK)
#dsd-fme -fH -i tcp:192.168.7.5:7355 -U 4532 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
#dsd-fme -fH -i rtl:0:850M:44:-2:24 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
#EDACS Extended Address Analog and Digital
#dsd-fme -fe -i tcp:192.168.7.5:7355 -U 4532 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
#dsd-fme -fe -i rtl:0:850M:44:-2:24 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
#EDACS Extended Address Analog and Digital (with ESK)
#dsd-fme -fE -i tcp:192.168.7.5:7355 -U 4532 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
#dsd-fme -fE -i rtl:0:850M:44:-2:24 -T -C edacs_channel_map.csv -G group.csv -N 2> log.ans
#NXDN48 Type-C or Type-D Trunking with Channel Map
#dsd-fme -fi -i tcp -T -U 4532 -C nxdn_channel_map.csv -N 2> log.ans

View File

@ -210,8 +210,8 @@ typedef struct
SF_INFO *audio_in_file_info;
uint32_t rtlsdr_center_freq;
int rtlsdr_ppm_error;
int audio_in_type;
int rtlsdr_ppm_error;
int audio_in_type;
char audio_out_dev[1024];
int audio_out_fd;
int audio_out_fdR; //right channel audio for OSS hack
@ -367,7 +367,7 @@ typedef struct
char group_in_file[1024];
char lcn_in_file[1024];
char chan_in_file[1024];
char key_in_file[1024];
char key_in_file[1024];
//end import filenames
//reverse mute
@ -454,7 +454,7 @@ typedef struct
short s_ru[160*6]; //single sample right
short s_l4u[4][160*6]; //quad sample for up to a P25p2 4V
short s_r4u[4][160*6]; //quad sample for up to a P25p2 4V
//end
//end
int audio_out_idx;
int audio_out_idx2;
int audio_out_idxR;
@ -616,7 +616,7 @@ typedef struct
char dmr_cach_fragment[4][17]; //unsure of size, will need to check/verify
int dmr_cach_counter; //counter for dmr_cach_fragments 0-3; not sure if needed yet.
//dmr talker alias new/fixed stuff
uint8_t dmr_alias_format[2]; //per slot
uint8_t dmr_alias_len[2]; //per slot
@ -695,13 +695,23 @@ typedef struct
//edacs
int ea_mode;
int esk_mode;
unsigned short esk_mask;
unsigned long long int edacs_site_id;
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)
int edacs_tuned_lcn; //the vc we are currently tuned to...above variable is for updating all in the matrix
int edacs_vc_call_type; //the type of call on the given VC - see defines below
//flags for EDACS call type
#define EDACS_IS_VOICE 0x01
#define EDACS_IS_DIGITAL 0x02
#define EDACS_IS_EMERGENCY 0x04
#define EDACS_IS_GROUP 0x08
#define EDACS_IS_INDIVIDUAL 0x10
#define EDACS_IS_ALL_CALL 0x20
#define EDACS_IS_INTERCONNECT 0x40
//trunking group and lcn freq list
long int trunk_lcn_freq[26]; //max number on an EDACS system, should be enough on DMR too hopefully
@ -1188,7 +1198,7 @@ bool crc8_ok(uint8_t bits[], unsigned int len);
//modified CRC functions for SB/RC
uint8_t crc7(uint8_t bits[], unsigned int len);
uint8_t crc3(uint8_t bits[], unsigned int len);
uint8_t crc4(uint8_t bits[], unsigned int len);
uint8_t crc4(uint8_t bits[], unsigned int len);
//LFSR and LFSRP code courtesy of https://github.com/mattames/LFSR/
void LFSR(dsd_state * state);

View File

@ -1047,8 +1047,8 @@ initState (dsd_state * state)
//edacs - may need to make these user configurable instead for stability on non-ea systems
state->ea_mode = -1; //init on -1, 0 is standard, 1 is ea
state->esk_mode = -1; //same as above, but with esk or not
state->esk_mask = 0x0; //toggles from 0x0 to 0xA0 if esk mode enabled
state->edacs_vc_call_type = 0;
state->esk_mask = 0x0; //esk mask value
state->edacs_site_id = 0;
state->edacs_lcn_count = 0;
state->edacs_cc_lcn = 0;
@ -1333,7 +1333,11 @@ usage ()
printf (" -fz Decode only M17*\n");
printf (" -fi Decode only NXDN48* (6.25 kHz) / IDAS*\n");
printf (" -fn Decode only NXDN96* (12.5 kHz)\n");
printf (" -fp Decode only EDACS/ProVoice*\n");
printf (" -fp Decode only ProVoice*\n");
printf (" -fh Decode only EDACS Standard/ProVoice*\n");
printf (" -fH Decode only EDACS Standard/ProVoice with ESK 0xA0*\n");
printf (" -fe Decode only EDACS EA/ProVoice*\n");
printf (" -fE Decode only EDACS EA/ProVoice with ESK 0xA0*\n");
printf (" -fm Decode only dPMR*\n");
printf (" -l Disable DMR, dPMR, and NXDN input filtering\n");
printf (" -u <num> Unvoiced speech quality (default=3)\n");
@ -1416,7 +1420,7 @@ usage ()
printf (" P25 - 12000; NXDN48 - 7000; NXDN96: 12000; DMR - 7000-12000; EDACS/PV - 12000-24000;\n"); //redo this, or check work, or whatever
printf (" May vary based on system stregnth, etc.\n");
printf (" -t <secs> Set Trunking or Scan Speed VC/sync loss hangtime in seconds. (default = 1 second)\n");
printf (" -9 Force Enable EDACS Standard or Networked Mode if Auto Detection Fails \n");
// printf (" -9 Force Enable EDACS Standard or Networked Mode if Auto Detection Fails \n");
printf ("\n");
printf (" Trunking Example TCP: dsd-fme -fs -i tcp -U 4532 -T -C dmr_t3_chan.csv -G group.csv -N 2> log.ans\n");
printf (" Trunking Example RTL: dsd-fme -fs -i rtl:0:450M:26:-2:8 -T -C connect_plus_chan.csv -G group.csv -N 2> log.ans\n");
@ -1684,9 +1688,10 @@ main (int argc, char **argv)
fprintf (stderr, "TG Hold set to %d \n", state.tg_hold);
break;
case '9': //This is a temporary fix for RR issue until a permanent fix can be found
case '9': //Leaving Enabled to maintain backwards compatability
state.ea_mode = 0;
fprintf (stderr,"Force Enabling EDACS Standard/Networked Mode Mode\n");
state.esk_mask = 0;
fprintf (stderr,"Force Enabling EDACS Standard/Networked Mode Mode without ESK.\n");
break;
//experimental audio monitoring
@ -2182,6 +2187,146 @@ main (int argc, char **argv)
opts.rtl_bandwidth = 24;
// opts.rtl_gain_value = 36;
}
else if (optarg[0] == 'h') //standard / net w/o ESK
{
opts.frame_dstar = 0;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0;
opts.frame_p25p2 = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_dpmr = 0;
opts.frame_provoice = 1;
state.ea_mode = 0;
state.esk_mask = 0;
opts.frame_ysf = 0;
opts.frame_m17 = 0;
state.samplesPerSymbol = 5;
state.symbolCenter = 2;
opts.mod_c4fm = 0;
opts.mod_qpsk = 0;
opts.mod_gfsk = 1;
state.rf_mod = 2;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
opts.dmr_stereo = 0;
opts.dmr_mono = 0;
state.dmr_stereo = 0;
// opts.setmod_bw = 12500;
sprintf (opts.output_name, "EDACS/PV");
fprintf (stderr,"Setting symbol rate to 9600 / second\n");
fprintf (stderr,"Decoding EDACS STD/NET and ProVoice frames.\n");
fprintf (stderr,"EDACS Analog Voice Channels are Experimental.\n");
//rtl specific tweaks
opts.rtl_bandwidth = 24;
// opts.rtl_gain_value = 36;
}
else if (optarg[0] == 'H') //standard / net w/ ESK
{
opts.frame_dstar = 0;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0;
opts.frame_p25p2 = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_dpmr = 0;
opts.frame_provoice = 1;
state.ea_mode = 0;
state.esk_mask = 0xA0;
opts.frame_ysf = 0;
opts.frame_m17 = 0;
state.samplesPerSymbol = 5;
state.symbolCenter = 2;
opts.mod_c4fm = 0;
opts.mod_qpsk = 0;
opts.mod_gfsk = 1;
state.rf_mod = 2;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
opts.dmr_stereo = 0;
opts.dmr_mono = 0;
state.dmr_stereo = 0;
// opts.setmod_bw = 12500;
sprintf (opts.output_name, "EDACS/PV");
fprintf (stderr,"Setting symbol rate to 9600 / second\n");
fprintf (stderr,"Decoding EDACS STD/NET w/ ESK and ProVoice frames.\n");
fprintf (stderr,"EDACS Analog Voice Channels are Experimental.\n");
//rtl specific tweaks
opts.rtl_bandwidth = 24;
// opts.rtl_gain_value = 36;
}
else if (optarg[0] == 'e') //extended addressing w/o ESK
{
opts.frame_dstar = 0;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0;
opts.frame_p25p2 = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_dpmr = 0;
opts.frame_provoice = 1;
state.ea_mode = 1;
state.esk_mask = 0;
opts.frame_ysf = 0;
opts.frame_m17 = 0;
state.samplesPerSymbol = 5;
state.symbolCenter = 2;
opts.mod_c4fm = 0;
opts.mod_qpsk = 0;
opts.mod_gfsk = 1;
state.rf_mod = 2;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
opts.dmr_stereo = 0;
opts.dmr_mono = 0;
state.dmr_stereo = 0;
// opts.setmod_bw = 12500;
sprintf (opts.output_name, "EDACS/PV");
fprintf (stderr,"Setting symbol rate to 9600 / second\n");
fprintf (stderr,"Decoding EDACS Extended Addressing and ProVoice frames.\n");
fprintf (stderr,"EDACS Analog Voice Channels are Experimental.\n");
//rtl specific tweaks
opts.rtl_bandwidth = 24;
// opts.rtl_gain_value = 36;
}
else if (optarg[0] == 'E') //extended addressing w/ ESK
{
opts.frame_dstar = 0;
opts.frame_x2tdma = 0;
opts.frame_p25p1 = 0;
opts.frame_p25p2 = 0;
opts.frame_nxdn48 = 0;
opts.frame_nxdn96 = 0;
opts.frame_dmr = 0;
opts.frame_dpmr = 0;
opts.frame_provoice = 1;
state.ea_mode = 1;
state.esk_mask = 0xA0;
opts.frame_ysf = 0;
opts.frame_m17 = 0;
state.samplesPerSymbol = 5;
state.symbolCenter = 2;
opts.mod_c4fm = 0;
opts.mod_qpsk = 0;
opts.mod_gfsk = 1;
state.rf_mod = 2;
opts.pulse_digi_rate_out = 8000;
opts.pulse_digi_out_channels = 1;
opts.dmr_stereo = 0;
opts.dmr_mono = 0;
state.dmr_stereo = 0;
// opts.setmod_bw = 12500;
sprintf (opts.output_name, "EDACS/PV");
fprintf (stderr,"Setting symbol rate to 9600 / second\n");
fprintf (stderr,"Decoding EDACS Extended Addressing w/ ESK and ProVoice frames.\n");
fprintf (stderr,"EDACS Analog Voice Channels are Experimental.\n");
//rtl specific tweaks
opts.rtl_bandwidth = 24;
// opts.rtl_gain_value = 36;
}
else if (optarg[0] == '1')
{
opts.frame_dstar = 0;

View File

@ -7,6 +7,9 @@
*
* LWVMOBILE
* 2022-08 DSD-FME Florida Man Edition
*
* ilyacodes
* 2024-03 EDACS-FME display improvements
*-----------------------------------------------------------------------------*/
@ -110,13 +113,13 @@ char * DMRBusrtTypes[32] = {
"R34D ",
"IDLE ",
"R1_D ",
"ERR ",
"ERR ",
"DUID ERR ",
"R-S ERR ",
"CRC ERR ",
"NULL ",
"VOICE",
" ",
"VOICE",
" ",
"INIT ",
"INIT ",
"PTT", //20 MAC
@ -188,7 +191,7 @@ void beeper (dsd_opts * opts, dsd_state * state, int lr)
if (opts->pulse_digi_out_channels == 1 && opts->floating_point == 0)
pa_simple_write(opts->pulse_digi_dev_out, samp_s, 160*2, NULL);
}
else if (opts->audio_out_type == 8) //UDP Audio
@ -204,7 +207,7 @@ void beeper (dsd_opts * opts, dsd_state * state, int lr)
if (opts->pulse_digi_out_channels == 1 && opts->floating_point == 0)
udp_socket_blaster (opts, state, 160*2, samp_s);
}
else if (opts->audio_out_type == 1) //STDOUT
@ -245,10 +248,10 @@ void beeper (dsd_opts * opts, dsd_state * state, int lr)
samp_su[(i*6)+4] = outbuf[4];
samp_su[(i*6)+5] = outbuf[5];
}
write (opts->audio_out_fd, samp_su, 960*2);
}
}
}
@ -328,7 +331,7 @@ char *choicesc[] = {
"Setup and Start RTL Input ",
"Retune RTL Dongle ",
"Toggle C4FM/QPSK (P2 TDMA CC)",
"Toggle C4FM/QPSK (P1 FDMA CC)",
"Toggle C4FM/QPSK (P1 FDMA CC)",
"Start TCP Direct Link Audio",
"Configure RIGCTL",
"Stop All Decoded WAV Saving",
@ -415,7 +418,7 @@ void ncursesOpen (dsd_opts * opts, dsd_state * state)
//this is primarily used to push a quick audio blip through OSS so it will show up in the mixer immediately
// if (opts->audio_out_type == 2 || opts->audio_out_type == 5)
// beeper (opts, state, 0); //causes crash in Cygwin when mixed input/output
//terminate all values
for (int i = 0; i < 10; i++)
sprintf (alias_ch[i], "%s", "");
@ -462,7 +465,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
closePulseOutput (opts);
}
//close OSS output
//close OSS output
if (opts->audio_out_type == 2 || opts->audio_out_type == 5)
{
close (opts->audio_out_fd);
@ -760,7 +763,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
opts->rtl_dev_index = i;
break;
}
}
entry_win = newwin(17, WIDTH+20, starty+10, startx+10);
@ -861,7 +864,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
// if (opts->audio_out == 0)
// {
// opts->audio_out = 1;
// opts->audio_out_type = 0;
// opts->audio_out_type = 0;
// // state->audio_out_buf_p = 0;
// // state->audio_out_buf_pR = 0;
// state->audio_out_idx = 0;
@ -933,7 +936,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
opts->audio_in_type = 0;
}
else opts->audio_in_type = 5;
}
state->audio_smoothing = 0; //disable smoothing to prevent random crackling/buzzing
@ -1222,7 +1225,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
wscanw(entry_win, "%lld", &state->R);
noecho();
if (state->R > 0x7FFF) state->R = 0x7FFF;
state->keyloader = 0; //turn off keyloader
}
//toggle enforcement of basic privacy key over enc bit set on traffic
@ -1844,7 +1847,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
{
openOSSOutput (opts);
}
if (opts->audio_in_type == 0) //reopen pulse input if it is the specified input method
{
@ -1854,7 +1857,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state)
if (opts->audio_in_type == 3) //open rtl input if it is the specified input method
{
// ncursesPrinter (opts, state); //not sure why this was placed here originally, but causes a double free core dump when calling free(timestr)
#ifdef USE_RTLSDR
#ifdef USE_RTLSDR
if (opts->rtl_started == 0)
{
opts->rtl_started = 1; //set here so ncurses terminal doesn't attempt to open it again
@ -1892,7 +1895,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (opts->audio_in_type != 1) //can't run getch/menu when using STDIN -
{
timeout(0); //
timeout(0); //
c = getch(); //
}
@ -1908,7 +1911,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//Variable reset/set section
//set lls sync types
if (state->synctype >= 0 && state->synctype < 39)
if (state->synctype >= 0 && state->synctype < 39)
{
lls = state->synctype;
}
@ -2002,16 +2005,23 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//Edacs - ProVoice
if ( (lls == 14 || lls == 15 || lls == 37 || lls == 38) && state->carrier == 1)
{
if (state->edacs_vc_lcn != -1)
if (state->edacs_vc_lcn != -1)
{
call_matrix[state->edacs_vc_lcn][0] = lls;
call_matrix[state->edacs_vc_lcn][1] = state->edacs_vc_lcn;
call_matrix[state->edacs_vc_lcn][2] = state->lasttg;
call_matrix[state->edacs_vc_lcn][3] = state->lastsrc;
call_matrix[state->edacs_vc_lcn][4] = 1;
call_matrix[state->edacs_vc_lcn][2] = state->lasttg;
//EDACS standard does not provide source LIDs on channel update messages; instead, for the sake of display, let's
//assume the prior source for a given LCN is still accurate, unless we have an updated one provided (or the call
//type has changed under us).
//
//If you MUST have perfectly-accurate source LIDs, look at the logged CC messages yourself - incorrect source LIDs
//may be displayed if we miss an initial call channel assignment.
if (state->ea_mode == 1 || (state->lastsrc != 0 || call_matrix[state->edacs_vc_lcn][4] != state->edacs_vc_call_type))
call_matrix[state->edacs_vc_lcn][3] = state->lastsrc;
call_matrix[state->edacs_vc_lcn][4] = state->edacs_vc_call_type;
call_matrix[state->edacs_vc_lcn][5] = time(NULL);
}
}
}
@ -2074,7 +2084,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
}
//TODO: Find better placement for these
if ( strcmp(state->str50a, "") != 0 )
sprintf (alias_ch[9], "%s", state->str50a);
@ -2257,7 +2267,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
// state->lastsrc = 0;
// rd = 0;
// tg = 0;
// }
// }
// if (state->dmrburstR == 2 && state->dmr_end_alert[1] == 0) //if TLC and flag not tripped
// {
// beeper (opts, state, 1);
@ -2266,7 +2276,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
// state->lastsrcR = 0;
// rdR = 0;
// tgR = 0;
// }
// }
// }
//Start Printing Section
@ -2276,7 +2286,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
{
printw ("------------------------------------------------------------------------------\n");
printw ("| Digital Speech Decoder: Florida Man Edition - Aero %s \n", "AW (20231015)");
printw ("------------------------------------------------------------------------------\n");
printw ("------------------------------------------------------------------------------\n");
}
#elif LIMAZULUTWEAKS
if (opts->ncurses_compact == 1)
@ -2318,7 +2328,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
#elif ZDEV_BUILD
if (i == 5) printw (" %s ", "AW ");
if (i == 6) printw (" %s \n", GIT_TAG);
#else
#else
if (i == 5) printw (" %s ", "AW ");
if (i == 6) printw (" %s \n", GIT_TAG);
#endif
@ -2383,7 +2393,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw (" SQ: %i;", opts->rtl_squelch_level);
printw (" RMS: %04li;", opts->rtl_rms);
printw (" BW: %i kHz;", opts->rtl_bandwidth);
printw (" FRQ: %i;", opts->rtlsdr_center_freq);
printw (" FRQ: %i;", opts->rtlsdr_center_freq);
if (opts->rtl_udp_port != 0) printw ("\n| External RTL Tuning on UDP Port: %i", opts->rtl_udp_port);
printw ("\n");
}
@ -2505,6 +2515,66 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
else printw (" - Black List Mode\n");
}
#endif
//print additional information for EDACS modes and toggles
#ifdef PRETTY_COLORS
if (opts->p25_trunk == 1 && opts->frame_provoice == 1)
{
printw ("| \\--EDACS -");
if (state->ea_mode == -1)
{
attron(COLOR_PAIR(2));
printw (" Standard/Network");
printw (" Extended Address");
attron(COLOR_PAIR(4));
}
else if (state->ea_mode == 0)
{
printw (" Standard/Network");
attron(COLOR_PAIR(2));
printw (" Extended Address");
attron(COLOR_PAIR(4));
}
else if (state->ea_mode == 1)
{
attron(COLOR_PAIR(2));
printw (" Standard/Network");
attron(COLOR_PAIR(4));
printw (" Extended Address");
}
printw (" Mode (S);");
printw(" ESK Mask: %02X", state->esk_mask);
printw (" (A); ");
attron(COLOR_PAIR(4));
printw ("\n");
}
#else //set on to UPPER CASE, off to lower case
if (opts->p25_trunk == 1 && opts->frame_provoice == 1)
{
printw ("| \\--EDACS -");
if (state->ea_mode == -1)
{
printw (" standard/network");
printw (" extended address");
}
else if (state->ea_mode == 0)
{
printw (" STANDARD/NETWORK");
printw (" extended address");
}
else if (state->ea_mode == 1)
{
printw (" standard/network");
printw (" EXTENDED ADDRESS");
}
printw (" Mode (S);");
printw(" ESK Mask: %02X", state->esk_mask);
printw (" (A) Toggle; ");
printw ("\n");
}
#endif
// if (opts->aggressive_framesync == 0) printw ("| Selective CRC ERR Bypass Enabled (RAS) \n");
if (state->M == 1)
{
@ -2521,9 +2591,9 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (opts->scanner_mode == 1)
{
printw ("| Scan Mode: ");
if (state->lcn_freq_roll != 0)
if (state->lcn_freq_roll != 0)
printw (" Frequency: %.06lf Mhz", (double)state->trunk_lcn_freq[state->lcn_freq_roll-1]/1000000);
printw (" Speed: %.02lf sec \n", opts->trunk_hangtime); //not sure values less than 1 make a difference, may be system/environment dependent
printw (" Speed: %.02lf sec \n", opts->trunk_hangtime); //not sure values less than 1 make a difference, may be system/environment dependent
}
if (opts->reverse_mute == 1) printw ("| Reverse Mute - Muting Unencrypted Voice\n");
@ -2565,7 +2635,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
printw ("\n");
printw ("| In Level: [%02d%%] \n", level);
if (opts->dmr_stereo == 0)
{
printw ("| Voice Error: [%X][%X]", state->errs&0xF, state->errs2&0xF);
@ -2588,7 +2658,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw ("------------------------------------------------------------------------------\n");
printw ("--Call Info-------------------------------------------------------------------\n");
//DSTAR
if (lls == 6 || lls == 7 || lls == 18 || lls == 19)
{
@ -2629,7 +2699,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw("RESERVED (%012llx) ", state->m17_dst);
else
printw("%s", state->m17_dst_str);
printw ("\n");
printw ("| ");
@ -2639,7 +2709,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
else
printw("%s", state->m17_src_str);
printw ("\n");
printw ("| ");
@ -2666,7 +2736,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (state->m17_enc == 3)
{
printw (" Reserved Enc - Type: %d", state->m17_enc_st);
}
}
printw ("\n");
@ -2727,7 +2797,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
// printw ("%c", state->ysf_txt[i][j]);
// }
// // printw (" "); //just a single space between each 'block'
// }
// }
printw ("\n");
@ -2750,7 +2820,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
{
printw (" - Frequency: %.06lf Mhz ", (double)state->p25_cc_freq/1000000);
}
}
}
else if (opts->p25_is_tuned == 1)
{
if (idas == 0) printw ("Monitoring RTCH Channel"); //Traffic Channel
@ -2763,8 +2833,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw ("\n");
}
printw ("| ");
// #ifdef LIMAZULUTWEAKS
@ -2862,10 +2932,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
//Active Trunking Channels (NXDN and IDAS)
if (1 == 1) //opts->p25_trunk
if (1 == 1) //opts->p25_trunk
{
printw ("\n");
printw ("| ");
printw ("| ");
//active channel display
attron(COLOR_PAIR(4));
@ -2883,8 +2953,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw("\n");
}
//P25 and DMR BS/MS
//P25 and DMR BS/MS
if ( lls == 0 || lls == 1 || lls == 12 || lls == 13 || lls == 10 ||
lls == 11 || lls == 32 || lls == 33 || lls == 34 || lls == 35 || lls == 36)
{
@ -2895,7 +2965,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
// printw ("%s %s", state->dmr_branding, state->dmr_branding_sub);
printw ("%s ", state->dmr_branding);
printw ("%s", state->dmr_branding_sub);
printw ("%s", state->dmr_site_parms); //site id, net id, etc
printw ("%s", state->dmr_site_parms); //site id, net id, etc
if (state->dmr_rest_channel > 0)
{
printw ("Rest LSN: %02d; ", state->dmr_rest_channel);
@ -2908,7 +2978,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
{
printw ("Freq: %.06lf MHz", (double)state->p25_cc_freq/1000000);
}
}
else if (lls == 32 || lls == 33 || lls == 34)
{
@ -2937,7 +3007,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw (" Phase 2 Invalid Parameters ");
attron(COLOR_PAIR(3));
}
else
else
{
if (state->p25_cc_freq != 0)
{
@ -3059,7 +3129,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//Not always correct, or correct at all, depends on context
//this is already in the call_string anyways
// if(state->dmrburstL == 16 && state->dmr_so == 0x40 && state->R == 0) //0100 0000
// {
// attron(COLOR_PAIR(2));
@ -3096,13 +3166,13 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//Embedded GPS (not LRRP)
printw ("%s ", state->dmr_embedded_gps[0]);
//Embedded Talker Alias Blocks
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 7; j++)
{
printw ("%s", state->dmr_alias_block_segment[0][i][j]);
printw ("%s", state->dmr_alias_block_segment[0][i][j]);
}
}
@ -3145,7 +3215,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//Slot 2 [1] -- Also Including DMR MS now to keep the display more 'uniform' in nature
// if (lls < 30 || lls == 35 || lls == 36)
{
{
printw ("| SLOT 2 - ");
if (state->dmrburstR < 16 && state->carrier == 1 && state->lasttgR > 0 && state->lastsrcR > 0)
{
@ -3161,10 +3231,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw ("%s | ", state->call_string[1]);
printw ("%s ", DMRBusrtTypes[state->dmrburstR]);
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21) ) printw ("*M*");
if (opts->slot_preference == 0 && opts->audio_out_type == 5 && opts->audio_out == 1 && ( state->dmrburstL == 16 || state->dmrburstL == 21) && (state->dmrburstR == 16 || state->dmrburstR == 21) ) printw ("*M*");
printw ("\n");
printw ("| V XTRA | "); //10 spaces
if(state->dmrburstR == 16 && state->payload_algidR == 0 && (state->dmr_soR & 0xCF) == 0x40) //4F or CF mask?
@ -3285,7 +3355,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if(state->dmrburstR == 16 || state->dmrburstR == 21) //only during call
{
//Embedded GPS (not LRRP)
attron(COLOR_PAIR(4));
printw ("%s ", state->dmr_embedded_gps[1]);
@ -3295,7 +3365,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
{
for (int j = 0; j < 7; j++)
{
printw ("%s", state->dmr_alias_block_segment[1][i][j]);
printw ("%s", state->dmr_alias_block_segment[1][i][j]);
}
}
@ -3313,7 +3383,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
attron(COLOR_PAIR(4));
printw ("%s", state->dmr_lrrp_gps[1]);
}
//Group Name Labels from CSV import
if (state->dmrburstR == 16 || state->dmrburstR > 19)
{
@ -3401,7 +3471,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//EDACS and ProVoice
if (lls == 14 || lls == 15 || lls == 37 || lls == 38)
{
attroff (COLOR_PAIR(3)); //colors off for EDACS
attroff (COLOR_PAIR(3)); //colors off for EDACS
if (state->edacs_site_id != 0)
{
if (opts->p25_is_tuned == 0)
@ -3412,8 +3482,8 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
{
printw ("| Monitoring Voice Channel - LCN [%02d]\n", state->edacs_tuned_lcn);
//since we are tuned, keep updating the time so it doesn't disappear during call
call_matrix[state->edacs_tuned_lcn][5] = time(NULL);
}
call_matrix[state->edacs_tuned_lcn][5] = time(NULL);
}
printw ("| SITE [%03lld][%02llX]", state->edacs_site_id, state->edacs_site_id);
if (state->ea_mode == 1)
@ -3430,11 +3500,11 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
for (i = 1; i <= state->edacs_lcn_count; i++)
{
//shim 443 afs in here for display purposes
int a = (call_matrix[i][3] >> 7) & 0xF;
int fs = call_matrix[i][3] & 0x7F;
printw ("| - LCN [%02d][%.06lf] MHz", i, (double)state->trunk_lcn_freq[i-1]/1000000);
// Compute 4:4:3 AFS for display purposes only
int a = (call_matrix[i][2] >> 7) & 0xF;
int fs = call_matrix[i][2] & 0x7F;
printw ("| - LCN [%02d][%010.06lf] MHz", i, (double)state->trunk_lcn_freq[i-1]/1000000);
//print Control Channel on LCN line with the current Control Channel
if ( (i) == state->edacs_cc_lcn)
{
@ -3442,12 +3512,82 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
printw (" Control Channel");
attroff (COLOR_PAIR(1));
}
int print_call = 0;
//print active calls on corresponding LCN line
if ((i != state->edacs_cc_lcn) && time(NULL) - call_matrix[i][5] < 2)
if ((i != state->edacs_cc_lcn) && time(NULL) - call_matrix[i][5] < 2)
{
attron (COLOR_PAIR(3));
if (state->ea_mode == 1) printw (" TG [%5lld] SRC [%8lld]", call_matrix[i][2], call_matrix[i][3] );
else printw (" AFS [%03lld][%02d-%03d]", call_matrix[i][3], a, fs );
print_call = 3;
attron (COLOR_PAIR(3));
}
//print dying or dead calls in red for x seconds longer
else if ( (i != state->edacs_cc_lcn) && (time(NULL) - call_matrix[i][5] >= 2) && (time(NULL) - call_matrix[i][5] < 5) )
{
print_call = 2;
attron (COLOR_PAIR(2));
}
if (print_call != 0)
{
if (state->ea_mode == 1) {
// Voice call
if ((call_matrix[i][4] & EDACS_IS_VOICE) != 0)
{
// System all-call
if ((call_matrix[i][4] & EDACS_IS_GROUP) != 0)
printw (" TGT [%8lld] SRC [%8lld]", call_matrix[i][2], call_matrix[i][3] );
// I-Call
else if ((call_matrix[i][4] & EDACS_IS_INDIVIDUAL) != 0)
printw (" TGT [%8lld] SRC [%8lld] I-Call", call_matrix[i][2], call_matrix[i][3] );
// System all-call
else if ((call_matrix[i][4] & EDACS_IS_ALL_CALL) != 0)
printw (" TGT [ SYSTEM ] SRC [%8lld] All-Call", call_matrix[i][3] );
// Interconnect call
else if ((call_matrix[i][4] & EDACS_IS_INTERCONNECT) != 0)
printw (" TGT [ SYSTEM ] SRC [%8lld] Interconnect", call_matrix[i][3] );
// Unknown call
else
printw (" Unknown call type" );
// Call flags
if ((call_matrix[i][4] & EDACS_IS_DIGITAL) == 0) printw (" [Ana]");
else printw (" [Dig]");
if ((call_matrix[i][4] & EDACS_IS_EMERGENCY) != 0) printw ("[EM]");
}
else
// Data call
printw (" TGT [ DATA ] SRC [%8lld] Data", call_matrix[i][3] );
}
else
{
// Voice call
if ((call_matrix[i][4] & EDACS_IS_VOICE) != 0)
{
// Group call
if ((call_matrix[i][4] & EDACS_IS_GROUP) != 0)
printw (" TGT [%6lld][%02d-%03d] SRC [%5lld]", call_matrix[i][2], a, fs, call_matrix[i][3] );
// I-Call
else if ((call_matrix[i][4] & EDACS_IS_INDIVIDUAL) != 0)
printw (" TGT [%6lld][ UNIT ] SRC [%5lld] I-Call", call_matrix[i][2], call_matrix[i][3] );
// System all-call
else if ((call_matrix[i][4] & EDACS_IS_ALL_CALL) != 0)
printw (" TGT [ SYSTEM ] SRC [%5lld] All-Call", call_matrix[i][3] );
// Interconnect call
else if ((call_matrix[i][4] & EDACS_IS_INTERCONNECT) != 0)
printw (" TGT [ SYSTEM ] SRC [%5lld] Interconnect", call_matrix[i][3] );
// Unknown call
else
printw (" Unknown call type" );
// Call flags
if ((call_matrix[i][4] & EDACS_IS_DIGITAL) == 0) printw (" [Ana]");
else printw (" [Dig]");
if ((call_matrix[i][4] & EDACS_IS_EMERGENCY) != 0) printw ("[EM]");
}
else
// Data call
printw (" TGT [ DATA ] SRC [%8lld] Data", call_matrix[i][3] );
}
for (int k = 0; k < state->group_tally; k++)
{
if (state->group_array[k].groupNumber == call_matrix[i][2] && call_matrix[i][2] != 0)
@ -3463,37 +3603,19 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
break;
}
}
attroff (COLOR_PAIR(3));
if (print_call == 3)
attroff (COLOR_PAIR(3));
else if (print_call == 2)
attroff (COLOR_PAIR(2));
}
//print dying or dead calls in red for x seconds longer
if ( (i != state->edacs_cc_lcn) && (time(NULL) - call_matrix[i][5] >= 2) && (time(NULL) - call_matrix[i][5] < 5) )
{
attron (COLOR_PAIR(2));
if (state->ea_mode == 1) printw (" TG [%5lld] SRC [%8lld]", call_matrix[i][2], call_matrix[i][3] );
else printw (" AFS [%03lld][%02d-%03d]", call_matrix[i][3], a, fs );
for (int k = 0; k < state->group_tally; k++)
{
if (state->group_array[k].groupNumber == call_matrix[i][2] && call_matrix[i][2] != 0)
{
printw (" [%s]", state->group_array[k].groupName);
printw ("[%s]", state->group_array[k].groupMode);
break;
}
else if (state->group_array[k].groupNumber == call_matrix[i][3] && call_matrix[i][3] != 0)
{
printw (" [%s]", state->group_array[k].groupName);
printw ("[%s]", state->group_array[k].groupMode);
break;
}
}
attroff (COLOR_PAIR(2));
}
if (i == state->edacs_tuned_lcn && opts->p25_is_tuned == 1) printw (" **T**"); //asterisk which lcn is opened
if (i == state->edacs_tuned_lcn && opts->p25_is_tuned == 1) printw (" **T**"); //asterisk which lcn is tuned
printw ("\n");
}
if (state->carrier == 1)
{
attron (COLOR_PAIR(3));
attron (COLOR_PAIR(3));
}
}
@ -3585,23 +3707,76 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//EDACS and ProVoice, outside of timestamp loop
if (call_matrix[j][0] == 14 || call_matrix[j][0] == 15 || call_matrix[j][0] == 37 || call_matrix[j][0] == 38 )
{
if (call_matrix[j][3] != 0)
if (call_matrix[j][2] != 0)
{
printw ("| ");
printw ("%s ", getDateC(call_matrix[j][5]) );
printw ("%s ", getDateC(call_matrix[j][5]) );
printw ("%s ", getTimeC(call_matrix[j][5]) );
printw ("LCN [%2lld] ", call_matrix[j][1]);
if (state->ea_mode == 1)
{
printw ("Group [%8lld] ", call_matrix[j][2]);
printw ("Source [%8lld] ", call_matrix[j][3]);
// Voice call
if ((call_matrix[j][4] & EDACS_IS_VOICE) != 0)
{
// Group call
if ((call_matrix[j][4] & EDACS_IS_GROUP) != 0)
printw ("Target [%8lld] Source [%8lld]", call_matrix[j][2], call_matrix[j][3]);
// I-Call
else if ((call_matrix[j][4] & EDACS_IS_INDIVIDUAL) != 0)
printw ("Target [%8lld] Source [%8lld] I-Call", call_matrix[j][2], call_matrix[j][3]);
// System all-call
else if ((call_matrix[j][4] & EDACS_IS_ALL_CALL) != 0)
printw ("Target [ SYSTEM ] Source [%8lld] All-Call", call_matrix[j][3]);
// Interconnect
else if ((call_matrix[j][4] & EDACS_IS_INTERCONNECT) != 0)
printw ("Target [ SYSTEM ] Source [%8lld] Interconnect", call_matrix[j][3]);
// Unknown call
else
printw ("Unknown call type");
// Call flags
if ((call_matrix[j][4] & EDACS_IS_DIGITAL) == 0) printw (" [Ana]");
else printw (" [Dig]");
if ((call_matrix[j][4] & EDACS_IS_EMERGENCY) != 0) printw ("[EM]");
}
else
// Data call
printw ("Target [ DATA ] Source [%8lld] Data", call_matrix[j][3]);
}
else
else
{
int a = (call_matrix[j][3] >> 7) & 0xF;
int fs = call_matrix[j][3] & 0x7F;
printw (" AFS [%03lld][%02d-%03d]", call_matrix[j][3], a, fs );
}
// Voice call
if ((call_matrix[j][4] & EDACS_IS_VOICE) != 0)
{
// Compute 4:4:3 AFS for display purposes only
int a = (call_matrix[j][2] >> 7) & 0xF;
int fs = call_matrix[j][2] & 0x7F;
// Group call
if ((call_matrix[j][4] & EDACS_IS_GROUP) != 0)
printw ("Target [%6lld][%02d-%03d] Source [%5lld]", call_matrix[j][2], a, fs, call_matrix[j][3]);
// I-Call
else if ((call_matrix[j][4] & EDACS_IS_INDIVIDUAL) != 0)
printw ("Target [%6lld][ UNIT ] Source [%5lld] I-Call", call_matrix[j][2], call_matrix[j][3]);
// System all-call
else if ((call_matrix[j][4] & EDACS_IS_ALL_CALL) != 0)
printw ("Target [ SYSTEM ] Source [%5lld] All-Call", call_matrix[j][3]);
// Interconnect
else if ((call_matrix[j][4] & EDACS_IS_INTERCONNECT) != 0)
printw ("Target [ SYSTEM ] Source [%5lld] Interconnect", call_matrix[j][3]);
// Unknown call
else
printw ("Unknown call type");
// Call flags
if ((call_matrix[j][4] & EDACS_IS_DIGITAL) == 0) printw (" [Ana]");
else printw (" [Dig]");
if ((call_matrix[j][4] & EDACS_IS_EMERGENCY) != 0) printw ("[EM]");
}
else
// Data call
printw ("Target [ DATA ] Source [%5lld] Data", call_matrix[j][3]);
}
//test
for (int k = 0; k < state->group_tally; k++)
{
@ -3621,7 +3796,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//end test
printw ("\n");
}
}
} //end Call History
//fence bottom
@ -3678,7 +3853,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
else if (opts->slot1_on == 0)
{
opts->slot1_on = 1;
if (opts->audio_out_type == 5) //OSS 48k/1
if (opts->audio_out_type == 5) //OSS 48k/1
{
opts->slot_preference = 0; //slot 1
// opts->slot2_on = 0; //turn off slot 2
@ -3704,7 +3879,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
else if (opts->slot2_on == 0)
{
opts->slot2_on = 1;
if (opts->audio_out_type == 5) //OSS 48k/1
if (opts->audio_out_type == 5) //OSS 48k/1
{
opts->slot_preference = 1; //slot 2
// opts->slot1_on = 0; //turn off slot 1
@ -3910,14 +4085,14 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
{
fprintf (stderr, "-T %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);
mkdir(wav_file_directory, 0700);
}
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);
openWavOutFileL (opts, state);
openWavOutFileR (opts, state);
}
//this one could cause issues, but seems okay
@ -3934,15 +4109,15 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
//
#ifdef AERO_BUILD //this might be okay on Aero as well, will need to look into and/or test
//
//
#else
if (c == 115) //'s' key, stop playing wav or symbol in files
{
if (opts->symbolfile != NULL)
{
if (opts->audio_in_type == 4)
if (opts->audio_in_type == 4)
{
fclose(opts->symbolfile);
fclose(opts->symbolfile);
}
}
@ -3956,12 +4131,12 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
opts->audio_in_type = 0;
openPulseInput(opts);
}
else opts->audio_in_type = 5; //exitflag = 1;
else opts->audio_in_type = 5; //exitflag = 1;
}
#endif
//makes buzzing sound when locked out in new audio config and short, probably something to do with processaudio running or not running
//makes buzzing sound when locked out in new audio config and short, probably something to do with processaudio running or not running
if (state->lasttg != 0 && opts->frame_provoice != 1 && c == 33) //SHIFT+'1' key (exclamation point), lockout slot 1 or conventional tg from tuning/playback during session
{
state->group_array[state->group_tally].groupNumber = state->lasttg;
@ -4097,40 +4272,40 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
// if (c == 48) //'0' key, toggle upsampled audio smoothing
// {
// if (state->audio_smoothing == 1) state->audio_smoothing = 0;
// else state->audio_smoothing = 1;
// else state->audio_smoothing = 1;
// }
if (opts->p25_trunk == 1 && c == 119) //'w' key, toggle white list/black list mode
if (opts->p25_trunk == 1 && c == 119) //'w' key, toggle white list/black list mode
{
if (opts->trunk_use_allow_list == 1) opts->trunk_use_allow_list = 0;
else opts->trunk_use_allow_list = 1;
else opts->trunk_use_allow_list = 1;
}
if (opts->p25_trunk == 1 && c == 117) //'u' key, toggle tune private calls
{
if (opts->trunk_tune_private_calls == 1) opts->trunk_tune_private_calls = 0;
else opts->trunk_tune_private_calls = 1;
else opts->trunk_tune_private_calls = 1;
}
if (opts->p25_trunk == 1 && c == 100) //'d' key, toggle tune data calls
{
if (opts->trunk_tune_data_calls == 1) opts->trunk_tune_data_calls = 0;
else opts->trunk_tune_data_calls = 1;
else opts->trunk_tune_data_calls = 1;
}
if (opts->p25_trunk == 1 && c == 101) //'e' key, toggle tune enc calls (P25 only on certain grants)
{
if (opts->trunk_tune_enc_calls == 1) opts->trunk_tune_enc_calls = 0;
else opts->trunk_tune_enc_calls = 1;
else opts->trunk_tune_enc_calls = 1;
}
if (opts->p25_trunk == 1 && c == 103) //'g' key, toggle tune group calls
{
if (opts->trunk_tune_group_calls == 1) opts->trunk_tune_group_calls = 0;
else opts->trunk_tune_group_calls = 1;
else opts->trunk_tune_group_calls = 1;
}
if (c == 70) //'F' key - toggle agressive sync/crc failure/ras
if (c == 70) //'F' key - toggle agressive sync/crc failure/ras
{
if (opts->aggressive_framesync == 0) opts->aggressive_framesync = 1;
else opts->aggressive_framesync = 0;
@ -4138,7 +4313,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (c == 68) //'D' key - Reset DMR Site Parms/Call Strings, etc.
{
//dmr trunking/ncurses stuff
//dmr trunking/ncurses stuff
state->dmr_rest_channel = -1; //init on -1
state->dmr_mfid = -1; //
@ -4200,7 +4375,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
if (opts->audio_in_type == 0) closePulseInput(opts);
fprintf (stderr, "TCP Socket Connected Successfully.\n");
opts->audio_in_type = 8;
}
}
}
else fprintf (stderr, "TCP Socket Connection Error.\n");
}
@ -4272,7 +4447,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
state->symbolCenter = 3;
}
fprintf (stderr, "\n User Activated Return to CC; \n ");
fprintf (stderr, "\n User Activated Return to CC; \n ");
}
@ -4318,15 +4493,15 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
{
state->lcn_freq_roll++;
//check roll again if greater than expected, then go back to zero
if (state->lcn_freq_roll >= state->lcn_freq_count)
if (state->lcn_freq_roll >= state->lcn_freq_count)
{
state->lcn_freq_roll = 0; //reset to zero
}
}
}
}
//check that we have a non zero value first, then tune next frequency
if (state->trunk_lcn_freq[state->lcn_freq_roll] != 0)
if (state->trunk_lcn_freq[state->lcn_freq_roll] != 0)
{
//rigctl
if (opts->use_rigctl == 1)
@ -4343,7 +4518,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
}
fprintf (stderr, "\n User Activated Channel Cycle;");
fprintf (stderr, " Tuning to Frequency: %.06lf MHz\n",
fprintf (stderr, " Tuning to Frequency: %.06lf MHz\n",
(double)state->trunk_lcn_freq[state->lcn_freq_roll]/1000000);
}
@ -4365,22 +4540,48 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state)
{
state->samplesPerSymbol = 8;
state->symbolCenter = 3;
}
}
}
if (opts->m17encoder == 1 && c == 92) //'\' key - toggle M17 encoder Encode + TX
if (opts->m17encoder == 1 && c == 92) //'\' key - toggle M17 encoder Encode + TX
{
if (state->m17encoder_tx == 0) state->m17encoder_tx = 1;
else state->m17encoder_tx = 0;
//flag on the EOT marker to send last frame after toggling encoder to zero
if (state->m17encoder_tx == 0) state->m17encoder_eot = 1;
}
if(opts->frame_provoice == 1 && c == 65) //'A' Key, toggle ESK mask 0xA0
{
if (state->esk_mask == 0) state->esk_mask = 0xA0;
else state->esk_mask = 0;
}
if(opts->frame_provoice == 1 && c == 83) //'S' Key, toggle STD or EA mode and reset
{
if (state->ea_mode == -1) state->ea_mode = 0;
else if (state->ea_mode == 0) state->ea_mode = 1;
else state->ea_mode = 0;
//reset -- test to make sure these don't do weird things when reset
state->edacs_site_id = 0;
state->edacs_lcn_count = 0;
state->edacs_cc_lcn = 0;
state->edacs_vc_lcn = 0;
state->edacs_tuned_lcn = -1;
state->edacs_vc_call_type = 0;
state->p25_cc_freq = 0;
opts->p25_is_tuned = 0;
state->lasttg = 0;
state->lastsrc = 0;
}
//anything with an entry box will need the inputs and outputs stopped first
//so probably just write a function to handle c input, and when c = certain values
//so probably just write a function to handle c input, and when c = certain values
//needing an entry box, then stop all of those
//allocated memory pointer needs to be free'd each time

File diff suppressed because it is too large Load Diff

View File

@ -27,12 +27,19 @@ void processProVoice (dsd_opts * opts, dsd_state * state)
fprintf (stderr," VOICE");
//print group and source values if EA trunked
//print group/target and source values if EA trunked
if (opts->p25_trunk == 1 && opts->p25_is_tuned == 1 && state->ea_mode == 1)
{
fprintf (stderr, "%s", KGRN);
fprintf (stderr, " Site: %lld Group: %d Source: %d LCN: %d ",
state->edacs_site_id, state->lasttg, state->lastsrc, state->edacs_tuned_lcn);
if (state->lasttg > 100000) {
// I-Call
fprintf (stderr, " Site: %lld Target: %d Source: %d LCN: %d ",
state->edacs_site_id, state->lasttg - 100000, state->lastsrc, state->edacs_tuned_lcn);
} else {
// Group call
fprintf (stderr, " Site: %lld Group: %d Source: %d LCN: %d ",
state->edacs_site_id, state->lasttg, state->lastsrc, state->edacs_tuned_lcn);
}
fprintf (stderr, "%s", KNRM);
}
//print afs value if standard/networked trunked