From 23b1036c6b67f627bc727e4945dbcda09a9ef8ba Mon Sep 17 00:00:00 2001 From: lwvmobile Date: Sat, 29 Jul 2023 21:46:11 -0400 Subject: [PATCH] Rewrite and Simplify DSTAR Handling; --- include/dsd.h | 9 +- src/dsd_frame.c | 58 ++++--------- src/dsd_frame_sync.c | 8 +- src/dsd_main.c | 14 ++- src/dsd_ncurses.c | 71 ++++++---------- src/dstar.c | 197 +++++++++---------------------------------- src/dstar_header.c | 88 +++++++++---------- 7 files changed, 147 insertions(+), 298 deletions(-) diff --git a/include/dsd.h b/include/dsd.h index 25d79bf..2f86535 100644 --- a/include/dsd.h +++ b/include/dsd.h @@ -672,9 +672,6 @@ typedef struct int symbol_throttle; //throttle speed int use_throttle; //only use throttle if set to 1 - //dstar header for ncurses - unsigned char dstarradioheader[41]; - //dmr trunking stuff int dmr_rest_channel; int dmr_mfid; //just when 'fid' is used as a manufacturer ID and not a feature set id @@ -756,6 +753,12 @@ typedef struct char ysf_rm4[6]; char ysf_txt[21][21]; //text storage blocks + //DSTAR Call Strings and Info + char dstar_rpt1[9]; + char dstar_rpt2[9]; + char dstar_dst[9]; + char dstar_src[13]; + //M17 Storage uint8_t m17_lsf[360]; uint8_t m17_str_dt; //stream contents diff --git a/src/dsd_frame.c b/src/dsd_frame.c index 9aafc2c..01827c4 100644 --- a/src/dsd_frame.c +++ b/src/dsd_frame.c @@ -93,50 +93,24 @@ processFrame (dsd_opts * opts, dsd_state * state) nxdn_frame (opts, state); return; } + + //DSTAR else if ((state->synctype == 6) || (state->synctype == 7)) - { - state->nac = 0; - state->lastsrc = 0; - state->lasttg = 0; - if (opts->errorbars == 1) - { - if (opts->verbose > 0) - { - level = (int) state->max / 164; - //fprintf (stderr,"inlvl: %2i%% ", level); - } - } - state->nac = 0; - if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) - { - openMbeOutFile (opts, state); //dstar ambe files are read back incorrectly, need to change file extension to differentiate when doing a playback - } - sprintf (state->fsubtype, " VOICE "); - processDSTAR (opts, state); - return; - } + { + if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) + openMbeOutFile (opts, state); + sprintf (state->fsubtype, " VOICE "); + processDSTAR (opts, state); + return; + } else if ((state->synctype == 18) || (state->synctype == 19)) - { - state->nac = 0; - state->lastsrc = 0; - state->lasttg = 0; - if (opts->errorbars == 1) - { - if (opts->verbose > 0) - { - level = (int) state->max / 164; - //fprintf (stderr,"inlvl: %2i%% ", level); - } - } - state->nac = 0; - if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) - { - openMbeOutFile (opts, state); //dstar ambe files are read back incorrectly, need to change file extension to differentiate when doing a playback - } - sprintf (state->fsubtype, " DATA "); - processDSTAR_HD (opts, state); - return; - } + { + if ((opts->mbe_out_dir[0] != 0) && (opts->mbe_out_f == NULL)) + openMbeOutFile (opts, state); + sprintf (state->fsubtype, " DATA "); + processDSTAR_HD (opts, state); + return; + } //Start DMR Types else if ((state->synctype >= 10) && (state->synctype <= 13) || (state->synctype == 32) || (state->synctype == 33) || (state->synctype == 34) ) //32-34 DMR MS and RC { diff --git a/src/dsd_frame_sync.c b/src/dsd_frame_sync.c index 1d76752..07c6fcc 100644 --- a/src/dsd_frame_sync.c +++ b/src/dsd_frame_sync.c @@ -1315,7 +1315,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) sprintf (state->ftype, "D-STAR "); if (opts->errorbars == 1) { - printFrameSync (opts, state, "+D-STAR ", synctest_pos + 1, modulation); + printFrameSync (opts, state, "+D-STAR VOICE", synctest_pos + 1, modulation); } state->lastsynctype = 6; if ( opts->monitor_input_audio == 1) @@ -1334,7 +1334,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) sprintf (state->ftype, "D-STAR "); if (opts->errorbars == 1) { - printFrameSync (opts, state, "-D-STAR ", synctest_pos + 1, modulation); + printFrameSync (opts, state, "-D-STAR VOICE", synctest_pos + 1, modulation); } state->lastsynctype = 7; if ( opts->monitor_input_audio == 1) @@ -1353,7 +1353,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) sprintf (state->ftype, "D-STAR_HD "); if (opts->errorbars == 1) { - printFrameSync (opts, state, "+D-STAR_HD ", synctest_pos + 1, modulation); + printFrameSync (opts, state, "+D-STAR HEADER ", synctest_pos + 1, modulation); } state->lastsynctype = 18; if ( opts->monitor_input_audio == 1) @@ -1372,7 +1372,7 @@ getFrameSync (dsd_opts * opts, dsd_state * state) sprintf (state->ftype, " D-STAR_HD"); if (opts->errorbars == 1) { - printFrameSync (opts, state, "-D-STAR_HD ", synctest_pos + 1, modulation); + printFrameSync (opts, state, "-D-STAR 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 f481c25..c35dc75 100644 --- a/src/dsd_main.c +++ b/src/dsd_main.c @@ -470,6 +470,12 @@ if(opts->frame_m17 == 1) //&& opts->audio_in_type == 5 state->ysf_fi = 9; state->ysf_cm = 9; + //DSTAR Call Strings + sprintf (state->dstar_rpt1, "%s", " "); //8 spaces + sprintf (state->dstar_rpt2, "%s", " "); //8 spaces + sprintf (state->dstar_dst, "%s", " "); //8 spaces + sprintf (state->dstar_src, "%s", " "); //8 spaces + //M17 Storage memset (state->m17_lsf, 1, sizeof(state->m17_lsf)); state->m17_str_dt = 9; @@ -941,8 +947,6 @@ initState (dsd_state * state) state->payload_miP = 0; - memset(state->dstarradioheader, 0, 41); - //initialize dmr data header source state->dmr_lrrp_source[0] = 0; state->dmr_lrrp_source[1] = 0; @@ -1116,6 +1120,12 @@ initState (dsd_state * state) state->ysf_fi = 9; state->ysf_cm = 9; + //DSTAR Call Strings + sprintf (state->dstar_rpt1, "%s", " "); //8 spaces + sprintf (state->dstar_rpt2, "%s", " "); //8 spaces + sprintf (state->dstar_dst, "%s", " "); //8 spaces + sprintf (state->dstar_src, "%s", " "); //8 spaces + //M17 Storage memset (state->m17_lsf, 1, sizeof(state->m17_lsf)); state->m17_str_dt = 9; diff --git a/src/dsd_ncurses.c b/src/dsd_ncurses.c index bed66a8..fbfa77e 100644 --- a/src/dsd_ncurses.c +++ b/src/dsd_ncurses.c @@ -1936,27 +1936,27 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) } - //D-STAR, work on adding the headers later - if ( (lls == 6 || lls == 7 || lls == 18 || lls == 19) && (time(NULL) - call_matrix[9][5] > 5) && state->carrier == 1) - { - for (short int k = 0; k < 9; k++) - { - call_matrix[k][0] = call_matrix[k+1][0]; - call_matrix[k][1] = call_matrix[k+1][1]; - call_matrix[k][2] = call_matrix[k+1][2]; - call_matrix[k][3] = call_matrix[k+1][3]; - call_matrix[k][4] = call_matrix[k+1][4]; - call_matrix[k][5] = call_matrix[k+1][5]; - } + //DSTAR + // if ( (lls == 6 || lls == 7 || lls == 18 || lls == 19) && (time(NULL) - call_matrix[9][5] > 5) && state->carrier == 1) + // { + // for (short int k = 0; k < 9; k++) + // { + // call_matrix[k][0] = call_matrix[k+1][0]; + // call_matrix[k][1] = call_matrix[k+1][1]; + // call_matrix[k][2] = call_matrix[k+1][2]; + // call_matrix[k][3] = call_matrix[k+1][3]; + // call_matrix[k][4] = call_matrix[k+1][4]; + // call_matrix[k][5] = call_matrix[k+1][5]; + // } - call_matrix[9][0] = lls; - call_matrix[9][1] = 1; - call_matrix[9][2] = 1; - call_matrix[9][3] = 1; - call_matrix[9][4] = 1; - call_matrix[9][5] = time(NULL); + // call_matrix[9][0] = lls; + // call_matrix[9][1] = 1; + // call_matrix[9][2] = 1; + // call_matrix[9][3] = 1; + // call_matrix[9][4] = 1; + // call_matrix[9][5] = time(NULL); - } + // } //NXDN -- I really need to fix this better, but this is good enough for today if ( call_matrix[9][2] != src && src != 0 && rn != -1 ) @@ -2430,25 +2430,17 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) printw ("------------------------------------------------------------------------------\n"); printw ("--Call Info-------------------------------------------------------------------\n"); - //DSTAR...what a pain... + //DSTAR if (lls == 6 || lls == 7 || lls == 18 || lls == 19) { - if (state->dstarradioheader[3] != 0) // - { - printw ("| RPT 2: [%c%c%c%c%c%c%c%c] ", state->dstarradioheader[3], state->dstarradioheader[4], - state->dstarradioheader[5], state->dstarradioheader[6], state->dstarradioheader[7], state->dstarradioheader[8], - state->dstarradioheader[9], state->dstarradioheader[10]); - printw ("RPT 1: [%c%c%c%c%c%c%c%c] \n| ", state->dstarradioheader[11], state->dstarradioheader[12], - state->dstarradioheader[13], state->dstarradioheader[14], state->dstarradioheader[15], state->dstarradioheader[16], - state->dstarradioheader[17], state->dstarradioheader[18]); - printw ("YOUR: [%c%c%c%c%c%c%c%c] ", state->dstarradioheader[19], state->dstarradioheader[20], - state->dstarradioheader[21], state->dstarradioheader[22], state->dstarradioheader[23], state->dstarradioheader[24], - state->dstarradioheader[25], state->dstarradioheader[26]); - printw ("MY: [%c%c%c%c%c%c%c%c] [%c%c%c%c]\n", state->dstarradioheader[27], - state->dstarradioheader[28], state->dstarradioheader[29], state->dstarradioheader[30], state->dstarradioheader[31], - state->dstarradioheader[32], state->dstarradioheader[33], state->dstarradioheader[34], state->dstarradioheader[35], - state->dstarradioheader[36], state->dstarradioheader[37], state->dstarradioheader[38]); - } + printw ("| %s ", SyncTypes[lls]); + printw ("\n"); + printw ("| RPT2: %s", state->dstar_rpt2); + printw (" RPT1: %s", state->dstar_rpt1); + printw ("\n"); + printw ("| DEST: %s", state->dstar_dst); + printw (" SRC: %s", state->dstar_src); + printw ("\n"); } //M17 @@ -3328,13 +3320,6 @@ ncursesPrinter (dsd_opts * opts, dsd_state * state) } } - - if (lls == 6 || lls == 7 || lls == 18 || lls == 19) - { - printw ("| %s ", SyncTypes[lls]); - //printw ("%s", state->dmr_branding); - printw ("\n"); - } //fence bottom printw ("------------------------------------------------------------------------------\n"); //colors off diff --git a/src/dstar.c b/src/dstar.c index dfc3875..bc98965 100644 --- a/src/dstar.c +++ b/src/dstar.c @@ -1,181 +1,62 @@ -/* - * Copyright (C) 2010 DSD Author - * GPG Key ID: 0x3F1D7FD0 (74EF 430D F7F2 0A48 FCE6 F630 FAA2 635D 3F1D 7FD0) - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Note: D-STAR support is fairly complete at this point. - * The ambe3600x2450 decoder is similar butnot compatible with D-STAR voice frames. - * The dstar interleave pattern is different as well. - * GMSK modulation optimizations will also required to get a usable bit error - */ - #include "dsd.h" #include "dstar_const.h" #include "dstar_header.h" - -void processDSTAR(dsd_opts * opts, dsd_state * state) { - // extracts AMBE frames from D-STAR voice frame - int i, dibit; +//simplified DSTAR +void processDSTAR(dsd_opts * opts, dsd_state * state) +{ + uint8_t sd[480]; + memset (sd, 0, sizeof(sd)); + int i, j, dibit; char ambe_fr[4][24]; - int framecount; - int sync_missed = 0; - unsigned char slowdata[4]; - unsigned int bitbuffer = 0; const int *w, *x; + memset(ambe_fr, 0, sizeof(ambe_fr)); + w = dW; + x = dX; - //set carrier to 1 so ncurses will light up green - state->carrier = 1; + //20 voice and 19 slow data frames (20th is frame sync) + for (j = 0; j < 21; j++) + { - if (opts->errorbars == 1) { - fprintf (stderr, "e:"); - } + memset(ambe_fr, 0, sizeof(ambe_fr)); + w = dW; + x = dX; -#ifdef DSTAR_DUMP - fprintf (stderr, "\n"); -#endif + for (i = 0; i < 72; i++) + { + dibit = getDibit(opts, state); + ambe_fr[*w][*x] = dibit & 1; + w++; + x++; + } - if (state->synctype == 18) { - framecount = 0; - state->synctype = 6; - } else if (state->synctype == 19) { - framecount = 0; - state->synctype = 7; - } else { - framecount = 1; //just saw a sync frame; there should be 20 not 21 till the next - } - //why is this running in a loop for? - while (sync_missed < 3) { + soft_mbe(opts, state, NULL, ambe_fr, NULL); - memset(ambe_fr, 0, 96); - // voice frame - w = dW; - x = dX; + if (j != 20) + { + for (i = 0; i < 24; i++) + { + //slow data + sd[(j*24)+i] = getDibit(opts, state); + } + } - for (i = 0; i < 72; i++) { + } - dibit = getDibit(opts, state); - - bitbuffer <<= 1; - if (dibit == 1) { - bitbuffer |= 0x01; - } - if ((bitbuffer & 0x00FFFFFF) == 0x00AAB468) { - // we're slipping bits - fprintf (stderr, "sync in voice after i=%d, restarting\n", i); - //ugh just start over - i = 0; - w = dW; - x = dX; - framecount = 1; - continue; - } - - ambe_fr[*w][*x] = (1 & dibit); - w++; - x++; - - } + fprintf (stderr, "\n"); - processMbeFrame(opts, state, NULL, ambe_fr, NULL); - - // data frame - 24 bits - for (i = 73; i < 97; i++) { - dibit = getDibit(opts, state); - bitbuffer <<= 1; - if (dibit == 1) { - bitbuffer |= 0x01; - } - if ((bitbuffer & 0x00FFFFFF) == 0x00AAB468) { - // looking if we're slipping bits - if (i != 96) { - fprintf (stderr, "sync after i=%d\n", i); - i = 96; - } - } - } - - slowdata[0] = (bitbuffer >> 16) & 0x000000FF; - slowdata[1] = (bitbuffer >> 8) & 0x000000FF; - slowdata[2] = (bitbuffer) & 0x000000FF; - slowdata[3] = 0; - - if ((bitbuffer & 0x00FFFFFF) == 0x00AAB468) { - //We got sync! - //fprintf (stderr, "Sync on framecount = %d\n", framecount); - sync_missed = 0; - } else if ((bitbuffer & 0x00FFFFFF) == 0xAAAAAA) { - //End of transmission - fprintf (stderr, "End of transmission\n"); - goto end; - } else if (framecount % 21 == 0) { - fprintf (stderr, "Missed sync on framecount = %d, value = %x/%x/%x\n", - framecount, slowdata[0], slowdata[1], slowdata[2]); - sync_missed++; - } else if (framecount != 0 && (bitbuffer & 0x00FFFFFF) != 0x000000) { - slowdata[0] ^= 0x70; - slowdata[1] ^= 0x4f; - slowdata[2] ^= 0x93; - //fprintf (stderr, "unscrambled- %02X %02X %02X %02X \n", slowdata[0], slowdata[1], slowdata[2], slowdata[3] ); - - } else if (framecount == 0) { - //fprintf (stderr, "never scrambled-%c\n",slowdata); - //fprintf (stderr, "never scrambled- %02X %02X %02X %02X \n", slowdata[0], slowdata[1], slowdata[2], slowdata[3] ); - - } - for (short int i = 0; i < 4; i++) - { - if (slowdata[i] <= 0x7E && slowdata[i] >=0x20) - { - //fprintf (stderr, "%c", slowdata[i]); - } - //else fprintf (stderr, "."); - } - //fprintf (stderr, "\n"); - framecount++; - - //since we are in a while loop, run ncursesPrinter here. - if (opts->use_ncurses_terminal == 1) - { - ncursesPrinter(opts, state); - } - - } //end while loop - - end: if (opts->errorbars == 1) { - fprintf (stderr, "\n"); - } } void processDSTAR_HD(dsd_opts * opts, dsd_state * state) { - int j; - int radioheaderbuffer[660]; + int i; + int radioheaderbuffer[660]; - for (j = 0; j < 660; j++) { - radioheaderbuffer[j] = getDibit(opts, state); - } + for (i = 0; i < 660; i++) + radioheaderbuffer[i] = getDibit(opts, state); - // Note: These routines contain GPLed code. Remove if you object to that. - // Due to this, they are in a separate source file. - dstar_header_decode(state, radioheaderbuffer); - - //We officially have sync now, so just pass on to the above routine: - - processDSTAR(opts, state); + dstar_header_decode(state, radioheaderbuffer); + processDSTAR(opts, state); } diff --git a/src/dstar_header.c b/src/dstar_header.c index 03295c4..2d4dc7e 100644 --- a/src/dstar_header.c +++ b/src/dstar_header.c @@ -1,8 +1,8 @@ /* - * - * This code is taken largely from on1arf's GMSK code. Original copyright below: - * - * +* +* This code is taken largely from on1arf's GMSK code. Original copyright below: +* +* * Copyright (C) 2011 by Kristoff Bonne, ON1ARF * * This program is free software; you can redistribute it and/or modify @@ -13,74 +13,70 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - */ +* +*/ #include "fcs.h" #include "descramble.h" #include "dstar_header.h" #include "dsd.h" -void dstar_header_decode(dsd_state * state, int radioheaderbuffer[660]) { +void dstar_header_decode(dsd_state * state, int radioheaderbuffer[660]) +{ int radioheaderbuffer2[660]; - unsigned char radioheader[41]; + char radioheader[41]; int octetcount, bitcount, loop; unsigned char bit2octet[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; - int len; - UNUSED(len); scramble(radioheaderbuffer, radioheaderbuffer2); deinterleave(radioheaderbuffer2, radioheaderbuffer); - len = FECdecoder(radioheaderbuffer, radioheaderbuffer2); + FECdecoder(radioheaderbuffer, radioheaderbuffer2); memset(radioheader, 0, 41); - //memset(state->dstarradioheader, 0, 41); + // note we receive 330 bits, but we only use 328 of them (41 octets) // bits 329 and 330 are unused octetcount = 0; bitcount = 0; - for (loop = 0; loop < 328; loop++) { - if (radioheaderbuffer2[loop]) { + for (loop = 0; loop < 328; loop++) + { + if (radioheaderbuffer2[loop]) radioheader[octetcount] |= bit2octet[bitcount]; - }; bitcount++; // increase octetcounter and reset bitcounter every 8 bits - if (bitcount >= 8) { + if (bitcount >= 8) + { octetcount++; bitcount = 0; } } - //state->dstarradioheader = radioheader; - for (short i = 0; i < 41; i++) - { - state->dstarradioheader[i] = radioheader[i]; - } + char str1[9]; + char str2[9]; + char str3[9]; + char str4[13]; + memcpy (str1, radioheader+3, 8); + memcpy (str2, radioheader+11, 8); + memcpy (str3, radioheader+19, 8); + memcpy (str4, radioheader+27, 12); - // print header - fprintf (stderr, "\nDSTAR HEADER: "); - //fprintf (stderr, "FLAG1: %02X - FLAG2: %02X - FLAG3: %02X\n", radioheader[0], - // radioheader[1], radioheader[2]); - fprintf (stderr, "RPT 2: %c%c%c%c%c%c%c%c ", radioheader[3], radioheader[4], - radioheader[5], radioheader[6], radioheader[7], radioheader[8], - radioheader[9], radioheader[10]); - fprintf (stderr, "RPT 1: %c%c%c%c%c%c%c%c ", radioheader[11], radioheader[12], - radioheader[13], radioheader[14], radioheader[15], radioheader[16], - radioheader[17], radioheader[18]); - fprintf (stderr, "YOUR: %c%c%c%c%c%c%c%c ", radioheader[19], radioheader[20], - radioheader[21], radioheader[22], radioheader[23], radioheader[24], - radioheader[25], radioheader[26]); - fprintf (stderr, "MY: %c%c%c%c%c%c%c%c/%c%c%c%c\n", radioheader[27], - radioheader[28], radioheader[29], radioheader[30], radioheader[31], - radioheader[32], radioheader[33], radioheader[34], radioheader[35], - radioheader[36], radioheader[37], radioheader[38]); + str1[8] = '\0'; + str2[8] = '\0'; + str3[8] = '\0'; + str4[12] = '\0'; - //FCSinheader = ((radioheader[39] << 8) | radioheader[40]) & 0xFFFF; - //FCScalculated = calc_fcs((unsigned char*) radioheader, 39); - //fprintf (stderr, "Check sum = %04X ", FCSinheader); - //if (FCSinheader == FCScalculated) { - // fprintf (stderr, "(OK)\n"); - //} else { - // fprintf (stderr, "(NOT OK- Calculated FCS = %04X)\n", FCScalculated); - //}; // end else - if + //debug + // fprintf (stderr, " %02X %02X %02X", radioheader[0], radioheader[1], radioheader[2]); + + fprintf (stderr, " RPT 2: %s", str1); + fprintf (stderr, " RPT 1: %s", str2); + fprintf (stderr, " DST: %s", str3); + fprintf (stderr, " SRC: %s", str4); + + 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)); + + //TODO: Call History for DSTAR }