From 53980c98edf0ce5eb429817d2c96a63221f5ba66 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Tue, 13 Dec 2022 20:20:28 -0500 Subject: [PATCH] DMR Con+ VC Hangtime Tweaks; --- include/dsd.h | 2 ++ src/dmr_bs.c | 3 +++ src/dmr_csbk.c | 18 +++++++++--------- src/dmr_data.c | 27 +++++++++++++++++++++++++++ src/dmr_ms.c | 5 ++++- src/dsd_main.c | 2 ++ 6 files changed, 47 insertions(+), 10 deletions(-) diff --git a/include/dsd.h b/include/dsd.h index f8a067c..55ad7b3 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -600,6 +600,8 @@ typedef struct int lcn_freq_count; int lcn_freq_roll; //number we have 'rolled' to in search of the CC time_t last_cc_sync_time; //use this to start hunting for CC after signal lost + time_t last_vc_sync_time; //flag for voice activity bursts, tune back on con+ after more than x seconds no voice + int is_con_plus; //con_plus flag for knowing its safe to skip payload channel after x seconds of no voice sync //new nxdn stuff int nxdn_part_of_frame; diff --git a/src/dmr_bs.c b/src/dmr_bs.c index e3da820..f613d1b 100644 --- a/src/dmr_bs.c +++ b/src/dmr_bs.c @@ -364,6 +364,9 @@ void dmrBS (dsd_opts * opts, dsd_state * state) if (internalslot == 0) vc1++; if (internalslot == 1) vc2++; + //update voice sync time for trunking purposes (particularly Con+) + state->last_vc_sync_time = time(NULL); + //reset err checks cach_err = 1; tact_okay = 0; diff --git a/src/dmr_csbk.c b/src/dmr_csbk.c index f28aec5..27b80f6 100644 --- a/src/dmr_csbk.c +++ b/src/dmr_csbk.c @@ -495,9 +495,9 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 } } - //either j, or j+1 != restchannel (don't think restchannel would show a tg value, but could erroneously do so) - //also, some active channels reported a tg value of 0, so could be bad decode, or unit-to-unit? - if (t_tg[j] != 0 && state->p25_cc_freq != 0 && opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0)) //&& j+1 != restchannel + //no more 0 reporting, that was some bad code that caused that issue + //without priority, this will tune the first one it finds (if group isn't blocked) + if (t_tg[j] != 0 && state->p25_cc_freq != 0 && opts->p25_trunk == 1 && (strcmp(mode, "DE") != 0)) { if (state->trunk_chan_map[j+1] != 0) //if we have a valid frequency { @@ -568,8 +568,6 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 state->dmr_mfid = 0x06; sprintf (state->dmr_branding, "%s", "Motorola"); sprintf(state->dmr_branding_sub, "Con+ "); - // state->dmr_vc_lcn = lcn; - // state->dmr_vc_lsn = lcn * (tslot+1); //if using rigctl we can set an unknown cc frequency by polling rigctl for the current frequency if (opts->use_rigctl == 1 && state->p25_cc_freq == 0) //if not set from channel map 0 @@ -613,7 +611,8 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 if (opts->setmod_bw != 0 ) SetModulation(opts->rigctl_sockfd, opts->setmod_bw); SetFreq(opts->rigctl_sockfd, state->trunk_chan_map[lcn]); state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[lcn]; - opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop + opts->p25_is_tuned = 1; //set to 1 to set as currently tuned so we don't keep tuning nonstop + state->is_con_plus = 1; //flag on } } @@ -623,6 +622,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 rtl_udp_tune (opts, state, state->trunk_chan_map[lcn]); state->p25_vc_freq[0] = state->p25_vc_freq[1] = state->trunk_chan_map[lcn]; opts->p25_is_tuned = 1; + state->is_con_plus = 1; //flag on } } } @@ -651,10 +651,10 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 fprintf (stderr, "\n"); uint32_t srcAddr = ( (cs_pdu[2] << 16) + (cs_pdu[3] << 8) + cs_pdu[4] ); uint32_t grpAddr = ( (cs_pdu[5] << 16) + (cs_pdu[6] << 8) + cs_pdu[7] ); - uint8_t lcn = ( (cs_pdu[8] & 0xF0 ) >> 4 ) ; ////extract(csbk, 64, 68); //double check these? - uint8_t tslot = ( (cs_pdu[8] & 0x08 ) >> 3 ); //csbk[68]; + uint8_t lcn = ( (cs_pdu[8] & 0xF0 ) >> 4 ); + uint8_t tslot = ( (cs_pdu[8] & 0x08 ) >> 3 ); fprintf (stderr, "%s", KYEL); - fprintf (stderr, " Connect Plus Terminate Channel Grant\n"); //Data only shows a srcAddr?? + fprintf (stderr, " Connect Plus Terminate Channel Grant\n"); fprintf (stderr, " srcAddr(%8d), grpAddr(%8d), LCN(%d), TS(%d)",srcAddr, grpAddr, lcn, tslot); state->dmr_mfid = 0x06; sprintf (state->dmr_branding, "%s", "Motorola"); diff --git a/src/dmr_data.c b/src/dmr_data.c index c0cdba8..56b1cee 100644 --- a/src/dmr_data.c +++ b/src/dmr_data.c @@ -315,4 +315,31 @@ dmr_data_sync (dsd_opts * opts, dsd_state * state) skipDibit (opts, state, 12 + 49 + 5); } + //if using con+ trunking and last voice observed more than x seconds ago, snap back to con+ cc + //con+ voice channels can have extremely long idle periods without properly tearing down + if (opts->p25_trunk == 1 && opts->p25_is_tuned == 1 && state->is_con_plus == 1) + { + if ( (time(NULL) - state->last_vc_sync_time > 3) ) + { + if (opts->use_rigctl == 1) //rigctl tuning + { + if (opts->setmod_bw != 0) SetModulation(opts->rigctl_sockfd, opts->setmod_bw); + SetFreq(opts->rigctl_sockfd, state->p25_cc_freq); + + } + + else if (opts->audio_in_type == 3) //rtl_fm tuning + { + //UDP command to tune the RTL dongle + rtl_udp_tune(opts, state, state->p25_cc_freq); + } + opts->p25_is_tuned = 0; + //zero out vc frequencies + state->p25_vc_freq[0] = 0; + state->p25_vc_freq[1] = 0; + state->last_cc_sync_time = time(NULL); + state->is_con_plus = 0; //con+ flag off + } + } + } diff --git a/src/dmr_ms.c b/src/dmr_ms.c index bc732eb..5b64dca 100644 --- a/src/dmr_ms.c +++ b/src/dmr_ms.c @@ -174,7 +174,7 @@ void dmrMS (dsd_opts * opts, dsd_state * state) if(vc > 1 && vc < 6) //grab on vc1 values 2-5 B C D and E { state->dmr_embedded_signalling[internalslot][vc-1][i*2] = (1 & (dibit >> 1)); // bit 1 - state->dmr_embedded_signalling[internalslot][vc-1][i*2+1] = (1 & dibit); // bit 1 + state->dmr_embedded_signalling[internalslot][vc-1][i*2+1] = (1 & dibit); // bit 0 } } @@ -264,6 +264,9 @@ void dmrMS (dsd_opts * opts, dsd_state * state) //errors in ms/mono since we skip the other slot // cach_err = dmr_cach (opts, state, cachdata); + //update voice sync time for trunking purposes (particularly Con+) + state->last_vc_sync_time = time(NULL); + vc++; //this is necessary because we need to skip and collect dibits, not just skip them if (vc > 6) goto END; diff --git a/src/dsd_main.c b/src/dsd_main.c index 88b7049..89342a6 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -737,6 +737,8 @@ initState (dsd_state * state) state->lcn_freq_count = 0; //number of frequncies imported from LCN state->lcn_freq_roll = 0; //needs reset if sync is found? state->last_cc_sync_time = time(NULL); + state->last_vc_sync_time = time(NULL); + state->is_con_plus = 0; //dmr trunking/ncurses stuff state->dmr_rest_channel = -1; //init on -1