From 57e3f518dd6ae32ef2784f5a746b11128f4edfe4 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Thu, 15 Dec 2022 19:22:54 -0500 Subject: [PATCH] DMR T3 DX Calls; RTL Input Frequency Check; --- src/dmr_csbk.c | 22 +++++++++++++++++++--- src/edacs-fme.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/nxdn_element.c | 12 ++++++++++-- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/dmr_csbk.c b/src/dmr_csbk.c index bdac93f..1b17b95 100644 --- a/src/dmr_csbk.c +++ b/src/dmr_csbk.c @@ -48,7 +48,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 fprintf (stderr, "%s", KYEL); //7.1.1.1.1 Channel Grant CSBK/MBC PDU - if (csbk_o > 47 && csbk_o < 53 ) + if (csbk_o > 47 && csbk_o < 55 ) { //users will need to import the cc frequency as channel 0 for now @@ -65,6 +65,8 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 if (csbk_o == 50) fprintf (stderr, " Private Broadcast Voice Channel Grant (BTV_GRANT)"); if (csbk_o == 51) fprintf (stderr, " Private Data Channel Grant: Single Item (PD_GRANT)"); if (csbk_o == 52) fprintf (stderr, " Talkgroup Data Channel Grant: Single Item (TD_GRANT)"); + if (csbk_o == 53) fprintf (stderr, " Duplex Private Voice Channel Grant (PV_GRANT_DX)"); + if (csbk_o == 54) fprintf (stderr, " Duplex Private Data Channel Grant (PD_GRANT_DX)"); //Logical Physical Channel Number uint16_t lpchannum = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[16], 12); @@ -79,7 +81,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 //LCN conveyed here is the tdma timeslot variety, and not the RF frequency variety uint8_t lcn = cs_pdu_bits[28]; //the next three bits can have different meanings depending on which item above for context - uint8_t st1 = cs_pdu_bits[29]; //late_entry, hi_rate + uint8_t st1 = cs_pdu_bits[29]; //late_entry, hi_rate, reserved(dx) uint8_t st2 = cs_pdu_bits[30]; //emergency uint8_t st3 = cs_pdu_bits[31]; //offset, call direction //target and source are always the same bits @@ -137,7 +139,7 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 } //if not a data channel grant (only tuning to voice channel grants) - if (csbk_o < 51) //48, 49, 50 are voice grants, 51 and 52 are data grants + if (csbk_o == 48 || csbk_o == 49 || csbk_o == 50 || csbk_o == 53) //48, 49, 50 are voice grants, 51 and 52 are data grants, 53 Duplex Private Voice, 54 Duplex Private Data { //shim in chan map 0 as the cc frequency, user will need to specify it in the channel map file if (state->p25_cc_freq != 0 && state->trunk_chan_map[0] != 0) state->p25_cc_freq = state->trunk_chan_map[0]; @@ -263,6 +265,13 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 if (ccfreq != 0) state->p25_cc_freq = ccfreq; } + //if using rtl input, we can ask for the current frequency tuned + if (opts->audio_in_type == 3 && state->p25_cc_freq == 0) + { + ccfreq = (long int)opts->rtlsdr_center_freq; + if (ccfreq != 0) state->p25_cc_freq = ccfreq; + } + uint16_t syscode = (uint16_t)ConvertBitIntoBytes(&cs_pdu_bits[40], 16); //debug print @@ -574,6 +583,13 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 if (ccfreq != 0) state->p25_cc_freq = ccfreq; } + //if using rtl input, we can ask for the current frequency tuned + if (opts->audio_in_type == 3 && state->p25_cc_freq == 0) + { + ccfreq = (long int)opts->rtlsdr_center_freq; + if (ccfreq != 0) state->p25_cc_freq = ccfreq; + } + //shim in here for ncurses freq display when not trunking (playback, not live) if (opts->p25_trunk == 0 && state->trunk_chan_map[lcn] != 0) { diff --git a/src/edacs-fme.c b/src/edacs-fme.c index 34d5cf3..7dbd735 100644 --- a/src/edacs-fme.c +++ b/src/edacs-fme.c @@ -199,6 +199,25 @@ void edacs(dsd_opts * opts, dsd_state * state) state->edacs_lcn_count = state->edacs_cc_lcn; } fprintf (stderr, " [%d]", state->edacs_cc_lcn); + + //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) + { + long int lcnfreq = 0; + //if using rigctl, we can ask for the currrent frequency + if (opts->use_rigctl == 1) + { + lcnfreq = GetCurrentFreq (opts->rigctl_sockfd); + if (lcnfreq != 0) state->trunk_lcn_freq[state->edacs_cc_lcn-1] = lcnfreq; + } + //if using rtl input, we can ask for the current frequency tuned + if (opts->audio_in_type == 3) + { + lcnfreq = (long int)opts->rtlsdr_center_freq; + if (lcnfreq != 0) state->trunk_lcn_freq[state->edacs_cc_lcn-1] = lcnfreq; + } + } + //set trunking cc here so we know where to come back to if (opts->p25_trunk == 1 && state->trunk_lcn_freq[state->edacs_cc_lcn-1] != 0) { @@ -309,10 +328,36 @@ void edacs(dsd_opts * opts, dsd_state * state) fprintf (stderr, "%s", KNRM); state->edacs_site_id = site_id; state->edacs_cc_lcn = cc_lcn; + if (state->edacs_cc_lcn > state->edacs_lcn_count && lcn < 26) { state->edacs_lcn_count = state->edacs_cc_lcn; } + + //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) + { + long int lcnfreq = 0; + //if using rigctl, we can ask for the currrent frequency + if (opts->use_rigctl == 1) + { + lcnfreq = GetCurrentFreq (opts->rigctl_sockfd); + if (lcnfreq != 0) state->trunk_lcn_freq[state->edacs_cc_lcn-1] = lcnfreq; + } + //if using rtl input, we can ask for the current frequency tuned + if (opts->audio_in_type == 3) + { + lcnfreq = (long int)opts->rtlsdr_center_freq; + if (lcnfreq != 0) state->trunk_lcn_freq[state->edacs_cc_lcn-1] = lcnfreq; + } + } + + //set trunking cc here so we know where to come back to + if (opts->p25_trunk == 1 && state->trunk_lcn_freq[state->edacs_cc_lcn-1] != 0) + { + state->p25_cc_freq = state->trunk_lcn_freq[state->edacs_cc_lcn-1]; //index starts at zero, lcn's locally here start at 1 + } + } //voice call assignment diff --git a/src/nxdn_element.c b/src/nxdn_element.c index 67012ed..1a42f7d 100644 --- a/src/nxdn_element.c +++ b/src/nxdn_element.c @@ -236,16 +236,24 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa //check for control channel frequency in the channel map if not available if (opts->p25_trunk == 1 && state->p25_cc_freq == 0) { + long int ccfreq = 0; if (state->trunk_chan_map[0] != 0) state->p25_cc_freq = state->trunk_chan_map[0]; - //if not available from the import file, then poll rigctl if its available + //we are assuming that the current channel is the control channel //unsure whether or not control signalling is available on NXDN voice channels + + //if not available from the import file, then poll rigctl if its available else if (opts->use_rigctl == 1) { - long int ccfreq = 0; ccfreq = GetCurrentFreq (opts->rigctl_sockfd); if (ccfreq != 0) state->p25_cc_freq = ccfreq; } + //if using rtl input, we can ask for the current frequency tuned + else if (opts->audio_in_type == 3) + { + ccfreq = (long int)opts->rtlsdr_center_freq; + if (ccfreq != 0) state->p25_cc_freq = ccfreq; + } } //run group/source analysis and tune if available/desired