mirror of
https://github.com/lwvmobile/dsd-fme.git
synced 2026-11-12 16:57:23 -05:00
DSTAR Fix CRC on Slow Data Header; Cleanup;
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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')
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
200
src/dstar.c
200
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<len; i++)
|
||||
{
|
||||
uint8_t bit = buf[i] & 1;
|
||||
crc = ((crc << 1) | bit) & 0x1ffff;
|
||||
if (crc & 0x10000) crc = (crc & 0xffff) ^ poly;
|
||||
}
|
||||
crc = crc ^ 0xffff;
|
||||
return crc & 0xffff;
|
||||
}
|
||||
|
||||
//no so simplified Slow Data
|
||||
void processDSTAR_SD(dsd_opts * opts, dsd_state * state, uint8_t * sd)
|
||||
{
|
||||
|
||||
int i, j, len;
|
||||
uint8_t sd_bytes[60]; //raw slow data packed into bytes
|
||||
uint8_t hd_bytes[51]; //storage for packed bytes sans the header indicator byte (0x55)
|
||||
uint8_t hd_bytes[60]; //storage for packed bytes sans the header indicator byte (0x55)
|
||||
uint8_t payload[60]; //unchanged copy of sd_bytes for payload printing
|
||||
uint8_t rev[480]; //storage for reversing the bit order
|
||||
memset (sd_bytes, 0, sizeof(sd_bytes));
|
||||
memset (hd_bytes, 0, sizeof(hd_bytes));
|
||||
memset (payload, 0, sizeof(payload));
|
||||
|
||||
//apply the descrambler
|
||||
for (i = 0; i < 480; i++)
|
||||
sd[i] ^= sd_d[i%24];
|
||||
|
||||
//reverse the bit order
|
||||
for (i = 0; i < 480; i++)
|
||||
rev[i] = sd[479-i];
|
||||
@@ -112,25 +102,12 @@ void processDSTAR_SD(dsd_opts * opts, dsd_state * state, uint8_t * sd)
|
||||
for (i = 0; i < 60; i++)
|
||||
sd_bytes[59-i] = (uint8_t)ConvertBitIntoBytes(&sd[i*8+0], 8);
|
||||
|
||||
//make a copy to payload that won't be altered
|
||||
memcpy (payload, sd_bytes, sizeof(payload));
|
||||
|
||||
len = sd_bytes[0] & 0xF;
|
||||
len += 1;
|
||||
|
||||
//load payload bytes without the header indicator byte
|
||||
// for (i = 0, j = 1; i < 50; i++)
|
||||
// {
|
||||
// hd_bytes[i] = sd_bytes[j];
|
||||
// if (j == 5) j++;
|
||||
// if (j == 11) j++;
|
||||
// if (j == 17) j++;
|
||||
// if (j == 23) j++;
|
||||
// if (j == 29) j++;
|
||||
// if (j == 35) j++;
|
||||
// if (j == 41) j++;
|
||||
// if (j == 47) j++;
|
||||
// if (j == 53) j++;
|
||||
// j++;
|
||||
// }
|
||||
|
||||
//load payload bytes without the header indicator byte
|
||||
for (i = 0, j = 0; i < 50; i++)
|
||||
{
|
||||
@@ -144,30 +121,12 @@ void processDSTAR_SD(dsd_opts * opts, dsd_state * state, uint8_t * sd)
|
||||
if (j == len*6-1) j++;
|
||||
if (j == len*7-1) j++;
|
||||
if (j == len*8-1) j++;
|
||||
if (j == len*9-1) j++;
|
||||
if (j == len*9-1) j++;
|
||||
}
|
||||
|
||||
uint8_t hd_bits[660];
|
||||
memset (hd_bits, 0, sizeof(hd_bits));
|
||||
|
||||
for(i = 0; i < 50; i++)
|
||||
{
|
||||
hd_bits[(i*8)+0] = (hd_bytes[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);
|
||||
|
||||
@@ -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++)
|
||||
|
||||
Reference in New Issue
Block a user