From c4010352099387227637c0e9b8225edb9e107378 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Wed, 14 Feb 2024 18:03:07 -0500 Subject: [PATCH] NXDN - Rolling CAC CRC fix (reset demodulator state); Scrambler SEED Fix Each PF; --- src/nxdn_deperm.c | 89 ++++++++++++++++++++++++++++++++++++++++++++-- src/nxdn_element.c | 10 +++--- 2 files changed, 92 insertions(+), 7 deletions(-) diff --git a/src/nxdn_deperm.c b/src/nxdn_deperm.c index 0437e1b..a2cb97c 100644 --- a/src/nxdn_deperm.c +++ b/src/nxdn_deperm.c @@ -280,6 +280,8 @@ void nxdn_deperm_sacch(dsd_opts * opts, dsd_state * state, uint8_t bits[60]) } fprintf (stderr, "PF 1/1"); + if (state->nxdn_cipher_type == 1 && state->R != 0) state->payload_miN = state->R; //reset scrambler seed + else if (state->M == 1 && state->R != 0) state->payload_miN = state->R; //force reset scrambler seed if (crc == check) NXDN_Elements_Content_decode(opts, state, 1, nsf_sacch); // else if (opts->aggressive_framesync == 0) NXDN_Elements_Content_decode(opts, state, 0, nsf_sacch); @@ -331,6 +333,11 @@ void nxdn_deperm_sacch(dsd_opts * opts, dsd_state * state, uint8_t bits[60]) fprintf (stderr, "%s", KNRM); fprintf (stderr, "PF %d/4", part_of_frame+1); + if (part_of_frame == 0) + { + if (state->nxdn_cipher_type == 1 && state->R != 0) state->payload_miN = state->R; //reset scrambler seed + else if (state->M == 1 && state->R != 0) state->payload_miN = state->R; //force reset scrambler seed + } // if (crc != check) // { @@ -340,7 +347,33 @@ void nxdn_deperm_sacch(dsd_opts * opts, dsd_state * state, uint8_t bits[60]) // } //reset scrambler seed to key value on new superframe - if (part_of_frame == 0 && state->nxdn_cipher_type == 0x1) state->payload_miN = 0; + // if (part_of_frame == 0 && state->nxdn_cipher_type == 0x1) state->payload_miN = 0; + + //reset scrambler seed to key value on new superframe + if (part_of_frame == 0 && state->nxdn_cipher_type == 0x1) + { + if (state->nxdn_cipher_type == 1 && state->R != 0) state->payload_miN = state->R; //reset scrambler seed + else if (state->M == 1 && state->R != 0) state->payload_miN = state->R; //force reset scrambler seed + } + //this seems to work much better now + else if (part_of_frame != 0 && state->nxdn_cipher_type == 0x1) + { + if (state->nxdn_cipher_type == 1 && state->R != 0) state->payload_miN = state->R; //reset scrambler seed + else if (state->M == 1 && state->R != 0) state->payload_miN = state->R; //force reset scrambler seed + + //advance seed by required number of turns depending on the current pf value + int start = 0; int end = part_of_frame; + char ambe_temp[49] = {0}; + char ambe_d[49] = {0}; + for (start = 0; start < end; start++) + { + //run 4 times + LFSRN(ambe_temp, ambe_d, state); + LFSRN(ambe_temp, ambe_d, state); + LFSRN(ambe_temp, ambe_d, state); + LFSRN(ambe_temp, ambe_d, state); + } + } if (crc == check) { @@ -568,7 +601,7 @@ void nxdn_deperm_facch2_udch(dsd_opts * opts, dsd_state * state, uint8_t bits[34 } } - +static int cac_fail = 0; void nxdn_deperm_cac(dsd_opts * opts, dsd_state * state, uint8_t bits[300]) { uint8_t deperm[300]; //300 @@ -684,6 +717,49 @@ void nxdn_deperm_cac(dsd_opts * opts, dsd_state * state, uint8_t bits[300]) fprintf (stderr, "%s", KNRM); } + //check for accumulative cac failures and reset if multiple errors pile up + //(LZ issue and also issue very occasssionally noticed on remote) + if (crc != 0) cac_fail++; + else cac_fail = 0; + + //reset some parameters if CAC continues to fail + if (cac_fail >= 5) + { + //simple reset + state->synctype = 0; + state->lastsynctype = -1; + state->carrier = 0; + state->last_cc_sync_time = time(NULL)+2; //probably not necesary + cac_fail = 0; //reset + + //more advanced modulator reset + state->center = 0; + state->jitter = -1; + state->synctype = -1; + state->min = -15000; + state->max = 15000; + state->lmid = 0; + state->umid = 0; + state->minref = -12000; + state->maxref = 12000; + state->lastsample = 0; + for (int i = 0; i < 128; i++) state->sbuf[i] = 0; + state->sidx = 0; + for (int i = 0; i < 1024; i++) state->maxbuf[i] = 15000; + for (int i = 0; i < 1024; i++) state->minbuf[i] = -15000; + state->midx = 0; + state->symbolcnt = 0; + + //reset the dibit buffer + state->dibit_buf_p = state->dibit_buf + 200; + memset (state->dibit_buf, 0, sizeof (int) * 200); + state->offset = 0; + + //debug notification + // fprintf (stderr, " RESET CARRIER; "); + + } + if (crc == 0) NXDN_Elements_Content_decode(opts, state, 1, cac_message_buffer); // else if (opts->aggressive_framesync == 0) NXDN_Elements_Content_decode(opts, state, 0, cac_message_buffer); @@ -816,7 +892,14 @@ void nxdn_deperm_scch(dsd_opts * opts, dsd_state * state, uint8_t bits[60], uint else part_of_frame = 0; //reset scrambler seed to key value on new superframe - if (part_of_frame == 0 && state->nxdn_cipher_type == 0x1) state->payload_miN = 0; + // if (part_of_frame == 0 && state->nxdn_cipher_type == 0x1) state->payload_miN = 0; + + //reset scrambler seed to key value on new superframe + if (part_of_frame == 0 && state->nxdn_cipher_type == 0x1) + { + if (state->nxdn_cipher_type == 1 && state->R != 0) state->payload_miN = state->R; //reset scrambler seed + else if (state->M == 1 && state->R != 0) state->payload_miN = state->R; //force reset scrambler seed + } /* 4.3.2. Mapping to Functional Channel diff --git a/src/nxdn_element.c b/src/nxdn_element.c index d84be2e..9d6112e 100644 --- a/src/nxdn_element.c +++ b/src/nxdn_element.c @@ -150,9 +150,9 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state, NXDN_decode_VCALL(opts, state, ElementsContent); memset (state->nxdn_alias_block_segment, 0, sizeof(state->nxdn_alias_block_segment)); - #ifdef LIMAZULUTWEAKS - ; //do nothing -- testing errors on CAC messages when returning quickly from RTCH - #else + // #ifdef LIMAZULUTWEAKS + // ; //do nothing -- testing errors on CAC messages when returning quickly from RTCH + // #else //tune back to CC here - save about 1-2 seconds if (opts->p25_trunk == 1 && state->p25_cc_freq != 0 && opts->p25_is_tuned == 1) @@ -197,7 +197,7 @@ void NXDN_Elements_Content_decode(dsd_opts * opts, dsd_state * state, state->last_cc_sync_time = time(NULL); //allow tuners a second to catch up, particularly rtl input } - #endif + // #endif break; //Idle @@ -654,6 +654,7 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa state->R = state->rkey_array[DestinationID]; fprintf (stderr, " %s", KYEL); fprintf (stderr, " Key Loaded: %lld", state->rkey_array[DestinationID]); + state->payload_miN = state->R; //should be okay to load here, will test } if (state->M == 1) state->nxdn_cipher_type = 0x1; } @@ -687,6 +688,7 @@ void NXDN_decode_VCALL_ASSGN(dsd_opts * opts, dsd_state * state, uint8_t * Messa state->R = state->rkey_array[DestinationID]; fprintf (stderr, " %s", KYEL); fprintf (stderr, " Key Loaded: %lld", state->rkey_array[DestinationID]); + state->payload_miN = state->R; //should be okay to load here, will test } if (state->M == 1) state->nxdn_cipher_type = 0x1; #endif