NXDN: Rework code for the FACCH1 duplicate message check post NXDN Viterbi overhaul;

Use static array to hold facch1 message after recovery and compare when LICH type calls for 2 individual FACCH1 messages in an NXDN frame;

Zero out facch1_storage on SACCH or SCCH decode (happens first) and after potential comparison time in FACCH1 decode;
This commit is contained in:
lwvmobile
2026-02-03 02:57:02 -05:00
parent d7ce5e4cae
commit 53a256bee8
3 changed files with 37 additions and 6 deletions

View File

@@ -1272,7 +1272,7 @@ void nxdn_voice (dsd_opts * opts, dsd_state * state, int voice, uint8_t * dbuf);
//All-in-One NXDN Soft Decision Viterbi Function based on libM17
uint32_t nxdn_soft_decision_viterbi(uint8_t * bits, const uint16_t * interleave, uint8_t * puncture, int d_len, int p_len, int num_bytes, int offset, uint8_t * viterbi_bits, uint8_t * viterbi_bytes);
//NXDN Conventional and Type-C
void nxdn_facch1(dsd_opts * opts, dsd_state * state, uint8_t * bits);
void nxdn_facch1(dsd_opts * opts, dsd_state * state, uint8_t * bits, uint8_t frame);
void nxdn_sacch(dsd_opts * opts, dsd_state * state, uint8_t * bits);
void nxdn_cac(dsd_opts * opts, dsd_state * state, uint8_t * bits);
void nxdn_facch2_udch(dsd_opts * opts, dsd_state * state, uint8_t * bits, uint8_t type);

View File

@@ -339,10 +339,16 @@ uint8_t facch1_puncture[4] = {1,0,1,1};
uint8_t facch2_puncture[14] = {1,1,1,0,1,1,1,1,1,1,1,0,1,1};
uint8_t cac_puncture[14] = {1,1,1,0,1,1,1,1,1,1,1,0,1,1};
//facch1 storage, for duplicate message check
static uint8_t facch1_storage[12] = {0};
//sacch soft decision making
void nxdn_sacch(dsd_opts * opts, dsd_state * state, uint8_t * bits)
{
//erase facch1 storage (facch1 only happens along with a sacch/scch frame)
memset(facch1_storage, 0, sizeof(facch1_storage));
uint8_t crc = 1; //value computed by crc6 on payload
uint8_t check = 0; //value pulled from last 6 bits
int sf = 0;
@@ -575,7 +581,7 @@ void nxdn_sacch(dsd_opts * opts, dsd_state * state, uint8_t * bits)
}
void nxdn_facch1(dsd_opts * opts, dsd_state * state, uint8_t * bits)
void nxdn_facch1(dsd_opts * opts, dsd_state * state, uint8_t * bits, uint8_t frame)
{
uint16_t crc = 0;
@@ -606,8 +612,22 @@ void nxdn_facch1(dsd_opts * opts, dsd_state * state, uint8_t * bits)
check = check | viterbi_bits[80+i];
}
//duplicate frame check if frame == 2
uint8_t duplicate = 0;
if (frame == 2)
{
if (memcmp(facch1_storage, viterbi_bytes, 12) == 0)
duplicate = 1;
}
if (crc == check) NXDN_Elements_Content_decode(opts, state, 1, viterbi_bits);
//erase facch1 storage
memset(facch1_storage, 0, sizeof(facch1_storage));
//store facch1 message viterbi bytes if frame == 1
if (frame == 1)
memcpy(facch1_storage, viterbi_bytes, sizeof(facch1_storage));
if (crc == check && duplicate == 0) NXDN_Elements_Content_decode(opts, state, 1, viterbi_bits);
// else if (opts->aggressive_framesync == 0) NXDN_Elements_Content_decode(opts, state, 0, viterbi_bits);
if (opts->payload == 1)
@@ -750,6 +770,9 @@ void nxdn_cac(dsd_opts * opts, dsd_state * state, uint8_t * bits)
void idas_scch(dsd_opts * opts, dsd_state * state, uint8_t * bits, uint8_t direction)
{
//erase facch1 storage (facch1 only happens along with a sacch/scch frame)
memset(facch1_storage, 0, sizeof(facch1_storage));
fprintf (stderr, "%s", KYEL);
fprintf (stderr, " SCCH");

View File

@@ -556,9 +556,17 @@ void nxdn_frame (dsd_opts * opts, dsd_state * state)
if (sacch) nxdn_sacch(opts, state, sacch_bits);
if (cac) nxdn_cac(opts, state, cac_bits);
//TODO: Redo duplicate facch check inside decoder? storage for facch message?
if (facch & 1) nxdn_facch1(opts, state, facch_bits_a);
if (facch & 2) nxdn_facch1(opts, state, facch_bits_b);
//Duplicate facch check inside decoder. store and compare for facch message, depending on passed frame value
if (facch == 3)
{
if (facch & 1) nxdn_facch1(opts, state, facch_bits_a, 1);
if (facch & 2) nxdn_facch1(opts, state, facch_bits_b, 2);
}
else //facch1 steals, or single facch only messages
{
if (facch & 1) nxdn_facch1(opts, state, facch_bits_a, 0);
if (facch & 2) nxdn_facch1(opts, state, facch_bits_b, 0);
}
//Seperated UDCH user data from facch2 data
if (udch) nxdn_facch2_udch(opts, state, facch2_bits, 0);