From c1577905cd514a66bce820cfe6de489bfbd094e5 Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Sun, 10 Mar 2024 01:39:42 -0500 Subject: [PATCH] M17 - Packet Decoder WIP; --- include/dsd.h | 7 ++-- src/dsd_dibit.c | 7 +++- src/dsd_frame.c | 8 +++- src/dsd_frame_sync.c | 33 ++++++++++++++++ src/m17.c | 92 +++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 141 insertions(+), 6 deletions(-) diff --git a/include/dsd.h b/include/dsd.h index 3202422..c5b826b 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -812,7 +812,7 @@ typedef struct * Frame sync patterns */ -//The inverse of LSF also seems to be Stream Frame Type, only going to work on Stream mode for now +//M17 Sync Patterns #define M17_LSF "11113313" #define M17_STR "33331131" //alternating with last symbol opposite of first symbol of LSF @@ -820,8 +820,8 @@ typedef struct #define M17_PIV "13131313" #define M17_PRE_LSF "3131313133331131" //Preamble + LSF #define M17_PIV_LSF "1313131311113313" //Preamble + LSF -// #define M17_BRT "31331111" -// #define M17_PKT "13113333" +#define M17_BRT "31331111" +#define M17_PKT "13113333" #define FUSION_SYNC "31111311313113131131" #define INV_FUSION_SYNC "13333133131331313313" @@ -1016,6 +1016,7 @@ void processDSTAR_HD (dsd_opts * opts, dsd_state * state); //DSTAR Header void processDSTAR_SD (dsd_opts * opts, dsd_state * state, uint8_t * sd); //DSTAR Slow Data void processYSF(dsd_opts * opts, dsd_state * state); //YSF void processM17STR(dsd_opts * opts, dsd_state * state); //M17 (STR) +void processM17PKT(dsd_opts * opts, dsd_state * state); //M17 (PKT) void processM17LSF(dsd_opts * opts, dsd_state * state); //M17 (LSF) void encodeM17STR(dsd_opts * opts, dsd_state * state); //M17 (STR) encoder void encodeM17BRT(dsd_opts * opts, dsd_state * state); //M17 (BRT) encoder diff --git a/src/dsd_dibit.c b/src/dsd_dibit.c index ebb488c..5424f7a 100644 --- a/src/dsd_dibit.c +++ b/src/dsd_dibit.c @@ -267,7 +267,8 @@ int digitize (dsd_opts* opts, dsd_state* state, int symbol) else if ((state->synctype == 1) || (state->synctype == 3) || (state->synctype == 5) || (state->synctype == 9) || (state->synctype == 11) || (state->synctype == 13) || (state->synctype == 17) || (state->synctype == 29) || (state->synctype == 31) || - (state->synctype == 36) || (state->synctype == 99) ) + (state->synctype == 77) || (state->synctype == 87) ||(state->synctype == 36) || + (state->synctype == 99) ) { // 1 -P25p1 @@ -280,6 +281,8 @@ int digitize (dsd_opts* opts, dsd_state* state, int symbol) // 29 -NXDN (inverted FSW) // 31 -YSF // 36 -P25p2 + // 77 -M17 BRT + // 87 -M17 PKT // 99 -M17 Preamble int valid; @@ -349,6 +352,8 @@ int digitize (dsd_opts* opts, dsd_state* state, int symbol) // 28 +NXND (FSW) // 30 +YSF // 35 +p25p2 + // 76 +M17 BRT + // 86 +M17 PKT // 98 +M17 Preamble int valid; diff --git a/src/dsd_frame.c b/src/dsd_frame.c index 3b2a3e1..577169c 100644 --- a/src/dsd_frame.c +++ b/src/dsd_frame.c @@ -270,12 +270,18 @@ processFrame (dsd_opts * opts, dsd_state * state) return; } //M17 - else if ((state->synctype == 16) || (state->synctype == 9) || (state->synctype == 17) || (state->synctype == 8) || (state->synctype == 99) || (state->synctype == 98)) + else if ((state->synctype == 16) || (state->synctype == 9) || (state->synctype == 17) || (state->synctype == 8) || + (state->synctype == 76) || (state->synctype == 77) || (state->synctype == 86) || (state->synctype == 87) || + (state->synctype == 99) || (state->synctype == 98) ) { if (state->synctype == 98 || state->synctype == 99) //preamble only skipDibit(opts, state, 8); //skip dibits to prime the demodulator else if (state->synctype == 16 || state->synctype == 17) processM17STR(opts, state); + else if (state->synctype == 76 || state->synctype == 77) {} //Not available yet + // processM17BRT(opts, state); //Not available yet + else if (state->synctype == 86 || state->synctype == 87) + processM17PKT(opts, state); else processM17LSF(opts, state); return; diff --git a/src/dsd_frame_sync.c b/src/dsd_frame_sync.c index 2c320e2..1b4bf71 100644 --- a/src/dsd_frame_sync.c +++ b/src/dsd_frame_sync.c @@ -613,6 +613,39 @@ getFrameSync (dsd_opts * opts, dsd_state * state) return (99); } } + else if (strcmp(synctest8, M17_PKT) == 0) + { + if (opts->inverted_m17 == 0) + { + printFrameSync (opts, state, "+M17 PKT", synctest_pos + 1, modulation); + state->carrier = 1; + state->offset = synctest_pos; + state->max = ((state->max) + lmax) / 2; + state->min = ((state->min) + lmin) / 2; + if (state->lastsynctype == 86 || state->lastsynctype == 8) + { + state->lastsynctype = 86; + return (86); + } + state->lastsynctype = 86; + fprintf (stderr, "\n"); + } + // else //unknown, -BRT? + // { + // printFrameSync (opts, state, "-M17 BRT", synctest_pos + 1, modulation); + // state->carrier = 1; + // state->offset = synctest_pos; + // state->max = ((state->max) + lmax) / 2; + // state->min = ((state->min) + lmin) / 2; + // if (state->lastsynctype == 77) + // { + // state->lastsynctype = 77; + // return (77); + // } + // state->lastsynctype = 77; + // fprintf (stderr, "\n"); + // } + } else if (strcmp(synctest8, M17_STR) == 0) { if (opts->inverted_m17 == 0) diff --git a/src/m17.c b/src/m17.c index 6b6f824..93bdc6c 100644 --- a/src/m17.c +++ b/src/m17.c @@ -2541,4 +2541,94 @@ void encodeM17PKT(dsd_opts * opts, dsd_state * state) pbc++; } -} \ No newline at end of file +} + +//WIP PKT decoder +void processM17PKT(dsd_opts * opts, dsd_state * state) +{ + + int i, j, k, x; + uint8_t dbuf[184]; //384-bit (192 symbol) frame - 16-bit (8 symbol) sync pattern (184 dibits) + uint8_t m17_int_bits[368]; //368 bits that are still interleaved + uint8_t m17_rnd_bits[368]; //368 bits that are still scrambled + uint16_t m17_bits[368]; //368 bits that have been de-interleaved and de-scrambled + uint16_t m17_depunc[488]; //488 weighted byte representation of bits after depuncturing + uint8_t pkt_packed[50]; + uint8_t pkt_bytes[48]; + + uint32_t v_err = 0; //errors in viterbi decoder + UNUSED(v_err); + + memset (dbuf, 0, sizeof(dbuf)); + memset (state->m17_lsf, 0, sizeof(state->m17_lsf)); + memset (m17_int_bits, 0, sizeof(m17_int_bits)); + memset (m17_bits, 0, sizeof(m17_bits)); + memset (m17_rnd_bits, 0, sizeof(m17_rnd_bits)); + memset (m17_depunc, 0, sizeof(m17_depunc)); + + memset (pkt_packed, 0, sizeof(pkt_packed)); + memset (pkt_bytes, 0, sizeof(pkt_bytes)); + + + //load dibits into dibit buffer + for (i = 0; i < 184; i++) + dbuf[i] = getDibit(opts, state); + + //convert dbuf into a bit array + for (i = 0; i < 184; i++) + { + m17_rnd_bits[i*2+0] = (dbuf[i] >> 1) & 1; + m17_rnd_bits[i*2+1] = (dbuf[i] >> 0) & 1; + } + + //descramble the frame + for (i = 0; i < 368; i++) + m17_int_bits[i] = (m17_rnd_bits[i] ^ m17_scramble[i]) & 1; + + //deinterleave the bit array using Quadratic Permutation Polynomial + //function π(x) = (45x + 92x^2 ) mod 368 + for (i = 0; i < 368; i++) + { + x = ((45*i)+(92*i*i)) % 368; + m17_bits[i] = m17_int_bits[x]; + } + + //P3 Depuncture and Add Weights + x = 0; + for (i = 0; i < 420; i++) + { + if (p3[i%8] == 1) + m17_depunc[i] = m17_bits[x++]; + else m17_depunc[i] = 0; + + if (m17_depunc[i]) + m17_depunc[i] = 0xFFFF; + else m17_depunc[i] = 0x7FFF; + } + + + //use the libM17 Viterbi Decoder + uint16_t len = 420; + v_err = viterbi_decode(pkt_bytes, m17_depunc, len); + // v_err -= 3932040; //cost negation (double check this as well as unit, meaning, etc) + + //debug + fprintf (stderr, "\n pkt_bytes: \n"); + for (i = 0; i < 26; i++) + fprintf (stderr, " %02X", pkt_bytes[i]); + + //copy + left shift one octet + memcpy (pkt_packed, pkt_bytes+1, 25); + + //Unpack bytes into bits?? + + + //zero out after decoding + memset (state->m17_lsf, 0, sizeof(state->m17_lsf)); + + //ending linebreak + fprintf (stderr, "\n"); + + UNUSED(j); UNUSED(k); + +} //end processM17LSF \ No newline at end of file