Rewrite and Simplify DSTAR Handling;

This commit is contained in:
lwvmobile
2023-07-29 21:46:11 -04:00
parent 0d4ab17d0a
commit 23b1036c6b
7 changed files with 147 additions and 298 deletions

View File

@@ -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

View File

@@ -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
{

View File

@@ -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)

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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
}