diff --git a/examples/Example_Usage.md b/examples/Example_Usage.md index 0e4549b..943280f 100644 --- a/examples/Example_Usage.md +++ b/examples/Example_Usage.md @@ -195,6 +195,10 @@ Z - Simulate NoCarrier/No VC/CC sync (capital Z) ! - Lockout Tuning/Playback of TG in Slot 1 or Conventional -- Current Session Only if no group.csv file specified @ - Lockout Tuning/Playback of TG in Slot 2 -- Current Session Only if no group.csv file specified + +k - Hold TG in Slot 1 or Conventional, or clear current hold (Testing/WIP: DMR T3 Only) +l - Hold TG in Slot 2 on TDMA Systems, or clear current hold (Testing/WIP: DMR T3 Only) + ``` Sending Audio to a Icecast 2 Server via FFmpeg (Windows) diff --git a/include/dsd.h b/include/dsd.h index 3690c86..e2ed506 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -681,6 +681,7 @@ typedef struct int dmr_vc_lsn; int dmr_tuned_lcn; uint16_t dmr_cc_lpcn; //dmr t3 logical physical channel number + uint32_t tg_hold; //single TG to hold on when enabled //edacs int ea_mode; diff --git a/src/dmr_csbk.c b/src/dmr_csbk.c index fbc1e38..4970675 100644 --- a/src/dmr_csbk.c +++ b/src/dmr_csbk.c @@ -207,6 +207,11 @@ 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 == 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 { + + //if tg hold is specified and matches target, allow for a call pre-emption by nullifying the last vc sync time + if (state->tg_hold != 0 && state->tg_hold == target) + state->last_vc_sync_time = 0; + //TIII tuner fix if voice assignment occurs to the control channel itself, //then it may not want to resume tuning due to no framesync loss after call ends if ( (time(NULL) - state->last_vc_sync_time > 2) ) @@ -243,7 +248,11 @@ void dmr_cspdu (dsd_opts * opts, dsd_state * state, uint8_t cs_pdu_bits[], uint8 strcpy (mode, state->group_array[i].groupMode); break; } - } + } + + //TG hold on DMR T3 Systems -- block non-matching target, allow matching target + if (state->tg_hold != 0 && state->tg_hold != target) sprintf (mode, "%s", "B"); + if (state->tg_hold != 0 && state->tg_hold == target) sprintf (mode, "%s", "A"); if (state->p25_cc_freq != 0 && opts->p25_trunk == 1 && (strcmp(mode, "B") != 0) && (strcmp(mode, "DE") != 0)) { diff --git a/src/dsd_main.c b/src/dsd_main.c index 28537dd..392a954 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -1035,6 +1035,7 @@ initState (dsd_state * state) state->dmr_rest_channel = -1; //init on -1 state->dmr_mfid = -1; // state->dmr_cc_lpcn = 0; + state->tg_hold = 0; //new nxdn stuff state->nxdn_part_of_frame = 0; diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index 0145efa..9d34e28 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -3288,6 +3288,10 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) attron(COLOR_PAIR(4)); printw ("Frequency: %.06lf MHz ", (double)state->p25_vc_freq[0]/1000000); } + + //TG Hold, if specified by user + if (state->tg_hold != 0) printw ("TG HOLD: %d", state->tg_hold); + if (state->carrier == 1) attron(COLOR_PAIR(3)); else attroff(COLOR_PAIR(4)); printw ("\n"); @@ -3529,6 +3533,21 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) ncursesMenu (opts, state); //just a quick test } + //use k and l keys to test tg hold toggles on slots 1 and slots 2 + if (c == 107) //'k' key, hold tg on slot 1 for trunking purposes, or toggle clear + { + if (state->tg_hold == 0) + state->tg_hold = state->lasttg; + else state->tg_hold = 0; + } + + if (c == 108) //'k' key, hold tg on slot 2 for trunking purposes, or toggle clear + { + if (state->tg_hold == 0) + state->tg_hold = state->lasttgR; + else state->tg_hold = 0; + } + //toggling when 48k/1 OSS still has some lag -- needed to clear out the buffer when switching if (c == 49) // '1' key, toggle slot1 on {