From 6978ac9cd3661760b19aa73ec90da6cc83d1540a Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Mon, 31 Jul 2023 19:50:12 -0400 Subject: [PATCH] DSTAR Fix CRC on Slow Data Header; Cleanup; --- src/dsd_frame_sync.c | 16 ++-- src/dsd_main.c | 6 +- src/dsd_ncurses.c | 14 +-- src/dstar.c | 200 ++++++++++++++++++++++++------------------- src/dstar_header.c | 6 +- 5 files changed, 137 insertions(+), 105 deletions(-) diff --git a/src/dsd_frame_sync.c b/src/dsd_frame_sync.c index bae0b85..75cd3bc 100644 --- a/src/dsd_frame_sync.c +++ b/src/dsd_frame_sync.c @@ -1312,10 +1312,10 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; state->min = ((state->min) + lmin) / 2; - sprintf (state->ftype, "D-STAR "); + sprintf (state->ftype, "DSTAR "); if (opts->errorbars == 1) { - printFrameSync (opts, state, "+D-STAR VOICE ", synctest_pos + 1, modulation); + printFrameSync (opts, state, "+DSTAR VOICE ", synctest_pos + 1, modulation); } state->lastsynctype = 6; if ( opts->monitor_input_audio == 1) @@ -1331,10 +1331,10 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; state->min = ((state->min) + lmin) / 2; - sprintf (state->ftype, "D-STAR "); + sprintf (state->ftype, "DSTAR "); if (opts->errorbars == 1) { - printFrameSync (opts, state, "-D-STAR VOICE ", synctest_pos + 1, modulation); + printFrameSync (opts, state, "-DSTAR VOICE ", synctest_pos + 1, modulation); } state->lastsynctype = 7; if ( opts->monitor_input_audio == 1) @@ -1350,10 +1350,10 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; state->min = ((state->min) + lmin) / 2; - sprintf (state->ftype, "D-STAR_HD "); + sprintf (state->ftype, "DSTAR_HD "); if (opts->errorbars == 1) { - printFrameSync (opts, state, "+D-STAR HEADER", synctest_pos + 1, modulation); + printFrameSync (opts, state, "+DSTAR HEADER", synctest_pos + 1, modulation); } state->lastsynctype = 18; if ( opts->monitor_input_audio == 1) @@ -1369,10 +1369,10 @@ getFrameSync (dsd_opts * opts, dsd_state * state) state->offset = synctest_pos; state->max = ((state->max) + lmax) / 2; state->min = ((state->min) + lmin) / 2; - sprintf (state->ftype, " D-STAR_HD"); + sprintf (state->ftype, " DSTAR_HD"); if (opts->errorbars == 1) { - printFrameSync (opts, state, "-D-STAR HEADER", synctest_pos + 1, modulation); + printFrameSync (opts, state, "-DSTAR HEADER", synctest_pos + 1, modulation); } state->lastsynctype = 19; if ( opts->monitor_input_audio == 1) diff --git a/src/dsd_main.c b/src/dsd_main.c index 96f50f5..fe41b22 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -1240,7 +1240,7 @@ usage () printf (" -fs DMR Stereo BS and MS Simplex\n"); printf (" -f1 Decode only P25 Phase 1\n"); printf (" -f2 Decode only P25 Phase 2 (6000 sps) **\n"); - printf (" -fd Decode only D-STAR\n"); + printf (" -fd Decode only DSTAR\n"); printf (" -fx Decode only X2-TDMA\n"); printf (" -fy Decode only YSF\n"); printf (" -fz Decode only M17*\n"); @@ -1954,8 +1954,8 @@ main (int argc, char **argv) state.dmr_stereo = 0; opts.dmr_mono = 0; state.rf_mod = 0; - sprintf (opts.output_name, "D-STAR"); - fprintf (stderr,"Decoding only D-STAR frames.\n"); + sprintf (opts.output_name, "DSTAR"); + fprintf (stderr,"Decoding only DSTAR frames.\n"); } else if (optarg[0] == 'x') { diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index f5adbe1..e079ea6 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -62,8 +62,8 @@ char * SyncTypes[44] = { "X2TDMA DATA", "X2TDMA VOICE", "X2TDMA VOICE", - "DSTAR", - "DSTAR", + "DSTAR", //voice + "DSTAR", //voice "NXDN VOICE", "NXDN VOICE", "DMR", //10 @@ -74,8 +74,8 @@ char * SyncTypes[44] = { "EDACS/PV", "NXDN VOICE", //DATA "NXDN VOICE", //DATA - "DSTAR HD", - "DSTAR HD", + "DSTAR", //header + "DSTAR", //header "dPMR", //20 "dPMR", "dPMR", @@ -322,7 +322,7 @@ char *choices[] = { "Resume Decoding", "Decode AUTO", "Decode M17", - "Decode D-STAR", + "Decode DSTAR", "Decode P25p1", "Decode EDACS/PV", "Decode P25p2 ", @@ -1261,7 +1261,7 @@ void ncursesMenu (dsd_opts * opts, dsd_state * state) // resetState (state); //use sparingly, may cause memory leak state->samplesPerSymbol = 10; state->symbolCenter = 4; - sprintf (opts->output_name, "D-STAR"); + sprintf (opts->output_name, "DSTAR"); opts->dmr_mono = 0; opts->dmr_stereo = 0; //this value is the end user option state->dmr_stereo = 0; //this values toggles on and off depending on voice or data handling @@ -2443,7 +2443,7 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) printw ("\n"); printw ("| TEXT: %s", state->dstar_txt); printw ("\n"); - printw ("| XTRA: %s", state->dstar_gps); + printw ("| DATA: %s", state->dstar_gps); printw ("\n"); } diff --git a/src/dstar.c b/src/dstar.c index c61a59d..9a08924 100644 --- a/src/dstar.c +++ b/src/dstar.c @@ -1,6 +1,6 @@ #include "dsd.h" #include "dstar_const.h" -#include "dstar_header.h" +#include "fcs.h" //simplified DSTAR void processDSTAR(dsd_opts * opts, dsd_state * state) @@ -74,33 +74,23 @@ uint8_t sd_d[48] = 1,1,0,0, //C 1,0,0,1};//9 -uint16_t crc16ds(uint8_t *buf, int len) -{ - uint32_t poly = 0x1021; //1021, 0811, 8408, 8810 - uint32_t crc = 0x0; //0, of FFFF - for(int i=0; i> 7) & 1; - hd_bits[(i*8)+1] = (hd_bytes[i] >> 6) & 1; - hd_bits[(i*8)+2] = (hd_bytes[i] >> 5) & 1; - hd_bits[(i*8)+3] = (hd_bytes[i] >> 4) & 1; - hd_bits[(i*8)+4] = (hd_bytes[i] >> 3) & 1; - hd_bits[(i*8)+5] = (hd_bytes[i] >> 2) & 1; - hd_bits[(i*8)+6] = (hd_bytes[i] >> 1) & 1; - hd_bits[(i*8)+7] = (hd_bytes[i] >> 0) & 1; - } - - uint16_t crc_ext = 0; - uint16_t crc_cmp = 0; - - //todo: fix me - crc_ext = (uint16_t)ConvertBitIntoBytes(&hd_bits[312], 16); - crc_cmp = crc16ds(hd_bits, 312+16); + //works on header format -- may not work on others + uint16_t crc_ext = (hd_bytes[39] << 8) + hd_bytes[40]; + uint16_t crc_cmp = calc_fcs(hd_bytes, 39); char str1[9]; char str2[9]; @@ -177,69 +136,138 @@ void processDSTAR_SD(dsd_opts * opts, dsd_state * state, uint8_t * sd) char strt[60]; memset (strf, 0x20, sizeof(strf)); memset (strt, 0x20, sizeof(strf)); - memcpy (str1, hd_bytes+3, 8); memcpy (str2, hd_bytes+11, 8); memcpy (str3, hd_bytes+19, 8); memcpy (str4, hd_bytes+27, 12); - memcpy (strf, sd_bytes+3, 56); //copy the entire thing as a string -- full - memcpy (strt, hd_bytes+3, 46); //copy the entire thing as a string -- truncated - - str1[8] = '\0'; + str1[8] = '\0'; str2[8] = '\0'; str3[8] = '\0'; str4[12] = '\0'; + + //safety check, don't want to load nasty values into the strings + for (i = 1; i < 60; i++) + { + //substitue non-ascii characters for spaces + if (sd_bytes[i] < 0x20) + sd_bytes[i] = 0x20; + else if (sd_bytes[i] > 0x7E) + sd_bytes[i] = 0x20; + + //substitue non-ascii characters for spaces + if (hd_bytes[i] < 0x20) + hd_bytes[i] = 0x20; + else if (hd_bytes[i] > 0x7E) + hd_bytes[i] = 0x20; + + //replace terminating ffffffff (repeating 0x66 values) with NULL (0x00) + if (i < 59) + { + if (sd_bytes[i] == 0x66 && sd_bytes[i+1] == 0x66) + sd_bytes[i] = 0x00; + + if (hd_bytes[i] == 0x66 && hd_bytes[i+1] == 0x66) + hd_bytes[i] = 0x00; + } + + if (i == 59 && sd_bytes[i] == 0x66) + sd_bytes[i] = 0x00; + + if (i == 59 && hd_bytes[i] == 0x66) + hd_bytes[i] = 0x00; + + } + + memcpy (strf, sd_bytes+1, 58); //copy the entire thing as a string -- full + memcpy (strt, hd_bytes+1, 48); //copy the entire thing as a string -- truncated strf[59] = '\0'; strt[59] = '\0'; if (sd_bytes[0] == 0x55) //header format { - fprintf (stderr, " RPT 2: %s", str1); - fprintf (stderr, " RPT 1: %s", str2); - fprintf (stderr, " DST: %s", str3); - fprintf (stderr, " SRC: %s", str4); - - //check flags for info - if (sd_bytes[1] & 0x80) fprintf (stderr, " DATA"); - if (sd_bytes[1] & 0x40) fprintf (stderr, " REPEATER"); - if (sd_bytes[1] & 0x20) fprintf (stderr, " INTERRUPTED"); - if (sd_bytes[1] & 0x10) fprintf (stderr, " CONTROL SIGNAL"); - if (sd_bytes[1] & 0x08) fprintf (stderr, " URGENT"); - - if (crc_cmp == crc_ext) //crc_cmp == crc_ext + if (crc_cmp == crc_ext) { + fprintf (stderr, " RPT 2: %s", str1); + fprintf (stderr, " RPT 1: %s", str2); + fprintf (stderr, " DST: %s", str3); + fprintf (stderr, " SRC: %s", str4); + + //check flags for info + if (sd_bytes[1] & 0x80) fprintf (stderr, " DATA"); + if (sd_bytes[1] & 0x40) fprintf (stderr, " REPEATER"); + if (sd_bytes[1] & 0x20) fprintf (stderr, " INTERRUPTED"); + if (sd_bytes[1] & 0x10) fprintf (stderr, " CONTROL SIGNAL"); + if (sd_bytes[1] & 0x08) fprintf (stderr, " URGENT"); + memcpy (state->dstar_rpt2, str1, sizeof(str1)); memcpy (state->dstar_rpt1, str2, sizeof(str2)); memcpy (state->dstar_dst, str3, sizeof(str3)); memcpy (state->dstar_src, str4, sizeof(str4)); } - else fprintf (stderr, " (CRC ERR)"); + else fprintf (stderr, " SLOW DATA - HEADER FORMAT (CRC ERR)"); } - else //any other format (test, nmea gps, etc) + //I'm tired of trying to work out all the nuances here, so if its wrong, it is what it is + //I really doubt anybody who likes DSTAR uses this anyways. + else //any other format (text, nmea gps, etc) { + //I'd have to rewrite the upper loading portion for a consistent good crc when the header + //indicator bytes have different len values, so these will most likely always fail a crc, + //but I am going to leave them active since I have the 'safety' check in place to prevent + //rouge non-ascii values doing odd things in the terminal and in ncurses - fprintf (stderr, " %s", strf); - if (crc_cmp == crc_ext) //crc_cmp == crc_ext + //sure would be a lot easier if there was seperate and uniform opcodes for all the data types, + //instead of having to over analyze everyhign to figure out what is text, and GPS, and APRS + if (1 == 1) //crc_cmp == crc_ext { - if (sd_bytes[0] == 0x40) //fixed-form text (5 bytes each piece) - memcpy (state->dstar_txt, strf, sizeof(strf)); - else memcpy (state->dstar_gps, strt, sizeof(strt)); + //fixed-form at 5 bytes, use the truncated (Some Interleaved APRS/GPS TEXT combos may display incorrectly) + if (sd_bytes[0] == 0x35) + { + fprintf (stderr, " DATA:"); + fprintf (stderr, " %s", strt); + memcpy (state->dstar_gps, strt, sizeof(strt)); + } + //free-form text at 5 bytes, use the truncated + else if (sd_bytes[0] == 0x40) + { + fprintf (stderr, " TEXT:"); + fprintf (stderr, " %s", strt); + memcpy (state->dstar_txt, strt, sizeof(strt)); + } + //any other 5 byte block value + else if (sd_bytes[0] & 0x05) + { + fprintf (stderr, " _UNK:"); + fprintf (stderr, " %s", strt); + memcpy (state->dstar_txt, strt, sizeof(strt)); + } + //coded squelch data + else if (sd_bytes[0] == 0xC2) + { + fprintf (stderr, " SQL: %02X (%03d)", payload[1], payload[1]); + sprintf (state->dstar_gps, " SQL: %02X (%03d) ", payload[1], payload[1]); + } + //any variable len block values + else //print entire thing + { + fprintf (stderr, " _UNK:"); + fprintf (stderr, " %s", strf); + memcpy (state->dstar_gps, strf, sizeof(strf)); + } } - else fprintf (stderr, " (CRC ERR)"); + // if (crc_cmp != crc_ext) fprintf (stderr, " (CRC ERR)"); } - if (opts->payload == 1) { fprintf (stderr, "\n SD: "); - for (i = 0; i < 60; i++) - fprintf (stderr, "%02X ", sd_bytes[i]); - fprintf (stderr, "\n SD: "); - for (i = 0; i < 50; i++) - fprintf (stderr, "%02X ", hd_bytes[i]); + for (i = 0; i < 60; i++) + { + fprintf (stderr, "[%02X]", payload[i]); + if (i == 29) fprintf (stderr, "\n "); + } if (crc_cmp != crc_ext) fprintf (stderr, "CRC - EXT: %04X CMP: %04X", crc_ext, crc_cmp); diff --git a/src/dstar_header.c b/src/dstar_header.c index b3b12bf..35a9d3e 100644 --- a/src/dstar_header.c +++ b/src/dstar_header.c @@ -16,10 +16,10 @@ * */ -#include "fcs.h" #include "descramble.h" #include "dstar_header.h" #include "dsd.h" +// #include "fcs.h" //error: multiple definition of `calc_fcs'; CMakeFiles/dsd-fme.dir/src/dstar.c.o:dstar.c:(.text+0x0): first defined here void dstar_header_decode(dsd_state * state, int radioheaderbuffer[660]) { @@ -65,6 +65,10 @@ void dstar_header_decode(dsd_state * state, int radioheaderbuffer[660]) str3[8] = '\0'; str4[12] = '\0'; + //TODO: Add fcs_calc to header as well + // uint16_t crc_ext = (radioheader[39] << 8) + radioheader[40]; + // uint16_t crc_cmp = calc_fcs(radioheader, 39); + //debug // fprintf (stderr, "\n HD: "); // for (int i = 0; i < 40; i++)